Add CPU temperature sensor to AVM FRITZ!Box Tools (#151328)

This commit is contained in:
Roland Moers
2025-09-11 21:05:59 +02:00
committed by GitHub
parent 5413131885
commit 27c0df3da8
4 changed files with 98 additions and 0 deletions

View File

@@ -20,6 +20,7 @@ from homeassistant.const import (
EntityCategory,
UnitOfDataRate,
UnitOfInformation,
UnitOfTemperature,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
@@ -142,6 +143,13 @@ def _retrieve_link_attenuation_received_state(
return status.attenuation[1] / 10 # type: ignore[no-any-return]
def _retrieve_cpu_temperature_state(
status: FritzStatus, last_value: float | None
) -> float:
"""Return the first CPU temperature value."""
return status.get_cpu_temperatures()[0] # type: ignore[no-any-return]
@dataclass(frozen=True, kw_only=True)
class FritzSensorEntityDescription(SensorEntityDescription, FritzEntityDescription):
"""Describes Fritz sensor entity."""
@@ -274,6 +282,16 @@ SENSOR_TYPES: tuple[FritzSensorEntityDescription, ...] = (
value_fn=_retrieve_link_attenuation_received_state,
is_suitable=lambda info: info.wan_enabled and info.connection == DSL_CONNECTION,
),
FritzSensorEntityDescription(
key="cpu_temperature",
translation_key="cpu_temperature",
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
device_class=SensorDeviceClass.TEMPERATURE,
entity_category=EntityCategory.DIAGNOSTIC,
state_class=SensorStateClass.MEASUREMENT,
value_fn=_retrieve_cpu_temperature_state,
is_suitable=lambda info: True,
),
)

View File

@@ -174,6 +174,9 @@
},
"max_kb_s_sent": {
"name": "Max connection upload throughput"
},
"cpu_temperature": {
"name": "CPU Temperature"
}
}
},

View File

@@ -27,6 +27,26 @@ class FritzServiceMock(Service):
self.serviceId = serviceId
class FritzResponseMock:
"""Response mocking."""
def json(self):
"""Mock json method."""
return {"CPUTEMP": "69,68,67"}
class FritzHttpMock:
"""FritzHttp mocking."""
def __init__(self) -> None:
"""Init Mocking class."""
self.router_url = "http://fritz.box"
def call_url(self, *args, **kwargs):
"""Mock call_url method."""
return FritzResponseMock()
class FritzConnectionMock:
"""FritzConnection mocking."""
@@ -39,6 +59,7 @@ class FritzConnectionMock:
srv: FritzServiceMock(serviceId=srv, actions=actions)
for srv, actions in services.items()
}
self.http_interface = FritzHttpMock()
LOGGER.debug("-" * 80)
LOGGER.debug("FritzConnectionMock - services: %s", self.services)

View File

@@ -825,3 +825,59 @@
'state': '3.4',
})
# ---
# name: test_sensor_setup[sensor.mock_title_cpu_temperature-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_id': 'sensor.mock_title_cpu_temperature',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
'sensor': dict({
'suggested_display_precision': 1,
}),
}),
'original_device_class': <SensorDeviceClass.TEMPERATURE: 'temperature'>,
'original_icon': None,
'original_name': 'CPU Temperature',
'platform': 'fritz',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'cpu_temperature',
'unique_id': '1C:ED:6F:12:34:11-cpu_temperature',
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
})
# ---
# name: test_sensor_setup[sensor.mock_title_cpu_temperature-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'temperature',
'friendly_name': 'Mock Title CPU Temperature',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
}),
'context': <ANY>,
'entity_id': 'sensor.mock_title_cpu_temperature',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '69',
})
# ---