DeviceChain
Download
Open IoT platform

Query the fleet. Command the device.

Ingest, detect and react across every device you own — self-hosted, no per-device metering, Apache-2.0 end to end.

The path

Packet in. Action out.

A device speaks MQTT, Sparkplug B or LwM2M over CoAP/DTLS. DeviceChain decodes it, resolves which device it came from, records the event, updates that device's live state, evaluates it against your rules, and acts on the result. One path, and no glue code between the stages.

Edge & ingest

Golden MQTT and HTTP, a stateful Sparkplug B host application, and an LwM2M terminator. MQTT, Sparkplug and LwM2M all assert device presence rather than inferring it from silence. What each transport carries, and what it does not, is set out in the transport matrix.

Detect

Keyed streaming CEL predicates over the resolved event stream, scoped to the devices you choose. Deterministic by construction.

React

Raise an alarm, send a command, or hand the event to an outbound connector — webhook, MQTT, Kafka, SNS or SQS.

Command

Persistent two-way dispatch against typed command definitions declared on the device profile, with delivery state you can query.

Device model

A device is a typed object, not a row.

What a device can measure, report and be commanded to do lives in a device profile — a versioned capability aggregate, separate from the device type that references it. Change a profile and you publish a new version; devices are not silently redefined underneath you.

Devices relate to customers, areas, assets and to each other through one typed relationship graph rather than a fixed hierarchy, so the model bends to how your fleet is actually organized.

Device profiles
Versioned metrics, attributes and typed command definitions. Published, not edited in place.
Relationship graph
Typed edges between any entities, with faceted classification instead of one rigid tree.
Dynamic groups
A CEL selector over entity attributes, resolved as an indexed query — membership follows the data.
Customers, areas, assets
Real entities, not examples — areas carry polygon boundaries and nest, assets are assigned to devices as a tracked relationship, and telemetry is anchored to that context when it is written.
Credentials, and replacement
Identity is the stable token; credentials are separate, rotatable material. Swapping failed hardware is one operation that retires every enabled credential with it.
Live state
Last-known-state per device with authoritative presence — asserted by the transport where it can be, inferred from activity where it cannot. No per-device metering.
Detect

Test the rule before the fleet does.

Automation is only trustworthy if it behaves in production the way it behaved when you wrote it. Every rule — however it was authored — lowers to one deterministic compiler and one engine, so the same events always produce the same alarms.

That property is what makes the preview meaningful: you can replay real history through a rule and watch what it would have done, before it governs anything.

Author three ways
A typed form on the profile, a visual automation canvas, or by describing the rule in plain language.
Alarms as state
Alarm objects integrate level state over time rather than firing on every matching event.
Eight kinds of rule
Thresholds, rates of change, repetition, duration, absence, aggregates, correlation and connectivity — so "tell me when a device stops reporting" is a rule kind, not a workaround.
Geofences
Draw them in the console or send polygons over the API, holes and all. Containment is callable from any rule, and every fence set is archived so a replay answers with the fences that were live then.
Scoped, not global
Rules are authored on a device profile and can be narrowed to a dynamic group, pinned to a published version of it; membership is stamped at resolution time.
Authoring

Compiled, not guessed.

Describe what you want in plain language and DeviceChain drafts a candidate rule — then runs it through the exact same compiler as every hand-authored one. If it does not compile, it does not ship. AI proposes; the compiler disposes.

Nothing generated sits in the path that has to stay reproducible, and the feature is opt-in per tenant: the operator registers the model provider and enables external routing tenant by tenant — until then the path is unavailable rather than degraded — or you never turn it on at all.

Dashboards

Dashboards that ship with a version number.

A dashboard is a tenant resource with a draft, a published version and a rollback — not a document someone edited at 2am. Build one against synthetic data before a single device exists, then point the same layout at a live fleet.

Embed them in your own application through the widget runtime, or hand people the standalone viewer with its own login and nothing else attached.

Your data

Point your BI tool at it. That is the integration.

