Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 42 additions & 1 deletion homeassistant/components/velux/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
import voluptuous as vol

from homeassistant.const import CONF_HOST, CONF_PASSWORD, EVENT_HOMEASSISTANT_STOP
from homeassistant.core import callback
from homeassistant.helpers import discovery
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import Entity

DOMAIN = "velux"
DATA_VELUX = "data_velux"
PLATFORMS = ["cover", "scene"]
PLATFORMS = ["cover", "light", "scene"]
_LOGGER = logging.getLogger(__name__)

CONFIG_SCHEMA = vol.Schema(
Expand Down Expand Up @@ -75,3 +77,42 @@ async def async_start(self):
_LOGGER.debug("Velux interface started")
await self.pyvlx.load_scenes()
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
38 changes: 2 additions & 36 deletions homeassistant/components/velux/cover.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,8 @@
SUPPORT_STOP_TILT,
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):
Expand All @@ -35,42 +34,9 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
async_add_entities(entities)


class VeluxCover(CoverEntity):
class VeluxCover(VeluxEntity, CoverEntity):
"""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
def supported_features(self):
"""Flag supported features."""
Expand Down
56 changes: 56 additions & 0 deletions homeassistant/components/velux/light.py
Original file line number Diff line number Diff line change
@@ -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)