868 lines
28 KiB
Python
868 lines
28 KiB
Python
"""Support for ZHA AnalogOutput cluster."""
|
|
from __future__ import annotations
|
|
|
|
import functools
|
|
import logging
|
|
from typing import TYPE_CHECKING, Any, TypeVar
|
|
|
|
import zigpy.exceptions
|
|
from zigpy.zcl.foundation import Status
|
|
|
|
from homeassistant.components.number import NumberEntity, NumberMode
|
|
from homeassistant.config_entries import ConfigEntry
|
|
from homeassistant.const import Platform, UnitOfMass
|
|
from homeassistant.core import HomeAssistant, callback
|
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
|
from homeassistant.helpers.entity import EntityCategory
|
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|
|
|
from .core import discovery
|
|
from .core.const import (
|
|
CHANNEL_ANALOG_OUTPUT,
|
|
CHANNEL_BASIC,
|
|
CHANNEL_COLOR,
|
|
CHANNEL_INOVELLI,
|
|
CHANNEL_LEVEL,
|
|
DATA_ZHA,
|
|
SIGNAL_ADD_ENTITIES,
|
|
SIGNAL_ATTR_UPDATED,
|
|
)
|
|
from .core.registries import ZHA_ENTITIES
|
|
from .entity import ZhaEntity
|
|
|
|
if TYPE_CHECKING:
|
|
from .core.channels.base import ZigbeeChannel
|
|
from .core.device import ZHADevice
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
_ZHANumberConfigurationEntitySelfT = TypeVar(
|
|
"_ZHANumberConfigurationEntitySelfT", bound="ZHANumberConfigurationEntity"
|
|
)
|
|
|
|
STRICT_MATCH = functools.partial(ZHA_ENTITIES.strict_match, Platform.NUMBER)
|
|
CONFIG_DIAGNOSTIC_MATCH = functools.partial(
|
|
ZHA_ENTITIES.config_diagnostic_match, Platform.NUMBER
|
|
)
|
|
|
|
|
|
UNITS = {
|
|
0: "Square-meters",
|
|
1: "Square-feet",
|
|
2: "Milliamperes",
|
|
3: "Amperes",
|
|
4: "Ohms",
|
|
5: "Volts",
|
|
6: "Kilo-volts",
|
|
7: "Mega-volts",
|
|
8: "Volt-amperes",
|
|
9: "Kilo-volt-amperes",
|
|
10: "Mega-volt-amperes",
|
|
11: "Volt-amperes-reactive",
|
|
12: "Kilo-volt-amperes-reactive",
|
|
13: "Mega-volt-amperes-reactive",
|
|
14: "Degrees-phase",
|
|
15: "Power-factor",
|
|
16: "Joules",
|
|
17: "Kilojoules",
|
|
18: "Watt-hours",
|
|
19: "Kilowatt-hours",
|
|
20: "BTUs",
|
|
21: "Therms",
|
|
22: "Ton-hours",
|
|
23: "Joules-per-kilogram-dry-air",
|
|
24: "BTUs-per-pound-dry-air",
|
|
25: "Cycles-per-hour",
|
|
26: "Cycles-per-minute",
|
|
27: "Hertz",
|
|
28: "Grams-of-water-per-kilogram-dry-air",
|
|
29: "Percent-relative-humidity",
|
|
30: "Millimeters",
|
|
31: "Meters",
|
|
32: "Inches",
|
|
33: "Feet",
|
|
34: "Watts-per-square-foot",
|
|
35: "Watts-per-square-meter",
|
|
36: "Lumens",
|
|
37: "Luxes",
|
|
38: "Foot-candles",
|
|
39: "Kilograms",
|
|
40: "Pounds-mass",
|
|
41: "Tons",
|
|
42: "Kilograms-per-second",
|
|
43: "Kilograms-per-minute",
|
|
44: "Kilograms-per-hour",
|
|
45: "Pounds-mass-per-minute",
|
|
46: "Pounds-mass-per-hour",
|
|
47: "Watts",
|
|
48: "Kilowatts",
|
|
49: "Megawatts",
|
|
50: "BTUs-per-hour",
|
|
51: "Horsepower",
|
|
52: "Tons-refrigeration",
|
|
53: "Pascals",
|
|
54: "Kilopascals",
|
|
55: "Bars",
|
|
56: "Pounds-force-per-square-inch",
|
|
57: "Centimeters-of-water",
|
|
58: "Inches-of-water",
|
|
59: "Millimeters-of-mercury",
|
|
60: "Centimeters-of-mercury",
|
|
61: "Inches-of-mercury",
|
|
62: "°C",
|
|
63: "°K",
|
|
64: "°F",
|
|
65: "Degree-days-Celsius",
|
|
66: "Degree-days-Fahrenheit",
|
|
67: "Years",
|
|
68: "Months",
|
|
69: "Weeks",
|
|
70: "Days",
|
|
71: "Hours",
|
|
72: "Minutes",
|
|
73: "Seconds",
|
|
74: "Meters-per-second",
|
|
75: "Kilometers-per-hour",
|
|
76: "Feet-per-second",
|
|
77: "Feet-per-minute",
|
|
78: "Miles-per-hour",
|
|
79: "Cubic-feet",
|
|
80: "Cubic-meters",
|
|
81: "Imperial-gallons",
|
|
82: "Liters",
|
|
83: "Us-gallons",
|
|
84: "Cubic-feet-per-minute",
|
|
85: "Cubic-meters-per-second",
|
|
86: "Imperial-gallons-per-minute",
|
|
87: "Liters-per-second",
|
|
88: "Liters-per-minute",
|
|
89: "Us-gallons-per-minute",
|
|
90: "Degrees-angular",
|
|
91: "Degrees-Celsius-per-hour",
|
|
92: "Degrees-Celsius-per-minute",
|
|
93: "Degrees-Fahrenheit-per-hour",
|
|
94: "Degrees-Fahrenheit-per-minute",
|
|
95: None,
|
|
96: "Parts-per-million",
|
|
97: "Parts-per-billion",
|
|
98: "%",
|
|
99: "Percent-per-second",
|
|
100: "Per-minute",
|
|
101: "Per-second",
|
|
102: "Psi-per-Degree-Fahrenheit",
|
|
103: "Radians",
|
|
104: "Revolutions-per-minute",
|
|
105: "Currency1",
|
|
106: "Currency2",
|
|
107: "Currency3",
|
|
108: "Currency4",
|
|
109: "Currency5",
|
|
110: "Currency6",
|
|
111: "Currency7",
|
|
112: "Currency8",
|
|
113: "Currency9",
|
|
114: "Currency10",
|
|
115: "Square-inches",
|
|
116: "Square-centimeters",
|
|
117: "BTUs-per-pound",
|
|
118: "Centimeters",
|
|
119: "Pounds-mass-per-second",
|
|
120: "Delta-Degrees-Fahrenheit",
|
|
121: "Delta-Degrees-Kelvin",
|
|
122: "Kilohms",
|
|
123: "Megohms",
|
|
124: "Millivolts",
|
|
125: "Kilojoules-per-kilogram",
|
|
126: "Megajoules",
|
|
127: "Joules-per-degree-Kelvin",
|
|
128: "Joules-per-kilogram-degree-Kelvin",
|
|
129: "Kilohertz",
|
|
130: "Megahertz",
|
|
131: "Per-hour",
|
|
132: "Milliwatts",
|
|
133: "Hectopascals",
|
|
134: "Millibars",
|
|
135: "Cubic-meters-per-hour",
|
|
136: "Liters-per-hour",
|
|
137: "Kilowatt-hours-per-square-meter",
|
|
138: "Kilowatt-hours-per-square-foot",
|
|
139: "Megajoules-per-square-meter",
|
|
140: "Megajoules-per-square-foot",
|
|
141: "Watts-per-square-meter-Degree-Kelvin",
|
|
142: "Cubic-feet-per-second",
|
|
143: "Percent-obscuration-per-foot",
|
|
144: "Percent-obscuration-per-meter",
|
|
145: "Milliohms",
|
|
146: "Megawatt-hours",
|
|
147: "Kilo-BTUs",
|
|
148: "Mega-BTUs",
|
|
149: "Kilojoules-per-kilogram-dry-air",
|
|
150: "Megajoules-per-kilogram-dry-air",
|
|
151: "Kilojoules-per-degree-Kelvin",
|
|
152: "Megajoules-per-degree-Kelvin",
|
|
153: "Newton",
|
|
154: "Grams-per-second",
|
|
155: "Grams-per-minute",
|
|
156: "Tons-per-hour",
|
|
157: "Kilo-BTUs-per-hour",
|
|
158: "Hundredths-seconds",
|
|
159: "Milliseconds",
|
|
160: "Newton-meters",
|
|
161: "Millimeters-per-second",
|
|
162: "Millimeters-per-minute",
|
|
163: "Meters-per-minute",
|
|
164: "Meters-per-hour",
|
|
165: "Cubic-meters-per-minute",
|
|
166: "Meters-per-second-per-second",
|
|
167: "Amperes-per-meter",
|
|
168: "Amperes-per-square-meter",
|
|
169: "Ampere-square-meters",
|
|
170: "Farads",
|
|
171: "Henrys",
|
|
172: "Ohm-meters",
|
|
173: "Siemens",
|
|
174: "Siemens-per-meter",
|
|
175: "Teslas",
|
|
176: "Volts-per-degree-Kelvin",
|
|
177: "Volts-per-meter",
|
|
178: "Webers",
|
|
179: "Candelas",
|
|
180: "Candelas-per-square-meter",
|
|
181: "Kelvins-per-hour",
|
|
182: "Kelvins-per-minute",
|
|
183: "Joule-seconds",
|
|
185: "Square-meters-per-Newton",
|
|
186: "Kilogram-per-cubic-meter",
|
|
187: "Newton-seconds",
|
|
188: "Newtons-per-meter",
|
|
189: "Watts-per-meter-per-degree-Kelvin",
|
|
}
|
|
|
|
ICONS = {
|
|
0: "mdi:temperature-celsius",
|
|
1: "mdi:water-percent",
|
|
2: "mdi:gauge",
|
|
3: "mdi:speedometer",
|
|
4: "mdi:percent",
|
|
5: "mdi:air-filter",
|
|
6: "mdi:fan",
|
|
7: "mdi:flash",
|
|
8: "mdi:current-ac",
|
|
9: "mdi:flash",
|
|
10: "mdi:flash",
|
|
11: "mdi:flash",
|
|
12: "mdi:counter",
|
|
13: "mdi:thermometer-lines",
|
|
14: "mdi:timer",
|
|
15: "mdi:palette",
|
|
16: "mdi:brightness-percent",
|
|
}
|
|
|
|
|
|
async def async_setup_entry(
|
|
hass: HomeAssistant,
|
|
config_entry: ConfigEntry,
|
|
async_add_entities: AddEntitiesCallback,
|
|
) -> None:
|
|
"""Set up the Zigbee Home Automation Analog Output from config entry."""
|
|
entities_to_create = hass.data[DATA_ZHA][Platform.NUMBER]
|
|
|
|
unsub = async_dispatcher_connect(
|
|
hass,
|
|
SIGNAL_ADD_ENTITIES,
|
|
functools.partial(
|
|
discovery.async_add_entities,
|
|
async_add_entities,
|
|
entities_to_create,
|
|
),
|
|
)
|
|
config_entry.async_on_unload(unsub)
|
|
|
|
|
|
@STRICT_MATCH(channel_names=CHANNEL_ANALOG_OUTPUT)
|
|
class ZhaNumber(ZhaEntity, NumberEntity):
|
|
"""Representation of a ZHA Number entity."""
|
|
|
|
def __init__(
|
|
self,
|
|
unique_id: str,
|
|
zha_device: ZHADevice,
|
|
channels: list[ZigbeeChannel],
|
|
**kwargs: Any,
|
|
) -> None:
|
|
"""Init this entity."""
|
|
super().__init__(unique_id, zha_device, channels, **kwargs)
|
|
self._analog_output_channel = self.cluster_channels[CHANNEL_ANALOG_OUTPUT]
|
|
|
|
async def async_added_to_hass(self) -> None:
|
|
"""Run when about to be added to hass."""
|
|
await super().async_added_to_hass()
|
|
self.async_accept_signal(
|
|
self._analog_output_channel, SIGNAL_ATTR_UPDATED, self.async_set_state
|
|
)
|
|
|
|
@property
|
|
def native_value(self) -> float | None:
|
|
"""Return the current value."""
|
|
return self._analog_output_channel.present_value
|
|
|
|
@property
|
|
def native_min_value(self) -> float:
|
|
"""Return the minimum value."""
|
|
min_present_value = self._analog_output_channel.min_present_value
|
|
if min_present_value is not None:
|
|
return min_present_value
|
|
return 0
|
|
|
|
@property
|
|
def native_max_value(self) -> float:
|
|
"""Return the maximum value."""
|
|
max_present_value = self._analog_output_channel.max_present_value
|
|
if max_present_value is not None:
|
|
return max_present_value
|
|
return 1023
|
|
|
|
@property
|
|
def native_step(self) -> float | None:
|
|
"""Return the value step."""
|
|
resolution = self._analog_output_channel.resolution
|
|
if resolution is not None:
|
|
return resolution
|
|
return super().native_step
|
|
|
|
@property
|
|
def name(self) -> str:
|
|
"""Return the name of the number entity."""
|
|
description = self._analog_output_channel.description
|
|
if description is not None and len(description) > 0:
|
|
return f"{super().name} {description}"
|
|
return super().name
|
|
|
|
@property
|
|
def icon(self) -> str | None:
|
|
"""Return the icon to be used for this entity."""
|
|
application_type = self._analog_output_channel.application_type
|
|
if application_type is not None:
|
|
return ICONS.get(application_type >> 16, super().icon)
|
|
return super().icon
|
|
|
|
@property
|
|
def native_unit_of_measurement(self) -> str | None:
|
|
"""Return the unit the value is expressed in."""
|
|
engineering_units = self._analog_output_channel.engineering_units
|
|
return UNITS.get(engineering_units)
|
|
|
|
@callback
|
|
def async_set_state(self, attr_id, attr_name, value):
|
|
"""Handle value update from channel."""
|
|
self.async_write_ha_state()
|
|
|
|
async def async_set_native_value(self, value: float) -> None:
|
|
"""Update the current value from HA."""
|
|
num_value = float(value)
|
|
if await self._analog_output_channel.async_set_present_value(num_value):
|
|
self.async_write_ha_state()
|
|
|
|
async def async_update(self) -> None:
|
|
"""Attempt to retrieve the state of the entity."""
|
|
await super().async_update()
|
|
_LOGGER.debug("polling current state")
|
|
if self._analog_output_channel:
|
|
value = await self._analog_output_channel.get_attribute_value(
|
|
"present_value", from_cache=False
|
|
)
|
|
_LOGGER.debug("read value=%s", value)
|
|
|
|
|
|
class ZHANumberConfigurationEntity(ZhaEntity, NumberEntity):
|
|
"""Representation of a ZHA number configuration entity."""
|
|
|
|
_attr_entity_category = EntityCategory.CONFIG
|
|
_attr_native_step: float = 1.0
|
|
_zcl_attribute: str
|
|
|
|
@classmethod
|
|
def create_entity(
|
|
cls: type[_ZHANumberConfigurationEntitySelfT],
|
|
unique_id: str,
|
|
zha_device: ZHADevice,
|
|
channels: list[ZigbeeChannel],
|
|
**kwargs: Any,
|
|
) -> _ZHANumberConfigurationEntitySelfT | None:
|
|
"""Entity Factory.
|
|
|
|
Return entity if it is a supported configuration, otherwise return None
|
|
"""
|
|
channel = channels[0]
|
|
if (
|
|
cls._zcl_attribute in channel.cluster.unsupported_attributes
|
|
or channel.cluster.get(cls._zcl_attribute) is None
|
|
):
|
|
_LOGGER.debug(
|
|
"%s is not supported - skipping %s entity creation",
|
|
cls._zcl_attribute,
|
|
cls.__name__,
|
|
)
|
|
return None
|
|
|
|
return cls(unique_id, zha_device, channels, **kwargs)
|
|
|
|
def __init__(
|
|
self,
|
|
unique_id: str,
|
|
zha_device: ZHADevice,
|
|
channels: list[ZigbeeChannel],
|
|
**kwargs: Any,
|
|
) -> None:
|
|
"""Init this number configuration entity."""
|
|
self._channel: ZigbeeChannel = channels[0]
|
|
super().__init__(unique_id, zha_device, channels, **kwargs)
|
|
|
|
@property
|
|
def native_value(self) -> float:
|
|
"""Return the current value."""
|
|
return self._channel.cluster.get(self._zcl_attribute)
|
|
|
|
async def async_set_native_value(self, value: float) -> None:
|
|
"""Update the current value from HA."""
|
|
try:
|
|
res = await self._channel.cluster.write_attributes(
|
|
{self._zcl_attribute: int(value)}
|
|
)
|
|
except zigpy.exceptions.ZigbeeException as ex:
|
|
self.error("Could not set value: %s", ex)
|
|
return
|
|
if not isinstance(res, Exception) and all(
|
|
record.status == Status.SUCCESS for record in res[0]
|
|
):
|
|
self.async_write_ha_state()
|
|
|
|
async def async_update(self) -> None:
|
|
"""Attempt to retrieve the state of the entity."""
|
|
await super().async_update()
|
|
_LOGGER.debug("polling current state")
|
|
if self._channel:
|
|
value = await self._channel.get_attribute_value(
|
|
self._zcl_attribute, from_cache=False
|
|
)
|
|
_LOGGER.debug("read value=%s", value)
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(
|
|
channel_names="opple_cluster", models={"lumi.motion.ac02", "lumi.motion.agl04"}
|
|
)
|
|
class AqaraMotionDetectionInterval(
|
|
ZHANumberConfigurationEntity, id_suffix="detection_interval"
|
|
):
|
|
"""Representation of a ZHA motion detection interval configuration entity."""
|
|
|
|
_attr_native_min_value: float = 2
|
|
_attr_native_max_value: float = 65535
|
|
_zcl_attribute: str = "detection_interval"
|
|
_attr_name = "Detection interval"
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(channel_names=CHANNEL_LEVEL)
|
|
class OnOffTransitionTimeConfigurationEntity(
|
|
ZHANumberConfigurationEntity, id_suffix="on_off_transition_time"
|
|
):
|
|
"""Representation of a ZHA on off transition time configuration entity."""
|
|
|
|
_attr_native_min_value: float = 0x0000
|
|
_attr_native_max_value: float = 0xFFFF
|
|
_zcl_attribute: str = "on_off_transition_time"
|
|
_attr_name = "On/Off transition time"
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(channel_names=CHANNEL_LEVEL)
|
|
class OnLevelConfigurationEntity(ZHANumberConfigurationEntity, id_suffix="on_level"):
|
|
"""Representation of a ZHA on level configuration entity."""
|
|
|
|
_attr_native_min_value: float = 0x00
|
|
_attr_native_max_value: float = 0xFF
|
|
_zcl_attribute: str = "on_level"
|
|
_attr_name = "On level"
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(channel_names=CHANNEL_LEVEL)
|
|
class OnTransitionTimeConfigurationEntity(
|
|
ZHANumberConfigurationEntity, id_suffix="on_transition_time"
|
|
):
|
|
"""Representation of a ZHA on transition time configuration entity."""
|
|
|
|
_attr_native_min_value: float = 0x0000
|
|
_attr_native_max_value: float = 0xFFFE
|
|
_zcl_attribute: str = "on_transition_time"
|
|
_attr_name = "On transition time"
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(channel_names=CHANNEL_LEVEL)
|
|
class OffTransitionTimeConfigurationEntity(
|
|
ZHANumberConfigurationEntity, id_suffix="off_transition_time"
|
|
):
|
|
"""Representation of a ZHA off transition time configuration entity."""
|
|
|
|
_attr_native_min_value: float = 0x0000
|
|
_attr_native_max_value: float = 0xFFFE
|
|
_zcl_attribute: str = "off_transition_time"
|
|
_attr_name = "Off transition time"
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(channel_names=CHANNEL_LEVEL)
|
|
class DefaultMoveRateConfigurationEntity(
|
|
ZHANumberConfigurationEntity, id_suffix="default_move_rate"
|
|
):
|
|
"""Representation of a ZHA default move rate configuration entity."""
|
|
|
|
_attr_native_min_value: float = 0x00
|
|
_attr_native_max_value: float = 0xFE
|
|
_zcl_attribute: str = "default_move_rate"
|
|
_attr_name = "Default move rate"
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(channel_names=CHANNEL_LEVEL)
|
|
class StartUpCurrentLevelConfigurationEntity(
|
|
ZHANumberConfigurationEntity, id_suffix="start_up_current_level"
|
|
):
|
|
"""Representation of a ZHA startup current level configuration entity."""
|
|
|
|
_attr_native_min_value: float = 0x00
|
|
_attr_native_max_value: float = 0xFF
|
|
_zcl_attribute: str = "start_up_current_level"
|
|
_attr_name = "Start-up current level"
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(channel_names=CHANNEL_COLOR)
|
|
class StartUpColorTemperatureConfigurationEntity(
|
|
ZHANumberConfigurationEntity, id_suffix="start_up_color_temperature"
|
|
):
|
|
"""Representation of a ZHA startup color temperature configuration entity."""
|
|
|
|
_attr_native_min_value: float = 153
|
|
_attr_native_max_value: float = 500
|
|
_zcl_attribute: str = "start_up_color_temperature"
|
|
_attr_name = "Start-up color temperature"
|
|
|
|
def __init__(
|
|
self,
|
|
unique_id: str,
|
|
zha_device: ZHADevice,
|
|
channels: list[ZigbeeChannel],
|
|
**kwargs: Any,
|
|
) -> None:
|
|
"""Init this ZHA startup color temperature entity."""
|
|
super().__init__(unique_id, zha_device, channels, **kwargs)
|
|
if self._channel:
|
|
self._attr_native_min_value: float = self._channel.min_mireds
|
|
self._attr_native_max_value: float = self._channel.max_mireds
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(
|
|
channel_names="tuya_manufacturer",
|
|
manufacturers={
|
|
"_TZE200_htnnfasr",
|
|
},
|
|
)
|
|
class TimerDurationMinutes(ZHANumberConfigurationEntity, id_suffix="timer_duration"):
|
|
"""Representation of a ZHA timer duration configuration entity."""
|
|
|
|
_attr_entity_category = EntityCategory.CONFIG
|
|
_attr_icon: str = ICONS[14]
|
|
_attr_native_min_value: float = 0x00
|
|
_attr_native_max_value: float = 0x257
|
|
_attr_native_unit_of_measurement: str | None = UNITS[72]
|
|
_zcl_attribute: str = "timer_duration"
|
|
_attr_name = "Timer duration"
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(channel_names="ikea_airpurifier")
|
|
class FilterLifeTime(ZHANumberConfigurationEntity, id_suffix="filter_life_time"):
|
|
"""Representation of a ZHA filter lifetime configuration entity."""
|
|
|
|
_attr_entity_category = EntityCategory.CONFIG
|
|
_attr_icon: str = ICONS[14]
|
|
_attr_native_min_value: float = 0x00
|
|
_attr_native_max_value: float = 0xFFFFFFFF
|
|
_attr_native_unit_of_measurement: str | None = UNITS[72]
|
|
_zcl_attribute: str = "filter_life_time"
|
|
_attr_name = "Filter life time"
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(
|
|
channel_names=CHANNEL_BASIC,
|
|
manufacturers={"TexasInstruments"},
|
|
models={"ti.router"},
|
|
)
|
|
class TiRouterTransmitPower(ZHANumberConfigurationEntity, id_suffix="transmit_power"):
|
|
"""Representation of a ZHA TI transmit power configuration entity."""
|
|
|
|
_attr_native_min_value: float = -20
|
|
_attr_native_max_value: float = 20
|
|
_zcl_attribute: str = "transmit_power"
|
|
_attr_name = "Transmit power"
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(channel_names=CHANNEL_INOVELLI)
|
|
class InovelliRemoteDimmingUpSpeed(
|
|
ZHANumberConfigurationEntity, id_suffix="dimming_speed_up_remote"
|
|
):
|
|
"""Inovelli remote dimming up speed configuration entity."""
|
|
|
|
_attr_entity_category = EntityCategory.CONFIG
|
|
_attr_icon: str = ICONS[3]
|
|
_attr_native_min_value: float = 0
|
|
_attr_native_max_value: float = 126
|
|
_zcl_attribute: str = "dimming_speed_up_remote"
|
|
_attr_name: str = "Remote dimming up speed"
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(channel_names=CHANNEL_INOVELLI)
|
|
class InovelliButtonDelay(ZHANumberConfigurationEntity, id_suffix="button_delay"):
|
|
"""Inovelli button delay configuration entity."""
|
|
|
|
_attr_entity_category = EntityCategory.CONFIG
|
|
_attr_icon: str = ICONS[3]
|
|
_attr_native_min_value: float = 0
|
|
_attr_native_max_value: float = 9
|
|
_zcl_attribute: str = "button_delay"
|
|
_attr_name: str = "Button delay"
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(channel_names=CHANNEL_INOVELLI)
|
|
class InovelliLocalDimmingUpSpeed(
|
|
ZHANumberConfigurationEntity, id_suffix="dimming_speed_up_local"
|
|
):
|
|
"""Inovelli local dimming up speed configuration entity."""
|
|
|
|
_attr_entity_category = EntityCategory.CONFIG
|
|
_attr_icon: str = ICONS[3]
|
|
_attr_native_min_value: float = 0
|
|
_attr_native_max_value: float = 127
|
|
_zcl_attribute: str = "dimming_speed_up_local"
|
|
_attr_name: str = "Local dimming up speed"
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(channel_names=CHANNEL_INOVELLI)
|
|
class InovelliLocalRampRateOffToOn(
|
|
ZHANumberConfigurationEntity, id_suffix="ramp_rate_off_to_on_local"
|
|
):
|
|
"""Inovelli off to on local ramp rate configuration entity."""
|
|
|
|
_attr_entity_category = EntityCategory.CONFIG
|
|
_attr_icon: str = ICONS[3]
|
|
_attr_native_min_value: float = 0
|
|
_attr_native_max_value: float = 127
|
|
_zcl_attribute: str = "ramp_rate_off_to_on_local"
|
|
_attr_name: str = "Local ramp rate off to on"
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(channel_names=CHANNEL_INOVELLI)
|
|
class InovelliRemoteDimmingSpeedOffToOn(
|
|
ZHANumberConfigurationEntity, id_suffix="ramp_rate_off_to_on_remote"
|
|
):
|
|
"""Inovelli off to on remote ramp rate configuration entity."""
|
|
|
|
_attr_entity_category = EntityCategory.CONFIG
|
|
_attr_icon: str = ICONS[3]
|
|
_attr_native_min_value: float = 0
|
|
_attr_native_max_value: float = 127
|
|
_zcl_attribute: str = "ramp_rate_off_to_on_remote"
|
|
_attr_name: str = "Remote ramp rate off to on"
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(channel_names=CHANNEL_INOVELLI)
|
|
class InovelliRemoteDimmingDownSpeed(
|
|
ZHANumberConfigurationEntity, id_suffix="dimming_speed_down_remote"
|
|
):
|
|
"""Inovelli remote dimming down speed configuration entity."""
|
|
|
|
_attr_entity_category = EntityCategory.CONFIG
|
|
_attr_icon: str = ICONS[3]
|
|
_attr_native_min_value: float = 0
|
|
_attr_native_max_value: float = 127
|
|
_zcl_attribute: str = "dimming_speed_down_remote"
|
|
_attr_name: str = "Remote dimming down speed"
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(channel_names=CHANNEL_INOVELLI)
|
|
class InovelliLocalDimmingDownSpeed(
|
|
ZHANumberConfigurationEntity, id_suffix="dimming_speed_down_local"
|
|
):
|
|
"""Inovelli local dimming down speed configuration entity."""
|
|
|
|
_attr_entity_category = EntityCategory.CONFIG
|
|
_attr_icon: str = ICONS[3]
|
|
_attr_native_min_value: float = 0
|
|
_attr_native_max_value: float = 127
|
|
_zcl_attribute: str = "dimming_speed_down_local"
|
|
_attr_name: str = "Local dimming down speed"
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(channel_names=CHANNEL_INOVELLI)
|
|
class InovelliLocalRampRateOnToOff(
|
|
ZHANumberConfigurationEntity, id_suffix="ramp_rate_on_to_off_local"
|
|
):
|
|
"""Inovelli local on to off ramp rate configuration entity."""
|
|
|
|
_attr_entity_category = EntityCategory.CONFIG
|
|
_attr_icon: str = ICONS[3]
|
|
_attr_native_min_value: float = 0
|
|
_attr_native_max_value: float = 127
|
|
_zcl_attribute: str = "ramp_rate_on_to_off_local"
|
|
_attr_name: str = "Local ramp rate on to off"
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(channel_names=CHANNEL_INOVELLI)
|
|
class InovelliRemoteDimmingSpeedOnToOff(
|
|
ZHANumberConfigurationEntity, id_suffix="ramp_rate_on_to_off_remote"
|
|
):
|
|
"""Inovelli remote on to off ramp rate configuration entity."""
|
|
|
|
_attr_entity_category = EntityCategory.CONFIG
|
|
_attr_icon: str = ICONS[3]
|
|
_attr_native_min_value: float = 0
|
|
_attr_native_max_value: float = 127
|
|
_zcl_attribute: str = "ramp_rate_on_to_off_remote"
|
|
_attr_name: str = "Remote ramp rate on to off"
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(channel_names=CHANNEL_INOVELLI)
|
|
class InovelliMinimumLoadDimmingLevel(
|
|
ZHANumberConfigurationEntity, id_suffix="minimum_level"
|
|
):
|
|
"""Inovelli minimum load dimming level configuration entity."""
|
|
|
|
_attr_entity_category = EntityCategory.CONFIG
|
|
_attr_icon: str = ICONS[16]
|
|
_attr_native_min_value: float = 1
|
|
_attr_native_max_value: float = 254
|
|
_zcl_attribute: str = "minimum_level"
|
|
_attr_name: str = "Minimum load dimming level"
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(channel_names=CHANNEL_INOVELLI)
|
|
class InovelliMaximumLoadDimmingLevel(
|
|
ZHANumberConfigurationEntity, id_suffix="maximum_level"
|
|
):
|
|
"""Inovelli maximum load dimming level configuration entity."""
|
|
|
|
_attr_entity_category = EntityCategory.CONFIG
|
|
_attr_icon: str = ICONS[16]
|
|
_attr_native_min_value: float = 2
|
|
_attr_native_max_value: float = 255
|
|
_zcl_attribute: str = "maximum_level"
|
|
_attr_name: str = "Maximum load dimming level"
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(channel_names=CHANNEL_INOVELLI)
|
|
class InovelliAutoShutoffTimer(
|
|
ZHANumberConfigurationEntity, id_suffix="auto_off_timer"
|
|
):
|
|
"""Inovelli automatic switch shutoff timer configuration entity."""
|
|
|
|
_attr_entity_category = EntityCategory.CONFIG
|
|
_attr_icon: str = ICONS[14]
|
|
_attr_native_min_value: float = 0
|
|
_attr_native_max_value: float = 32767
|
|
_zcl_attribute: str = "auto_off_timer"
|
|
_attr_name: str = "Automatic switch shutoff timer"
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(channel_names=CHANNEL_INOVELLI)
|
|
class InovelliLoadLevelIndicatorTimeout(
|
|
ZHANumberConfigurationEntity, id_suffix="load_level_indicator_timeout"
|
|
):
|
|
"""Inovelli load level indicator timeout configuration entity."""
|
|
|
|
_attr_entity_category = EntityCategory.CONFIG
|
|
_attr_icon: str = ICONS[14]
|
|
_attr_native_min_value: float = 0
|
|
_attr_native_max_value: float = 11
|
|
_zcl_attribute: str = "load_level_indicator_timeout"
|
|
_attr_name: str = "Load level indicator timeout"
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(channel_names=CHANNEL_INOVELLI)
|
|
class InovelliDefaultAllLEDOnColor(
|
|
ZHANumberConfigurationEntity, id_suffix="led_color_when_on"
|
|
):
|
|
"""Inovelli default all led color when on configuration entity."""
|
|
|
|
_attr_entity_category = EntityCategory.CONFIG
|
|
_attr_icon: str = ICONS[15]
|
|
_attr_native_min_value: float = 0
|
|
_attr_native_max_value: float = 255
|
|
_zcl_attribute: str = "led_color_when_on"
|
|
_attr_name: str = "Default all LED on color"
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(channel_names=CHANNEL_INOVELLI)
|
|
class InovelliDefaultAllLEDOffColor(
|
|
ZHANumberConfigurationEntity, id_suffix="led_color_when_off"
|
|
):
|
|
"""Inovelli default all led color when off configuration entity."""
|
|
|
|
_attr_entity_category = EntityCategory.CONFIG
|
|
_attr_icon: str = ICONS[15]
|
|
_attr_native_min_value: float = 0
|
|
_attr_native_max_value: float = 255
|
|
_zcl_attribute: str = "led_color_when_off"
|
|
_attr_name: str = "Default all LED off color"
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(channel_names=CHANNEL_INOVELLI)
|
|
class InovelliDefaultAllLEDOnIntensity(
|
|
ZHANumberConfigurationEntity, id_suffix="led_intensity_when_on"
|
|
):
|
|
"""Inovelli default all led intensity when on configuration entity."""
|
|
|
|
_attr_entity_category = EntityCategory.CONFIG
|
|
_attr_icon: str = ICONS[16]
|
|
_attr_native_min_value: float = 0
|
|
_attr_native_max_value: float = 100
|
|
_zcl_attribute: str = "led_intensity_when_on"
|
|
_attr_name: str = "Default all LED on intensity"
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(channel_names=CHANNEL_INOVELLI)
|
|
class InovelliDefaultAllLEDOffIntensity(
|
|
ZHANumberConfigurationEntity, id_suffix="led_intensity_when_off"
|
|
):
|
|
"""Inovelli default all led intensity when off configuration entity."""
|
|
|
|
_attr_entity_category = EntityCategory.CONFIG
|
|
_attr_icon: str = ICONS[16]
|
|
_attr_native_min_value: float = 0
|
|
_attr_native_max_value: float = 100
|
|
_zcl_attribute: str = "led_intensity_when_off"
|
|
_attr_name: str = "Default all LED off intensity"
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(channel_names="opple_cluster", models={"aqara.feeder.acn001"})
|
|
class AqaraPetFeederServingSize(ZHANumberConfigurationEntity, id_suffix="serving_size"):
|
|
"""Aqara pet feeder serving size configuration entity."""
|
|
|
|
_attr_entity_category = EntityCategory.CONFIG
|
|
_attr_native_min_value: float = 1
|
|
_attr_native_max_value: float = 10
|
|
_zcl_attribute: str = "serving_size"
|
|
_attr_name: str = "Serving to dispense"
|
|
_attr_mode: NumberMode = NumberMode.BOX
|
|
_attr_icon: str = "mdi:counter"
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(channel_names="opple_cluster", models={"aqara.feeder.acn001"})
|
|
class AqaraPetFeederPortionWeight(
|
|
ZHANumberConfigurationEntity, id_suffix="portion_weight"
|
|
):
|
|
"""Aqara pet feeder portion weight configuration entity."""
|
|
|
|
_attr_entity_category = EntityCategory.CONFIG
|
|
_attr_native_min_value: float = 1
|
|
_attr_native_max_value: float = 100
|
|
_zcl_attribute: str = "portion_weight"
|
|
_attr_name: str = "Portion weight"
|
|
_attr_mode: NumberMode = NumberMode.BOX
|
|
_attr_native_unit_of_measurement: str = UnitOfMass.GRAMS
|
|
_attr_icon: str = "mdi:weight-gram"
|