Add state class measurement to all suitable sensors on Speedtest.net (#53693)

* Add state class measurement

* use tuple instead of list
This commit is contained in:
Michael 2021-08-02 17:00:25 +02:00 committed by GitHub
parent 1265aa0f64
commit bffa9f960d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 23 deletions

View file

@ -1,17 +1,38 @@
"""Consts used by Speedtest.net.""" """Consts used by Speedtest.net."""
from __future__ import annotations
from typing import Final from typing import Final
from homeassistant.components.sensor import (
STATE_CLASS_MEASUREMENT,
SensorEntityDescription,
)
from homeassistant.const import DATA_RATE_MEGABITS_PER_SECOND, TIME_MILLISECONDS from homeassistant.const import DATA_RATE_MEGABITS_PER_SECOND, TIME_MILLISECONDS
DOMAIN: Final = "speedtestdotnet" DOMAIN: Final = "speedtestdotnet"
SPEED_TEST_SERVICE: Final = "speedtest" SPEED_TEST_SERVICE: Final = "speedtest"
SENSOR_TYPES: Final = { SENSOR_TYPES: Final[tuple[SensorEntityDescription, ...]] = (
"ping": ["Ping", TIME_MILLISECONDS], SensorEntityDescription(
"download": ["Download", DATA_RATE_MEGABITS_PER_SECOND], key="ping",
"upload": ["Upload", DATA_RATE_MEGABITS_PER_SECOND], name="Ping",
} unit_of_measurement=TIME_MILLISECONDS,
state_class=STATE_CLASS_MEASUREMENT,
),
SensorEntityDescription(
key="download",
name="Download",
unit_of_measurement=DATA_RATE_MEGABITS_PER_SECOND,
state_class=STATE_CLASS_MEASUREMENT,
),
SensorEntityDescription(
key="upload",
name="Upload",
unit_of_measurement=DATA_RATE_MEGABITS_PER_SECOND,
state_class=STATE_CLASS_MEASUREMENT,
),
)
CONF_SERVER_NAME: Final = "server_name" CONF_SERVER_NAME: Final = "server_name"
CONF_SERVER_ID: Final = "server_id" CONF_SERVER_ID: Final = "server_id"

View file

@ -3,7 +3,7 @@ from __future__ import annotations
from typing import Any from typing import Any
from homeassistant.components.sensor import SensorEntity from homeassistant.components.sensor import SensorEntity, SensorEntityDescription
from homeassistant.components.speedtestdotnet import SpeedTestDataCoordinator from homeassistant.components.speedtestdotnet import SpeedTestDataCoordinator
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_ATTRIBUTION from homeassistant.const import ATTR_ATTRIBUTION
@ -34,8 +34,8 @@ async def async_setup_entry(
"""Set up the Speedtestdotnet sensors.""" """Set up the Speedtestdotnet sensors."""
speedtest_coordinator = hass.data[DOMAIN] speedtest_coordinator = hass.data[DOMAIN]
async_add_entities( async_add_entities(
SpeedtestSensor(speedtest_coordinator, sensor_type) SpeedtestSensor(speedtest_coordinator, description)
for sensor_type in SENSOR_TYPES for description in SENSOR_TYPES
) )
@ -46,14 +46,17 @@ class SpeedtestSensor(CoordinatorEntity, RestoreEntity, SensorEntity):
_attr_icon = ICON _attr_icon = ICON
def __init__(self, coordinator: SpeedTestDataCoordinator, sensor_type: str) -> None: def __init__(
self,
coordinator: SpeedTestDataCoordinator,
description: SensorEntityDescription,
) -> None:
"""Initialize the sensor.""" """Initialize the sensor."""
super().__init__(coordinator) super().__init__(coordinator)
self.type = sensor_type self.entity_description = description
self._attr_name = f"{DEFAULT_NAME} {SENSOR_TYPES[sensor_type][0]}" self._attr_name = f"{DEFAULT_NAME} {description.name}"
self._attr_unit_of_measurement = SENSOR_TYPES[self.type][1] self._attr_unique_id = description.key
self._attr_unique_id = sensor_type
self._attrs = {ATTR_ATTRIBUTION: ATTRIBUTION} self._attrs = {ATTR_ATTRIBUTION: ATTRIBUTION}
@property @property
@ -68,11 +71,11 @@ class SpeedtestSensor(CoordinatorEntity, RestoreEntity, SensorEntity):
} }
) )
if self.type == "download": if self.entity_description.key == "download":
self._attrs[ATTR_BYTES_RECEIVED] = self.coordinator.data[ self._attrs[ATTR_BYTES_RECEIVED] = self.coordinator.data[
"bytes_received" "bytes_received"
] ]
elif self.type == "upload": elif self.entity_description.key == "upload":
self._attrs[ATTR_BYTES_SENT] = self.coordinator.data["bytes_sent"] self._attrs[ATTR_BYTES_SENT] = self.coordinator.data["bytes_sent"]
return self._attrs return self._attrs
@ -96,9 +99,9 @@ class SpeedtestSensor(CoordinatorEntity, RestoreEntity, SensorEntity):
def _update_state(self): def _update_state(self):
"""Update sensors state.""" """Update sensors state."""
if self.coordinator.data: if self.coordinator.data:
if self.type == "ping": if self.entity_description.key == "ping":
self._attr_state = self.coordinator.data["ping"] self._attr_state = self.coordinator.data["ping"]
elif self.type == "download": elif self.entity_description.key == "download":
self._attr_state = round(self.coordinator.data["download"] / 10 ** 6, 2) self._attr_state = round(self.coordinator.data["download"] / 10 ** 6, 2)
elif self.type == "upload": elif self.entity_description.key == "upload":
self._attr_state = round(self.coordinator.data["upload"] / 10 ** 6, 2) self._attr_state = round(self.coordinator.data["upload"] / 10 ** 6, 2)

View file

@ -26,9 +26,7 @@ async def test_speedtestdotnet_sensors(
assert len(hass.states.async_entity_ids(SENSOR_DOMAIN)) == 3 assert len(hass.states.async_entity_ids(SENSOR_DOMAIN)) == 3
for sensor_type in SENSOR_TYPES: for description in SENSOR_TYPES:
sensor = hass.states.get( sensor = hass.states.get(f"sensor.{DEFAULT_NAME}_{description.name}")
f"sensor.{DEFAULT_NAME}_{SENSOR_TYPES[sensor_type][0]}"
)
assert sensor assert sensor
assert sensor.state == MOCK_STATES[sensor_type] assert sensor.state == MOCK_STATES[description.key]