forked from yutoyazaki/hass-nature-remo
-
Notifications
You must be signed in to change notification settings - Fork 5
/
light.py
146 lines (120 loc) · 4.54 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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
"""Support for Nature Remo Light."""
import logging
from enum import Enum
import voluptuous as vol
from homeassistant.components.light import (
LightEntity,
SUPPORT_BRIGHTNESS,
SUPPORT_COLOR_TEMP,
)
from homeassistant.helpers import config_validation as cv, entity_platform
from . import DOMAIN, NatureRemoBase
_LOGGER = logging.getLogger(__name__)
SERVICE_PRESS_LIGHT_BUTTON = "press_light_button"
SERVICE_PRESS_CUSTOM_BUTTON = "press_custom_button"
ATTR_IS_NIGHT = "is_night"
class LightButton(Enum):
on = "on"
max = "on-100"
favorite = "on-favorite"
on_off = "onoff"
night = "night"
bright_up = "bright-up"
bright_down = "bright-down"
color_temp_up = "colortemp-up"
color_temp_down = "colortemp-down"
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
"""Set up the Nature Remo Light."""
if discovery_info is None:
return
_LOGGER.debug("Setting up light platform.")
coordinator = hass.data[DOMAIN]["coordinator"]
api = hass.data[DOMAIN]["api"]
config = hass.data[DOMAIN]["config"]
appliances = coordinator.data["appliances"]
async_add_entities(
[
NatureRemoLight(coordinator, api, appliance, config)
for appliance in appliances.values()
if appliance["type"] == "LIGHT"
]
)
platform = entity_platform.current_platform.get()
_LOGGER.debug("Registering light entity services.")
platform.async_register_entity_service(
SERVICE_PRESS_LIGHT_BUTTON,
{vol.Required("button_name"): cv.enum(LightButton)},
NatureRemoLight.async_press_light_button,
)
platform.async_register_entity_service(
SERVICE_PRESS_CUSTOM_BUTTON,
{vol.Required("button_name"): cv.string},
NatureRemoLight.async_press_custom_button,
)
class NatureRemoLight(NatureRemoBase, LightEntity):
"""Implementation of a Nature Remo Light component."""
def __init__(self, coordinator, api, appliance, config):
super().__init__(coordinator, appliance)
self._api = api
self._buttons = [b["name"] for b in appliance["light"]["buttons"]]
self._signals = {s["name"]: s["id"] for s in appliance["signals"]}
self._is_on = False
self._is_night = False
# Entity methods
@property
def assumed_state(self):
"""Return True if unable to access real state of the entity."""
# Remo does return light.state however it doesn't seem to be correct
# in my experience.
return True
# ToggleEntity methods
@property
def is_on(self):
"""Return True if entity is on."""
return self._is_on
async def async_turn_on(self, **kwargs):
"""Turn device on."""
await self._post({"button": "on"})
self._set_on(True)
async def async_turn_off(self, **kwargs):
"""Turn device off."""
await self._post({"button": "off"})
self._set_on(False)
# LightEntity methods
@property
def supported_features(self):
"""Flag supported features."""
# Even though the IR remote of the light may support adjusting
# the brightness and color temperature, it's only ever by 1 grade
# and we don't know how many grades there are, so we can't even
# map the grades into anything useful.
return 0
@property
def state_attributes(self):
"""Return state attributes."""
if not self.is_on:
return None
return {ATTR_IS_NIGHT: self._is_night}
# own methods
async def _post(self, data):
await self._api.post(f"/appliances/{self._appliance_id}/light", data)
def _set_on(self, is_on, is_night = False):
self._is_on = is_on
self._is_night = is_night
self.async_write_ha_state()
async def async_press_light_button(self, service_call):
button = LightButton(service_call.data["button_name"])
await self._post({"button": button.value})
if button == LightButton.on_off and self._is_on \
or button == LightButton.night and self._is_night:
self._set_on(False)
else:
self._set_on(True, button == LightButton.night)
async def async_press_custom_button(self, service_call):
signal_name = service_call.data["button_name"]
signal_id = self._signals.get(signal_name)
if signal_id is None:
_LOGGER.error(f"Invalid signal name: {signal_name}")
return
await self._api.post(f"/signals/{signal_id}/send", None)
self._set_on(True)