Historian
TimescaleDB, promoted to a hypertable when the extension is there and falling back to native range partitioning when it is not. Per-tag deadband filtering, so a sensor jittering in its last bit does not write a row every scan forever.
It polls real equipment over real protocols, keeps what it reads, alarms on it, automates against it, and exposes the whole plant to agents over MCP. One static Go binary, no sidecar, running as a non-root user with every capability dropped.
Version 4.13.0 is merged, and the code is moving into this org. Nothing here is downloadable yet, and the release notes say exactly which versions have and have not been tagged.
From the UI, the API, an automation, or an agent. Policy lives in that one place rather than being re-implemented at each call site, where one of them would eventually be forgotten.
safety.allowWrites is off by default, and has been since 4.4.0.
safety.allowMcpWrites is a narrowing of the master switch, not a way around it.
values.write for a logged-in user, which a viewer does not have, or the MCP write setting for an agent.
Tags are read-only until somebody decides otherwise, one at a time. A browse import never arms anything.
It is rejected, not clamped, because sending 400 when someone asked for 500 is quietly doing something else.
Before the value reaches the wire, including every refusal, with the actor and the source.
An MCP client gets no special path. write_tag hits the same gate an operator does, and it
requires a stated reason that is recorded next to the write, because an audit row nobody can interpret six
months later is barely better than none.
13 tools and 4 resources, over streamable HTTP and over stdio, so an agent can read the plant and, only through the gate, act on it. There is also an outbound client, so a rule can call a tool on another system.
The Sites screen uses the same mechanism. Point one gateway at the others as outbound MCP servers and it asks each of them the question it would answer itself. A site that does not answer is shown as unreachable, with the reason, and is left out of the roll-up, because counting a plant you cannot reach as zero alarms would be the worst possible default.
Every reading carries good, uncertain, or bad. A driver that cannot read a point still emits a reading, marked bad, because silence looks identical to a value that has not changed.
Alarm evaluation holds its previous state on a bad reading rather than evaluating it. A sensor that fails to zero would otherwise trip every low alarm on the unit and look like a process event, when it is an instrument problem.
Prefer this one when a device offers a choice. It browses, it is properly secured, and it subscribes.
The 1979 workhorse. PLCs, VFDs, power meters, RTUs, and the fallback of every gateway that has nothing better.
Plain MQTT, or Sparkplug B as a full primary host application.
Allen-Bradley ControlLogix, CompactLogix, and Micro820. Tags have names, so the controller can be asked what it holds.
Siemens S7-300, S7-400, S7-1200, and S7-1500, over ISO-on-TCP by rack and slot.
Read-only machine tool telemetry. There is no command channel in MTConnect, and this driver does not pretend otherwise.
The catch-all, for energy meters, environmental sensors, OEM controllers, and the REST side of a gateway that speaks something proprietary underneath.
Their decoding is tested thoroughly, but tested decoding is not the same as a value that came off a real controller. If you are the first to point either at real hardware, treat it as commissioning and check a known value before you trust a screen.
TimescaleDB, promoted to a hypertable when the extension is there and falling back to native range partitioning when it is not. Per-tag deadband filtering, so a sensor jittering in its last bit does not write a row every scan forever.
ISA-18.2, including rtn-unack for an alarm that cleared before anybody saw it. Acknowledgement and return-to-normal are independent axes, so a transient trip at 03:00 is still on the list when the morning shift arrives.
Nine trigger types, a sandboxed condition, and actions. Conditions are compiled when a rule is saved, so a broken rule is caught in the editor and not at 3am.
The screen that gets left on a wall. Pinned tags are gauges with their alarm limits marked where they fall, layout stored with the plant so the panel PC and the laptop show the same board.
Alarm notifications by webhook or email, so a 03:00 alarm can reach a phone. It composes with whatever paging service you already use, and off by default.
Read-only, so a third-party client can browse and read the Gateway's tags. Secure channels, the same users as the web login, and no write handler at all.
A second, lighter binary with no database, about 16.9 MB against the Gateway's 33.4 MB, that polls and forwards over Sparkplug B. Fleet management tracks and commands registered relays.
An optional in-process MQTT broker, so a single-box install can be its own Sparkplug hub. There is no per-topic access control by design, so use a dedicated broker at scale.
A logical snapshot taken in pure Go over the existing connection, with a restore that refuses to touch a database that already has data.
The Gateway is source-available under the HotLoop Community License, which is not an OSI open source license. Individual, home, hobbyist, nonprofit, and educational use is free. Any business or for-profit use goes through Embernet, which provides the support and the warranty.