From ffcc2254ceb6a5bfda2249c51528d87f0d8c0c19 Mon Sep 17 00:00:00 2001 From: Joost Lekkerkerker Date: Fri, 11 Apr 2025 19:40:37 +0200 Subject: [PATCH] Refactor Syncthru binary sensor (#142696) --- .../components/syncthru/binary_sensor.py | 92 +++++++++---------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/homeassistant/components/syncthru/binary_sensor.py b/homeassistant/components/syncthru/binary_sensor.py index 6f6bd73af77..d863c5546d8 100644 --- a/homeassistant/components/syncthru/binary_sensor.py +++ b/homeassistant/components/syncthru/binary_sensor.py @@ -2,11 +2,15 @@ from __future__ import annotations -from pysyncthru import SyncthruState +from collections.abc import Callable +from dataclasses import dataclass + +from pysyncthru import SyncThru, SyncthruState from homeassistant.components.binary_sensor import ( BinarySensorDeviceClass, BinarySensorEntity, + BinarySensorEntityDescription, ) from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_NAME @@ -29,6 +33,27 @@ SYNCTHRU_STATE_PROBLEM = { } +@dataclass(frozen=True, kw_only=True) +class SyncThruBinarySensorDescription(BinarySensorEntityDescription): + """Describes Syncthru binary sensor entities.""" + + value_fn: Callable[[SyncThru], bool | None] + + +BINARY_SENSORS: tuple[SyncThruBinarySensorDescription, ...] = ( + SyncThruBinarySensorDescription( + key="online", + device_class=BinarySensorDeviceClass.CONNECTIVITY, + value_fn=lambda printer: printer.is_online(), + ), + SyncThruBinarySensorDescription( + key="problem", + device_class=BinarySensorDeviceClass.PROBLEM, + value_fn=lambda printer: SYNCTHRU_STATE_PROBLEM[printer.device_status()], + ), +) + + async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, @@ -39,67 +64,42 @@ async def async_setup_entry( coordinator: SyncthruCoordinator = hass.data[DOMAIN][config_entry.entry_id] name: str = config_entry.data[CONF_NAME] - entities = [ - SyncThruOnlineSensor(coordinator, name), - SyncThruProblemSensor(coordinator, name), - ] - async_add_entities(entities) + async_add_entities( + SyncThruBinarySensor(coordinator, name, description) + for description in BINARY_SENSORS + ) class SyncThruBinarySensor(CoordinatorEntity[SyncthruCoordinator], BinarySensorEntity): """Implementation of an abstract Samsung Printer binary sensor platform.""" - def __init__(self, coordinator: SyncthruCoordinator, name: str) -> None: + entity_description: SyncThruBinarySensorDescription + + def __init__( + self, + coordinator: SyncthruCoordinator, + name: str, + entity_description: SyncThruBinarySensorDescription, + ) -> None: """Initialize the sensor.""" super().__init__(coordinator) - self.syncthru = coordinator.data + self.entity_description = entity_description + serial_number = coordinator.data.serial_number() + assert serial_number is not None + self._attr_unique_id = f"{serial_number}_{entity_description.key}" self._attr_name = name - self._id_suffix = "" - - @property - def unique_id(self): - """Return unique ID for the sensor.""" - serial = self.syncthru.serial_number() - return f"{serial}{self._id_suffix}" if serial else None @property def device_info(self) -> DeviceInfo | None: """Return device information.""" - if (identifiers := device_identifiers(self.syncthru)) is None: + if (identifiers := device_identifiers(self.coordinator.data)) is None: return None return DeviceInfo( identifiers=identifiers, ) - -class SyncThruOnlineSensor(SyncThruBinarySensor): - """Implementation of a sensor that checks whether is turned on/online.""" - - _attr_device_class = BinarySensorDeviceClass.CONNECTIVITY - - def __init__(self, coordinator: SyncthruCoordinator, name: str) -> None: - """Initialize the sensor.""" - super().__init__(coordinator, name) - self._id_suffix = "_online" - @property - def is_on(self): - """Set the state to whether the printer is online.""" - return self.syncthru.is_online() - - -class SyncThruProblemSensor(SyncThruBinarySensor): - """Implementation of a sensor that checks whether the printer works correctly.""" - - _attr_device_class = BinarySensorDeviceClass.PROBLEM - - def __init__(self, coordinator: SyncthruCoordinator, name: str) -> None: - """Initialize the sensor.""" - super().__init__(coordinator, name) - self._id_suffix = "_problem" - - @property - def is_on(self): - """Set the state to whether there is a problem with the printer.""" - return SYNCTHRU_STATE_PROBLEM[self.syncthru.device_status()] + def is_on(self) -> bool | None: + """Return true if the binary sensor is on.""" + return self.entity_description.value_fn(self.coordinator.data)