Skip to content

Commit 27c0df3

Browse files
authored
Add CPU temperature sensor to AVM FRITZ!Box Tools (home-assistant#151328)
1 parent 5413131 commit 27c0df3

File tree

4 files changed

+98
-0
lines changed

4 files changed

+98
-0
lines changed

homeassistant/components/fritz/sensor.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
EntityCategory,
2121
UnitOfDataRate,
2222
UnitOfInformation,
23+
UnitOfTemperature,
2324
)
2425
from homeassistant.core import HomeAssistant
2526
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
@@ -142,6 +143,13 @@ def _retrieve_link_attenuation_received_state(
142143
return status.attenuation[1] / 10 # type: ignore[no-any-return]
143144

144145

146+
def _retrieve_cpu_temperature_state(
147+
status: FritzStatus, last_value: float | None
148+
) -> float:
149+
"""Return the first CPU temperature value."""
150+
return status.get_cpu_temperatures()[0] # type: ignore[no-any-return]
151+
152+
145153
@dataclass(frozen=True, kw_only=True)
146154
class FritzSensorEntityDescription(SensorEntityDescription, FritzEntityDescription):
147155
"""Describes Fritz sensor entity."""
@@ -274,6 +282,16 @@ class FritzSensorEntityDescription(SensorEntityDescription, FritzEntityDescripti
274282
value_fn=_retrieve_link_attenuation_received_state,
275283
is_suitable=lambda info: info.wan_enabled and info.connection == DSL_CONNECTION,
276284
),
285+
FritzSensorEntityDescription(
286+
key="cpu_temperature",
287+
translation_key="cpu_temperature",
288+
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
289+
device_class=SensorDeviceClass.TEMPERATURE,
290+
entity_category=EntityCategory.DIAGNOSTIC,
291+
state_class=SensorStateClass.MEASUREMENT,
292+
value_fn=_retrieve_cpu_temperature_state,
293+
is_suitable=lambda info: True,
294+
),
277295
)
278296

279297

homeassistant/components/fritz/strings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,9 @@
174174
},
175175
"max_kb_s_sent": {
176176
"name": "Max connection upload throughput"
177+
},
178+
"cpu_temperature": {
179+
"name": "CPU Temperature"
177180
}
178181
}
179182
},

tests/components/fritz/conftest.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,26 @@ def __init__(self, serviceId: str, actions: dict) -> None:
2727
self.serviceId = serviceId
2828

2929

30+
class FritzResponseMock:
31+
"""Response mocking."""
32+
33+
def json(self):
34+
"""Mock json method."""
35+
return {"CPUTEMP": "69,68,67"}
36+
37+
38+
class FritzHttpMock:
39+
"""FritzHttp mocking."""
40+
41+
def __init__(self) -> None:
42+
"""Init Mocking class."""
43+
self.router_url = "http://fritz.box"
44+
45+
def call_url(self, *args, **kwargs):
46+
"""Mock call_url method."""
47+
return FritzResponseMock()
48+
49+
3050
class FritzConnectionMock:
3151
"""FritzConnection mocking."""
3252

@@ -39,6 +59,7 @@ def __init__(self, services) -> None:
3959
srv: FritzServiceMock(serviceId=srv, actions=actions)
4060
for srv, actions in services.items()
4161
}
62+
self.http_interface = FritzHttpMock()
4263
LOGGER.debug("-" * 80)
4364
LOGGER.debug("FritzConnectionMock - services: %s", self.services)
4465

tests/components/fritz/snapshots/test_sensor.ambr

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,3 +825,59 @@
825825
'state': '3.4',
826826
})
827827
# ---
828+
# name: test_sensor_setup[sensor.mock_title_cpu_temperature-entry]
829+
EntityRegistryEntrySnapshot({
830+
'aliases': set({
831+
}),
832+
'area_id': None,
833+
'capabilities': dict({
834+
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
835+
}),
836+
'config_entry_id': <ANY>,
837+
'config_subentry_id': <ANY>,
838+
'device_class': None,
839+
'device_id': <ANY>,
840+
'disabled_by': None,
841+
'domain': 'sensor',
842+
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
843+
'entity_id': 'sensor.mock_title_cpu_temperature',
844+
'has_entity_name': True,
845+
'hidden_by': None,
846+
'icon': None,
847+
'id': <ANY>,
848+
'labels': set({
849+
}),
850+
'name': None,
851+
'options': dict({
852+
'sensor': dict({
853+
'suggested_display_precision': 1,
854+
}),
855+
}),
856+
'original_device_class': <SensorDeviceClass.TEMPERATURE: 'temperature'>,
857+
'original_icon': None,
858+
'original_name': 'CPU Temperature',
859+
'platform': 'fritz',
860+
'previous_unique_id': None,
861+
'suggested_object_id': None,
862+
'supported_features': 0,
863+
'translation_key': 'cpu_temperature',
864+
'unique_id': '1C:ED:6F:12:34:11-cpu_temperature',
865+
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
866+
})
867+
# ---
868+
# name: test_sensor_setup[sensor.mock_title_cpu_temperature-state]
869+
StateSnapshot({
870+
'attributes': ReadOnlyDict({
871+
'device_class': 'temperature',
872+
'friendly_name': 'Mock Title CPU Temperature',
873+
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
874+
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
875+
}),
876+
'context': <ANY>,
877+
'entity_id': 'sensor.mock_title_cpu_temperature',
878+
'last_changed': <ANY>,
879+
'last_reported': <ANY>,
880+
'last_updated': <ANY>,
881+
'state': '69',
882+
})
883+
# ---

0 commit comments

Comments
 (0)