Files
fori_ZLTECHDRIVER_ID_SET/zltech_modbus.py
T
2026-08-07 13:44:56 +09:00

56 lines
1.9 KiB
Python

"""pymodbus-based helpers for the ZLAC8015D V4 RS485 (Modbus RTU) protocol.
Register reference (from "ZLAC8015D V4 Series RS485 Communication" manual):
0x2001 RS485 Custom Drive Node Number (RW/S, range 1-127, default 1)
0x2002 RS485 custom communication baud rate (RW/S)
0x2010 Save all RW attribute parameters to EEPROM (write 1 to save)
Requires: pip install pymodbus pyserial
"""
from pymodbus.client import ModbusSerialClient
REG_NODE_ID = 0x2001
REG_SAVE_EEPROM = 0x2010
# pymodbus renamed the "slave id" keyword across major versions
# (unit -> slave -> device_id). Try each so this works regardless of
# which pymodbus version is installed (e.g. on the Ubuntu test box).
_ID_KWARGS = ("device_id", "slave", "unit")
def _call(fn, *args, node_id, **kwargs):
last_err = None
for kw in _ID_KWARGS:
try:
return fn(*args, **{kw: node_id}, **kwargs)
except TypeError as exc:
last_err = exc
continue
raise TypeError(f"pymodbus client does not accept any of {_ID_KWARGS}: {last_err}")
def make_client(port: str, baud: int = 115200, timeout: float = 0.3) -> ModbusSerialClient:
return ModbusSerialClient(
port,
baudrate=baud,
bytesize=8,
parity="N",
stopbits=1,
timeout=timeout,
)
def read_register(client: ModbusSerialClient, node_id: int, address: int, count: int = 1):
"""Return list of register values, or None on error/no response."""
result = _call(client.read_holding_registers, address, node_id=node_id, count=count)
if result is None or result.isError():
return None
return result.registers
def write_register(client: ModbusSerialClient, node_id: int, address: int, value: int) -> bool:
result = _call(client.write_register, address, value, node_id=node_id)
if result is None or result.isError():
return False
return True