aiohomematic-test-support 2025.11.3__tar.gz → 2025.11.11__tar.gz
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.
- {aiohomematic_test_support-2025.11.3/aiohomematic_test_support.egg-info → aiohomematic_test_support-2025.11.11}/PKG-INFO +1 -1
- {aiohomematic_test_support-2025.11.3 → aiohomematic_test_support-2025.11.11}/__init__.py +1 -1
- {aiohomematic_test_support-2025.11.3 → aiohomematic_test_support-2025.11.11/aiohomematic_test_support.egg-info}/PKG-INFO +1 -1
- {aiohomematic_test_support-2025.11.3 → aiohomematic_test_support-2025.11.11}/mock.py +128 -128
- {aiohomematic_test_support-2025.11.3 → aiohomematic_test_support-2025.11.11}/MANIFEST.in +0 -0
- {aiohomematic_test_support-2025.11.3 → aiohomematic_test_support-2025.11.11}/README.md +0 -0
- {aiohomematic_test_support-2025.11.3 → aiohomematic_test_support-2025.11.11}/aiohomematic_test_support.egg-info/SOURCES.txt +0 -0
- {aiohomematic_test_support-2025.11.3 → aiohomematic_test_support-2025.11.11}/aiohomematic_test_support.egg-info/dependency_links.txt +0 -0
- {aiohomematic_test_support-2025.11.3 → aiohomematic_test_support-2025.11.11}/aiohomematic_test_support.egg-info/top_level.txt +0 -0
- {aiohomematic_test_support-2025.11.3 → aiohomematic_test_support-2025.11.11}/const.py +0 -0
- {aiohomematic_test_support-2025.11.3 → aiohomematic_test_support-2025.11.11}/data/full_session_randomized_ccu.zip +0 -0
- {aiohomematic_test_support-2025.11.3 → aiohomematic_test_support-2025.11.11}/data/full_session_randomized_pydevccu.zip +0 -0
- {aiohomematic_test_support-2025.11.3 → aiohomematic_test_support-2025.11.11}/factory.py +56 -56
- {aiohomematic_test_support-2025.11.3 → aiohomematic_test_support-2025.11.11}/helper.py +0 -0
- {aiohomematic_test_support-2025.11.3 → aiohomematic_test_support-2025.11.11}/py.typed +0 -0
- {aiohomematic_test_support-2025.11.3 → aiohomematic_test_support-2025.11.11}/pyproject.toml +0 -0
- {aiohomematic_test_support-2025.11.3 → aiohomematic_test_support-2025.11.11}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aiohomematic-test-support
|
|
3
|
-
Version: 2025.11.
|
|
3
|
+
Version: 2025.11.11
|
|
4
4
|
Summary: Support-only package for AioHomematic (tests/dev). Not part of production builds.
|
|
5
5
|
Author-email: SukramJ <sukramj@icloud.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/SukramJ/aiohomematic
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
__version__ = "2025.11.
|
|
1
|
+
__version__ = "2025.11.11"
|
|
2
2
|
"""Module to support aiohomematic testing with a local client."""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aiohomematic-test-support
|
|
3
|
-
Version: 2025.11.
|
|
3
|
+
Version: 2025.11.11
|
|
4
4
|
Summary: Support-only package for AioHomematic (tests/dev). Not part of production builds.
|
|
5
5
|
Author-email: SukramJ <sukramj@icloud.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/SukramJ/aiohomematic
|
|
@@ -63,9 +63,9 @@ def get_client_session( # noqa: C901
|
|
|
63
63
|
"""
|
|
64
64
|
|
|
65
65
|
class _MockResponse:
|
|
66
|
-
def __init__(self, *, json_data: dict | None) -> None:
|
|
66
|
+
def __init__(self, *, json_data: dict[str, Any] | None) -> None:
|
|
67
67
|
# If no match is found, emulate backend error payload
|
|
68
|
-
self._json = json_data or {
|
|
68
|
+
self._json: dict[str, Any] = json_data or {
|
|
69
69
|
_JsonKey.RESULT: None,
|
|
70
70
|
_JsonKey.ERROR: {"name": "-1", "code": -1, "message": "Not found in session player"},
|
|
71
71
|
_JsonKey.ID: 0,
|
|
@@ -83,9 +83,8 @@ def get_client_session( # noqa: C901
|
|
|
83
83
|
"""Initialize the mock client session."""
|
|
84
84
|
self._central: CentralUnit | None = None
|
|
85
85
|
|
|
86
|
-
def
|
|
87
|
-
|
|
88
|
-
self._central = central
|
|
86
|
+
async def close(self) -> None: # compatibility
|
|
87
|
+
return None
|
|
89
88
|
|
|
90
89
|
async def post(
|
|
91
90
|
self,
|
|
@@ -187,8 +186,9 @@ def get_client_session( # noqa: C901
|
|
|
187
186
|
json_data[_JsonKey.RESULT] = new_devices
|
|
188
187
|
return _MockResponse(json_data=json_data)
|
|
189
188
|
|
|
190
|
-
|
|
191
|
-
|
|
189
|
+
def set_central(self, *, central: CentralUnit) -> None:
|
|
190
|
+
"""Set the central."""
|
|
191
|
+
self._central = central
|
|
192
192
|
|
|
193
193
|
return cast(ClientSession, _MockClientSession())
|
|
194
194
|
|
|
@@ -212,29 +212,40 @@ def get_xml_rpc_proxy( # noqa: C901
|
|
|
212
212
|
self._name = full_name
|
|
213
213
|
self._caller = caller
|
|
214
214
|
|
|
215
|
-
def __getattr__(self, sub: str) -> _Method:
|
|
216
|
-
# Allow chaining like proxy.system.listMethods
|
|
217
|
-
return _Method(f"{self._name}.{sub}", self._caller)
|
|
218
|
-
|
|
219
215
|
async def __call__(self, *args: Any) -> Any:
|
|
220
216
|
# Forward to caller with collected method name and positional params
|
|
221
217
|
return await self._caller(self._name, *args)
|
|
222
218
|
|
|
219
|
+
def __getattr__(self, sub: str) -> _Method:
|
|
220
|
+
# Allow chaining like proxy.system.listMethods
|
|
221
|
+
return _Method(f"{self._name}.{sub}", self._caller)
|
|
222
|
+
|
|
223
223
|
class _AioXmlRpcProxyFromSession:
|
|
224
224
|
def __init__(self) -> None:
|
|
225
225
|
self._player = player
|
|
226
226
|
self._supported_methods: tuple[str, ...] = ()
|
|
227
227
|
self._central: CentralUnit | None = None
|
|
228
228
|
|
|
229
|
-
def
|
|
230
|
-
|
|
231
|
-
self.
|
|
229
|
+
def __getattr__(self, name: str) -> Any:
|
|
230
|
+
# Start of method chain
|
|
231
|
+
return _Method(name, self._invoke)
|
|
232
232
|
|
|
233
233
|
@property
|
|
234
234
|
def supported_methods(self) -> tuple[str, ...]:
|
|
235
235
|
"""Return the supported methods."""
|
|
236
236
|
return self._supported_methods
|
|
237
237
|
|
|
238
|
+
async def clientServerInitialized(self, interface_id: str) -> None:
|
|
239
|
+
"""Answer clientServerInitialized with pong."""
|
|
240
|
+
await self.ping(callerId=interface_id)
|
|
241
|
+
|
|
242
|
+
async def do_init(self) -> None:
|
|
243
|
+
"""Init the xml rpc proxy."""
|
|
244
|
+
if supported_methods := await self.system.listMethods():
|
|
245
|
+
# ping is missing in VirtualDevices interface but can be used.
|
|
246
|
+
supported_methods.append(_RpcMethod.PING)
|
|
247
|
+
self._supported_methods = tuple(supported_methods)
|
|
248
|
+
|
|
238
249
|
async def getAllSystemVariables(self) -> dict[str, Any]:
|
|
239
250
|
"""Return all system variables."""
|
|
240
251
|
return const.SYSVAR_DATA_XML
|
|
@@ -249,41 +260,6 @@ def get_xml_rpc_proxy( # noqa: C901
|
|
|
249
260
|
)
|
|
250
261
|
return result if result else {}
|
|
251
262
|
|
|
252
|
-
async def setValue(self, channel_address: str, parameter: str, value: Any, rx_mode: Any | None = None) -> None:
|
|
253
|
-
"""Set a value."""
|
|
254
|
-
if self._central:
|
|
255
|
-
await self._central.data_point_event(
|
|
256
|
-
interface_id=self._central.primary_client.interface_id, # type: ignore[union-attr]
|
|
257
|
-
channel_address=channel_address,
|
|
258
|
-
parameter=parameter,
|
|
259
|
-
value=value,
|
|
260
|
-
)
|
|
261
|
-
|
|
262
|
-
async def putParamset(
|
|
263
|
-
self, channel_address: str, paramset_key: str, values: Any, rx_mode: Any | None = None
|
|
264
|
-
) -> None:
|
|
265
|
-
"""Set a paramset."""
|
|
266
|
-
if self._central and paramset_key == ParamsetKey.VALUES:
|
|
267
|
-
interface_id = self._central.primary_client.interface_id # type: ignore[union-attr]
|
|
268
|
-
for param, value in values.items():
|
|
269
|
-
await self._central.data_point_event(
|
|
270
|
-
interface_id=interface_id, channel_address=channel_address, parameter=param, value=value
|
|
271
|
-
)
|
|
272
|
-
|
|
273
|
-
async def ping(self, callerId: str) -> None:
|
|
274
|
-
"""Answer ping with pong."""
|
|
275
|
-
if self._central:
|
|
276
|
-
await self._central.data_point_event(
|
|
277
|
-
interface_id=callerId,
|
|
278
|
-
channel_address="",
|
|
279
|
-
parameter=Parameter.PONG,
|
|
280
|
-
value=callerId,
|
|
281
|
-
)
|
|
282
|
-
|
|
283
|
-
async def clientServerInitialized(self, interface_id: str) -> None:
|
|
284
|
-
"""Answer clientServerInitialized with pong."""
|
|
285
|
-
await self.ping(callerId=interface_id)
|
|
286
|
-
|
|
287
263
|
async def listDevices(self) -> list[Any]:
|
|
288
264
|
"""Return a list of devices."""
|
|
289
265
|
devices = self._player.get_latest_response_by_params(
|
|
@@ -309,9 +285,43 @@ def get_xml_rpc_proxy( # noqa: C901
|
|
|
309
285
|
|
|
310
286
|
return new_devices
|
|
311
287
|
|
|
312
|
-
def
|
|
313
|
-
|
|
314
|
-
|
|
288
|
+
async def ping(self, callerId: str) -> None:
|
|
289
|
+
"""Answer ping with pong."""
|
|
290
|
+
if self._central:
|
|
291
|
+
await self._central.data_point_event(
|
|
292
|
+
interface_id=callerId,
|
|
293
|
+
channel_address="",
|
|
294
|
+
parameter=Parameter.PONG,
|
|
295
|
+
value=callerId,
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
async def putParamset(
|
|
299
|
+
self, channel_address: str, paramset_key: str, values: Any, rx_mode: Any | None = None
|
|
300
|
+
) -> None:
|
|
301
|
+
"""Set a paramset."""
|
|
302
|
+
if self._central and paramset_key == ParamsetKey.VALUES:
|
|
303
|
+
interface_id = self._central.primary_client.interface_id # type: ignore[union-attr]
|
|
304
|
+
for param, value in values.items():
|
|
305
|
+
await self._central.data_point_event(
|
|
306
|
+
interface_id=interface_id, channel_address=channel_address, parameter=param, value=value
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
async def setValue(self, channel_address: str, parameter: str, value: Any, rx_mode: Any | None = None) -> None:
|
|
310
|
+
"""Set a value."""
|
|
311
|
+
if self._central:
|
|
312
|
+
await self._central.data_point_event(
|
|
313
|
+
interface_id=self._central.primary_client.interface_id, # type: ignore[union-attr]
|
|
314
|
+
channel_address=channel_address,
|
|
315
|
+
parameter=parameter,
|
|
316
|
+
value=value,
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
def set_central(self, *, central: CentralUnit) -> None:
|
|
320
|
+
"""Set the central."""
|
|
321
|
+
self._central = central
|
|
322
|
+
|
|
323
|
+
async def stop(self) -> None: # compatibility with AioXmlRpcProxy.stop
|
|
324
|
+
return None
|
|
315
325
|
|
|
316
326
|
async def _invoke(self, method: str, *args: Any) -> Any:
|
|
317
327
|
params = tuple(args)
|
|
@@ -321,16 +331,6 @@ def get_xml_rpc_proxy( # noqa: C901
|
|
|
321
331
|
params=params,
|
|
322
332
|
)
|
|
323
333
|
|
|
324
|
-
async def stop(self) -> None: # compatibility with AioXmlRpcProxy.stop
|
|
325
|
-
return None
|
|
326
|
-
|
|
327
|
-
async def do_init(self) -> None:
|
|
328
|
-
"""Init the xml rpc proxy."""
|
|
329
|
-
if supported_methods := await self.system.listMethods():
|
|
330
|
-
# ping is missing in VirtualDevices interface but can be used.
|
|
331
|
-
supported_methods.append(_RpcMethod.PING)
|
|
332
|
-
self._supported_methods = tuple(supported_methods)
|
|
333
|
-
|
|
334
334
|
return cast(BaseRpcProxy, _AioXmlRpcProxyFromSession())
|
|
335
335
|
|
|
336
336
|
|
|
@@ -389,45 +389,23 @@ class SessionPlayer:
|
|
|
389
389
|
"""Return the secondary store for the given file_id."""
|
|
390
390
|
return [fid for fid in self._store if fid != self._file_id]
|
|
391
391
|
|
|
392
|
-
def
|
|
393
|
-
"""Return
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
Supports plain JSON files and ZIP archives containing a JSON file.
|
|
401
|
-
When a ZIP archive is provided, the first JSON member inside the archive
|
|
402
|
-
will be loaded.
|
|
403
|
-
"""
|
|
404
|
-
|
|
405
|
-
if self.supports_file_id(file_id=file_id):
|
|
406
|
-
return DataOperationResult.NO_LOAD
|
|
407
|
-
|
|
408
|
-
if not os.path.exists(file_path):
|
|
409
|
-
return DataOperationResult.NO_LOAD
|
|
410
|
-
|
|
411
|
-
def _perform_load() -> DataOperationResult:
|
|
412
|
-
try:
|
|
413
|
-
if zipfile.is_zipfile(file_path):
|
|
414
|
-
with zipfile.ZipFile(file_path, mode="r") as zf:
|
|
415
|
-
# Prefer json files; pick the first .json entry if available
|
|
416
|
-
if not (json_members := [n for n in zf.namelist() if n.lower().endswith(".json")]):
|
|
417
|
-
return DataOperationResult.LOAD_FAIL
|
|
418
|
-
raw = zf.read(json_members[0]).decode(UTF_8)
|
|
419
|
-
data = json.loads(raw)
|
|
420
|
-
else:
|
|
421
|
-
with open(file=file_path, encoding=UTF_8) as file_pointer:
|
|
422
|
-
data = json.loads(file_pointer.read())
|
|
423
|
-
|
|
424
|
-
self._store[file_id] = data
|
|
425
|
-
except (json.JSONDecodeError, zipfile.BadZipFile, UnicodeDecodeError, OSError):
|
|
426
|
-
return DataOperationResult.LOAD_FAIL
|
|
427
|
-
return DataOperationResult.LOAD_SUCCESS
|
|
392
|
+
def get_latest_response_by_method(self, *, rpc_type: str, method: str) -> list[tuple[Any, Any]]:
|
|
393
|
+
"""Return latest non-expired responses for a given (rpc_type, method)."""
|
|
394
|
+
if pri_result := self.get_latest_response_by_method_for_file_id(
|
|
395
|
+
file_id=self._file_id,
|
|
396
|
+
rpc_type=rpc_type,
|
|
397
|
+
method=method,
|
|
398
|
+
):
|
|
399
|
+
return pri_result
|
|
428
400
|
|
|
429
|
-
|
|
430
|
-
|
|
401
|
+
for secondary_file_id in self._secondary_file_ids:
|
|
402
|
+
if sec_result := self.get_latest_response_by_method_for_file_id(
|
|
403
|
+
file_id=secondary_file_id,
|
|
404
|
+
rpc_type=rpc_type,
|
|
405
|
+
method=method,
|
|
406
|
+
):
|
|
407
|
+
return sec_result
|
|
408
|
+
return pri_result
|
|
431
409
|
|
|
432
410
|
def get_latest_response_by_method_for_file_id(
|
|
433
411
|
self, *, file_id: str, rpc_type: str, method: str
|
|
@@ -453,20 +431,28 @@ class SessionPlayer:
|
|
|
453
431
|
result.append((params, resp))
|
|
454
432
|
return result
|
|
455
433
|
|
|
456
|
-
def
|
|
457
|
-
|
|
458
|
-
|
|
434
|
+
def get_latest_response_by_params(
|
|
435
|
+
self,
|
|
436
|
+
*,
|
|
437
|
+
rpc_type: str,
|
|
438
|
+
method: str,
|
|
439
|
+
params: Any,
|
|
440
|
+
) -> Any:
|
|
441
|
+
"""Return latest non-expired responses for a given (rpc_type, method, params)."""
|
|
442
|
+
if pri_result := self.get_latest_response_by_params_for_file_id(
|
|
459
443
|
file_id=self._file_id,
|
|
460
444
|
rpc_type=rpc_type,
|
|
461
445
|
method=method,
|
|
446
|
+
params=params,
|
|
462
447
|
):
|
|
463
448
|
return pri_result
|
|
464
449
|
|
|
465
450
|
for secondary_file_id in self._secondary_file_ids:
|
|
466
|
-
if sec_result := self.
|
|
451
|
+
if sec_result := self.get_latest_response_by_params_for_file_id(
|
|
467
452
|
file_id=secondary_file_id,
|
|
468
453
|
rpc_type=rpc_type,
|
|
469
454
|
method=method,
|
|
455
|
+
params=params,
|
|
470
456
|
):
|
|
471
457
|
return sec_result
|
|
472
458
|
return pri_result
|
|
@@ -497,28 +483,42 @@ class SessionPlayer:
|
|
|
497
483
|
except ValueError:
|
|
498
484
|
return None
|
|
499
485
|
|
|
500
|
-
def
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
rpc_type: str,
|
|
504
|
-
method: str,
|
|
505
|
-
params: Any,
|
|
506
|
-
) -> Any:
|
|
507
|
-
"""Return latest non-expired responses for a given (rpc_type, method, params)."""
|
|
508
|
-
if pri_result := self.get_latest_response_by_params_for_file_id(
|
|
509
|
-
file_id=self._file_id,
|
|
510
|
-
rpc_type=rpc_type,
|
|
511
|
-
method=method,
|
|
512
|
-
params=params,
|
|
513
|
-
):
|
|
514
|
-
return pri_result
|
|
486
|
+
async def load(self, *, file_path: str, file_id: str) -> DataOperationResult:
|
|
487
|
+
"""
|
|
488
|
+
Load data from disk into the dictionary.
|
|
515
489
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
490
|
+
Supports plain JSON files and ZIP archives containing a JSON file.
|
|
491
|
+
When a ZIP archive is provided, the first JSON member inside the archive
|
|
492
|
+
will be loaded.
|
|
493
|
+
"""
|
|
494
|
+
|
|
495
|
+
if self.supports_file_id(file_id=file_id):
|
|
496
|
+
return DataOperationResult.NO_LOAD
|
|
497
|
+
|
|
498
|
+
if not os.path.exists(file_path):
|
|
499
|
+
return DataOperationResult.NO_LOAD
|
|
500
|
+
|
|
501
|
+
def _perform_load() -> DataOperationResult:
|
|
502
|
+
try:
|
|
503
|
+
if zipfile.is_zipfile(file_path):
|
|
504
|
+
with zipfile.ZipFile(file_path, mode="r") as zf:
|
|
505
|
+
# Prefer json files; pick the first .json entry if available
|
|
506
|
+
if not (json_members := [n for n in zf.namelist() if n.lower().endswith(".json")]):
|
|
507
|
+
return DataOperationResult.LOAD_FAIL
|
|
508
|
+
raw = zf.read(json_members[0]).decode(UTF_8)
|
|
509
|
+
data = json.loads(raw)
|
|
510
|
+
else:
|
|
511
|
+
with open(file=file_path, encoding=UTF_8) as file_pointer:
|
|
512
|
+
data = json.loads(file_pointer.read())
|
|
513
|
+
|
|
514
|
+
self._store[file_id] = data
|
|
515
|
+
except (json.JSONDecodeError, zipfile.BadZipFile, UnicodeDecodeError, OSError):
|
|
516
|
+
return DataOperationResult.LOAD_FAIL
|
|
517
|
+
return DataOperationResult.LOAD_SUCCESS
|
|
518
|
+
|
|
519
|
+
loop = asyncio.get_running_loop()
|
|
520
|
+
return await loop.run_in_executor(None, _perform_load)
|
|
521
|
+
|
|
522
|
+
def supports_file_id(self, *, file_id: str) -> bool:
|
|
523
|
+
"""Return whether the session player supports the given file_id."""
|
|
524
|
+
return file_id in self._store
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -52,6 +52,62 @@ class FactoryWithClient:
|
|
|
52
52
|
self.system_event_mock = MagicMock()
|
|
53
53
|
self.ha_event_mock = MagicMock()
|
|
54
54
|
|
|
55
|
+
async def get_default_central(self, *, start: bool = True) -> CentralUnit:
|
|
56
|
+
"""Return a central based on give address_device_translation."""
|
|
57
|
+
central = await self.get_raw_central()
|
|
58
|
+
|
|
59
|
+
await self._xml_proxy.do_init()
|
|
60
|
+
patch("aiohomematic.client.ClientConfig._create_xml_rpc_proxy", return_value=self._xml_proxy).start()
|
|
61
|
+
patch("aiohomematic.central.CentralUnit._identify_ip_addr", return_value=LOCAL_HOST).start()
|
|
62
|
+
|
|
63
|
+
# Optionally patch client creation to return a mocked client
|
|
64
|
+
if self._do_mock_client:
|
|
65
|
+
_orig_create_client = ClientConfig.create_client
|
|
66
|
+
|
|
67
|
+
async def _mocked_create_client(config: ClientConfig) -> Client | Mock:
|
|
68
|
+
real_client = await _orig_create_client(config)
|
|
69
|
+
return cast(
|
|
70
|
+
Mock,
|
|
71
|
+
get_mock(
|
|
72
|
+
instance=real_client,
|
|
73
|
+
exclude_methods=self._exclude_methods_from_mocks,
|
|
74
|
+
include_properties=self._include_properties_in_mocks,
|
|
75
|
+
),
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
patch("aiohomematic.client.ClientConfig.create_client", _mocked_create_client).start()
|
|
79
|
+
|
|
80
|
+
if start:
|
|
81
|
+
await central.start()
|
|
82
|
+
await central._init_hub()
|
|
83
|
+
assert central
|
|
84
|
+
return central
|
|
85
|
+
|
|
86
|
+
async def get_raw_central(self) -> CentralUnit:
|
|
87
|
+
"""Return a central based on give address_device_translation."""
|
|
88
|
+
interface_configs = self._interface_configs if self._interface_configs else set()
|
|
89
|
+
central = CentralConfig(
|
|
90
|
+
name=const.CENTRAL_NAME,
|
|
91
|
+
host=const.CCU_HOST,
|
|
92
|
+
username=const.CCU_USERNAME,
|
|
93
|
+
password=const.CCU_PASSWORD,
|
|
94
|
+
central_id="test1234",
|
|
95
|
+
interface_configs=interface_configs,
|
|
96
|
+
client_session=self._client_session,
|
|
97
|
+
un_ignore_list=self._un_ignore_list,
|
|
98
|
+
ignore_custom_device_definition_models=frozenset(self._ignore_custom_device_definition_models or []),
|
|
99
|
+
start_direct=True,
|
|
100
|
+
optional_settings=(OptionalSettings.ENABLE_LINKED_ENTITY_CLIMATE_ACTIVITY,),
|
|
101
|
+
).create_central()
|
|
102
|
+
|
|
103
|
+
central.register_backend_system_callback(cb=self.system_event_mock)
|
|
104
|
+
central.register_homematic_callback(cb=self.ha_event_mock)
|
|
105
|
+
|
|
106
|
+
assert central
|
|
107
|
+
self._client_session.set_central(central=central) # type: ignore[attr-defined]
|
|
108
|
+
self._xml_proxy.set_central(central=central)
|
|
109
|
+
return central
|
|
110
|
+
|
|
55
111
|
def init(
|
|
56
112
|
self,
|
|
57
113
|
*,
|
|
@@ -95,62 +151,6 @@ class FactoryWithClient:
|
|
|
95
151
|
)
|
|
96
152
|
return self
|
|
97
153
|
|
|
98
|
-
async def get_raw_central(self) -> CentralUnit:
|
|
99
|
-
"""Return a central based on give address_device_translation."""
|
|
100
|
-
interface_configs = self._interface_configs if self._interface_configs else set()
|
|
101
|
-
central = CentralConfig(
|
|
102
|
-
name=const.CENTRAL_NAME,
|
|
103
|
-
host=const.CCU_HOST,
|
|
104
|
-
username=const.CCU_USERNAME,
|
|
105
|
-
password=const.CCU_PASSWORD,
|
|
106
|
-
central_id="test1234",
|
|
107
|
-
interface_configs=interface_configs,
|
|
108
|
-
client_session=self._client_session,
|
|
109
|
-
un_ignore_list=self._un_ignore_list,
|
|
110
|
-
ignore_custom_device_definition_models=frozenset(self._ignore_custom_device_definition_models or []),
|
|
111
|
-
start_direct=True,
|
|
112
|
-
optional_settings=(OptionalSettings.ENABLE_LINKED_ENTITY_CLIMATE_ACTIVITY,),
|
|
113
|
-
).create_central()
|
|
114
|
-
|
|
115
|
-
central.register_backend_system_callback(cb=self.system_event_mock)
|
|
116
|
-
central.register_homematic_callback(cb=self.ha_event_mock)
|
|
117
|
-
|
|
118
|
-
assert central
|
|
119
|
-
self._client_session.set_central(central=central) # type: ignore[attr-defined]
|
|
120
|
-
self._xml_proxy.set_central(central=central)
|
|
121
|
-
return central
|
|
122
|
-
|
|
123
|
-
async def get_default_central(self, *, start: bool = True) -> CentralUnit:
|
|
124
|
-
"""Return a central based on give address_device_translation."""
|
|
125
|
-
central = await self.get_raw_central()
|
|
126
|
-
|
|
127
|
-
await self._xml_proxy.do_init()
|
|
128
|
-
patch("aiohomematic.client.ClientConfig._create_xml_rpc_proxy", return_value=self._xml_proxy).start()
|
|
129
|
-
patch("aiohomematic.central.CentralUnit._identify_ip_addr", return_value=LOCAL_HOST).start()
|
|
130
|
-
|
|
131
|
-
# Optionally patch client creation to return a mocked client
|
|
132
|
-
if self._do_mock_client:
|
|
133
|
-
_orig_create_client = ClientConfig.create_client
|
|
134
|
-
|
|
135
|
-
async def _mocked_create_client(config: ClientConfig) -> Client | Mock:
|
|
136
|
-
real_client = await _orig_create_client(config)
|
|
137
|
-
return cast(
|
|
138
|
-
Mock,
|
|
139
|
-
get_mock(
|
|
140
|
-
instance=real_client,
|
|
141
|
-
exclude_methods=self._exclude_methods_from_mocks,
|
|
142
|
-
include_properties=self._include_properties_in_mocks,
|
|
143
|
-
),
|
|
144
|
-
)
|
|
145
|
-
|
|
146
|
-
patch("aiohomematic.client.ClientConfig.create_client", _mocked_create_client).start()
|
|
147
|
-
|
|
148
|
-
if start:
|
|
149
|
-
await central.start()
|
|
150
|
-
await central._init_hub()
|
|
151
|
-
assert central
|
|
152
|
-
return central
|
|
153
|
-
|
|
154
154
|
|
|
155
155
|
async def get_central_client_factory(
|
|
156
156
|
*,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|