mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 03:07:37 +00:00
Add support for Velux light devices (#49338)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
This commit is contained in:
parent
ea1ec91c9c
commit
87e41e807c
@ -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
|
||||||
|
@ -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."""
|
||||||
|
56
homeassistant/components/velux/light.py
Normal file
56
homeassistant/components/velux/light.py
Normal 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)
|
Loading…
x
Reference in New Issue
Block a user