Ping from tag-script

Hi,

I want to perform a cyclic “ping” to check if a device is available on the network. If the device is not responding, i want to create an alarm.

Is there any way to perform a ping operation from a script run in a tag?

I know there is a ping driver available on the marketplace, but the cost is rather high.

I would not run this from an event script on a tag.
Instead run it in Gateway Timer script that calls the ping asynchronously.

def ping(address):
	import subprocess
	command = 'ping', '%s' % address
	# shell=True hides the shell window, stdout to PIPE enables communicate() to get the ping command result
	process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
	# trimming it to the actual lines with information
	process_out = process.communicate()[0].strip().split('\r\n')
	# print out the return of the ping
	print process_out[1:5]

But as brandon1 says is better for you to call this script in a Gateway Timer Script.
Just set the address you need inside the variable “address” and you’ll be good to go

But, not all devices accept ping or they may block ICMP. Java’s InetAddress is more reliable in this instance. And you don’t have to subprocess it.

def ping(host, timeout=1000):
  from java.net import InetAddress

  ip = InetAddress.getByName(host)
  r =  ip.isReachable(timeout)

  return r
 
4 Likes

How would it be more reliable Jordan? InetAddress tries to use ICMP and if not available falls back to echo on port 7 - which I would think is even less likely to be available nowadays.

Do something like this. Make sure to run asynchronous:

import os
def ping():
status = (os.system("ping " + deviceIP) == 0)

    def checkStatus():
    	if deviceOnline: 
    		output = deviceName + " with IP: " + deviceIP + " is online."
    		state = 1
    	else:
    		output = deviceName + " with IP: " + deviceIP + " is not connected."
    		state = 0
    	
    system.util.invokeLater(checkStatus)

 deviceOnline = system.util.invokeAsynchronous(ping)

These approaches are all pretty much equivalent - an ICMP echo request.

I like that @awaege has set it up to be async.

1 Like

It’s based on my admittedly anecdotal evidence from working with the devices around here in the facility in which I work. :slight_smile:

In many cases (again, around here), a managed switch may block ICMP, but be transparent to TCP port 7. Same with NAT devices.

Yeah, but… have you ever actually seen a server or device running the echo service (in… the last 10 years? more? ever?)

Ever? Pfft. I have running equipment from the 90s here, so yeah, I kinda have. Just life in the trenches. Lol

Heck, I’m old enough to have installed and used ARCnet, back in the day. ARCnet was bulletproof enough we once strung three PCs together with spiral notebook wire, and it still worked.

Sorry for aimlessly wandering. Part of getting old…

3 Likes

See? I’m so old I sidetracked myself!

I’ll need to revisit at some point, but if I recall, isReachable doesn’t require an echo service to be running. The reset packet from the target was enough to return True.

Or something like that. I first looked into this five or six years ago. And since it worked for my needs, with aforementioned equipment, I didn’t look any further into it.

Ended up using Jordans script triggered from a gateway timed event. Works great! Thanks.

I have enhanced the script to use a dataset with a list of ping. On a schedule script it will ping just one device by turn not to flood the network.



# Script to get the network status of a device. If the 
# the device is online, Last_Response will be true otherwise false for 
# disconnected device

def ping():
	from java.net import InetAddress
	# index as int
	# Ip_List as dataset(index, IP, Last_Response,TimeOut)
	# get Table data 
	ds = system.tag.read("Ip_List").value
	index = system.tag.read("Index").value
	if index < 0:
		index=0 
		system.tag.write("Index", index)
	if index > (len(ds.data)-2):
		index=0 
		system.tag.write("Index", index + 1)	
	timeout = ds.getValueAt( index, "TimeOut")
	host= ds.getValueAt(index,"IP" )
	
	# Java Inet, ping
	ip = InetAddress.getByName(host)
	Response = ip.isReachable(timeout)
	
	# Write back the value
	system.tag.write("Index", index + 1)
	system.tag.write("Ip_List", system.dataset.setValue(ds, index, "Last_Response", Response))