Skip to content

Fix OverkizCommandParam STANDARD/HISTORICAL/ERROR/UNHEALTHY casing regression#2126

Merged
iMicknl merged 1 commit into
mainfrom
fix/command-param-casing-regression
Jun 4, 2026
Merged

Fix OverkizCommandParam STANDARD/HISTORICAL/ERROR/UNHEALTHY casing regression#2126
iMicknl merged 1 commit into
mainfrom
fix/command-param-casing-regression

Conversation

@iMicknl
Copy link
Copy Markdown
Owner

@iMicknl iMicknl commented Jun 4, 2026

Follow-up to #2096.

Problem

Four more OverkizCommandParam members were regressed from their lowercase API state values to capitalized variants in #2085 — the same bug class as ON/OFF/UNKNOWN/BATTERY (fixed in #2096):

Member Was Now Real lowercase source
STANDARD "Standard" "standard" io:MemorizedSimpleVolumeState, io:VentilationConfigurationModeState, modbus:DHWModeState, modbus:YutakiDHWVirtualOperatingModeState
HISTORICAL "Historical" "historical" (Linky pair of STANDARD)
ERROR "Error" "error" core:UpdateStatusState
UNHEALTHY "Unhealthy" "unhealthy" core:AirQualityIndexLevelState

The real Overkiz API returns these state values in lowercase, so every equality comparison against these members silently fails — breaking downstream consumers such as Home Assistant's overkiz integration (e.g. DHW/ventilation state maps keyed on OverkizCommandParam.STANDARD).

Root cause

The capitalized values were harvested from other states that emit the same word in different casing (zigbee:LinkyModeState"Standard"/"Historical", netatmo:HealthIndexState"Error"/"Unhealthy"). Both casings are real API values, but they collapse to one SCREAMING_SNAKE enum name. The generator's alphabetical sort (codepoint order, capitals first) let the capitalized catalog value claim the name and drop the lowercase value consumers depend on — exactly the mechanism described in #2096.

Fix

  1. Restore the four values to lowercase in pyoverkiz/enums/command.py. The generator's existing "preserve established value on a name collision" guard now pins them on regeneration.
  2. Extend the OverkizCommandParam.ON/OFF/UNKNOWN regressed to capitalized values in #2085 (API returns lowercase) #2093 regression test (TestOverkizCommandParamApiValues) to pin all four.

Notes / follow-up

  • FAIR/POOR were intentionally left as "Fair"/"Poor" — those casings are the only values netatmo:HealthIndexState emits; no lowercase variant exists in the API.
  • The capitalized variants (zigbee:LinkyModeState "Standard"/"Historical", netatmo:HealthIndexState "Error"/"Unhealthy") are dropped for now. They're real state values the single-name enum structurally can't represent alongside the lowercase ones. Keeping both would require an explicit alias map in the generator (e.g. STANDARD_LINKY = "Standard") plus a hard failure on unhandled collisions — tracked as a separate change.

Verification

  • uv run utils/generate_enums.py is idempotent — all four values stay lowercase after regeneration (+0 new params).
  • uv run pytest tests/test_enums.py — 10 passed.

…gression

Follow-up to #2096. Four more OverkizCommandParam members were regressed
from their lowercase API state values to capitalized variants in #2085,
the same way ON/OFF/UNKNOWN/BATTERY were:

  STANDARD   = "Standard"   -> "standard"    # io/modbus DHW & ventilation states
  HISTORICAL = "Historical" -> "historical"
  ERROR      = "Error"      -> "error"       # core:UpdateStatusState
  UNHEALTHY  = "Unhealthy"  -> "unhealthy"   # core:AirQualityIndexLevelState

The capitalized values were harvested from other states that happen to
emit the same word in different casing (zigbee:LinkyModeState "Standard"/
"Historical", netatmo:HealthIndexState "Error"/"Unhealthy"). Both casings
are real API values, but they collapse to one SCREAMING_SNAKE enum name,
and the alphabetical sort let the capitalized catalog value clobber the
lowercase value downstream consumers (e.g. Home Assistant's overkiz
integration) compare against.

Restoring the lowercase values lets the generator's existing
"preserve established value on a name collision" guard pin them on
regeneration. The capitalized variants are dropped for now; representing
both would need an explicit alias map (separate change).

Extend the #2093 regression test to pin all four to their lowercase
API state values.
Copilot AI review requested due to automatic review settings June 4, 2026 22:28
@iMicknl iMicknl requested a review from tetienne as a code owner June 4, 2026 22:28
@github-actions github-actions Bot added the bug Something isn't working label Jun 4, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR is a follow-up to #2096, fixing four additional OverkizCommandParam enum members (STANDARD, HISTORICAL, ERROR, UNHEALTHY) whose values were regressed from lowercase to capitalized in #2085. The real Overkiz API returns these state values in lowercase, so the capitalized values broke equality comparisons for downstream consumers like Home Assistant's overkiz integration.

Changes:

  • Restored four OverkizCommandParam values to their correct lowercase form in pyoverkiz/enums/command.py.
  • Extended the existing regression test class (TestOverkizCommandParamApiValues) to pin all four new values.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
pyoverkiz/enums/command.py Changes ERROR, HISTORICAL, STANDARD, and UNHEALTHY enum values from capitalized to lowercase to match real API responses.
tests/test_enums.py Adds four assertions to the existing regression test to pin the corrected lowercase values.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@iMicknl iMicknl merged commit 4d78d1a into main Jun 4, 2026
11 checks passed
@iMicknl iMicknl deleted the fix/command-param-casing-regression branch June 4, 2026 22:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants