-
-
Notifications
You must be signed in to change notification settings - Fork 33.4k
/
Copy pathlight.py
130 lines (101 loc) · 4.57 KB
/
light.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
"""Support for SwitchBee light."""
from __future__ import annotations
from typing import Any
from switchbee.api.central_unit import SwitchBeeDeviceOfflineError, SwitchBeeError
from switchbee.device import ApiStateCommand, DeviceType, SwitchBeeDimmer
from homeassistant.components.light import ATTR_BRIGHTNESS, ColorMode, LightEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .const import DOMAIN
from .coordinator import SwitchBeeCoordinator
from .entity import SwitchBeeDeviceEntity
MAX_BRIGHTNESS = 255
def _hass_brightness_to_switchbee(value: int) -> int:
"""Convert hass brightness to SwitchBee."""
sb_brightness = int(100 * value / MAX_BRIGHTNESS)
# SwitchBee maximum brightness is 99
return sb_brightness if sb_brightness != 100 else 99
def _switchbee_brightness_to_hass(value: int) -> int:
"""Convert SwitchBee brightness to hass."""
if value == 99:
value = 100
return round(value * MAX_BRIGHTNESS / 100)
async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up SwitchBee light."""
coordinator = hass.data[DOMAIN][entry.entry_id]
async_add_entities(
SwitchBeeLightEntity(switchbee_device, coordinator)
for switchbee_device in coordinator.data.values()
if switchbee_device.type == DeviceType.Dimmer
)
class SwitchBeeLightEntity(SwitchBeeDeviceEntity[SwitchBeeDimmer], LightEntity):
"""Representation of a SwitchBee light."""
_attr_color_mode = ColorMode.BRIGHTNESS
_attr_supported_color_modes = {ColorMode.BRIGHTNESS}
def __init__(
self,
device: SwitchBeeDimmer,
coordinator: SwitchBeeCoordinator,
) -> None:
"""Initialize the SwitchBee light."""
super().__init__(device, coordinator)
self._attr_is_on = False
self._attr_brightness = 0
self._update_attrs_from_coordinator()
@callback
def _handle_coordinator_update(self) -> None:
"""Handle updated data from the coordinator."""
self._update_attrs_from_coordinator()
super()._handle_coordinator_update()
def _update_attrs_from_coordinator(self) -> None:
coordinator_device = self._get_coordinator_device()
brightness = coordinator_device.brightness
# module is offline
if brightness == -1:
self._check_if_became_offline()
return
self._check_if_became_online()
self._attr_is_on = bool(brightness != 0)
# 1-99 is the only valid SwitchBee brightness range
if 0 < brightness < 100:
self._attr_brightness = _switchbee_brightness_to_hass(brightness)
async def async_turn_on(self, **kwargs: Any) -> None:
"""Async function to set on to light."""
if ATTR_BRIGHTNESS in kwargs:
state: int | str = _hass_brightness_to_switchbee(kwargs[ATTR_BRIGHTNESS])
else:
state = ApiStateCommand.ON
if self.brightness:
state = _hass_brightness_to_switchbee(self.brightness)
try:
await self.coordinator.api.set_state(self._device.id, state)
except (SwitchBeeError, SwitchBeeDeviceOfflineError) as exp:
raise HomeAssistantError(
f"Failed to set {self.name} state {state}, {exp!s}"
) from exp
if not isinstance(state, int):
# We just turned the light on, still don't know the last brightness
# known the Central Unit (yet) the brightness will be learned
# and updated in the next coordinator refresh
return
# update the coordinator data manually we already know the Central Unit
# brightness data for this light
self._get_coordinator_device().brightness = state
self.coordinator.async_set_updated_data(self.coordinator.data)
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn off SwitchBee light."""
try:
await self.coordinator.api.set_state(self._device.id, ApiStateCommand.OFF)
except (SwitchBeeError, SwitchBeeDeviceOfflineError) as exp:
raise HomeAssistantError(
f"Failed to turn off {self._attr_name}, {exp!s}"
) from exp
# update the coordinator manually
self._get_coordinator_device().brightness = 0
self.coordinator.async_set_updated_data(self.coordinator.data)