mirror of
https://github.com/home-assistant/core.git
synced 2025-07-24 21:57:51 +00:00
Use EntityDescription - radarr (#54997)
This commit is contained in:
parent
a84f1284c0
commit
4b069b42f0
@ -1,12 +1,19 @@
|
|||||||
"""Support for Radarr."""
|
"""Support for Radarr."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity
|
from homeassistant.components.sensor import (
|
||||||
|
PLATFORM_SCHEMA,
|
||||||
|
SensorEntity,
|
||||||
|
SensorEntityDescription,
|
||||||
|
)
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONF_API_KEY,
|
CONF_API_KEY,
|
||||||
CONF_HOST,
|
CONF_HOST,
|
||||||
@ -42,14 +49,46 @@ DEFAULT_UNIT = DATA_GIGABYTES
|
|||||||
|
|
||||||
SCAN_INTERVAL = timedelta(minutes=10)
|
SCAN_INTERVAL = timedelta(minutes=10)
|
||||||
|
|
||||||
SENSOR_TYPES = {
|
SENSOR_TYPES: tuple[SensorEntityDescription, ...] = (
|
||||||
"diskspace": ["Disk Space", DATA_GIGABYTES, "mdi:harddisk"],
|
SensorEntityDescription(
|
||||||
"upcoming": ["Upcoming", "Movies", "mdi:television"],
|
key="diskspace",
|
||||||
"wanted": ["Wanted", "Movies", "mdi:television"],
|
name="Disk Space",
|
||||||
"movies": ["Movies", "Movies", "mdi:television"],
|
native_unit_of_measurement=DATA_GIGABYTES,
|
||||||
"commands": ["Commands", "Commands", "mdi:code-braces"],
|
icon="mdi:harddisk",
|
||||||
"status": ["Status", "Status", "mdi:information"],
|
),
|
||||||
}
|
SensorEntityDescription(
|
||||||
|
key="upcoming",
|
||||||
|
name="Upcoming",
|
||||||
|
native_unit_of_measurement="Movies",
|
||||||
|
icon="mdi:television",
|
||||||
|
),
|
||||||
|
SensorEntityDescription(
|
||||||
|
key="wanted",
|
||||||
|
name="Wanted",
|
||||||
|
native_unit_of_measurement="Movies",
|
||||||
|
icon="mdi:television",
|
||||||
|
),
|
||||||
|
SensorEntityDescription(
|
||||||
|
key="movies",
|
||||||
|
name="Movies",
|
||||||
|
native_unit_of_measurement="Movies",
|
||||||
|
icon="mdi:television",
|
||||||
|
),
|
||||||
|
SensorEntityDescription(
|
||||||
|
key="commands",
|
||||||
|
name="Commands",
|
||||||
|
native_unit_of_measurement="Commands",
|
||||||
|
icon="mdi:code-braces",
|
||||||
|
),
|
||||||
|
SensorEntityDescription(
|
||||||
|
key="status",
|
||||||
|
name="Status",
|
||||||
|
native_unit_of_measurement="Status",
|
||||||
|
icon="mdi:information",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
SENSOR_KEYS: list[str] = [desc.key for desc in SENSOR_TYPES]
|
||||||
|
|
||||||
ENDPOINTS = {
|
ENDPOINTS = {
|
||||||
"diskspace": "{0}://{1}:{2}/{3}api/diskspace",
|
"diskspace": "{0}://{1}:{2}/{3}api/diskspace",
|
||||||
@ -78,7 +117,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
|||||||
vol.Optional(CONF_HOST, default=DEFAULT_HOST): cv.string,
|
vol.Optional(CONF_HOST, default=DEFAULT_HOST): cv.string,
|
||||||
vol.Optional(CONF_INCLUDED, default=[]): cv.ensure_list,
|
vol.Optional(CONF_INCLUDED, default=[]): cv.ensure_list,
|
||||||
vol.Optional(CONF_MONITORED_CONDITIONS, default=["movies"]): vol.All(
|
vol.Optional(CONF_MONITORED_CONDITIONS, default=["movies"]): vol.All(
|
||||||
cv.ensure_list, [vol.In(list(SENSOR_TYPES))]
|
cv.ensure_list, [vol.In(SENSOR_KEYS)]
|
||||||
),
|
),
|
||||||
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
|
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
|
||||||
vol.Optional(CONF_SSL, default=False): cv.boolean,
|
vol.Optional(CONF_SSL, default=False): cv.boolean,
|
||||||
@ -90,15 +129,21 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
|||||||
|
|
||||||
def setup_platform(hass, config, add_entities, discovery_info=None):
|
def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||||
"""Set up the Radarr platform."""
|
"""Set up the Radarr platform."""
|
||||||
conditions = config.get(CONF_MONITORED_CONDITIONS)
|
conditions = config[CONF_MONITORED_CONDITIONS]
|
||||||
add_entities([RadarrSensor(hass, config, sensor) for sensor in conditions], True)
|
entities = [
|
||||||
|
RadarrSensor(hass, config, description)
|
||||||
|
for description in SENSOR_TYPES
|
||||||
|
if description.key in conditions
|
||||||
|
]
|
||||||
|
add_entities(entities, True)
|
||||||
|
|
||||||
|
|
||||||
class RadarrSensor(SensorEntity):
|
class RadarrSensor(SensorEntity):
|
||||||
"""Implementation of the Radarr sensor."""
|
"""Implementation of the Radarr sensor."""
|
||||||
|
|
||||||
def __init__(self, hass, conf, sensor_type):
|
def __init__(self, hass, conf, description: SensorEntityDescription):
|
||||||
"""Create Radarr entity."""
|
"""Create Radarr entity."""
|
||||||
|
self.entity_description = description
|
||||||
|
|
||||||
self.conf = conf
|
self.conf = conf
|
||||||
self.host = conf.get(CONF_HOST)
|
self.host = conf.get(CONF_HOST)
|
||||||
@ -110,78 +155,55 @@ class RadarrSensor(SensorEntity):
|
|||||||
self.included = conf.get(CONF_INCLUDED)
|
self.included = conf.get(CONF_INCLUDED)
|
||||||
self.days = int(conf.get(CONF_DAYS))
|
self.days = int(conf.get(CONF_DAYS))
|
||||||
self.ssl = "https" if conf.get(CONF_SSL) else "http"
|
self.ssl = "https" if conf.get(CONF_SSL) else "http"
|
||||||
self._state = None
|
self.data: list[Any] = []
|
||||||
self.data = []
|
self._attr_name = f"Radarr {description.name}"
|
||||||
self.type = sensor_type
|
if description.key == "diskspace":
|
||||||
self._name = SENSOR_TYPES[self.type][0]
|
self._attr_native_unit_of_measurement = conf.get(CONF_UNIT)
|
||||||
if self.type == "diskspace":
|
self._attr_available = False
|
||||||
self._unit = conf.get(CONF_UNIT)
|
|
||||||
else:
|
|
||||||
self._unit = SENSOR_TYPES[self.type][1]
|
|
||||||
self._icon = SENSOR_TYPES[self.type][2]
|
|
||||||
self._available = False
|
|
||||||
|
|
||||||
@property
|
|
||||||
def name(self):
|
|
||||||
"""Return the name of the sensor."""
|
|
||||||
return "{} {}".format("Radarr", self._name)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def native_value(self):
|
|
||||||
"""Return sensor state."""
|
|
||||||
return self._state
|
|
||||||
|
|
||||||
@property
|
|
||||||
def available(self):
|
|
||||||
"""Return sensor availability."""
|
|
||||||
return self._available
|
|
||||||
|
|
||||||
@property
|
|
||||||
def native_unit_of_measurement(self):
|
|
||||||
"""Return the unit of the sensor."""
|
|
||||||
return self._unit
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def extra_state_attributes(self):
|
def extra_state_attributes(self):
|
||||||
"""Return the state attributes of the sensor."""
|
"""Return the state attributes of the sensor."""
|
||||||
attributes = {}
|
attributes = {}
|
||||||
if self.type == "upcoming":
|
sensor_type = self.entity_description.key
|
||||||
|
if sensor_type == "upcoming":
|
||||||
for movie in self.data:
|
for movie in self.data:
|
||||||
attributes[to_key(movie)] = get_release_date(movie)
|
attributes[to_key(movie)] = get_release_date(movie)
|
||||||
elif self.type == "commands":
|
elif sensor_type == "commands":
|
||||||
for command in self.data:
|
for command in self.data:
|
||||||
attributes[command["name"]] = command["state"]
|
attributes[command["name"]] = command["state"]
|
||||||
elif self.type == "diskspace":
|
elif sensor_type == "diskspace":
|
||||||
for data in self.data:
|
for data in self.data:
|
||||||
free_space = to_unit(data["freeSpace"], self._unit)
|
free_space = to_unit(data["freeSpace"], self.native_unit_of_measurement)
|
||||||
total_space = to_unit(data["totalSpace"], self._unit)
|
total_space = to_unit(
|
||||||
|
data["totalSpace"], self.native_unit_of_measurement
|
||||||
|
)
|
||||||
percentage_used = (
|
percentage_used = (
|
||||||
0 if total_space == 0 else free_space / total_space * 100
|
0 if total_space == 0 else free_space / total_space * 100
|
||||||
)
|
)
|
||||||
attributes[data["path"]] = "{:.2f}/{:.2f}{} ({:.2f}%)".format(
|
attributes[data["path"]] = "{:.2f}/{:.2f}{} ({:.2f}%)".format(
|
||||||
free_space, total_space, self._unit, percentage_used
|
free_space,
|
||||||
|
total_space,
|
||||||
|
self.native_unit_of_measurement,
|
||||||
|
percentage_used,
|
||||||
)
|
)
|
||||||
elif self.type == "movies":
|
elif sensor_type == "movies":
|
||||||
for movie in self.data:
|
for movie in self.data:
|
||||||
attributes[to_key(movie)] = movie["downloaded"]
|
attributes[to_key(movie)] = movie["downloaded"]
|
||||||
elif self.type == "status":
|
elif sensor_type == "status":
|
||||||
attributes = self.data
|
attributes = self.data
|
||||||
|
|
||||||
return attributes
|
return attributes
|
||||||
|
|
||||||
@property
|
|
||||||
def icon(self):
|
|
||||||
"""Return the icon of the sensor."""
|
|
||||||
return self._icon
|
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
"""Update the data for the sensor."""
|
"""Update the data for the sensor."""
|
||||||
|
sensor_type = self.entity_description.key
|
||||||
time_zone = dt_util.get_time_zone(self.hass.config.time_zone)
|
time_zone = dt_util.get_time_zone(self.hass.config.time_zone)
|
||||||
start = get_date(time_zone)
|
start = get_date(time_zone)
|
||||||
end = get_date(time_zone, self.days)
|
end = get_date(time_zone, self.days)
|
||||||
try:
|
try:
|
||||||
res = requests.get(
|
res = requests.get(
|
||||||
ENDPOINTS[self.type].format(
|
ENDPOINTS[sensor_type].format(
|
||||||
self.ssl, self.host, self.port, self.urlbase, start, end
|
self.ssl, self.host, self.port, self.urlbase, start, end
|
||||||
),
|
),
|
||||||
headers={"X-Api-Key": self.apikey},
|
headers={"X-Api-Key": self.apikey},
|
||||||
@ -189,15 +211,15 @@ class RadarrSensor(SensorEntity):
|
|||||||
)
|
)
|
||||||
except OSError:
|
except OSError:
|
||||||
_LOGGER.warning("Host %s is not available", self.host)
|
_LOGGER.warning("Host %s is not available", self.host)
|
||||||
self._available = False
|
self._attr_available = False
|
||||||
self._state = None
|
self._attr_native_value = None
|
||||||
return
|
return
|
||||||
|
|
||||||
if res.status_code == HTTP_OK:
|
if res.status_code == HTTP_OK:
|
||||||
if self.type in ("upcoming", "movies", "commands"):
|
if sensor_type in ("upcoming", "movies", "commands"):
|
||||||
self.data = res.json()
|
self.data = res.json()
|
||||||
self._state = len(self.data)
|
self._attr_native_value = len(self.data)
|
||||||
elif self.type == "diskspace":
|
elif sensor_type == "diskspace":
|
||||||
# If included paths are not provided, use all data
|
# If included paths are not provided, use all data
|
||||||
if self.included == []:
|
if self.included == []:
|
||||||
self.data = res.json()
|
self.data = res.json()
|
||||||
@ -206,13 +228,16 @@ class RadarrSensor(SensorEntity):
|
|||||||
self.data = list(
|
self.data = list(
|
||||||
filter(lambda x: x["path"] in self.included, res.json())
|
filter(lambda x: x["path"] in self.included, res.json())
|
||||||
)
|
)
|
||||||
self._state = "{:.2f}".format(
|
self._attr_native_value = "{:.2f}".format(
|
||||||
to_unit(sum(data["freeSpace"] for data in self.data), self._unit)
|
to_unit(
|
||||||
|
sum(data["freeSpace"] for data in self.data),
|
||||||
|
self.native_unit_of_measurement,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
elif self.type == "status":
|
elif sensor_type == "status":
|
||||||
self.data = res.json()
|
self.data = res.json()
|
||||||
self._state = self.data["version"]
|
self._attr_native_value = self.data["version"]
|
||||||
self._available = True
|
self._attr_available = True
|
||||||
|
|
||||||
|
|
||||||
def get_date(zone, offset=0):
|
def get_date(zone, offset=0):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user