Integrations
What myHAB talks to, how, and what you have to set up for each.
Supported device models
| Model | Kind | Transport | Default |
|---|---|---|---|
ESP32 | Relay / sensor board | MQTT | on |
MEGAD_2561_RTC | Ethernet I/O controller | MQTT + HTTP | on |
TMEZON_INTERCOM | Door entry system | MQTT | on |
CAM_ONVIF | IP camera | MQTT via an ONVIF bridge | optional |
NIBE_F1145_8_EM | Ground-source heat pump | Cloud REST → MQTT | on |
HUAWEI_SUN2000_12KTL_M2 | Solar inverter | Cloud REST → MQTT | off |
HUAWEI_DONGLE | Inverter comms dongle | Cloud REST → MQTT | off |
ELECTRIC_METER_DTS | DTSU-series smart meter | Cloud REST → MQTT | off |
OPEN_METEO_API | Weather station (virtual) | REST → MQTT | on |
NAVIMOW_SEGWAY | Robotic lawn mower | Cloud REST → MQTT | off |
A polling job publishes what it fetched to the broker; the broker echoes it back through the same
myhab/# subscription, and it is persisted exactly like a physical sensor reading. One
pipeline, one audit path, and cloud data appears in the MQTT explorer next to hardware data.
MQTT topic contracts
Every model declares the topics it listens on and publishes to. The prefix
(myhab by default) comes from mqtt.topic.prefix.
| Model | Inbound (device → myHAB) | Outbound (myHAB → device) |
|---|---|---|
| ESP32 | myhab/<device>/<type>/<port>/statemyhab/<device>/status |
myhab/<device>/<type>/<port>/cmd |
| MegaD | <device>/<port><device>/status |
<device>/cmd |
| NIBE | myhab/<device>/<type>/<param>/value |
same topic (published by the sync job) |
| Inverter | myhab/<device>/inverter/<group>/<param>/value |
same topic |
| Electric meter | myhab/<device>/emeters/<group>/<param>/value |
same topic |
| Weather station | myhab/<device>/sensor/<param>/value |
same topic |
| Navimow | myhab/<device>/mower/<param>/valuemyhab/<device>/mower-status |
same topics |
| ONVIF | onvif2mqtt/<camera>/motion |
— |
| Any source | myhab/<source>/notify — raises an in-app message |
— |
Outbound topics are built from a template, but inbound state topics are matched with
\w-based patterns, and \w excludes -. A hyphenated code
publishes commands happily and then silently drops every echo — the control looks dead, with
nothing in the logs.
The path segments differ per model on purpose — /state, /value,
/mower/, /emeters/, /inverter/ — so the patterns cannot overlap
when they are matched in order against a single wildcard subscription.
ESP32
The workhorse. Any ESP32 firmware that follows the topic contract above works — commands arrive on
.../cmd, and the board is expected to echo its resulting state on .../state.
# myHAB publishes
myhab/esp_terrace/relay/3/cmd → ON
# the board applies it and echoes
myhab/esp_terrace/relay/3/state → {"port":3,"value":"ON"}- Availability is reported on
myhab/<device>/status; a broker last-will message marks a board offline when it drops. - Sensor ports publish numeric values on the same
/stateshape. - With
admin.ports.autoimportenabled, unknown ports create themselves on first message.
MegaD-2561
Multi-port Ethernet I/O controllers. They speak a flatter topic shape
(<device>/<port>) and, unlike the ESP boards, also expose an HTTP interface.
myHAB uses both: MQTT for the fast path, and a periodic HTTP ?cmd=all sweep as ground
truth. The reconciliation job compares what the controller actually reports against what the database
believes, which is what catches a relay that changed state without an echo — and what raises the
“device offline” message when the controller stops answering.
ONVIF cameras
Motion and presence events are bridged onto MQTT by an external ONVIF-to-MQTT gateway, publishing on
onvif2mqtt/<camera>/motion. myHAB treats those as ordinary port values, so they can
trigger scenarios: turn on the drive lights when the gate camera sees movement after dark.
A surveillance UI can be linked from the header via the surveillance.url configuration
key — myHAB does not proxy video itself.
NIBE heat pumps
Tested against the F1145-8 EM; the API is shared across the family.
| Aspect | Detail |
|---|---|
| Transport | The myUplink cloud REST API, polled by nibeInfoSync (300 s by default). |
| Auth | OAuth. nibeTokenRefresh spends the refresh token before the access token expires. |
| Data | All temperature sensors — outdoor, room, supply, return, hot water, brine in/out — plus compressor hours and starts, degree-minutes, alarms, and firmware version. |
| Ports | Auto-created from the parameter list, labelled with the vendor's parameter ids. |
| Enabled | By default, but inert until credentials exist. |
The dashboard widget renders the sensor set plus the heating circuit's supply/return ΔT and the compressor state. Degree-minutes feed the heating automation job.
Huawei solar
| Aspect | Detail |
|---|---|
| Devices | SUN2000 inverter, its communication dongle, and a DTSU666-H smart meter. |
| Transport | The FusionSolar cloud API, polled by huaweiInfoSync (300 s). |
| Inverter data | Instantaneous active power, daily and lifetime yield, efficiency, internal temperature, per-string voltages. |
| Meter data | Per-phase active power (A/B/C), voltages and currents, total import and export, power factor. |
| Enabled | off — turn on quartz.jobs.huaweiInfoSync once configured. |
The dashboard widget derives the flow diagram from these: PV production, house consumption, grid import and grid export, with directional arrows. Longer-range analysis is a Grafana dashboard embedded on the Solar Reports page.
Do not shorten the poll interval below the documented default without checking; the API responds to over-polling by locking the account out for a while.
Weather (Open-Meteo)
| Aspect | Detail |
|---|---|
| Transport | The Open-Meteo public API — no API key required. Polled by meteoStationSync (1800 s). |
| Current | Temperature, precipitation, wind speed, humidity, soil temperature, visibility. |
| Daily | Min/max and apparent temperature, sunrise, sunset, daylight and sunshine duration, rain total, maximum wind. |
| Hourly | Temperature, precipitation probability, wind. |
| Setup | Create a device of model OPEN_METEO_API, set its coordinates, and name the location with ui.meteo.locationName. |
Weather is not just a widget: the sunrise/sunset window backs isDay() and
isNight(), and precipitation backs isRaining() and
rainAmount(minutes) in the scenario DSL. It is also the fallback source for
currentExternTemperature() when no outdoor sensor is available.
Segway Navimow
| Aspect | Detail |
|---|---|
| Transport | Segway's cloud REST API, polled by navimowInfoSync (30 s). |
| Auth | A one-button OAuth flow under Devices → your mower → Connect Navimow account. A popup signs in and stores the token automatically. |
| Token life | Roughly one to two days. navimowTokenRefresh keeps it alive; expiry raises a message naming the exact device that needs re-authorising. |
| Region | Non-EU installs override the API base URL and OAuth client through per-device configuration keys. |
| State | Docked, Mowing, Paused, Returning, Charging, Idle, Error — plus battery level and the cloud's own label. |
| Commands | Start, Pause, Resume, Return to dock, enabled per current state. |
Notifications cover errors and stuck mowers, state transitions, completed runs, low battery or autonomous return, and token expiry. Commands are also callable from scenarios:
mowerCommand([deviceId: 42, action: 'DOCK'])…and by voice — “start mowing”, “trimite mașina la bază”.
Telegram
| Aspect | Detail |
|---|---|
| Setup | Create a bot with BotFather, put its token and channel ids in configuration, and set myhab.telegram.enabled. |
| Linking | A myHAB user must have their Telegram username recorded on their account; unknown senders get nothing. |
| Commands | Hierarchical menus for device status, switching, gate opening (with confirmation) and running scenarios. |
| Authorisation | The same roles as the web UI. Sensitive actions require admin. |
| Notifications | Alerts and events can be pushed to a channel or a direct chat. |
| Audit | Actions go through the normal event path, so they appear in the event log attributed to the Telegram user. |
Web push and alerting
- Web Push — with VAPID keys configured, in-app messages also arrive as browser notifications on subscribed devices. Muted messages are suppressed at the source, so a mute rule silences the push too.
- OpsGenie — optional alert escalation. Its keys are only read when an alert is actually raised, so leaving them out costs nothing.
Grafana
myHAB stores time series in PostgreSQL, so Grafana can query the same database directly. Two places
embed a dashboard back into the UI: the Solar Reports page and the temperature chart card. Configure
grafana.url plus the dashboard (and panel) ids — see
Configuration.
Adding a new integration
The shape is consistent, and the existing cloud integrations are the template:
- Add a value to the device-model enum.
- Declare its topic contract — inbound match patterns and outbound templates — making sure the path segments cannot collide with an existing model's.
- For a cloud service, write a Quartz job that polls it and publishes to the broker rather than writing to the database directly. Persistence, WebSocket fan-out and the audit trail then come for free.
- Add the job's toggle and interval under
quartz.jobs.*, defaulting to off. - Put any credentials in per-device configuration keys, not in code.
- If it needs a dashboard widget, register it with the configuration keys it requires so the UI can hide it when unconfigured.