Building automation · IoT
A building automation platform where a device contract is defined once
A KNX hardware manufacturer needed a software platform to control its own devices and any third-party KNX device. We defined the architecture and built the logic engine, the visual automation editor and the tablet client.
- Period
- 2025 – present
- What we delivered
- System architecture, logic execution engine, shared type library, admin panel, tablet client
- Setting
- Two-engineer core team alongside the client
Client and project names are withheld under confidentiality. Sector, scale and outcomes are reported as delivered.
One contract
Node schema shared by backend, admin panel and mobile
4 surfaces
Logic engine, admin panel, API and tablet client
Node graph
Automation composed visually, not hand-written
Android · iOS · web
Single React Native codebase
Context
The client manufactures KNX-based building automation hardware. They needed a software platform to control and monitor its own devices first, and subsequently any third-party device speaking the KNX protocol.
Comparable to Home Assistant in scope, but differentiated by out-of-the-box support for KNX devices, requiring no integration work from the installer. Tablet-first, with mobile and web as follow-on surfaces.
A three-person core team: two senior engineers owning architecture and implementation, plus a designer. We took one of those two seats and owned the overall architecture.
Problem
A platform like this has a structural trap. The definition of a device node — its metadata, its connection handles, its validation rules — is needed by the backend engine that executes it, the admin panel where installers compose it, and the mobile client that displays it. Define it three times and the three definitions drift. Then an installer composes an automation that the engine refuses to execute, and nobody can say which of the three was wrong.
The second constraint: installers are not programmers. Automation logic had to be composable without writing rules by hand.
Approach
One typed contract, consumed identically everywhere
We designed the platform’s shared contract library: a strictly typed TypeScript package defining every node component, its metadata schema, its connection-handle model and runtime validation via TypeBox. It is consumed identically by the backend engine, the admin panel and the mobile client — so a node’s contract is defined exactly once across the entire platform, and a change to it cannot silently fail to reach one of the three.
The logic execution engine
The logic execution engine is the platform’s core: a TypeScript/Fastify service bridging a NATS message bus and Socket.IO clients, routing device events through a graph of composable logic nodes — boolean operators, delay, clock, switch, toggle, dimmer, thermostat, KNX device nodes and VoIP/SIP nodes.
It is built on an abstract node contract, so new node types can be added without modifying the engine. That is the difference between a platform and a product: the engine does not need to know what a thermostat is.
A visual editor instead of hand-written rules
We built the automation editor in the Next.js admin panel on React Flow, letting installers compose logic as a node graph rather than writing rules, with Redux Toolkit and redux-saga managing state and full internationalisation.
The tablet client
The tablet-first control application is built in React Native / Expo, sharing the same typed contracts and communicating with the logic engine over Socket.IO in real time — targeting Android, iOS and web from a single codebase.
SIP/VoIP intercom
We designed and built the intercom subsystem end to end as a proof of concept — the TypeScript/Node backend and the demonstration Android and iOS client applications. Integration points are already present in the logic engine as SipNode and VoipNode; full platform integration remains pending.
Engineering standards
Authored a custom shared ESLint rule package published for the team via semantic-release, plus Jest test suites, strict TypeScript configuration, Prettier, Husky pre-commit hooks and Bitbucket Pipelines CI.
Outcome
- Delivered across every layer, language and architectural decision in the platform — the TypeScript logic engine and shared libraries, the Next.js admin panel, the dotnet core API and the React Native client.
- A node’s definition lives in exactly one place. Adding a node type is a change to shared contracts and a new node implementation, not a coordinated edit across three codebases.
- Installers compose automation visually, with validation derived from the same schema the engine executes against.
- The engagement continued from a continuous 12-month build into ongoing on-demand work.
Related work
Enterprise retail e-commerce
Taking an enterprise commerce platform from 1,000 daily errors to double digits
A composable-commerce platform for a large optical retail chain was logging around a thousand errors a day, timing out on discounts and charging the wrong amounts. We worked the defect classes down in order.
~1,000 → double digitsError log entries per day
Read the case study →
Regulated consumer products · D2C
A regulated direct-to-consumer storefront, live and transacting in 45 days
We won the engagement on a commitment competitors would not make — a custom storefront taking live card payments within 45 days, under a 100% uptime guarantee. Both were met.
45 daysFrom zero to live card payments
Read the case study →
Lead-generation SaaS
Removing a SaaS platform's scalability ceiling
Ten concurrent users in the editor degraded the entire product to multi-minute waits. We isolated that workload first, then decomposed the rest — and the customer base grew sixfold without the architecture becoming the limit.
300 → ~2,000Customer accounts during the engagement
Read the case study →