diff --git a/.coveragerc b/.coveragerc index d2d3a19d6ab..e24d3f9a7b9 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1026,6 +1026,7 @@ omit = homeassistant/components/sensibo/number.py homeassistant/components/sensibo/select.py homeassistant/components/sensibo/sensor.py + homeassistant/components/sensibo/update.py homeassistant/components/senz/__init__.py homeassistant/components/senz/api.py homeassistant/components/senz/climate.py diff --git a/homeassistant/components/sensibo/binary_sensor.py b/homeassistant/components/sensibo/binary_sensor.py index 02f86dbe009..27e551a51c8 100644 --- a/homeassistant/components/sensibo/binary_sensor.py +++ b/homeassistant/components/sensibo/binary_sensor.py @@ -82,14 +82,6 @@ DEVICE_SENSOR_TYPES: tuple[SensiboDeviceBinarySensorEntityDescription, ...] = ( icon="mdi:motion-sensor", value_fn=lambda data: data.room_occupied, ), - SensiboDeviceBinarySensorEntityDescription( - key="update_available", - device_class=BinarySensorDeviceClass.UPDATE, - entity_category=EntityCategory.DIAGNOSTIC, - name="Update Available", - icon="mdi:rocket-launch", - value_fn=lambda data: data.update_available, - ), ) diff --git a/homeassistant/components/sensibo/const.py b/homeassistant/components/sensibo/const.py index ac3df435e29..5fce3822bb2 100644 --- a/homeassistant/components/sensibo/const.py +++ b/homeassistant/components/sensibo/const.py @@ -18,6 +18,7 @@ PLATFORMS = [ Platform.NUMBER, Platform.SELECT, Platform.SENSOR, + Platform.UPDATE, ] DEFAULT_NAME = "Sensibo" TIMEOUT = 8 diff --git a/homeassistant/components/sensibo/manifest.json b/homeassistant/components/sensibo/manifest.json index 233bf009c75..c8ad6511f02 100644 --- a/homeassistant/components/sensibo/manifest.json +++ b/homeassistant/components/sensibo/manifest.json @@ -2,7 +2,7 @@ "domain": "sensibo", "name": "Sensibo", "documentation": "https://www.home-assistant.io/integrations/sensibo", - "requirements": ["pysensibo==1.0.9"], + "requirements": ["pysensibo==1.0.10"], "config_flow": true, "codeowners": ["@andrey-git", "@gjohansson-ST"], "iot_class": "cloud_polling", diff --git a/homeassistant/components/sensibo/update.py b/homeassistant/components/sensibo/update.py new file mode 100644 index 00000000000..6e227a891b0 --- /dev/null +++ b/homeassistant/components/sensibo/update.py @@ -0,0 +1,93 @@ +"""Update platform for Sensibo integration.""" +from __future__ import annotations + +from collections.abc import Callable +from dataclasses import dataclass + +from pysensibo.model import SensiboDevice + +from homeassistant.components.update import ( + UpdateDeviceClass, + UpdateEntity, + UpdateEntityDescription, +) +from homeassistant.config_entries import ConfigEntry +from homeassistant.core import HomeAssistant +from homeassistant.helpers.entity import EntityCategory +from homeassistant.helpers.entity_platform import AddEntitiesCallback + +from .const import DOMAIN +from .coordinator import SensiboDataUpdateCoordinator +from .entity import SensiboDeviceBaseEntity + + +@dataclass +class DeviceBaseEntityDescriptionMixin: + """Mixin for required Sensibo base description keys.""" + + value_version: Callable[[SensiboDevice], str | None] + value_available: Callable[[SensiboDevice], str | None] + + +@dataclass +class SensiboDeviceUpdateEntityDescription( + UpdateEntityDescription, DeviceBaseEntityDescriptionMixin +): + """Describes Sensibo Update entity.""" + + +DEVICE_SENSOR_TYPES: tuple[SensiboDeviceUpdateEntityDescription, ...] = ( + SensiboDeviceUpdateEntityDescription( + key="fw_ver_available", + device_class=UpdateDeviceClass.FIRMWARE, + entity_category=EntityCategory.DIAGNOSTIC, + name="Update Available", + icon="mdi:rocket-launch", + value_version=lambda data: data.fw_ver, + value_available=lambda data: data.fw_ver_available, + ), +) + + +async def async_setup_entry( + hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback +) -> None: + """Set up Sensibo Update platform.""" + + coordinator: SensiboDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] + + async_add_entities( + SensiboDeviceUpdate(coordinator, device_id, description) + for description in DEVICE_SENSOR_TYPES + for device_id, device_data in coordinator.data.parsed.items() + if description.value_available(device_data) is not None + ) + + +class SensiboDeviceUpdate(SensiboDeviceBaseEntity, UpdateEntity): + """Representation of a Sensibo Device Update.""" + + entity_description: SensiboDeviceUpdateEntityDescription + + def __init__( + self, + coordinator: SensiboDataUpdateCoordinator, + device_id: str, + entity_description: SensiboDeviceUpdateEntityDescription, + ) -> None: + """Initiate Sensibo Device Update.""" + super().__init__(coordinator, device_id) + self.entity_description = entity_description + self._attr_unique_id = f"{device_id}-{entity_description.key}" + self._attr_name = f"{self.device_data.name} {entity_description.name}" + self._attr_title = self.device_data.model + + @property + def installed_version(self) -> str | None: + """Return version currently installed.""" + return self.entity_description.value_version(self.device_data) + + @property + def latest_version(self) -> str | None: + """Return latest available version.""" + return self.entity_description.value_available(self.device_data) diff --git a/requirements_all.txt b/requirements_all.txt index 0e414214df4..f76e45edd95 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1777,7 +1777,7 @@ pysaj==0.0.16 pysdcp==1 # homeassistant.components.sensibo -pysensibo==1.0.9 +pysensibo==1.0.10 # homeassistant.components.serial # homeassistant.components.zha diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 34be9e90fa6..af6c50799bd 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1187,7 +1187,7 @@ pyrituals==0.0.6 pyruckus==0.12 # homeassistant.components.sensibo -pysensibo==1.0.9 +pysensibo==1.0.10 # homeassistant.components.serial # homeassistant.components.zha