mirror of
https://github.com/home-assistant/core.git
synced 2026-04-02 08:26:41 +01:00
feat(transmission): add session and cumulative stats sensors (#166134)
This commit is contained in:
@@ -21,12 +21,30 @@
|
||||
"paused_torrents": {
|
||||
"default": "mdi:counter"
|
||||
},
|
||||
"session_download": {
|
||||
"default": "mdi:download"
|
||||
},
|
||||
"session_ratio": {
|
||||
"default": "mdi:swap-vertical"
|
||||
},
|
||||
"session_upload": {
|
||||
"default": "mdi:upload"
|
||||
},
|
||||
"started_torrents": {
|
||||
"default": "mdi:counter"
|
||||
},
|
||||
"total_download": {
|
||||
"default": "mdi:download-multiple"
|
||||
},
|
||||
"total_ratio": {
|
||||
"default": "mdi:swap-vertical-bold"
|
||||
},
|
||||
"total_torrents": {
|
||||
"default": "mdi:counter"
|
||||
},
|
||||
"total_upload": {
|
||||
"default": "mdi:upload-multiple"
|
||||
},
|
||||
"transmission_status": {
|
||||
"default": "mdi:information-outline"
|
||||
},
|
||||
|
||||
@@ -11,8 +11,9 @@ from homeassistant.components.sensor import (
|
||||
SensorDeviceClass,
|
||||
SensorEntity,
|
||||
SensorEntityDescription,
|
||||
SensorStateClass,
|
||||
)
|
||||
from homeassistant.const import STATE_IDLE, UnitOfDataRate
|
||||
from homeassistant.const import STATE_IDLE, UnitOfDataRate, UnitOfInformation
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
from homeassistant.helpers.typing import StateType
|
||||
@@ -40,6 +41,18 @@ class TransmissionSensorEntityDescription(SensorEntityDescription):
|
||||
extra_state_attr_func: Callable[[Any], dict[str, str]] | None = None
|
||||
|
||||
|
||||
def _compute_ratio(uploaded: int | None, downloaded: int | None) -> float | None:
|
||||
"""Compute upload/download ratio.
|
||||
|
||||
Returns None when data is unavailable or downloaded == 0.
|
||||
"""
|
||||
if uploaded is None or downloaded is None:
|
||||
return None
|
||||
if downloaded == 0:
|
||||
return None
|
||||
return uploaded / downloaded
|
||||
|
||||
|
||||
SENSOR_TYPES: tuple[TransmissionSensorEntityDescription, ...] = (
|
||||
TransmissionSensorEntityDescription(
|
||||
key="download",
|
||||
@@ -112,6 +125,66 @@ SENSOR_TYPES: tuple[TransmissionSensorEntityDescription, ...] = (
|
||||
coordinator=coordinator, key="started"
|
||||
),
|
||||
),
|
||||
TransmissionSensorEntityDescription(
|
||||
key="session_download",
|
||||
translation_key="session_download",
|
||||
device_class=SensorDeviceClass.DATA_SIZE,
|
||||
native_unit_of_measurement=UnitOfInformation.BYTES,
|
||||
suggested_unit_of_measurement=UnitOfInformation.GIBIBYTES,
|
||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||
suggested_display_precision=3,
|
||||
val_func=lambda coordinator: coordinator.data.current_stats.downloaded_bytes,
|
||||
),
|
||||
TransmissionSensorEntityDescription(
|
||||
key="session_upload",
|
||||
translation_key="session_upload",
|
||||
device_class=SensorDeviceClass.DATA_SIZE,
|
||||
native_unit_of_measurement=UnitOfInformation.BYTES,
|
||||
suggested_unit_of_measurement=UnitOfInformation.GIBIBYTES,
|
||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||
suggested_display_precision=3,
|
||||
val_func=lambda coordinator: coordinator.data.current_stats.uploaded_bytes,
|
||||
),
|
||||
TransmissionSensorEntityDescription(
|
||||
key="total_download",
|
||||
translation_key="total_download",
|
||||
device_class=SensorDeviceClass.DATA_SIZE,
|
||||
native_unit_of_measurement=UnitOfInformation.BYTES,
|
||||
suggested_unit_of_measurement=UnitOfInformation.GIBIBYTES,
|
||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||
suggested_display_precision=3,
|
||||
val_func=lambda coordinator: coordinator.data.cumulative_stats.downloaded_bytes,
|
||||
),
|
||||
TransmissionSensorEntityDescription(
|
||||
key="total_upload",
|
||||
translation_key="total_upload",
|
||||
device_class=SensorDeviceClass.DATA_SIZE,
|
||||
native_unit_of_measurement=UnitOfInformation.BYTES,
|
||||
suggested_unit_of_measurement=UnitOfInformation.GIBIBYTES,
|
||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||
suggested_display_precision=3,
|
||||
val_func=lambda coordinator: coordinator.data.cumulative_stats.uploaded_bytes,
|
||||
),
|
||||
TransmissionSensorEntityDescription(
|
||||
key="session_ratio",
|
||||
translation_key="session_ratio",
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
suggested_display_precision=3,
|
||||
val_func=lambda coordinator: _compute_ratio(
|
||||
coordinator.data.current_stats.uploaded_bytes,
|
||||
coordinator.data.current_stats.downloaded_bytes,
|
||||
),
|
||||
),
|
||||
TransmissionSensorEntityDescription(
|
||||
key="total_ratio",
|
||||
translation_key="total_ratio",
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
suggested_display_precision=3,
|
||||
val_func=lambda coordinator: _compute_ratio(
|
||||
coordinator.data.cumulative_stats.uploaded_bytes,
|
||||
coordinator.data.cumulative_stats.downloaded_bytes,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -121,7 +194,6 @@ async def async_setup_entry(
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the Transmission sensors."""
|
||||
|
||||
coordinator = config_entry.runtime_data
|
||||
|
||||
async_add_entities(
|
||||
|
||||
@@ -66,14 +66,32 @@
|
||||
"name": "Paused torrents",
|
||||
"unit_of_measurement": "[%key:component::transmission::entity::sensor::active_torrents::unit_of_measurement%]"
|
||||
},
|
||||
"session_download": {
|
||||
"name": "Session download"
|
||||
},
|
||||
"session_ratio": {
|
||||
"name": "Session ratio"
|
||||
},
|
||||
"session_upload": {
|
||||
"name": "Session upload"
|
||||
},
|
||||
"started_torrents": {
|
||||
"name": "Started torrents",
|
||||
"unit_of_measurement": "[%key:component::transmission::entity::sensor::active_torrents::unit_of_measurement%]"
|
||||
},
|
||||
"total_download": {
|
||||
"name": "Total download"
|
||||
},
|
||||
"total_ratio": {
|
||||
"name": "Total ratio"
|
||||
},
|
||||
"total_torrents": {
|
||||
"name": "Total torrents",
|
||||
"unit_of_measurement": "[%key:component::transmission::entity::sensor::active_torrents::unit_of_measurement%]"
|
||||
},
|
||||
"total_upload": {
|
||||
"name": "Total upload"
|
||||
},
|
||||
"transmission_status": {
|
||||
"name": "Status",
|
||||
"state": {
|
||||
|
||||
@@ -55,6 +55,14 @@ def mock_transmission_client() -> Generator[AsyncMock]:
|
||||
"activeTorrentCount": 0,
|
||||
"pausedTorrentCount": 0,
|
||||
"torrentCount": 0,
|
||||
"current-stats": {
|
||||
"uploadedBytes": 5368709120,
|
||||
"downloadedBytes": 10737418240,
|
||||
},
|
||||
"cumulative-stats": {
|
||||
"uploadedBytes": 85899345920,
|
||||
"downloadedBytes": 107374182400,
|
||||
},
|
||||
}
|
||||
client.session_stats.return_value = SessionStats(fields=session_stats_data)
|
||||
|
||||
@@ -62,7 +70,6 @@ def mock_transmission_client() -> Generator[AsyncMock]:
|
||||
client.get_session.return_value = Session(fields=session_data)
|
||||
|
||||
client.get_torrents.return_value = []
|
||||
client.port_test.return_value = True
|
||||
|
||||
yield mock_client_class
|
||||
|
||||
|
||||
@@ -216,6 +216,184 @@
|
||||
'state': '0',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.transmission_session_download-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
None,
|
||||
]),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.transmission_session_download',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Session download',
|
||||
'options': dict({
|
||||
'sensor': dict({
|
||||
'suggested_display_precision': 3,
|
||||
}),
|
||||
'sensor.private': dict({
|
||||
'suggested_unit_of_measurement': <UnitOfInformation.GIBIBYTES: 'GiB'>,
|
||||
}),
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.DATA_SIZE: 'data_size'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Session download',
|
||||
'platform': 'transmission',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'session_download',
|
||||
'unique_id': '01J0BC4QM2YBRP6H5G933AETT7-session_download',
|
||||
'unit_of_measurement': <UnitOfInformation.GIBIBYTES: 'GiB'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.transmission_session_download-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'data_size',
|
||||
'friendly_name': 'Transmission Session download',
|
||||
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
||||
'unit_of_measurement': <UnitOfInformation.GIBIBYTES: 'GiB'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.transmission_session_download',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '10.0',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.transmission_session_ratio-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
None,
|
||||
]),
|
||||
'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': None,
|
||||
'entity_id': 'sensor.transmission_session_ratio',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Session ratio',
|
||||
'options': dict({
|
||||
'sensor': dict({
|
||||
'suggested_display_precision': 3,
|
||||
}),
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Session ratio',
|
||||
'platform': 'transmission',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'session_ratio',
|
||||
'unique_id': '01J0BC4QM2YBRP6H5G933AETT7-session_ratio',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.transmission_session_ratio-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Transmission Session ratio',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.transmission_session_ratio',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '0.5',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.transmission_session_upload-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
None,
|
||||
]),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.transmission_session_upload',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Session upload',
|
||||
'options': dict({
|
||||
'sensor': dict({
|
||||
'suggested_display_precision': 3,
|
||||
}),
|
||||
'sensor.private': dict({
|
||||
'suggested_unit_of_measurement': <UnitOfInformation.GIBIBYTES: 'GiB'>,
|
||||
}),
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.DATA_SIZE: 'data_size'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Session upload',
|
||||
'platform': 'transmission',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'session_upload',
|
||||
'unique_id': '01J0BC4QM2YBRP6H5G933AETT7-session_upload',
|
||||
'unit_of_measurement': <UnitOfInformation.GIBIBYTES: 'GiB'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.transmission_session_upload-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'data_size',
|
||||
'friendly_name': 'Transmission Session upload',
|
||||
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
||||
'unit_of_measurement': <UnitOfInformation.GIBIBYTES: 'GiB'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.transmission_session_upload',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '5.0',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.transmission_started_torrents-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
@@ -333,6 +511,123 @@
|
||||
'state': 'up_down',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.transmission_total_download-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
None,
|
||||
]),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.transmission_total_download',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Total download',
|
||||
'options': dict({
|
||||
'sensor': dict({
|
||||
'suggested_display_precision': 3,
|
||||
}),
|
||||
'sensor.private': dict({
|
||||
'suggested_unit_of_measurement': <UnitOfInformation.GIBIBYTES: 'GiB'>,
|
||||
}),
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.DATA_SIZE: 'data_size'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Total download',
|
||||
'platform': 'transmission',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'total_download',
|
||||
'unique_id': '01J0BC4QM2YBRP6H5G933AETT7-total_download',
|
||||
'unit_of_measurement': <UnitOfInformation.GIBIBYTES: 'GiB'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.transmission_total_download-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'data_size',
|
||||
'friendly_name': 'Transmission Total download',
|
||||
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
||||
'unit_of_measurement': <UnitOfInformation.GIBIBYTES: 'GiB'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.transmission_total_download',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '100.0',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.transmission_total_ratio-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
None,
|
||||
]),
|
||||
'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': None,
|
||||
'entity_id': 'sensor.transmission_total_ratio',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Total ratio',
|
||||
'options': dict({
|
||||
'sensor': dict({
|
||||
'suggested_display_precision': 3,
|
||||
}),
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Total ratio',
|
||||
'platform': 'transmission',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'total_ratio',
|
||||
'unique_id': '01J0BC4QM2YBRP6H5G933AETT7-total_ratio',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.transmission_total_ratio-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Transmission Total ratio',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.transmission_total_ratio',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '0.8',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.transmission_total_torrents-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
@@ -386,6 +681,67 @@
|
||||
'state': '0',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.transmission_total_upload-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
None,
|
||||
]),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.transmission_total_upload',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Total upload',
|
||||
'options': dict({
|
||||
'sensor': dict({
|
||||
'suggested_display_precision': 3,
|
||||
}),
|
||||
'sensor.private': dict({
|
||||
'suggested_unit_of_measurement': <UnitOfInformation.GIBIBYTES: 'GiB'>,
|
||||
}),
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.DATA_SIZE: 'data_size'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Total upload',
|
||||
'platform': 'transmission',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'total_upload',
|
||||
'unique_id': '01J0BC4QM2YBRP6H5G933AETT7-total_upload',
|
||||
'unit_of_measurement': <UnitOfInformation.GIBIBYTES: 'GiB'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.transmission_total_upload-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'data_size',
|
||||
'friendly_name': 'Transmission Total upload',
|
||||
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
||||
'unit_of_measurement': <UnitOfInformation.GIBIBYTES: 'GiB'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.transmission_total_upload',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '80.0',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.transmission_upload_speed-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
|
||||
@@ -2,9 +2,16 @@
|
||||
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
import pytest
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
from homeassistant.const import Platform
|
||||
from homeassistant.components.transmission.const import (
|
||||
STATE_DOWNLOADING,
|
||||
STATE_SEEDING,
|
||||
STATE_UP_DOWN,
|
||||
)
|
||||
from homeassistant.components.transmission.sensor import _compute_ratio, get_state
|
||||
from homeassistant.const import STATE_IDLE, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
@@ -25,3 +32,66 @@ async def test_sensors(
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
|
||||
|
||||
|
||||
async def test_stats_sensors(
|
||||
hass: HomeAssistant,
|
||||
mock_transmission_client: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test session and cumulative stats sensors."""
|
||||
with patch("homeassistant.components.transmission.PLATFORMS", [Platform.SENSOR]):
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
# Session download: 10 GiB = 10.0 GiB
|
||||
state = hass.states.get("sensor.transmission_session_download")
|
||||
assert state is not None
|
||||
assert float(state.state) == pytest.approx(10.0, rel=1e-3)
|
||||
|
||||
# Session upload: 5 GiB = 5.0 GiB
|
||||
state = hass.states.get("sensor.transmission_session_upload")
|
||||
assert state is not None
|
||||
assert float(state.state) == pytest.approx(5.0, rel=1e-3)
|
||||
|
||||
# Total download: 100 GiB = 100.0 GiB
|
||||
state = hass.states.get("sensor.transmission_total_download")
|
||||
assert state is not None
|
||||
assert float(state.state) == pytest.approx(100.0, rel=1e-3)
|
||||
|
||||
# Total upload: 80 GiB = 80.0 GiB
|
||||
state = hass.states.get("sensor.transmission_total_upload")
|
||||
assert state is not None
|
||||
assert float(state.state) == pytest.approx(80.0, rel=1e-3)
|
||||
|
||||
# Session ratio: 5 GiB / 10 GiB = 0.5
|
||||
state = hass.states.get("sensor.transmission_session_ratio")
|
||||
assert state is not None
|
||||
assert float(state.state) == pytest.approx(0.5, rel=1e-3)
|
||||
|
||||
# Total ratio: 80 GiB / 100 GiB = 0.8
|
||||
state = hass.states.get("sensor.transmission_total_ratio")
|
||||
assert state is not None
|
||||
assert float(state.state) == pytest.approx(0.8, rel=1e-3)
|
||||
|
||||
|
||||
def test_get_state_combinations() -> None:
|
||||
"""Test get_state with all upload/download combinations."""
|
||||
|
||||
assert get_state(1, 1) == STATE_UP_DOWN
|
||||
assert get_state(1, 0) == STATE_SEEDING
|
||||
assert get_state(0, 1) == STATE_DOWNLOADING
|
||||
assert get_state(0, 0) == STATE_IDLE
|
||||
|
||||
|
||||
def test_helper_functions() -> None:
|
||||
"""Test helper functions directly."""
|
||||
|
||||
# _compute_ratio - zero download
|
||||
assert _compute_ratio(100, 0) is None
|
||||
|
||||
# _compute_ratio - None values
|
||||
assert _compute_ratio(None, 100) is None
|
||||
assert _compute_ratio(100, None) is None
|
||||
|
||||
# _compute_ratio - normal
|
||||
assert _compute_ratio(500, 1000) == 0.5
|
||||
|
||||
Reference in New Issue
Block a user