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,147 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2021-2025
|
|
3
|
+
"""
|
|
4
|
+
Dummy generic data point (backend-detached placeholder).
|
|
5
|
+
|
|
6
|
+
This class derives from `GenericDataPoint` but overrides all methods that would
|
|
7
|
+
normally interact with the backend so it behaves like an inert data point that
|
|
8
|
+
uses safe default values only.
|
|
9
|
+
The DpDummy class is intended to be used as a placeholder for custom data
|
|
10
|
+
points that are not implemented in the backend.
|
|
11
|
+
|
|
12
|
+
Key properties:
|
|
13
|
+
- It never triggers backend I/O (no reads, no writes, no subscriptions).
|
|
14
|
+
- It always reports `usage = DataPointUsage.NO_CREATE` so it is not created as a
|
|
15
|
+
real entity.
|
|
16
|
+
- It is not readable or writable and does not require polling nor support
|
|
17
|
+
events.
|
|
18
|
+
- It exposes safe, static defaults for metadata and state.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
from datetime import datetime
|
|
24
|
+
from typing import Any, cast
|
|
25
|
+
|
|
26
|
+
from aiohomematic.const import (
|
|
27
|
+
DP_KEY_VALUE,
|
|
28
|
+
INIT_DATETIME,
|
|
29
|
+
CallSource,
|
|
30
|
+
DataPointKey,
|
|
31
|
+
DataPointUsage,
|
|
32
|
+
Field,
|
|
33
|
+
ParameterData,
|
|
34
|
+
ParameterType,
|
|
35
|
+
ParamsetKey,
|
|
36
|
+
)
|
|
37
|
+
from aiohomematic.model import device as hmd
|
|
38
|
+
from aiohomematic.model.data_point import CallParameterCollector
|
|
39
|
+
from aiohomematic.model.generic.data_point import GenericDataPoint
|
|
40
|
+
from aiohomematic.model.support import DataPointNameData
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class DpDummy(GenericDataPoint[Any, Any]):
|
|
44
|
+
"""
|
|
45
|
+
Backend-detached `GenericDataPoint` using only default values.
|
|
46
|
+
|
|
47
|
+
All backend-touching operations are overridden to be no-ops.
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
__slots__ = ()
|
|
51
|
+
|
|
52
|
+
is_hmtype = False
|
|
53
|
+
|
|
54
|
+
def __init__(self, *, channel: hmd.Channel, param_field: str | Field) -> None:
|
|
55
|
+
"""
|
|
56
|
+
Initialize the dummy data point.
|
|
57
|
+
|
|
58
|
+
We still call `super().__init__` to get a valid object layout, but all
|
|
59
|
+
runtime behavior that would contact the backend is disabled via
|
|
60
|
+
overrides below.
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
super().__init__(
|
|
64
|
+
channel=channel,
|
|
65
|
+
paramset_key=ParamsetKey.DUMMY,
|
|
66
|
+
parameter=f"DUMMY-{str(param_field)}",
|
|
67
|
+
parameter_data=ParameterData(
|
|
68
|
+
DEFAULT=None,
|
|
69
|
+
FLAGS=0,
|
|
70
|
+
ID="0",
|
|
71
|
+
MAX=None,
|
|
72
|
+
MIN=None,
|
|
73
|
+
OPERATIONS=0,
|
|
74
|
+
SPECIAL={},
|
|
75
|
+
TYPE=ParameterType.DUMMY,
|
|
76
|
+
UNIT="",
|
|
77
|
+
VALUE_LIST=(),
|
|
78
|
+
),
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
# --- Metadata and identity -------------------------------------------
|
|
82
|
+
@property
|
|
83
|
+
def usage(self) -> DataPointUsage:
|
|
84
|
+
"""Never create/ expose this data point as a real entity."""
|
|
85
|
+
return DataPointUsage.NO_CREATE
|
|
86
|
+
|
|
87
|
+
@property
|
|
88
|
+
def requires_polling(self) -> bool:
|
|
89
|
+
"""Never poll from this data point."""
|
|
90
|
+
return False
|
|
91
|
+
|
|
92
|
+
@property
|
|
93
|
+
def state_uncertain(self) -> bool:
|
|
94
|
+
"""Never report state uncertainty for this data point."""
|
|
95
|
+
return True
|
|
96
|
+
|
|
97
|
+
@property
|
|
98
|
+
def modified_at(self) -> datetime:
|
|
99
|
+
"""Never report modification timestamp for this data point."""
|
|
100
|
+
return INIT_DATETIME
|
|
101
|
+
|
|
102
|
+
@property
|
|
103
|
+
def refreshed_at(self) -> datetime:
|
|
104
|
+
"""Never report refresh timestamp for this data point."""
|
|
105
|
+
return INIT_DATETIME
|
|
106
|
+
|
|
107
|
+
@property
|
|
108
|
+
def dpk(self) -> DataPointKey:
|
|
109
|
+
"""Return a stable placeholder data point key."""
|
|
110
|
+
# Return a stable placeholder key so equality/set operations are safe.
|
|
111
|
+
return cast(DataPointKey, ("", "", ""))
|
|
112
|
+
|
|
113
|
+
@property
|
|
114
|
+
def value(self) -> Any:
|
|
115
|
+
"""Return the value of the data_point."""
|
|
116
|
+
return None
|
|
117
|
+
|
|
118
|
+
# Optional: provide a stable, recognizable name to aid debugging
|
|
119
|
+
def _get_data_point_name(self) -> DataPointNameData:
|
|
120
|
+
"""Return a stable, recognizable name to aid debugging."""
|
|
121
|
+
name = super()._get_data_point_name()
|
|
122
|
+
# Replace parameter part with a dummy marker without touching address
|
|
123
|
+
return DataPointNameData(
|
|
124
|
+
device_name=f"DUMMY_{name.name}",
|
|
125
|
+
channel_name=f"DUMMY_{name.full_name}",
|
|
126
|
+
parameter_name=f"DUMMY_{name.parameter_name}",
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
# --- Backend interactions (all no-ops) --------------------------------
|
|
130
|
+
async def event(self, *, value: Any, received_at: datetime) -> None:
|
|
131
|
+
"""Ignore backend events entirely."""
|
|
132
|
+
return
|
|
133
|
+
|
|
134
|
+
async def load_data_point_value(self, *, call_source: CallSource, direct_call: bool = False) -> None:
|
|
135
|
+
"""Do not read from backend; keep defaults as-is."""
|
|
136
|
+
return
|
|
137
|
+
|
|
138
|
+
async def send_value(
|
|
139
|
+
self,
|
|
140
|
+
*,
|
|
141
|
+
value: Any,
|
|
142
|
+
collector: CallParameterCollector | None = None,
|
|
143
|
+
collector_order: int = 50,
|
|
144
|
+
do_validate: bool = True,
|
|
145
|
+
) -> set[DP_KEY_VALUE]:
|
|
146
|
+
"""Do not write to backend; accept but perform no operation."""
|
|
147
|
+
return set()
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2021-2025
|
|
3
|
+
"""Module for data points implemented using the number category."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing import cast
|
|
8
|
+
|
|
9
|
+
from aiohomematic.const import DataPointCategory
|
|
10
|
+
from aiohomematic.exceptions import ValidationException
|
|
11
|
+
from aiohomematic.model.generic.data_point import GenericDataPoint
|
|
12
|
+
from aiohomematic.property_decorators import state_property
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class BaseDpNumber[NumberParameterT: int | float | None](GenericDataPoint[NumberParameterT, int | float | str]):
|
|
16
|
+
"""
|
|
17
|
+
Implementation of a number.
|
|
18
|
+
|
|
19
|
+
This is a default data point that gets automatically generated.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
__slots__ = ()
|
|
23
|
+
|
|
24
|
+
_category = DataPointCategory.NUMBER
|
|
25
|
+
|
|
26
|
+
def _prepare_number_for_sending(
|
|
27
|
+
self, *, value: int | float | str, type_converter: type, do_validate: bool = True
|
|
28
|
+
) -> NumberParameterT:
|
|
29
|
+
"""Prepare value before sending."""
|
|
30
|
+
if not do_validate or (
|
|
31
|
+
value is not None and isinstance(value, int | float) and self._min <= type_converter(value) <= self._max
|
|
32
|
+
):
|
|
33
|
+
return cast(NumberParameterT, type_converter(value))
|
|
34
|
+
if self._special and isinstance(value, str) and value in self._special:
|
|
35
|
+
return cast(NumberParameterT, type_converter(self._special[value]))
|
|
36
|
+
raise ValidationException(
|
|
37
|
+
f"NUMBER failed: Invalid value: {value} (min: {self._min}, max: {self._max}, special:{self._special})"
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class DpFloat(BaseDpNumber[float | None]):
|
|
42
|
+
"""
|
|
43
|
+
Implementation of a Float.
|
|
44
|
+
|
|
45
|
+
This is a default data point that gets automatically generated.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
__slots__ = ()
|
|
49
|
+
|
|
50
|
+
def _prepare_value_for_sending(self, *, value: int | float | str, do_validate: bool = True) -> float | None:
|
|
51
|
+
"""Prepare value before sending."""
|
|
52
|
+
return self._prepare_number_for_sending(value=value, type_converter=float, do_validate=do_validate)
|
|
53
|
+
|
|
54
|
+
@state_property
|
|
55
|
+
def value(self) -> float | None:
|
|
56
|
+
"""Return the value of the data_point."""
|
|
57
|
+
return cast(float | None, self._value)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class DpInteger(BaseDpNumber[int | None]):
|
|
61
|
+
"""
|
|
62
|
+
Implementation of an Integer.
|
|
63
|
+
|
|
64
|
+
This is a default data point that gets automatically generated.
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
__slots__ = ()
|
|
68
|
+
|
|
69
|
+
def _prepare_value_for_sending(self, *, value: int | float | str, do_validate: bool = True) -> int | None:
|
|
70
|
+
"""Prepare value before sending."""
|
|
71
|
+
return self._prepare_number_for_sending(value=value, type_converter=int, do_validate=do_validate)
|
|
72
|
+
|
|
73
|
+
@state_property
|
|
74
|
+
def value(self) -> int | None:
|
|
75
|
+
"""Return the value of the data_point."""
|
|
76
|
+
return cast(int | None, self._value)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2021-2025
|
|
3
|
+
"""Module for data points implemented using the select category."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from aiohomematic.const import DataPointCategory
|
|
8
|
+
from aiohomematic.exceptions import ValidationException
|
|
9
|
+
from aiohomematic.model.generic.data_point import GenericDataPoint
|
|
10
|
+
from aiohomematic.model.support import get_value_from_value_list
|
|
11
|
+
from aiohomematic.property_decorators import state_property
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class DpSelect(GenericDataPoint[int | str, int | float | str]):
|
|
15
|
+
"""
|
|
16
|
+
Implementation of a select data_point.
|
|
17
|
+
|
|
18
|
+
This is a default data point that gets automatically generated.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
__slots__ = ()
|
|
22
|
+
|
|
23
|
+
_category = DataPointCategory.SELECT
|
|
24
|
+
|
|
25
|
+
@state_property
|
|
26
|
+
def value(self) -> str | None:
|
|
27
|
+
"""Get the value of the data_point."""
|
|
28
|
+
if (value := get_value_from_value_list(value=self._value, value_list=self.values)) is not None:
|
|
29
|
+
return value
|
|
30
|
+
return str(self._default)
|
|
31
|
+
|
|
32
|
+
def _prepare_value_for_sending(self, *, value: int | float | str, do_validate: bool = True) -> int:
|
|
33
|
+
"""Prepare value before sending."""
|
|
34
|
+
# We allow setting the value via index as well, just in case.
|
|
35
|
+
if isinstance(value, int | float) and self._values and 0 <= value < len(self._values):
|
|
36
|
+
return int(value)
|
|
37
|
+
if self._values and value in self._values:
|
|
38
|
+
return self._values.index(value)
|
|
39
|
+
raise ValidationException(f"Value not in value_list for {self.name}/{self.unique_id}")
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2021-2025
|
|
3
|
+
"""Module for data points implemented using the sensor category."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from collections.abc import Mapping
|
|
8
|
+
import logging
|
|
9
|
+
from typing import Any, Final, cast
|
|
10
|
+
|
|
11
|
+
from aiohomematic.const import DataPointCategory, Parameter, ParameterType
|
|
12
|
+
from aiohomematic.model.generic.data_point import GenericDataPoint
|
|
13
|
+
from aiohomematic.model.support import check_length_and_log, get_value_from_value_list
|
|
14
|
+
from aiohomematic.property_decorators import state_property
|
|
15
|
+
|
|
16
|
+
_LOGGER: Final = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class DpSensor[SensorT: float | int | str | None](GenericDataPoint[SensorT, None]):
|
|
20
|
+
"""
|
|
21
|
+
Implementation of a sensor.
|
|
22
|
+
|
|
23
|
+
This is a default data point that gets automatically generated.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
__slots__ = ()
|
|
27
|
+
|
|
28
|
+
_category = DataPointCategory.SENSOR
|
|
29
|
+
|
|
30
|
+
@state_property
|
|
31
|
+
def value(self) -> SensorT:
|
|
32
|
+
"""Return the value."""
|
|
33
|
+
if (value := get_value_from_value_list(value=self._value, value_list=self.values)) is not None:
|
|
34
|
+
return cast(SensorT, value)
|
|
35
|
+
if convert_func := self._get_converter_func():
|
|
36
|
+
return cast(SensorT, convert_func(value=self._value))
|
|
37
|
+
return cast(
|
|
38
|
+
SensorT,
|
|
39
|
+
check_length_and_log(name=self.name, value=self._value)
|
|
40
|
+
if self._type == ParameterType.STRING
|
|
41
|
+
else self._value,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
def _get_converter_func(self) -> Any:
|
|
45
|
+
"""Return a converter based on sensor."""
|
|
46
|
+
if convert_func := _VALUE_CONVERTERS_BY_PARAM.get(self.parameter):
|
|
47
|
+
return convert_func
|
|
48
|
+
return None
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _fix_rssi(*, value: Any) -> int | None:
|
|
52
|
+
"""
|
|
53
|
+
Fix rssi value.
|
|
54
|
+
|
|
55
|
+
See https://github.com/sukramj/aiohomematic/blob/devel/docs/rssi_fix.md.
|
|
56
|
+
"""
|
|
57
|
+
if value is None:
|
|
58
|
+
return None
|
|
59
|
+
if isinstance(value, int):
|
|
60
|
+
if -127 < value < 0:
|
|
61
|
+
return value
|
|
62
|
+
if 1 < value < 127:
|
|
63
|
+
return value * -1
|
|
64
|
+
if -256 < value < -129:
|
|
65
|
+
return (value * -1) - 256
|
|
66
|
+
if 129 < value < 256:
|
|
67
|
+
return value - 256
|
|
68
|
+
return None
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
_VALUE_CONVERTERS_BY_PARAM: Mapping[str, Any] = {
|
|
72
|
+
Parameter.RSSI_PEER: _fix_rssi,
|
|
73
|
+
Parameter.RSSI_DEVICE: _fix_rssi,
|
|
74
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
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 typing import cast
|
|
8
|
+
|
|
9
|
+
from aiohomematic.const import DataPointCategory, Parameter, ParameterType
|
|
10
|
+
from aiohomematic.decorators import inspector
|
|
11
|
+
from aiohomematic.model.data_point import CallParameterCollector
|
|
12
|
+
from aiohomematic.model.generic.data_point import GenericDataPoint
|
|
13
|
+
from aiohomematic.property_decorators import state_property
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class DpSwitch(GenericDataPoint[bool | None, bool]):
|
|
17
|
+
"""
|
|
18
|
+
Implementation of a switch.
|
|
19
|
+
|
|
20
|
+
This is a default data point that gets automatically generated.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
__slots__ = ()
|
|
24
|
+
|
|
25
|
+
_category = DataPointCategory.SWITCH
|
|
26
|
+
|
|
27
|
+
@state_property
|
|
28
|
+
def value(self) -> bool | None:
|
|
29
|
+
"""Get the value of the data_point."""
|
|
30
|
+
if self._type == ParameterType.ACTION:
|
|
31
|
+
return False
|
|
32
|
+
return cast(bool | None, self._value)
|
|
33
|
+
|
|
34
|
+
@inspector
|
|
35
|
+
async def turn_on(self, *, on_time: float | None = None, collector: CallParameterCollector | None = None) -> None:
|
|
36
|
+
"""Turn the switch on."""
|
|
37
|
+
if on_time is not None:
|
|
38
|
+
await self.set_on_time(on_time=on_time)
|
|
39
|
+
await self.send_value(value=True, collector=collector)
|
|
40
|
+
|
|
41
|
+
@inspector
|
|
42
|
+
async def turn_off(self, *, collector: CallParameterCollector | None = None) -> None:
|
|
43
|
+
"""Turn the switch off."""
|
|
44
|
+
await self.send_value(value=False, collector=collector)
|
|
45
|
+
|
|
46
|
+
@inspector
|
|
47
|
+
async def set_on_time(self, *, on_time: float) -> None:
|
|
48
|
+
"""Set the on time value in seconds."""
|
|
49
|
+
await self._client.set_value(
|
|
50
|
+
channel_address=self._channel.address,
|
|
51
|
+
paramset_key=self._paramset_key,
|
|
52
|
+
parameter=Parameter.ON_TIME,
|
|
53
|
+
value=float(on_time),
|
|
54
|
+
)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2021-2025
|
|
3
|
+
"""Module for data points implemented using the text category."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing import cast
|
|
8
|
+
|
|
9
|
+
from aiohomematic.const import DataPointCategory
|
|
10
|
+
from aiohomematic.model.generic.data_point import GenericDataPoint
|
|
11
|
+
from aiohomematic.model.support import check_length_and_log
|
|
12
|
+
from aiohomematic.property_decorators import state_property
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class DpText(GenericDataPoint[str, str]):
|
|
16
|
+
"""
|
|
17
|
+
Implementation of a text.
|
|
18
|
+
|
|
19
|
+
This is a default data point that gets automatically generated.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
__slots__ = ()
|
|
23
|
+
|
|
24
|
+
_category = DataPointCategory.TEXT
|
|
25
|
+
|
|
26
|
+
@state_property
|
|
27
|
+
def value(self) -> str | None:
|
|
28
|
+
"""Get the value of the data_point."""
|
|
29
|
+
return cast(str | None, check_length_and_log(name=self.name, value=self._value))
|