Skip to content

Commit 4c46099

Browse files
authored
fix #1983 - fallback to home assistant state in get_state if entity state not yet cached (#1996)
* fix #1983 - fallback to home assistant state in get_state if entity state not yet cached * fix pylance test
1 parent ef8761a commit 4c46099

3 files changed

Lines changed: 32 additions & 2 deletions

File tree

custom_components/versatile_thermostat/state_manager.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@ async def calculate_current_hvac_mode(self, vtherm: "BaseThermostat") -> bool:
146146
self._current_state.set_hvac_mode(VThermHvacMode_OFF)
147147

148148
elif vtherm.last_central_mode == CENTRAL_MODE_FROST_PROTECTION and self._requested_state.hvac_mode != VThermHvacMode_OFF:
149-
if VThermPreset.FROST not in vtherm.vtherm_preset_modes or VThermHvacMode_HEAT not in vtherm.vtherm_hvac_modes:
149+
preset_modes = vtherm.vtherm_preset_modes
150+
if preset_modes is None or VThermPreset.FROST not in preset_modes or VThermHvacMode_HEAT not in vtherm.vtherm_hvac_modes:
150151
self._current_state.set_hvac_mode(VThermHvacMode_OFF)
151152
vtherm.set_hvac_off_reason(HVAC_OFF_REASON_CENTRAL_MODE)
152153
elif vtherm.vtherm_hvac_mode != VThermHvacMode_HEAT and VThermHvacMode_HEAT in vtherm.vtherm_hvac_modes:
@@ -196,7 +197,8 @@ async def calculate_current_preset(self, vtherm: "BaseThermostat") -> bool:
196197
self._current_state.set_preset(VThermPreset.SAFETY)
197198

198199
elif vtherm.last_central_mode == CENTRAL_MODE_FROST_PROTECTION:
199-
if VThermPreset.FROST in vtherm.vtherm_preset_modes and vtherm.vtherm_hvac_mode == VThermHvacMode_HEAT:
200+
preset_modes = vtherm.vtherm_preset_modes
201+
if preset_modes is not None and VThermPreset.FROST in preset_modes and vtherm.vtherm_hvac_mode == VThermHvacMode_HEAT:
200202
self._current_state.set_preset(VThermPreset.FROST)
201203
vtherm.set_temperature_reason(MSG_TARGET_TEMP_CENTRAL_MODE)
202204

custom_components/versatile_thermostat/underlying_state_manager.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,13 @@ def get_state(self, entity_id: str) -> Optional[State]:
7878
"""Return the last known `State` for `entity_id`, or `None` if unknown."""
7979
idx = self._index_of(entity_id)
8080
if idx is None:
81+
state = self._hass.states.get(entity_id)
82+
if state is not None:
83+
_LOGGER.debug(
84+
"UnderlyingStateManager - Requested state for unknown entity_id: %s, found in HA",
85+
entity_id,
86+
)
87+
return state
8188
_LOGGER.error("UnderlyingStateManager - Requested state for unknown entity_id: %s", entity_id)
8289
return None
8390
return self._states[idx]

tests/test_under_state_manager.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,3 +94,24 @@ async def on_change(entity_id: str, state, old_state):
9494
hass.states.async_set("switch.cb", "off")
9595
await hass.async_block_till_done()
9696
assert len(calls) == before
97+
98+
99+
async def test_get_state_unknown_but_found_in_ha(hass: HomeAssistant):
100+
"""Test get_state with an unknown entity_id, which gets retrieved from HA but not added to manager."""
101+
mgr = UnderlyingStateManager(hass)
102+
assert mgr._entity_ids == []
103+
104+
# Prepare state in HA but do not add to manager initially
105+
hass.states.async_set("switch.test_ha_only", "on")
106+
await hass.async_block_till_done()
107+
108+
# Request state of unknown entity_id, should retrieve it from HA without adding it
109+
state = mgr.get_state("switch.test_ha_only")
110+
assert state is not None
111+
assert state.state == "on"
112+
assert "switch.test_ha_only" not in mgr._entity_ids
113+
114+
# Request state of another still unknown entity, which is not in HA either, should return None
115+
state_unknown = mgr.get_state("sensor.not_existing")
116+
assert state_unknown is None
117+
assert "sensor.not_existing" not in mgr._entity_ids

0 commit comments

Comments
 (0)