myHAB documentation
My Home Automation Backend — a self-hosted platform for controlling, monitoring and automating a real house.
myHAB is a full-stack home automation system: a JVM backend that talks to your devices over MQTT, a PostgreSQL database that remembers everything they ever reported, and a Vue 3 PWA that lets you drive the lot from a phone, a wall tablet or a desktop.
The fastest way to understand the product is to open the live demo and click around — a fictional seven-zone house with simulated controllers, no signup. Then come back for Installation.
What myHAB is
Most home automation software models devices: a light, a switch, a thermostat. myHAB models the installation. A light is a peripheral, wired by a cable to a numbered port on a physical controller, mounted in a rack, serving one or more zones. That extra structure is what makes it possible to print a QR label for a cable, scan it in the attic six months later, and land on the screen that tells you what it feeds.
It was written for, and is still run in, a real house — a mixed installation of ESP32 boards, MegaD Ethernet I/O controllers, a solar inverter, a ground-source heat pump, irrigation, gates and cameras. Everything in it exists because something in that house needed it.
Who it is for
A good fit if…
- Your house is wired, not just full of plug-in smart bulbs
- You want commands to work when the internet is down
- You care about energy data and want it kept, not sampled and thrown away
- You are comfortable running Docker, PostgreSQL and an MQTT broker
- You would rather write six lines of Groovy than click through a rule builder
Probably not if…
- You want a one-click appliance with an app store of integrations
- Your devices are all Zigbee/Z-Wave and cloud-paired — there is no built-in radio stack
- You need multi-tenant isolation; myHAB assumes one household
- You are not willing to expose anything to a reverse proxy you maintain yourself
Core concepts
Everything in the UI maps onto one of these. They are worth reading once.
| Concept | What it is |
|---|---|
| Zone | A physical place — a room, a floor, the terrace, the whole house. Zones nest, so “turn off the ground floor” reaches everything inside it. |
| Layer | A logical grouping that cuts across zones — electrical, network, heating. Used for filtering and for cable documentation. |
| Device | A physical controller: an ESP32, a MegaD-2561, or a virtual device standing in for a cloud service (the weather station, the inverter, the mower). |
| DevicePort | One numbered I/O line on a device. Ports carry a type (relay, sensor, …), a state and a last value, and are the unit that time-series data is stored against. |
| DevicePeripheral | The thing a human cares about — “Terrace light”, “Water pump”, “Small gate”. A peripheral is connected to one or more ports, and belongs to zones. |
| Cable | A documented physical run between a port and a peripheral, optionally via a patch panel. Printable as a labelled QR tag. |
| Rack / PatchPanel | Where the controllers live and where the cables terminate. Pure documentation, but it is the documentation you want at 11pm. |
| Scenario | A short Groovy script executed by the DSL engine. Can switch things, pause, query the weather, command the mower. |
| Job | A schedulable unit — a cron trigger, an event trigger, or both — that runs a scenario. Jobs can be marked as favourites and triggered by hand. |
| EventDefinition / EventSubscription | Named event topics (EVT_LIGHT, EVT_GATE, …) and who listens to them. This is the seam scenarios and integrations hook into. |
| Configuration | A key/value sidecar attachable to almost any entity — auto-off timeouts, voice aliases, device credentials, API endpoints. |
| DashboardScreen | A floor plan (or any background image) with live widgets positioned on it. Rendered at /wui. |
| SharedWidget | A tokenised public link that operates exactly one peripheral, a limited number of times. |
| User / Role | Accounts with ROLE_USER, ROLE_ADMIN, ROLE_SUPER_ADMIN. Roles gate both the UI and the API. |
How a command actually travels
Understanding this one path explains most of the system's behaviour, including why a control can look "stuck".
You tap a light in the UI
↓ GraphQL mutation (or an event published by a scenario / voice / Telegram / shared link)
UIMessageService.handleSwitchEvent
↓ resolves PERIPHERAL → its connected PORTs (recursively for a ZONE)
PowerService
↓ publishes the command on MQTT
Broker → the device
↓ the device applies it and echoes its new state back
MqttTopicService
↓ writes the port value + an event_log row
WebSocket (STOMP) → every open client updatesmyHAB does not optimistically flip a control and hope. The UI updates when the device confirms. That is why an unreachable controller shows a control that does not move — and why the demo needs a simulator answering the broker for anything to appear to work at all.
Ways to control it
Web & PWA
Vue 3 + Quasar, installable from the browser, works on phone, tablet and desktop. The primary interface.
Floor-plan screens
Full-screen live plans at /wui — ideal for a wall-mounted tablet.
Voice
An LLM agent grounded in your real catalogue. In the browser, or hands-free from the Android client.
Telegram
A role-aware bot for status, switching, gates and notifications when you are away from the app.
Shared links
Single-peripheral, time-boxed, use-limited public URLs for guests and trades.
GraphQL API
Everything the UI can do, scriptable. Plus REST for the public share pages and MQTT for devices.
What ships enabled, and what does not
myHAB is a product, not one household's configuration. Anything tied to hardware you may not own is
off by default and enabled per installation. Defaults in the repository are neutral:
empty, localhost, or example.com.
| Subsystem | Default | Notes |
|---|---|---|
| MQTT device control (ESP32, MegaD) | on | The core of the system. |
| Device state sync, port value sync, config sync, auto-off | on | Housekeeping jobs. |
| Weather sync (Open-Meteo) | on | No API key needed; set your location. |
| NIBE heat pump sync + token refresh | on | Enabled in defaults but inert without credentials. |
| Statistics rollups, event log reader, heating control | off | Turn on per installation. |
| Huawei solar sync | off | Needs FusionSolar credentials. |
| Navimow mower sync + token refresh | off | Needs the Segway cloud OAuth flow. |
| Voice assistant | off | feature.voice.enabled; needs an LLM API key. |
| Neural text-to-speech | off | Needs a Google Cloud service account. |
| Telegram bot | off | myhab.telegram.enabled. |
| Web push notifications | off | Needs VAPID keys. |
Where to go next
Installation →
Docker Compose, from source, prerequisites and first boot.
Configuration →
Environment variables, the git-backed config store, job intervals.
Feature reference →
Every screen and what it does, with screenshots.
Architecture →
Modules, data flow, domain model, the event system.
Integrations →
MQTT topic contracts and per-vendor setup.
API reference →
GraphQL, REST, WebSocket and MQTT surfaces.