Sign in to follow this  
AzeoTech

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.

 

   

Share this post


Link to post
Share on other sites

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

 

 

 

 

 

 

Share this post


Link to post
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.

Share this post


Link to post
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.

Share this post


Link to post
Share on other sites

but DF did not created file probe2  ??  "d:\razno\probe2"),

now I have result 0.000, 0.000, 0.000  ( variable value component )

there is no error but ping is still not working...what I missed ?

Share this post


Link to post
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..

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this