Pinging A Device From Daqfactory


Recommended Posts

Sometimes it can be hard to tell if a failure to communicate with a device is caused by a networking issue (cut cable, no power to remote device) or something else (protocol error, etc.)  In these cases, the first thing we tend to do is ping the device.  A successful ping at least tells us that the device is powered up and the IP is accessible from this computer.  It doesn't tell us if the device will allow us to connect to it, a firewall is blocking the desired ports (say 502 for Modbus), or other issues, but it does eliminate some possible problems.  There are many times when we wish to do this automatically.  So, here is a simple script we'd like to share that you can use to ping a device from script:

 

function checkPing(string ip, string path)
   system.ShellExecute("cmd","","/C ping " + ip + " > " + path, "", "hide")
   delay(5)
   private h = file.Open(path,1,0,0,0)
   private string data = file.Read(h, file.GetLength(h))
   file.Close(h)
   return(find(data,"TTL=",0) != -1)

It does this by triggering the command line ping, just like you would type it, and then piping the result to a file.  Then it opens the file and looks for "TTL=" which really only appears if a ping is successful.  The delay(5) is to give the ping command time to execute as there is no way us to know.  ShellExecute() is a non-blocking function, meaning it will trigger the command but then immediately return.  Because we are using command line piping we have to have shellExecute() run "CMD" not "Ping" directly.  We pass the /C flag to CMD to tell it to run the Ping command then quit.

 

The design of this function is to allow you to, in script, check the network status on many devices.  Simply call this function with the ip and a path to the file you'd like ping to create with the result.  You'll want to make sure if you are calling this function from multiple threads for multiple IPs that you pass a different path.  

Note also that this function will take at least 5 seconds to run, so don't call it from the command line or a button press.  Make sure and call it from a sequence running in a background thread.

 

   
Link to comment
Share on other sites

  • 2 years later...

Hi, 

To check if all devices work OK I'm using expression (  systime() - temp_gorice.time[0] > 5 )..Now I need to check other IP devices eg. TCP/RS232, access points, IP printers , IP cams that is not modbus so only solution is to ping them.

so here I need to make sequence like this...

function checkPing(string ip, string path)
   system.ShellExecute("cmd","","/C ping " + ip + " > " + path, "", "hide")
   delay(5)
   private h = file.Open(path,1,0,0,0)
   private string data = file.Read(h, file.GetLength(h))
   file.Close(h)
   return(find(data,"TTL=",0) != -1)

I want to show for every device on network their TTL time like...

node 12 ( Lexmark printer, room 12) : 12ms

node 15 ( IP cam, room 14): 10ms

etc...

please see screen, is that OK ?  DF freezes..

what should be there ... string path  --> path to txt file with ping results... ??

 

blob.png.4c52ff22bdfe93cd079beae00986fe7f.png

 

 

 

 

 

 

Link to comment
Share on other sites

You can't put something in the Expression field of any screen control that isn't really fast.  Your code will take a minimum of 5 seconds to run given the delay(5) and so will flat out hang the user interface.  You will need to put the checkPing() function calls in a Sequence that runs in the background and updates some global variable that you can then reference from your screen control.

Link to comment
Share on other sites

Sure.  There are lots of ways of doing this.  I don't see why you need a separate file for each location since they'll be ping sequentially though, so:

global pingIPs = {"192.168.1.1", "192.168.1.2", "192.168.1.34"}
global pingState = fill(0, numrows(pingIPs))
while(1)
   try
      for (private i = 0, i < numrows(pingIPs), i++)
         pingState[i] = checkPing(pingIps[i], "d:\razno\probe2")
         delay(0.1)
     endfor
   catch()
      ? strLastError
      delay(0.1)
   endcatch
endwhile

Run that in the background, then have your screen control use the pingState global to display the status.

Note also that your screenshot is invalid.  The first parameter is a string.  192.168.1.1 on it's own doesn't exist in DAQFactory and will be translated to simply 192 (or maybe it's 1, I don't know and there's no reason to know since it's just wrong).  So, in your example, it will ping the address 192.  You need to put the IP address in quotes.

Link to comment
Share on other sites

