aiohomematic 2025.10.1__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 +87 -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 +2 -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 +32 -18
- 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.1.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.1.dist-info/RECORD +0 -78
- {aiohomematic-2025.10.1.dist-info → aiohomematic-2025.10.2.dist-info}/WHEEL +0 -0
- {aiohomematic-2025.10.1.dist-info → aiohomematic-2025.10.2.dist-info}/licenses/LICENSE +0 -0
- {aiohomematic-2025.10.1.dist-info → aiohomematic-2025.10.2.dist-info}/top_level.txt +0 -0
aiohomematic/central/__init__.py
CHANGED
|
@@ -193,7 +193,7 @@ INTERFACE_EVENT_SCHEMA = vol.Schema(
|
|
|
193
193
|
class CentralUnit(LogContextMixin, PayloadMixin):
|
|
194
194
|
"""Central unit that collects everything to handle communication from/to the backend."""
|
|
195
195
|
|
|
196
|
-
def __init__(self, central_config: CentralConfig) -> None:
|
|
196
|
+
def __init__(self, *, central_config: CentralConfig) -> None:
|
|
197
197
|
"""Init the central unit."""
|
|
198
198
|
self._state: CentralUnitState = CentralUnitState.NEW
|
|
199
199
|
self._clients_started: bool = False
|
|
@@ -219,7 +219,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
219
219
|
# {interface_id, client}
|
|
220
220
|
self._clients: Final[dict[str, hmcl.Client]] = {}
|
|
221
221
|
self._data_point_key_event_subscriptions: Final[
|
|
222
|
-
dict[DataPointKey, list[Callable[
|
|
222
|
+
dict[DataPointKey, list[Callable[..., Coroutine[Any, Any, None]]]]
|
|
223
223
|
] = {}
|
|
224
224
|
self._data_point_path_event_subscriptions: Final[dict[str, DataPointKey]] = {}
|
|
225
225
|
self._sysvar_data_point_event_subscriptions: Final[dict[str, Callable]] = {}
|
|
@@ -229,7 +229,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
229
229
|
self._sysvar_data_points: Final[dict[str, GenericSysvarDataPoint]] = {}
|
|
230
230
|
# {sysvar_name, program_button}
|
|
231
231
|
self._program_data_points: Final[dict[str, ProgramDpType]] = {}
|
|
232
|
-
# Signature: (
|
|
232
|
+
# Signature: (system_event, new_data_points, new_channel_events, **kwargs)
|
|
233
233
|
# e.g. DEVICES_CREATED, HUB_REFRESHED
|
|
234
234
|
self._backend_system_callbacks: Final[set[Callable]] = set()
|
|
235
235
|
# Signature: (interface_id, channel_address, parameter, value)
|
|
@@ -421,14 +421,14 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
421
421
|
self._version = max(versions) if versions else None
|
|
422
422
|
return self._version
|
|
423
423
|
|
|
424
|
-
def add_sysvar_data_point(self, sysvar_data_point: GenericSysvarDataPoint) -> None:
|
|
424
|
+
def add_sysvar_data_point(self, *, sysvar_data_point: GenericSysvarDataPoint) -> None:
|
|
425
425
|
"""Add new program button."""
|
|
426
426
|
if (vid := sysvar_data_point.vid) is not None:
|
|
427
427
|
self._sysvar_data_points[vid] = sysvar_data_point
|
|
428
428
|
if sysvar_data_point.state_path not in self._sysvar_data_point_event_subscriptions:
|
|
429
429
|
self._sysvar_data_point_event_subscriptions[sysvar_data_point.state_path] = sysvar_data_point.event
|
|
430
430
|
|
|
431
|
-
def remove_sysvar_data_point(self, vid: str) -> None:
|
|
431
|
+
def remove_sysvar_data_point(self, *, vid: str) -> None:
|
|
432
432
|
"""Remove a sysvar data_point."""
|
|
433
433
|
if (sysvar_dp := self.get_sysvar_data_point(vid=vid)) is not None:
|
|
434
434
|
sysvar_dp.fire_device_removed_callback()
|
|
@@ -436,18 +436,18 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
436
436
|
if sysvar_dp.state_path in self._sysvar_data_point_event_subscriptions:
|
|
437
437
|
del self._sysvar_data_point_event_subscriptions[sysvar_dp.state_path]
|
|
438
438
|
|
|
439
|
-
def add_program_data_point(self, program_dp: ProgramDpType) -> None:
|
|
439
|
+
def add_program_data_point(self, *, program_dp: ProgramDpType) -> None:
|
|
440
440
|
"""Add new program button."""
|
|
441
441
|
self._program_data_points[program_dp.pid] = program_dp
|
|
442
442
|
|
|
443
|
-
def remove_program_button(self, pid: str) -> None:
|
|
443
|
+
def remove_program_button(self, *, pid: str) -> None:
|
|
444
444
|
"""Remove a program button."""
|
|
445
445
|
if (program_dp := self.get_program_data_point(pid=pid)) is not None:
|
|
446
446
|
program_dp.button.fire_device_removed_callback()
|
|
447
447
|
program_dp.switch.fire_device_removed_callback()
|
|
448
448
|
del self._program_data_points[pid]
|
|
449
449
|
|
|
450
|
-
def identify_channel(self, text: str) -> Channel | None:
|
|
450
|
+
def identify_channel(self, *, text: str) -> Channel | None:
|
|
451
451
|
"""Identify channel within a text."""
|
|
452
452
|
for device in self._devices.values():
|
|
453
453
|
if channel := device.identify_channel(text=text):
|
|
@@ -455,7 +455,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
455
455
|
return None
|
|
456
456
|
|
|
457
457
|
async def save_caches(
|
|
458
|
-
self, save_device_descriptions: bool = False, save_paramset_descriptions: bool = False
|
|
458
|
+
self, *, save_device_descriptions: bool = False, save_paramset_descriptions: bool = False
|
|
459
459
|
) -> None:
|
|
460
460
|
"""Save persistent caches."""
|
|
461
461
|
if save_device_descriptions:
|
|
@@ -496,7 +496,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
496
496
|
):
|
|
497
497
|
self._xml_rpc_server = xml_rpc_server
|
|
498
498
|
self._listen_port = xml_rpc_server.listen_port
|
|
499
|
-
self._xml_rpc_server.add_central(self)
|
|
499
|
+
self._xml_rpc_server.add_central(central=self)
|
|
500
500
|
except OSError as oserr:
|
|
501
501
|
self._state = CentralUnitState.STOPPED_BY_ERROR
|
|
502
502
|
raise AioHomematicException(
|
|
@@ -573,7 +573,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
573
573
|
_LOGGER.info("RESTART_CLIENTS: Central %s restarted clients", self.name)
|
|
574
574
|
|
|
575
575
|
@inspector(re_raise=False)
|
|
576
|
-
async def refresh_firmware_data(self, device_address: str | None = None) -> None:
|
|
576
|
+
async def refresh_firmware_data(self, *, device_address: str | None = None) -> None:
|
|
577
577
|
"""Refresh device firmware data."""
|
|
578
578
|
if device_address and (device := self.get_device(address=device_address)) is not None and device.is_updatable:
|
|
579
579
|
await self._refresh_device_descriptions(client=device.client, device_address=device_address)
|
|
@@ -586,7 +586,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
586
586
|
device.refresh_firmware_data()
|
|
587
587
|
|
|
588
588
|
@inspector(re_raise=False)
|
|
589
|
-
async def refresh_firmware_data_by_state(self, device_firmware_states: tuple[DeviceFirmwareState, ...]) -> None:
|
|
589
|
+
async def refresh_firmware_data_by_state(self, *, device_firmware_states: tuple[DeviceFirmwareState, ...]) -> None:
|
|
590
590
|
"""Refresh device firmware data for processing devices."""
|
|
591
591
|
for device in [
|
|
592
592
|
device_in_state
|
|
@@ -595,7 +595,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
595
595
|
]:
|
|
596
596
|
await self.refresh_firmware_data(device_address=device.address)
|
|
597
597
|
|
|
598
|
-
async def _refresh_device_descriptions(self, client: hmcl.Client, device_address: str | None = None) -> None:
|
|
598
|
+
async def _refresh_device_descriptions(self, *, client: hmcl.Client, device_address: str | None = None) -> None:
|
|
599
599
|
"""Refresh device descriptions."""
|
|
600
600
|
device_descriptions: tuple[DeviceDescription, ...] | None = None
|
|
601
601
|
if (
|
|
@@ -688,7 +688,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
688
688
|
_LOGGER.debug("CREATE_CLIENTS successful for %s", self.name)
|
|
689
689
|
return True
|
|
690
690
|
|
|
691
|
-
async def _create_client(self, interface_config: hmcl.InterfaceConfig) -> bool:
|
|
691
|
+
async def _create_client(self, *, interface_config: hmcl.InterfaceConfig) -> bool:
|
|
692
692
|
"""Create a client."""
|
|
693
693
|
try:
|
|
694
694
|
if client := await hmcl.create_client(
|
|
@@ -744,6 +744,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
744
744
|
@loop_check
|
|
745
745
|
def fire_interface_event(
|
|
746
746
|
self,
|
|
747
|
+
*,
|
|
747
748
|
interface_id: str,
|
|
748
749
|
interface_event_type: InterfaceEventType,
|
|
749
750
|
data: dict[str, Any],
|
|
@@ -761,7 +762,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
761
762
|
event_data=cast(dict[EventKey, Any], INTERFACE_EVENT_SCHEMA(event_data)),
|
|
762
763
|
)
|
|
763
764
|
|
|
764
|
-
async def _identify_ip_addr(self, port: int) -> str:
|
|
765
|
+
async def _identify_ip_addr(self, *, port: int) -> str:
|
|
765
766
|
ip_addr: str | None = None
|
|
766
767
|
while ip_addr is None:
|
|
767
768
|
try:
|
|
@@ -811,24 +812,24 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
811
812
|
system_information = client.system_information
|
|
812
813
|
return system_information
|
|
813
814
|
|
|
814
|
-
def get_client(self, interface_id: str) -> hmcl.Client:
|
|
815
|
+
def get_client(self, *, interface_id: str) -> hmcl.Client:
|
|
815
816
|
"""Return a client by interface_id."""
|
|
816
817
|
if not self.has_client(interface_id=interface_id):
|
|
817
818
|
raise AioHomematicException(f"get_client: interface_id {interface_id} does not exist on {self.name}")
|
|
818
819
|
return self._clients[interface_id]
|
|
819
820
|
|
|
820
|
-
def get_channel(self, channel_address: str) -> Channel | None:
|
|
821
|
+
def get_channel(self, *, channel_address: str) -> Channel | None:
|
|
821
822
|
"""Return Homematic channel."""
|
|
822
823
|
if device := self.get_device(address=channel_address):
|
|
823
824
|
return device.get_channel(channel_address=channel_address)
|
|
824
825
|
return None
|
|
825
826
|
|
|
826
|
-
def get_device(self, address: str) -> Device | None:
|
|
827
|
+
def get_device(self, *, address: str) -> Device | None:
|
|
827
828
|
"""Return Homematic device."""
|
|
828
829
|
d_address = get_device_address(address=address)
|
|
829
830
|
return self._devices.get(d_address)
|
|
830
831
|
|
|
831
|
-
def get_data_point_by_custom_id(self, custom_id: str) -> CallbackDataPoint | None:
|
|
832
|
+
def get_data_point_by_custom_id(self, *, custom_id: str) -> CallbackDataPoint | None:
|
|
832
833
|
"""Return Homematic data_point by custom_id."""
|
|
833
834
|
for dp in self.get_data_points(registered=True):
|
|
834
835
|
if dp.custom_id == custom_id:
|
|
@@ -837,6 +838,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
837
838
|
|
|
838
839
|
def get_data_points(
|
|
839
840
|
self,
|
|
841
|
+
*,
|
|
840
842
|
category: DataPointCategory | None = None,
|
|
841
843
|
interface: Interface | None = None,
|
|
842
844
|
exclude_no_create: bool = True,
|
|
@@ -853,7 +855,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
853
855
|
return tuple(all_data_points)
|
|
854
856
|
|
|
855
857
|
def get_readable_generic_data_points(
|
|
856
|
-
self, paramset_key: ParamsetKey | None = None, interface: Interface | None = None
|
|
858
|
+
self, *, paramset_key: ParamsetKey | None = None, interface: Interface | None = None
|
|
857
859
|
) -> tuple[GenericDataPoint, ...]:
|
|
858
860
|
"""Return the readable generic data points."""
|
|
859
861
|
return tuple(
|
|
@@ -875,7 +877,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
875
877
|
return client
|
|
876
878
|
|
|
877
879
|
def get_hub_data_points(
|
|
878
|
-
self, category: DataPointCategory | None = None, registered: bool | None = None
|
|
880
|
+
self, *, category: DataPointCategory | None = None, registered: bool | None = None
|
|
879
881
|
) -> tuple[GenericHubDataPoint, ...]:
|
|
880
882
|
"""Return the program data points."""
|
|
881
883
|
return tuple(
|
|
@@ -884,7 +886,9 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
884
886
|
if (category is None or he.category == category) and (registered is None or he.is_registered == registered)
|
|
885
887
|
)
|
|
886
888
|
|
|
887
|
-
def get_events(
|
|
889
|
+
def get_events(
|
|
890
|
+
self, *, event_type: EventType, registered: bool | None = None
|
|
891
|
+
) -> tuple[tuple[GenericEvent, ...], ...]:
|
|
888
892
|
"""Return all channel event data points."""
|
|
889
893
|
hm_channel_events: list[tuple[GenericEvent, ...]] = []
|
|
890
894
|
for device in self.devices:
|
|
@@ -902,7 +906,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
902
906
|
if cl.get_virtual_remote() is not None
|
|
903
907
|
)
|
|
904
908
|
|
|
905
|
-
def has_client(self, interface_id: str) -> bool:
|
|
909
|
+
def has_client(self, *, interface_id: str) -> bool:
|
|
906
910
|
"""Check if client exists in central."""
|
|
907
911
|
return interface_id in self._clients
|
|
908
912
|
|
|
@@ -930,7 +934,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
930
934
|
await self._data_cache.load()
|
|
931
935
|
return True
|
|
932
936
|
|
|
933
|
-
async def _create_devices(self, new_device_addresses: Mapping[str, set[str]]) -> None:
|
|
937
|
+
async def _create_devices(self, *, new_device_addresses: Mapping[str, set[str]]) -> None:
|
|
934
938
|
"""Trigger creation of the objects that expose the functionality."""
|
|
935
939
|
if not self._clients:
|
|
936
940
|
raise AioHomematicException(
|
|
@@ -986,7 +990,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
986
990
|
new_channel_events=new_channel_events,
|
|
987
991
|
)
|
|
988
992
|
|
|
989
|
-
async def delete_device(self, interface_id: str, device_address: str) -> None:
|
|
993
|
+
async def delete_device(self, *, interface_id: str, device_address: str) -> None:
|
|
990
994
|
"""Delete devices from central."""
|
|
991
995
|
_LOGGER.debug(
|
|
992
996
|
"DELETE_DEVICE: interface_id = %s, device_address = %s",
|
|
@@ -1000,7 +1004,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
1000
1004
|
await self.delete_devices(interface_id=interface_id, addresses=[device_address, *list(device.channels.keys())])
|
|
1001
1005
|
|
|
1002
1006
|
@callback_backend_system(system_event=BackendSystemEvent.DELETE_DEVICES)
|
|
1003
|
-
async def delete_devices(self, interface_id: str, addresses: tuple[str, ...]) -> None:
|
|
1007
|
+
async def delete_devices(self, *, interface_id: str, addresses: tuple[str, ...]) -> None:
|
|
1004
1008
|
"""Delete devices from central."""
|
|
1005
1009
|
_LOGGER.debug(
|
|
1006
1010
|
"DELETE_DEVICES: interface_id = %s, addresses = %s",
|
|
@@ -1013,12 +1017,12 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
1013
1017
|
await self.save_caches()
|
|
1014
1018
|
|
|
1015
1019
|
@callback_backend_system(system_event=BackendSystemEvent.NEW_DEVICES)
|
|
1016
|
-
async def add_new_devices(self, interface_id: str, device_descriptions: tuple[DeviceDescription, ...]) -> None:
|
|
1020
|
+
async def add_new_devices(self, *, interface_id: str, device_descriptions: tuple[DeviceDescription, ...]) -> None:
|
|
1017
1021
|
"""Add new devices to central unit."""
|
|
1018
1022
|
await self._add_new_devices(interface_id=interface_id, device_descriptions=device_descriptions)
|
|
1019
1023
|
|
|
1020
1024
|
@inspector(measure_performance=True)
|
|
1021
|
-
async def _add_new_devices(self, interface_id: str, device_descriptions: tuple[DeviceDescription, ...]) -> None:
|
|
1025
|
+
async def _add_new_devices(self, *, interface_id: str, device_descriptions: tuple[DeviceDescription, ...]) -> None:
|
|
1022
1026
|
"""Add new devices to central unit."""
|
|
1023
1027
|
if not device_descriptions:
|
|
1024
1028
|
_LOGGER.debug(
|
|
@@ -1104,7 +1108,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
1104
1108
|
return new_device_addresses
|
|
1105
1109
|
|
|
1106
1110
|
@callback_event
|
|
1107
|
-
async def data_point_event(self, interface_id: str, channel_address: str, parameter: str, value: Any) -> None:
|
|
1111
|
+
async def data_point_event(self, *, interface_id: str, channel_address: str, parameter: str, value: Any) -> None:
|
|
1108
1112
|
"""If a device emits some sort event, we will handle it here."""
|
|
1109
1113
|
_LOGGER_EVENT.debug(
|
|
1110
1114
|
"EVENT: interface_id = %s, channel_address = %s, parameter = %s, value = %s",
|
|
@@ -1143,7 +1147,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
1143
1147
|
received_at = datetime.now()
|
|
1144
1148
|
for callback_handler in self._data_point_key_event_subscriptions[dpk]:
|
|
1145
1149
|
if callable(callback_handler):
|
|
1146
|
-
await callback_handler(value, received_at)
|
|
1150
|
+
await callback_handler(value=value, received_at=received_at)
|
|
1147
1151
|
except RuntimeError as rterr: # pragma: no cover
|
|
1148
1152
|
_LOGGER_EVENT.debug(
|
|
1149
1153
|
"EVENT: RuntimeError [%s]. Failed to call callback for: %s, %s, %s",
|
|
@@ -1161,7 +1165,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
1161
1165
|
extract_exc_args(exc=exc),
|
|
1162
1166
|
)
|
|
1163
1167
|
|
|
1164
|
-
def data_point_path_event(self, state_path: str, value: str) -> None:
|
|
1168
|
+
def data_point_path_event(self, *, state_path: str, value: str) -> None:
|
|
1165
1169
|
"""If a device emits some sort event, we will handle it here."""
|
|
1166
1170
|
_LOGGER_EVENT.debug(
|
|
1167
1171
|
"DATA_POINT_PATH_EVENT: topic = %s, payload = %s",
|
|
@@ -1171,7 +1175,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
1171
1175
|
|
|
1172
1176
|
if (dpk := self._data_point_path_event_subscriptions.get(state_path)) is not None:
|
|
1173
1177
|
self._looper.create_task(
|
|
1174
|
-
self.data_point_event(
|
|
1178
|
+
target=self.data_point_event(
|
|
1175
1179
|
interface_id=dpk.interface_id,
|
|
1176
1180
|
channel_address=dpk.channel_address,
|
|
1177
1181
|
parameter=dpk.parameter,
|
|
@@ -1180,7 +1184,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
1180
1184
|
name=f"device-data-point-event-{dpk.interface_id}-{dpk.channel_address}-{dpk.parameter}",
|
|
1181
1185
|
)
|
|
1182
1186
|
|
|
1183
|
-
def sysvar_data_point_path_event(self, state_path: str, value: str) -> None:
|
|
1187
|
+
def sysvar_data_point_path_event(self, *, state_path: str, value: str) -> None:
|
|
1184
1188
|
"""If a device emits some sort event, we will handle it here."""
|
|
1185
1189
|
_LOGGER_EVENT.debug(
|
|
1186
1190
|
"SYSVAR_DATA_POINT_PATH_EVENT: topic = %s, payload = %s",
|
|
@@ -1194,7 +1198,8 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
1194
1198
|
if callable(callback_handler):
|
|
1195
1199
|
received_at = datetime.now()
|
|
1196
1200
|
self._looper.create_task(
|
|
1197
|
-
callback_handler(value, received_at),
|
|
1201
|
+
target=callback_handler(value=value, received_at=received_at),
|
|
1202
|
+
name=f"sysvar-data-point-event-{state_path}",
|
|
1198
1203
|
)
|
|
1199
1204
|
except RuntimeError as rterr: # pragma: no cover
|
|
1200
1205
|
_LOGGER_EVENT.debug(
|
|
@@ -1210,13 +1215,13 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
1210
1215
|
)
|
|
1211
1216
|
|
|
1212
1217
|
@callback_backend_system(system_event=BackendSystemEvent.LIST_DEVICES)
|
|
1213
|
-
def list_devices(self, interface_id: str) -> list[DeviceDescription]:
|
|
1218
|
+
def list_devices(self, *, interface_id: str) -> list[DeviceDescription]:
|
|
1214
1219
|
"""Return already existing devices to the backend."""
|
|
1215
1220
|
result = self._device_descriptions.get_raw_device_descriptions(interface_id=interface_id)
|
|
1216
1221
|
_LOGGER.debug("LIST_DEVICES: interface_id = %s, channel_count = %i", interface_id, len(result))
|
|
1217
1222
|
return result
|
|
1218
1223
|
|
|
1219
|
-
def add_event_subscription(self, data_point: BaseParameterDataPoint) -> None:
|
|
1224
|
+
def add_event_subscription(self, *, data_point: BaseParameterDataPoint) -> None:
|
|
1220
1225
|
"""Add data_point to central event subscription."""
|
|
1221
1226
|
if isinstance(data_point, GenericDataPoint | GenericEvent) and (
|
|
1222
1227
|
data_point.is_readable or data_point.supports_events
|
|
@@ -1242,7 +1247,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
1242
1247
|
for device in self.devices:
|
|
1243
1248
|
await device.remove_central_links()
|
|
1244
1249
|
|
|
1245
|
-
def remove_device(self, device: Device) -> None:
|
|
1250
|
+
def remove_device(self, *, device: Device) -> None:
|
|
1246
1251
|
"""Remove device to central collections."""
|
|
1247
1252
|
if device.address not in self._devices:
|
|
1248
1253
|
_LOGGER.debug(
|
|
@@ -1257,7 +1262,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
1257
1262
|
self._device_details.remove_device(device=device)
|
|
1258
1263
|
del self._devices[device.address]
|
|
1259
1264
|
|
|
1260
|
-
def remove_event_subscription(self, data_point: BaseParameterDataPoint) -> None:
|
|
1265
|
+
def remove_event_subscription(self, *, data_point: BaseParameterDataPoint) -> None:
|
|
1261
1266
|
"""Remove event subscription from central collections."""
|
|
1262
1267
|
if isinstance(data_point, GenericDataPoint | GenericEvent) and data_point.supports_events:
|
|
1263
1268
|
if data_point.dpk in self._data_point_key_event_subscriptions:
|
|
@@ -1265,39 +1270,40 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
1265
1270
|
if data_point.state_path in self._data_point_path_event_subscriptions:
|
|
1266
1271
|
del self._data_point_path_event_subscriptions[data_point.state_path]
|
|
1267
1272
|
|
|
1268
|
-
def get_last_event_seen_for_interface(self, interface_id: str) -> datetime | None:
|
|
1273
|
+
def get_last_event_seen_for_interface(self, *, interface_id: str) -> datetime | None:
|
|
1269
1274
|
"""Return the last event seen for an interface."""
|
|
1270
1275
|
return self._last_event_seen_for_interface.get(interface_id)
|
|
1271
1276
|
|
|
1272
|
-
def set_last_event_seen_for_interface(self, interface_id: str) -> None:
|
|
1277
|
+
def set_last_event_seen_for_interface(self, *, interface_id: str) -> None:
|
|
1273
1278
|
"""Set the last event seen for an interface."""
|
|
1274
1279
|
self._last_event_seen_for_interface[interface_id] = datetime.now()
|
|
1275
1280
|
|
|
1276
|
-
async def execute_program(self, pid: str) -> bool:
|
|
1281
|
+
async def execute_program(self, *, pid: str) -> bool:
|
|
1277
1282
|
"""Execute a program on the backend."""
|
|
1278
1283
|
if client := self.primary_client:
|
|
1279
1284
|
return await client.execute_program(pid=pid)
|
|
1280
1285
|
return False
|
|
1281
1286
|
|
|
1282
|
-
async def set_program_state(self, pid: str, state: bool) -> bool:
|
|
1287
|
+
async def set_program_state(self, *, pid: str, state: bool) -> bool:
|
|
1283
1288
|
"""Execute a program on the backend."""
|
|
1284
1289
|
if client := self.primary_client:
|
|
1285
1290
|
return await client.set_program_state(pid=pid, state=state)
|
|
1286
1291
|
return False
|
|
1287
1292
|
|
|
1288
1293
|
@inspector(re_raise=False)
|
|
1289
|
-
async def fetch_sysvar_data(self, scheduled: bool) -> None:
|
|
1294
|
+
async def fetch_sysvar_data(self, *, scheduled: bool) -> None:
|
|
1290
1295
|
"""Fetch sysvar data for the hub."""
|
|
1291
1296
|
await self._hub.fetch_sysvar_data(scheduled=scheduled)
|
|
1292
1297
|
|
|
1293
1298
|
@inspector(re_raise=False)
|
|
1294
|
-
async def fetch_program_data(self, scheduled: bool) -> None:
|
|
1299
|
+
async def fetch_program_data(self, *, scheduled: bool) -> None:
|
|
1295
1300
|
"""Fetch program data for the hub."""
|
|
1296
1301
|
await self._hub.fetch_program_data(scheduled=scheduled)
|
|
1297
1302
|
|
|
1298
1303
|
@inspector(measure_performance=True)
|
|
1299
1304
|
async def load_and_refresh_data_point_data(
|
|
1300
1305
|
self,
|
|
1306
|
+
*,
|
|
1301
1307
|
interface: Interface,
|
|
1302
1308
|
paramset_key: ParamsetKey | None = None,
|
|
1303
1309
|
direct_call: bool = False,
|
|
@@ -1309,13 +1315,13 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
1309
1315
|
paramset_key=paramset_key, interface=interface, direct_call=direct_call
|
|
1310
1316
|
)
|
|
1311
1317
|
|
|
1312
|
-
async def get_system_variable(self, legacy_name: str) -> Any | None:
|
|
1318
|
+
async def get_system_variable(self, *, legacy_name: str) -> Any | None:
|
|
1313
1319
|
"""Get system variable from the backend."""
|
|
1314
1320
|
if client := self.primary_client:
|
|
1315
|
-
return await client.get_system_variable(legacy_name)
|
|
1321
|
+
return await client.get_system_variable(name=legacy_name)
|
|
1316
1322
|
return None
|
|
1317
1323
|
|
|
1318
|
-
async def set_system_variable(self, legacy_name: str, value: Any) -> None:
|
|
1324
|
+
async def set_system_variable(self, *, legacy_name: str, value: Any) -> None:
|
|
1319
1325
|
"""Set variable value on the backend."""
|
|
1320
1326
|
if dp := self.get_sysvar_data_point(legacy_name=legacy_name):
|
|
1321
1327
|
await dp.send_variable(value=value)
|
|
@@ -1324,6 +1330,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
1324
1330
|
|
|
1325
1331
|
def get_parameters(
|
|
1326
1332
|
self,
|
|
1333
|
+
*,
|
|
1327
1334
|
paramset_key: ParamsetKey,
|
|
1328
1335
|
operations: tuple[Operations, ...],
|
|
1329
1336
|
full_format: bool = False,
|
|
@@ -1401,7 +1408,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
1401
1408
|
|
|
1402
1409
|
return tuple(parameters)
|
|
1403
1410
|
|
|
1404
|
-
def _get_virtual_remote(self, device_address: str) -> Device | None:
|
|
1411
|
+
def _get_virtual_remote(self, *, device_address: str) -> Device | None:
|
|
1405
1412
|
"""Get the virtual remote for the Client."""
|
|
1406
1413
|
for client in self._clients.values():
|
|
1407
1414
|
virtual_remote = client.get_virtual_remote()
|
|
@@ -1410,7 +1417,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
1410
1417
|
return None
|
|
1411
1418
|
|
|
1412
1419
|
def get_generic_data_point(
|
|
1413
|
-
self, channel_address: str, parameter: str, paramset_key: ParamsetKey | None = None
|
|
1420
|
+
self, *, channel_address: str, parameter: str, paramset_key: ParamsetKey | None = None
|
|
1414
1421
|
) -> GenericDataPoint | None:
|
|
1415
1422
|
"""Get data_point by channel_address and parameter."""
|
|
1416
1423
|
if device := self.get_device(address=channel_address):
|
|
@@ -1419,20 +1426,20 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
1419
1426
|
)
|
|
1420
1427
|
return None
|
|
1421
1428
|
|
|
1422
|
-
def get_event(self, channel_address: str, parameter: str) -> GenericEvent | None:
|
|
1429
|
+
def get_event(self, *, channel_address: str, parameter: str) -> GenericEvent | None:
|
|
1423
1430
|
"""Return the hm event."""
|
|
1424
1431
|
if device := self.get_device(address=channel_address):
|
|
1425
1432
|
return device.get_generic_event(channel_address=channel_address, parameter=parameter)
|
|
1426
1433
|
return None
|
|
1427
1434
|
|
|
1428
|
-
def get_custom_data_point(self, address: str, channel_no: int) -> CustomDataPoint | None:
|
|
1435
|
+
def get_custom_data_point(self, *, address: str, channel_no: int) -> CustomDataPoint | None:
|
|
1429
1436
|
"""Return the hm custom_data_point."""
|
|
1430
1437
|
if device := self.get_device(address=address):
|
|
1431
1438
|
return device.get_custom_data_point(channel_no=channel_no)
|
|
1432
1439
|
return None
|
|
1433
1440
|
|
|
1434
1441
|
def get_sysvar_data_point(
|
|
1435
|
-
self, vid: str | None = None, legacy_name: str | None = None
|
|
1442
|
+
self, *, vid: str | None = None, legacy_name: str | None = None
|
|
1436
1443
|
) -> GenericSysvarDataPoint | None:
|
|
1437
1444
|
"""Return the sysvar data_point."""
|
|
1438
1445
|
if vid and (sysvar := self._sysvar_data_points.get(vid)):
|
|
@@ -1443,7 +1450,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
1443
1450
|
return sysvar
|
|
1444
1451
|
return None
|
|
1445
1452
|
|
|
1446
|
-
def get_program_data_point(self, pid: str | None = None, legacy_name: str | None = None) -> ProgramDpType | None:
|
|
1453
|
+
def get_program_data_point(self, *, pid: str | None = None, legacy_name: str | None = None) -> ProgramDpType | None:
|
|
1447
1454
|
"""Return the program data points."""
|
|
1448
1455
|
if pid and (program := self._program_data_points.get(pid)):
|
|
1449
1456
|
return program
|
|
@@ -1461,7 +1468,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
1461
1468
|
"""Return the registered sysvar state path."""
|
|
1462
1469
|
return tuple(self._sysvar_data_point_event_subscriptions)
|
|
1463
1470
|
|
|
1464
|
-
def get_un_ignore_candidates(self, include_master: bool = False) -> list[str]:
|
|
1471
|
+
def get_un_ignore_candidates(self, *, include_master: bool = False) -> list[str]:
|
|
1465
1472
|
"""Return the candidates for un_ignore."""
|
|
1466
1473
|
candidates = sorted(
|
|
1467
1474
|
# 1. request simple parameter list for values parameters
|
|
@@ -1505,20 +1512,20 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
1505
1512
|
self._device_details.clear()
|
|
1506
1513
|
self._data_cache.clear()
|
|
1507
1514
|
|
|
1508
|
-
def register_homematic_callback(self, cb: Callable) -> CALLBACK_TYPE:
|
|
1515
|
+
def register_homematic_callback(self, *, cb: Callable) -> CALLBACK_TYPE:
|
|
1509
1516
|
"""Register ha_event callback in central."""
|
|
1510
1517
|
if callable(cb) and cb not in self._homematic_callbacks:
|
|
1511
1518
|
self._homematic_callbacks.add(cb)
|
|
1512
1519
|
return partial(self._unregister_homematic_callback, cb=cb)
|
|
1513
1520
|
return None
|
|
1514
1521
|
|
|
1515
|
-
def _unregister_homematic_callback(self, cb: Callable) -> None:
|
|
1522
|
+
def _unregister_homematic_callback(self, *, cb: Callable) -> None:
|
|
1516
1523
|
"""RUn register ha_event callback in central."""
|
|
1517
1524
|
if cb in self._homematic_callbacks:
|
|
1518
1525
|
self._homematic_callbacks.remove(cb)
|
|
1519
1526
|
|
|
1520
1527
|
@loop_check
|
|
1521
|
-
def fire_homematic_callback(self, event_type: EventType, event_data: dict[EventKey, str]) -> None:
|
|
1528
|
+
def fire_homematic_callback(self, *, event_type: EventType, event_data: dict[EventKey, str]) -> None:
|
|
1522
1529
|
"""
|
|
1523
1530
|
Fire homematic_callback in central.
|
|
1524
1531
|
|
|
@@ -1526,28 +1533,28 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
1526
1533
|
"""
|
|
1527
1534
|
for callback_handler in self._homematic_callbacks:
|
|
1528
1535
|
try:
|
|
1529
|
-
callback_handler(event_type, event_data)
|
|
1536
|
+
callback_handler(event_type=event_type, event_data=event_data)
|
|
1530
1537
|
except Exception as exc:
|
|
1531
1538
|
_LOGGER.error(
|
|
1532
1539
|
"FIRE_HOMEMATIC_CALLBACK: Unable to call handler: %s",
|
|
1533
1540
|
extract_exc_args(exc=exc),
|
|
1534
1541
|
)
|
|
1535
1542
|
|
|
1536
|
-
def register_backend_parameter_callback(self, cb: Callable) -> CALLBACK_TYPE:
|
|
1543
|
+
def register_backend_parameter_callback(self, *, cb: Callable) -> CALLBACK_TYPE:
|
|
1537
1544
|
"""Register backend_parameter callback in central."""
|
|
1538
1545
|
if callable(cb) and cb not in self._backend_parameter_callbacks:
|
|
1539
1546
|
self._backend_parameter_callbacks.add(cb)
|
|
1540
1547
|
return partial(self._unregister_backend_parameter_callback, cb=cb)
|
|
1541
1548
|
return None
|
|
1542
1549
|
|
|
1543
|
-
def _unregister_backend_parameter_callback(self, cb: Callable) -> None:
|
|
1550
|
+
def _unregister_backend_parameter_callback(self, *, cb: Callable) -> None:
|
|
1544
1551
|
"""Un register backend_parameter callback in central."""
|
|
1545
1552
|
if cb in self._backend_parameter_callbacks:
|
|
1546
1553
|
self._backend_parameter_callbacks.remove(cb)
|
|
1547
1554
|
|
|
1548
1555
|
@loop_check
|
|
1549
1556
|
def fire_backend_parameter_callback(
|
|
1550
|
-
self, interface_id: str, channel_address: str, parameter: str, value: Any
|
|
1557
|
+
self, *, interface_id: str, channel_address: str, parameter: str, value: Any
|
|
1551
1558
|
) -> None:
|
|
1552
1559
|
"""
|
|
1553
1560
|
Fire backend_parameter callback in central.
|
|
@@ -1556,27 +1563,29 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
1556
1563
|
"""
|
|
1557
1564
|
for callback_handler in self._backend_parameter_callbacks:
|
|
1558
1565
|
try:
|
|
1559
|
-
callback_handler(
|
|
1566
|
+
callback_handler(
|
|
1567
|
+
interface_id=interface_id, channel_address=channel_address, parameter=parameter, value=value
|
|
1568
|
+
)
|
|
1560
1569
|
except Exception as exc:
|
|
1561
1570
|
_LOGGER.error(
|
|
1562
1571
|
"FIRE_BACKEND_PARAMETER_CALLBACK: Unable to call handler: %s",
|
|
1563
1572
|
extract_exc_args(exc=exc),
|
|
1564
1573
|
)
|
|
1565
1574
|
|
|
1566
|
-
def register_backend_system_callback(self, cb: Callable) -> CALLBACK_TYPE:
|
|
1575
|
+
def register_backend_system_callback(self, *, cb: Callable) -> CALLBACK_TYPE:
|
|
1567
1576
|
"""Register system_event callback in central."""
|
|
1568
1577
|
if callable(cb) and cb not in self._backend_parameter_callbacks:
|
|
1569
1578
|
self._backend_system_callbacks.add(cb)
|
|
1570
1579
|
return partial(self._unregister_backend_system_callback, cb=cb)
|
|
1571
1580
|
return None
|
|
1572
1581
|
|
|
1573
|
-
def _unregister_backend_system_callback(self, cb: Callable) -> None:
|
|
1582
|
+
def _unregister_backend_system_callback(self, *, cb: Callable) -> None:
|
|
1574
1583
|
"""Un register system_event callback in central."""
|
|
1575
1584
|
if cb in self._backend_system_callbacks:
|
|
1576
1585
|
self._backend_system_callbacks.remove(cb)
|
|
1577
1586
|
|
|
1578
1587
|
@loop_check
|
|
1579
|
-
def fire_backend_system_callback(self, system_event: BackendSystemEvent, **kwargs: Any) -> None:
|
|
1588
|
+
def fire_backend_system_callback(self, *, system_event: BackendSystemEvent, **kwargs: Any) -> None:
|
|
1580
1589
|
"""
|
|
1581
1590
|
Fire system_event callback in central.
|
|
1582
1591
|
|
|
@@ -1584,7 +1593,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
1584
1593
|
"""
|
|
1585
1594
|
for callback_handler in self._backend_system_callbacks:
|
|
1586
1595
|
try:
|
|
1587
|
-
callback_handler(system_event, **kwargs)
|
|
1596
|
+
callback_handler(system_event=system_event, **kwargs)
|
|
1588
1597
|
except Exception as exc:
|
|
1589
1598
|
_LOGGER.error(
|
|
1590
1599
|
"FIRE_BACKEND_SYSTEM_CALLBACK: Unable to call handler: %s",
|
|
@@ -1599,7 +1608,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
1599
1608
|
class _Scheduler(threading.Thread):
|
|
1600
1609
|
"""Periodically check connection to the backend, and load data when required."""
|
|
1601
1610
|
|
|
1602
|
-
def __init__(self, central: CentralUnit) -> None:
|
|
1611
|
+
def __init__(self, *, central: CentralUnit) -> None:
|
|
1603
1612
|
"""Init the connection checker."""
|
|
1604
1613
|
threading.Thread.__init__(self, name=f"ConnectionChecker for {central.name}")
|
|
1605
1614
|
self._central: Final = central
|
|
@@ -1644,7 +1653,7 @@ class _Scheduler(threading.Thread):
|
|
|
1644
1653
|
)
|
|
1645
1654
|
|
|
1646
1655
|
self._central.looper.create_task(
|
|
1647
|
-
self._run_scheduler_tasks(),
|
|
1656
|
+
target=self._run_scheduler_tasks(),
|
|
1648
1657
|
name="run_scheduler_tasks",
|
|
1649
1658
|
)
|
|
1650
1659
|
|
|
@@ -1799,6 +1808,7 @@ class _SchedulerJob:
|
|
|
1799
1808
|
|
|
1800
1809
|
def __init__(
|
|
1801
1810
|
self,
|
|
1811
|
+
*,
|
|
1802
1812
|
task: Callable,
|
|
1803
1813
|
run_interval: int,
|
|
1804
1814
|
next_run: datetime | None = None,
|
|
@@ -1827,6 +1837,7 @@ class CentralConfig:
|
|
|
1827
1837
|
|
|
1828
1838
|
def __init__(
|
|
1829
1839
|
self,
|
|
1840
|
+
*,
|
|
1830
1841
|
central_id: str,
|
|
1831
1842
|
host: str,
|
|
1832
1843
|
interface_configs: AbstractSet[hmcl.InterfaceConfig],
|
|
@@ -1939,7 +1950,7 @@ class CentralConfig:
|
|
|
1939
1950
|
"""Create the central. Throws BaseHomematicException on validation failure."""
|
|
1940
1951
|
try:
|
|
1941
1952
|
self.check_config()
|
|
1942
|
-
return CentralUnit(self)
|
|
1953
|
+
return CentralUnit(central_config=self)
|
|
1943
1954
|
except BaseHomematicException as bhexc:
|
|
1944
1955
|
raise AioHomematicException(
|
|
1945
1956
|
f"CREATE_CENTRAL: Not able to create a central: : {extract_exc_args(exc=bhexc)}"
|
|
@@ -1953,7 +1964,7 @@ class CentralConfig:
|
|
|
1953
1964
|
url = f"{url}:{self.json_port}"
|
|
1954
1965
|
return f"{url}"
|
|
1955
1966
|
|
|
1956
|
-
def create_json_rpc_client(self, central: CentralUnit) -> JsonRpcAioHttpClient:
|
|
1967
|
+
def create_json_rpc_client(self, *, central: CentralUnit) -> JsonRpcAioHttpClient:
|
|
1957
1968
|
"""Create a json rpc client."""
|
|
1958
1969
|
return JsonRpcAioHttpClient(
|
|
1959
1970
|
username=self.username,
|
|
@@ -1974,7 +1985,7 @@ class CentralConnectionState:
|
|
|
1974
1985
|
self._json_issues: Final[list[str]] = []
|
|
1975
1986
|
self._xml_proxy_issues: Final[list[str]] = []
|
|
1976
1987
|
|
|
1977
|
-
def add_issue(self, issuer: ConnectionProblemIssuer, iid: str) -> bool:
|
|
1988
|
+
def add_issue(self, *, issuer: ConnectionProblemIssuer, iid: str) -> bool:
|
|
1978
1989
|
"""Add issue to collection."""
|
|
1979
1990
|
if isinstance(issuer, JsonRpcAioHttpClient) and iid not in self._json_issues:
|
|
1980
1991
|
self._json_issues.append(iid)
|
|
@@ -1986,7 +1997,7 @@ class CentralConnectionState:
|
|
|
1986
1997
|
return True
|
|
1987
1998
|
return False
|
|
1988
1999
|
|
|
1989
|
-
def remove_issue(self, issuer: ConnectionProblemIssuer, iid: str) -> bool:
|
|
2000
|
+
def remove_issue(self, *, issuer: ConnectionProblemIssuer, iid: str) -> bool:
|
|
1990
2001
|
"""Add issue to collection."""
|
|
1991
2002
|
if isinstance(issuer, JsonRpcAioHttpClient) and iid in self._json_issues:
|
|
1992
2003
|
self._json_issues.remove(iid)
|
|
@@ -1998,7 +2009,7 @@ class CentralConnectionState:
|
|
|
1998
2009
|
return True
|
|
1999
2010
|
return False
|
|
2000
2011
|
|
|
2001
|
-
def has_issue(self, issuer: ConnectionProblemIssuer, iid: str) -> bool:
|
|
2012
|
+
def has_issue(self, *, issuer: ConnectionProblemIssuer, iid: str) -> bool:
|
|
2002
2013
|
"""Add issue to collection."""
|
|
2003
2014
|
if isinstance(issuer, JsonRpcAioHttpClient):
|
|
2004
2015
|
return iid in self._json_issues
|
|
@@ -2007,6 +2018,7 @@ class CentralConnectionState:
|
|
|
2007
2018
|
|
|
2008
2019
|
def handle_exception_log(
|
|
2009
2020
|
self,
|
|
2021
|
+
*,
|
|
2010
2022
|
issuer: ConnectionProblemIssuer,
|
|
2011
2023
|
iid: str,
|
|
2012
2024
|
exception: Exception,
|
|
@@ -2038,6 +2050,7 @@ class CentralConnectionState:
|
|
|
2038
2050
|
|
|
2039
2051
|
|
|
2040
2052
|
def _get_new_data_points(
|
|
2053
|
+
*,
|
|
2041
2054
|
new_devices: set[Device],
|
|
2042
2055
|
) -> Mapping[DataPointCategory, AbstractSet[CallbackDataPoint]]:
|
|
2043
2056
|
"""Return new data points by category."""
|
|
@@ -2053,7 +2066,7 @@ def _get_new_data_points(
|
|
|
2053
2066
|
return data_points_by_category
|
|
2054
2067
|
|
|
2055
2068
|
|
|
2056
|
-
def _get_new_channel_events(new_devices: set[Device]) -> tuple[tuple[GenericEvent, ...], ...]:
|
|
2069
|
+
def _get_new_channel_events(*, new_devices: set[Device]) -> tuple[tuple[GenericEvent, ...], ...]:
|
|
2057
2070
|
"""Return new channel events by category."""
|
|
2058
2071
|
channel_events: list[tuple[GenericEvent, ...]] = []
|
|
2059
2072
|
|