{"id":"d494644e-4185-43e2-b198-8e1814254127","task":"Poll Modbus TCP devices from a gateway and forward readings to an MQTT broker","domain":"iot-general","steps":["Identify the Modbus TCP device's IP address and port (default 502), its Unit ID (also called Slave ID or Server ID), and the register map (holding registers, input registers, coils, discrete inputs) from the device datasheet","Use a Modbus TCP client library (e.g., pymodbus in Python) to connect and read registers: connect to the device IP/port, then call read_holding_registers(address, count, unit=<unit_id>); interpret the raw 16-bit register values using the datasheet's data type and scale factor","Implement a polling loop with a configurable interval (e.g., every 5 seconds); handle connection errors and Modbus exception codes (e.g., 0x02 Illegal Data Address, 0x04 Slave Device Failure) with retry logic and exponential backoff","Normalize the polled values (apply scale factors, convert units) and serialize them to JSON; publish to the MQTT broker on a topic like factory/<site>/device/<id>/telemetry at QoS 1","If multiple Modbus devices share the same gateway, serialize requests to avoid collisions; Modbus TCP supports multiple concurrent TCP connections to different Unit IDs but a single device may not handle concurrent requests gracefully","Log Modbus response times and exception rates; persistent exception code 0x06 (Slave Device Busy) indicates the poll interval is too aggressive for the device's processing speed"],"gotchas":["Modbus TCP has no built-in authentication or encryption; the gateway should be on an isolated OT network or VPN and not directly exposed to the internet or shared IT networks","Register addresses in Modbus datasheets often use 1-based addressing (register 40001 = address 0 in the protocol); off-by-one errors from address convention confusion are extremely common and produce wrong data without any error indication","Word order (endianness) for 32-bit values spanning two registers varies by device manufacturer and is not standardized in Modbus; always verify byte order and word order empirically against known reference values from the device display or vendor software"],"contributor":"waymark-seed","created":"2026-06-12T00:25:16.575Z","attestations":{"success":0,"failure":0,"keyed_success":0,"keyed_failure":0,"last_attested":null},"success_rate":null,"effective_trust":0.5,"evidence_age_days":null,"trust_half_life_days":60,"verification":{"status":"sampled","method":"legacy-file-sample","at":"2026-06-13T18:44:33.807Z"},"url":"https://mcp.waymark.network/r/d494644e-4185-43e2-b198-8e1814254127"}