Make sure you
import socket at the top of the script to include the socket library, and determine the host (whether hardcoded, localhost, or taken as an argument). Then:
Create a socket:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Use that socket to connect to the controller with a tuple made by the host at port 2001:
s.connect( (host,port) ) # ex. host = '127.0.0.1' (string), port = 2001 (integer)
Binary-encode the array of data and send it through the socket:
result = s.send(bytearray(myBytes)) # 'myBytes' is the sixteen-entry array built last section.
Note: s.send() returns the number of bytes sent and read block requests must be 16 bytes, so if
result != 16then something is wrong, which is helpful to know while debugging.
Save the response:
data = s.recv(24) # read block response is 24 bytes long
data holds the requested read data (or, depending on the transaction code, write confirmation), and takes the format
(#,) with the actual value at
#. However, this is behind both binary encoding and little-endian byte ordering – so we have to reverse the bytes and decode the response to get that.
In the case of a Read Block Response, the data length is held in bytes 12–15, and the actual data block is the last quadlet (four bytes) of the response, 16–19. Since
socket.recv() returns a string, we can treat this response package like an array and slice it starting at 16 and ending at 20, so that we grab the 19th byte.
data_block = data[16:20]
Now we use the built-in function
bytearray() to convert the string to bytes, then hand that to the external
struct library (you must
import struct) to get the integer response out of the byte array.
data_blockholds the bytes in big-endian order (the most significant digit is stored first) so be sure to include the flag
>for big-endian as well as
ifor integer value.
output = struct.unpack_from('>i', bytearray(data_block))
At this stage
output holds the formatted response
($,). Now we can slice out the first and last two characters,
,), print the rest to the screen, and we’re all done!
Check out the code samples below to see all of these moving parts together, and feel free to modify them for your own use.
This guide references material from three sample python scripts:
getUptime.py returns the uptime of a controller in ms. The IP is an optional argument that defaults to localhost.
readModCh.py takes two arguments (module and channel numbers) and returns the value at that digital point.
writeModChVal.py takes three arguments: module, channel, and the value to be written (either 0 or 1).
Continue to sample Python scripts
Or go back to Building your first OptoMMP data package with Python
Or check out the prebuilt Python package for groov EPIC.