diff --git a/homeassistant/components/switchbot/binary_sensor.py b/homeassistant/components/switchbot/binary_sensor.py index 296cd4c1800..95623c66b46 100644 --- a/homeassistant/components/switchbot/binary_sensor.py +++ b/homeassistant/components/switchbot/binary_sensor.py @@ -54,7 +54,7 @@ async def async_setup_entry( coordinator: SwitchbotDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] async_add_entities( SwitchBotBinarySensor(coordinator, binary_sensor) - for binary_sensor in coordinator.data["data"] + for binary_sensor in coordinator.device.parsed_data if binary_sensor in BINARY_SENSOR_TYPES ) @@ -77,4 +77,4 @@ class SwitchBotBinarySensor(SwitchbotEntity, BinarySensorEntity): @property def is_on(self) -> bool: """Return the state of the sensor.""" - return self.data["data"][self._sensor] + return self.parsed_data[self._sensor] diff --git a/homeassistant/components/switchbot/coordinator.py b/homeassistant/components/switchbot/coordinator.py index 5783286c5c5..e46d2ebf95c 100644 --- a/homeassistant/components/switchbot/coordinator.py +++ b/homeassistant/components/switchbot/coordinator.py @@ -4,7 +4,7 @@ from __future__ import annotations import asyncio import contextlib import logging -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING import async_timeout import switchbot @@ -25,14 +25,6 @@ _LOGGER = logging.getLogger(__name__) DEVICE_STARTUP_TIMEOUT = 30 -def flatten_sensors_data(sensor): - """Deconstruct SwitchBot library temp object C/FÂș readings from dictionary.""" - if "temp" in sensor["data"]: - sensor["data"]["temperature"] = sensor["data"]["temp"]["c"] - - return sensor - - class SwitchbotDataUpdateCoordinator(PassiveBluetoothDataUpdateCoordinator): """Class to manage fetching switchbot data.""" @@ -57,7 +49,6 @@ class SwitchbotDataUpdateCoordinator(PassiveBluetoothDataUpdateCoordinator): ) self.ble_device = ble_device self.device = device - self.data: dict[str, Any] = {} self.device_name = device_name self.base_unique_id = base_unique_id self.model = model @@ -88,11 +79,12 @@ class SwitchbotDataUpdateCoordinator(PassiveBluetoothDataUpdateCoordinator): return if "modelName" in adv.data: self._ready_event.set() - _LOGGER.debug("%s: Switchbot data: %s", self.ble_device.address, self.data) + _LOGGER.debug( + "%s: Switchbot data: %s", self.ble_device.address, self.device.data + ) if not self.device.advertisement_changed(adv) and not self._was_unavailable: return self._was_unavailable = False - self.data = flatten_sensors_data(adv.data) self.device.update_from_advertisement(adv) super()._async_handle_bluetooth_event(service_info, change) diff --git a/homeassistant/components/switchbot/cover.py b/homeassistant/components/switchbot/cover.py index 696c9455f28..7450653e9a9 100644 --- a/homeassistant/components/switchbot/cover.py +++ b/homeassistant/components/switchbot/cover.py @@ -98,7 +98,7 @@ class SwitchBotCurtainEntity(SwitchbotEntity, CoverEntity, RestoreEntity): @callback def _handle_coordinator_update(self) -> None: """Handle updated data from the coordinator.""" - self._attr_current_cover_position = self.data["data"]["position"] - self._attr_is_closed = self.data["data"]["position"] <= 20 - self._attr_is_opening = self.data["data"]["inMotion"] + self._attr_current_cover_position = self.parsed_data["position"] + self._attr_is_closed = self.parsed_data["position"] <= 20 + self._attr_is_opening = self.parsed_data["inMotion"] self.async_write_ha_state() diff --git a/homeassistant/components/switchbot/entity.py b/homeassistant/components/switchbot/entity.py index e7b41d157cc..60e7528dba6 100644 --- a/homeassistant/components/switchbot/entity.py +++ b/homeassistant/components/switchbot/entity.py @@ -1,7 +1,6 @@ """An abstract class common to all Switchbot entities.""" from __future__ import annotations -from abc import abstractmethod from collections.abc import Mapping import logging from typing import Any @@ -54,15 +53,37 @@ class SwitchbotEntity(PassiveBluetoothCoordinatorEntity): ) @property - def data(self) -> dict[str, Any]: - """Return coordinator data for this entity.""" - return self.coordinator.data + def parsed_data(self) -> dict[str, Any]: + """Return parsed device data for this entity.""" + return self.coordinator.device.parsed_data @property def extra_state_attributes(self) -> Mapping[Any, Any]: """Return the state attributes.""" return {"last_run_success": self._last_run_success} + @callback + def _async_update_attrs(self) -> None: + """Update the entity attributes.""" + + @callback + def _handle_coordinator_update(self) -> None: + """Handle data update.""" + self._async_update_attrs() + self.async_write_ha_state() + + async def async_added_to_hass(self) -> None: + """Register callbacks.""" + self.async_on_remove(self._device.subscribe(self._handle_coordinator_update)) + return await super().async_added_to_hass() + + async def async_update(self) -> None: + """Update the entity. + + Only used by the generic entity update service. + """ + await self._device.update() + class SwitchbotSwitchedEntity(SwitchbotEntity, ToggleEntity): """Base class for Switchbot entities that can be turned on and off.""" @@ -86,29 +107,3 @@ class SwitchbotSwitchedEntity(SwitchbotEntity, ToggleEntity): if self._last_run_success: self._attr_is_on = False self.async_write_ha_state() - - -class SwitchbotSubscribeEntity(SwitchbotEntity): - """Base class for Switchbot entities that use subscribe.""" - - @abstractmethod - def _async_update_attrs(self) -> None: - """Update the entity attributes.""" - - @callback - def _handle_coordinator_update(self) -> None: - """Handle data update.""" - self._async_update_attrs() - self.async_write_ha_state() - - async def async_added_to_hass(self) -> None: - """Register callbacks.""" - self.async_on_remove(self._device.subscribe(self._handle_coordinator_update)) - return await super().async_added_to_hass() - - async def async_update(self) -> None: - """Update the entity. - - Only used by the generic entity update service. - """ - await self._device.update() diff --git a/homeassistant/components/switchbot/light.py b/homeassistant/components/switchbot/light.py index 0b4f748f1b2..5dc99c5d6f1 100644 --- a/homeassistant/components/switchbot/light.py +++ b/homeassistant/components/switchbot/light.py @@ -22,7 +22,7 @@ from homeassistant.util.color import ( from .const import DOMAIN from .coordinator import SwitchbotDataUpdateCoordinator -from .entity import SwitchbotSubscribeEntity +from .entity import SwitchbotEntity SWITCHBOT_COLOR_MODE_TO_HASS = { SwitchBotColorMode.RGB: ColorMode.RGB, @@ -42,7 +42,7 @@ async def async_setup_entry( async_add_entities([SwitchbotLightEntity(coordinator)]) -class SwitchbotLightEntity(SwitchbotSubscribeEntity, LightEntity): +class SwitchbotLightEntity(SwitchbotEntity, LightEntity): """Representation of switchbot light bulb.""" _device: SwitchbotBaseLight diff --git a/homeassistant/components/switchbot/sensor.py b/homeassistant/components/switchbot/sensor.py index 91f99047ca1..bafb08cc908 100644 --- a/homeassistant/components/switchbot/sensor.py +++ b/homeassistant/components/switchbot/sensor.py @@ -89,11 +89,8 @@ async def async_setup_entry( """Set up Switchbot sensor based on a config entry.""" coordinator: SwitchbotDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] entities = [ - SwitchBotSensor( - coordinator, - sensor, - ) - for sensor in coordinator.data["data"] + SwitchBotSensor(coordinator, sensor) + for sensor in coordinator.device.parsed_data if sensor in SENSOR_TYPES ] entities.append(SwitchbotRSSISensor(coordinator, "rssi")) @@ -117,7 +114,7 @@ class SwitchBotSensor(SwitchbotEntity, SensorEntity): @property def native_value(self) -> str | int | None: """Return the state of the sensor.""" - return self.data["data"][self._sensor] + return self.parsed_data[self._sensor] class SwitchbotRSSISensor(SwitchBotSensor):