aiohomematic 2025.11.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of aiohomematic might be problematic. Click here for more details.
- aiohomematic/__init__.py +61 -0
- aiohomematic/async_support.py +212 -0
- aiohomematic/central/__init__.py +2309 -0
- aiohomematic/central/decorators.py +155 -0
- aiohomematic/central/rpc_server.py +295 -0
- aiohomematic/client/__init__.py +1848 -0
- aiohomematic/client/_rpc_errors.py +81 -0
- aiohomematic/client/json_rpc.py +1326 -0
- aiohomematic/client/rpc_proxy.py +311 -0
- aiohomematic/const.py +1127 -0
- aiohomematic/context.py +18 -0
- aiohomematic/converter.py +108 -0
- aiohomematic/decorators.py +302 -0
- aiohomematic/exceptions.py +164 -0
- aiohomematic/hmcli.py +186 -0
- aiohomematic/model/__init__.py +140 -0
- aiohomematic/model/calculated/__init__.py +84 -0
- aiohomematic/model/calculated/climate.py +290 -0
- aiohomematic/model/calculated/data_point.py +327 -0
- aiohomematic/model/calculated/operating_voltage_level.py +299 -0
- aiohomematic/model/calculated/support.py +234 -0
- aiohomematic/model/custom/__init__.py +177 -0
- aiohomematic/model/custom/climate.py +1532 -0
- aiohomematic/model/custom/cover.py +792 -0
- aiohomematic/model/custom/data_point.py +334 -0
- aiohomematic/model/custom/definition.py +871 -0
- aiohomematic/model/custom/light.py +1128 -0
- aiohomematic/model/custom/lock.py +394 -0
- aiohomematic/model/custom/siren.py +275 -0
- aiohomematic/model/custom/support.py +41 -0
- aiohomematic/model/custom/switch.py +175 -0
- aiohomematic/model/custom/valve.py +114 -0
- aiohomematic/model/data_point.py +1123 -0
- aiohomematic/model/device.py +1445 -0
- aiohomematic/model/event.py +208 -0
- aiohomematic/model/generic/__init__.py +217 -0
- aiohomematic/model/generic/action.py +34 -0
- aiohomematic/model/generic/binary_sensor.py +30 -0
- aiohomematic/model/generic/button.py +27 -0
- aiohomematic/model/generic/data_point.py +171 -0
- aiohomematic/model/generic/dummy.py +147 -0
- aiohomematic/model/generic/number.py +76 -0
- aiohomematic/model/generic/select.py +39 -0
- aiohomematic/model/generic/sensor.py +74 -0
- aiohomematic/model/generic/switch.py +54 -0
- aiohomematic/model/generic/text.py +29 -0
- aiohomematic/model/hub/__init__.py +333 -0
- aiohomematic/model/hub/binary_sensor.py +24 -0
- aiohomematic/model/hub/button.py +28 -0
- aiohomematic/model/hub/data_point.py +340 -0
- aiohomematic/model/hub/number.py +39 -0
- aiohomematic/model/hub/select.py +49 -0
- aiohomematic/model/hub/sensor.py +37 -0
- aiohomematic/model/hub/switch.py +44 -0
- aiohomematic/model/hub/text.py +30 -0
- aiohomematic/model/support.py +586 -0
- aiohomematic/model/update.py +143 -0
- aiohomematic/property_decorators.py +496 -0
- aiohomematic/py.typed +0 -0
- aiohomematic/rega_scripts/fetch_all_device_data.fn +92 -0
- aiohomematic/rega_scripts/get_program_descriptions.fn +30 -0
- aiohomematic/rega_scripts/get_serial.fn +44 -0
- aiohomematic/rega_scripts/get_system_variable_descriptions.fn +30 -0
- aiohomematic/rega_scripts/set_program_state.fn +12 -0
- aiohomematic/rega_scripts/set_system_variable.fn +15 -0
- aiohomematic/store/__init__.py +34 -0
- aiohomematic/store/dynamic.py +551 -0
- aiohomematic/store/persistent.py +988 -0
- aiohomematic/store/visibility.py +812 -0
- aiohomematic/support.py +664 -0
- aiohomematic/validator.py +112 -0
- aiohomematic-2025.11.3.dist-info/METADATA +144 -0
- aiohomematic-2025.11.3.dist-info/RECORD +77 -0
- aiohomematic-2025.11.3.dist-info/WHEEL +5 -0
- aiohomematic-2025.11.3.dist-info/entry_points.txt +2 -0
- aiohomematic-2025.11.3.dist-info/licenses/LICENSE +21 -0
- aiohomematic-2025.11.3.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2021-2025
|
|
3
|
+
"""
|
|
4
|
+
A number of functions used to calculate values based on existing data.
|
|
5
|
+
|
|
6
|
+
Climate related formula are based on:
|
|
7
|
+
- thermal comfort (https://github.com/dolezsa/thermal_comfort) ground works.
|
|
8
|
+
- https://gist.github.com/E3V3A/8f9f0aa18380d4ab2546cd50b725a219
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import logging
|
|
14
|
+
import math
|
|
15
|
+
from typing import Final
|
|
16
|
+
|
|
17
|
+
from aiohomematic.support import extract_exc_args
|
|
18
|
+
|
|
19
|
+
_DEFAULT_PRESSURE_HPA: Final = 1013.25
|
|
20
|
+
_LOGGER: Final = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def calculate_dew_point_spread(*, temperature: float, humidity: int) -> float | None:
|
|
24
|
+
"""
|
|
25
|
+
Calculate the dew point spread.
|
|
26
|
+
|
|
27
|
+
Dew point spread = Difference between current air temperature and dew point.
|
|
28
|
+
Specifies the safety margin against condensation(K).
|
|
29
|
+
"""
|
|
30
|
+
if dew_point := calculate_dew_point(temperature=temperature, humidity=humidity):
|
|
31
|
+
return round(temperature - dew_point, 2)
|
|
32
|
+
return None
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def calculate_enthalpy(
|
|
36
|
+
*, temperature: float, humidity: int, pressure_hPa: float = _DEFAULT_PRESSURE_HPA
|
|
37
|
+
) -> float | None:
|
|
38
|
+
"""
|
|
39
|
+
Calculate the enthalpy based on temperature and humidity.
|
|
40
|
+
|
|
41
|
+
Calculates the specific enthalpy of humid air in kJ/kg (relative to dry air).
|
|
42
|
+
temperature: Air temperature in °C
|
|
43
|
+
humidity: Relative humidity in %
|
|
44
|
+
pressure_hPa: Air pressure (default: 1013.25 hPa)
|
|
45
|
+
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
# Saturation vapor pressure according to Magnus in hPa
|
|
49
|
+
e_s = 6.112 * math.exp((17.62 * temperature) / (243.12 + temperature))
|
|
50
|
+
e = humidity / 100.0 * e_s # aktueller Dampfdruck in hPa
|
|
51
|
+
|
|
52
|
+
# Mixing ratio (g water / kg dry air)
|
|
53
|
+
r = 622 * e / (pressure_hPa - e)
|
|
54
|
+
|
|
55
|
+
# Specific enthalpy (kJ/kg dry air)
|
|
56
|
+
h = 1.006 * temperature + r * (2501 + 1.86 * temperature) / 1000 # in kJ/kg
|
|
57
|
+
return round(h, 2)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _calculate_heat_index(*, temperature: float, humidity: int) -> float:
|
|
61
|
+
"""
|
|
62
|
+
Calculate the Heat Index (feels like temperature) based on the NOAA equation.
|
|
63
|
+
|
|
64
|
+
References:
|
|
65
|
+
[1] https://en.wikipedia.org/wiki/Heat_index
|
|
66
|
+
[2] http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml
|
|
67
|
+
[3] https://github.com/geanders/weathermetrics/blob/master/R/heat_index.R
|
|
68
|
+
[4] https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3801457/
|
|
69
|
+
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
# SI units (Celsius)
|
|
73
|
+
c1 = -8.78469475556
|
|
74
|
+
c2 = 1.61139411
|
|
75
|
+
c3 = 2.33854883889
|
|
76
|
+
c4 = -0.14611605
|
|
77
|
+
c5 = -0.012308094
|
|
78
|
+
c6 = -0.0164248277778
|
|
79
|
+
c7 = 0.002211732
|
|
80
|
+
c8 = 0.00072546
|
|
81
|
+
c9 = -0.000003582
|
|
82
|
+
|
|
83
|
+
temperature_fahrenheit = (temperature * 9 / 5) + 32
|
|
84
|
+
heat_index_fahrenheit = 0.5 * (
|
|
85
|
+
temperature_fahrenheit + 61.0 + (temperature_fahrenheit - 68.0) * 1.2 + humidity * 0.094
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
if ((heat_index_fahrenheit + temperature_fahrenheit) / 2) >= 80: # [°F]
|
|
89
|
+
# temperature > 27C and humidity > 40 %
|
|
90
|
+
heat_index_celsius = math.fsum(
|
|
91
|
+
[
|
|
92
|
+
c1,
|
|
93
|
+
c2 * temperature,
|
|
94
|
+
c3 * humidity,
|
|
95
|
+
c4 * temperature * humidity,
|
|
96
|
+
c5 * temperature**2,
|
|
97
|
+
c6 * humidity**2,
|
|
98
|
+
c7 * temperature**2 * humidity,
|
|
99
|
+
c8 * temperature * humidity**2,
|
|
100
|
+
c9 * temperature**2 * humidity**2,
|
|
101
|
+
]
|
|
102
|
+
)
|
|
103
|
+
else:
|
|
104
|
+
heat_index_celsius = (heat_index_fahrenheit - 32) * 5 / 9
|
|
105
|
+
|
|
106
|
+
return heat_index_celsius
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def _calculate_wind_chill(*, temperature: float, wind_speed: float) -> float | None:
|
|
110
|
+
"""
|
|
111
|
+
Calculate the Wind Chill (feels like temperature) based on NOAA.
|
|
112
|
+
|
|
113
|
+
References:
|
|
114
|
+
[1] https://en.wikipedia.org/wiki/Wind_chill
|
|
115
|
+
[2] https://www.wpc.ncep.noaa.gov/html/windchill.shtml
|
|
116
|
+
|
|
117
|
+
"""
|
|
118
|
+
# Wind Chill Temperature is only defined for temperatures at or below 10°C and wind speeds above 4.8 Km/h.
|
|
119
|
+
if temperature > 10 or wind_speed <= 4.8: # if temperature > 50 or wind_speed <= 3: # (°F, Mph)
|
|
120
|
+
return None
|
|
121
|
+
|
|
122
|
+
return float(13.12 + (0.6215 * temperature) - 11.37 * wind_speed**0.16 + 0.3965 * temperature * wind_speed**0.16)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def calculate_vapor_concentration(*, temperature: float, humidity: int) -> float | None:
|
|
126
|
+
"""Calculate the vapor concentration."""
|
|
127
|
+
try:
|
|
128
|
+
abs_temperature = temperature + 273.15
|
|
129
|
+
vapor_concentration = 6.112
|
|
130
|
+
vapor_concentration *= math.exp((17.67 * temperature) / (243.5 + temperature))
|
|
131
|
+
vapor_concentration *= humidity
|
|
132
|
+
vapor_concentration *= 2.1674
|
|
133
|
+
vapor_concentration /= abs_temperature
|
|
134
|
+
|
|
135
|
+
return round(vapor_concentration, 2)
|
|
136
|
+
except ValueError as verr:
|
|
137
|
+
_LOGGER.debug(
|
|
138
|
+
"Unable to calculate 'vapor concentration' with temperature: %s, humidity: %s (%s)",
|
|
139
|
+
temperature,
|
|
140
|
+
humidity,
|
|
141
|
+
extract_exc_args(exc=verr),
|
|
142
|
+
)
|
|
143
|
+
return None
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def calculate_apparent_temperature(*, temperature: float, humidity: int, wind_speed: float) -> float | None:
|
|
147
|
+
"""Calculate the apparent temperature based on NOAA."""
|
|
148
|
+
try:
|
|
149
|
+
if temperature <= 10 and wind_speed > 4.8:
|
|
150
|
+
# Wind Chill for low temp cases (and wind)
|
|
151
|
+
apparent_temperature = _calculate_wind_chill(temperature=temperature, wind_speed=wind_speed)
|
|
152
|
+
elif temperature >= 26.7:
|
|
153
|
+
# Heat Index for High temp cases
|
|
154
|
+
apparent_temperature = _calculate_heat_index(temperature=temperature, humidity=humidity)
|
|
155
|
+
else:
|
|
156
|
+
apparent_temperature = temperature
|
|
157
|
+
|
|
158
|
+
return round(apparent_temperature, 1) # type: ignore[arg-type]
|
|
159
|
+
except ValueError as verr:
|
|
160
|
+
if temperature == 0.0 and humidity == 0:
|
|
161
|
+
return 0.0
|
|
162
|
+
_LOGGER.debug(
|
|
163
|
+
"Unable to calculate 'apparent temperature' with temperature: %s, humidity: %s (%s)",
|
|
164
|
+
temperature,
|
|
165
|
+
humidity,
|
|
166
|
+
extract_exc_args(exc=verr),
|
|
167
|
+
)
|
|
168
|
+
return None
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def calculate_dew_point(*, temperature: float, humidity: int) -> float | None:
|
|
172
|
+
"""Calculate the dew point."""
|
|
173
|
+
try:
|
|
174
|
+
a0 = 373.15 / (273.15 + temperature)
|
|
175
|
+
s = -7.90298 * (a0 - 1)
|
|
176
|
+
s += 5.02808 * math.log(a0, 10)
|
|
177
|
+
s += -1.3816e-7 * (pow(10, (11.344 * (1 - 1 / a0))) - 1)
|
|
178
|
+
s += 8.1328e-3 * (pow(10, (-3.49149 * (a0 - 1))) - 1)
|
|
179
|
+
s += math.log(1013.246, 10)
|
|
180
|
+
vp = pow(10, s - 3) * humidity
|
|
181
|
+
td = math.log(vp / 0.61078)
|
|
182
|
+
|
|
183
|
+
return round((241.88 * td) / (17.558 - td), 1)
|
|
184
|
+
except ValueError as verr:
|
|
185
|
+
if temperature == 0.0 and humidity == 0:
|
|
186
|
+
return 0.0
|
|
187
|
+
_LOGGER.debug(
|
|
188
|
+
"Unable to calculate 'dew point' with temperature: %s, humidity: %s (%s)",
|
|
189
|
+
temperature,
|
|
190
|
+
humidity,
|
|
191
|
+
extract_exc_args(exc=verr),
|
|
192
|
+
)
|
|
193
|
+
return None
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def calculate_frost_point(*, temperature: float, humidity: int) -> float | None:
|
|
197
|
+
"""Calculate the frost point."""
|
|
198
|
+
try:
|
|
199
|
+
if (dew_point := calculate_dew_point(temperature=temperature, humidity=humidity)) is None:
|
|
200
|
+
return None
|
|
201
|
+
t = temperature + 273.15
|
|
202
|
+
td = dew_point + 273.15
|
|
203
|
+
|
|
204
|
+
return round((td + (2671.02 / ((2954.61 / t) + 2.193665 * math.log(t) - 13.3448)) - t) - 273.15, 1)
|
|
205
|
+
except ValueError as verr:
|
|
206
|
+
if temperature == 0.0 and humidity == 0:
|
|
207
|
+
return 0.0
|
|
208
|
+
_LOGGER.debug(
|
|
209
|
+
"Unable to calculate 'frost point' with temperature: %s, humidity: %s (%s)",
|
|
210
|
+
temperature,
|
|
211
|
+
humidity,
|
|
212
|
+
extract_exc_args(exc=verr),
|
|
213
|
+
)
|
|
214
|
+
return None
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def calculate_operating_voltage_level(
|
|
218
|
+
*, operating_voltage: float | None, low_bat_limit: float | None, voltage_max: float | None
|
|
219
|
+
) -> float | None:
|
|
220
|
+
"""Return the operating voltage level."""
|
|
221
|
+
if operating_voltage is None or low_bat_limit is None or voltage_max is None:
|
|
222
|
+
return None
|
|
223
|
+
return max(
|
|
224
|
+
0,
|
|
225
|
+
min(
|
|
226
|
+
100,
|
|
227
|
+
float(
|
|
228
|
+
round(
|
|
229
|
+
((float(operating_voltage) - low_bat_limit) / (voltage_max - low_bat_limit) * 100),
|
|
230
|
+
1,
|
|
231
|
+
)
|
|
232
|
+
),
|
|
233
|
+
),
|
|
234
|
+
)
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2021-2025
|
|
3
|
+
"""
|
|
4
|
+
Custom data points for AioHomematic.
|
|
5
|
+
|
|
6
|
+
This subpackage provides higher-level, device-specific data points that combine
|
|
7
|
+
multiple backend parameters into single, meaningful entities (for example: a
|
|
8
|
+
thermostat, a blind with tilt, a fixed-color light, a lock, a siren, a switch,
|
|
9
|
+
or an irrigation valve). It also contains discovery helpers and a schema-based
|
|
10
|
+
validation for model-specific configurations.
|
|
11
|
+
|
|
12
|
+
What this package does
|
|
13
|
+
- Discovery: create_custom_data_points() inspects a device model and, if a
|
|
14
|
+
matching custom definition exists and the device is not ignored for customs,
|
|
15
|
+
creates the appropriate custom data point(s) and attaches them to the device.
|
|
16
|
+
- Definitions: The definition module holds the catalog of supported models and
|
|
17
|
+
the rules that describe which parameters form each custom entity. It exposes
|
|
18
|
+
helpers to query availability, enumerate required parameters, and validate the
|
|
19
|
+
definition schema.
|
|
20
|
+
- Specializations: Rich custom data point classes for climate, light, cover,
|
|
21
|
+
lock, siren, switch, and irrigation valve provide tailored behavior and an API
|
|
22
|
+
focused on user intent (e.g., set_temperature, open_tilt, set_profile,
|
|
23
|
+
turn_on with effect, lock/open, vent, etc.).
|
|
24
|
+
|
|
25
|
+
How it relates to the generic layer
|
|
26
|
+
Custom data points build on top of generic data points. While the generic layer
|
|
27
|
+
maps one backend parameter to one data point, this package groups multiple
|
|
28
|
+
parameters across channels (where needed) into a single higher-level entity. The
|
|
29
|
+
result is a simpler interface for automations and UIs, while still allowing the
|
|
30
|
+
underlying generic data points to be created when desired.
|
|
31
|
+
|
|
32
|
+
Public API entry points commonly used by integrators
|
|
33
|
+
- create_custom_data_points(device): Run discovery and attach custom data points.
|
|
34
|
+
- data_point_definition_exists(model): Check if a custom definition is available.
|
|
35
|
+
- get_custom_configs(model, category=None): Retrieve the CustomConfig entries
|
|
36
|
+
used to create custom data points for a model (optionally filtered by
|
|
37
|
+
category).
|
|
38
|
+
- get_required_parameters(): Return all parameters that must be fetched to allow
|
|
39
|
+
custom data points to function properly.
|
|
40
|
+
- validate_custom_data_point_definition(): Validate the internal definition
|
|
41
|
+
schema; useful in tests and development.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
from __future__ import annotations
|
|
45
|
+
|
|
46
|
+
import logging
|
|
47
|
+
from typing import Final
|
|
48
|
+
|
|
49
|
+
from aiohomematic.decorators import inspector
|
|
50
|
+
from aiohomematic.model import device as hmd
|
|
51
|
+
from aiohomematic.model.custom.climate import (
|
|
52
|
+
PROFILE_DICT,
|
|
53
|
+
PROFILE_PREFIX,
|
|
54
|
+
SIMPLE_PROFILE_DICT,
|
|
55
|
+
SIMPLE_WEEKDAY_LIST,
|
|
56
|
+
WEEKDAY_DICT,
|
|
57
|
+
BaseCustomDpClimate,
|
|
58
|
+
ClimateActivity,
|
|
59
|
+
ClimateMode,
|
|
60
|
+
ClimateProfile,
|
|
61
|
+
CustomDpIpThermostat,
|
|
62
|
+
CustomDpRfThermostat,
|
|
63
|
+
CustomDpSimpleRfThermostat,
|
|
64
|
+
ScheduleProfile,
|
|
65
|
+
ScheduleWeekday,
|
|
66
|
+
)
|
|
67
|
+
from aiohomematic.model.custom.cover import (
|
|
68
|
+
CustomDpBlind,
|
|
69
|
+
CustomDpCover,
|
|
70
|
+
CustomDpGarage,
|
|
71
|
+
CustomDpIpBlind,
|
|
72
|
+
CustomDpWindowDrive,
|
|
73
|
+
)
|
|
74
|
+
from aiohomematic.model.custom.data_point import CustomDataPoint
|
|
75
|
+
from aiohomematic.model.custom.definition import (
|
|
76
|
+
data_point_definition_exists,
|
|
77
|
+
get_custom_configs,
|
|
78
|
+
get_required_parameters,
|
|
79
|
+
validate_custom_data_point_definition,
|
|
80
|
+
)
|
|
81
|
+
from aiohomematic.model.custom.light import (
|
|
82
|
+
CustomDpColorDimmer,
|
|
83
|
+
CustomDpColorDimmerEffect,
|
|
84
|
+
CustomDpColorTempDimmer,
|
|
85
|
+
CustomDpDimmer,
|
|
86
|
+
CustomDpIpDrgDaliLight,
|
|
87
|
+
CustomDpIpFixedColorLight,
|
|
88
|
+
CustomDpIpRGBWLight,
|
|
89
|
+
LightOffArgs,
|
|
90
|
+
LightOnArgs,
|
|
91
|
+
)
|
|
92
|
+
from aiohomematic.model.custom.lock import (
|
|
93
|
+
BaseCustomDpLock,
|
|
94
|
+
CustomDpButtonLock,
|
|
95
|
+
CustomDpIpLock,
|
|
96
|
+
CustomDpRfLock,
|
|
97
|
+
LockState,
|
|
98
|
+
)
|
|
99
|
+
from aiohomematic.model.custom.siren import BaseCustomDpSiren, CustomDpIpSiren, CustomDpIpSirenSmoke, SirenOnArgs
|
|
100
|
+
from aiohomematic.model.custom.switch import CustomDpSwitch
|
|
101
|
+
from aiohomematic.model.custom.valve import CustomDpIpIrrigationValve
|
|
102
|
+
|
|
103
|
+
__all__ = [
|
|
104
|
+
"BaseCustomDpClimate",
|
|
105
|
+
"BaseCustomDpLock",
|
|
106
|
+
"BaseCustomDpSiren",
|
|
107
|
+
"ClimateActivity",
|
|
108
|
+
"ClimateMode",
|
|
109
|
+
"ClimateProfile",
|
|
110
|
+
"CustomDataPoint",
|
|
111
|
+
"CustomDpBlind",
|
|
112
|
+
"CustomDpButtonLock",
|
|
113
|
+
"CustomDpColorDimmer",
|
|
114
|
+
"CustomDpColorDimmerEffect",
|
|
115
|
+
"CustomDpColorTempDimmer",
|
|
116
|
+
"CustomDpCover",
|
|
117
|
+
"CustomDpDimmer",
|
|
118
|
+
"CustomDpGarage",
|
|
119
|
+
"CustomDpIpBlind",
|
|
120
|
+
"CustomDpIpDrgDaliLight",
|
|
121
|
+
"CustomDpIpFixedColorLight",
|
|
122
|
+
"CustomDpIpIrrigationValve",
|
|
123
|
+
"CustomDpIpLock",
|
|
124
|
+
"CustomDpIpRGBWLight",
|
|
125
|
+
"CustomDpIpSiren",
|
|
126
|
+
"CustomDpIpSirenSmoke",
|
|
127
|
+
"CustomDpIpThermostat",
|
|
128
|
+
"CustomDpRfLock",
|
|
129
|
+
"CustomDpRfThermostat",
|
|
130
|
+
"CustomDpSimpleRfThermostat",
|
|
131
|
+
"CustomDpSwitch",
|
|
132
|
+
"CustomDpWindowDrive",
|
|
133
|
+
"LightOffArgs",
|
|
134
|
+
"LightOnArgs",
|
|
135
|
+
"LockState",
|
|
136
|
+
"PROFILE_DICT",
|
|
137
|
+
"PROFILE_PREFIX",
|
|
138
|
+
"SIMPLE_PROFILE_DICT",
|
|
139
|
+
"SIMPLE_WEEKDAY_LIST",
|
|
140
|
+
"ScheduleProfile",
|
|
141
|
+
"ScheduleWeekday",
|
|
142
|
+
"SirenOnArgs",
|
|
143
|
+
"WEEKDAY_DICT",
|
|
144
|
+
"create_custom_data_points",
|
|
145
|
+
"data_point_definition_exists",
|
|
146
|
+
"get_custom_configs",
|
|
147
|
+
"get_required_parameters",
|
|
148
|
+
"validate_custom_data_point_definition",
|
|
149
|
+
]
|
|
150
|
+
|
|
151
|
+
_LOGGER: Final = logging.getLogger(__name__)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
@inspector
|
|
155
|
+
def create_custom_data_points(*, device: hmd.Device) -> None:
|
|
156
|
+
"""Decides which data point category should be used, and creates the required data points."""
|
|
157
|
+
|
|
158
|
+
if device.ignore_for_custom_data_point:
|
|
159
|
+
_LOGGER.debug(
|
|
160
|
+
"CREATE_CUSTOM_DATA_POINTS: Ignoring for custom data point: %s, %s, %s due to ignored",
|
|
161
|
+
device.interface_id,
|
|
162
|
+
device,
|
|
163
|
+
device.model,
|
|
164
|
+
)
|
|
165
|
+
return
|
|
166
|
+
if data_point_definition_exists(model=device.model):
|
|
167
|
+
_LOGGER.debug(
|
|
168
|
+
"CREATE_CUSTOM_DATA_POINTS: Handling custom data point integration: %s, %s, %s",
|
|
169
|
+
device.interface_id,
|
|
170
|
+
device,
|
|
171
|
+
device.model,
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
# Call the custom creation function.
|
|
175
|
+
for custom_config in get_custom_configs(model=device.model):
|
|
176
|
+
for channel in device.channels.values():
|
|
177
|
+
custom_config.make_ce_func(channel=channel, custom_config=custom_config)
|