A Home Assistant add-on for local control of Ambientika ventilation devices with MQTT integration.
Based on ambientika-local-control by sragas.
- Home Assistant add-on — easy installation through the add-on store
- MQTT integration — full MQTT support with auto-discovery
- Multi-zone support — control master/slave device pairs across zones
- Cloud sync — optional parallel forwarding to the Ambientika cloud so the official app keeps working
- Local control — no cloud dependency required for Home Assistant control
- Command persistence — reliable operating mode changes queued until acknowledged
- Add this repository to your Home Assistant add-on store
- Install the "Ambientika Local Control" add-on
- Configure MQTT settings
- Configure device routing (BLE provisioning or static route — see below)
- Start the add-on
Devices need to know your Home Assistant IP so they connect to the add-on instead of the Ambientika cloud. There are two ways to achieve this.
Each device is configured once over Bluetooth to connect directly to your HA IP. Write the following three values to the device's WiFi characteristic (Service 0000a002-*, Characteristic 0000c302-*):
| Value | Example |
|---|---|
H_<HA-IP>:11000 |
H_192.168.1.10:11000 |
S_<wifi-ssid> |
S_MyNetwork |
P_<wifi-password> |
P_mypassword |
BLE apps: LightBlue Explorer (iOS) or BLE Tester (Android). (nRF Connect can fail to trigger the device's automatic restart after writing — see #28.)
The device appears as VMC_<MAC> in BLE scans. After writing, it restarts and connects to the add-on.
Re-provisioning is only needed if your HA IP changes or a device is factory-reset.
Instead of re-provisioning devices, add a static route in your router that redirects all Ambientika cloud traffic to your HA host:
- Destination:
195.39.253.2/32(current IP forapp.ambientika.eu— the cloud has moved before, so re-check this if the redirect stops working) - Gateway: your HA IP (e.g.
192.168.1.10)
Then add a persistent IP alias on the HA host so it accepts packets addressed to the cloud IP. Add to configuration.yaml:
shell_command:
add_ip_alias: 'ip addr add 195.39.253.2/32 dev end0 || true'
automation:
- alias: "Add IP alias on startup"
trigger:
- platform: homeassistant
event: start
action:
- delay: '00:00:30'
- service: shell_command.add_ip_aliasNote: This method redirects the cloud IP for all devices on your network. BLE provisioning is preferred when possible as it is more targeted and does not require router access.
If you use DNS-based redirection (pointing
app.ambientika.euat your HA IP on your gateway) instead of a static route, and you also enablecloud_sync_enabled, setcloud_hostto the real cloud IP (195.39.253.2) rather than the hostname. Otherwise the add-on would resolveapp.ambientika.euthrough your own redirected DNS and try to relay cloud traffic back to itself.
With cloud_sync_enabled: true the add-on forwards device traffic to the Ambientika cloud in parallel. This allows the official Ambientika app to continue working alongside Home Assistant — devices appear online in both.
Without cloud sync, devices are only accessible via Home Assistant and show as offline in the official app.
For the full binary protocol spec see PROTOCOL.md.
For cloud API and provisioning architecture see CLOUD-INTEGRATION.md.
| Value | Name | Description |
|---|---|---|
| 0 | SMART |
Self-managing. Uses indoor/outdoor sensors. Auto-triggers free-cooling (MASTER_SLAVE_FLOW) when indoor > 24°C and outdoor is lower. |
| 1 | AUTO |
Humidity-controlled. Ventilates when humidity exceeds the configured threshold. |
| 2 | MANUAL_HEAT_RECOVERY |
Fixed heat-recovery at a chosen fan speed. All sensors disabled. |
| 3 | NIGHT |
All units at NIGHT fan speed in heat-recovery mode. |
| 4 | AWAY_HOME |
Standby, damper closed. Starts at LOW on humidity > 60%. |
| 5 | SURVEILLANCE |
Standby, damper closed. Expels at configured speed on humidity alarm. |
| 6 | TIMED_EXPULSION |
All units expel at HIGH for 20 minutes, then return to previous mode. |
| 7 | EXPULSION |
Continuous expulsion at chosen speed. |
| 8 | INTAKE |
Continuous intake at chosen speed. |
| 9 | MASTER_SLAVE_FLOW |
Airflow MASTER → SLAVE_OPPOSITE_MASTER. Used to push air into a room. |
| 10 | SLAVE_MASTER_FLOW |
Reverse of MASTER_SLAVE_FLOW. |
| 11 | OFF |
All units off, sensors disabled, damper closed. |
MASTER_SLAVE_FLOWandSLAVE_MASTER_FLOWcan be set manually or triggered automatically by SMART mode's free-cooling logic.
| Value | Name | Description |
|---|---|---|
| 0 | LOW |
Minimum speed |
| 1 | MEDIUM |
Average speed |
| 2 | HIGH |
Maximum speed |
| 3 | NIGHT |
Night-time speed — quieter than LOW. Set automatically by SMART and NIGHT modes. |
| Value | Name | Description |
|---|---|---|
| 0 | MASTER |
Primary device. Receives all commands and propagates to slaves. |
| 1 | SLAVE_EQUAL_MASTER |
Secondary device, same airflow direction as master. |
| 2 | SLAVE_OPPOSITE_MASTER |
Secondary device, opposite airflow direction to master. |
Commands must always be sent to the MASTER device.
| Byte(s) | Content |
|---|---|
| 0–1 | Packet header (0x01 0x00) |
| 2–7 | Serial number (6 bytes, MAC) |
| 8 | Operating mode |
| 9 | Fan speed |
| 10 | Humidity level (threshold setting) |
| 11 | Temperature (°C) |
| 12 | Humidity (%) |
| 13 | Air quality |
| 14 | Humidity alarm (0/1) |
| 15 | Filter status |
| 16 | Night alarm (0/1) |
| 17 | Device role |
| 18 | Last operating mode |
| 19 | Light sensitivity |
| 20 | Signal strength |
Legacy 19-byte variant: devices on older radio/micro firmware (observed on
0.0.11) send a truncated 19-byte status packet — identical to the layout above through byte 18, but without thelightSensitivity/signalStrengthfields. The add-on handles both lengths; on the 19-byte variant,lightSensitivitydefaults toNOT_AVAILABLEandsignalStrengthto0. (#36)
Newer 22-byte variant: devices on radio/micro firmware
1.1.13and later send a 22-byte status packet — identical to the layout above (bytes 0–20) plus one trailing byte whose meaning hasn't been identified yet. The add-on parses it the same way as the 21-byte format and ignores the extra byte. On this firmware, a standalone master with no paired slave reports byte 17 (device role) as0xFF, which falls back toMASTER. (#72)
Device serial numbers are effectively credentials in this ecosystem — the vendor protocol
is unauthenticated, and the add-on's REST/MQTT paths address devices purely by serial. To
avoid leaking them when logs are shared (e.g. pasted into a GitHub issue), serials are
masked in all log output by default, keeping the last 4 hex characters so multiple
devices stay distinguishable (e.g. xxxxxxxx50e0). This covers plain log lines and serials
embedded inside raw packet hex dumps.
Set log_full_serials: true to see full serials in the logs (useful when debugging locally).
Note: this only affects log output. MQTT topic names and REST API paths still address devices by their real serial number — masking log lines doesn't change how the add-on is addressed over the network.
The REST API (rest_api_port, default 3000) is unauthenticated by default and, because the
add-on runs with host_network: true, reachable from anywhere on your LAN — the vendor
device protocol itself has no authentication, and this add-on can only lock down the parts
it controls.
rest_api_bind(default0.0.0.0) — set to127.0.0.1to restrict the API to the HA host itself if you don't need LAN access to it.rest_api_token— when set, every endpoint exceptGET /healthrequires anAuthorization: Bearer <token>header./healthis always left open since the Supervisor watchdog polls it directly with no credentials.enable_debug_endpoints(defaultfalse) — gatesPOST /cloud/send-setup/:serialNumber, a debug endpoint that lets a caller directly reconfigure a device's role/zone/house ID.:serialNumberpath params are validated (12 hex characters) before reaching any handler, and request bodies for/device/operating-modeand/device/weather-updateare validated against the known enum values / sane ranges rather than passed straight into buffer construction.
ambientika/{serialNumber}/setup/set
{"role": "SLAVE_OPPOSITE_MASTER", "zone": 1, "houseId": 12048}
ambientika/{serialNumber}/raw_command/set
02001234567890ab00020200102f0000
Disabled by default — set enable_raw_commands: true to turn it on. Any hex payload
published here is written straight to the device's TCP socket with no validation beyond
hex-format and a 32-byte length limit, bypassing all the modeled/validated command paths.
On a broker with weak or anonymous ACLs (common in home setups), MQTT publish access
becomes unrestricted device control — only enable this if you trust everyone with publish
access to your broker, and prefer requiring broker authentication regardless.
config.yamlversion is the single source of truth —package.jsonhas no version field- Bump
versioninconfig.yaml, commit todev, open PR tomaster - Merging to
masterautomatically creates the GitHub release and triggers Docker builds foramd64andaarch64
Based on the original ambientika-local-control project by sragas.