Add support for Velux light devices (#49338)

Co-authored-by: Franck Nijhof <frenck@frenck.nl>
This commit is contained in:
Bram Gerritsen 2021-07-24 15:52:14 +02:00 committed by GitHub
parent ea1ec91c9c
commit 87e41e807c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 100 additions and 37 deletions

View File

@ -5,12 +5,14 @@ from pyvlx import PyVLX, PyVLXException
import voluptuous as vol import voluptuous as vol
from homeassistant.const import CONF_HOST, CONF_PASSWORD, EVENT_HOMEASSISTANT_STOP from homeassistant.const import CONF_HOST, CONF_PASSWORD, EVENT_HOMEASSISTANT_STOP
from homeassistant.core import callback
from homeassistant.helpers import discovery from homeassistant.helpers import discovery
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import Entity
DOMAIN = "velux" DOMAIN = "velux"
DATA_VELUX = "data_velux" DATA_VELUX = "data_velux"
PLATFORMS = ["cover", "scene"] PLATFORMS = ["cover", "light", "scene"]
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
CONFIG_SCHEMA = vol.Schema( CONFIG_SCHEMA = vol.Schema(
@ -75,3 +77,42 @@ class VeluxModule:
_LOGGER.debug("Velux interface started") _LOGGER.debug("Velux interface started")
await self.pyvlx.load_scenes() await self.pyvlx.load_scenes()
await self.pyvlx.load_nodes() await self.pyvlx.load_nodes()
class VeluxEntity(Entity):
"""Abstraction for al Velux entities."""
def __init__(self, node):
"""Initialize the Velux device."""
self.node = node
@callback
def async_register_callbacks(self):
"""Register callbacks to update hass after device was changed."""
async def after_update_callback(device):
"""Call after device was updated."""
self.async_write_ha_state()
self.node.register_device_updated_cb(after_update_callback)
async def async_added_to_hass(self):
"""Store register state change callback."""
self.async_register_callbacks()
@property
def unique_id(self) -> str:
"""Return the unique id base on the serial_id returned by Velux."""
return self.node.serial_number
@property
def name(self):
"""Return the name of the Velux device."""
if not self.node.name:
return "#" + str(self.node.node_id)
return self.node.name
@property
def should_poll(self):
"""No polling needed within Velux."""
return False

View File

@ -21,9 +21,8 @@ from homeassistant.components.cover import (
SUPPORT_STOP_TILT, SUPPORT_STOP_TILT,
CoverEntity, CoverEntity,
) )
from homeassistant.core import callback
from . import DATA_VELUX from . import DATA_VELUX, VeluxEntity
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
@ -35,42 +34,9 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
async_add_entities(entities) async_add_entities(entities)
class VeluxCover(CoverEntity): class VeluxCover(VeluxEntity, CoverEntity):
"""Representation of a Velux cover.""" """Representation of a Velux cover."""
def __init__(self, node):
"""Initialize the cover."""
self.node = node
@callback
def async_register_callbacks(self):
"""Register callbacks to update hass after device was changed."""
async def after_update_callback(device):
"""Call after device was updated."""
self.async_write_ha_state()
self.node.register_device_updated_cb(after_update_callback)
async def async_added_to_hass(self):
"""Store register state change callback."""
self.async_register_callbacks()
@property
def unique_id(self):
"""Return the unique ID of this cover."""
return self.node.serial_number
@property
def name(self):
"""Return the name of the Velux device."""
return self.node.name
@property
def should_poll(self):
"""No polling needed within Velux."""
return False
@property @property
def supported_features(self): def supported_features(self):
"""Flag supported features.""" """Flag supported features."""

View File

@ -0,0 +1,56 @@
"""Support for Velux lights."""
from pyvlx import Intensity, LighteningDevice
from pyvlx.node import Node
from homeassistant.components.light import (
ATTR_BRIGHTNESS,
COLOR_MODE_BRIGHTNESS,
LightEntity,
)
from . import DATA_VELUX, VeluxEntity
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
"""Set up light(s) for Velux platform."""
async_add_entities(
VeluxLight(node)
for node in hass.data[DATA_VELUX].pyvlx.nodes
if isinstance(node, LighteningDevice)
)
class VeluxLight(VeluxEntity, LightEntity):
"""Representation of a Velux light."""
def __init__(self, node: Node) -> None:
"""Initialize the Velux light."""
super().__init__(node)
self._attr_supported_color_modes = {COLOR_MODE_BRIGHTNESS}
self._attr_color_mode = COLOR_MODE_BRIGHTNESS
@property
def brightness(self):
"""Return the current brightness."""
return int((100 - self.node.intensity.intensity_percent) * 255 / 100)
@property
def is_on(self):
"""Return true if light is on."""
return not self.node.intensity.off and self.node.intensity.known
async def async_turn_on(self, **kwargs):
"""Instruct the light to turn on."""
if ATTR_BRIGHTNESS in kwargs:
intensity_percent = int(100 - kwargs[ATTR_BRIGHTNESS] / 255 * 100)
await self.node.set_intensity(
Intensity(intensity_percent=intensity_percent),
wait_for_completion=True,
)
else:
await self.node.turn_on(wait_for_completion=True)
async def async_turn_off(self, **kwargs):
"""Instruct the light to turn off."""
await self.node.turn_off(wait_for_completion=True)