Handle single state requests from ESPHome (#124660)

Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
Jesse Hills 2024-08-28 10:15:41 +12:00 committed by GitHub
parent fa084143ef
commit e84d9e21f7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 54 additions and 2 deletions

View file

@ -329,6 +329,15 @@ class ESPHomeManager:
entity_id, attribute, hass.states.get(entity_id)
)
@callback
def async_on_state_request(
self, entity_id: str, attribute: str | None = None
) -> None:
"""Forward state for requested entity."""
self._send_home_assistant_state(
entity_id, attribute, self.hass.states.get(entity_id)
)
def _handle_pipeline_finished(self) -> None:
self.entry_data.async_set_assist_pipeline_state(False)
@ -526,7 +535,10 @@ class ESPHomeManager:
cli.subscribe_states(entry_data.async_update_state)
cli.subscribe_service_calls(self.async_on_service_call)
cli.subscribe_home_assistant_states(self.async_on_state_subscription)
cli.subscribe_home_assistant_states(
self.async_on_state_subscription,
self.async_on_state_request,
)
entry_data.async_save_to_store()
_async_check_firmware_version(hass, device_info, api_version)

View file

@ -205,6 +205,7 @@ class MockESPHomeDevice:
self.home_assistant_state_subscription_callback: Callable[
[str, str | None], None
]
self.home_assistant_state_request_callback: Callable[[str, str | None], None]
self.voice_assistant_handle_start_callback: Callable[
[str, int, VoiceAssistantAudioSettings, str | None],
Coroutine[Any, Any, int | None],
@ -268,9 +269,11 @@ class MockESPHomeDevice:
def set_home_assistant_state_subscription_callback(
self,
on_state_sub: Callable[[str, str | None], None],
on_state_request: Callable[[str, str | None], None],
) -> None:
"""Set the state call callback."""
self.home_assistant_state_subscription_callback = on_state_sub
self.home_assistant_state_request_callback = on_state_request
def mock_home_assistant_state_subscription(
self, entity_id: str, attribute: str | None
@ -278,6 +281,12 @@ class MockESPHomeDevice:
"""Mock a state subscription."""
self.home_assistant_state_subscription_callback(entity_id, attribute)
def mock_home_assistant_state_request(
self, entity_id: str, attribute: str | None
) -> None:
"""Mock a state request."""
self.home_assistant_state_request_callback(entity_id, attribute)
def set_subscribe_voice_assistant_callbacks(
self,
handle_start: Callable[
@ -378,9 +387,12 @@ async def _mock_generic_device_entry(
def _subscribe_home_assistant_states(
on_state_sub: Callable[[str, str | None], None],
on_state_request: Callable[[str, str | None], None],
) -> None:
"""Subscribe to home assistant states."""
mock_device.set_home_assistant_state_subscription_callback(on_state_sub)
mock_device.set_home_assistant_state_subscription_callback(
on_state_sub, on_state_request
)
def _subscribe_voice_assistant(
*,

View file

@ -721,6 +721,34 @@ async def test_state_subscription(
assert mock_client.send_home_assistant_state.mock_calls == []
async def test_state_request(
mock_client: APIClient,
hass: HomeAssistant,
mock_esphome_device: Callable[
[APIClient, list[EntityInfo], list[UserService], list[EntityState]],
Awaitable[MockESPHomeDevice],
],
) -> None:
"""Test ESPHome requests state change."""
device: MockESPHomeDevice = await mock_esphome_device(
mock_client=mock_client,
entity_info=[],
user_service=[],
states=[],
)
await hass.async_block_till_done()
hass.states.async_set("binary_sensor.test", "on", {"bool": True, "float": 3.0})
device.mock_home_assistant_state_request("binary_sensor.test", None)
await hass.async_block_till_done()
assert mock_client.send_home_assistant_state.mock_calls == [
call("binary_sensor.test", None, "on")
]
mock_client.send_home_assistant_state.reset_mock()
hass.states.async_set("binary_sensor.test", "off", {"bool": False, "float": 5.0})
await hass.async_block_till_done()
assert mock_client.send_home_assistant_state.mock_calls == []
async def test_debug_logging(
mock_client: APIClient,
hass: HomeAssistant,