Telemetry lands in TimescaleDB and stays queryable as SQL. A governed analytics schema exposes per-relation views with a per-tenant read role, so Metabase, Grafana, Power BI, a notebook or plain psql connect straight to it. No export job, no second store to keep in sync, nothing extra to license.

Tenant isolation is enforced inside the database rather than by the application in front of it — grants plus a tenant predicate keyed on the connecting role — because a BI tool arrives over the Postgres wire and never passes through our API at all.

Read-only by construction
A per-tenant role with select on its own views and nothing else. Opt-in per instance.
Or use the API
GraphQL for applications, SQL for analysts, and the same rows underneath both.
Interfaces

One API, and a door built for agents.

The platform is addressed through per-area GraphQL schemas behind one authenticated surface, with published client SDKs for TypeScript and C# — the latter built to stay usable under AOT, so it works inside Unity as well as on a server.

There is also a read-only Model Context Protocol surface, so an AI agent can inspect devices, state, telemetry, alarms and commands. It carries the caller's own token rather than a service account: an agent can never see more than the person operating it.

GraphQL
Per-area schemas behind one authenticated surface.
SDKs
TypeScript and C#/.NET, plus a Unity package you build from source.
MCP
OAuth 2.1 resource server, read-only in 1.0, scoped to the user's own tenant access.
Run it yourself

No Redis. No Zookeeper. No Elasticsearch.

It runs on PostgreSQL and NATS — TimescaleDB for telemetry, and NATS for both messaging and the coordination that usually drags a cache into the diagram. Run it on your own cluster with a Helm chart and a Kubernetes operator, or bring the whole thing up on a laptop. Multi-tenancy is enforced in storage and messaging, not by giving every tenant its own pods.

Device inventory, live device state, two-way command dispatch and hard tenant isolation are defaults rather than premium SKUs — Apache-2.0, no open-core split, no per-device metering.

Monitoring comes up with it: a bootstrap installs Prometheus, Grafana and the alert rules for the platform's own signals, so the first thing you see is whether it is healthy. Disaster recovery and the high-availability behaviour are drilled against a live cluster rather than described — including a restore that has to decrypt real secrets on the other side to count as passing.

Also included

The unglamorous half.

The parts nobody puts on a homepage, which are the parts you need in the second month.

Notifications

Per-tenant policy, SMTP and webhook delivery, and an escalation scheduler that survives failover.

Outbound connectors

A dedicated egress service publishing to MQTT, Kafka, SNS and SQS.

Egress boundary

Webhooks, SMTP relays and connector calls are refused at the dial for loopback, private, carrier-NAT, link-local and cloud-metadata addresses. A refusal is final rather than retried, and an operator re-permits a specific destination per tenant.

Audit journal

Every entity change is journaled. Deleting a tenant destroys the people in it and keeps the record that it happened.

Governance

Per-tenant ingest and egress limits with a platform ceiling — missing or zero means the default, never unlimited.

Data lifecycle

TimescaleDB hypertables, a retention reconciler and continuous aggregates for rollups.

Tenant deletion

Deleting a tenant erases its data — database, telemetry, broker, object store, key-value state and the running rule engine — and records what each one did.

Secrets

An envelope-encrypted store; credentials are referenced by handle and never returned once written.

White-labeling

Per-tenant branding that cascades tenant to operator to platform floor.

Device simulation

Drive realistic fleets without hardware — for demos, for load, and for building dashboards early.

Edge agent

A small agent that buffers durably through a network outage and replays when the link returns — exactly-once for JSON payloads, at-least-once for anything else.

Start with the docs.

Bring up a full instance locally, register a device, send it a command and watch a rule fire — before you decide whether any of this belongs in your stack.

DeviceChain is pre-1.0 and in active development. The capabilities on this page are built and exercised in CI, and the disaster-recovery and high-availability behaviour has been drilled against a live cluster rather than assumed. What remains before 1.0 is documentation, a showcase deployment, and the hardening that only comes from running somewhere that is not our own machine. Interfaces may still change until that release — which is why we would rather hear a rough report now than a polished one after they are frozen. Tell us what broke.