Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 29 additions & 20 deletions homeassistant/components/proxmoxve/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from collections.abc import Callable
from dataclasses import dataclass
from datetime import datetime
from datetime import datetime, timedelta
from typing import Any

from homeassistant.components.sensor import (
Expand Down Expand Up @@ -40,14 +40,14 @@ class ProxmoxNodeSensorEntityDescription(SensorEntityDescription):
class ProxmoxVMSensorEntityDescription(SensorEntityDescription):
"""Class to hold Proxmox VM sensor description."""

value_fn: Callable[[dict[str, Any]], StateType]
value_fn: Callable[[dict[str, Any]], StateType | datetime]


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

value_fn: Callable[[dict[str, Any]], StateType]
value_fn: Callable[[dict[str, Any]], StateType | datetime]


@dataclass(frozen=True, kw_only=True)
Expand Down Expand Up @@ -128,12 +128,15 @@ class ProxmoxStorageSensorEntityDescription(SensorEntityDescription):
ProxmoxNodeSensorEntityDescription(
key="node_uptime",
translation_key="node_uptime",
value_fn=lambda data: data.node["uptime"],
device_class=SensorDeviceClass.DURATION,
native_unit_of_measurement=UnitOfTime.SECONDS,
suggested_unit_of_measurement=UnitOfTime.HOURS,
value_fn=(
lambda data: (
(dt_util.utcnow() - timedelta(seconds=data.node["uptime"]))
if data.node["uptime"] is not None
else None
)
),
device_class=SensorDeviceClass.UPTIME,
entity_category=EntityCategory.DIAGNOSTIC,
state_class=SensorStateClass.MEASUREMENT,
),
Comment on lines 128 to 140
Comment on lines 128 to 140
ProxmoxNodeSensorEntityDescription(
key="node_status",
Expand Down Expand Up @@ -218,12 +221,15 @@ class ProxmoxStorageSensorEntityDescription(SensorEntityDescription):
ProxmoxVMSensorEntityDescription(
key="vm_uptime",
translation_key="vm_uptime",
value_fn=lambda data: data["uptime"],
device_class=SensorDeviceClass.DURATION,
native_unit_of_measurement=UnitOfTime.SECONDS,
suggested_unit_of_measurement=UnitOfTime.HOURS,
value_fn=(
lambda data: (
(dt_util.utcnow() - timedelta(seconds=data["uptime"]))
if data["uptime"] is not None
else None
)
),
device_class=SensorDeviceClass.UPTIME,
entity_category=EntityCategory.DIAGNOSTIC,
state_class=SensorStateClass.MEASUREMENT,
),
ProxmoxVMSensorEntityDescription(
key="vm_disk",
Expand Down Expand Up @@ -327,12 +333,15 @@ class ProxmoxStorageSensorEntityDescription(SensorEntityDescription):
ProxmoxContainerSensorEntityDescription(
key="container_uptime",
translation_key="container_uptime",
value_fn=lambda data: data["uptime"],
device_class=SensorDeviceClass.DURATION,
native_unit_of_measurement=UnitOfTime.SECONDS,
suggested_unit_of_measurement=UnitOfTime.HOURS,
value_fn=(
lambda data: (
(dt_util.utcnow() - timedelta(seconds=data["uptime"]))
if data["uptime"] is not None
else None
)
),
device_class=SensorDeviceClass.UPTIME,
entity_category=EntityCategory.DIAGNOSTIC,
state_class=SensorStateClass.MEASUREMENT,
),
ProxmoxContainerSensorEntityDescription(
key="container_disk",
Expand Down Expand Up @@ -539,7 +548,7 @@ class ProxmoxVMSensor(ProxmoxVMEntity, SensorEntity):
entity_description: ProxmoxVMSensorEntityDescription

@property
def native_value(self) -> StateType:
def native_value(self) -> StateType | datetime:
"""Return the native value of the sensor."""
return self.entity_description.value_fn(self.vm_data)

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

@property
def native_value(self) -> StateType:
def native_value(self) -> StateType | datetime:
"""Return the native value of the sensor."""
return self.entity_description.value_fn(self.container_data)

Expand Down
100 changes: 25 additions & 75 deletions tests/components/proxmoxve/snapshots/test_sensor.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -597,9 +597,7 @@
None,
]),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'capabilities': None,
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
Expand All @@ -617,14 +615,8 @@
'name': None,
'object_id_base': 'Uptime',
'options': dict({
'sensor': dict({
'suggested_display_precision': 2,
}),
'sensor.private': dict({
'suggested_unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
}),
}),
'original_device_class': <SensorDeviceClass.DURATION: 'duration'>,
'original_device_class': <SensorDeviceClass.UPTIME: 'uptime'>,
'original_icon': None,
'original_name': 'Uptime',
'platform': 'proxmoxve',
Expand All @@ -633,23 +625,21 @@
'supported_features': 0,
'translation_key': 'container_uptime',
'unique_id': '1234_201_container_uptime',
'unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[sensor.ct_backup_uptime-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'duration',
'device_class': 'uptime',
'friendly_name': 'ct-backup Uptime',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
}),
'context': <ANY>,
'entity_id': 'sensor.ct_backup_uptime',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '12.0',
'state': '2026-05-03T00:00:00+00:00',
})
# ---
# name: test_all_entities[sensor.ct_nginx_cpu_usage-entry]
Expand Down Expand Up @@ -1250,9 +1240,7 @@
None,
]),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'capabilities': None,
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
Expand All @@ -1270,14 +1258,8 @@
'name': None,
'object_id_base': 'Uptime',
'options': dict({
'sensor': dict({
'suggested_display_precision': 2,
}),
'sensor.private': dict({
'suggested_unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
}),
}),
'original_device_class': <SensorDeviceClass.DURATION: 'duration'>,
'original_device_class': <SensorDeviceClass.UPTIME: 'uptime'>,
'original_icon': None,
'original_name': 'Uptime',
'platform': 'proxmoxve',
Expand All @@ -1286,23 +1268,21 @@
'supported_features': 0,
'translation_key': 'container_uptime',
'unique_id': '1234_200_container_uptime',
'unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[sensor.ct_nginx_uptime-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'duration',
'device_class': 'uptime',
'friendly_name': 'ct-nginx Uptime',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
}),
'context': <ANY>,
'entity_id': 'sensor.ct_nginx_uptime',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '12.0',
'state': '2026-05-03T00:00:00+00:00',
})
# ---
# name: test_all_entities[sensor.pve1_backup_duration-entry]
Expand Down Expand Up @@ -1891,9 +1871,7 @@
None,
]),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'capabilities': None,
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
Expand All @@ -1911,14 +1889,8 @@
'name': None,
'object_id_base': 'Uptime',
'options': dict({
'sensor': dict({
'suggested_display_precision': 2,
}),
'sensor.private': dict({
'suggested_unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
}),
}),
'original_device_class': <SensorDeviceClass.DURATION: 'duration'>,
'original_device_class': <SensorDeviceClass.UPTIME: 'uptime'>,
'original_icon': None,
'original_name': 'Uptime',
'platform': 'proxmoxve',
Expand All @@ -1927,23 +1899,21 @@
'supported_features': 0,
'translation_key': 'node_uptime',
'unique_id': '1234_node/pve1_node_uptime',
'unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[sensor.pve1_uptime-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'duration',
'device_class': 'uptime',
'friendly_name': 'pve1 Uptime',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
}),
'context': <ANY>,
'entity_id': 'sensor.pve1_uptime',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '24.0',
'state': '2026-05-02T12:00:00+00:00',
})
# ---
# name: test_all_entities[sensor.storage_local_available_storage-entry]
Expand Down Expand Up @@ -3018,9 +2988,7 @@
None,
]),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'capabilities': None,
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
Expand All @@ -3038,14 +3006,8 @@
'name': None,
'object_id_base': 'Uptime',
'options': dict({
'sensor': dict({
'suggested_display_precision': 2,
}),
'sensor.private': dict({
'suggested_unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
}),
}),
'original_device_class': <SensorDeviceClass.DURATION: 'duration'>,
'original_device_class': <SensorDeviceClass.UPTIME: 'uptime'>,
'original_icon': None,
'original_name': 'Uptime',
'platform': 'proxmoxve',
Expand All @@ -3054,23 +3016,21 @@
'supported_features': 0,
'translation_key': 'vm_uptime',
'unique_id': '1234_101_vm_uptime',
'unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[sensor.vm_db_uptime-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'duration',
'device_class': 'uptime',
'friendly_name': 'vm-db Uptime',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
}),
'context': <ANY>,
'entity_id': 'sensor.vm_db_uptime',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '24.0',
'state': '2026-05-02T12:00:00+00:00',
})
# ---
# name: test_all_entities[sensor.vm_web_cpu_usage-entry]
Expand Down Expand Up @@ -3671,9 +3631,7 @@
None,
]),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'capabilities': None,
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
Expand All @@ -3691,14 +3649,8 @@
'name': None,
'object_id_base': 'Uptime',
'options': dict({
'sensor': dict({
'suggested_display_precision': 2,
}),
'sensor.private': dict({
'suggested_unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
}),
}),
'original_device_class': <SensorDeviceClass.DURATION: 'duration'>,
'original_device_class': <SensorDeviceClass.UPTIME: 'uptime'>,
'original_icon': None,
'original_name': 'Uptime',
'platform': 'proxmoxve',
Expand All @@ -3707,22 +3659,20 @@
'supported_features': 0,
'translation_key': 'vm_uptime',
'unique_id': '1234_100_vm_uptime',
'unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[sensor.vm_web_uptime-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'duration',
'device_class': 'uptime',
'friendly_name': 'vm-web Uptime',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
}),
'context': <ANY>,
'entity_id': 'sensor.vm_web_uptime',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '24.0',
'state': '2026-05-02T12:00:00+00:00',
})
# ---
1 change: 1 addition & 0 deletions tests/components/proxmoxve/test_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def enable_all_entities(entity_registry_enabled_by_default: None) -> None:
"""Make sure all entities are enabled."""


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