Home Assistant Unofficial Reference 2024.12.1
sensor.py
Go to the documentation of this file.
1 """Support for Speedtest.net internet speed testing sensor."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Callable
6 from dataclasses import dataclass
7 from typing import Any, cast
8 
10  SensorDeviceClass,
11  SensorEntity,
12  SensorEntityDescription,
13  SensorStateClass,
14 )
15 from homeassistant.const import UnitOfDataRate, UnitOfTime
16 from homeassistant.core import HomeAssistant
17 from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
18 from homeassistant.helpers.entity_platform import AddEntitiesCallback
19 from homeassistant.helpers.typing import StateType
20 from homeassistant.helpers.update_coordinator import CoordinatorEntity
21 
22 from . import SpeedTestConfigEntry
23 from .const import (
24  ATTR_BYTES_RECEIVED,
25  ATTR_BYTES_SENT,
26  ATTR_SERVER_COUNTRY,
27  ATTR_SERVER_ID,
28  ATTR_SERVER_NAME,
29  ATTRIBUTION,
30  DEFAULT_NAME,
31  DOMAIN,
32 )
33 from .coordinator import SpeedTestDataCoordinator
34 
35 
36 @dataclass(frozen=True)
38  """Class describing Speedtest sensor entities."""
39 
40  value: Callable = round
41 
42 
43 SENSOR_TYPES: tuple[SpeedtestSensorEntityDescription, ...] = (
45  key="ping",
46  translation_key="ping",
47  native_unit_of_measurement=UnitOfTime.MILLISECONDS,
48  state_class=SensorStateClass.MEASUREMENT,
49  device_class=SensorDeviceClass.DURATION,
50  ),
52  key="download",
53  translation_key="download",
54  native_unit_of_measurement=UnitOfDataRate.MEGABITS_PER_SECOND,
55  state_class=SensorStateClass.MEASUREMENT,
56  device_class=SensorDeviceClass.DATA_RATE,
57  value=lambda value: round(value / 10**6, 2),
58  ),
60  key="upload",
61  translation_key="upload",
62  native_unit_of_measurement=UnitOfDataRate.MEGABITS_PER_SECOND,
63  state_class=SensorStateClass.MEASUREMENT,
64  device_class=SensorDeviceClass.DATA_RATE,
65  value=lambda value: round(value / 10**6, 2),
66  ),
67 )
68 
69 
71  hass: HomeAssistant,
72  config_entry: SpeedTestConfigEntry,
73  async_add_entities: AddEntitiesCallback,
74 ) -> None:
75  """Set up the Speedtestdotnet sensors."""
76  speedtest_coordinator = config_entry.runtime_data
78  SpeedtestSensor(speedtest_coordinator, description)
79  for description in SENSOR_TYPES
80  )
81 
82 
83 class SpeedtestSensor(CoordinatorEntity[SpeedTestDataCoordinator], SensorEntity):
84  """Implementation of a speedtest.net sensor."""
85 
86  entity_description: SpeedtestSensorEntityDescription
87  _attr_attribution = ATTRIBUTION
88  _attr_has_entity_name = True
89 
90  def __init__(
91  self,
92  coordinator: SpeedTestDataCoordinator,
93  description: SpeedtestSensorEntityDescription,
94  ) -> None:
95  """Initialize the sensor."""
96  super().__init__(coordinator)
97  self.entity_descriptionentity_description = description
98  self._attr_unique_id_attr_unique_id = description.key
99  self._state_state: StateType = None
100  self._attrs: dict[str, Any] = {}
101  self._attr_device_info_attr_device_info = DeviceInfo(
102  identifiers={(DOMAIN, self.coordinator.config_entry.entry_id)},
103  name=DEFAULT_NAME,
104  entry_type=DeviceEntryType.SERVICE,
105  configuration_url="https://www.speedtest.net/",
106  )
107 
108  @property
109  def native_value(self) -> StateType:
110  """Return native value for entity."""
111  if self.coordinator.data:
112  state = self.coordinator.data[self.entity_descriptionentity_description.key]
113  self._state_state = cast(StateType, self.entity_descriptionentity_description.value(state))
114  return self._state_state
115 
116  @property
117  def extra_state_attributes(self) -> dict[str, Any]:
118  """Return the state attributes."""
119  if self.coordinator.data:
120  self._attrs.update(
121  {
122  ATTR_SERVER_NAME: self.coordinator.data["server"]["name"],
123  ATTR_SERVER_COUNTRY: self.coordinator.data["server"]["country"],
124  ATTR_SERVER_ID: self.coordinator.data["server"]["id"],
125  }
126  )
127 
128  if self.entity_descriptionentity_description.key == "download":
129  self._attrs[ATTR_BYTES_RECEIVED] = self.coordinator.data[
130  ATTR_BYTES_RECEIVED
131  ]
132  elif self.entity_descriptionentity_description.key == "upload":
133  self._attrs[ATTR_BYTES_SENT] = self.coordinator.data[ATTR_BYTES_SENT]
134 
135  return self._attrs
None __init__(self, SpeedTestDataCoordinator coordinator, SpeedtestSensorEntityDescription description)
Definition: sensor.py:94
IssData update(pyiss.ISS iss)
Definition: __init__.py:33
None async_setup_entry(HomeAssistant hass, SpeedTestConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Definition: sensor.py:74