- build_controllers_config.py: gateway-config.json 생성 - load_map_master.py: hc900_map_master 테이블 적재 - measure_scan_time.py: HC900 스캔 시간 측정 유틸
84 lines
2.4 KiB
Python
84 lines
2.4 KiB
Python
#!/usr/bin/env python3
|
|
"""Measure real scan time against C3 (192.168.0.240) using EXACT gateway batching logic."""
|
|
import json
|
|
import time
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
from pymodbus.client import ModbusTcpClient
|
|
|
|
REG_MAP = Path(__file__).parent.parent / "docs" / "register-map-c3.json"
|
|
HOST = "192.168.0.240"
|
|
PORT = 502
|
|
RUNS = 5
|
|
|
|
def load_regs():
|
|
with open(REG_MAP) as f:
|
|
return json.load(f)["registers"]
|
|
|
|
def build_batches(regs):
|
|
"""
|
|
EXACT gateway logic (gateway.cpp:123-173):
|
|
1. Sort registers by address
|
|
2. For each batch: start_addr = first register's addr
|
|
3. Collect all registers where: addr + count - batch_start <= 120
|
|
4. Read count = last.addr + last.count - batch_start
|
|
"""
|
|
sorted_regs = sorted(regs, key=lambda r: r["addr"])
|
|
batches = []
|
|
MAX_BATCH = 120
|
|
i = 0
|
|
while i < len(sorted_regs):
|
|
batch_start = sorted_regs[i]["addr"]
|
|
j = i
|
|
while j < len(sorted_regs):
|
|
e = sorted_regs[j]
|
|
if e["addr"] + e["count"] - batch_start > MAX_BATCH:
|
|
break
|
|
j += 1
|
|
# j-1 is the last register in this batch
|
|
last = sorted_regs[j - 1]
|
|
read_count = last["addr"] + last["count"] - batch_start
|
|
batches.append((batch_start, read_count))
|
|
i = j
|
|
return batches
|
|
|
|
def main():
|
|
regs = load_regs()
|
|
batches = build_batches(regs)
|
|
|
|
total_regs = len(regs)
|
|
total_words = sum(r["count"] for r in regs)
|
|
print(f"Registers: {total_regs}, Total words: {total_words}, Batches: {len(batches)}")
|
|
print(f"Target: {HOST}:{PORT}")
|
|
print()
|
|
|
|
client = ModbusTcpClient(HOST, port=PORT, timeout=5)
|
|
if not client.connect():
|
|
print("ERROR: connection failed"); sys.exit(1)
|
|
|
|
times = []
|
|
for run in range(1, RUNS + 1):
|
|
t0 = time.perf_counter()
|
|
errors = 0
|
|
for i, (addr, count) in enumerate(batches):
|
|
resp = client.read_holding_registers(addr, count=count)
|
|
if resp.isError():
|
|
errors += 1
|
|
|
|
elapsed = (time.perf_counter() - t0) * 1000
|
|
times.append(elapsed)
|
|
print(f"run{run}: {elapsed:.1f} ms (batches {len(batches)}, errors {errors})")
|
|
|
|
client.close()
|
|
|
|
times.sort()
|
|
print(f"\n---")
|
|
print(f"Min: {times[0]:.1f} ms")
|
|
print(f"Max: {times[-1]:.1f} ms")
|
|
print(f"Avg: {sum(times)/len(times):.1f} ms")
|
|
print(f"Median: {times[len(times)//2]:.1f} ms")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|