Something with your shellExecute().  DAQFactory was never going to create the probe2 file.  That is handled by the > in your command line.   You should probably ? the result of the string concatenation of the shellExecute() then try it from an actual command line.  Yes, you can do cmd /C from the command line.  It will just open another command shell. My guess is that you need quotes for everything after the /c, so the result is something like:

cmd /C "ping 192.168.1.1 > d:\razno\probe2"

Note that you'll need to use single quotes then in DAQFactory so you can put double quotes inside:

'/C "ping ' + etc..

Link to comment
Share on other sites

hi, 

I found somewhere bat file that runs ping test from  txt file..

Results are saved in separate txt file  like here, IP address and ping result has" ;" delimiter

192.168.1.1; is OK 
192.168.1.3; is NOT OK 
google.com; is OK 
jadrtovac.dyndns.info; is OK 
hans.dyndns.info; is OK 
192.168.1.11; is NOT OK 
jutarnji.hr; is OK 

So, here in attachement is sample of code

My plan is to make map with devices and change colour depending of ping result.

I created sequence to activate bat file and save results in file pingresults.txt in format IP address, ping result.

system.ShellExecute("D:\razno\ping_test_boje_ver3.bat","open","D:\razno","hide")   --> runs BAT file but I can't hide it from main screen ??

 

How to read results from file pingresults.txt and store results in array ??

what do you suggest ?

blob.png.a549089e018b28baea434f4057fdc4fd.png

ping_test_boje_ver3.bat

servers.txt

Link to comment
Share on other sites

  • 1 year later...

Thanks for reply but these are my sequences below 

function checkPing(string ip, string path)
   system.ShellExecute("cmd","",'/C "ping ' + ip + " > " + path, "", "hide")
   delay(5)
   private h = file.Open(path,1,0,0,0)
   private string data = file.Read(h, file.GetLength(h))
   file.Close(h)
   return(find(data,"TTL=",0) != -1)

 

 

 

 

global pingIPs = {'192.168.141.50', '192.168.141.55', '192.168.141.94'}
global pingState = fill(0, numrows(pingIPs))
while(1)
   try
      for (private i = 0, i < numrows(pingIPs), i++)
         pingState = checkPing(pingIps, "d:\DAQFACTORY\probe2")
         delay(0.1)
     endfor
   catch()
      ? strLastError
      delay(0.1)
   endcatch
endwhile

Link to comment
Share on other sites

OK, is there an issue?  One thing I will point out is that in newer releases of DAQFactory, the C:\DAQFactory installation folder is read-only when DAQFactory is run in normal mode.  This is for security reasons.  That means that your code might not be able to write the text to D:\DAQFactory\probe2.  Check the security settings on the folder, or better yet, create a new folder for this file.

Link to comment
Share on other sites

Thanks for that but the folder isn't the DAQ install folder i just created that folder for this script. the file is being created as intended but all that shows up is. 

Pinging 192.0.0.168 with 32 bytes of data:
Request timed out.
Request timed out.
Request timed out.

 

The problem is as you can see from my sequence that isn't the ip i have listed  global pingIPs = {'192.168.141.50', '192.168.141.55', '192.168.141.94'}

Link to comment
Share on other sites

Right.  Sorry didn't look carefully and missed your typo.  Look in the calling function.  You have pingIPs declared as a number, not a string.  You then define it as an array of strings, but the variable is still declared as a number, so DAQFactory is converting all it to an array of 192.168's and the rest is thrown away because it is not a valid number.  DAQFactory will convert string numbers to actual numbers up to the point where it is invalid, or if the first character is invalid it will convert it to NaN.   So, "192.168.141.50" becomes 192.168, and "ab192" becomes NaN, and "192ab" becomes 192.

If you go to a command prompt and type: ping 192.168 you'll see that it will actually try and ping 192.0.0.168.  That's being done by the ping executable.

Link to comment
Share on other sites

That's because you already declared pingIPs as a number.  Declaring a global variable after it is already declared doesn't change the type.  You need to either save and restart, or enter ClearGlobals() at the command / alert window to clear out all existing globals so that pingIPs can be redeclared as a string.  I recommend the restart option so your auto-start sequence  runs (if any) otherwise you end up with other problems (other global variables that have now been "undeclared")

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.