from pyModbusTCP.client import ModbusClient
c = ModbusClient(host="192.168.0.1", auto_open=True)
while True:
# read 16 bits at address 0, these are the Digital Outputs for the TechMan
bits = c.read_coils(0, 16)
print("bit ad #0 to 9: "+str(bits) if bits else "read error")
# sleep 2s
time.sleep(2)
It is also possible to read / write floats, but so far only user defined values can be read:
# how-to add float support to ModbusClient
from pyModbusTCP.client import ModbusClient
from pyModbusTCP import utils
class FloatModbusClient(ModbusClient):
def read_float(self, address, number=1):
reg_l = self.read_holding_registers(address, number * 2)
if reg_l:
return [utils.decode_ieee(f) for f in utils.word_list_to_long(reg_l)]
else:
return None
def write_float(self, address, floats_list):
b32_l = [utils.encode_ieee(f) for f in floats_list]
b16_l = utils.long_list_to_word(b32_l)
return self.write_multiple_registers(address, b16_l)
c = FloatModbusClient(host='192.168.0.1', port=502, auto_open=True)
c.write_float(9000, [123.0])
# read @0 to 9
float_l = c.read_float(9000)
print(float_l)
c.close()
To read a X,Y,Z coordinate you have to read a input register instead of a holding register. It still is a float so we copied the read_float function and made some adjustments.
We added this function to the class FloatModbusClient:
class FloatModbusClient(ModbusClient):
def read_float(self, address, number=1):
reg_l = self.read_holding_registers(address, number * 2)
if reg_l:
return [utils.decode_ieee(f) for f in utils.word_list_to_long(reg_l)]
else:
return None
def read_input_registers_float(self, address, number=1):
reg_1 = self.read_input_registers(address, number * 2)
if reg_1:
return [utils.decode_ieee(f) for f in utils.word_list_to_long(reg_1)]
else:
return None
def write_float(self, address, floats_list):
b32_l = [utils.encode_ieee(f) for f in floats_list]
b16_l = utils.long_list_to_word(b32_l)
return self.write_multiple_registers(address, b16_l)
def write_single_register_float(self, address, floats_list):
b32_l = [utils.encode_ieee(f) for f in floats_list]
b16_l = utils.long_list_to_word(b32_l)
return self.write_single_register(address, b16_l)