TCP/IP Socket Comms

Customer is putting in an AGV system. The AGV systems wants to talk to the gateway through TCP/IP Socket Comms. So I need to create a listener on the gateway that will write the data it received to a tag. I have read through the following posts:

There is this post, that talks thorugh using the pyton socket library. And it does talk through creating a listener.

However, according to this post, which is a much newer post, it is stated that you should not use the python socket library and should be done in Java.

So I have attempted to do just that. However, I am getting an error when attempting to start this through a startup script on the gateway.

Here is the code that I have in the startup script.

def read_tcp():
	# Import Needed Librarys
	from java.net import Socket,InetAddress
	import system as system
	
	# Set the variables needed
	ip = '192.168.25.16'
	port = 120
	
	try:
		# Create the socket
		s = Socket(InetAddress.getByName(ip),port)
		# Set socket variables
		s.setReuseAddress(True)
		# Bind the socket
		s = s.bind(InetAddress.getByName(ip))
		
		# Setup the listener
		while True:
			inStream = s.getInputStream()
			print "Received %s" % (inStream)
			system.tag.writeBlocking(["[NPT_SMCLineTags]AGV/recMessage"], [inStream])
	
	except Exception as e:
	    print("Error:", e)
			
system.util.invokeAsynchronous(read_tcp,'listener')

Here is the error that I am getting in the gateway log.

SystemUtilities	09Jul2024 09:22:23	Error running function from system.util.invokeAsynchronous
com.inductiveautomation.ignition.common.script.JythonExecException: Traceback (most recent call last): File "<[NPT_SMCLineTesting_New] Startup Script>", line 12, in read_tcp File "<[NPT_SMCLineTesting_New] Startup Script>", line 12, in read_tcp at java.base/sun.nio.ch.Net.connect0(Native Method) at java.base/sun.nio.ch.Net.connect(Unknown Source) at java.base/sun.nio.ch.Net.connect(Unknown Source) at java.base/sun.nio.ch.NioSocketImpl.connect(Unknown Source) at java.base/java.net.SocksSocketImpl.connect(Unknown Source) at java.base/java.net.Socket.connect(Unknown Source) at java.base/java.net.Socket.connect(Unknown Source) at java.base/java.net.Socket.(Unknown Source) at java.base/java.net.Socket.(Unknown Source) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Unknown Source) at java.base/java.lang.reflect.Constructor.newInstance(Unknown Source) at org.python.core.PyReflectedConstructor.constructProxy(PyReflectedConstructor.java:213) java.net.ConnectException: java.net.ConnectException: Connection refused: connect
at org.python.core.Py.JavaError(Py.java:545)
at org.python.core.Py.JavaError(Py.java:536)
at org.python.core.PyReflectedConstructor.constructProxy(PyReflectedConstructor.java:223)
at org.python.core.PyReflectedConstructor.__call__(PyReflectedConstructor.java:182)
at org.python.core.PyObject.__call__(PyObject.java:422)
at org.python.core.PyMethod.instancemethod___call__(PyMethod.java:237)
at org.python.core.PyMethod.__call__(PyMethod.java:228)
at org.python.core.PyMethod.__call__(PyMethod.java:223)
at org.python.core.Deriveds.dispatch__init__(Deriveds.java:20)
at org.python.core.PyObjectDerived.dispatch__init__(PyObjectDerived.java:1112)
at org.python.core.PyType.type___call__(PyType.java:2408)
at org.python.core.PyType.__call__(PyType.java:2389)
at org.python.core.PyObject.__call__(PyObject.java:477)
at org.python.core.PyObject.__call__(PyObject.java:481)
at org.python.pycode._pyx4440.read_tcp$1(<[NPT_SMCLineTesting_New] Startup Script>:25)
at org.python.pycode._pyx4440.call_function(<[NPT_SMCLineTesting_New] Startup Script>)
at org.python.core.PyTableCode.call(PyTableCode.java:173)
at org.python.core.PyBaseCode.call(PyBaseCode.java:306)
at org.python.core.PyFunction.function___call__(PyFunction.java:474)
at org.python.core.PyFunction.__call__(PyFunction.java:469)
at org.python.core.PyFunction.__call__(PyFunction.java:464)
at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:847)
at com.inductiveautomation.ignition.gateway.script.GatewaySystemUtilities.lambda$_invokeAsyncImpl$0(GatewaySystemUtilities.java:152)
at java.base/java.lang.Thread.run(Unknown Source)
Caused by: org.python.core.PyException: java.net.ConnectException: java.net.ConnectException: Connection refused: connect
... 24 common frames omitted
Caused by: java.net.ConnectException: Connection refused: connect
at java.base/sun.nio.ch.Net.connect0(Native Method)
at java.base/sun.nio.ch.Net.connect(Unknown Source)
at java.base/sun.nio.ch.Net.connect(Unknown Source)
at java.base/sun.nio.ch.NioSocketImpl.connect(Unknown Source)
at java.base/java.net.SocksSocketImpl.connect(Unknown Source)
at java.base/java.net.Socket.connect(Unknown Source)
at java.base/java.net.Socket.connect(Unknown Source)
at java.base/java.net.Socket.(Unknown Source)
at java.base/java.net.Socket.(Unknown Source)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Unknown Source)
at java.base/java.lang.reflect.Constructor.newInstance(Unknown Source)
at org.python.core.PyReflectedConstructor.constructProxy(PyReflectedConstructor.java:213)
... 21 common frames omitted

Can anyone provide some feedback on what I have done wrong?

1 Like

First, create a project library script. Gateway event scripts have legacy scoping issues, and event scripts are difficult to maintain. Events should be one-liners that delegate to a project library script function.

The asynchronous task needs some means to be interrupted--no while True: is acceptable. Any project edit and save will restart scripts and launch another asynch task--the new one needs a method to kill off the old one. That almost always means you need to use system.util.getGlobals() (or a modern alternative like my system.util.globalVarMap()) to hold a thread reference for interrupting/joining.

I have had much success with @chi 's module generic-tcp-driver. GitHub - chi-Ignition/generic-tcp-driver: A universal tcp client/server driver for the Ignition(R) OPC-UA server.
It can act as a listener and you can create tags to receive the raw data.

Interesting. How does one install this on the server?

Download the zip file. Then go to your Ignition Gateway (Config>Modules>Install Module). I can't remember if it will accept the zip file as is or if you need to rename the file extension to .modl. After that, you create a device connection specifying this new driver (Client or Server).
If the AGV's can be added as individual clients via their IP address, that would be best so you can keep track of which one is online/offline. Otherwise, you just have to wait for data to come in.

image

1 Like