mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 21:27:38 +00:00
Velbus typing part 2 (#59148)
This commit is contained in:
parent
a079b4fd58
commit
6a21b241c0
@ -137,6 +137,7 @@ homeassistant.components.uptime.*
|
|||||||
homeassistant.components.uptimerobot.*
|
homeassistant.components.uptimerobot.*
|
||||||
homeassistant.components.vacuum.*
|
homeassistant.components.vacuum.*
|
||||||
homeassistant.components.vallox.*
|
homeassistant.components.vallox.*
|
||||||
|
homeassistant.components.velbus.*
|
||||||
homeassistant.components.vlc_telnet.*
|
homeassistant.components.vlc_telnet.*
|
||||||
homeassistant.components.water_heater.*
|
homeassistant.components.water_heater.*
|
||||||
homeassistant.components.watttime.*
|
homeassistant.components.watttime.*
|
||||||
|
@ -3,16 +3,18 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from velbusaio.channels import Channel as VelbusChannel
|
||||||
from velbusaio.controller import Velbus
|
from velbusaio.controller import Velbus
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
|
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
|
||||||
from homeassistant.const import CONF_ADDRESS, CONF_NAME, CONF_PORT
|
from homeassistant.const import CONF_ADDRESS, CONF_NAME, CONF_PORT
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant, ServiceCall
|
||||||
from homeassistant.helpers import device_registry
|
from homeassistant.helpers import device_registry
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
from homeassistant.helpers.device_registry import DeviceEntry
|
from homeassistant.helpers.device_registry import DeviceEntry
|
||||||
from homeassistant.helpers.entity import DeviceInfo, Entity
|
from homeassistant.helpers.entity import DeviceInfo, Entity
|
||||||
|
from homeassistant.helpers.typing import ConfigType
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
CONF_INTERFACE,
|
CONF_INTERFACE,
|
||||||
@ -32,7 +34,7 @@ CONFIG_SCHEMA = vol.Schema(
|
|||||||
PLATFORMS = ["switch", "sensor", "binary_sensor", "cover", "climate", "light"]
|
PLATFORMS = ["switch", "sensor", "binary_sensor", "cover", "climate", "light"]
|
||||||
|
|
||||||
|
|
||||||
async def async_setup(hass, config):
|
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||||
"""Set up the Velbus platform."""
|
"""Set up the Velbus platform."""
|
||||||
# Import from the configuration file if needed
|
# Import from the configuration file if needed
|
||||||
if DOMAIN not in config:
|
if DOMAIN not in config:
|
||||||
@ -97,7 +99,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
if hass.services.has_service(DOMAIN, SERVICE_SCAN):
|
if hass.services.has_service(DOMAIN, SERVICE_SCAN):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def check_entry_id(interface: str):
|
def check_entry_id(interface: str) -> str:
|
||||||
for entry in hass.config_entries.async_entries(DOMAIN):
|
for entry in hass.config_entries.async_entries(DOMAIN):
|
||||||
if "port" in entry.data and entry.data["port"] == interface:
|
if "port" in entry.data and entry.data["port"] == interface:
|
||||||
return entry.entry_id
|
return entry.entry_id
|
||||||
@ -105,7 +107,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
"The interface provided is not defined as a port in a Velbus integration"
|
"The interface provided is not defined as a port in a Velbus integration"
|
||||||
)
|
)
|
||||||
|
|
||||||
async def scan(call):
|
async def scan(call: ServiceCall) -> None:
|
||||||
await hass.data[DOMAIN][call.data[CONF_INTERFACE]]["cntrl"].scan()
|
await hass.data[DOMAIN][call.data[CONF_INTERFACE]]["cntrl"].scan()
|
||||||
|
|
||||||
hass.services.async_register(
|
hass.services.async_register(
|
||||||
@ -115,7 +117,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
vol.Schema({vol.Required(CONF_INTERFACE): vol.All(cv.string, check_entry_id)}),
|
vol.Schema({vol.Required(CONF_INTERFACE): vol.All(cv.string, check_entry_id)}),
|
||||||
)
|
)
|
||||||
|
|
||||||
async def syn_clock(call):
|
async def syn_clock(call: ServiceCall) -> None:
|
||||||
await hass.data[DOMAIN][call.data[CONF_INTERFACE]]["cntrl"].sync_clock()
|
await hass.data[DOMAIN][call.data[CONF_INTERFACE]]["cntrl"].sync_clock()
|
||||||
|
|
||||||
hass.services.async_register(
|
hass.services.async_register(
|
||||||
@ -125,7 +127,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
vol.Schema({vol.Required(CONF_INTERFACE): vol.All(cv.string, check_entry_id)}),
|
vol.Schema({vol.Required(CONF_INTERFACE): vol.All(cv.string, check_entry_id)}),
|
||||||
)
|
)
|
||||||
|
|
||||||
async def set_memo_text(call):
|
async def set_memo_text(call: ServiceCall) -> None:
|
||||||
"""Handle Memo Text service call."""
|
"""Handle Memo Text service call."""
|
||||||
memo_text = call.data[CONF_MEMO_TEXT]
|
memo_text = call.data[CONF_MEMO_TEXT]
|
||||||
memo_text.hass = hass
|
memo_text.hass = hass
|
||||||
@ -167,32 +169,32 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
class VelbusEntity(Entity):
|
class VelbusEntity(Entity):
|
||||||
"""Representation of a Velbus entity."""
|
"""Representation of a Velbus entity."""
|
||||||
|
|
||||||
def __init__(self, channel):
|
def __init__(self, channel: VelbusChannel) -> None:
|
||||||
"""Initialize a Velbus entity."""
|
"""Initialize a Velbus entity."""
|
||||||
self._channel = channel
|
self._channel = channel
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def unique_id(self):
|
def unique_id(self) -> str:
|
||||||
"""Get unique ID."""
|
"""Get unique ID."""
|
||||||
if (serial := self._channel.get_module_serial()) == 0:
|
if (serial := self._channel.get_module_serial()) == "":
|
||||||
serial = self._channel.get_module_address()
|
serial = str(self._channel.get_module_address())
|
||||||
return f"{serial}-{self._channel.get_channel_number()}"
|
return f"{serial}-{self._channel.get_channel_number()}"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self) -> str:
|
||||||
"""Return the display name of this entity."""
|
"""Return the display name of this entity."""
|
||||||
return self._channel.get_name()
|
return self._channel.get_name()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def should_poll(self):
|
def should_poll(self) -> bool:
|
||||||
"""Disable polling."""
|
"""Disable polling."""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
async def async_added_to_hass(self):
|
async def async_added_to_hass(self) -> None:
|
||||||
"""Add listener for state changes."""
|
"""Add listener for state changes."""
|
||||||
self._channel.on_status_update(self._on_update)
|
self._channel.on_status_update(self._on_update)
|
||||||
|
|
||||||
async def _on_update(self):
|
async def _on_update(self) -> None:
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -200,7 +202,7 @@ class VelbusEntity(Entity):
|
|||||||
"""Return the device info."""
|
"""Return the device info."""
|
||||||
return DeviceInfo(
|
return DeviceInfo(
|
||||||
identifiers={
|
identifiers={
|
||||||
(DOMAIN, self._channel.get_module_address()),
|
(DOMAIN, str(self._channel.get_module_address())),
|
||||||
},
|
},
|
||||||
manufacturer="Velleman",
|
manufacturer="Velleman",
|
||||||
model=self._channel.get_module_type_name(),
|
model=self._channel.get_module_type_name(),
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
"""Support for Velbus Binary Sensors."""
|
"""Support for Velbus Binary Sensors."""
|
||||||
|
from velbusaio.channels import Button as VelbusButton
|
||||||
|
|
||||||
from homeassistant.components.binary_sensor import BinarySensorEntity
|
from homeassistant.components.binary_sensor import BinarySensorEntity
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
@ -25,6 +27,8 @@ async def async_setup_entry(
|
|||||||
class VelbusBinarySensor(VelbusEntity, BinarySensorEntity):
|
class VelbusBinarySensor(VelbusEntity, BinarySensorEntity):
|
||||||
"""Representation of a Velbus Binary Sensor."""
|
"""Representation of a Velbus Binary Sensor."""
|
||||||
|
|
||||||
|
_channel: VelbusButton
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_on(self) -> bool:
|
def is_on(self) -> bool:
|
||||||
"""Return true if the sensor is on."""
|
"""Return true if the sensor is on."""
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
"""Support for Velbus thermostat."""
|
"""Support for Velbus thermostat."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from velbusaio.channels import Temperature as VelbusTemp
|
||||||
|
|
||||||
from homeassistant.components.climate import ClimateEntity
|
from homeassistant.components.climate import ClimateEntity
|
||||||
from homeassistant.components.climate.const import (
|
from homeassistant.components.climate.const import (
|
||||||
HVAC_MODE_HEAT,
|
HVAC_MODE_HEAT,
|
||||||
@ -33,6 +37,7 @@ async def async_setup_entry(
|
|||||||
class VelbusClimate(VelbusEntity, ClimateEntity):
|
class VelbusClimate(VelbusEntity, ClimateEntity):
|
||||||
"""Representation of a Velbus thermostat."""
|
"""Representation of a Velbus thermostat."""
|
||||||
|
|
||||||
|
_channel: VelbusTemp
|
||||||
_attr_supported_features = SUPPORT_TARGET_TEMPERATURE | SUPPORT_PRESET_MODE
|
_attr_supported_features = SUPPORT_TARGET_TEMPERATURE | SUPPORT_PRESET_MODE
|
||||||
_attr_temperature_unit = TEMP_CELSIUS
|
_attr_temperature_unit = TEMP_CELSIUS
|
||||||
_attr_hvac_mode = HVAC_MODE_HEAT
|
_attr_hvac_mode = HVAC_MODE_HEAT
|
||||||
@ -40,7 +45,7 @@ class VelbusClimate(VelbusEntity, ClimateEntity):
|
|||||||
_attr_preset_modes = list(PRESET_MODES)
|
_attr_preset_modes = list(PRESET_MODES)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def target_temperature(self) -> int | None:
|
def target_temperature(self) -> float | None:
|
||||||
"""Return the temperature we try to reach."""
|
"""Return the temperature we try to reach."""
|
||||||
return self._channel.get_climate_target()
|
return self._channel.get_climate_target()
|
||||||
|
|
||||||
@ -56,7 +61,7 @@ class VelbusClimate(VelbusEntity, ClimateEntity):
|
|||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def async_set_temperature(self, **kwargs) -> None:
|
async def async_set_temperature(self, **kwargs: Any) -> None:
|
||||||
"""Set new target temperatures."""
|
"""Set new target temperatures."""
|
||||||
if (temp := kwargs.get(ATTR_TEMPERATURE)) is None:
|
if (temp := kwargs.get(ATTR_TEMPERATURE)) is None:
|
||||||
return
|
return
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
"""Config flow for the Velbus platform."""
|
"""Config flow for the Velbus platform."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import velbusaio
|
import velbusaio
|
||||||
from velbusaio.exceptions import VelbusConnectionFailed
|
from velbusaio.exceptions import VelbusConnectionFailed
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
@ -8,16 +10,17 @@ import voluptuous as vol
|
|||||||
from homeassistant import config_entries
|
from homeassistant import config_entries
|
||||||
from homeassistant.const import CONF_NAME, CONF_PORT
|
from homeassistant.const import CONF_NAME, CONF_PORT
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
|
from homeassistant.data_entry_flow import FlowResult
|
||||||
from homeassistant.util import slugify
|
from homeassistant.util import slugify
|
||||||
|
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
|
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def velbus_entries(hass: HomeAssistant):
|
def velbus_entries(hass: HomeAssistant) -> set[str]:
|
||||||
"""Return connections for Velbus domain."""
|
"""Return connections for Velbus domain."""
|
||||||
return {
|
return {
|
||||||
(entry.data[CONF_PORT]) for entry in hass.config_entries.async_entries(DOMAIN)
|
entry.data[CONF_PORT] for entry in hass.config_entries.async_entries(DOMAIN)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -30,11 +33,11 @@ class VelbusConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
"""Initialize the velbus config flow."""
|
"""Initialize the velbus config flow."""
|
||||||
self._errors: dict[str, str] = {}
|
self._errors: dict[str, str] = {}
|
||||||
|
|
||||||
def _create_device(self, name: str, prt: str):
|
def _create_device(self, name: str, prt: str) -> FlowResult:
|
||||||
"""Create an entry async."""
|
"""Create an entry async."""
|
||||||
return self.async_create_entry(title=name, data={CONF_PORT: prt})
|
return self.async_create_entry(title=name, data={CONF_PORT: prt})
|
||||||
|
|
||||||
async def _test_connection(self, prt):
|
async def _test_connection(self, prt: str) -> bool:
|
||||||
"""Try to connect to the velbus with the port specified."""
|
"""Try to connect to the velbus with the port specified."""
|
||||||
try:
|
try:
|
||||||
controller = velbusaio.controller.Velbus(prt)
|
controller = velbusaio.controller.Velbus(prt)
|
||||||
@ -51,7 +54,9 @@ class VelbusConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
async def async_step_user(self, user_input=None):
|
async def async_step_user(
|
||||||
|
self, user_input: dict[str, Any] | None = None
|
||||||
|
) -> FlowResult:
|
||||||
"""Step when user initializes a integration."""
|
"""Step when user initializes a integration."""
|
||||||
self._errors = {}
|
self._errors = {}
|
||||||
if user_input is not None:
|
if user_input is not None:
|
||||||
@ -78,7 +83,7 @@ class VelbusConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
errors=self._errors,
|
errors=self._errors,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def async_step_import(self, user_input=None):
|
async def async_step_import(self, user_input: dict[str, Any]) -> FlowResult:
|
||||||
"""Import a config entry."""
|
"""Import a config entry."""
|
||||||
user_input[CONF_NAME] = "Velbus Import"
|
user_input[CONF_NAME] = "Velbus Import"
|
||||||
prt = user_input[CONF_PORT]
|
prt = user_input[CONF_PORT]
|
||||||
|
@ -3,7 +3,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from velbusaio.channels import Channel as VelbusChannel
|
from velbusaio.channels import Blind as VelbusBlind
|
||||||
|
|
||||||
from homeassistant.components.cover import (
|
from homeassistant.components.cover import (
|
||||||
ATTR_POSITION,
|
ATTR_POSITION,
|
||||||
@ -38,7 +38,9 @@ async def async_setup_entry(
|
|||||||
class VelbusCover(VelbusEntity, CoverEntity):
|
class VelbusCover(VelbusEntity, CoverEntity):
|
||||||
"""Representation a Velbus cover."""
|
"""Representation a Velbus cover."""
|
||||||
|
|
||||||
def __init__(self, channel: VelbusChannel) -> None:
|
_channel: VelbusBlind
|
||||||
|
|
||||||
|
def __init__(self, channel: VelbusBlind) -> None:
|
||||||
"""Initialize the dimmer."""
|
"""Initialize the dimmer."""
|
||||||
super().__init__(channel)
|
super().__init__(channel)
|
||||||
if self._channel.support_position():
|
if self._channel.support_position():
|
||||||
@ -60,8 +62,7 @@ class VelbusCover(VelbusEntity, CoverEntity):
|
|||||||
None is unknown, 0 is closed, 100 is fully open
|
None is unknown, 0 is closed, 100 is fully open
|
||||||
Velbus: 100 = closed, 0 = open
|
Velbus: 100 = closed, 0 = open
|
||||||
"""
|
"""
|
||||||
pos = self._channel.get_position()
|
return 100 - self._channel.get_position()
|
||||||
return 100 - pos
|
|
||||||
|
|
||||||
async def async_open_cover(self, **kwargs: Any) -> None:
|
async def async_open_cover(self, **kwargs: Any) -> None:
|
||||||
"""Open the cover."""
|
"""Open the cover."""
|
||||||
|
@ -1,4 +1,14 @@
|
|||||||
"""Support for Velbus light."""
|
"""Support for Velbus light."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from velbusaio.channels import (
|
||||||
|
Button as VelbusButton,
|
||||||
|
Channel as VelbusChannel,
|
||||||
|
Dimmer as VelbusDimmer,
|
||||||
|
)
|
||||||
|
|
||||||
from homeassistant.components.light import (
|
from homeassistant.components.light import (
|
||||||
ATTR_BRIGHTNESS,
|
ATTR_BRIGHTNESS,
|
||||||
ATTR_FLASH,
|
ATTR_FLASH,
|
||||||
@ -10,16 +20,24 @@ from homeassistant.components.light import (
|
|||||||
SUPPORT_TRANSITION,
|
SUPPORT_TRANSITION,
|
||||||
LightEntity,
|
LightEntity,
|
||||||
)
|
)
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.entity import Entity
|
||||||
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import VelbusEntity
|
from . import VelbusEntity
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass, entry, async_add_entities):
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
entry: ConfigEntry,
|
||||||
|
async_add_entities: AddEntitiesCallback,
|
||||||
|
) -> None:
|
||||||
"""Set up Velbus switch based on config_entry."""
|
"""Set up Velbus switch based on config_entry."""
|
||||||
await hass.data[DOMAIN][entry.entry_id]["tsk"]
|
await hass.data[DOMAIN][entry.entry_id]["tsk"]
|
||||||
cntrl = hass.data[DOMAIN][entry.entry_id]["cntrl"]
|
cntrl = hass.data[DOMAIN][entry.entry_id]["cntrl"]
|
||||||
entities = []
|
entities: list[Entity] = []
|
||||||
for channel in cntrl.get_all("light"):
|
for channel in cntrl.get_all("light"):
|
||||||
entities.append(VelbusLight(channel))
|
entities.append(VelbusLight(channel))
|
||||||
for channel in cntrl.get_all("led"):
|
for channel in cntrl.get_all("led"):
|
||||||
@ -30,24 +48,25 @@ async def async_setup_entry(hass, entry, async_add_entities):
|
|||||||
class VelbusLight(VelbusEntity, LightEntity):
|
class VelbusLight(VelbusEntity, LightEntity):
|
||||||
"""Representation of a Velbus light."""
|
"""Representation of a Velbus light."""
|
||||||
|
|
||||||
|
_channel: VelbusDimmer
|
||||||
_attr_supported_feature = SUPPORT_BRIGHTNESS | SUPPORT_TRANSITION
|
_attr_supported_feature = SUPPORT_BRIGHTNESS | SUPPORT_TRANSITION
|
||||||
|
|
||||||
def __init__(self, channel):
|
def __init__(self, channel: VelbusDimmer) -> None:
|
||||||
"""Initialize the dimmer."""
|
"""Initialize the dimmer."""
|
||||||
super().__init__(channel)
|
super().__init__(channel)
|
||||||
self._attr_name = self._channel.get_name()
|
self._attr_name = self._channel.get_name()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_on(self):
|
def is_on(self) -> bool:
|
||||||
"""Return true if the light is on."""
|
"""Return true if the light is on."""
|
||||||
return self._channel.is_on()
|
return self._channel.is_on()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def brightness(self):
|
def brightness(self) -> int:
|
||||||
"""Return the brightness of the light."""
|
"""Return the brightness of the light."""
|
||||||
return int((self._channel.get_dimmer_state() * 255) / 100)
|
return int((self._channel.get_dimmer_state() * 255) / 100)
|
||||||
|
|
||||||
async def async_turn_on(self, **kwargs):
|
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||||
"""Instruct the Velbus light to turn on."""
|
"""Instruct the Velbus light to turn on."""
|
||||||
if ATTR_BRIGHTNESS in kwargs:
|
if ATTR_BRIGHTNESS in kwargs:
|
||||||
# Make sure a low but non-zero value is not rounded down to zero
|
# Make sure a low but non-zero value is not rounded down to zero
|
||||||
@ -67,7 +86,7 @@ class VelbusLight(VelbusEntity, LightEntity):
|
|||||||
)
|
)
|
||||||
await getattr(self._channel, attr)(*args)
|
await getattr(self._channel, attr)(*args)
|
||||||
|
|
||||||
async def async_turn_off(self, **kwargs):
|
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||||
"""Instruct the velbus light to turn off."""
|
"""Instruct the velbus light to turn off."""
|
||||||
attr, *args = (
|
attr, *args = (
|
||||||
"set_dimmer_state",
|
"set_dimmer_state",
|
||||||
@ -80,25 +99,21 @@ class VelbusLight(VelbusEntity, LightEntity):
|
|||||||
class VelbusButtonLight(VelbusEntity, LightEntity):
|
class VelbusButtonLight(VelbusEntity, LightEntity):
|
||||||
"""Representation of a Velbus light."""
|
"""Representation of a Velbus light."""
|
||||||
|
|
||||||
|
_channel: VelbusButton
|
||||||
_attr_entity_registry_enabled_default = False
|
_attr_entity_registry_enabled_default = False
|
||||||
_attr_supported_feature = SUPPORT_FLASH
|
_attr_supported_feature = SUPPORT_FLASH
|
||||||
|
|
||||||
def __init__(self, channel):
|
def __init__(self, channel: VelbusChannel) -> None:
|
||||||
"""Initialize the button light (led)."""
|
"""Initialize the button light (led)."""
|
||||||
super().__init__(channel)
|
super().__init__(channel)
|
||||||
self._attr_name = f"LED {self._channel.get_name()}"
|
self._attr_name = f"LED {self._channel.get_name()}"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_on(self):
|
def is_on(self) -> Any:
|
||||||
"""Return true if the light is on."""
|
"""Return true if the light is on."""
|
||||||
return self._channel.is_on()
|
return self._channel.is_on()
|
||||||
|
|
||||||
@property
|
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||||
def brightness(self):
|
|
||||||
"""Return the brightness of the light."""
|
|
||||||
return int((self._channel.get_dimmer_state() * 255) / 100)
|
|
||||||
|
|
||||||
async def async_turn_on(self, **kwargs):
|
|
||||||
"""Instruct the Velbus light to turn on."""
|
"""Instruct the Velbus light to turn on."""
|
||||||
if ATTR_FLASH in kwargs:
|
if ATTR_FLASH in kwargs:
|
||||||
if kwargs[ATTR_FLASH] == FLASH_LONG:
|
if kwargs[ATTR_FLASH] == FLASH_LONG:
|
||||||
@ -111,7 +126,7 @@ class VelbusButtonLight(VelbusEntity, LightEntity):
|
|||||||
attr, *args = "set_led_state", "on"
|
attr, *args = "set_led_state", "on"
|
||||||
await getattr(self._channel, attr)(*args)
|
await getattr(self._channel, attr)(*args)
|
||||||
|
|
||||||
async def async_turn_off(self, **kwargs):
|
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||||
"""Instruct the velbus light to turn off."""
|
"""Instruct the velbus light to turn off."""
|
||||||
attr, *args = "set_led_state", "off"
|
attr, *args = "set_led_state", "off"
|
||||||
await getattr(self._channel, attr)(*args)
|
await getattr(self._channel, attr)(*args)
|
||||||
|
@ -1,22 +1,31 @@
|
|||||||
"""Support for Velbus sensors."""
|
"""Support for Velbus sensors."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from velbusaio.channels import ButtonCounter, LightSensor, SensorNumber, Temperature
|
||||||
|
|
||||||
from homeassistant.components.sensor import (
|
from homeassistant.components.sensor import (
|
||||||
STATE_CLASS_MEASUREMENT,
|
STATE_CLASS_MEASUREMENT,
|
||||||
STATE_CLASS_TOTAL_INCREASING,
|
STATE_CLASS_TOTAL_INCREASING,
|
||||||
SensorEntity,
|
SensorEntity,
|
||||||
)
|
)
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
DEVICE_CLASS_ENERGY,
|
DEVICE_CLASS_ENERGY,
|
||||||
DEVICE_CLASS_POWER,
|
DEVICE_CLASS_POWER,
|
||||||
DEVICE_CLASS_TEMPERATURE,
|
DEVICE_CLASS_TEMPERATURE,
|
||||||
)
|
)
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import VelbusEntity
|
from . import VelbusEntity
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass, entry, async_add_entities):
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
entry: ConfigEntry,
|
||||||
|
async_add_entities: AddEntitiesCallback,
|
||||||
|
) -> None:
|
||||||
"""Set up Velbus switch based on config_entry."""
|
"""Set up Velbus switch based on config_entry."""
|
||||||
await hass.data[DOMAIN][entry.entry_id]["tsk"]
|
await hass.data[DOMAIN][entry.entry_id]["tsk"]
|
||||||
cntrl = hass.data[DOMAIN][entry.entry_id]["cntrl"]
|
cntrl = hass.data[DOMAIN][entry.entry_id]["cntrl"]
|
||||||
@ -31,13 +40,19 @@ async def async_setup_entry(hass, entry, async_add_entities):
|
|||||||
class VelbusSensor(VelbusEntity, SensorEntity):
|
class VelbusSensor(VelbusEntity, SensorEntity):
|
||||||
"""Representation of a sensor."""
|
"""Representation of a sensor."""
|
||||||
|
|
||||||
def __init__(self, channel, counter=False):
|
_channel: ButtonCounter | Temperature | LightSensor | SensorNumber
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
channel: ButtonCounter | Temperature | LightSensor | SensorNumber,
|
||||||
|
counter: bool = False,
|
||||||
|
) -> None:
|
||||||
"""Initialize a sensor Velbus entity."""
|
"""Initialize a sensor Velbus entity."""
|
||||||
super().__init__(channel)
|
super().__init__(channel)
|
||||||
self._is_counter = counter
|
self._is_counter: bool = counter
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def unique_id(self):
|
def unique_id(self) -> str:
|
||||||
"""Return unique ID for counter sensors."""
|
"""Return unique ID for counter sensors."""
|
||||||
unique_id = super().unique_id
|
unique_id = super().unique_id
|
||||||
if self._is_counter:
|
if self._is_counter:
|
||||||
@ -45,7 +60,7 @@ class VelbusSensor(VelbusEntity, SensorEntity):
|
|||||||
return unique_id
|
return unique_id
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self) -> str:
|
||||||
"""Return the name for the sensor."""
|
"""Return the name for the sensor."""
|
||||||
name = super().name
|
name = super().name
|
||||||
if self._is_counter:
|
if self._is_counter:
|
||||||
@ -53,7 +68,7 @@ class VelbusSensor(VelbusEntity, SensorEntity):
|
|||||||
return name
|
return name
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_class(self):
|
def device_class(self) -> str | None:
|
||||||
"""Return the device class of the sensor."""
|
"""Return the device class of the sensor."""
|
||||||
if self._is_counter:
|
if self._is_counter:
|
||||||
return DEVICE_CLASS_ENERGY
|
return DEVICE_CLASS_ENERGY
|
||||||
@ -64,28 +79,28 @@ class VelbusSensor(VelbusEntity, SensorEntity):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_value(self):
|
def native_value(self) -> float | int | None:
|
||||||
"""Return the state of the sensor."""
|
"""Return the state of the sensor."""
|
||||||
if self._is_counter:
|
if self._is_counter:
|
||||||
return self._channel.get_counter_state()
|
return float(self._channel.get_counter_state())
|
||||||
return self._channel.get_state()
|
return float(self._channel.get_state())
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_unit_of_measurement(self):
|
def native_unit_of_measurement(self) -> str:
|
||||||
"""Return the unit this state is expressed in."""
|
"""Return the unit this state is expressed in."""
|
||||||
if self._is_counter:
|
if self._is_counter:
|
||||||
return self._channel.get_counter_unit()
|
return str(self._channel.get_counter_unit())
|
||||||
return self._channel.get_unit()
|
return str(self._channel.get_unit())
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def icon(self):
|
def icon(self) -> str | None:
|
||||||
"""Icon to use in the frontend."""
|
"""Icon to use in the frontend."""
|
||||||
if self._is_counter:
|
if self._is_counter:
|
||||||
return "mdi:counter"
|
return "mdi:counter"
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def state_class(self):
|
def state_class(self) -> str:
|
||||||
"""Return the state class of this device."""
|
"""Return the state class of this device."""
|
||||||
if self._is_counter:
|
if self._is_counter:
|
||||||
return STATE_CLASS_TOTAL_INCREASING
|
return STATE_CLASS_TOTAL_INCREASING
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
"""Support for Velbus switches."""
|
"""Support for Velbus switches."""
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
from velbusaio.channels import Relay as VelbusRelay
|
||||||
|
|
||||||
from homeassistant.components.switch import SwitchEntity
|
from homeassistant.components.switch import SwitchEntity
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
@ -27,6 +29,8 @@ async def async_setup_entry(
|
|||||||
class VelbusSwitch(VelbusEntity, SwitchEntity):
|
class VelbusSwitch(VelbusEntity, SwitchEntity):
|
||||||
"""Representation of a switch."""
|
"""Representation of a switch."""
|
||||||
|
|
||||||
|
_channel: VelbusRelay
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_on(self) -> bool:
|
def is_on(self) -> bool:
|
||||||
"""Return true if the switch is on."""
|
"""Return true if the switch is on."""
|
||||||
|
11
mypy.ini
11
mypy.ini
@ -1518,6 +1518,17 @@ no_implicit_optional = true
|
|||||||
warn_return_any = true
|
warn_return_any = true
|
||||||
warn_unreachable = true
|
warn_unreachable = true
|
||||||
|
|
||||||
|
[mypy-homeassistant.components.velbus.*]
|
||||||
|
check_untyped_defs = true
|
||||||
|
disallow_incomplete_defs = true
|
||||||
|
disallow_subclassing_any = true
|
||||||
|
disallow_untyped_calls = true
|
||||||
|
disallow_untyped_decorators = true
|
||||||
|
disallow_untyped_defs = true
|
||||||
|
no_implicit_optional = true
|
||||||
|
warn_return_any = true
|
||||||
|
warn_unreachable = true
|
||||||
|
|
||||||
[mypy-homeassistant.components.vlc_telnet.*]
|
[mypy-homeassistant.components.vlc_telnet.*]
|
||||||
check_untyped_defs = true
|
check_untyped_defs = true
|
||||||
disallow_incomplete_defs = true
|
disallow_incomplete_defs = true
|
||||||
|
Loading…
x
Reference in New Issue
Block a user