The public demo
A complete myHAB installation you can break, at demo.myhab.org.
Sign in
These credentials are published on the login page. They protect nothing — treat the demo as a public whiteboard.
What is in it
A fictional house: seven zones and twenty-one peripherals, wired to simulated ESP32 controllers, with enough history seeded that the charts look like a real installation.
- Lighting, sockets, heating and irrigation across ground and upper floors, a terrace, a lawn and a garden.
- Two floor-plan screens with widgets placed on them.
- A scheduled irrigation job in the sprinkler scheduler.
- Scenarios you can read and run.
- Seeded inbox messages for both accounts.
- Cabling, racks and patch panels documented, so the QR-label screens have something to print.
esp_shed — the Shed Light — never answers. It is there so you can see what an
unreachable controller looks like, without it blocking anything you would actually want to try.
The devices are simulated, not faked
A companion process answers MQTT commands as if it were the ESP32 controllers. This is not decoration. myHAB publishes a command and then waits for the device to echo its new state back, and that echo is what updates the database and the UI. With nothing answering the broker, every control in the demo would appear dead.
So what you are exercising is the real pipeline — real MQTT, real event bus, real persistence, real WebSocket fan-out. Only the hardware at the far end is imaginary.
It is shared, and it resets
Every visitor works on the same dataset. There is no per-session isolation: the application has a single datasource, and the MQTT and WebSocket threads carry no tenant context. Real isolation would mean a database per session with a routing datasource, or a container per visitor — neither worth it here.
Instead the sandbox resets, which gets most of the way there for a fraction of the cost:
| Trigger | When |
|---|---|
| Idle | Someone changed something, and nobody has changed anything for about twenty minutes. |
| Manual | The Reset demo button in the banner. |
| Nightly | Once a day, unconditionally. |
In practice the next visitor almost always finds a clean house. The banner says plainly that the data is shared, so nobody is misled.
A reset restores the seed and then shifts every timestamp forward by the age of the seed, so charts always end “now”. The dataset never has to be rebuilt to stay plausible.
What is switched off
The demo must not be able to reach anything real — no production database, no LAN controllers, no third-party clouds.
- Every job that reaches an external system is disabled: Huawei, NIBE, Navimow, weather, the HTTP device sync and the configuration sync.
- Telegram is off.
- The cache runs single-node with multicast disabled.
- The configuration repository is local to the deployment and contains only demo-safe values.
The admin configuration query returns every key to any admin-authenticated caller. The demo's configuration therefore deliberately omits notification tokens, alerting keys and push credentials — each of which degrades cleanly when absent. Nothing secret may ever be added to it.
Things worth trying
As demo
- Switch lights on the dashboard and watch the state come back from the “device”
- Open a floor plan and tap a bulb on the plan itself
- Open the gate card and see the confirmation dialog
- Read the inbox, mute a repeated warning
- Switch the interface to Romanian in Settings
As demo-admin
- Browse Devices → Ports → Peripherals and follow a light back to its controller port
- Open the MQTT explorer and watch the raw monitor while you switch something
- Read a scenario, then run it
- Edit a floor plan and move a widget
- Create a shared link and open it in a private window
- Change an irrigation schedule
Running the same sandbox locally
The demo is not a separate product — it is a Grails environment in the same repository. You can run it on your machine with no Docker and no hardware:
./gradlew demoSeedLocal # (re)build the myhab_demo database — destructive, idempotent
./gradlew demoSim # simulator + embedded MQTT broker on :1883
./gradlew demoRun # the backend, in the `demo` environment
./gradlew serve # Quasar dev server on :10002Then open http://localhost:10002 and sign in with demo / demo.
| Task | Does |
|---|---|
demoSeedLocal | Drops and rebuilds the demo database from the seed SQL. |
demoConfigRepo | Materialises a bare configuration repo from the demo's config seed. |
demoSim | Runs the simulator with an embedded broker, so no Mosquitto install is needed. |
demoRun | Starts the backend in the demo environment. |
demoSim before demoRun.
The application connects to the broker at boot, and the simulator is hosting it. Also note that
demoSeedLocal drops the database and disconnects anything attached — including a
running demoRun. That is deliberate; restart the app afterwards.
Override the database with DEMO_DB, DEMO_DB_USER,
DEMO_DB_PASSWORD, DEMO_DB_HOST and DEMO_DB_PORT.
Two safety properties worth knowing
- The reset refuses to run unless the environment is
demoand a seed schema exists. A normal deployment has neither, so the reset is inert there even if someone misconfigures the environment. - The list of tables to restore is derived from the seed schema at runtime rather than hard-coded, so adding a domain class cannot silently leave a table un-restored.