Skip to content

5.16: Z-Wave code tables follow the standard, plus contract tests - #1

Merged
Highsteads merged 2 commits into
mainfrom
claude/tests-and-review
Nov 1, 2026
Merged

Highsteads merged 2 commits into
mainfrom
claude/tests-and-review

Conversation

@Highsteads

Copy link
Copy Markdown
Owner

Summary

This adds new contract tests from a code review, and fixes the two Z-Wave code tables that the tests showed were wrong. The expected values come from the zwave-js project's definitions (BinarySensorType in packages/cc/src/lib/_Types.ts and packages/core/src/registries/Sensors.ts), fetched on 01-11-2026.

Tests

  • tests/conftest.py reuses the bundle's own test_plugin.py indigo stand-in rather than adding a second one.
  • test_xml_callbacks_and_changelog.py checks that:
    • every CallbackMethod and List method= named in the XML exists
    • every state written by name is declared
    • the newest docs/changelog.md entry matches Info.plist
  • test_zwave_code_tables.py checks both tables against the standard, every mapped code, codes with no matching state, scales and conversions, and the notification codes.

5.16: code tables (the plugin change)

  • BINARY_SENSOR_TYPES:
    • 0x06 Water now sets waterLeak (it set tamper)
    • 0x08 Tamper now sets tamper (it set motion)
    • 0x04 CO2, 0x09 Aux and 0x0B Tilt no longer set waterLeak or motion; like any type with no state of its own, they set only onOffState
  • SENSOR_TYPES:
    • correct up to 0x09 before, wrong from 0x0B; for example 0x10 Current was written to watts, 0x0F Voltage to co2Level, and 0x11 CO2 to uvIndex
    • now follows the standard; velocity, loudness, target temperature, PM2.5 and VOC are at their real codes
    • codes with no matching state are logged as unknown instead of being written to an unrelated state
  • SENSOR_SCALES: the unit follows the scale the sensor sends. mV and mA are converted to V and A. Target temperature (0x22) is converted to °C/°F like temperature.
  • Tests that checked the old codes: one self-test sample and six existing bundle tests used the old codes. They now use the standard ones.
  • Version 5.16 in Info.plist, the plugin.py header, the README and docs/changelog.md.

Not fixed (still xfail(strict))

A Home Security "idle" notification clears motion and tamper on every idle. It also writes onOffState=False whatever the device type, so a contact device can show closed when a tamper clears. I'm fairly, but not fully, confident that the standard's idle event names the event that ended in its first event parameter.

Test plan

  • pytest: 264 passed, 2 xfailed. Ruff and compileall are clean.
  • Before the fix, each table test failed for the stated reason (checked with --runxfail).
  • Run Parser Self-Test: 14 passed, 0 failed.
  • Not yet run on the Indigo Mac. If a sensor uses the older binary report, or sends current, voltage or CO2 as a multilevel report, check that its states now read correctly. Check any triggers built on Tamper, Motion, Water Leak, CO2, Voltage, Current or UV.

Generated by Claude Code

- conftest.py: bundle on sys.path; reuses the bundle test_plugin.py indigo
  stand-in (no second stub)
- test_xml_callbacks_and_changelog.py: every CallbackMethod and List method
  exists; every state written by name is declared; docs/changelog.md newest
  entry matches Info.plist
- test_zwave_code_tables.py: the code tables against the Z-Wave standard
  (zwave-js definitions, fetched 01-11-2026) and the decoders on real-shaped
  reports. Seven xfail(strict) tests pin real faults:
    * BINARY_SENSOR_TYPES: 0x06 Water decoded as tamper, 0x08 Tamper as motion,
      0x04 CO2 as waterLeak, 0x09 Aux / 0x0B Tilt as motion
    * SENSOR_TYPES from 0x0B: e.g. 0x10 Current written to watts, 0x0F Voltage
      to co2Level, 0x11 CO2 to uvIndex
    * Home Security idle clears motion AND tamper on every idle and sets
      onOffState False on a contact device

No plugin code changed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019Z2FM7PBbhgq9QjrM5W2HY
Checked against the zwave-js definitions (BinarySensorType, Sensors.ts).

- BINARY_SENSOR_TYPES: 0x06 Water -> waterLeak (was tamper), 0x08 Tamper ->
  tamper (was motion). 0x04 CO2, 0x09 Aux and 0x0B Tilt no longer map to
  waterLeak / motion; codes with no state of their own fall back to
  onOffState as before.
- SENSOR_TYPES: correct from 0x0B up (0x0F voltage, 0x10 current, 0x11 CO2,
  0x12 air flow, 0x1B UV, 0x1E loudness, 0x1F moisture, 0x22 target
  temperature, 0x23 PM2.5, 0x27 VOC; 0x06 velocity added). Codes with no
  matching state are logged as unknown instead of written somewhere wrong.
- SENSOR_SCALES: unit per scale; mV and mA converted to V and A. Target
  temperature converted to degC/degF like temperature.
- Self-test sample and six bundle tests that encoded the old codes updated
  to the standard codes. tests/test_zwave_code_tables.py: the five table
  xfails now pass and their markers are removed; new tests for every code,
  unknown codes, scales and conversions. The idle-event xfails remain.
- Version 5.16: Info.plist, plugin.py header, README, docs/changelog.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019Z2FM7PBbhgq9QjrM5W2HY
@Highsteads
Highsteads merged commit 50515f0 into main Nov 1, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants