Skip to content

Commit b081df6

Browse files
committed
Proxmox refactor to use UPTIME sensor
1 parent c1c62e6 commit b081df6

3 files changed

Lines changed: 55 additions & 95 deletions

File tree

homeassistant/components/proxmoxve/sensor.py

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from collections.abc import Callable
44
from dataclasses import dataclass
5-
from datetime import datetime
5+
from datetime import datetime, timedelta
66
from typing import Any
77

88
from homeassistant.components.sensor import (
@@ -40,14 +40,14 @@ class ProxmoxNodeSensorEntityDescription(SensorEntityDescription):
4040
class ProxmoxVMSensorEntityDescription(SensorEntityDescription):
4141
"""Class to hold Proxmox VM sensor description."""
4242

43-
value_fn: Callable[[dict[str, Any]], StateType]
43+
value_fn: Callable[[dict[str, Any]], StateType | datetime]
4444

4545

4646
@dataclass(frozen=True, kw_only=True)
4747
class ProxmoxContainerSensorEntityDescription(SensorEntityDescription):
4848
"""Class to hold Proxmox container sensor description."""
4949

50-
value_fn: Callable[[dict[str, Any]], StateType]
50+
value_fn: Callable[[dict[str, Any]], StateType | datetime]
5151

5252

5353
@dataclass(frozen=True, kw_only=True)
@@ -128,12 +128,15 @@ class ProxmoxStorageSensorEntityDescription(SensorEntityDescription):
128128
ProxmoxNodeSensorEntityDescription(
129129
key="node_uptime",
130130
translation_key="node_uptime",
131-
value_fn=lambda data: data.node["uptime"],
132-
device_class=SensorDeviceClass.DURATION,
133-
native_unit_of_measurement=UnitOfTime.SECONDS,
134-
suggested_unit_of_measurement=UnitOfTime.HOURS,
131+
value_fn=(
132+
lambda data: (
133+
(dt_util.utcnow() - timedelta(seconds=data.node["uptime"]))
134+
if data.node["uptime"] is not None
135+
else None
136+
)
137+
),
138+
device_class=SensorDeviceClass.UPTIME,
135139
entity_category=EntityCategory.DIAGNOSTIC,
136-
state_class=SensorStateClass.MEASUREMENT,
137140
),
138141
ProxmoxNodeSensorEntityDescription(
139142
key="node_status",
@@ -218,12 +221,15 @@ class ProxmoxStorageSensorEntityDescription(SensorEntityDescription):
218221
ProxmoxVMSensorEntityDescription(
219222
key="vm_uptime",
220223
translation_key="vm_uptime",
221-
value_fn=lambda data: data["uptime"],
222-
device_class=SensorDeviceClass.DURATION,
223-
native_unit_of_measurement=UnitOfTime.SECONDS,
224-
suggested_unit_of_measurement=UnitOfTime.HOURS,
224+
value_fn=(
225+
lambda data: (
226+
(dt_util.utcnow() - timedelta(seconds=data["uptime"]))
227+
if data["uptime"] is not None
228+
else None
229+
)
230+
),
231+
device_class=SensorDeviceClass.UPTIME,
225232
entity_category=EntityCategory.DIAGNOSTIC,
226-
state_class=SensorStateClass.MEASUREMENT,
227233
),
228234
ProxmoxVMSensorEntityDescription(
229235
key="vm_disk",
@@ -327,12 +333,15 @@ class ProxmoxStorageSensorEntityDescription(SensorEntityDescription):
327333
ProxmoxContainerSensorEntityDescription(
328334
key="container_uptime",
329335
translation_key="container_uptime",
330-
value_fn=lambda data: data["uptime"],
331-
device_class=SensorDeviceClass.DURATION,
332-
native_unit_of_measurement=UnitOfTime.SECONDS,
333-
suggested_unit_of_measurement=UnitOfTime.HOURS,
336+
value_fn=(
337+
lambda data: (
338+
(dt_util.utcnow() - timedelta(seconds=data["uptime"]))
339+
if data["uptime"] is not None
340+
else None
341+
)
342+
),
343+
device_class=SensorDeviceClass.UPTIME,
334344
entity_category=EntityCategory.DIAGNOSTIC,
335-
state_class=SensorStateClass.MEASUREMENT,
336345
),
337346
ProxmoxContainerSensorEntityDescription(
338347
key="container_disk",
@@ -539,7 +548,7 @@ class ProxmoxVMSensor(ProxmoxVMEntity, SensorEntity):
539548
entity_description: ProxmoxVMSensorEntityDescription
540549

541550
@property
542-
def native_value(self) -> StateType:
551+
def native_value(self) -> StateType | datetime:
543552
"""Return the native value of the sensor."""
544553
return self.entity_description.value_fn(self.vm_data)
545554

@@ -550,7 +559,7 @@ class ProxmoxContainerSensor(ProxmoxContainerEntity, SensorEntity):
550559
entity_description: ProxmoxContainerSensorEntityDescription
551560

552561
@property
553-
def native_value(self) -> StateType:
562+
def native_value(self) -> StateType | datetime:
554563
"""Return the native value of the sensor."""
555564
return self.entity_description.value_fn(self.container_data)
556565

tests/components/proxmoxve/snapshots/test_sensor.ambr

Lines changed: 25 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -597,9 +597,7 @@
597597
None,
598598
]),
599599
'area_id': None,
600-
'capabilities': dict({
601-
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
602-
}),
600+
'capabilities': None,
603601
'config_entry_id': <ANY>,
604602
'config_subentry_id': <ANY>,
605603
'device_class': None,
@@ -617,14 +615,8 @@
617615
'name': None,
618616
'object_id_base': 'Uptime',
619617
'options': dict({
620-
'sensor': dict({
621-
'suggested_display_precision': 2,
622-
}),
623-
'sensor.private': dict({
624-
'suggested_unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
625-
}),
626618
}),
627-
'original_device_class': <SensorDeviceClass.DURATION: 'duration'>,
619+
'original_device_class': <SensorDeviceClass.UPTIME: 'uptime'>,
628620
'original_icon': None,
629621
'original_name': 'Uptime',
630622
'platform': 'proxmoxve',
@@ -633,23 +625,21 @@
633625
'supported_features': 0,
634626
'translation_key': 'container_uptime',
635627
'unique_id': '1234_201_container_uptime',
636-
'unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
628+
'unit_of_measurement': None,
637629
})
638630
# ---
639631
# name: test_all_entities[sensor.ct_backup_uptime-state]
640632
StateSnapshot({
641633
'attributes': ReadOnlyDict({
642-
'device_class': 'duration',
634+
'device_class': 'uptime',
643635
'friendly_name': 'ct-backup Uptime',
644-
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
645-
'unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
646636
}),
647637
'context': <ANY>,
648638
'entity_id': 'sensor.ct_backup_uptime',
649639
'last_changed': <ANY>,
650640
'last_reported': <ANY>,
651641
'last_updated': <ANY>,
652-
'state': '12.0',
642+
'state': '2026-05-03T00:00:00+00:00',
653643
})
654644
# ---
655645
# name: test_all_entities[sensor.ct_nginx_cpu_usage-entry]
@@ -1250,9 +1240,7 @@
12501240
None,
12511241
]),
12521242
'area_id': None,
1253-
'capabilities': dict({
1254-
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
1255-
}),
1243+
'capabilities': None,
12561244
'config_entry_id': <ANY>,
12571245
'config_subentry_id': <ANY>,
12581246
'device_class': None,
@@ -1270,14 +1258,8 @@
12701258
'name': None,
12711259
'object_id_base': 'Uptime',
12721260
'options': dict({
1273-
'sensor': dict({
1274-
'suggested_display_precision': 2,
1275-
}),
1276-
'sensor.private': dict({
1277-
'suggested_unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
1278-
}),
12791261
}),
1280-
'original_device_class': <SensorDeviceClass.DURATION: 'duration'>,
1262+
'original_device_class': <SensorDeviceClass.UPTIME: 'uptime'>,
12811263
'original_icon': None,
12821264
'original_name': 'Uptime',
12831265
'platform': 'proxmoxve',
@@ -1286,23 +1268,21 @@
12861268
'supported_features': 0,
12871269
'translation_key': 'container_uptime',
12881270
'unique_id': '1234_200_container_uptime',
1289-
'unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
1271+
'unit_of_measurement': None,
12901272
})
12911273
# ---
12921274
# name: test_all_entities[sensor.ct_nginx_uptime-state]
12931275
StateSnapshot({
12941276
'attributes': ReadOnlyDict({
1295-
'device_class': 'duration',
1277+
'device_class': 'uptime',
12961278
'friendly_name': 'ct-nginx Uptime',
1297-
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
1298-
'unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
12991279
}),
13001280
'context': <ANY>,
13011281
'entity_id': 'sensor.ct_nginx_uptime',
13021282
'last_changed': <ANY>,
13031283
'last_reported': <ANY>,
13041284
'last_updated': <ANY>,
1305-
'state': '12.0',
1285+
'state': '2026-05-03T00:00:00+00:00',
13061286
})
13071287
# ---
13081288
# name: test_all_entities[sensor.pve1_backup_duration-entry]
@@ -1891,9 +1871,7 @@
18911871
None,
18921872
]),
18931873
'area_id': None,
1894-
'capabilities': dict({
1895-
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
1896-
}),
1874+
'capabilities': None,
18971875
'config_entry_id': <ANY>,
18981876
'config_subentry_id': <ANY>,
18991877
'device_class': None,
@@ -1911,14 +1889,8 @@
19111889
'name': None,
19121890
'object_id_base': 'Uptime',
19131891
'options': dict({
1914-
'sensor': dict({
1915-
'suggested_display_precision': 2,
1916-
}),
1917-
'sensor.private': dict({
1918-
'suggested_unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
1919-
}),
19201892
}),
1921-
'original_device_class': <SensorDeviceClass.DURATION: 'duration'>,
1893+
'original_device_class': <SensorDeviceClass.UPTIME: 'uptime'>,
19221894
'original_icon': None,
19231895
'original_name': 'Uptime',
19241896
'platform': 'proxmoxve',
@@ -1927,23 +1899,21 @@
19271899
'supported_features': 0,
19281900
'translation_key': 'node_uptime',
19291901
'unique_id': '1234_node/pve1_node_uptime',
1930-
'unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
1902+
'unit_of_measurement': None,
19311903
})
19321904
# ---
19331905
# name: test_all_entities[sensor.pve1_uptime-state]
19341906
StateSnapshot({
19351907
'attributes': ReadOnlyDict({
1936-
'device_class': 'duration',
1908+
'device_class': 'uptime',
19371909
'friendly_name': 'pve1 Uptime',
1938-
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
1939-
'unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
19401910
}),
19411911
'context': <ANY>,
19421912
'entity_id': 'sensor.pve1_uptime',
19431913
'last_changed': <ANY>,
19441914
'last_reported': <ANY>,
19451915
'last_updated': <ANY>,
1946-
'state': '24.0',
1916+
'state': '2026-05-02T12:00:00+00:00',
19471917
})
19481918
# ---
19491919
# name: test_all_entities[sensor.storage_local_available_storage-entry]
@@ -3018,9 +2988,7 @@
30182988
None,
30192989
]),
30202990
'area_id': None,
3021-
'capabilities': dict({
3022-
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
3023-
}),
2991+
'capabilities': None,
30242992
'config_entry_id': <ANY>,
30252993
'config_subentry_id': <ANY>,
30262994
'device_class': None,
@@ -3038,14 +3006,8 @@
30383006
'name': None,
30393007
'object_id_base': 'Uptime',
30403008
'options': dict({
3041-
'sensor': dict({
3042-
'suggested_display_precision': 2,
3043-
}),
3044-
'sensor.private': dict({
3045-
'suggested_unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
3046-
}),
30473009
}),
3048-
'original_device_class': <SensorDeviceClass.DURATION: 'duration'>,
3010+
'original_device_class': <SensorDeviceClass.UPTIME: 'uptime'>,
30493011
'original_icon': None,
30503012
'original_name': 'Uptime',
30513013
'platform': 'proxmoxve',
@@ -3054,23 +3016,21 @@
30543016
'supported_features': 0,
30553017
'translation_key': 'vm_uptime',
30563018
'unique_id': '1234_101_vm_uptime',
3057-
'unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
3019+
'unit_of_measurement': None,
30583020
})
30593021
# ---
30603022
# name: test_all_entities[sensor.vm_db_uptime-state]
30613023
StateSnapshot({
30623024
'attributes': ReadOnlyDict({
3063-
'device_class': 'duration',
3025+
'device_class': 'uptime',
30643026
'friendly_name': 'vm-db Uptime',
3065-
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
3066-
'unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
30673027
}),
30683028
'context': <ANY>,
30693029
'entity_id': 'sensor.vm_db_uptime',
30703030
'last_changed': <ANY>,
30713031
'last_reported': <ANY>,
30723032
'last_updated': <ANY>,
3073-
'state': '24.0',
3033+
'state': '2026-05-02T12:00:00+00:00',
30743034
})
30753035
# ---
30763036
# name: test_all_entities[sensor.vm_web_cpu_usage-entry]
@@ -3671,9 +3631,7 @@
36713631
None,
36723632
]),
36733633
'area_id': None,
3674-
'capabilities': dict({
3675-
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
3676-
}),
3634+
'capabilities': None,
36773635
'config_entry_id': <ANY>,
36783636
'config_subentry_id': <ANY>,
36793637
'device_class': None,
@@ -3691,14 +3649,8 @@
36913649
'name': None,
36923650
'object_id_base': 'Uptime',
36933651
'options': dict({
3694-
'sensor': dict({
3695-
'suggested_display_precision': 2,
3696-
}),
3697-
'sensor.private': dict({
3698-
'suggested_unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
3699-
}),
37003652
}),
3701-
'original_device_class': <SensorDeviceClass.DURATION: 'duration'>,
3653+
'original_device_class': <SensorDeviceClass.UPTIME: 'uptime'>,
37023654
'original_icon': None,
37033655
'original_name': 'Uptime',
37043656
'platform': 'proxmoxve',
@@ -3707,22 +3659,20 @@
37073659
'supported_features': 0,
37083660
'translation_key': 'vm_uptime',
37093661
'unique_id': '1234_100_vm_uptime',
3710-
'unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
3662+
'unit_of_measurement': None,
37113663
})
37123664
# ---
37133665
# name: test_all_entities[sensor.vm_web_uptime-state]
37143666
StateSnapshot({
37153667
'attributes': ReadOnlyDict({
3716-
'device_class': 'duration',
3668+
'device_class': 'uptime',
37173669
'friendly_name': 'vm-web Uptime',
3718-
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
3719-
'unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
37203670
}),
37213671
'context': <ANY>,
37223672
'entity_id': 'sensor.vm_web_uptime',
37233673
'last_changed': <ANY>,
37243674
'last_reported': <ANY>,
37253675
'last_updated': <ANY>,
3726-
'state': '24.0',
3676+
'state': '2026-05-02T12:00:00+00:00',
37273677
})
37283678
# ---

tests/components/proxmoxve/test_sensor.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ def enable_all_entities(entity_registry_enabled_by_default: None) -> None:
2323
"""Make sure all entities are enabled."""
2424

2525

26+
@pytest.mark.freeze_time("2026-05-03T12:00:00+00:00")
2627
async def test_all_entities(
2728
hass: HomeAssistant,
2829
snapshot: SnapshotAssertion,

0 commit comments

Comments
 (0)