The Quadlet units under systemd
IoT's SQLite unit was run. The PostgreSQL one was generated from the Gateway's rootless-tested units and not started. A real Pi under systemd as root: not yet.
Entities, automations, helpers, scripts, the logbook, dashboards, notifications and MCP, on MQTT with discovery, plus every industrial driver HotLoop has. Written from scratch in Go, one static binary. It's the box for your garage, your greenhouse, your small shop, and the used PLC you bought off eBay because you couldn't help yourself.
The image is ghcr.io/hotloop-io/hotloop-iot:4.18.10 for amd64, arm64 and arm/v7, about 29 MB on arm, and it pulls
with no login. The chart is hotloop-iot from https://hotloop.io/hotloop. MQTT
discovery was the condition for shipping it, and it's in: IoT finds your Shelly, ESPHome, Tasmota and
Zigbee2MQTT gear by itself instead of making you type topics.
A tag is what a driver talks about: a register, a NodeId, a DB offset. An entity is what people talk
about: the zone 1 temperature, the conveyor run switch. IoT puts every signal behind an entity whose id
never changes. Somebody deletes the tag and re-imports it during a PLC change? The entity comes back with
its id, so the rule that says sensor.oven_temperature keeps working instead of quietly dying.
Every line is ours, written in Go, for OT. Nothing embedded, bridged or forked, so when something breaks at 3am there's one codebase to read and nobody else's bug to wait on. Every command goes through the one write gate, and a failed read is bad quality, never a zero.
Edge is IoT plus the machine layer. The Gateway is everything plus fleet, multi-site and reports. The Edge Relay is the headless one. One codebase, one tag, four images, released together, so a fix in IoT is a fix in all of them the same day.
Its database is SQLite or PostgreSQL, picked by a setting, in the same image. SQLite for the Pi on the shelf with no second container, PostgreSQL when it grows up. IoT keeps 30 days of history by default, because Pi disks are small. Moving up to Edge or the Gateway keeps your data and your config, and it has been run on the Quadlet units, so starting small doesn't paint you into a corner.
"In 4.18.10" means it ships in the published release, and you can run it tonight. "Works on paper" means the path exists and nobody has pointed it at the real thing yet. "Being built" means somebody is writing it right now. "Not built yet" means exactly that, and no amount of squinting turns it into a feature.
Every tag gets an entity with an id that never changes, on one ISA-95 tree. A motor is one entity built from the tags it really is, so rules and agents talk about the pump, not register 40001.
Eleven trigger types, entity state and the sun included, compiled when you save. A broken rule dies in the editor, not at 3am halfway through a batch.
Condition, wait and stop steps inside a sequence, and forSec on a state trigger. "The pump has been on for five minutes" is one trigger, not a timer hack.
The values the plant's people own, like today's batch target or which shift is on: toggles, numbers, selects, text, counters, timers and schedules. Kept across restarts, never clamped.
State changes, writes, alarms, rule runs and config changes on one timeline, for the plant, one area or one entity. "What happened right before?" is one list, not five screens.
Write the CIP cycle once, name it, run it from a rule, a screen, MCP or its own entity. A dry run goes through the real gate, so you see the refusal before anything moves.
Grade A's setpoints off the laminated sheet and into the plant in one go: checked whole, refused whole, written in order and read back from the device.
Write a rule once with blanks and fill it in per pump. Each rule keeps the blueprint version it was made from, so one edit never quietly changes forty rules.
A card builder with drag and drop: gauges, numbers, trends, entity lists, write buttons, script and recipe buttons, alarm lists, text, cameras and a floor plan. Give a dashboard to the roles that need it, or bind it to one physical screen. One layout folds from twelve columns on a panel PC to one on a phone, so nobody ever builds the phone version. A card commands nothing itself, so a button still meets the write gate.
rtn-unack included, so a trip that fixed itself is still there at shift change. Shelving ends, and unshelve brings the alarm back in the state it's really in.
ntfy, Gotify, Discord (a webhook, or a bot), webhooks and email. Press Acknowledge on an ntfy push or in the Discord bot and the alarm is acknowledged, signed and single use. Gotify and the Discord webhook are one way. Discord has only met a stand-in, not the real thing.
An agent can read the whole plant and touch only what you armed, through the write gate, and never without a stated reason, which goes in the system log next to the write.
Plain topics with JSON paths, Sparkplug B, and an optional broker in the same process, so one box can be the whole install.
Sunrise, sunset, dawn, dusk and the sun's height and bearing, worked out on the box from the site's latitude and longitude, plus a sun trigger with an offset. A site whose uplink died three weeks ago still turns the yard lights on at dusk.
ESPHome, Zigbee2MQTT, Tasmota and Shelly Gen2 and later show up on their own, reading, on the embedded broker or any other. Nothing is armed until a person accepts the device and arms each point, so a device announcing itself never earns the right to flip a relay. Proven against recordings of real devices, not yet a bench of them.
mDNS and SSDP are overheard, and DHCP is heard if the deployment allows it. Finds land next to the MQTT devices with what they are and how HotLoop could talk to them. Probing stays off until a network is named, because a port sweep has knocked over PLCs. Nothing is added by itself.
A twelve dollar plug's login can't publish to the boiler's command topic. Logins made in HotLoop carry publish and subscribe rules from a profile, checked on every publish, subscription and outgoing message. Logins from HOTLOOP_BROKER_USERS are unrestricted, as before.
Every reading also goes to the plant's own database: PostgreSQL and TimescaleDB, SQL Server, InfluxDB 2 and 3, MySQL and MariaDB. Same readings, same deadband, same quality. Polling never waits for a target, and one that falls behind catches up from HotLoop's own history.
The database is a setting. A Pi can run any product on a SQLite file with no second container and no 300 MB database image on the SD card. Moving between databases is a backup and a restore.
Quadlet boxes follow the stable tag and update themselves, and an update that can't pass its healthcheck is rolled back instead of reported as a success. On Helm you run the upgrade. Rolling back is only safe because migrations only add.
OPC UA, Modbus, MQTT and Sparkplug B, EtherNet/IP, S7comm, MTConnect, HTTP and UniFi. Protocols don't split the products, so nobody runs the Gateway just to reach one PLC.
Devices, ports, PoE, WAN failover and clients as tags, and a quiet PLC tells you which switch port it's on. WAN health comes from the console's own checks, so a backup link that's been dead for two days reads dead. Read on two real consoles, though a PoE draw above zero has not been seen yet. Nothing writes to a console yet.
An overview with the WAN strip, a topology map that zooms and pinches and is laid out the same way every time, switch faceplates with port traffic traces, clients, networks and WiFi, one button that makes the usual alarms, and the console's event stream so a switch dropping off lands in the logbook in seconds. An agent can ask over MCP for the topology and the latest events. Proven against a lab controller, with touch emulated, and not yet looked at on real gear.
Writes through the gate, starting with the locate LED. Then Protect, Access and PDUs, each only after it has run on real gear. Nothing writes to a console today.
Pure Go over the database connection, in IoT, Edge and the Gateway. It's also how you move between them, so it has to work every time.
One chart repository holds all four charts, so adding it once is enough. Call the release
hotloop whichever product it is: the release name is what the database volume, the Secrets
and the Service are named after, and keeping it is what lets a site move up a product later.
helm repo add hotloop https://hotloop.io/hotloop
helm repo update
helm install hotloop hotloop/hotloop-iot --version 4.18.10 \
--namespace hotloop --create-namespace
The chart runs PostgreSQL 16 by default. database.type takes postgresql or
sqlite, and asking the IoT chart for timescaledb fails the install, because
IoT doesn't offer it. SQLite means no database container at all, which is what a Pi wants.
For a Pi or a small PC outside any cluster. The IoT units are under deploy/quadlet/iot/ in
the hotloop repository, and deploy/quadlet/iot/sqlite/ is the same thing with the
database as a file. That repository is private for now, so the
Quadlet install guide is where to read how they
work. They need Podman 5.0 or newer, so a Pi wants Raspberry Pi OS Trixie or newer, because Bookworm ships 4.3, which has no Quadlet at all.
The app follows :stable, and a release that can't start is rolled back on its own. Put the
database on a USB SSD and not the SD card, because history writes all day and SD cards die of exactly that.
Open http://localhost:8080 once it's up, sign in, add a device. Then notice you can't write to
anything. That's on purpose: every tag starts read-only and gets armed one at a time.
IoT's SQLite unit was run. The PostgreSQL one was generated from the Gateway's rootless-tested units and not started. A real Pi under systemd as root: not yet.
MQTT discovery is proven against recordings of real installs, not against devices on a bench. ESPHome's mqtt: component doesn't build for a host, so there is no live ESPHome in the tests.
The arm/v7 image is built and published. It hasn't met a Pi 3 under load yet.
IoT's SQLite unit was run. The PostgreSQL one was generated from the Gateway's, whose units were run rootless under systemd, and checked against them, but it was not started. A real Pi under systemd as root: not yet.
IoT is under the HotLoop Business Source License 1.1, like everything else HotLoop makes. Home and lab use is free. Business use is free through EmberNET. No tiers, no key, and no email six months in asking you to upgrade.