Home Assistant Unofficial Reference 2024.12.1
sensor.py
Go to the documentation of this file.
1 """Support for Radarr."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Callable
6 import dataclasses
7 from datetime import UTC, datetime
8 from typing import Any, Generic
9 
10 from aiopyarr import Diskspace, RootFolder, SystemStatus
11 
13  SensorDeviceClass,
14  SensorEntity,
15  SensorEntityDescription,
16  SensorStateClass,
17 )
18 from homeassistant.const import EntityCategory, UnitOfInformation
19 from homeassistant.core import HomeAssistant
20 from homeassistant.helpers.entity_platform import AddEntitiesCallback
21 
22 from . import RadarrConfigEntry
23 from .coordinator import RadarrDataUpdateCoordinator, T
24 from .entity import RadarrEntity
25 
26 
27 def get_space(data: list[Diskspace], name: str) -> str:
28  """Get space."""
29  space = [
30  mount.freeSpace / 1024 ** BYTE_SIZES.index(UnitOfInformation.GIGABYTES)
31  for mount in data
32  if name in mount.path
33  ]
34  return f"{space[0]:.2f}"
35 
36 
38  description: RadarrSensorEntityDescription[T], mount: RootFolder
39 ) -> tuple[RadarrSensorEntityDescription[T], str]:
40  """Return modified description and folder name."""
41  name = mount.path.rsplit("/")[-1].rsplit("\\")[-1]
42  desc = dataclasses.replace(
43  description,
44  key=f"{description.key}_{name}",
45  name=f"{description.name} {name}".capitalize(),
46  )
47  return desc, name
48 
49 
50 @dataclasses.dataclass(frozen=True)
52  """Mixin for required keys."""
53 
54  value_fn: Callable[[T, str], str | int | datetime]
55 
56 
57 @dataclasses.dataclass(frozen=True)
59  SensorEntityDescription, RadarrSensorEntityDescriptionMixIn[T], Generic[T]
60 ):
61  """Class to describe a Radarr sensor."""
62 
63  description_fn: (
64  Callable[
65  [RadarrSensorEntityDescription[T], RootFolder],
66  tuple[RadarrSensorEntityDescription[T], str] | None,
67  ]
68  | None
69  ) = None
70 
71 
72 SENSOR_TYPES: dict[str, RadarrSensorEntityDescription[Any]] = {
73  "disk_space": RadarrSensorEntityDescription(
74  key="disk_space",
75  name="Disk space",
76  native_unit_of_measurement=UnitOfInformation.GIGABYTES,
77  device_class=SensorDeviceClass.DATA_SIZE,
78  icon="mdi:harddisk",
79  value_fn=get_space,
80  description_fn=get_modified_description,
81  ),
82  "movie": RadarrSensorEntityDescription[int](
83  key="movies",
84  translation_key="movies",
85  native_unit_of_measurement="Movies",
86  entity_registry_enabled_default=False,
87  value_fn=lambda data, _: data,
88  ),
89  "queue": RadarrSensorEntityDescription[int](
90  key="queue",
91  translation_key="queue",
92  native_unit_of_measurement="Movies",
93  entity_registry_enabled_default=False,
94  state_class=SensorStateClass.TOTAL,
95  value_fn=lambda data, _: data,
96  ),
97  "status": RadarrSensorEntityDescription[SystemStatus](
98  key="start_time",
99  translation_key="start_time",
100  device_class=SensorDeviceClass.TIMESTAMP,
101  entity_category=EntityCategory.DIAGNOSTIC,
102  entity_registry_enabled_default=False,
103  value_fn=lambda data, _: data.startTime.replace(tzinfo=UTC),
104  ),
105 }
106 
107 BYTE_SIZES = [
108  UnitOfInformation.BYTES,
109  UnitOfInformation.KILOBYTES,
110  UnitOfInformation.MEGABYTES,
111  UnitOfInformation.GIGABYTES,
112 ]
113 
114 PARALLEL_UPDATES = 1
115 
116 
118  hass: HomeAssistant,
119  entry: RadarrConfigEntry,
120  async_add_entities: AddEntitiesCallback,
121 ) -> None:
122  """Set up Radarr sensors based on a config entry."""
123  entities: list[RadarrSensor[Any]] = []
124  for coordinator_type, description in SENSOR_TYPES.items():
125  coordinator = getattr(entry.runtime_data, coordinator_type)
126  if coordinator_type != "disk_space":
127  entities.append(RadarrSensor(coordinator, description))
128  else:
129  entities.extend(
130  RadarrSensor(coordinator, *get_modified_description(description, mount))
131  for mount in coordinator.data
132  if description.description_fn
133  )
134  async_add_entities(entities)
135 
136 
137 class RadarrSensor(RadarrEntity[T], SensorEntity):
138  """Implementation of the Radarr sensor."""
139 
140  coordinator: RadarrDataUpdateCoordinator[T]
141  entity_description: RadarrSensorEntityDescription[T]
142 
143  def __init__(
144  self,
145  coordinator: RadarrDataUpdateCoordinator[T],
146  description: RadarrSensorEntityDescription[T],
147  folder_name: str = "",
148  ) -> None:
149  """Create Radarr entity."""
150  super().__init__(coordinator, description)
151  self.folder_namefolder_name = folder_name
152 
153  @property
154  def native_value(self) -> str | int | datetime:
155  """Return the state of the sensor."""
156  return self.entity_descriptionentity_description.value_fn(self.coordinator.data, self.folder_namefolder_name)
None __init__(self, RadarrDataUpdateCoordinator[T] coordinator, RadarrSensorEntityDescription[T] description, str folder_name="")
Definition: sensor.py:148
str get_space(list[Diskspace] data, str name)
Definition: sensor.py:27
tuple[RadarrSensorEntityDescription[T], str] get_modified_description(RadarrSensorEntityDescription[T] description, RootFolder mount)
Definition: sensor.py:39
None async_setup_entry(HomeAssistant hass, RadarrConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: sensor.py:121