aiohomematic 2025.9.1__py3-none-any.whl → 2025.9.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/caches/dynamic.py +1 -6
- aiohomematic/central/__init__.py +34 -23
- aiohomematic/central/xml_rpc_server.py +1 -1
- aiohomematic/client/__init__.py +35 -29
- aiohomematic/client/json_rpc.py +44 -12
- aiohomematic/client/xml_rpc.py +53 -20
- aiohomematic/const.py +2 -2
- aiohomematic/decorators.py +56 -21
- aiohomematic/model/__init__.py +1 -1
- aiohomematic/model/calculated/__init__.py +1 -1
- aiohomematic/model/calculated/climate.py +1 -1
- aiohomematic/model/calculated/data_point.py +3 -3
- aiohomematic/model/calculated/operating_voltage_level.py +7 -21
- aiohomematic/model/calculated/support.py +20 -0
- aiohomematic/model/custom/__init__.py +1 -1
- aiohomematic/model/custom/climate.py +18 -18
- aiohomematic/model/custom/cover.py +1 -1
- aiohomematic/model/custom/data_point.py +1 -1
- aiohomematic/model/custom/light.py +1 -1
- aiohomematic/model/custom/lock.py +1 -1
- aiohomematic/model/custom/siren.py +1 -1
- aiohomematic/model/custom/switch.py +1 -1
- aiohomematic/model/custom/valve.py +1 -1
- aiohomematic/model/data_point.py +24 -24
- aiohomematic/model/device.py +22 -21
- aiohomematic/model/event.py +3 -8
- aiohomematic/model/generic/__init__.py +1 -1
- aiohomematic/model/generic/binary_sensor.py +1 -1
- aiohomematic/model/generic/button.py +1 -1
- aiohomematic/model/generic/data_point.py +4 -6
- aiohomematic/model/generic/number.py +1 -1
- aiohomematic/model/generic/select.py +1 -1
- aiohomematic/model/generic/sensor.py +1 -1
- aiohomematic/model/generic/switch.py +4 -4
- aiohomematic/model/generic/text.py +1 -1
- aiohomematic/model/hub/binary_sensor.py +1 -1
- aiohomematic/model/hub/button.py +2 -2
- aiohomematic/model/hub/data_point.py +4 -7
- aiohomematic/model/hub/number.py +1 -1
- aiohomematic/model/hub/select.py +2 -2
- aiohomematic/model/hub/sensor.py +1 -1
- aiohomematic/model/hub/switch.py +3 -3
- aiohomematic/model/hub/text.py +1 -1
- aiohomematic/model/support.py +1 -40
- aiohomematic/model/update.py +5 -4
- aiohomematic/property_decorators.py +511 -0
- aiohomematic/support.py +71 -85
- {aiohomematic-2025.9.1.dist-info → aiohomematic-2025.9.3.dist-info}/METADATA +7 -5
- aiohomematic-2025.9.3.dist-info/RECORD +78 -0
- aiohomematic_support/client_local.py +5 -5
- aiohomematic/model/decorators.py +0 -194
- aiohomematic-2025.9.1.dist-info/RECORD +0 -78
- {aiohomematic-2025.9.1.dist-info → aiohomematic-2025.9.3.dist-info}/WHEEL +0 -0
- {aiohomematic-2025.9.1.dist-info → aiohomematic-2025.9.3.dist-info}/licenses/LICENSE +0 -0
- {aiohomematic-2025.9.1.dist-info → aiohomematic-2025.9.3.dist-info}/top_level.txt +0 -0
|
@@ -16,8 +16,8 @@ from aiohomematic.model.custom.const import DeviceProfile, Field
|
|
|
16
16
|
from aiohomematic.model.custom.data_point import CustomDataPoint
|
|
17
17
|
from aiohomematic.model.custom.support import CustomConfig
|
|
18
18
|
from aiohomematic.model.data_point import CallParameterCollector, bind_collector
|
|
19
|
-
from aiohomematic.model.decorators import state_property
|
|
20
19
|
from aiohomematic.model.generic import DpAction, DpBinarySensor, DpSwitch
|
|
20
|
+
from aiohomematic.property_decorators import state_property
|
|
21
21
|
|
|
22
22
|
_LOGGER: Final = logging.getLogger(__name__)
|
|
23
23
|
|
aiohomematic/model/data_point.py
CHANGED
|
@@ -65,17 +65,16 @@ from aiohomematic.context import IN_SERVICE_VAR
|
|
|
65
65
|
from aiohomematic.decorators import get_service_calls
|
|
66
66
|
from aiohomematic.exceptions import AioHomematicException, BaseHomematicException
|
|
67
67
|
from aiohomematic.model import device as hmd
|
|
68
|
-
from aiohomematic.model.decorators import cached_slot_property, config_property, state_property
|
|
69
68
|
from aiohomematic.model.support import (
|
|
70
69
|
DataPointNameData,
|
|
71
70
|
DataPointPathData,
|
|
72
71
|
GenericParameterType,
|
|
73
72
|
PathData,
|
|
74
|
-
PayloadMixin,
|
|
75
73
|
convert_value,
|
|
76
74
|
generate_unique_id,
|
|
77
75
|
)
|
|
78
|
-
from aiohomematic.
|
|
76
|
+
from aiohomematic.property_decorators import cached_property, config_property, hm_property, state_property
|
|
77
|
+
from aiohomematic.support import LogContextMixin, PayloadMixin, extract_exc_args, log_boundary_error
|
|
79
78
|
|
|
80
79
|
__all__ = [
|
|
81
80
|
"BaseDataPoint",
|
|
@@ -132,7 +131,7 @@ EVENT_DATA_SCHEMA = vol.Schema(
|
|
|
132
131
|
)
|
|
133
132
|
|
|
134
133
|
|
|
135
|
-
class CallbackDataPoint(ABC):
|
|
134
|
+
class CallbackDataPoint(ABC, LogContextMixin):
|
|
136
135
|
"""Base class for callback data point."""
|
|
137
136
|
|
|
138
137
|
__slots__ = (
|
|
@@ -270,7 +269,7 @@ class CallbackDataPoint(ABC):
|
|
|
270
269
|
"""Return the data_point usage."""
|
|
271
270
|
return DataPointUsage.DATA_POINT
|
|
272
271
|
|
|
273
|
-
@
|
|
272
|
+
@cached_property
|
|
274
273
|
def enabled_default(self) -> bool:
|
|
275
274
|
"""Return, if data_point should be enabled based on usage attribute."""
|
|
276
275
|
return self.usage in (
|
|
@@ -296,12 +295,12 @@ class CallbackDataPoint(ABC):
|
|
|
296
295
|
return self._path_data.state_path
|
|
297
296
|
|
|
298
297
|
# @property
|
|
299
|
-
@
|
|
298
|
+
@cached_property
|
|
300
299
|
def service_methods(self) -> Mapping[str, Callable]:
|
|
301
300
|
"""Return all service methods."""
|
|
302
301
|
return get_service_calls(obj=self)
|
|
303
302
|
|
|
304
|
-
@
|
|
303
|
+
@cached_property
|
|
305
304
|
def service_method_names(self) -> tuple[str, ...]:
|
|
306
305
|
"""Return all service methods."""
|
|
307
306
|
return tuple(self.service_methods.keys())
|
|
@@ -448,7 +447,7 @@ class BaseDataPoint(CallbackDataPoint, PayloadMixin):
|
|
|
448
447
|
"""Return the availability of the device."""
|
|
449
448
|
return self._device.available
|
|
450
449
|
|
|
451
|
-
@
|
|
450
|
+
@hm_property(log_context=True)
|
|
452
451
|
def channel(self) -> hmd.Channel:
|
|
453
452
|
"""Return the channel the data_point."""
|
|
454
453
|
return self._channel
|
|
@@ -660,7 +659,7 @@ class BaseParameterDataPoint[
|
|
|
660
659
|
"""Return if the parameter is un ignored."""
|
|
661
660
|
return self._is_un_ignored
|
|
662
661
|
|
|
663
|
-
@
|
|
662
|
+
@cached_property
|
|
664
663
|
def dpk(self) -> DataPointKey:
|
|
665
664
|
"""Return data_point key value."""
|
|
666
665
|
return DataPointKey(
|
|
@@ -685,7 +684,7 @@ class BaseParameterDataPoint[
|
|
|
685
684
|
"""Return multiplier value."""
|
|
686
685
|
return self._multiplier
|
|
687
686
|
|
|
688
|
-
@
|
|
687
|
+
@hm_property(log_context=True)
|
|
689
688
|
def parameter(self) -> str:
|
|
690
689
|
"""Return parameter name."""
|
|
691
690
|
return self._parameter
|
|
@@ -700,7 +699,7 @@ class BaseParameterDataPoint[
|
|
|
700
699
|
"""Return raw unit value."""
|
|
701
700
|
return self._raw_unit
|
|
702
701
|
|
|
703
|
-
@
|
|
702
|
+
@cached_property
|
|
704
703
|
def requires_polling(self) -> bool:
|
|
705
704
|
"""Return whether the data_point requires polling."""
|
|
706
705
|
return not self._channel.device.client.supports_push_updates or (
|
|
@@ -786,7 +785,7 @@ class BaseParameterDataPoint[
|
|
|
786
785
|
"""Return the if data_point is visible in ccu."""
|
|
787
786
|
return self._visible
|
|
788
787
|
|
|
789
|
-
@
|
|
788
|
+
@cached_property
|
|
790
789
|
def _enabled_by_channel_operation_mode(self) -> bool | None:
|
|
791
790
|
"""Return, if the data_point/event must be enabled."""
|
|
792
791
|
if self._channel.type_name not in _CONFIGURABLE_CHANNEL:
|
|
@@ -857,7 +856,7 @@ class BaseParameterDataPoint[
|
|
|
857
856
|
return f"{self._category}/{self._channel.device.model}/{self._parameter}"
|
|
858
857
|
|
|
859
858
|
@abstractmethod
|
|
860
|
-
async def event(self, value: Any, received_at: datetime
|
|
859
|
+
async def event(self, value: Any, received_at: datetime) -> None:
|
|
861
860
|
"""Handle event for which this handler has subscribed."""
|
|
862
861
|
|
|
863
862
|
async def load_data_point_value(self, call_source: CallSource, direct_call: bool = False) -> None:
|
|
@@ -1086,17 +1085,18 @@ def bind_collector(
|
|
|
1086
1085
|
IN_SERVICE_VAR.reset(token)
|
|
1087
1086
|
in_service = IN_SERVICE_VAR.get()
|
|
1088
1087
|
if not in_service and log_level > logging.NOTSET:
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1088
|
+
context_obj = args[0]
|
|
1089
|
+
logger = logging.getLogger(context_obj.__module__)
|
|
1090
|
+
log_context = context_obj.log_context if isinstance(context_obj, LogContextMixin) else None
|
|
1091
|
+
# Reuse centralized boundary logging to ensure consistent 'extra' structure
|
|
1092
|
+
log_boundary_error(
|
|
1093
|
+
logger=logger,
|
|
1094
|
+
boundary="service",
|
|
1095
|
+
action=func.__name__,
|
|
1096
|
+
err=bhexc,
|
|
1097
|
+
level=log_level,
|
|
1098
|
+
log_context=log_context,
|
|
1099
|
+
)
|
|
1100
1100
|
# Re-raise domain-specific exceptions so callers and tests can handle them
|
|
1101
1101
|
raise
|
|
1102
1102
|
else:
|
aiohomematic/model/device.py
CHANGED
|
@@ -71,19 +71,20 @@ from aiohomematic.exceptions import AioHomematicException, BaseHomematicExceptio
|
|
|
71
71
|
from aiohomematic.model.calculated import CalculatedDataPoint
|
|
72
72
|
from aiohomematic.model.custom import data_point as hmce, definition as hmed
|
|
73
73
|
from aiohomematic.model.data_point import BaseParameterDataPoint, CallbackDataPoint
|
|
74
|
-
from aiohomematic.model.decorators import cached_slot_property, info_property, state_property
|
|
75
74
|
from aiohomematic.model.event import GenericEvent
|
|
76
75
|
from aiohomematic.model.generic import GenericDataPoint
|
|
77
76
|
from aiohomematic.model.support import (
|
|
78
77
|
ChannelNameData,
|
|
79
|
-
PayloadMixin,
|
|
80
78
|
generate_channel_unique_id,
|
|
81
79
|
get_channel_name_data,
|
|
82
80
|
get_device_name,
|
|
83
81
|
)
|
|
84
82
|
from aiohomematic.model.update import DpUpdate
|
|
83
|
+
from aiohomematic.property_decorators import cached_property, hm_property, info_property, state_property
|
|
85
84
|
from aiohomematic.support import (
|
|
86
85
|
CacheEntry,
|
|
86
|
+
LogContextMixin,
|
|
87
|
+
PayloadMixin,
|
|
87
88
|
check_or_create_directory,
|
|
88
89
|
extract_exc_args,
|
|
89
90
|
get_channel_address,
|
|
@@ -96,7 +97,7 @@ __all__ = ["Channel", "Device"]
|
|
|
96
97
|
_LOGGER: Final = logging.getLogger(__name__)
|
|
97
98
|
|
|
98
99
|
|
|
99
|
-
class Device(PayloadMixin):
|
|
100
|
+
class Device(LogContextMixin, PayloadMixin):
|
|
100
101
|
"""Object to hold information about a device and associated data points."""
|
|
101
102
|
|
|
102
103
|
__slots__ = (
|
|
@@ -196,7 +197,7 @@ class Device(PayloadMixin):
|
|
|
196
197
|
return Manufacturer.MOEHLENHOFF
|
|
197
198
|
return Manufacturer.EQ3
|
|
198
199
|
|
|
199
|
-
@info_property
|
|
200
|
+
@info_property(log_context=True)
|
|
200
201
|
def address(self) -> str:
|
|
201
202
|
"""Return the address of the device."""
|
|
202
203
|
return self._address
|
|
@@ -326,7 +327,7 @@ class Device(PayloadMixin):
|
|
|
326
327
|
"""Return the interface of the device."""
|
|
327
328
|
return self._interface
|
|
328
329
|
|
|
329
|
-
@
|
|
330
|
+
@hm_property(log_context=True)
|
|
330
331
|
def interface_id(self) -> str:
|
|
331
332
|
"""Return the interface_id of the device."""
|
|
332
333
|
return self._interface_id
|
|
@@ -353,7 +354,7 @@ class Device(PayloadMixin):
|
|
|
353
354
|
"""Return the manufacturer of the device."""
|
|
354
355
|
return self._manufacturer
|
|
355
356
|
|
|
356
|
-
@info_property
|
|
357
|
+
@info_property(log_context=True)
|
|
357
358
|
def model(self) -> str:
|
|
358
359
|
"""Return the model of the device."""
|
|
359
360
|
return self._model
|
|
@@ -426,21 +427,21 @@ class Device(PayloadMixin):
|
|
|
426
427
|
elif self._channel_groups[channel_no] != group_no:
|
|
427
428
|
return
|
|
428
429
|
|
|
429
|
-
@inspector
|
|
430
|
+
@inspector
|
|
430
431
|
async def create_central_links(self) -> None:
|
|
431
432
|
"""Create a central links to support press events on all channels with click events."""
|
|
432
433
|
if self.relevant_for_central_link_management: # pylint: disable=using-constant-test
|
|
433
434
|
for channel in self._channels.values():
|
|
434
435
|
await channel.create_central_link()
|
|
435
436
|
|
|
436
|
-
@inspector
|
|
437
|
+
@inspector
|
|
437
438
|
async def remove_central_links(self) -> None:
|
|
438
439
|
"""Remove central links."""
|
|
439
440
|
if self.relevant_for_central_link_management: # pylint: disable=using-constant-test
|
|
440
441
|
for channel in self._channels.values():
|
|
441
442
|
await channel.remove_central_link()
|
|
442
443
|
|
|
443
|
-
@
|
|
444
|
+
@cached_property
|
|
444
445
|
def relevant_for_central_link_management(self) -> bool:
|
|
445
446
|
"""Return if channel is relevant for central link management."""
|
|
446
447
|
return (
|
|
@@ -583,7 +584,7 @@ class Device(PayloadMixin):
|
|
|
583
584
|
for dp in self.generic_data_points:
|
|
584
585
|
dp.fire_data_point_updated_callback()
|
|
585
586
|
|
|
586
|
-
@inspector
|
|
587
|
+
@inspector
|
|
587
588
|
async def export_device_definition(self) -> None:
|
|
588
589
|
"""Export the device definition for current device."""
|
|
589
590
|
try:
|
|
@@ -612,7 +613,7 @@ class Device(PayloadMixin):
|
|
|
612
613
|
for callback_handler in self._firmware_update_callbacks:
|
|
613
614
|
callback_handler()
|
|
614
615
|
|
|
615
|
-
@inspector
|
|
616
|
+
@inspector
|
|
616
617
|
async def update_firmware(self, refresh_after_update_intervals: tuple[int, ...]) -> bool:
|
|
617
618
|
"""Update the firmware of the homematic device."""
|
|
618
619
|
update_result = await self._client.update_device_firmware(device_address=self._address)
|
|
@@ -627,7 +628,7 @@ class Device(PayloadMixin):
|
|
|
627
628
|
|
|
628
629
|
return update_result
|
|
629
630
|
|
|
630
|
-
@inspector
|
|
631
|
+
@inspector
|
|
631
632
|
async def load_value_cache(self) -> None:
|
|
632
633
|
"""Init the parameter cache."""
|
|
633
634
|
if len(self.generic_data_points) > 0:
|
|
@@ -639,7 +640,7 @@ class Device(PayloadMixin):
|
|
|
639
640
|
self._address,
|
|
640
641
|
)
|
|
641
642
|
|
|
642
|
-
@inspector
|
|
643
|
+
@inspector
|
|
643
644
|
async def reload_paramset_descriptions(self) -> None:
|
|
644
645
|
"""Reload paramset for device."""
|
|
645
646
|
for (
|
|
@@ -682,7 +683,7 @@ class Device(PayloadMixin):
|
|
|
682
683
|
)
|
|
683
684
|
|
|
684
685
|
|
|
685
|
-
class Channel(PayloadMixin):
|
|
686
|
+
class Channel(LogContextMixin, PayloadMixin):
|
|
686
687
|
"""Object to hold information about a channel and associated data points."""
|
|
687
688
|
|
|
688
689
|
__slots__ = (
|
|
@@ -736,7 +737,7 @@ class Channel(PayloadMixin):
|
|
|
736
737
|
self._rooms: Final = self._central.device_details.get_channel_rooms(channel_address=channel_address)
|
|
737
738
|
self._function: Final = self._central.device_details.get_function_text(address=self._address)
|
|
738
739
|
|
|
739
|
-
@
|
|
740
|
+
@info_property
|
|
740
741
|
def address(self) -> str:
|
|
741
742
|
"""Return the address of the channel."""
|
|
742
743
|
return self._address
|
|
@@ -761,7 +762,7 @@ class Channel(PayloadMixin):
|
|
|
761
762
|
"""Return the device description for the channel."""
|
|
762
763
|
return self._description
|
|
763
764
|
|
|
764
|
-
@
|
|
765
|
+
@hm_property(log_context=True)
|
|
765
766
|
def device(self) -> Device:
|
|
766
767
|
"""Return the device of the channel."""
|
|
767
768
|
return self._device
|
|
@@ -831,7 +832,7 @@ class Channel(PayloadMixin):
|
|
|
831
832
|
"""Return the name data of the channel."""
|
|
832
833
|
return self._name_data
|
|
833
834
|
|
|
834
|
-
@
|
|
835
|
+
@hm_property(log_context=True)
|
|
835
836
|
def no(self) -> int | None:
|
|
836
837
|
"""Return the channel_no of the channel."""
|
|
837
838
|
return self._no
|
|
@@ -883,7 +884,7 @@ class Channel(PayloadMixin):
|
|
|
883
884
|
"""Return the unique_id of the channel."""
|
|
884
885
|
return self._unique_id
|
|
885
886
|
|
|
886
|
-
@inspector
|
|
887
|
+
@inspector
|
|
887
888
|
async def create_central_link(self) -> None:
|
|
888
889
|
"""Create a central link to support press events."""
|
|
889
890
|
if self._has_key_press_events and not await self._has_central_link():
|
|
@@ -891,7 +892,7 @@ class Channel(PayloadMixin):
|
|
|
891
892
|
address=self._address, value_id=REPORT_VALUE_USAGE_VALUE_ID, ref_counter=1
|
|
892
893
|
)
|
|
893
894
|
|
|
894
|
-
@inspector
|
|
895
|
+
@inspector
|
|
895
896
|
async def remove_central_link(self) -> None:
|
|
896
897
|
"""Remove a central link."""
|
|
897
898
|
if self._has_key_press_events and await self._has_central_link() and not await self._has_program_ids():
|
|
@@ -899,7 +900,7 @@ class Channel(PayloadMixin):
|
|
|
899
900
|
address=self._address, value_id=REPORT_VALUE_USAGE_VALUE_ID, ref_counter=0
|
|
900
901
|
)
|
|
901
902
|
|
|
902
|
-
@inspector
|
|
903
|
+
@inspector
|
|
903
904
|
async def cleanup_central_link_metadata(self) -> None:
|
|
904
905
|
"""Cleanup the metadata for central links."""
|
|
905
906
|
if metadata := await self._device.client.get_metadata(address=self._address, data_id=REPORT_VALUE_USAGE_DATA):
|
|
@@ -1259,7 +1260,7 @@ class _DefinitionExporter:
|
|
|
1259
1260
|
self._device_address: Final = device.address
|
|
1260
1261
|
self._random_id: Final[str] = f"VCU{int(random.randint(1000000, 9999999))}"
|
|
1261
1262
|
|
|
1262
|
-
@inspector
|
|
1263
|
+
@inspector
|
|
1263
1264
|
async def export_data(self) -> None:
|
|
1264
1265
|
"""Export data."""
|
|
1265
1266
|
device_descriptions: Mapping[str, DeviceDescription] = (
|
aiohomematic/model/event.py
CHANGED
|
@@ -98,10 +98,8 @@ class GenericEvent(BaseParameterDataPoint[Any, Any]):
|
|
|
98
98
|
"""Return the event_type of the event."""
|
|
99
99
|
return self._event_type
|
|
100
100
|
|
|
101
|
-
async def event(self, value: Any, received_at: datetime
|
|
101
|
+
async def event(self, value: Any, received_at: datetime) -> None:
|
|
102
102
|
"""Handle event for which this handler has subscribed."""
|
|
103
|
-
if received_at is None:
|
|
104
|
-
received_at = datetime.now()
|
|
105
103
|
if self.event_type in DATA_POINT_EVENTS:
|
|
106
104
|
self.fire_data_point_updated_callback()
|
|
107
105
|
self._set_modified_at(modified_at=received_at)
|
|
@@ -139,11 +137,8 @@ class DeviceErrorEvent(GenericEvent):
|
|
|
139
137
|
|
|
140
138
|
_event_type = EventType.DEVICE_ERROR
|
|
141
139
|
|
|
142
|
-
async def event(self, value: Any, received_at: datetime
|
|
140
|
+
async def event(self, value: Any, received_at: datetime) -> None:
|
|
143
141
|
"""Handle event for which this handler has subscribed."""
|
|
144
|
-
if received_at is None:
|
|
145
|
-
received_at = datetime.now()
|
|
146
|
-
|
|
147
142
|
old_value, new_value = self.write_value(value=value, write_at=received_at)
|
|
148
143
|
|
|
149
144
|
if (
|
|
@@ -164,7 +159,7 @@ class ImpulseEvent(GenericEvent):
|
|
|
164
159
|
_event_type = EventType.IMPULSE
|
|
165
160
|
|
|
166
161
|
|
|
167
|
-
@inspector
|
|
162
|
+
@inspector
|
|
168
163
|
def create_event_and_append_to_channel(channel: hmd.Channel, parameter: str, parameter_data: ParameterData) -> None:
|
|
169
164
|
"""Create action event data_point."""
|
|
170
165
|
_LOGGER.debug(
|
|
@@ -7,8 +7,8 @@ from __future__ import annotations
|
|
|
7
7
|
from typing import cast
|
|
8
8
|
|
|
9
9
|
from aiohomematic.const import DataPointCategory
|
|
10
|
-
from aiohomematic.model.decorators import state_property
|
|
11
10
|
from aiohomematic.model.generic.data_point import GenericDataPoint
|
|
11
|
+
from aiohomematic.property_decorators import state_property
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class DpBinarySensor(GenericDataPoint[bool | None, bool]):
|
|
@@ -20,8 +20,8 @@ from aiohomematic.const import (
|
|
|
20
20
|
from aiohomematic.decorators import inspector
|
|
21
21
|
from aiohomematic.exceptions import ValidationException
|
|
22
22
|
from aiohomematic.model import data_point as hme, device as hmd
|
|
23
|
-
from aiohomematic.model.decorators import cached_slot_property
|
|
24
23
|
from aiohomematic.model.support import DataPointNameData, GenericParameterType, get_data_point_name_data
|
|
24
|
+
from aiohomematic.property_decorators import cached_property
|
|
25
25
|
|
|
26
26
|
_LOGGER: Final = logging.getLogger(__name__)
|
|
27
27
|
|
|
@@ -51,7 +51,7 @@ class GenericDataPoint[ParameterT: GenericParameterType, InputParameterT: Generi
|
|
|
51
51
|
parameter_data=parameter_data,
|
|
52
52
|
)
|
|
53
53
|
|
|
54
|
-
@
|
|
54
|
+
@cached_property
|
|
55
55
|
def usage(self) -> DataPointUsage:
|
|
56
56
|
"""Return the data_point usage."""
|
|
57
57
|
if self._is_forced_sensor or self._is_un_ignored:
|
|
@@ -60,10 +60,8 @@ class GenericDataPoint[ParameterT: GenericParameterType, InputParameterT: Generi
|
|
|
60
60
|
return self._get_data_point_usage()
|
|
61
61
|
return DataPointUsage.DATA_POINT if force_enabled else DataPointUsage.NO_CREATE # pylint: disable=using-constant-test
|
|
62
62
|
|
|
63
|
-
async def event(self, value: Any, received_at: datetime
|
|
63
|
+
async def event(self, value: Any, received_at: datetime) -> None:
|
|
64
64
|
"""Handle event for which this data_point has subscribed."""
|
|
65
|
-
if received_at is None:
|
|
66
|
-
received_at = datetime.now()
|
|
67
65
|
self._device.client.last_value_send_cache.remove_last_value_send(
|
|
68
66
|
dpk=self.dpk,
|
|
69
67
|
value=value,
|
|
@@ -90,7 +88,7 @@ class GenericDataPoint[ParameterT: GenericParameterType, InputParameterT: Generi
|
|
|
90
88
|
event_data=self.get_event_data(new_value),
|
|
91
89
|
)
|
|
92
90
|
|
|
93
|
-
@inspector
|
|
91
|
+
@inspector
|
|
94
92
|
async def send_value(
|
|
95
93
|
self,
|
|
96
94
|
value: InputParameterT,
|
|
@@ -8,8 +8,8 @@ from typing import cast
|
|
|
8
8
|
|
|
9
9
|
from aiohomematic.const import DataPointCategory
|
|
10
10
|
from aiohomematic.exceptions import ValidationException
|
|
11
|
-
from aiohomematic.model.decorators import state_property
|
|
12
11
|
from aiohomematic.model.generic.data_point import GenericDataPoint
|
|
12
|
+
from aiohomematic.property_decorators import state_property
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class BaseDpNumber[NumberParameterT: int | float | None](GenericDataPoint[NumberParameterT, int | float | str]):
|
|
@@ -6,9 +6,9 @@ from __future__ import annotations
|
|
|
6
6
|
|
|
7
7
|
from aiohomematic.const import DataPointCategory
|
|
8
8
|
from aiohomematic.exceptions import ValidationException
|
|
9
|
-
from aiohomematic.model.decorators import state_property
|
|
10
9
|
from aiohomematic.model.generic.data_point import GenericDataPoint
|
|
11
10
|
from aiohomematic.model.support import get_value_from_value_list
|
|
11
|
+
from aiohomematic.property_decorators import state_property
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class DpSelect(GenericDataPoint[int | str, int | float | str]):
|
|
@@ -9,9 +9,9 @@ import logging
|
|
|
9
9
|
from typing import Any, Final, cast
|
|
10
10
|
|
|
11
11
|
from aiohomematic.const import DataPointCategory, Parameter, ParameterType
|
|
12
|
-
from aiohomematic.model.decorators import state_property
|
|
13
12
|
from aiohomematic.model.generic.data_point import GenericDataPoint
|
|
14
13
|
from aiohomematic.model.support import check_length_and_log, get_value_from_value_list
|
|
14
|
+
from aiohomematic.property_decorators import state_property
|
|
15
15
|
|
|
16
16
|
_LOGGER: Final = logging.getLogger(__name__)
|
|
17
17
|
|
|
@@ -9,8 +9,8 @@ from typing import cast
|
|
|
9
9
|
from aiohomematic.const import DataPointCategory, Parameter, ParameterType
|
|
10
10
|
from aiohomematic.decorators import inspector
|
|
11
11
|
from aiohomematic.model.data_point import CallParameterCollector
|
|
12
|
-
from aiohomematic.model.decorators import state_property
|
|
13
12
|
from aiohomematic.model.generic.data_point import GenericDataPoint
|
|
13
|
+
from aiohomematic.property_decorators import state_property
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class DpSwitch(GenericDataPoint[bool | None, bool]):
|
|
@@ -31,19 +31,19 @@ class DpSwitch(GenericDataPoint[bool | None, bool]):
|
|
|
31
31
|
return False
|
|
32
32
|
return cast(bool | None, self._value)
|
|
33
33
|
|
|
34
|
-
@inspector
|
|
34
|
+
@inspector
|
|
35
35
|
async def turn_on(self, collector: CallParameterCollector | None = None, on_time: float | None = None) -> None:
|
|
36
36
|
"""Turn the switch on."""
|
|
37
37
|
if on_time is not None:
|
|
38
38
|
await self.set_on_time(on_time=on_time)
|
|
39
39
|
await self.send_value(value=True, collector=collector)
|
|
40
40
|
|
|
41
|
-
@inspector
|
|
41
|
+
@inspector
|
|
42
42
|
async def turn_off(self, collector: CallParameterCollector | None = None) -> None:
|
|
43
43
|
"""Turn the switch off."""
|
|
44
44
|
await self.send_value(value=False, collector=collector)
|
|
45
45
|
|
|
46
|
-
@inspector
|
|
46
|
+
@inspector
|
|
47
47
|
async def set_on_time(self, on_time: float) -> None:
|
|
48
48
|
"""Set the on time value in seconds."""
|
|
49
49
|
await self._client.set_value(
|
|
@@ -7,9 +7,9 @@ from __future__ import annotations
|
|
|
7
7
|
from typing import cast
|
|
8
8
|
|
|
9
9
|
from aiohomematic.const import DataPointCategory
|
|
10
|
-
from aiohomematic.model.decorators import state_property
|
|
11
10
|
from aiohomematic.model.generic.data_point import GenericDataPoint
|
|
12
11
|
from aiohomematic.model.support import check_length_and_log
|
|
12
|
+
from aiohomematic.property_decorators import state_property
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class DpText(GenericDataPoint[str, str]):
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
7
7
|
from aiohomematic.const import DataPointCategory
|
|
8
|
-
from aiohomematic.model.decorators import state_property
|
|
9
8
|
from aiohomematic.model.hub.data_point import GenericSysvarDataPoint
|
|
9
|
+
from aiohomematic.property_decorators import state_property
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class SysvarDpBinarySensor(GenericSysvarDataPoint):
|
aiohomematic/model/hub/button.py
CHANGED
|
@@ -6,8 +6,8 @@ from __future__ import annotations
|
|
|
6
6
|
|
|
7
7
|
from aiohomematic.const import DataPointCategory
|
|
8
8
|
from aiohomematic.decorators import inspector
|
|
9
|
-
from aiohomematic.model.decorators import state_property
|
|
10
9
|
from aiohomematic.model.hub.data_point import GenericProgramDataPoint
|
|
10
|
+
from aiohomematic.property_decorators import state_property
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class ProgramDpButton(GenericProgramDataPoint):
|
|
@@ -22,7 +22,7 @@ class ProgramDpButton(GenericProgramDataPoint):
|
|
|
22
22
|
"""Return the availability of the device."""
|
|
23
23
|
return self._is_active and self._central.available
|
|
24
24
|
|
|
25
|
-
@inspector
|
|
25
|
+
@inspector
|
|
26
26
|
async def press(self) -> None:
|
|
27
27
|
"""Handle the button press."""
|
|
28
28
|
await self.central.execute_program(pid=self.pid)
|
|
@@ -21,17 +21,16 @@ from aiohomematic.const import (
|
|
|
21
21
|
)
|
|
22
22
|
from aiohomematic.decorators import inspector
|
|
23
23
|
from aiohomematic.model.data_point import CallbackDataPoint
|
|
24
|
-
from aiohomematic.model.decorators import config_property, state_property
|
|
25
24
|
from aiohomematic.model.device import Channel
|
|
26
25
|
from aiohomematic.model.support import (
|
|
27
26
|
PathData,
|
|
28
|
-
PayloadMixin,
|
|
29
27
|
ProgramPathData,
|
|
30
28
|
SysvarPathData,
|
|
31
29
|
generate_unique_id,
|
|
32
30
|
get_hub_data_point_name_data,
|
|
33
31
|
)
|
|
34
|
-
from aiohomematic.
|
|
32
|
+
from aiohomematic.property_decorators import config_property, state_property
|
|
33
|
+
from aiohomematic.support import PayloadMixin, parse_sys_var
|
|
35
34
|
|
|
36
35
|
|
|
37
36
|
class GenericHubDataPoint(CallbackDataPoint, PayloadMixin):
|
|
@@ -207,10 +206,8 @@ class GenericSysvarDataPoint(GenericHubDataPoint):
|
|
|
207
206
|
"""Return the path data of the data_point."""
|
|
208
207
|
return SysvarPathData(vid=self._vid)
|
|
209
208
|
|
|
210
|
-
async def event(self, value: Any, received_at: datetime
|
|
209
|
+
async def event(self, value: Any, received_at: datetime) -> None:
|
|
211
210
|
"""Handle event for which this data_point has subscribed."""
|
|
212
|
-
if received_at is None:
|
|
213
|
-
received_at = datetime.now()
|
|
214
211
|
self.write_value(value=value, write_at=received_at)
|
|
215
212
|
|
|
216
213
|
def _reset_temporary_value(self) -> None:
|
|
@@ -263,7 +260,7 @@ class GenericSysvarDataPoint(GenericHubDataPoint):
|
|
|
263
260
|
value = float(new_value)
|
|
264
261
|
return value
|
|
265
262
|
|
|
266
|
-
@inspector
|
|
263
|
+
@inspector
|
|
267
264
|
async def send_variable(self, value: Any) -> None:
|
|
268
265
|
"""Set variable value on CCU/Homegear."""
|
|
269
266
|
if client := self.central.primary_client:
|
aiohomematic/model/hub/number.py
CHANGED
|
@@ -22,7 +22,7 @@ class SysvarDpNumber(GenericSysvarDataPoint):
|
|
|
22
22
|
_category = DataPointCategory.HUB_NUMBER
|
|
23
23
|
_is_extended = True
|
|
24
24
|
|
|
25
|
-
@inspector
|
|
25
|
+
@inspector
|
|
26
26
|
async def send_variable(self, value: float) -> None:
|
|
27
27
|
"""Set the value of the data_point."""
|
|
28
28
|
if value is not None and self.max is not None and self.min is not None:
|
aiohomematic/model/hub/select.py
CHANGED
|
@@ -9,9 +9,9 @@ from typing import Final
|
|
|
9
9
|
|
|
10
10
|
from aiohomematic.const import DataPointCategory
|
|
11
11
|
from aiohomematic.decorators import inspector
|
|
12
|
-
from aiohomematic.model.decorators import state_property
|
|
13
12
|
from aiohomematic.model.hub.data_point import GenericSysvarDataPoint
|
|
14
13
|
from aiohomematic.model.support import get_value_from_value_list
|
|
14
|
+
from aiohomematic.property_decorators import state_property
|
|
15
15
|
|
|
16
16
|
_LOGGER: Final = logging.getLogger(__name__)
|
|
17
17
|
|
|
@@ -31,7 +31,7 @@ class SysvarDpSelect(GenericSysvarDataPoint):
|
|
|
31
31
|
return value
|
|
32
32
|
return None
|
|
33
33
|
|
|
34
|
-
@inspector
|
|
34
|
+
@inspector
|
|
35
35
|
async def send_variable(self, value: int | str) -> None:
|
|
36
36
|
"""Set the value of the data_point."""
|
|
37
37
|
# We allow setting the value via index as well, just in case.
|
aiohomematic/model/hub/sensor.py
CHANGED
|
@@ -8,9 +8,9 @@ import logging
|
|
|
8
8
|
from typing import Any, Final
|
|
9
9
|
|
|
10
10
|
from aiohomematic.const import DataPointCategory, SysvarType
|
|
11
|
-
from aiohomematic.model.decorators import state_property
|
|
12
11
|
from aiohomematic.model.hub.data_point import GenericSysvarDataPoint
|
|
13
12
|
from aiohomematic.model.support import check_length_and_log, get_value_from_value_list
|
|
13
|
+
from aiohomematic.property_decorators import state_property
|
|
14
14
|
|
|
15
15
|
_LOGGER: Final = logging.getLogger(__name__)
|
|
16
16
|
|
aiohomematic/model/hub/switch.py
CHANGED
|
@@ -6,8 +6,8 @@ from __future__ import annotations
|
|
|
6
6
|
|
|
7
7
|
from aiohomematic.const import DataPointCategory
|
|
8
8
|
from aiohomematic.decorators import inspector
|
|
9
|
-
from aiohomematic.model.decorators import state_property
|
|
10
9
|
from aiohomematic.model.hub.data_point import GenericProgramDataPoint, GenericSysvarDataPoint
|
|
10
|
+
from aiohomematic.property_decorators import state_property
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class SysvarDpSwitch(GenericSysvarDataPoint):
|
|
@@ -31,13 +31,13 @@ class ProgramDpSwitch(GenericProgramDataPoint):
|
|
|
31
31
|
"""Get the value of the data_point."""
|
|
32
32
|
return self._is_active
|
|
33
33
|
|
|
34
|
-
@inspector
|
|
34
|
+
@inspector
|
|
35
35
|
async def turn_on(self) -> None:
|
|
36
36
|
"""Turn the program on."""
|
|
37
37
|
await self.central.set_program_state(pid=self._pid, state=True)
|
|
38
38
|
await self._central.fetch_program_data(scheduled=False)
|
|
39
39
|
|
|
40
|
-
@inspector
|
|
40
|
+
@inspector
|
|
41
41
|
async def turn_off(self) -> None:
|
|
42
42
|
"""Turn the program off."""
|
|
43
43
|
await self.central.set_program_state(pid=self._pid, state=False)
|