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,175 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2021-2025
|
|
3
|
+
"""Module for data points implemented using the switch category."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from collections.abc import Mapping
|
|
8
|
+
from enum import StrEnum
|
|
9
|
+
import logging
|
|
10
|
+
from typing import Any, Final
|
|
11
|
+
|
|
12
|
+
from aiohomematic.const import DataPointCategory, DeviceProfile, Field, Parameter
|
|
13
|
+
from aiohomematic.model import device as hmd
|
|
14
|
+
from aiohomematic.model.custom import definition as hmed
|
|
15
|
+
from aiohomematic.model.custom.data_point import CustomDataPoint
|
|
16
|
+
from aiohomematic.model.custom.support import CustomConfig, ExtendedConfig
|
|
17
|
+
from aiohomematic.model.data_point import CallParameterCollector, bind_collector
|
|
18
|
+
from aiohomematic.model.generic import DpAction, DpBinarySensor, DpSwitch
|
|
19
|
+
from aiohomematic.property_decorators import state_property
|
|
20
|
+
|
|
21
|
+
_LOGGER: Final = logging.getLogger(__name__)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class _StateChangeArg(StrEnum):
|
|
25
|
+
"""Enum with switch state change arguments."""
|
|
26
|
+
|
|
27
|
+
OFF = "off"
|
|
28
|
+
ON = "on"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class CustomDpSwitch(CustomDataPoint):
|
|
32
|
+
"""Class for Homematic switch data point."""
|
|
33
|
+
|
|
34
|
+
__slots__ = (
|
|
35
|
+
"_dp_group_state",
|
|
36
|
+
"_dp_on_time_value",
|
|
37
|
+
"_dp_state",
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
_category = DataPointCategory.SWITCH
|
|
41
|
+
|
|
42
|
+
def _init_data_point_fields(self) -> None:
|
|
43
|
+
"""Init the data_point fields."""
|
|
44
|
+
super()._init_data_point_fields()
|
|
45
|
+
self._dp_state: DpSwitch = self._get_data_point(field=Field.STATE, data_point_type=DpSwitch)
|
|
46
|
+
self._dp_on_time_value: DpAction = self._get_data_point(field=Field.ON_TIME_VALUE, data_point_type=DpAction)
|
|
47
|
+
self._dp_group_state: DpBinarySensor = self._get_data_point(
|
|
48
|
+
field=Field.GROUP_STATE, data_point_type=DpBinarySensor
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
@property
|
|
52
|
+
def group_value(self) -> bool | None:
|
|
53
|
+
"""Return the current group value of the switch."""
|
|
54
|
+
return self._dp_group_state.value
|
|
55
|
+
|
|
56
|
+
@state_property
|
|
57
|
+
def value(self) -> bool | None:
|
|
58
|
+
"""Return the current channel value of the switch."""
|
|
59
|
+
return self._dp_state.value
|
|
60
|
+
|
|
61
|
+
@bind_collector()
|
|
62
|
+
async def turn_on(self, *, on_time: float | None = None, collector: CallParameterCollector | None = None) -> None:
|
|
63
|
+
"""Turn the switch on."""
|
|
64
|
+
if on_time is not None:
|
|
65
|
+
self.set_timer_on_time(on_time=on_time)
|
|
66
|
+
if not self.is_state_change(on=True):
|
|
67
|
+
return
|
|
68
|
+
|
|
69
|
+
if (timer := self.get_and_start_timer()) is not None:
|
|
70
|
+
await self._dp_on_time_value.send_value(value=timer, collector=collector, do_validate=False)
|
|
71
|
+
await self._dp_state.turn_on(collector=collector)
|
|
72
|
+
|
|
73
|
+
@bind_collector()
|
|
74
|
+
async def turn_off(self, *, collector: CallParameterCollector | None = None) -> None:
|
|
75
|
+
"""Turn the switch off."""
|
|
76
|
+
self.reset_timer_on_time()
|
|
77
|
+
if not self.is_state_change(off=True):
|
|
78
|
+
return
|
|
79
|
+
await self._dp_state.turn_off(collector=collector)
|
|
80
|
+
|
|
81
|
+
def is_state_change(self, **kwargs: Any) -> bool:
|
|
82
|
+
"""Check if the state changes due to kwargs."""
|
|
83
|
+
if (on_time_running := self.timer_on_time_running) is not None and on_time_running is True:
|
|
84
|
+
return True
|
|
85
|
+
if self.timer_on_time is not None:
|
|
86
|
+
return True
|
|
87
|
+
if kwargs.get(_StateChangeArg.ON) is not None and self.value is not True:
|
|
88
|
+
return True
|
|
89
|
+
if kwargs.get(_StateChangeArg.OFF) is not None and self.value is not False:
|
|
90
|
+
return True
|
|
91
|
+
return super().is_state_change(**kwargs)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def make_ip_switch(
|
|
95
|
+
*,
|
|
96
|
+
channel: hmd.Channel,
|
|
97
|
+
custom_config: CustomConfig,
|
|
98
|
+
) -> None:
|
|
99
|
+
"""Create HomematicIP switch data point."""
|
|
100
|
+
hmed.make_custom_data_point(
|
|
101
|
+
channel=channel,
|
|
102
|
+
data_point_class=CustomDpSwitch,
|
|
103
|
+
device_profile=DeviceProfile.IP_SWITCH,
|
|
104
|
+
custom_config=custom_config,
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
# Case for device model is not relevant.
|
|
109
|
+
# HomeBrew (HB-) devices are always listed as HM-.
|
|
110
|
+
DEVICES: Mapping[str, CustomConfig | tuple[CustomConfig, ...]] = {
|
|
111
|
+
"ELV-SH-BS2": CustomConfig(make_ce_func=make_ip_switch, channels=(4, 8)),
|
|
112
|
+
"ELV-SH-PSMCI": CustomConfig(make_ce_func=make_ip_switch, channels=(3,)),
|
|
113
|
+
"ELV-SH-SW1-BAT": CustomConfig(make_ce_func=make_ip_switch, channels=(3,)),
|
|
114
|
+
"HmIP-BS2": CustomConfig(make_ce_func=make_ip_switch, channels=(4, 8)),
|
|
115
|
+
"HmIP-BSL": CustomConfig(make_ce_func=make_ip_switch, channels=(4,)),
|
|
116
|
+
"HmIP-BSM": CustomConfig(make_ce_func=make_ip_switch, channels=(4,)),
|
|
117
|
+
"HmIP-DRSI1": CustomConfig(
|
|
118
|
+
make_ce_func=make_ip_switch,
|
|
119
|
+
channels=(3,),
|
|
120
|
+
),
|
|
121
|
+
"HmIP-DRSI4": CustomConfig(
|
|
122
|
+
make_ce_func=make_ip_switch,
|
|
123
|
+
channels=(6, 10, 14, 18),
|
|
124
|
+
),
|
|
125
|
+
"HmIP-FSI": CustomConfig(make_ce_func=make_ip_switch, channels=(3,)),
|
|
126
|
+
"HmIP-FSM": CustomConfig(make_ce_func=make_ip_switch, channels=(2,)),
|
|
127
|
+
"HmIP-MOD-OC8": CustomConfig(make_ce_func=make_ip_switch, channels=(10, 14, 18, 22, 26, 30, 34, 38)),
|
|
128
|
+
"HmIP-PCBS": CustomConfig(make_ce_func=make_ip_switch, channels=(3,)),
|
|
129
|
+
"HmIP-PCBS-BAT": CustomConfig(make_ce_func=make_ip_switch, channels=(3,)),
|
|
130
|
+
"HmIP-PCBS2": CustomConfig(make_ce_func=make_ip_switch, channels=(4, 8)),
|
|
131
|
+
"HmIP-PS": CustomConfig(make_ce_func=make_ip_switch, channels=(3,)),
|
|
132
|
+
"HmIP-SCTH230": CustomConfig(make_ce_func=make_ip_switch, channels=(8,)),
|
|
133
|
+
"HmIP-SMO230": CustomConfig(
|
|
134
|
+
make_ce_func=make_ip_switch,
|
|
135
|
+
channels=(10,),
|
|
136
|
+
extended=ExtendedConfig(
|
|
137
|
+
additional_data_points={
|
|
138
|
+
1: (
|
|
139
|
+
Parameter.ILLUMINATION,
|
|
140
|
+
Parameter.MOTION,
|
|
141
|
+
Parameter.MOTION_DETECTION_ACTIVE,
|
|
142
|
+
Parameter.RESET_MOTION,
|
|
143
|
+
),
|
|
144
|
+
2: (
|
|
145
|
+
Parameter.ILLUMINATION,
|
|
146
|
+
Parameter.MOTION,
|
|
147
|
+
Parameter.MOTION_DETECTION_ACTIVE,
|
|
148
|
+
Parameter.RESET_MOTION,
|
|
149
|
+
),
|
|
150
|
+
3: (
|
|
151
|
+
Parameter.ILLUMINATION,
|
|
152
|
+
Parameter.MOTION,
|
|
153
|
+
Parameter.MOTION_DETECTION_ACTIVE,
|
|
154
|
+
Parameter.RESET_MOTION,
|
|
155
|
+
),
|
|
156
|
+
4: (
|
|
157
|
+
Parameter.ILLUMINATION,
|
|
158
|
+
Parameter.MOTION,
|
|
159
|
+
Parameter.MOTION_DETECTION_ACTIVE,
|
|
160
|
+
Parameter.RESET_MOTION,
|
|
161
|
+
),
|
|
162
|
+
}
|
|
163
|
+
),
|
|
164
|
+
),
|
|
165
|
+
"HmIP-USBSM": CustomConfig(make_ce_func=make_ip_switch, channels=(3,)),
|
|
166
|
+
"HmIP-WGC": CustomConfig(make_ce_func=make_ip_switch, channels=(3,)),
|
|
167
|
+
"HmIP-WGT": CustomConfig(make_ce_func=make_ip_switch, channels=(4,)),
|
|
168
|
+
"HmIP-WHS2": CustomConfig(make_ce_func=make_ip_switch, channels=(2, 6)),
|
|
169
|
+
"HmIPW-DRS": CustomConfig(
|
|
170
|
+
make_ce_func=make_ip_switch,
|
|
171
|
+
channels=(2, 6, 10, 14, 18, 22, 26, 30),
|
|
172
|
+
),
|
|
173
|
+
"HmIPW-FIO6": CustomConfig(make_ce_func=make_ip_switch, channels=(8, 12, 16, 20, 24, 28)),
|
|
174
|
+
}
|
|
175
|
+
hmed.ALL_DEVICES[DataPointCategory.SWITCH] = DEVICES
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2021-2025
|
|
3
|
+
"""Module for data points implemented using the valve category."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from collections.abc import Mapping
|
|
8
|
+
from enum import StrEnum
|
|
9
|
+
import logging
|
|
10
|
+
from typing import Any, Final
|
|
11
|
+
|
|
12
|
+
from aiohomematic.const import DataPointCategory, DeviceProfile, Field
|
|
13
|
+
from aiohomematic.model import device as hmd
|
|
14
|
+
from aiohomematic.model.custom import definition as hmed
|
|
15
|
+
from aiohomematic.model.custom.data_point import CustomDataPoint
|
|
16
|
+
from aiohomematic.model.custom.support import CustomConfig
|
|
17
|
+
from aiohomematic.model.data_point import CallParameterCollector, bind_collector
|
|
18
|
+
from aiohomematic.model.generic import DpAction, DpBinarySensor, DpSwitch
|
|
19
|
+
from aiohomematic.property_decorators import state_property
|
|
20
|
+
|
|
21
|
+
_LOGGER: Final = logging.getLogger(__name__)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class _StateChangeArg(StrEnum):
|
|
25
|
+
"""Enum with valve state change arguments."""
|
|
26
|
+
|
|
27
|
+
OFF = "off"
|
|
28
|
+
ON = "on"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class CustomDpIpIrrigationValve(CustomDataPoint):
|
|
32
|
+
"""Class for Homematic irrigation valve data point."""
|
|
33
|
+
|
|
34
|
+
__slots__ = (
|
|
35
|
+
"_dp_group_state",
|
|
36
|
+
"_dp_on_time_value",
|
|
37
|
+
"_dp_state",
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
_category = DataPointCategory.VALVE
|
|
41
|
+
|
|
42
|
+
def _init_data_point_fields(self) -> None:
|
|
43
|
+
"""Init the data_point fields."""
|
|
44
|
+
super()._init_data_point_fields()
|
|
45
|
+
self._dp_state: DpSwitch = self._get_data_point(field=Field.STATE, data_point_type=DpSwitch)
|
|
46
|
+
self._dp_on_time_value: DpAction = self._get_data_point(field=Field.ON_TIME_VALUE, data_point_type=DpAction)
|
|
47
|
+
self._dp_group_state: DpBinarySensor = self._get_data_point(
|
|
48
|
+
field=Field.GROUP_STATE, data_point_type=DpBinarySensor
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
@property
|
|
52
|
+
def group_value(self) -> bool | None:
|
|
53
|
+
"""Return the current channel value of the valve."""
|
|
54
|
+
return self._dp_group_state.value
|
|
55
|
+
|
|
56
|
+
@state_property
|
|
57
|
+
def value(self) -> bool | None:
|
|
58
|
+
"""Return the current value of the valve."""
|
|
59
|
+
return self._dp_state.value
|
|
60
|
+
|
|
61
|
+
@bind_collector()
|
|
62
|
+
async def open(self, *, on_time: float | None = None, collector: CallParameterCollector | None = None) -> None:
|
|
63
|
+
"""Turn the valve on."""
|
|
64
|
+
if on_time is not None:
|
|
65
|
+
self.set_timer_on_time(on_time=on_time)
|
|
66
|
+
if not self.is_state_change(on=True):
|
|
67
|
+
return
|
|
68
|
+
|
|
69
|
+
if (timer := self.get_and_start_timer()) is not None:
|
|
70
|
+
await self._dp_on_time_value.send_value(value=timer, collector=collector, do_validate=False)
|
|
71
|
+
await self._dp_state.turn_on(collector=collector)
|
|
72
|
+
|
|
73
|
+
@bind_collector()
|
|
74
|
+
async def close(self, *, collector: CallParameterCollector | None = None) -> None:
|
|
75
|
+
"""Turn the valve off."""
|
|
76
|
+
self.reset_timer_on_time()
|
|
77
|
+
if not self.is_state_change(off=True):
|
|
78
|
+
return
|
|
79
|
+
await self._dp_state.turn_off(collector=collector)
|
|
80
|
+
|
|
81
|
+
def is_state_change(self, **kwargs: Any) -> bool:
|
|
82
|
+
"""Check if the state changes due to kwargs."""
|
|
83
|
+
if (on_time_running := self.timer_on_time_running) is not None and on_time_running is True:
|
|
84
|
+
return True
|
|
85
|
+
if self.timer_on_time is not None:
|
|
86
|
+
return True
|
|
87
|
+
if kwargs.get(_StateChangeArg.ON) is not None and self.value is not True:
|
|
88
|
+
return True
|
|
89
|
+
if kwargs.get(_StateChangeArg.OFF) is not None and self.value is not False:
|
|
90
|
+
return True
|
|
91
|
+
return super().is_state_change(**kwargs)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def make_ip_irrigation_valve(
|
|
95
|
+
*,
|
|
96
|
+
channel: hmd.Channel,
|
|
97
|
+
custom_config: CustomConfig,
|
|
98
|
+
) -> None:
|
|
99
|
+
"""Create HomematicIP irrigation valve data point."""
|
|
100
|
+
hmed.make_custom_data_point(
|
|
101
|
+
channel=channel,
|
|
102
|
+
data_point_class=CustomDpIpIrrigationValve,
|
|
103
|
+
device_profile=DeviceProfile.IP_IRRIGATION_VALVE,
|
|
104
|
+
custom_config=custom_config,
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
# Case for device model is not relevant.
|
|
109
|
+
# HomeBrew (HB-) devices are always listed as HM-.
|
|
110
|
+
DEVICES: Mapping[str, CustomConfig | tuple[CustomConfig, ...]] = {
|
|
111
|
+
"ELV-SH-WSM": CustomConfig(make_ce_func=make_ip_irrigation_valve, channels=(4,)),
|
|
112
|
+
"HmIP-WSM": CustomConfig(make_ce_func=make_ip_irrigation_valve, channels=(4,)),
|
|
113
|
+
}
|
|
114
|
+
hmed.ALL_DEVICES[DataPointCategory.VALVE] = DEVICES
|