Transmission Control Protocol (TCP)
SOCS provides a standard interface for connecting to devices using TCP. This page details how to use this interface. The primary benefit to using this interface is the included error handling.
A few important things to know about the behavior of the interface class:
The interface tries to connect to the device when instantiated.
It will log but not raise an error if it cannot connect, instead
self.commwill beNone.The connection will be reset when
send()is called if this happens. An exception will be raised if it still cannot connect.The interface is built to mimic
socket.send()andsocket.recv(), but usessocket.sendall()in its implementation, so all bytes in the included message are sent to the socket.
See the example below for how to implement use of the TCPInterface class in
your device drivers and how to add error handling to the agent.
Example
An example of using TCPInterface to create a class that interfaces with a
device:
from socs.tcp import TCPInterface
class Device(TCPInterface):
def __init__(self, ip_address, port=501, timeout=10, *args, **kwargs):
# Setup the TCP Interface
super().__init__(ip_address, port, timeout)
def get_data(self):
self.send(query_string)
data = self.recv()
# Optionally perform any decoding required
return data
Within the agent code where Device.get_data is used you should now handle
the possible ConnectionError, as shown below.
Note
This example is stripped down to focus on the error handling. Important parts of the agent process are missing here, like obtaining the lock and publishing data to a feed.
class DeviceAgent:
self.device = Device('192.168.1.2')
def main(self, session, params):
"""Main data acquisition process."""
while session.status in ['starting', 'running']:
try:
data = self.device.get_data()
if session.degraded:
self.log.info("Connection re-established.")
session.degraded = False
except ConnectionError:
self.log.error("Failed to get data from device. Check network connection.")
session.degraded = True
time.sleep(1) # wait between reconnection attempts
continue
return True, "Main process exited successfully."
See existing TCP agents, such as the Cryomech CPA Agent (which the above example is based on) for more examples.
API
If you are developing an agent that connects to a device using TCP, the
TCPInterface class is available for use and detailed here:
- class socs.tcp.TCPInterface(ip_address, port, timeout)[source]
Interface class for connecting to devices using TCP.
- Parameters:
ip_address (str) – IP address of the device.
port (int) – Associated port for TCP communication.
timeout (float) – Duration in seconds that operations wait before giving up.
- ip_address
IP address of the device.
- Type:
str
- port
Associated port for TCP communication.
- Type:
int
- timeout
Duration in seconds that operations wait before giving up.
- Type:
float
- comm
Socket object that forms the connection to the device.
- Type:
socket.socket
- send(msg)[source]
Send message to socket.
This method will try to send the message and if it runs into any issues will try to re-establish the socket connection before trying to send the message again. If it fails a second time it raises an exception.
If the connection has failed to reset from a previous
send, or has not yet been established, it will first try to connnect before sending the message. If it fails to establish the connection it will raise an exception.- Parameters:
msg (str) – Message string to send on socket.
- Raises:
ConnectionError – Raised if the communication fails for any reason.
- recv(bufsize=4096)[source]
Receive response from the device.
This method will check if the socket is ready to be read from before performing the recv. If there is no data to read, or the socket is otherwise unready an exception is raised.
- Parameters:
bufsize (int) – Amount of data to be recieved in bytes. Defaults to 4096.
- Returns:
The response from the device. The return type depends on the device.
- Return type:
strorbytes- Raises:
ConnectionError – Raised if the socket is not ready to read from.