Inovelli VZM32-SN: add mmWave area commands and reports#4944
Open
Inovelli VZM32-SN: add mmWave area commands and reports#4944
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## dev #4944 +/- ##
==========================================
+ Coverage 93.07% 93.09% +0.01%
==========================================
Files 401 401
Lines 13306 13331 +25
==========================================
+ Hits 12385 12410 +25
Misses 921 921 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Adds ZHA-side definitions for the Inovelli VZM32-SN mmWave (0xFC32) area configuration commands and device reports so ZHA can configure/read mmWave zones and parse live target/area reporting payloads.
Changes:
- Introduces
MMWaveAreaandMMWaveTargetZigpyStructs to model area bounds and live target reports. - Extends
InovelliVZM32SNMMWaveClusterwith new server commands for setting interference/detection/stay areas and new client (device→coordinator) report commands. - Adds unit tests validating round-trip serialize/deserialize of the new command payload schemas, including variable-length target reporting.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
zhaquirks/inovelli/types.py |
Adds new Zigpy Struct types used by mmWave command/report schemas. |
zhaquirks/inovelli/__init__.py |
Extends the VZM32-SN mmWave cluster with new control IDs and command/report definitions. |
tests/test_inovelli_blue.py |
Adds coverage for serialization/deserialization of the new mmWave commands/reports. |
The VZM32-SN mmWave cluster (0xFC32) exposes three area-definition
commands (interference, detection, stay) and five device-to-coordinator
reports that were previously only defined in zigbee-herdsman-converters'
inovelli.ts. This commit brings them to zha-device-handlers:
zhaquirks/inovelli/types.py
- MMWaveArea struct: x/y/z min/max bounds in mm
- MMWaveTarget struct: x, y, z, doppler, id for live target reports
zhaquirks/inovelli/__init__.py
- MMWaveControlId: add Reset_detection_area (0x04) and
Clear_stay_areas (0x05) to match the full device command set
- InovelliVZM32SNMMWaveCluster.ServerCommandDefs: add set_interference_area
(0x01), set_detection_area (0x02), set_stay_area (0x03). Docstring notes
the community-reported v1.00 set_stay_area xMin/xMax swap+negate bug
and the pre-compensation workaround.
- InovelliVZM32SNMMWaveCluster.ClientCommandDefs: new class with the five
device-originated reports. anyone_in_reporting_area (0x00) for per-area
occupancy, report_target_info (0x01) for live position streams using
t.List[MMWaveTarget], and report_interference_area / report_detection_area
/ report_stay_area (0x02-0x04) as readback responses to
mmwave_control_command(Obtain_areas).
Command names are snake_case per zha-device-handlers convention; payload
layouts match zigbee-herdsman-converters.
tests/test_inovelli_blue.py
- Round-trip tests for set_stay_area, report_stay_area, report_target_info
(variable-length), and anyone_in_reporting_area.
- ServerCommandDefs docstring: clarify the area_id indexing convention rather than treating it as inconsistent. Wire-level area_id is 0-indexed (0..3) per inovelli.ts, while report payloads use area_1..area_4 field names to match Inovelli's user-facing 1-indexed labeling. Document the mapping explicitly so callers don't read it as an off-by-one bug. - test_vzm32_mmwave_report_target_info_variable_length: drop the schema-introspection trick that grabbed the compiled list type from report_target.fields. zigpy's Struct coerces a plain Python list into the t.List[MMWaveTarget] field, so the test no longer reaches into zigpy internals.
9c854e4 to
20aaa66
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The VZM32-SN mmWave cluster (0xFC32) exposes three area-definition commands
(interference, detection, stay) and five device-to-coordinator reports that
are currently only defined in zigbee-herdsman-converters' inovelli.ts.
This PR brings them to zha-device-handlers so ZHA users can configure and
read back mmWave zones natively.
What's added
zhaquirks/inovelli/types.py— two structs:MMWaveArea— x/y/z min/max bounds in mmMMWaveTarget— x, y, z, doppler, id for live target reportszhaquirks/inovelli/__init__.py, inInovelliVZM32SNMMWaveCluster:MMWaveControlIdenum: addReset_detection_area = 0x04andClear_stay_areas = 0x05.ServerCommandDefs: addset_interference_area(0x01),set_detection_area(0x02),set_stay_area(0x03).ClientCommandDefs(new):anyone_in_reporting_area(0x00),report_target_info(0x01, variable-lengtht.List[MMWaveTarget]),report_interference_area(0x02),report_detection_area(0x03),report_stay_area(0x04).Command names are snake_case per the project's convention; payload layouts
match
inovelli.ts.A note on
set_stay_areaon v1.00The docstring records a community-reported bug
on main MCU firmware v1.00 where
set_stay_area'sx_min/x_maxareswapped and sign-inverted on write. Pre-compensation (send
-b, -ato landon
(a, b)) is documented as a workaround; symmetric ranges[-n, +n]areself-correcting. Status on v1.01/v1.02 betas is not publicly documented.
This is a device-firmware issue, not something this quirk can fix — the
note is there so callers know why asymmetric x-axis stay zones may need
pre-compensation.
Test plan
python -m pytest tests/test_inovelli_blue.py -vpasses (1 existing + 4 new tests)python -m ruff check zhaquirks/inovelli/ tests/test_inovelli_blue.py— cleanpython -m ruff format --check zhaquirks/inovelli/ tests/test_inovelli_blue.py— cleanpython -m pytest tests/— 4746 pass on this branch (3 pre-existing Tuya/time_machine failures on Python 3.14, unrelated)