mirror of
https://github.com/home-assistant/core.git
synced 2026-02-14 23:28:42 +00:00
Improve types and code in SpaceAPI (#162970)
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -1 +1 @@
|
||||
"""Tests for the spaceapi component."""
|
||||
"""Tests for the SpaceAPI component."""
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user