From e31d398811e6ebf501ef1f5e9e81b88a11da26cf Mon Sep 17 00:00:00 2001 From: Jan-Philipp Benecke Date: Tue, 26 Nov 2024 19:01:19 +0100 Subject: [PATCH] Add binary sensor to SABnzbd (#131651) --- homeassistant/components/sabnzbd/__init__.py | 2 +- .../components/sabnzbd/binary_sensor.py | 61 +++++++++++++++++++ homeassistant/components/sabnzbd/strings.json | 5 ++ tests/components/sabnzbd/fixtures/queue.json | 2 +- .../sabnzbd/snapshots/test_binary_sensor.ambr | 48 +++++++++++++++ .../components/sabnzbd/test_binary_sensor.py | 23 +++++++ 6 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 homeassistant/components/sabnzbd/binary_sensor.py create mode 100644 tests/components/sabnzbd/snapshots/test_binary_sensor.ambr create mode 100644 tests/components/sabnzbd/test_binary_sensor.py diff --git a/homeassistant/components/sabnzbd/__init__.py b/homeassistant/components/sabnzbd/__init__.py index 19b114a4525..cf2eb5d0a7d 100644 --- a/homeassistant/components/sabnzbd/__init__.py +++ b/homeassistant/components/sabnzbd/__init__.py @@ -27,7 +27,7 @@ from .const import ( from .coordinator import SabnzbdUpdateCoordinator from .helpers import get_client -PLATFORMS = [Platform.BUTTON, Platform.NUMBER, Platform.SENSOR] +PLATFORMS = [Platform.BINARY_SENSOR, Platform.BUTTON, Platform.NUMBER, Platform.SENSOR] _LOGGER = logging.getLogger(__name__) SERVICES = ( diff --git a/homeassistant/components/sabnzbd/binary_sensor.py b/homeassistant/components/sabnzbd/binary_sensor.py new file mode 100644 index 00000000000..8b1b1c37c89 --- /dev/null +++ b/homeassistant/components/sabnzbd/binary_sensor.py @@ -0,0 +1,61 @@ +"""Binary sensor platform for SABnzbd.""" + +from __future__ import annotations + +from collections.abc import Callable +from dataclasses import dataclass +from typing import Any + +from homeassistant.components.binary_sensor import ( + BinarySensorDeviceClass, + BinarySensorEntity, + BinarySensorEntityDescription, +) +from homeassistant.const import EntityCategory +from homeassistant.core import HomeAssistant +from homeassistant.helpers.entity_platform import AddEntitiesCallback + +from . import SabnzbdConfigEntry +from .entity import SabnzbdEntity + + +@dataclass(frozen=True, kw_only=True) +class SabnzbdBinarySensorEntityDescription(BinarySensorEntityDescription): + """Describes Sabnzbd binary sensor entity.""" + + is_on_fn: Callable[[dict[str, Any]], bool] + + +BINARY_SENSORS: tuple[SabnzbdBinarySensorEntityDescription, ...] = ( + SabnzbdBinarySensorEntityDescription( + key="warnings", + translation_key="warnings", + device_class=BinarySensorDeviceClass.PROBLEM, + entity_category=EntityCategory.DIAGNOSTIC, + is_on_fn=lambda data: data["have_warnings"] != "0", + ), +) + + +async def async_setup_entry( + hass: HomeAssistant, + config_entry: SabnzbdConfigEntry, + async_add_entities: AddEntitiesCallback, +) -> None: + """Set up a Sabnzbd sensor entry.""" + coordinator = config_entry.runtime_data + + async_add_entities( + [SabnzbdBinarySensor(coordinator, sensor) for sensor in BINARY_SENSORS] + ) + + +class SabnzbdBinarySensor(SabnzbdEntity, BinarySensorEntity): + """Representation of an SABnzbd binary sensor.""" + + entity_description: SabnzbdBinarySensorEntityDescription + + @property + def is_on(self) -> bool: + """Return latest sensor data.""" + return self.entity_description.is_on_fn(self.coordinator.data) diff --git a/homeassistant/components/sabnzbd/strings.json b/homeassistant/components/sabnzbd/strings.json index 186682e78e7..0ac8b93c57f 100644 --- a/homeassistant/components/sabnzbd/strings.json +++ b/homeassistant/components/sabnzbd/strings.json @@ -22,6 +22,11 @@ } }, "entity": { + "binary_sensor": { + "warnings": { + "name": "Warnings" + } + }, "button": { "pause": { "name": "[%key:common::action::pause%]" diff --git a/tests/components/sabnzbd/fixtures/queue.json b/tests/components/sabnzbd/fixtures/queue.json index 342500aea39..7acef65f2e9 100644 --- a/tests/components/sabnzbd/fixtures/queue.json +++ b/tests/components/sabnzbd/fixtures/queue.json @@ -15,7 +15,7 @@ "diskspacetotal2": "7448.42", "speedlimit": "85", "speedlimit_abs": "22282240", - "have_warnings": "0", + "have_warnings": "1", "finishaction": null, "quota": "0 ", "have_quota": false, diff --git a/tests/components/sabnzbd/snapshots/test_binary_sensor.ambr b/tests/components/sabnzbd/snapshots/test_binary_sensor.ambr new file mode 100644 index 00000000000..9f3087df3d1 --- /dev/null +++ b/tests/components/sabnzbd/snapshots/test_binary_sensor.ambr @@ -0,0 +1,48 @@ +# serializer version: 1 +# name: test_sensor[binary_sensor.sabnzbd_warnings-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.sabnzbd_warnings', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Warnings', + 'platform': 'sabnzbd', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'warnings', + 'unique_id': '01JD2YVVPBC62D620DGYNG2R8H_warnings', + 'unit_of_measurement': None, + }) +# --- +# name: test_sensor[binary_sensor.sabnzbd_warnings-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'problem', + 'friendly_name': 'Sabnzbd Warnings', + }), + 'context': , + 'entity_id': 'binary_sensor.sabnzbd_warnings', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- diff --git a/tests/components/sabnzbd/test_binary_sensor.py b/tests/components/sabnzbd/test_binary_sensor.py new file mode 100644 index 00000000000..48a3c006488 --- /dev/null +++ b/tests/components/sabnzbd/test_binary_sensor.py @@ -0,0 +1,23 @@ +"""Binary sensor tests for the Sabnzbd component.""" + +from unittest.mock import patch + +from syrupy import SnapshotAssertion + +from homeassistant.const import Platform +from homeassistant.core import HomeAssistant +from homeassistant.helpers import entity_registry as er + +from tests.common import MockConfigEntry, snapshot_platform + + +@patch("homeassistant.components.sabnzbd.PLATFORMS", [Platform.BINARY_SENSOR]) +async def test_sensor( + hass: HomeAssistant, + entity_registry: er.EntityRegistry, + config_entry: MockConfigEntry, + snapshot: SnapshotAssertion, +) -> None: + """Test binary sensor setup.""" + await hass.config_entries.async_setup(config_entry.entry_id) + await snapshot_platform(hass, entity_registry, snapshot, config_entry.entry_id)