Skip to content

[BUG] apyhiveapi.heating/hotwater log a bare "'mode'" ERROR every poll while a device is offline (3,005 in 13 hours) #209

Description

@peshmann

Describe the bug

While a device is offline, apyhiveapi.heating and apyhiveapi.hotwater log an ERROR on every poll, and the message is just the bare key name — 'mode'. No device name, no context, no traceback.

I collected 3,005 of each (6,010 lines) in a single 13-hour outage, at one pair every 15 seconds:

2026-08-19 00:51:55.208 ERROR (MainThread) [apyhiveapi.heating] 'mode'
2026-08-19 00:51:55.209 ERROR (MainThread) [apyhiveapi.hotwater] 'mode'
2026-08-19 00:52:10.210 ERROR (MainThread) [apyhiveapi.heating] 'mode'
...

The cause is heating.py:

try:
    data = self.session.data.products[device["hiveID"]]
    state = data["state"]["mode"]
    if state == "BOOST":
        state = data["props"]["previous"]["mode"]
    final = HIVETOHA[self.heatingType].get(state, state)
except KeyError as e:
    _LOGGER.error(e)          # <- logs only the missing key name

_LOGGER.error(e) on a KeyError renders as the repr of the key, so the operator sees 'mode' and nothing else. hotwater.py has the same shape, and device_attributes.py has a third instance.

Two smaller points worth noting:

  1. The try covers both data["state"]["mode"] and data["props"]["previous"]["mode"], so the log line cannot tell you which one was missing.
  2. helper/hive_helper.py errorCheck() already has a dedupe mechanism (session.config.errorList) so that "Device offline could not update entity" is logged once per device rather than every poll. The getMode/getState handlers don't use it, so a known-offline device still generates ERROR-level noise indefinitely.

To Reproduce

  1. Have a device go offline such that its product node no longer carries state.mode. (Mine came back from the API with error: MALFORMED_NODE_DESCRIPTOR, so the product was skipped and the cached entry had no state.)
  2. Leave HA running.
  3. Watch apyhiveapi.heating / apyhiveapi.hotwater emit an ERROR every 15 s indefinitely.

Expected behaviour

A known-offline or malformed device should log once, at WARNING, with enough context to act on — something like:

except KeyError as e:
    _LOGGER.warning(
        "Heating %s: product data missing key %s (device offline or malformed node)",
        device.get("haName", device.get("hiveID")), e,
    )

and ideally routed through the same errorList dedupe that errorCheck() already uses, so it doesn't repeat every poll.

Additional context

This matters beyond tidiness: at ERROR level and 5,760 lines/day it dominates the log, pushes genuinely useful entries out of the retained window, and trains people to ignore red text. It's also actively misleading — a bare 'mode' gives no indication that the underlying condition is simply "this device is offline", which the library already knows and already reports properly elsewhere.

Versions

  • Home Assistant Core 2026.8.2 (HAOS)
  • Hive-Custom-Component 2026.8.0
  • pyhive-integration 1.0.9

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions