Pin ha-n95-local-control tag v0.1.2 (7bed99cc4c3222bad648efcddcdfed95652277f7). Health bind failure no longer takes down 8007/8005/5223 when OTBR owns 8080.
12 KiB
Deebot N95 Local Control — documentation
Full installation, network, configuration, verification, and troubleshooting information for the Deebot N95 Local Control Home Assistant add-on.
How it works
The add-on replaces the legacy Ecovacs bootstrap and XMPP destinations used by an already-provisioned Deebot N95, then exposes the robot through Home Assistant MQTT discovery.
N95 ── DNS ──> your LAN resolver
N95 ── HTTP 8007 / 8005, XMPP 5223 ──> this add-on ──> MQTT broker ──> Home Assistant
The add-on does not provision a robot and does not run a DNS server. It supports multiple robots; each robot receives its own MQTT client and topic tree after it reaches XMPP READY state and reveals its serial number.
Before you start
You need:
- An already-provisioned Deebot N95 using the captured
wukong/ class155protocol. Other Ecovacs models are not established as compatible. - A stable LAN IPv4 address for the Home Assistant host, reserved in DHCP.
- Control of the DNS resolver supplied to the robot by DHCP.
- TCP
8007,8005, and5223available on the Home Assistant host and reachable from the robot. TCP8080is used for health checks. - A broker reachable from the Home Assistant host and Home Assistant MQTT configured with discovery enabled.
- A correct host clock and IANA timezone.
The robot caches its XMPP address after boot. If the address or listener ports change, update DNS/configuration and reboot the robot; an ordinary reconnect continues to use the cached destination.
Step 1 — reserve the host address and configure DNS
Reserve the Home Assistant host's LAN IPv4 address. Configure the resolver sent to the robot by DHCP with this A record:
lbo.ecouser.net A <HOME_ASSISTANT_LAN_IPV4>
Set the add-on's advertise_ip to the same literal IPv4 address. Do not use
0.0.0.0, a container address, or a hostname. The 155.ecorobot.net XMPP JID
domain does not need a DNS override for the captured firmware.
Step 2 — install and configure
- Add this repository in Home Assistant
(Settings → Add-ons → Add-on Store → ⋮ → Repositories):
https://git.i3omb.com/gronod/ha-gronod-addons - Install Deebot N95 Local Control.
- Enter the reserved host IPv4 under Advertised IP address.
- Select the correct IANA timezone, for example
Europe/London. - Leave advanced listener values unset unless their default ports conflict.
When a Supervisor MQTT service is available, the add-on automatically reads its host, port, TLS flag, username, and password. Every manually supplied MQTT option overrides only that individual discovered field. This permits, for example, using discovered credentials with a manually supplied private CA.
For an external broker with no Supervisor service, set at least mqtt_host and
any required credentials/TLS options.
Step 3 — start and redirect the robot
Start the add-on and inspect its log. Verify the DNS and HTTP endpoints using the checks below, then reboot the robot. The robot should bootstrap through the lookup endpoint, open XMPP to the add-on, and appear as an MQTT vacuum in Home Assistant.
No MQTT connection is expected when the add-on first starts. The bridge creates a broker client only after a robot reaches XMPP READY and identifies itself.
Configuration
Normal setup shows advertise_ip, timezone, and log_level. Select Show
unused optional configuration options to reveal MQTT overrides and advanced
network/protocol controls.
| Option | Default | Environment | Description |
|---|---|---|---|
advertise_ip |
required | ADVERTISE_IP |
Stable, nonzero host IPv4 returned in lookup responses |
timezone |
Etc/UTC |
TZ |
IANA timezone controlling the local offset sent to the robot |
log_level |
info |
LOG_LEVEL |
debug, info, warn, or error |
bind_address |
0.0.0.0 |
BIND_ADDRESS |
Advanced listener bind IP; normally leave unset |
port_lookup |
8007 |
PORT_LOOKUP |
Advanced HTTP POST /lookup.do listener |
port_firmware |
8005 |
PORT_FIRMWARE |
Advanced firmware-check listener; expected to return 404 |
port_xmpp |
5223 |
PORT_XMPP |
Advanced plaintext robot XMPP listener |
health_port |
8080 |
HEALTH_PORT |
Advanced HTTP GET /healthz listener. Bind failure is non-fatal from v0.1.2; robot ports stay up. Pick another port if OTBR already owns 8080. |
mqtt_host |
Supervisor/required | MQTT_HOST |
Broker host without scheme or port; overrides discovery |
mqtt_port |
1883/8883 |
MQTT_PORT |
Broker port; upstream chooses 8883 when TLS is enabled |
mqtt_tls |
false |
MQTT_TLS |
Start the MQTT connection with TLS and hostname verification |
mqtt_ca_file |
unset | MQTT_CA_FILE |
Readable PEM CA bundle, normally /ssl/<file>.pem |
mqtt_username |
Supervisor/unset | MQTT_USERNAME |
Broker username override |
mqtt_password |
Supervisor/unset | MQTT_PASSWORD |
Broker password override; nonempty requires username |
mqtt_client_id |
n95bridge-<hostname> |
MQTT_CLIENT_ID |
Client ID prefix; [A-Za-z0-9_-]{1,64} |
mqtt_base |
ecovacs |
MQTT_BASE |
One MQTT topic level before /<serial> |
ha_discovery_prefix |
homeassistant |
HA_DISCOVERY_PREFIX |
Must match Home Assistant MQTT discovery prefix |
controller_jid |
n95bridge@ecouser.net/homeassistant |
CONTROLLER_JID |
Advanced virtual controller JID in local@domain/resource form |
raw_commands |
false |
RAW_COMMANDS |
Risky protocol-level raw command input; keep disabled normally |
Optional values are exported only when configured, preserving upstream
defaults. Boolean values are passed as lowercase true or false. All four
listener ports must be distinct and in the range 1–65535.
Host networking and ports
The add-on uses host networking because the robot must connect to the exact
address and ports returned by /lookup.do. The same ports are declared in
config.yaml so Supervisor opens them on the Home Assistant OS host
firewall. Without that map, the process can listen on the host while LAN
clients (including the robot) time out.
| Port | Purpose | Robot access |
|---|---|---|
8007/tcp |
Bootstrap lookup (EcoMsgNew, EcoUpdate) |
required |
8005/tcp |
Firmware check (expected 404 response) | required |
5223/tcp |
Plaintext XMPP | required |
8080/tcp |
Health endpoint | not required |
Changing a robot-facing port changes both the listener and the value advertised
to the robot. Also change the matching ports: entry so Supervisor still
opens the host firewall for that port. Check that another host service does
not already occupy the port. Host networking means Docker does not remap
these ports; the ports map is for Supervisor visibility and firewall
allowance only.
MQTT and Home Assistant discovery
Supervisor MQTT values are loaded first; explicitly configured options then replace individual fields. The final broker host must come from one of those sources or the add-on exits with an actionable error.
For TLS with a private CA, place a readable PEM bundle in Home Assistant's
ssl directory and set mqtt_ca_file to its in-container path, such as
/ssl/broker-ca.pem. TLS hostname verification remains enabled, so
mqtt_host must match the broker certificate.
The bridge publishes discovery below
<ha_discovery_prefix>/vacuum/ecovacs_<serial>/config and robot data below
<mqtt_base>/<serial>/.... Broker ACLs must allow each generated client to
publish/subscribe under those trees. The default client prefix is based on the
add-on hostname and has the robot serial appended.
Robot features and entities
The tagged upstream release publishes a native MQTT vacuum with availability, state, battery, fan speed, error information, and start, stop, dock, spot, and locate commands. It also supports extension movement commands, cleaning modes, schedule CRUD, consumable lifespan state, and diagnostic topics. Pause, resume, mapping, and segment cleaning are not advertised. Multiple connected robots remain isolated by serial number.
raw_commands permits protocol-level <ctl> input intended for controlled
experimentation. It bypasses normal high-level command constraints and should
remain disabled for ordinary use.
Check the installation
Replace the example addresses with your resolver and Home Assistant host:
nslookup lbo.ecouser.net 192.0.2.53
curl -sS -X POST -H 'Content-Type: application/json' \
--data '{"todo":"FindBest","service":"EcoMsgNew"}' \
http://192.0.2.10:8007/lookup.do
curl -sS -X POST -H 'Content-Type: application/json' \
--data '{"todo":"FindBest","service":"EcoUpdate"}' \
http://192.0.2.10:8007/lookup.do
curl -i http://192.0.2.10:8005/products/wukong/class/155/firmware/latest.json
curl -sS http://192.0.2.10:8080/healthz
The lookup responses must contain the configured advertised IPv4 and numeric ports. The firmware request should return HTTP 404. The health endpoint should report healthy listeners. After these pass, reboot the robot and check:
- the add-on log for XMPP READY and the robot serial;
- broker activity below
ecovacs/<serial>and the discovery prefix; - a newly discovered MQTT vacuum entity in Home Assistant;
- state refresh and a harmless command such as locating the robot.
Security notes
- Robot XMPP, including SASL PLAIN credentials, is plaintext. Keep ports 8005, 8007, and 5223 restricted to the trusted robot LAN.
- MQTT authentication and TLS protect only the broker connection; they do not encrypt robot traffic.
- Protect broker passwords and private CA files. The wrapper and upstream configuration log do not print the MQTT password.
- Do not expose the robot-facing listeners to the internet.
Troubleshooting
The add-on exits with “No MQTT broker is available”
No Supervisor MQTT service was found and mqtt_host is unset. Install/configure
a broker service or enter the external broker host.
The robot still contacts the cloud
Query the exact resolver supplied by DHCP and confirm lbo.ecouser.net returns
advertise_ip. Remove cached/secondary public DNS paths, then reboot the robot.
LAN clients time out on 8007 even though the add-on log shows listeners
On Home Assistant OS, Supervisor only opens inbound host ports listed under
ports: in config.yaml. Version 0.1.1 declares 8007, 8005, 5223, and 8080.
Rebuild/update the add-on so that version is installed, then confirm the
Network tab lists those ports. Loopback on the HAOS box can succeed while
the robot still times out if the firewall hole is missing.
8007/8005/5223 never appear on the host while 8080 is owned by OTBR
Before v0.1.2 a busy health port stopped every listener. From v0.1.2 the
process logs health listener failed; robot listeners continue and keeps
8007/8005/5223. Set optional health_port to a free port if you want
/healthz. Rebuild so the add-on is 0.1.2.
The add-on reports an address-already-in-use error Another host service owns lookup, firmware, or XMPP. Stop that service or set a distinct optional port. Reboot the robot after changing advertised ports.
The robot does not reconnect after an address or port change The N95 caches XMPP details for its powered-on lifetime. Power-cycle/reboot it to force a new bootstrap lookup.
There is no MQTT connection immediately after startup This is expected until a robot reaches XMPP READY and provides its serial. Investigate DNS, listener reachability, and XMPP logs first.
The robot connects but no entity appears
Confirm Home Assistant MQTT discovery is enabled and
ha_discovery_prefix matches its configured prefix. Check broker ACLs for both
the discovery and robot topic trees.
MQTT authentication or TLS fails
Check the effective host, port, username, and TLS override combination. For a
private CA, verify the /ssl/... path exists and is readable, and that the
broker certificate matches mqtt_host.
Schedules run at the wrong time
Set timezone to the correct IANA name and restart the add-on, then reconnect
the robot so it receives the updated time and UTC offset.
Upstream and standalone usage
The add-on builds the immutable
ha-n95-local-control v0.1.2 release
at commit 7bed99cc4c3222bad648efcddcdfed95652277f7. See the
tagged upstream README
for Docker Compose and direct Go-binary operation outside Home Assistant. The
upstream project is under the
Apache License 2.0.