40-clients/ucepsa/edge-oee-demo/revpi/edge-oee/probe_modbus_float.py
2026-06-25 18:51:33 +02:00

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())