1 """Support for Sonarr sensors."""
3 from __future__
import annotations
5 from collections.abc
import Callable
6 from dataclasses
import dataclass
7 from typing
import Any, Generic
21 SensorEntityDescription,
30 from .const
import DOMAIN
31 from .coordinator
import SonarrDataT, SonarrDataUpdateCoordinator
32 from .entity
import SonarrEntity
35 @dataclass(frozen=True)
37 """Mixin for Sonarr sensor."""
39 attributes_fn: Callable[[SonarrDataT], dict[str, str]]
40 value_fn: Callable[[SonarrDataT], StateType]
43 @dataclass(frozen=True)
45 SensorEntityDescription, SonarrSensorEntityDescriptionMixIn[SonarrDataT]
47 """Class to describe a Sonarr sensor."""
51 """Create the attributes for disk space."""
52 attrs: dict[str, str] = {}
54 free = disk.freeSpace / 1024**3
55 total = disk.totalSpace / 1024**3
56 usage = free / total * 100
58 f
"{free:.2f}/{total:.2f}{UnitOfInformation.GIGABYTES} ({usage:.2f}%)"
64 """Create the attributes for series queue."""
65 attrs: dict[str, str] = {}
66 for item
in queue.records:
67 remaining = 1
if item.size == 0
else item.sizeleft / item.size
68 remaining_pct = 100 * (1 - remaining)
70 f
"S{item.episode.seasonNumber:02d}E{item.episode. episodeNumber:02d}"
72 attrs[f
"{item.series.title} {identifier}"] = f
"{remaining_pct:.2f}%"
77 """Create the attributes for missing series."""
78 attrs: dict[str, str] = {}
79 for item
in wanted.records:
80 identifier = f
"S{item.seasonNumber:02d}E{item.episodeNumber:02d}"
82 name = f
"{item.series.title} {identifier}"
83 attrs[name] = dt_util.as_local(
84 item.airDateUtc.replace(tzinfo=dt_util.UTC)
89 SENSOR_TYPES: dict[str, SonarrSensorEntityDescription[Any]] = {
90 "commands": SonarrSensorEntityDescription[list[Command]](
92 translation_key=
"commands",
93 native_unit_of_measurement=
"Commands",
94 entity_registry_enabled_default=
False,
96 attributes_fn=
lambda data: {c.name: c.status
for c
in data},
98 "diskspace": SonarrSensorEntityDescription[list[Diskspace]](
100 translation_key=
"diskspace",
101 native_unit_of_measurement=UnitOfInformation.GIGABYTES,
102 device_class=SensorDeviceClass.DATA_SIZE,
103 entity_registry_enabled_default=
False,
104 value_fn=
lambda data: f
"{sum(disk.freeSpace for disk in data) / 1024**3:.2f}",
105 attributes_fn=get_disk_space_attr,
107 "queue": SonarrSensorEntityDescription[SonarrQueue](
109 translation_key=
"queue",
110 native_unit_of_measurement=
"Episodes",
111 entity_registry_enabled_default=
False,
112 value_fn=
lambda data: data.totalRecords,
113 attributes_fn=get_queue_attr,
115 "series": SonarrSensorEntityDescription[list[SonarrSeries]](
117 translation_key=
"series",
118 native_unit_of_measurement=
"Series",
119 entity_registry_enabled_default=
False,
121 attributes_fn=
lambda data: {
123 f
"{getattr(i.statistics,'episodeFileCount', 0)}/{getattr(i.statistics, 'episodeCount', 0)} Episodes"
128 "upcoming": SonarrSensorEntityDescription[list[SonarrCalendar]](
130 translation_key=
"upcoming",
131 native_unit_of_measurement=
"Episodes",
133 attributes_fn=
lambda data: {
134 e.series.title: f
"S{e.seasonNumber:02d}E{e.episodeNumber:02d}" for e
in data
137 "wanted": SonarrSensorEntityDescription[SonarrWantedMissing](
139 translation_key=
"wanted",
140 native_unit_of_measurement=
"Episodes",
141 entity_registry_enabled_default=
False,
142 value_fn=
lambda data: data.totalRecords,
143 attributes_fn=get_wanted_attr,
151 async_add_entities: AddEntitiesCallback,
153 """Set up Sonarr sensors based on a config entry."""
154 coordinators: dict[str, SonarrDataUpdateCoordinator[Any]] = hass.data[DOMAIN][
158 SonarrSensor(coordinators[coordinator_type], description)
159 for coordinator_type, description
in SENSOR_TYPES.items()
164 """Implementation of the Sonarr sensor."""
166 coordinator: SonarrDataUpdateCoordinator[SonarrDataT]
167 entity_description: SonarrSensorEntityDescription[SonarrDataT]
171 """Return the state attributes of the entity."""
176 """Return the state of the sensor."""
StateType native_value(self)
dict[str, str] extra_state_attributes(self)
None async_setup_entry(HomeAssistant hass, ConfigEntry entry, AddEntitiesCallback async_add_entities)
dict[str, str] get_wanted_attr(SonarrWantedMissing wanted)
dict[str, str] get_disk_space_attr(list[Diskspace] disks)
dict[str, str] get_queue_attr(SonarrQueue queue)