diff --git a/homeassistant/components/spaceapi/__init__.py b/homeassistant/components/spaceapi/__init__.py index 6ef643488ad..7460cc5dcdf 100644 --- a/homeassistant/components/spaceapi/__init__.py +++ b/homeassistant/components/spaceapi/__init__.py @@ -2,7 +2,9 @@ from contextlib import suppress import math +from typing import Any +from aiohttp import web import voluptuous as vol from homeassistant import core as ha @@ -251,9 +253,11 @@ class APISpaceApiView(HomeAssistantView): name = "api:spaceapi" @staticmethod - def get_sensor_data(hass, spaceapi, sensor): + def get_sensor_data( + hass: HomeAssistant, spaceapi: dict[str, Any], entity_id: str + ) -> dict[str, str | float | dict[str, str]] | None: """Get data from a sensor.""" - if not (sensor_state := hass.states.get(sensor)): + if not (sensor_state := hass.states.get(entity_id)): return None # SpaceAPI sensor values must be numbers @@ -261,7 +265,7 @@ class APISpaceApiView(HomeAssistantView): state = float(sensor_state.state) except ValueError: state = math.nan - sensor_data = { + sensor_data: dict[str, str | float | dict[str, str]] = { ATTR_NAME: sensor_state.name, ATTR_VALUE: state, } @@ -273,16 +277,19 @@ class APISpaceApiView(HomeAssistantView): # Some sensors don't have a unit of measurement if ATTR_UNIT_OF_MEASUREMENT in sensor_state.attributes: sensor_data[ATTR_UNIT] = sensor_state.attributes[ATTR_UNIT_OF_MEASUREMENT] + return sensor_data @ha.callback - def get(self, request): + def get(self, request: web.Request) -> web.Response: """Get SpaceAPI data.""" hass = request.app[KEY_HASS] - spaceapi = dict(hass.data[DATA_SPACEAPI]) - is_sensors = spaceapi.get("sensors") + spaceapi: dict[str, Any] = hass.data[DATA_SPACEAPI] - location = {ATTR_LAT: hass.config.latitude, ATTR_LON: hass.config.longitude} + location = { + ATTR_LAT: hass.config.latitude, + ATTR_LON: hass.config.longitude, + } try: location[ATTR_ADDRESS] = spaceapi[ATTR_LOCATION][CONF_ADDRESS] @@ -291,20 +298,24 @@ class APISpaceApiView(HomeAssistantView): except TypeError: pass - state_entity = spaceapi["state"][ATTR_ENTITY_ID] + state_entity_id = spaceapi[CONF_STATE][ATTR_ENTITY_ID] - if (space_state := hass.states.get(state_entity)) is not None: + state: dict[str, bool | int | float | str | dict[str, str]] + if (space_state := hass.states.get(state_entity_id)) is not None: state = { ATTR_OPEN: space_state.state != "off", ATTR_LASTCHANGE: dt_util.as_timestamp(space_state.last_updated), } else: - state = {ATTR_OPEN: "null", ATTR_LASTCHANGE: 0} + state = { + ATTR_OPEN: "null", + ATTR_LASTCHANGE: 0, + } with suppress(KeyError): state[ATTR_ICON] = { - ATTR_OPEN: spaceapi["state"][CONF_ICON_OPEN], - ATTR_CLOSED: spaceapi["state"][CONF_ICON_CLOSED], + ATTR_OPEN: spaceapi[CONF_STATE][CONF_ICON_OPEN], + ATTR_CLOSED: spaceapi[CONF_STATE][CONF_ICON_CLOSED], } data = { @@ -339,13 +350,16 @@ class APISpaceApiView(HomeAssistantView): with suppress(KeyError): data[ATTR_RADIO_SHOW] = spaceapi[CONF_RADIO_SHOW] - if is_sensors is not None: - sensors = {} - for sensor_type in is_sensors: - sensors[sensor_type] = [] - for sensor in spaceapi["sensors"][sensor_type]: - sensor_data = self.get_sensor_data(hass, spaceapi, sensor) - sensors[sensor_type].append(sensor_data) - data[ATTR_SENSORS] = sensors + sensors: dict[str, list[str]] | None = spaceapi.get(CONF_SENSORS) + if isinstance(sensors, dict): + sensors_data: dict[str, list[dict[str, str | float | dict[str, str]]]] = {} + for sensor_type, entity_ids in sensors.items(): + sensors_data[sensor_type] = [ + sensor_data + for entity_id in entity_ids + if (sensor_data := self.get_sensor_data(hass, spaceapi, entity_id)) + is not None + ] + data[ATTR_SENSORS] = sensors_data return self.json(data) diff --git a/tests/components/spaceapi/__init__.py b/tests/components/spaceapi/__init__.py index 0b24e36acb2..49d9b893ff4 100644 --- a/tests/components/spaceapi/__init__.py +++ b/tests/components/spaceapi/__init__.py @@ -1 +1 @@ -"""Tests for the spaceapi component.""" +"""Tests for the SpaceAPI component.""" diff --git a/tests/components/spaceapi/test_init.py b/tests/components/spaceapi/test_init.py index 154ddb9253e..ae16a8fcf30 100644 --- a/tests/components/spaceapi/test_init.py +++ b/tests/components/spaceapi/test_init.py @@ -131,7 +131,7 @@ async def mock_client( return await hass_client() -async def test_spaceapi_get(hass: HomeAssistant, mock_client) -> None: +async def test_spaceapi_get(hass: HomeAssistant, mock_client: TestClient) -> None: """Test response after start-up Home Assistant.""" resp = await mock_client.get(URL_API_SPACEAPI) assert resp.status == HTTPStatus.OK @@ -175,7 +175,7 @@ async def test_spaceapi_get(hass: HomeAssistant, mock_client) -> None: assert data["radio_show"][0]["end"] == "2019-09-02T12:00Z" -async def test_spaceapi_state_get(hass: HomeAssistant, mock_client) -> None: +async def test_spaceapi_state_get(hass: HomeAssistant, mock_client: TestClient) -> None: """Test response if the state entity was set.""" hass.states.async_set("test.test_door", True) @@ -186,7 +186,9 @@ async def test_spaceapi_state_get(hass: HomeAssistant, mock_client) -> None: assert data["state"]["open"] == bool(1) -async def test_spaceapi_sensors_get(hass: HomeAssistant, mock_client) -> None: +async def test_spaceapi_sensors_get( + hass: HomeAssistant, mock_client: TestClient +) -> None: """Test the response for the sensors.""" resp = await mock_client.get(URL_API_SPACEAPI) assert resp.status == HTTPStatus.OK