Skip to content

fix: guard against null catLitterWeight and deodorantCountdown - #67

Open
meeowgler wants to merge 1 commit into
hasscc:mainfrom
meeowgler:fix/null-litter-weight-and-deodorant-countdown
Open

meeowgler wants to merge 1 commit into
hasscc:mainfrom
meeowgler:fix/null-litter-weight-and-deodorant-countdown

Conversation

@meeowgler

Copy link
Copy Markdown

Fixes #63.

The bug

The CatLink API returns catLitterWeight and deodorantCountdown present but null on some models. dict.get(key, default) only falls back when the key is absent, so the defaults never fire and both properties raise on every read:

Got litter weight failed: unsupported operand type(s) for -: 'NoneType' and 'float'
Get deodorant countdown failed: int() argument must be a string, a bytes-like object or a real number, not 'NoneType'

devices/litter_device.py:

# L51-54 -> None - float
cat_litter_weight = self.detail.get("catLitterWeight", self.empty_litter_box_weight)
litter_weight = cat_litter_weight - self.empty_litter_box_weight

# L108 -> int(None)
return int(self.detail.get("deodorantCountdown", 0))

Why it floods the log

Both are @property getters whose exception is caught and logged at ERROR, so the message is emitted every time Home Assistant reads the property, not once per poll cycle.

Measured on a 7-device account (2 litter boxes + 5 cat profiles, 156 entities) with the default SCAN_INTERVAL of 1 minute: ~17 lines/minute, roughly 24,000 a day. On that instance it was ~60% of all Home Assistant log output and shortened the readable log buffer to under an hour, which makes the log useless for anything else.

Worth noting: _LOGGER is defined in const.py and imported by 18 modules, so everything the integration logs appears under custom_components.catlink.const. That means there is no way for a user to silence just these two messages with a logger: rule without silencing the whole integration, including genuine auth and API failures.

The change

Guard both values explicitly instead of relying on a dict.get() default.

  • empty_litter_box_weight is always a float (additional_config.empty_weight or 0.0), so it stays a safe substitute for a missing weight.
  • An explicit is None check rather than or keeps a legitimate 0 reading intact — with or, a genuine zero weight would be silently replaced by the empty-box weight.

The existing _LOGGER.debug guards for the "value is 0" case are untouched; they were previously unreachable in the null case because the exception was raised first.

Testing

Applied to a live 2.1.1-beta install with two Open-X boxes (MODEL_00 and MODEL_01) that were producing both errors continuously. Both messages stop; litter_weight reports 0.0 and deodorant_countdown reports 0 for the null fields rather than raising, which matches the intended fallbacks.

Not covered here

The same issue report also mentions Got device logs for <device> failed: {...'scooperLogTop5': []...}. That is a separate warning about an unexpected response shape and is left alone to keep this change minimal.

The CatLink API returns these two keys *present but null* on some models.
`dict.get(key, default)` only falls back when the key is absent, so the
defaults never fire and both properties raise on every read:

    Got litter weight failed: unsupported operand type(s) for -: 'NoneType' and 'float'
    Get deodorant countdown failed: int() argument must be a string, a bytes-like object or a real number, not 'NoneType'

Because these are @Property getters whose exception is caught and logged at
ERROR, the message is emitted every time Home Assistant reads the property,
not once per poll. On a 7-device account with the default 1-minute
SCAN_INTERVAL that measured ~17 lines/minute, about 24,000 lines a day, which
is enough to push everything else out of the log buffer.

Guard both values explicitly rather than relying on a dict.get() default.
`empty_litter_box_weight` is always a float (`additional_config.empty_weight
or 0.0`), so it remains a safe substitute, and an explicit None check keeps a
legitimate 0 reading intact where `or` would discard it.

Fixes hasscc#63
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.

[BUG] Unhandled NoneType exception every ~60s parsing deodorant countdown / device logs (SCOOPER C08, v2.1.1)

1 participant