fix: clear battery_level_percentage when player goes offline#187
fix: clear battery_level_percentage when player goes offline#187sethfitz wants to merge 1 commit into
Conversation
When a device powers down, the last status response the library receives carries a batteryLevel reading that doesn't reflect the actual charge level at power-off. Because _set_online(player, False) left battery_level_percentage unchanged, that stale value persisted until the device came back online — commonly appearing as a fixed 86% regardless of the true charge state. Clear battery_level_percentage in _set_online(False) so callers see unknown rather than a misleading value while the device is off.
526f807 to
b4dd222
Compare
|
Hi 👋 How are you using Otherwise, many home assistant device don't clear the battery level when the device is offline. Even the official Yoto app still display the battery when the device is offline. |
|
Agreed I'm not sure you want to clear battery. It could be consumed offline but more likely it's off so you want o know if low so you can charge it. |
|
@piitaya I'm carrying a patch to --- upstream/sensor.py
+++ local/sensor.py
@@ -120,6 +120,11 @@
@property
def native_value(self):
"""Return the value reported by the sensor."""
+ # Workaround for yoto_api v2.x not clearing battery_level_percentage on
+ # offline: the shutdown MQTT status carries a stale reading that persists.
+ # Remove when https://github.com/cdnninja/yoto_api/pull/187 ships.
+ if self._key == 'battery_level_percentage' and not self.player.online:
+ return None
return getattr(self.player, self._key)@cdnninja I'll look for a way to drop the first battery update after going offline (using the previous, known-good value). I agree that having the last-good level would be best (esp. since it avoids the workaround above), but in the absence of that, no data (because it's offline and can't produce valid values) seems like it makes almost as much sense. |
|
Can you describe why you are trying to solve that? |
|
The underlying problem I'm trying to address is that HA (and therefore Yoto Cloud / the MQTT message received after shutting down) an incorrect battery level (86%) which persists in HA (and Yoto Cloud, but we have no control) until the player comes back online. I have a patch that uses an online → offline state transition (via REST API calls triggered by HA) to revert to last-known-good battery levels, but I want to better understand the root cause and when MQTT messages are triggered. I'll follow up later with more. |
|
Yoto has been added as a official integration in 2026.6 release. Currently only media player is supported but sensor will be added probably next release. I'm also in discussion with Yoto dev to fully rely on MQTT for live data instead of REST. For example, the official HA integration will not use REST for battery, only MQTT data. Let's see if it fix the issue before adding another patch. |
Problem
When a Yoto device powers down, the library's polling cycle sends a
command/status/requestvia MQTT. The device responds with abatteryLevelthat doesn't reflect its actual charge level at power-off._apply_status_patchstores this value faithfully, and because_set_online(player, False)never touchedbattery_level_percentage, the stale reading persisted until the device came back online and sent a fresh status response. In practice this means Home Assistant shows a misleading battery percentage (observed: consistently 86%, unrelated to actual charge level) any time the device is powered off.Root cause
_set_onlinesetsis_onlinebut leaves all other status fields unchanged, so the stale polling response outlives the online state.Fix
Clear
battery_level_percentagein_set_online(player, False). Battery level is only meaningful while the device is live; when the REST poll confirms offline, the value from the last status response is no longer reliable.Going back online does not clear the field, so a legitimate reading received via MQTT right after power-on is preserved.
Tests
Two new cases in
OnlineConsolidationTests:test_going_offline_clears_battery_level— simulates a stale battery value arriving, then REST detecting offline; asserts the field becomesNone.test_going_online_preserves_battery_level— confirms_set_online(True)leaves an existing reading intact.Meta
This patch was produced by Claude Code (Sonnet 4.6) with human (@sethfitz) oversight.