

先厘清设备边界,避免方案设计时就错位。上一轮讲的是"采集记录仪去轮询传感器";这一轮的主语是RJ45 以太网温湿度记录仪——它本身就是带网口、带本地存储、带协议栈的现场节点,既可能被平台轮询,也可能主动上送。多节点组网时,要先定清楚它在架构里扮演哪个角色,再谈 TCP/IP 下的组网。
工程上最常见的是 B+C 混合:现场记录仪是叶子节点,中心侧是采集服务或组态软件。
中心层
└── 采集服务 / 组态软件 / SCADA
│ (TCP 502 轮询 或 接收上送)
核心/接入交换机 (监测VLAN 100)
│
┌────┴───────────────┬──────────────┐
│ │ │
列头A接入交换机 列头B接入 备件/调试口
│ PoE │ PoE
├── 记录仪1 (192.168.100.10) ├── 记录仪N (192.168.100.N)
├── 以太网温湿度传感器xN ├── 以太网温湿度传感器xN
└── 预留端口注意:记录仪与传感器可以在同一VLAN、同一网段,也可分两段——记录仪上行口与传感器管理面同网段,平台采集面走聚合链路。别把管理面、采集面、业务面混在一个广播域。
import asyncio, time
from pymodbus.client import AsyncModbusTcpClient
NODES = {
"rec1": ("192.168.100.10", 502, 1),
"rec2": ("192.168.100.11", 502, 1),
}
async def poll_one(host, port, slave, sem):
async with sem:
client = AsyncModbusTcpClient(host, port=port, timeout=2.0)
await client.connect()
if not client.connected:
return host, None
try:
resp = await client.read_holding_registers(0, count=2, slave=slave)
if resp.isError():
return host, ("err", None)
t = resp.registers[0]*0.1; h = resp.registers[1]*0.1
return host, (t, h)
except Exception as e:
return host, ("exc", type(e).__name__)
finally:
await client.close()
async def cycle(nodes, period=10, dur=3600):
sem = asyncio.Semaphore(32)
start = time.time()
while time.time()-start < dur:
t0 = time.time()
res = await asyncio.gather(*[poll_one(*n, sem) for n in nodes.values()])
# 写本地缓冲/InfluxDB/转发
elapsed = time.time()-t0
wait = max(0, period-elapsed)
await asyncio.sleep(wait)
asyncio.run(cycle(NODES, period=10, dur=3600))原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。