98 lines
2.6 KiB
Python
Executable File
98 lines
2.6 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import argparse
|
|
import struct
|
|
from pymodbus.client import ModbusSerialClient
|
|
|
|
|
|
def regs_to_bytes(regs, mode):
|
|
a = regs[0]
|
|
b = regs[1]
|
|
|
|
ab = a.to_bytes(2, "big")
|
|
cd = b.to_bytes(2, "big")
|
|
|
|
if mode == "ABCD":
|
|
return ab + cd
|
|
if mode == "CDAB":
|
|
return cd + ab
|
|
if mode == "BADC":
|
|
return ab[::-1] + cd[::-1]
|
|
if mode == "DCBA":
|
|
return cd[::-1] + ab[::-1]
|
|
|
|
raise ValueError(mode)
|
|
|
|
|
|
def decode_float_candidates(regs):
|
|
out = {}
|
|
for mode in ["ABCD", "CDAB", "BADC", "DCBA"]:
|
|
try:
|
|
raw = regs_to_bytes(regs, mode)
|
|
out[mode] = struct.unpack(">f", raw)[0]
|
|
except Exception as exc:
|
|
out[mode] = f"ERR: {exc}"
|
|
return out
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("--port", default="/dev/ttyRS485")
|
|
parser.add_argument("--slave", type=int, default=1)
|
|
parser.add_argument("--baud", type=int, default=9600)
|
|
parser.add_argument("--parity", default="N", choices=["N", "E", "O"])
|
|
parser.add_argument("--stopbits", type=int, default=1)
|
|
parser.add_argument("--bytesize", type=int, default=8)
|
|
parser.add_argument("--address", type=int, default=0)
|
|
parser.add_argument("--count", type=int, default=2)
|
|
parser.add_argument("--timeout", type=float, default=1.5)
|
|
args = parser.parse_args()
|
|
|
|
print("--- MODBUS RTU PROBE ---")
|
|
print(f"port={args.port}")
|
|
print(f"slave={args.slave}")
|
|
print(f"baud={args.baud}")
|
|
print(f"parity={args.parity}")
|
|
print(f"address={args.address}")
|
|
print(f"count={args.count}")
|
|
|
|
client = ModbusSerialClient(
|
|
port=args.port,
|
|
baudrate=args.baud,
|
|
parity=args.parity,
|
|
stopbits=args.stopbits,
|
|
bytesize=args.bytesize,
|
|
timeout=args.timeout,
|
|
)
|
|
|
|
if not client.connect():
|
|
print("[ERROR] Cannot open serial port")
|
|
return 2
|
|
|
|
try:
|
|
rr = client.read_input_registers(
|
|
address=args.address,
|
|
count=args.count,
|
|
device_id=args.slave,
|
|
)
|
|
|
|
if rr.isError():
|
|
print(f"[ERROR] Modbus error: {rr}")
|
|
return 3
|
|
|
|
regs = rr.registers
|
|
print(f"registers={regs}")
|
|
print("float_candidates:")
|
|
for mode, value in decode_float_candidates(regs).items():
|
|
print(f" {mode}: {value}")
|
|
|
|
return 0
|
|
except Exception as exc:
|
|
print(f"[ERROR] No Modbus response: {type(exc).__name__}: {exc}")
|
|
return 3
|
|
finally:
|
|
client.close()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|