Architecture poster

A print-ready single-page system diagram

A single-page reference diagram of the OpenSense data flow, drawn in the same Cold Storage Panel aesthetic as the dashboard. Print at A3 landscape; tape it to the rack. Useful when a customer asks "where does my data go" and you want a one-glance answer.

data flowopensense · eu-central
DEVICEEDGEINGEST + RULESSTORAGEOUTBOUNDShelly H&THTTPS (GET/POST)Aqara THZigbee → MQTTEfento NS-TLoRaWAN → TTNDIY ESP32HTTPS or MQTTSClamp meterHTTPSCADDY · TLS 1.3→ /v1/ingest→ /v1/ingest/shelly→ /v1/ingest/lorawan→ MQTT bridge :8883per-device tokenrate limit 60/minpayload sanity→ /app (UI)→ /v1/* (mgmt)→ /v1/reports→ /v1/measurementsINGEST SERVICEJSON validatedevice matchchannel resolvesanity rangeidempotency (24h)dedupe (ts, ch)RULE ENGINErange / deltawindows (rrule)grace periodstate machineevent emitTIMESCALE · MEASUREMENTSraw 13 morollup 5 m 5 yrrollup 1 h 5 yrrollup 1 d foreverLUKS at resthourly backupshetzner falkensteinAUDIT + EVENTSappend-onlySHA-256 chaindaily head pubno UPDATEno DELETEOUTBOUNDTelegramEmailWebhookPDFretry+ digestOK · service nominalWARN · degradedALARM · pagedarrows: data direction · one-waySCH-001 · DATA FLOW · REV B · 2026-05 · NOT TO SCALE · NOT A MARKETING ILLUSTRATION

What each box does

Device. A sensor that emits measurements. We support the four classes shown: Shelly (WiFi), Aqara (Zigbee through a gateway), Efento (LoRaWAN), and a generic DIY ESP32 over either HTTPS or MQTTS. A clamp meter for energy is the fifth (also HTTPS — same wire format as the ESP32).

Edge. Caddy reverse-proxies all customer traffic with TLS 1.3 and per-route rate limits. The edge is the only host that talks to the public internet directly; everything downstream is on localhost.

Ingest service. A Go binary. Validates the payload structure, matches the token to a device, resolves measurement labels to channel ids, runs the sanity-range check, deduplicates, then writes to TimescaleDB. Fast path: a typical ingest completes in 1.4 ms p50.

Rule engine. Reads new measurements off a Postgres listen/notify channel. Holds per-channel rule state in memory (with periodic checkpoints). Emits events on state transitions; events go to the audit log and to the outbound dispatcher.

Storage. TimescaleDB on a dedicated LUKS-encrypted volume. Hypertable chunks are one day each; the 5-min, 1-hr and 1-day continuous aggregates run as Postgres background workers. Backups hourly to a separate volume, weekly off-site.

Audit + events. A separate Postgres table — append-only, hash- chained, daily head published. See audit trail for the cryptographic detail.

Outbound. Telegram, email (via Postmark with EU-only routing for our account), customer webhook, and PDF generation are all served by this one dispatcher. Retries with exponential backoff; respects per-channel digest policies.

What is not drawn

  • The web UI (a separate static SPA served from the same edge).
  • The reports container (Chromium-based, sits next to the dispatcher).
  • The MQTT bridge (drawn implicitly as one of the edge protocols).
  • The CI pipeline and the deploy host.

These are operational details, not data-flow concerns; they belong on a separate diagram which we have not yet drawn. If you need it, ask.

Want it as a PDF?

The SVG above is the source. Right-click → "Save image as…" gives you the SVG. Open in Inkscape or Illustrator; export to PDF at any size. The font (B612 Mono) is open-licensed; embed it freely.