Skip to content

Fix inverted work_state on Smart Towel Rack (yghsoyzoicezv8sy)#956

Open
multinet33 wants to merge 1 commit into
azerty9971:mainfrom
multinet33:fix/work-state-inverted-smart-towel-rack
Open

Fix inverted work_state on Smart Towel Rack (yghsoyzoicezv8sy)#956
multinet33 wants to merge 1 commit into
azerty9971:mainfrom
multinet33:fix/work-state-inverted-smart-towel-rack

Conversation

@multinet33

Copy link
Copy Markdown

Fix inverted work_state on Smart Towel Rack (yghsoyzoicezv8sy)

Problem

On a Tuya Smart Towel Rack (product_id yghsoyzoicezv8sy, category mjj), the
work_state enum sensor (dpId 14, range ["heating", "standby"]) reports the
opposite of the device's real state:

  • device off / idle → reports heating
  • device on and actively heating (temp rising toward setpoint) → reports standby

The inverted value comes straight from the Tuya cloud — a single status payload
contains {"switch": false, "work_state": "heating"} while the rail is off. The
official tuya integration shows the same, confirming the bad semantics are upstream
of this integration.

Why it isn't fixed today

XTDevice.apply_dpcode_strategy() calls tuya_sharing.strategy.convert("default", …),
but tuya-device-sharing-sdk==0.2.8 does not register a default strategy and
never consults enumMappingMap. The call raises, the exception is swallowed, and the
raw cloud value is forwarded unchanged. So neither a corrected enum range nor an
enumMappingMap entry would take effect — the value must be remapped explicitly.

Fix

Add a small per-product value-override table consulted on the report (read) path
inside apply_dpcode_strategy(), keyed product_id -> dpcode -> {raw: corrected}, and
register the heating ⇄ standby swap for yghsoyzoicezv8sy.

DPCODE_VALUE_OVERRIDES: dict[str, dict[str, dict[Any, Any]]] = {
    "yghsoyzoicezv8sy": {
        "work_state": {"heating": "standby", "standby": "heating"},
    },
}
  • Only reported values are touched; writable dpcodes and every other product are
    unaffected (unknown values pass through unchanged).
  • Both work_state enum members stay within the declared range, so the sensor's enum
    options remain valid.
  • Single, central hook — covers the tuya_iot, tuya_sharing and multi_manager
    update paths, which all funnel through apply_dpcode_strategy().

Testing

  • Verified the remap logic in isolation (swap both directions, unknown value
    passthrough, other dpcodes/products untouched).
  • On-device: switching the rail ON makes temp_current climb toward the 70 °C
    setpoint while the corrected sensor now reads heating (and standby/off when idle).

Notes / open questions

  • Happy to move the override table elsewhere (e.g. cloud_fix.py or const.py) if you
    prefer a different home — it lives in shared_classes.py to avoid a circular import,
    since that is where it is applied on every update.
  • Side observation: the device diagnostics export currently includes local_key in
    clear text. Might be worth redacting separately.

Closes #955

The Tuya cloud reports the `work_state` enum (dpId 14) inverted on this
product: "heating" while the device is off/idle and "standby" while it is
actually heating. The integration forwards the raw cloud value unchanged
(value_convert "default" is not registered in tuya-device-sharing-sdk, so
the conversion is a no-op), so the sensor shows the opposite of reality.

Add a per-product value override table consulted on the report path in
XTDevice.apply_dpcode_strategy(), and register the heating<->standby swap
for product_id yghsoyzoicezv8sy. The override is keyed by
product_id -> dpcode -> {raw: corrected} and only touches reported values,
leaving writable dpcodes and all other products untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

# work_state enum inverted on Smart Towel Rack (heating ⇄ standby)

1 participant