feat: add discrete-input support and RPU config-writable check
This commit is contained in:
@@ -94,6 +94,14 @@ class ModbusDevice:
|
||||
val = self.read_input_register(address)
|
||||
return val - 65536 if val > 32767 else val
|
||||
|
||||
def read_discrete_input(self, address):
|
||||
def _do():
|
||||
res = self.client.read_discrete_inputs(address, count=1, device_id=self.slave_id)
|
||||
if res.isError():
|
||||
raise ModbusReadError(f"{self.device_name}: failed to read discrete input {address}")
|
||||
return res.bits[0]
|
||||
return self._retry(_do)
|
||||
|
||||
def read_input_register_float(self, address):
|
||||
def _do():
|
||||
res = self.client.read_input_registers(address, count=2, device_id=self.slave_id)
|
||||
@@ -115,14 +123,14 @@ class ModbusDevice:
|
||||
raise ModbusWriteError(f"{self.device_name}: write coil {address}={value} not verified")
|
||||
self._retry(_do)
|
||||
|
||||
def write_holding_register(self, address, value):
|
||||
def write_holding_register(self, address, value, verify=True):
|
||||
value = int(value) & 0xFFFF # two's-complement wrap so negative (signed) values fit the uint16 wire format
|
||||
|
||||
def _do():
|
||||
res = self.client.write_register(address, value, device_id=self.slave_id)
|
||||
if res.isError():
|
||||
raise ModbusWriteError(f"{self.device_name}: failed to write holding {address}")
|
||||
if self.read_holding_register(address) != value:
|
||||
if verify and self.read_holding_register(address) != value:
|
||||
raise ModbusWriteError(f"{self.device_name}: write holding {address}={value} not verified")
|
||||
self._retry(_do)
|
||||
|
||||
@@ -155,6 +163,8 @@ class ModbusDevice:
|
||||
reg = self._register(label)
|
||||
if reg.object_type == "coil":
|
||||
return self.read_coil(reg.address)
|
||||
if reg.object_type == "discrete":
|
||||
return self.read_discrete_input(reg.address)
|
||||
if reg.object_type == "input":
|
||||
if reg.data_type == "float":
|
||||
return self.read_input_register_float(reg.address)
|
||||
@@ -169,16 +179,16 @@ class ModbusDevice:
|
||||
return self.read_holding_register(reg.address)
|
||||
raise ModbusDeviceError(f"{self.device_name}: unsupported object_type {reg.object_type!r} for {label!r}")
|
||||
|
||||
def write(self, label, value):
|
||||
def write(self, label, value, verify=True):
|
||||
reg = self._register(label)
|
||||
if reg.object_type == "coil":
|
||||
self.write_coil(reg.address, value)
|
||||
self.write_coil(reg.address, value, verify=verify)
|
||||
return
|
||||
if reg.object_type == "holding":
|
||||
if reg.data_type == "float":
|
||||
self.write_holding_register_float(reg.address, value)
|
||||
else:
|
||||
self.write_holding_register(reg.address, value)
|
||||
self.write_holding_register(reg.address, value, verify=verify)
|
||||
return
|
||||
raise ModbusDeviceError(f"{self.device_name}: cannot write to object_type {reg.object_type!r} for {label!r}")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user