aiohomematic 2025.10.0__py3-none-any.whl → 2025.10.2__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/async_support.py +7 -7
- aiohomematic/caches/dynamic.py +31 -26
- aiohomematic/caches/persistent.py +34 -32
- aiohomematic/caches/visibility.py +19 -7
- aiohomematic/central/__init__.py +90 -74
- aiohomematic/central/decorators.py +2 -2
- aiohomematic/central/xml_rpc_server.py +27 -24
- aiohomematic/client/__init__.py +72 -56
- aiohomematic/client/_rpc_errors.py +3 -3
- aiohomematic/client/json_rpc.py +33 -25
- aiohomematic/client/xml_rpc.py +14 -9
- aiohomematic/const.py +3 -1
- aiohomematic/converter.py +19 -19
- aiohomematic/exceptions.py +2 -1
- aiohomematic/model/__init__.py +4 -3
- aiohomematic/model/calculated/__init__.py +1 -1
- aiohomematic/model/calculated/climate.py +9 -9
- aiohomematic/model/calculated/data_point.py +13 -7
- aiohomematic/model/calculated/operating_voltage_level.py +2 -2
- aiohomematic/model/calculated/support.py +7 -7
- aiohomematic/model/custom/__init__.py +3 -3
- aiohomematic/model/custom/climate.py +57 -34
- aiohomematic/model/custom/cover.py +44 -20
- aiohomematic/model/custom/data_point.py +9 -7
- aiohomematic/model/custom/definition.py +23 -17
- aiohomematic/model/custom/light.py +52 -23
- aiohomematic/model/custom/lock.py +16 -12
- aiohomematic/model/custom/siren.py +6 -3
- aiohomematic/model/custom/switch.py +3 -2
- aiohomematic/model/custom/valve.py +3 -2
- aiohomematic/model/data_point.py +62 -49
- aiohomematic/model/device.py +48 -42
- aiohomematic/model/event.py +6 -5
- aiohomematic/model/generic/__init__.py +6 -4
- aiohomematic/model/generic/action.py +1 -1
- aiohomematic/model/generic/data_point.py +7 -5
- aiohomematic/model/generic/number.py +3 -3
- aiohomematic/model/generic/select.py +1 -1
- aiohomematic/model/generic/sensor.py +2 -2
- aiohomematic/model/generic/switch.py +3 -3
- aiohomematic/model/hub/__init__.py +17 -16
- aiohomematic/model/hub/data_point.py +12 -7
- aiohomematic/model/hub/number.py +3 -3
- aiohomematic/model/hub/select.py +3 -3
- aiohomematic/model/hub/text.py +2 -2
- aiohomematic/model/support.py +8 -7
- aiohomematic/model/update.py +6 -6
- aiohomematic/support.py +44 -38
- aiohomematic/validator.py +6 -6
- {aiohomematic-2025.10.0.dist-info → aiohomematic-2025.10.2.dist-info}/METADATA +1 -1
- aiohomematic-2025.10.2.dist-info/RECORD +78 -0
- aiohomematic_support/client_local.py +19 -12
- aiohomematic-2025.10.0.dist-info/RECORD +0 -78
- {aiohomematic-2025.10.0.dist-info → aiohomematic-2025.10.2.dist-info}/WHEEL +0 -0
- {aiohomematic-2025.10.0.dist-info → aiohomematic-2025.10.2.dist-info}/licenses/LICENSE +0 -0
- {aiohomematic-2025.10.0.dist-info → aiohomematic-2025.10.2.dist-info}/top_level.txt +0 -0
aiohomematic/client/__init__.py
CHANGED
|
@@ -129,7 +129,7 @@ _CCU_JSON_VALUE_TYPE: Final = {
|
|
|
129
129
|
class Client(ABC, LogContextMixin):
|
|
130
130
|
"""Client object to access the backends via XML-RPC or JSON-RPC."""
|
|
131
131
|
|
|
132
|
-
def __init__(self, client_config: _ClientConfig) -> None:
|
|
132
|
+
def __init__(self, *, client_config: _ClientConfig) -> None:
|
|
133
133
|
"""Initialize the Client."""
|
|
134
134
|
self._config: Final = client_config
|
|
135
135
|
self._supports_xml_rpc = self.interface in INTERFACES_SUPPORTING_XML_RPC
|
|
@@ -211,7 +211,7 @@ class Client(ABC, LogContextMixin):
|
|
|
211
211
|
"""Return the version id of the client."""
|
|
212
212
|
return self._config.version
|
|
213
213
|
|
|
214
|
-
def get_product_group(self, model: str) -> ProductGroup:
|
|
214
|
+
def get_product_group(self, *, model: str) -> ProductGroup:
|
|
215
215
|
"""Return the product group."""
|
|
216
216
|
l_model = model.lower()
|
|
217
217
|
if l_model.startswith("hmipw-"):
|
|
@@ -309,7 +309,7 @@ class Client(ABC, LogContextMixin):
|
|
|
309
309
|
return await self.initialize_proxy()
|
|
310
310
|
return ProxyInitState.DE_INIT_FAILED
|
|
311
311
|
|
|
312
|
-
def _mark_all_devices_forced_availability(self, forced_availability: ForcedDeviceAvailability) -> None:
|
|
312
|
+
def _mark_all_devices_forced_availability(self, *, forced_availability: ForcedDeviceAvailability) -> None:
|
|
313
313
|
"""Mark device's availability state for this interface."""
|
|
314
314
|
available = forced_availability != ForcedDeviceAvailability.FORCE_FALSE
|
|
315
315
|
if self._available != available:
|
|
@@ -419,44 +419,44 @@ class Client(ABC, LogContextMixin):
|
|
|
419
419
|
|
|
420
420
|
@abstractmethod
|
|
421
421
|
@inspector(re_raise=False, no_raise_return=False)
|
|
422
|
-
async def check_connection_availability(self, handle_ping_pong: bool) -> bool:
|
|
422
|
+
async def check_connection_availability(self, *, handle_ping_pong: bool) -> bool:
|
|
423
423
|
"""Send ping to the backend to generate PONG event."""
|
|
424
424
|
|
|
425
425
|
@abstractmethod
|
|
426
426
|
@inspector
|
|
427
|
-
async def execute_program(self, pid: str) -> bool:
|
|
427
|
+
async def execute_program(self, *, pid: str) -> bool:
|
|
428
428
|
"""Execute a program on the backend."""
|
|
429
429
|
|
|
430
430
|
@abstractmethod
|
|
431
431
|
@inspector
|
|
432
|
-
async def set_program_state(self, pid: str, state: bool) -> bool:
|
|
432
|
+
async def set_program_state(self, *, pid: str, state: bool) -> bool:
|
|
433
433
|
"""Set the program state on the backend."""
|
|
434
434
|
|
|
435
435
|
@abstractmethod
|
|
436
436
|
@inspector(measure_performance=True)
|
|
437
|
-
async def set_system_variable(self, legacy_name: str, value: Any) -> bool:
|
|
437
|
+
async def set_system_variable(self, *, legacy_name: str, value: Any) -> bool:
|
|
438
438
|
"""Set a system variable on the backend."""
|
|
439
439
|
|
|
440
440
|
@abstractmethod
|
|
441
441
|
@inspector
|
|
442
|
-
async def delete_system_variable(self, name: str) -> bool:
|
|
442
|
+
async def delete_system_variable(self, *, name: str) -> bool:
|
|
443
443
|
"""Delete a system variable from the backend."""
|
|
444
444
|
|
|
445
445
|
@abstractmethod
|
|
446
446
|
@inspector
|
|
447
|
-
async def get_system_variable(self, name: str) -> Any:
|
|
447
|
+
async def get_system_variable(self, *, name: str) -> Any:
|
|
448
448
|
"""Get single system variable from the backend."""
|
|
449
449
|
|
|
450
450
|
@abstractmethod
|
|
451
451
|
@inspector(re_raise=False)
|
|
452
452
|
async def get_all_system_variables(
|
|
453
|
-
self, markers: tuple[DescriptionMarker | str, ...]
|
|
453
|
+
self, *, markers: tuple[DescriptionMarker | str, ...]
|
|
454
454
|
) -> tuple[SystemVariableData, ...] | None:
|
|
455
455
|
"""Get all system variables from the backend."""
|
|
456
456
|
|
|
457
457
|
@abstractmethod
|
|
458
458
|
@inspector(re_raise=False)
|
|
459
|
-
async def get_all_programs(self, markers: tuple[DescriptionMarker | str, ...]) -> tuple[ProgramData, ...] | None:
|
|
459
|
+
async def get_all_programs(self, *, markers: tuple[DescriptionMarker | str, ...]) -> tuple[ProgramData, ...] | None:
|
|
460
460
|
"""Get all programs, if available."""
|
|
461
461
|
|
|
462
462
|
@abstractmethod
|
|
@@ -482,7 +482,7 @@ class Client(ABC, LogContextMixin):
|
|
|
482
482
|
return None
|
|
483
483
|
|
|
484
484
|
@inspector(re_raise=False)
|
|
485
|
-
async def get_device_description(self, device_address: str) -> DeviceDescription | None:
|
|
485
|
+
async def get_device_description(self, *, device_address: str) -> DeviceDescription | None:
|
|
486
486
|
"""Get device descriptions from the backend."""
|
|
487
487
|
try:
|
|
488
488
|
if device_description := cast(
|
|
@@ -495,7 +495,7 @@ class Client(ABC, LogContextMixin):
|
|
|
495
495
|
return None
|
|
496
496
|
|
|
497
497
|
@inspector
|
|
498
|
-
async def add_link(self, sender_address: str, receiver_address: str, name: str, description: str) -> None:
|
|
498
|
+
async def add_link(self, *, sender_address: str, receiver_address: str, name: str, description: str) -> None:
|
|
499
499
|
"""Return a list of links."""
|
|
500
500
|
try:
|
|
501
501
|
await self._proxy.addLink(sender_address, receiver_address, name, description)
|
|
@@ -505,7 +505,7 @@ class Client(ABC, LogContextMixin):
|
|
|
505
505
|
) from bhexc
|
|
506
506
|
|
|
507
507
|
@inspector
|
|
508
|
-
async def remove_link(self, sender_address: str, receiver_address: str) -> None:
|
|
508
|
+
async def remove_link(self, *, sender_address: str, receiver_address: str) -> None:
|
|
509
509
|
"""Return a list of links."""
|
|
510
510
|
try:
|
|
511
511
|
await self._proxy.removeLink(sender_address, receiver_address)
|
|
@@ -515,7 +515,7 @@ class Client(ABC, LogContextMixin):
|
|
|
515
515
|
) from bhexc
|
|
516
516
|
|
|
517
517
|
@inspector
|
|
518
|
-
async def get_link_peers(self, address: str) -> tuple[str, ...] | None:
|
|
518
|
+
async def get_link_peers(self, *, address: str) -> tuple[str, ...] | None:
|
|
519
519
|
"""Return a list of link pers."""
|
|
520
520
|
try:
|
|
521
521
|
return tuple(await self._proxy.getLinkPeers(address))
|
|
@@ -525,7 +525,7 @@ class Client(ABC, LogContextMixin):
|
|
|
525
525
|
) from bhexc
|
|
526
526
|
|
|
527
527
|
@inspector
|
|
528
|
-
async def get_links(self, address: str, flags: int) -> dict[str, Any]:
|
|
528
|
+
async def get_links(self, *, address: str, flags: int) -> dict[str, Any]:
|
|
529
529
|
"""Return a list of links."""
|
|
530
530
|
try:
|
|
531
531
|
return cast(dict[str, Any], await self._proxy.getLinks(address, flags))
|
|
@@ -533,7 +533,7 @@ class Client(ABC, LogContextMixin):
|
|
|
533
533
|
raise ClientException(f"GET_LINKS failed with for: {address}: {extract_exc_args(exc=bhexc)}") from bhexc
|
|
534
534
|
|
|
535
535
|
@inspector
|
|
536
|
-
async def get_metadata(self, address: str, data_id: str) -> dict[str, Any]:
|
|
536
|
+
async def get_metadata(self, *, address: str, data_id: str) -> dict[str, Any]:
|
|
537
537
|
"""Return the metadata for an object."""
|
|
538
538
|
try:
|
|
539
539
|
return cast(dict[str, Any], await self._proxy.getMetadata(address, data_id))
|
|
@@ -543,7 +543,7 @@ class Client(ABC, LogContextMixin):
|
|
|
543
543
|
) from bhexc
|
|
544
544
|
|
|
545
545
|
@inspector
|
|
546
|
-
async def set_metadata(self, address: str, data_id: str, value: dict[str, Any]) -> dict[str, Any]:
|
|
546
|
+
async def set_metadata(self, *, address: str, data_id: str, value: dict[str, Any]) -> dict[str, Any]:
|
|
547
547
|
"""Write the metadata for an object."""
|
|
548
548
|
try:
|
|
549
549
|
return cast(dict[str, Any], await self._proxy.setMetadata(address, data_id, value))
|
|
@@ -555,6 +555,7 @@ class Client(ABC, LogContextMixin):
|
|
|
555
555
|
@inspector(log_level=logging.NOTSET)
|
|
556
556
|
async def get_value(
|
|
557
557
|
self,
|
|
558
|
+
*,
|
|
558
559
|
channel_address: str,
|
|
559
560
|
paramset_key: ParamsetKey,
|
|
560
561
|
parameter: str,
|
|
@@ -581,6 +582,7 @@ class Client(ABC, LogContextMixin):
|
|
|
581
582
|
@inspector(measure_performance=True)
|
|
582
583
|
async def _set_value(
|
|
583
584
|
self,
|
|
585
|
+
*,
|
|
584
586
|
channel_address: str,
|
|
585
587
|
parameter: str,
|
|
586
588
|
value: Any,
|
|
@@ -636,6 +638,7 @@ class Client(ABC, LogContextMixin):
|
|
|
636
638
|
|
|
637
639
|
async def _exec_set_value(
|
|
638
640
|
self,
|
|
641
|
+
*,
|
|
639
642
|
channel_address: str,
|
|
640
643
|
parameter: str,
|
|
641
644
|
value: Any,
|
|
@@ -647,7 +650,7 @@ class Client(ABC, LogContextMixin):
|
|
|
647
650
|
else:
|
|
648
651
|
await self._proxy.setValue(channel_address, parameter, value)
|
|
649
652
|
|
|
650
|
-
def _check_set_value(self, channel_address: str, paramset_key: ParamsetKey, parameter: str, value: Any) -> Any:
|
|
653
|
+
def _check_set_value(self, *, channel_address: str, paramset_key: ParamsetKey, parameter: str, value: Any) -> Any:
|
|
651
654
|
"""Check set_value."""
|
|
652
655
|
return self._convert_value(
|
|
653
656
|
channel_address=channel_address,
|
|
@@ -657,7 +660,7 @@ class Client(ABC, LogContextMixin):
|
|
|
657
660
|
operation=Operations.WRITE,
|
|
658
661
|
)
|
|
659
662
|
|
|
660
|
-
def _write_temporary_value(self, dpk_values: set[DP_KEY_VALUE]) -> None:
|
|
663
|
+
def _write_temporary_value(self, *, dpk_values: set[DP_KEY_VALUE]) -> None:
|
|
661
664
|
"""Write data point temp value."""
|
|
662
665
|
for dpk, value in dpk_values:
|
|
663
666
|
if (
|
|
@@ -672,6 +675,7 @@ class Client(ABC, LogContextMixin):
|
|
|
672
675
|
@inspector(re_raise=False, no_raise_return=set())
|
|
673
676
|
async def set_value(
|
|
674
677
|
self,
|
|
678
|
+
*,
|
|
675
679
|
channel_address: str,
|
|
676
680
|
paramset_key: ParamsetKey,
|
|
677
681
|
parameter: str,
|
|
@@ -702,6 +706,7 @@ class Client(ABC, LogContextMixin):
|
|
|
702
706
|
@inspector
|
|
703
707
|
async def get_paramset(
|
|
704
708
|
self,
|
|
709
|
+
*,
|
|
705
710
|
address: str,
|
|
706
711
|
paramset_key: ParamsetKey | str,
|
|
707
712
|
call_source: CallSource = CallSource.MANUAL_OR_SCHEDULED,
|
|
@@ -728,6 +733,7 @@ class Client(ABC, LogContextMixin):
|
|
|
728
733
|
@inspector(measure_performance=True)
|
|
729
734
|
async def put_paramset(
|
|
730
735
|
self,
|
|
736
|
+
*,
|
|
731
737
|
channel_address: str,
|
|
732
738
|
paramset_key_or_link_address: ParamsetKey | str,
|
|
733
739
|
values: dict[str, Any],
|
|
@@ -830,6 +836,7 @@ class Client(ABC, LogContextMixin):
|
|
|
830
836
|
|
|
831
837
|
async def _exec_put_paramset(
|
|
832
838
|
self,
|
|
839
|
+
*,
|
|
833
840
|
channel_address: str,
|
|
834
841
|
paramset_key: ParamsetKey | str,
|
|
835
842
|
values: dict[str, Any],
|
|
@@ -842,7 +849,7 @@ class Client(ABC, LogContextMixin):
|
|
|
842
849
|
await self._proxy.putParamset(channel_address, paramset_key, values)
|
|
843
850
|
|
|
844
851
|
def _check_put_paramset(
|
|
845
|
-
self, channel_address: str, paramset_key: ParamsetKey, values: dict[str, Any]
|
|
852
|
+
self, *, channel_address: str, paramset_key: ParamsetKey, values: dict[str, Any]
|
|
846
853
|
) -> dict[str, Any]:
|
|
847
854
|
"""Check put_paramset."""
|
|
848
855
|
checked_values: dict[str, Any] = {}
|
|
@@ -858,6 +865,7 @@ class Client(ABC, LogContextMixin):
|
|
|
858
865
|
|
|
859
866
|
def _convert_value(
|
|
860
867
|
self,
|
|
868
|
+
*,
|
|
861
869
|
channel_address: str,
|
|
862
870
|
paramset_key: ParamsetKey,
|
|
863
871
|
parameter: str,
|
|
@@ -886,6 +894,7 @@ class Client(ABC, LogContextMixin):
|
|
|
886
894
|
|
|
887
895
|
def _get_parameter_type(
|
|
888
896
|
self,
|
|
897
|
+
*,
|
|
889
898
|
channel_address: str,
|
|
890
899
|
paramset_key: ParamsetKey,
|
|
891
900
|
parameter: str,
|
|
@@ -900,7 +909,7 @@ class Client(ABC, LogContextMixin):
|
|
|
900
909
|
return None
|
|
901
910
|
|
|
902
911
|
@inspector(re_raise=False)
|
|
903
|
-
async def fetch_paramset_description(self, channel_address: str, paramset_key: ParamsetKey) -> None:
|
|
912
|
+
async def fetch_paramset_description(self, *, channel_address: str, paramset_key: ParamsetKey) -> None:
|
|
904
913
|
"""Fetch a specific paramset and add it to the known ones."""
|
|
905
914
|
_LOGGER.debug("FETCH_PARAMSET_DESCRIPTION: %s for %s", paramset_key, channel_address)
|
|
906
915
|
|
|
@@ -915,7 +924,7 @@ class Client(ABC, LogContextMixin):
|
|
|
915
924
|
)
|
|
916
925
|
|
|
917
926
|
@inspector(re_raise=False)
|
|
918
|
-
async def fetch_paramset_descriptions(self, device_description: DeviceDescription) -> None:
|
|
927
|
+
async def fetch_paramset_descriptions(self, *, device_description: DeviceDescription) -> None:
|
|
919
928
|
"""Fetch paramsets for provided device description."""
|
|
920
929
|
data = await self.get_paramset_descriptions(device_description=device_description)
|
|
921
930
|
for address, paramsets in data.items():
|
|
@@ -930,7 +939,7 @@ class Client(ABC, LogContextMixin):
|
|
|
930
939
|
|
|
931
940
|
@inspector(re_raise=False, no_raise_return={})
|
|
932
941
|
async def get_paramset_descriptions(
|
|
933
|
-
self, device_description: DeviceDescription
|
|
942
|
+
self, *, device_description: DeviceDescription
|
|
934
943
|
) -> dict[str, dict[ParamsetKey, dict[str, ParameterData]]]:
|
|
935
944
|
"""Get paramsets for provided device description."""
|
|
936
945
|
paramsets: dict[str, dict[ParamsetKey, dict[str, ParameterData]]] = {}
|
|
@@ -944,7 +953,7 @@ class Client(ABC, LogContextMixin):
|
|
|
944
953
|
return paramsets
|
|
945
954
|
|
|
946
955
|
async def _get_paramset_description(
|
|
947
|
-
self, address: str, paramset_key: ParamsetKey
|
|
956
|
+
self, *, address: str, paramset_key: ParamsetKey
|
|
948
957
|
) -> dict[str, ParameterData] | None:
|
|
949
958
|
"""Get paramset description from the backend."""
|
|
950
959
|
try:
|
|
@@ -964,7 +973,7 @@ class Client(ABC, LogContextMixin):
|
|
|
964
973
|
|
|
965
974
|
@inspector
|
|
966
975
|
async def get_all_paramset_descriptions(
|
|
967
|
-
self, device_descriptions: tuple[DeviceDescription, ...]
|
|
976
|
+
self, *, device_descriptions: tuple[DeviceDescription, ...]
|
|
968
977
|
) -> dict[str, dict[ParamsetKey, dict[str, ParameterData]]]:
|
|
969
978
|
"""Get all paramset descriptions for provided device descriptions."""
|
|
970
979
|
all_paramsets: dict[str, dict[ParamsetKey, dict[str, ParameterData]]] = {}
|
|
@@ -973,7 +982,7 @@ class Client(ABC, LogContextMixin):
|
|
|
973
982
|
return all_paramsets
|
|
974
983
|
|
|
975
984
|
@inspector
|
|
976
|
-
async def has_program_ids(self, channel_hmid: str) -> bool:
|
|
985
|
+
async def has_program_ids(self, *, channel_hmid: str) -> bool:
|
|
977
986
|
"""Return if a channel has program ids."""
|
|
978
987
|
return False
|
|
979
988
|
|
|
@@ -991,12 +1000,12 @@ class Client(ABC, LogContextMixin):
|
|
|
991
1000
|
return None
|
|
992
1001
|
|
|
993
1002
|
@inspector
|
|
994
|
-
async def report_value_usage(self, address: str, value_id: str, ref_counter: int) -> bool:
|
|
1003
|
+
async def report_value_usage(self, *, address: str, value_id: str, ref_counter: int) -> bool:
|
|
995
1004
|
"""Report value usage."""
|
|
996
1005
|
return False
|
|
997
1006
|
|
|
998
1007
|
@inspector
|
|
999
|
-
async def update_device_firmware(self, device_address: str) -> bool:
|
|
1008
|
+
async def update_device_firmware(self, *, device_address: str) -> bool:
|
|
1000
1009
|
"""Update the firmware of a Homematic device."""
|
|
1001
1010
|
if device := self.central.get_device(address=device_address):
|
|
1002
1011
|
_LOGGER.info(
|
|
@@ -1021,7 +1030,7 @@ class Client(ABC, LogContextMixin):
|
|
|
1021
1030
|
return False
|
|
1022
1031
|
|
|
1023
1032
|
@inspector(re_raise=False)
|
|
1024
|
-
async def update_paramset_descriptions(self, device_address: str) -> None:
|
|
1033
|
+
async def update_paramset_descriptions(self, *, device_address: str) -> None:
|
|
1025
1034
|
"""Update paramsets descriptions for provided device_address."""
|
|
1026
1035
|
if not self.central.device_descriptions.get_device_descriptions(interface_id=self.interface_id):
|
|
1027
1036
|
_LOGGER.warning(
|
|
@@ -1052,7 +1061,7 @@ class Client(ABC, LogContextMixin):
|
|
|
1052
1061
|
class ClientCCU(Client):
|
|
1053
1062
|
"""Client implementation for CCU backend."""
|
|
1054
1063
|
|
|
1055
|
-
def __init__(self, client_config: _ClientConfig) -> None:
|
|
1064
|
+
def __init__(self, *, client_config: _ClientConfig) -> None:
|
|
1056
1065
|
"""Initialize the Client."""
|
|
1057
1066
|
self._json_rpc_client: Final = client_config.central.json_rpc_client
|
|
1058
1067
|
super().__init__(client_config=client_config)
|
|
@@ -1112,7 +1121,7 @@ class ClientCCU(Client):
|
|
|
1112
1121
|
)
|
|
1113
1122
|
|
|
1114
1123
|
@inspector(re_raise=False, no_raise_return=False)
|
|
1115
|
-
async def check_connection_availability(self, handle_ping_pong: bool) -> bool:
|
|
1124
|
+
async def check_connection_availability(self, *, handle_ping_pong: bool) -> bool:
|
|
1116
1125
|
"""Check if _proxy is still initialized."""
|
|
1117
1126
|
try:
|
|
1118
1127
|
dt_now = datetime.now()
|
|
@@ -1139,22 +1148,22 @@ class ClientCCU(Client):
|
|
|
1139
1148
|
return False
|
|
1140
1149
|
|
|
1141
1150
|
@inspector
|
|
1142
|
-
async def execute_program(self, pid: str) -> bool:
|
|
1151
|
+
async def execute_program(self, *, pid: str) -> bool:
|
|
1143
1152
|
"""Execute a program on the backend."""
|
|
1144
1153
|
return await self._json_rpc_client.execute_program(pid=pid)
|
|
1145
1154
|
|
|
1146
1155
|
@inspector
|
|
1147
|
-
async def set_program_state(self, pid: str, state: bool) -> bool:
|
|
1156
|
+
async def set_program_state(self, *, pid: str, state: bool) -> bool:
|
|
1148
1157
|
"""Set the program state on the backend."""
|
|
1149
1158
|
return await self._json_rpc_client.set_program_state(pid=pid, state=state)
|
|
1150
1159
|
|
|
1151
1160
|
@inspector
|
|
1152
|
-
async def has_program_ids(self, channel_hmid: str) -> bool:
|
|
1161
|
+
async def has_program_ids(self, *, channel_hmid: str) -> bool:
|
|
1153
1162
|
"""Return if a channel has program ids."""
|
|
1154
1163
|
return await self._json_rpc_client.has_program_ids(channel_hmid=channel_hmid)
|
|
1155
1164
|
|
|
1156
1165
|
@inspector
|
|
1157
|
-
async def report_value_usage(self, address: str, value_id: str, ref_counter: int) -> bool:
|
|
1166
|
+
async def report_value_usage(self, *, address: str, value_id: str, ref_counter: int) -> bool:
|
|
1158
1167
|
"""Report value usage."""
|
|
1159
1168
|
try:
|
|
1160
1169
|
return bool(await self._proxy.reportValueUsage(address, value_id, ref_counter))
|
|
@@ -1164,29 +1173,29 @@ class ClientCCU(Client):
|
|
|
1164
1173
|
) from bhexc
|
|
1165
1174
|
|
|
1166
1175
|
@inspector(measure_performance=True)
|
|
1167
|
-
async def set_system_variable(self, legacy_name: str, value: Any) -> bool:
|
|
1176
|
+
async def set_system_variable(self, *, legacy_name: str, value: Any) -> bool:
|
|
1168
1177
|
"""Set a system variable on the backend."""
|
|
1169
1178
|
return await self._json_rpc_client.set_system_variable(legacy_name=legacy_name, value=value)
|
|
1170
1179
|
|
|
1171
1180
|
@inspector
|
|
1172
|
-
async def delete_system_variable(self, name: str) -> bool:
|
|
1181
|
+
async def delete_system_variable(self, *, name: str) -> bool:
|
|
1173
1182
|
"""Delete a system variable from the backend."""
|
|
1174
1183
|
return await self._json_rpc_client.delete_system_variable(name=name)
|
|
1175
1184
|
|
|
1176
1185
|
@inspector
|
|
1177
|
-
async def get_system_variable(self, name: str) -> Any:
|
|
1186
|
+
async def get_system_variable(self, *, name: str) -> Any:
|
|
1178
1187
|
"""Get single system variable from the backend."""
|
|
1179
1188
|
return await self._json_rpc_client.get_system_variable(name=name)
|
|
1180
1189
|
|
|
1181
1190
|
@inspector(re_raise=False)
|
|
1182
1191
|
async def get_all_system_variables(
|
|
1183
|
-
self, markers: tuple[DescriptionMarker | str, ...]
|
|
1192
|
+
self, *, markers: tuple[DescriptionMarker | str, ...]
|
|
1184
1193
|
) -> tuple[SystemVariableData, ...] | None:
|
|
1185
1194
|
"""Get all system variables from the backend."""
|
|
1186
1195
|
return await self._json_rpc_client.get_all_system_variables(markers=markers)
|
|
1187
1196
|
|
|
1188
1197
|
@inspector(re_raise=False)
|
|
1189
|
-
async def get_all_programs(self, markers: tuple[DescriptionMarker | str, ...]) -> tuple[ProgramData, ...]:
|
|
1198
|
+
async def get_all_programs(self, *, markers: tuple[DescriptionMarker | str, ...]) -> tuple[ProgramData, ...]:
|
|
1190
1199
|
"""Get all programs, if available."""
|
|
1191
1200
|
return await self._json_rpc_client.get_all_programs(markers=markers)
|
|
1192
1201
|
|
|
@@ -1228,7 +1237,7 @@ class ClientJsonCCU(ClientCCU):
|
|
|
1228
1237
|
self._system_information = await self._get_system_information()
|
|
1229
1238
|
|
|
1230
1239
|
@inspector(re_raise=False, no_raise_return=False)
|
|
1231
|
-
async def check_connection_availability(self, handle_ping_pong: bool) -> bool:
|
|
1240
|
+
async def check_connection_availability(self, *, handle_ping_pong: bool) -> bool:
|
|
1232
1241
|
"""Check if proxy is still initialized."""
|
|
1233
1242
|
return await self._json_rpc_client.is_present(interface=self.interface)
|
|
1234
1243
|
|
|
@@ -1238,7 +1247,7 @@ class ClientJsonCCU(ClientCCU):
|
|
|
1238
1247
|
return False
|
|
1239
1248
|
|
|
1240
1249
|
@inspector(re_raise=False)
|
|
1241
|
-
async def get_device_description(self, device_address: str) -> DeviceDescription | None:
|
|
1250
|
+
async def get_device_description(self, *, device_address: str) -> DeviceDescription | None:
|
|
1242
1251
|
"""Get device descriptions from the backend."""
|
|
1243
1252
|
try:
|
|
1244
1253
|
if device_description := await self._json_rpc_client.get_device_description(
|
|
@@ -1252,6 +1261,7 @@ class ClientJsonCCU(ClientCCU):
|
|
|
1252
1261
|
@inspector
|
|
1253
1262
|
async def get_paramset(
|
|
1254
1263
|
self,
|
|
1264
|
+
*,
|
|
1255
1265
|
address: str,
|
|
1256
1266
|
paramset_key: ParamsetKey | str,
|
|
1257
1267
|
call_source: CallSource = CallSource.MANUAL_OR_SCHEDULED,
|
|
@@ -1283,6 +1293,7 @@ class ClientJsonCCU(ClientCCU):
|
|
|
1283
1293
|
@inspector(log_level=logging.NOTSET)
|
|
1284
1294
|
async def get_value(
|
|
1285
1295
|
self,
|
|
1296
|
+
*,
|
|
1286
1297
|
channel_address: str,
|
|
1287
1298
|
paramset_key: ParamsetKey,
|
|
1288
1299
|
parameter: str,
|
|
@@ -1332,7 +1343,7 @@ class ClientJsonCCU(ClientCCU):
|
|
|
1332
1343
|
return None
|
|
1333
1344
|
|
|
1334
1345
|
async def _get_paramset_description(
|
|
1335
|
-
self, address: str, paramset_key: ParamsetKey
|
|
1346
|
+
self, *, address: str, paramset_key: ParamsetKey
|
|
1336
1347
|
) -> dict[str, ParameterData] | None:
|
|
1337
1348
|
"""Get paramset description from the backend."""
|
|
1338
1349
|
try:
|
|
@@ -1354,6 +1365,7 @@ class ClientJsonCCU(ClientCCU):
|
|
|
1354
1365
|
|
|
1355
1366
|
async def _exec_put_paramset(
|
|
1356
1367
|
self,
|
|
1368
|
+
*,
|
|
1357
1369
|
channel_address: str,
|
|
1358
1370
|
paramset_key: ParamsetKey | str,
|
|
1359
1371
|
values: dict[str, Any],
|
|
@@ -1390,6 +1402,7 @@ class ClientJsonCCU(ClientCCU):
|
|
|
1390
1402
|
|
|
1391
1403
|
async def _exec_set_value(
|
|
1392
1404
|
self,
|
|
1405
|
+
*,
|
|
1393
1406
|
channel_address: str,
|
|
1394
1407
|
parameter: str,
|
|
1395
1408
|
value: Any,
|
|
@@ -1463,7 +1476,7 @@ class ClientHomegear(Client):
|
|
|
1463
1476
|
)
|
|
1464
1477
|
|
|
1465
1478
|
@inspector(re_raise=False, no_raise_return=False)
|
|
1466
|
-
async def check_connection_availability(self, handle_ping_pong: bool) -> bool:
|
|
1479
|
+
async def check_connection_availability(self, *, handle_ping_pong: bool) -> bool:
|
|
1467
1480
|
"""Check if proxy is still initialized."""
|
|
1468
1481
|
try:
|
|
1469
1482
|
await self._proxy.clientServerInitialized(self.interface_id)
|
|
@@ -1480,35 +1493,35 @@ class ClientHomegear(Client):
|
|
|
1480
1493
|
return False
|
|
1481
1494
|
|
|
1482
1495
|
@inspector
|
|
1483
|
-
async def execute_program(self, pid: str) -> bool:
|
|
1496
|
+
async def execute_program(self, *, pid: str) -> bool:
|
|
1484
1497
|
"""Execute a program on the backend."""
|
|
1485
1498
|
return True
|
|
1486
1499
|
|
|
1487
1500
|
@inspector
|
|
1488
|
-
async def set_program_state(self, pid: str, state: bool) -> bool:
|
|
1501
|
+
async def set_program_state(self, *, pid: str, state: bool) -> bool:
|
|
1489
1502
|
"""Set the program state on the backend."""
|
|
1490
1503
|
return True
|
|
1491
1504
|
|
|
1492
1505
|
@inspector(measure_performance=True)
|
|
1493
|
-
async def set_system_variable(self, legacy_name: str, value: Any) -> bool:
|
|
1506
|
+
async def set_system_variable(self, *, legacy_name: str, value: Any) -> bool:
|
|
1494
1507
|
"""Set a system variable on the backend."""
|
|
1495
1508
|
await self._proxy.setSystemVariable(legacy_name, value)
|
|
1496
1509
|
return True
|
|
1497
1510
|
|
|
1498
1511
|
@inspector
|
|
1499
|
-
async def delete_system_variable(self, name: str) -> bool:
|
|
1512
|
+
async def delete_system_variable(self, *, name: str) -> bool:
|
|
1500
1513
|
"""Delete a system variable from the backend."""
|
|
1501
1514
|
await self._proxy.deleteSystemVariable(name)
|
|
1502
1515
|
return True
|
|
1503
1516
|
|
|
1504
1517
|
@inspector
|
|
1505
|
-
async def get_system_variable(self, name: str) -> Any:
|
|
1518
|
+
async def get_system_variable(self, *, name: str) -> Any:
|
|
1506
1519
|
"""Get single system variable from the backend."""
|
|
1507
1520
|
return await self._proxy.getSystemVariable(name)
|
|
1508
1521
|
|
|
1509
1522
|
@inspector(re_raise=False)
|
|
1510
1523
|
async def get_all_system_variables(
|
|
1511
|
-
self, markers: tuple[DescriptionMarker | str, ...]
|
|
1524
|
+
self, *, markers: tuple[DescriptionMarker | str, ...]
|
|
1512
1525
|
) -> tuple[SystemVariableData, ...] | None:
|
|
1513
1526
|
"""Get all system variables from the backend."""
|
|
1514
1527
|
variables: list[SystemVariableData] = []
|
|
@@ -1518,7 +1531,7 @@ class ClientHomegear(Client):
|
|
|
1518
1531
|
return tuple(variables)
|
|
1519
1532
|
|
|
1520
1533
|
@inspector(re_raise=False)
|
|
1521
|
-
async def get_all_programs(self, markers: tuple[DescriptionMarker | str, ...]) -> tuple[ProgramData, ...] | None:
|
|
1534
|
+
async def get_all_programs(self, *, markers: tuple[DescriptionMarker | str, ...]) -> tuple[ProgramData, ...] | None:
|
|
1522
1535
|
"""Get all programs, if available."""
|
|
1523
1536
|
return ()
|
|
1524
1537
|
|
|
@@ -1542,6 +1555,7 @@ class _ClientConfig:
|
|
|
1542
1555
|
|
|
1543
1556
|
def __init__(
|
|
1544
1557
|
self,
|
|
1558
|
+
*,
|
|
1545
1559
|
central: hmcu.CentralUnit,
|
|
1546
1560
|
interface_config: InterfaceConfig,
|
|
1547
1561
|
) -> None:
|
|
@@ -1599,7 +1613,7 @@ class _ClientConfig:
|
|
|
1599
1613
|
return "0"
|
|
1600
1614
|
|
|
1601
1615
|
async def create_xml_rpc_proxy(
|
|
1602
|
-
self, auth_enabled: bool | None = None, max_workers: int = DEFAULT_MAX_WORKERS
|
|
1616
|
+
self, *, auth_enabled: bool | None = None, max_workers: int = DEFAULT_MAX_WORKERS
|
|
1603
1617
|
) -> XmlRpcProxy:
|
|
1604
1618
|
"""Return a XmlRPC proxy for the backend communication."""
|
|
1605
1619
|
config = self.central.config
|
|
@@ -1633,6 +1647,7 @@ class InterfaceConfig:
|
|
|
1633
1647
|
|
|
1634
1648
|
def __init__(
|
|
1635
1649
|
self,
|
|
1650
|
+
*,
|
|
1636
1651
|
central_name: str,
|
|
1637
1652
|
interface: Interface,
|
|
1638
1653
|
port: int | None = None,
|
|
@@ -1679,6 +1694,7 @@ def get_client(interface_id: str) -> Client | None:
|
|
|
1679
1694
|
|
|
1680
1695
|
@measure_execution_time
|
|
1681
1696
|
async def _wait_for_state_change_or_timeout(
|
|
1697
|
+
*,
|
|
1682
1698
|
device: Device,
|
|
1683
1699
|
dpk_values: set[DP_KEY_VALUE],
|
|
1684
1700
|
wait_for_callback: int,
|
|
@@ -1697,7 +1713,7 @@ async def _wait_for_state_change_or_timeout(
|
|
|
1697
1713
|
|
|
1698
1714
|
@measure_execution_time
|
|
1699
1715
|
async def _track_single_data_point_state_change_or_timeout(
|
|
1700
|
-
device: Device, dpk_value: DP_KEY_VALUE, wait_for_callback: int
|
|
1716
|
+
*, device: Device, dpk_value: DP_KEY_VALUE, wait_for_callback: int
|
|
1701
1717
|
) -> None:
|
|
1702
1718
|
"""Wait for a data_point to change state."""
|
|
1703
1719
|
ev = asyncio.Event()
|
|
@@ -1710,7 +1726,7 @@ async def _track_single_data_point_state_change_or_timeout(
|
|
|
1710
1726
|
dpk,
|
|
1711
1727
|
dp.value,
|
|
1712
1728
|
)
|
|
1713
|
-
if _isclose(value, dp.value):
|
|
1729
|
+
if _isclose(value1=value, value2=dp.value):
|
|
1714
1730
|
_LOGGER.debug(
|
|
1715
1731
|
"TRACK_SINGLE_DATA_POINT_STATE_CHANGE_OR_TIMEOUT: Finished event %s with value %s",
|
|
1716
1732
|
dpk,
|
|
@@ -1747,7 +1763,7 @@ async def _track_single_data_point_state_change_or_timeout(
|
|
|
1747
1763
|
unsub()
|
|
1748
1764
|
|
|
1749
1765
|
|
|
1750
|
-
def _isclose(value1: Any, value2: Any) -> bool:
|
|
1766
|
+
def _isclose(*, value1: Any, value2: Any) -> bool:
|
|
1751
1767
|
"""Check if the both values are close to each other."""
|
|
1752
1768
|
if isinstance(value1, float):
|
|
1753
1769
|
return bool(round(value1, 2) == round(value2, 2))
|
|
@@ -44,7 +44,7 @@ class RpcContext:
|
|
|
44
44
|
return ", ".join(parts)
|
|
45
45
|
|
|
46
46
|
|
|
47
|
-
def map_jsonrpc_error(error: Mapping[str, Any], ctx: RpcContext) -> Exception:
|
|
47
|
+
def map_jsonrpc_error(*, error: Mapping[str, Any], ctx: RpcContext) -> Exception:
|
|
48
48
|
"""Map JSON-RPC error to exception."""
|
|
49
49
|
# JSON-RPC 2.0 like error: {code, message, data?}
|
|
50
50
|
code = int(error.get("code", 0))
|
|
@@ -61,7 +61,7 @@ def map_jsonrpc_error(error: Mapping[str, Any], ctx: RpcContext) -> Exception:
|
|
|
61
61
|
return ClientException(base_msg)
|
|
62
62
|
|
|
63
63
|
|
|
64
|
-
def map_transport_error(exc: BaseException, ctx: RpcContext) -> Exception:
|
|
64
|
+
def map_transport_error(*, exc: BaseException, ctx: RpcContext) -> Exception:
|
|
65
65
|
"""Map transport error to exception."""
|
|
66
66
|
msg = f"{exc} ({ctx.fmt()})"
|
|
67
67
|
if isinstance(exc, OSError):
|
|
@@ -69,7 +69,7 @@ def map_transport_error(exc: BaseException, ctx: RpcContext) -> Exception:
|
|
|
69
69
|
return ClientException(msg)
|
|
70
70
|
|
|
71
71
|
|
|
72
|
-
def map_xmlrpc_fault(code: int, fault_string: str, ctx: RpcContext) -> Exception:
|
|
72
|
+
def map_xmlrpc_fault(*, code: int, fault_string: str, ctx: RpcContext) -> Exception:
|
|
73
73
|
"""Map XML-RPC fault to exception."""
|
|
74
74
|
# Enrich message with context
|
|
75
75
|
fault_msg = f"XMLRPC Fault {code}: {fault_string} ({ctx.fmt()})"
|