126 lines
3.4 KiB
Python
Executable File
126 lines
3.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import argparse
|
|
import time
|
|
from pymodbus.client import ModbusTcpClient
|
|
|
|
|
|
def read_block(client, kind, start, count, unit):
|
|
fn = client.read_holding_registers if kind == "holding" else client.read_input_registers
|
|
|
|
try:
|
|
rr = fn(address=start, count=count, device_id=unit)
|
|
except Exception:
|
|
return None
|
|
|
|
if rr.isError():
|
|
return None
|
|
|
|
return rr.registers
|
|
|
|
|
|
def snapshot(client, unit):
|
|
ranges = [
|
|
("holding", 0, 200),
|
|
("holding", 1000, 100),
|
|
("holding", 2000, 200),
|
|
("holding", 3000, 200),
|
|
("holding", 4000, 200),
|
|
("input", 0, 200),
|
|
("input", 1000, 100),
|
|
("input", 2000, 200),
|
|
("input", 3000, 200),
|
|
("input", 4000, 200),
|
|
]
|
|
|
|
data = {}
|
|
|
|
for kind, start, count in ranges:
|
|
regs = read_block(client, kind, start, count, unit)
|
|
if regs is None:
|
|
continue
|
|
|
|
for i, value in enumerate(regs):
|
|
data[(kind, start + i)] = value
|
|
|
|
return data
|
|
|
|
|
|
def u16_delta(before, after):
|
|
return (after - before) & 0xFFFF
|
|
|
|
|
|
def u32(hi, lo):
|
|
return ((hi & 0xFFFF) << 16) | (lo & 0xFFFF)
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("--host", required=True)
|
|
parser.add_argument("--unit", type=int, default=1)
|
|
parser.add_argument("--expected", type=int, default=10)
|
|
args = parser.parse_args()
|
|
|
|
client = ModbusTcpClient(args.host, port=502, timeout=2)
|
|
|
|
if not client.connect():
|
|
raise RuntimeError("No conecta con WISE")
|
|
|
|
try:
|
|
print("Tomando snapshot inicial...")
|
|
before = snapshot(client, args.unit)
|
|
|
|
print(f"\nAhora pulsa DI1 exactamente {args.expected} veces.")
|
|
input("Cuando termines, pulsa ENTER aquí...")
|
|
|
|
time.sleep(0.5)
|
|
|
|
print("Tomando snapshot final...")
|
|
after = snapshot(client, args.unit)
|
|
|
|
print("\nCambios 16-bit detectados:")
|
|
changes = []
|
|
|
|
for key, before_value in before.items():
|
|
if key not in after:
|
|
continue
|
|
|
|
after_value = after[key]
|
|
if after_value != before_value:
|
|
delta = u16_delta(before_value, after_value)
|
|
closeness = abs(delta - args.expected)
|
|
changes.append((closeness, key, before_value, after_value, delta))
|
|
|
|
for closeness, key, b, a, delta in sorted(changes, key=lambda x: x[0])[:40]:
|
|
kind, addr = key
|
|
print(f"{kind:7s} addr={addr:5d} before={b:6d} after={a:6d} delta={delta}")
|
|
|
|
print("\nCambios 32-bit por parejas:")
|
|
pair_changes = []
|
|
|
|
keys = sorted(before.keys())
|
|
|
|
for kind, addr in keys:
|
|
key_hi = (kind, addr)
|
|
key_lo = (kind, addr + 1)
|
|
|
|
if key_lo not in before or key_hi not in after or key_lo not in after:
|
|
continue
|
|
|
|
before_u32 = u32(before[key_hi], before[key_lo])
|
|
after_u32 = u32(after[key_hi], after[key_lo])
|
|
|
|
if before_u32 != after_u32:
|
|
delta = (after_u32 - before_u32) & 0xFFFFFFFF
|
|
closeness = abs(delta - args.expected)
|
|
pair_changes.append((closeness, kind, addr, before_u32, after_u32, delta))
|
|
|
|
for closeness, kind, addr, b, a, delta in sorted(pair_changes, key=lambda x: x[0])[:40]:
|
|
print(f"{kind:7s} addr={addr:5d}/{addr+1:5d} before={b} after={a} delta={delta}")
|
|
|
|
finally:
|
|
client.close()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|