#!/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()