From 065c50392d5aed429422b5793a09f17c723dd23b Mon Sep 17 00:00:00 2001 From: meeowgler <4227406+meeowgler@users.noreply.github.com> Date: Sun, 20 Sep 2026 21:03:47 -0400 Subject: [PATCH] fix: guard against null catLitterWeight and deodorantCountdown 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 #63 --- custom_components/catlink/devices/litter_device.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/custom_components/catlink/devices/litter_device.py b/custom_components/catlink/devices/litter_device.py index e1f599f..abe0580 100644 --- a/custom_components/catlink/devices/litter_device.py +++ b/custom_components/catlink/devices/litter_device.py @@ -48,9 +48,11 @@ def litter_weight(self) -> float: """Return the litter weight.""" litter_weight = 0.0 try: - cat_litter_weight = self.detail.get( - "catLitterWeight", self.empty_litter_box_weight - ) + cat_litter_weight = self.detail.get("catLitterWeight") + if cat_litter_weight is None: + # The API sends the key with a null value on some models, so the + # dict.get() default never fires - guard explicitly. + cat_litter_weight = self.empty_litter_box_weight litter_weight = cat_litter_weight - self.empty_litter_box_weight self._litter_weight_during_day.append(litter_weight) if litter_weight == 0.0: @@ -105,7 +107,9 @@ def manual_clean_time(self) -> int: def deodorant_countdown(self) -> int: """Return the deodorant countdown.""" try: - return int(self.detail.get("deodorantCountdown", 0)) + raw = self.detail.get("deodorantCountdown") + # Same here: the key is present but null, so the default is skipped. + return int(raw) if raw is not None else 0 except Exception as exc: _LOGGER.error("Get deodorant countdown failed: %s", exc) return 0