Skip to content

Commit 3b014c6

Browse files
g.delsorboclaude
andcommitted
Fix climate: optimistic state for temperature/fan/swing + fix watcher timer leak
Climate setters async_set_temperature, async_set_fan_mode and async_set_swing_mode sent the command but never wrote HA state nor armed start_watcher(), so the next 60s coordinator poll overwrote the value with the stale cloud shadow (target temp / fan / swing "reverting" in the UI). Align them with async_set_hvac_mode/turn_on/turn_off. Also fix a timer leak: start_watcher() used a repeating async_track_time_interval whose cancel callback was never called; switch to a one-shot async_call_later, cancel any pending watcher first, and cancel it on entity removal. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 05ad92f commit 3b014c6

1 file changed

Lines changed: 10 additions & 3 deletions

File tree

custom_components/hon/climate.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
)
5757
from homeassistant.core import callback
5858
from homeassistant.helpers.dispatcher import async_dispatcher_connect
59-
from homeassistant.helpers.event import async_track_time_interval
59+
from homeassistant.helpers.event import async_call_later
6060
from homeassistant.helpers import config_validation as cv, entity_platform
6161
from .const import(
6262
DOMAIN,
@@ -257,7 +257,9 @@ async def async_set_eco_pilot_mode(self, value: int):
257257
await self._device.settings_command(parameters).send()
258258

259259
def start_watcher(self, timedelta=timedelta(seconds=8)):
260-
self._watcher = async_track_time_interval(self._hass, self.async_update_after_state_change, timedelta)
260+
if self._watcher is not None:
261+
self._watcher()
262+
self._watcher = async_call_later(self._hass, timedelta, self.async_update_after_state_change)
261263
self.async_write_ha_state()
262264

263265
async def async_update_after_state_change(self, now: Optional[datetime] = None) -> None:
@@ -350,6 +352,8 @@ async def async_set_temperature(self, **kwargs):
350352
if (temperature := kwargs.get(ATTR_TEMPERATURE)) is None:
351353
return False
352354
await self._device.settings_command({'tempSel': temperature}).send()
355+
self._attr_target_temperature = int(float(temperature))
356+
self.start_watcher()
353357

354358

355359
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
@@ -386,6 +390,7 @@ async def async_turn_on(self) -> None:
386390
async def async_set_fan_mode(self, fan_mode: str):
387391
self._attr_fan_mode = fan_mode
388392
await self._device.settings_command({'windSpeed':CLIMATE_FAN_MODE.get(fan_mode, CLIMATE_FAN_MODE.get(FAN_MEDIUM))}).send()
393+
self.start_watcher()
389394

390395

391396
async def async_set_swing_mode(self, swing_mode: str):
@@ -414,10 +419,12 @@ async def async_set_swing_mode(self, swing_mode: str):
414419

415420
self._attr_swing_mode = swing_mode
416421
await self._device.settings_command(parameters).send()
422+
self.start_watcher()
417423

418424

419425
async def async_will_remove_from_hass(self):
420426
"""When entity will be removed from hass."""
421-
if self._watcher != None:
427+
if self._watcher is not None:
428+
self._watcher()
422429
self._watcher = None
423430

0 commit comments

Comments
 (0)