Use a single source of data for switchbot (#84215)
parent
6e612a45ff
commit
7c13e7cdfd
|
@ -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]
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
|
Loading…
Reference in New Issue