Releases: sytchi/NarwalIntegration
Release list
v2.1.2 — Broadcast path off the event loop
⚠️ Upgrading from 1.x? 2.0.0 removed the 1:1camera.*_mapand the pixelclean_zonecontract. Repoint tocamera.*_map_hdwith camera calibration.
Performance only. No configuration, entity or service changes.
Changed
- Broadcast decoding no longer uses
blackboxprotobuf. A purpose-built wire-format decoder is 7.1x faster and bit-for-bit compatible; payloads it cannot reproduce fall back to the library. - Duplicate broadcasts are skipped before decoding. While docked, ~84% of frames are byte-identical repeats.
- The WebSocket listener yields between frames, so several buffered frames no longer land in one blocking event-loop step.
Impact
Event-loop time blocked by the listener, measured on a live Home Assistant host (x86_64, CPython 3.14):
| before | after | |
|---|---|---|
| docked | 11.44 ms/s | 0.11 ms/s |
| cleaning | — | 7.0 ms/s (0.7% of wall time) |
Verified against blackboxprotobuf on 325 captured payloads and 40 000 generated ones, plus 801 real frames replayed through the old and new paths with identical resulting state.
Full details in the CHANGELOG.
v2.1.1 — rejected commands surface as errors
⚠️ Upgrading from 1.x? 2.0.0 removed the 1:1camera.*_mapand the pixelclean_zonecontract — repoint your map card tocamera.*_map_hdwithcalibration_source: {camera: true}. See v2.0.0.
Changed
- Rejected start commands now raise an error instead of only logging one — a map-card tap or an automation step no longer looks successful while the robot stays put. Applies to
vacuum.start,narwal.clean_roomsandnarwal.clean_zone;narwal.resumestays log-only (it is sent blind by design). - Rejection reasons are spelled out, including the newly decoded result code 4 (
NOT_READY): the robot declines to start until it has charged — observed right after a long clean (rejected at 23-26% battery, accepted at 30%; a running mop-drying cycle is not what blocks it). The error carries the current battery level.
Added
- Map gallery screenshots: a full-session HD map and a live zone clean with the amber active-zone overlay.
v2.1.0 — Rooms config generator
⚠️ Upgrading from 1.x? 2.0.0 removed the 1:1camera.*_mapand the pixelclean_zonecontract — repoint your map card tocamera.*_map_hdwithcalibration_source: {camera: true}. See v2.0.0.
Added
roomsattribute oncamera.*_map_hd— per-room outlines (world coords), names, label anchors.- One-click Rooms mode via
xiaomi-vacuum-map-card's "Generate rooms config" button (reads that attribute; replaces the ROOM mode'spredefined_selections). - README images use absolute URLs (render on the HACS info page).
v2.0.0 — Map breaking changes (legacy camera + pixel zones removed)
⚠️ BREAKING CHANGES — the map changed
If you use a map card or zone automations, read this before upgrading.
🗺️ The legacy 1:1 camera.*_map entity is gone
Only the high-resolution camera.*_map_hd remains. Any dashboard card, picture entity or automation referencing camera.*_map will break — repoint it to camera.*_map_hd.
📐 narwal.clean_zone is world-coordinates only
The map-image pixel contract (and its auto/pixels detection) is removed. Zones are now always robot world coordinates — exactly what xiaomi-vacuum-map-card sends with calibration_source: {camera: true}.
The coordinates service field is still accepted so pre-2.0 automations keep validating, but it is ignored — a call that used to send pixels is now treated as world coordinates and would clean the wrong area. Drop coordinates: pixels from your calls.
✅ Migration
- Point your map card at
camera.*_map_hdwithcalibration_source: {camera: true}— see the README map-card example. The card then produces world coordinates automatically and needs no re-calibration when you changemap_scale. - Remove any
coordinates: pixelsfrom yournarwal.clean_zoneservice calls.
The deprecation was announced in 1.6.0. Not ready to migrate? Pin the integration to v1.6.0 in HACS.
Everything else from 1.6.0 (HD map, performance overhaul, carpet detection) is unchanged. See CHANGELOG.md.
v1.6.0 — HD map, performance overhaul, carpet detection
High-resolution live map, a performance overhaul that removes the event-loop stalls, and carpet detection.
Highlights
- HD map camera
camera.*_map_hd: upscaled grid with anti-aliased vector overlays, livecalibration_pointsforxiaomi-vacuum-map-card(calibration_source: {camera: true}), and amap_scaleoption (2–6). - Live overlays: robot-recorded trail, the exact vacuumed strip, planned trajectory, furniture (with rotation), and per-overlay switches you can toggle from the UI.
- Lidar cell marks with carpet detection: cells the robot flags as carpet render as a light tint above the floor (like the Narwal app); wall-adjacent cells take the wall shade; free-standing detections are minimally darker. Carpet persists across sessions; the noisier buffers reset each run.
⚡ Performance
The map camera used to redraw every accumulated swath and lidar cell on every frame — an O(total) cost that grew through a clean and, holding the GIL, stalled Home Assistant's event loop up to ~3.9 s on a large map.
Swath and lidar are now painted once onto persistent RGBA layers; only new cells are drawn per frame (O(new)). Measured under a full live clean: CPU flat at 4–19 %, render latency ≤360 ms, zero multi-second stalls.
⚠️ Deprecated (removed in 2.0.0)
- The map-image pixel contract of
narwal.clean_zone - The legacy 1:1
camera.*_mapentity
Both will be removed in 2.0.0, which defaults to world coordinates. Migrate your map card to the HD camera with calibration_source: {camera: true}.
See CHANGELOG.md for the full list.
v1.5.1
Patch release — recommended for Home Assistant 2026.x on Python 3.14.
Fixed
- Manifest requirements no longer force a pip install/downgrade at load time.
HA core pinswebsockets>=15.0.1andprotobuf==6.32.0; the 1.5.0 upper
bounds (websockets<14,protobuf<6) conflicted with those, causing a
ResolutionImpossiblethat prevented the integration from loading on recent
HA. Requirements are nowwebsockets>=12.0,bbpb>=1.4.0,Pillow>=9.0.0
(all satisfied by HA's bundled versions → nothing is installed at load).
protobufis dropped:bbpbis pure-Python and does not use it.
No functional changes to entities, services, or the map — same as v1.5.0.
v1.5.0
First public release of this fork of sjmotew/NarwalIntegration.
A fully local, cloud-free Home Assistant integration for Narwal robot vacuums (local WebSocket, port 9002). Fully supported and maintained on the Narwal Flow (AX12); other models are "probably working" (worked on upstream before this fork, not re-tested here).
Highlights over upstream
- Clean modes: vacuum / mop / vacuum+mop / vacuum-then-mop (sequential)
- Zone cleaning (
narwal.clean_zone) and per-room cleaning (narwal.clean_rooms) - Station controls: wash mop, dry mop, empty dustbin, wake; mop-humidity select
- Sensors: cleaning progress, dust-bag health, station activity, and a fault-code sensor with 48 codes translated to readable states (EN/FR/PL)
- Live map: color-coded floor plan, dock marker, robot trail, active-zone overlay
narwal.resumeto recover false "robot lifted" pauses- Firmware-compatibility fixes for v01.08.03+ (docked/paused detection)
See the README for setup and the CHANGELOG for full history.
Install via HACS -> Custom repositories -> https://github.com/sytchi/NarwalIntegration (Integration).
This is an unofficial, community integration, not affiliated with Narwal. Reverse-engineered for interoperability; use at your own risk.