Skip to content

Commit

Permalink
Separate enable/disable sysvar and program scan (#1719)
Browse files Browse the repository at this point in the history
* Separate enable/disable sysvar and program scan

* Fix default

* Fix test
  • Loading branch information
SukramJ authored Sep 24, 2024
1 parent 8e14097 commit 8134d13
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 22 deletions.
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
- Catch bind address errors of xml rpc server
- Refactor get_events, get_new_entities
- Remove unnecessary checks
- Separate enable/disable sysvar and program scan
- Use paramset_description from channel

# Version 2024.9.9 (2024-09-21)
Expand Down
24 changes: 18 additions & 6 deletions hahomematic/central/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
from hahomematic.const import (
CALLBACK_TYPE,
DATETIME_FORMAT_MILLIS,
DEFAULT_INCLUDE_INTERNAL_PROGRAMS,
DEFAULT_INCLUDE_INTERNAL_SYSVARS,
DEFAULT_PROGRAM_SCAN_ENABLED,
DEFAULT_SYSVAR_SCAN_ENABLED,
DEFAULT_TLS,
DEFAULT_VERIFY_TLS,
ENTITY_EVENTS,
Expand Down Expand Up @@ -568,8 +572,8 @@ async def _de_init_clients(self) -> None:

async def _init_hub(self) -> None:
"""Init the hub."""
await self._hub.fetch_program_data()
await self._hub.fetch_sysvar_data()
await self._hub.fetch_program_data(scheduled=True)
await self._hub.fetch_sysvar_data(scheduled=True)

@loop_check
def fire_interface_event(
Expand Down Expand Up @@ -1040,13 +1044,13 @@ async def execute_program(self, pid: str) -> bool:
return await client.execute_program(pid=pid)
return False

async def fetch_sysvar_data(self, include_internal: bool = True) -> None:
async def fetch_sysvar_data(self, scheduled: bool) -> None:
"""Fetch sysvar data for the hub."""
await self._hub.fetch_sysvar_data(include_internal=include_internal)
await self._hub.fetch_sysvar_data(scheduled=scheduled)

async def fetch_program_data(self, include_internal: bool = False) -> None:
async def fetch_program_data(self, scheduled: bool) -> None:
"""Fetch program data for the hub."""
await self._hub.fetch_program_data(include_internal=include_internal)
await self._hub.fetch_program_data(scheduled=scheduled)

@measure_execution_time
async def load_and_refresh_entity_data(self, paramset_key: ParamsetKey | None = None) -> None:
Expand Down Expand Up @@ -1412,6 +1416,10 @@ def __init__(
callback_port: int | None = None,
json_port: int | None = None,
un_ignore_list: list[str] | None = None,
program_scan_enabled: bool = DEFAULT_PROGRAM_SCAN_ENABLED,
include_internal_programs: bool = DEFAULT_INCLUDE_INTERNAL_PROGRAMS,
sysvar_scan_enabled: bool = DEFAULT_SYSVAR_SCAN_ENABLED,
include_internal_sysvars: bool = DEFAULT_INCLUDE_INTERNAL_SYSVARS,
start_direct: bool = False,
base_path: str | None = None,
) -> None:
Expand All @@ -1432,6 +1440,10 @@ def __init__(
self.callback_port: Final = callback_port
self.json_port: Final = json_port
self.un_ignore_list: Final = un_ignore_list
self.program_scan_enabled: Final = program_scan_enabled
self.include_internal_programs: Final = include_internal_programs
self.sysvar_scan_enabled: Final = sysvar_scan_enabled
self.include_internal_sysvars: Final = include_internal_sysvars
self.start_direct: Final = start_direct
self._json_rpc_client: JsonRpcAioHttpClient | None = None
self._base_path: Final = base_path
Expand Down
4 changes: 4 additions & 0 deletions hahomematic/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@
DEFAULT_CONNECTION_CHECKER_INTERVAL: Final = 15 # check if connection is available via rpc ping
DEFAULT_CUSTOM_ID: Final = "custom_id"
DEFAULT_ENCODING: Final = "UTF-8"
DEFAULT_INCLUDE_INTERNAL_PROGRAMS: Final = False
DEFAULT_INCLUDE_INTERNAL_SYSVARS: Final = True
DEFAULT_JSON_SESSION_AGE: Final = 90
DEFAULT_LAST_COMMAND_SEND_STORE_TIMEOUT: Final = 60
DEFAULT_PING_PONG_MISMATCH_COUNT: Final = 15
DEFAULT_PING_PONG_MISMATCH_COUNT_TTL: Final = 300
DEFAULT_PROGRAM_SCAN_ENABLED: Final = True
DEFAULT_RECONNECT_WAIT: Final = 120 # wait with reconnect after a first ping was successful
DEFAULT_SYSVAR_SCAN_ENABLED: Final = True
DEFAULT_TIMEOUT: Final = 60 # default timeout for a connection
DEFAULT_TLS: Final = False
DEFAULT_VERIFY_TLS: Final = False
Expand Down
41 changes: 29 additions & 12 deletions hahomematic/platforms/hub/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,24 +42,39 @@ def __init__(self, central: hmcu.CentralUnit) -> None:
self._sema_fetch_sysvars: Final = asyncio.Semaphore()
self._sema_fetch_programs: Final = asyncio.Semaphore()
self._central: Final = central
self._config: Final = central.config

async def fetch_sysvar_data(self, include_internal: bool = True) -> None:
async def fetch_sysvar_data(self, scheduled: bool) -> None:
"""Fetch sysvar data for the hub."""
async with self._sema_fetch_sysvars:
if self._central.available:
await self._update_sysvar_entities(include_internal=include_internal)
if self._config.sysvar_scan_enabled:
_LOGGER.debug(
"FETCH_SYSVAR_DATA: % fetching of system variables for %s",
"Scheduled" if scheduled else "Manual",
self._central.name,
)
async with self._sema_fetch_sysvars:
if self._central.available:
await self._update_sysvar_entities()

async def fetch_program_data(self, include_internal: bool = False) -> None:
async def fetch_program_data(self, scheduled: bool) -> None:
"""Fetch program data for the hub."""
async with self._sema_fetch_programs:
if self._central.available:
await self._update_program_entities(include_internal=include_internal)
if self._config.program_scan_enabled:
_LOGGER.debug(
"FETCH_PROGRAM_DATA: % fetching of programs for %s",
"Scheduled" if scheduled else "Manual",
self._central.name,
)
async with self._sema_fetch_programs:
if self._central.available:
await self._update_program_entities()

async def _update_program_entities(self, include_internal: bool) -> None:
async def _update_program_entities(self) -> None:
"""Retrieve all program data and update program values."""
programs: tuple[ProgramData, ...] = ()
if client := self._central.primary_client:
programs = await client.get_all_programs(include_internal=include_internal)
programs = await client.get_all_programs(
include_internal=self._config.include_internal_programs
)
if not programs:
_LOGGER.debug(
"UPDATE_PROGRAM_ENTITIES: No programs received for %s",
Expand Down Expand Up @@ -89,11 +104,13 @@ async def _update_program_entities(self, include_internal: bool) -> None:
new_hub_entities=_get_new_hub_entities(entities=new_programs),
)

async def _update_sysvar_entities(self, include_internal: bool = True) -> None:
async def _update_sysvar_entities(self) -> None:
"""Retrieve all variable data and update hmvariable values."""
variables: tuple[SystemVariableData, ...] = ()
if client := self._central.primary_client:
variables = await client.get_all_system_variables(include_internal=include_internal)
variables = await client.get_all_system_variables(
include_internal=self._config.include_internal_sysvars
)
if not variables:
_LOGGER.debug(
"UPDATE_SYSVAR_ENTITIES: No sysvars received for %s",
Expand Down
14 changes: 10 additions & 4 deletions tests/test_central.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
from hahomematic.config import PING_PONG_MISMATCH_COUNT
from hahomematic.const import (
DATETIME_FORMAT_MILLIS,
DEFAULT_INCLUDE_INTERNAL_PROGRAMS,
DEFAULT_INCLUDE_INTERNAL_SYSVARS,
EVENT_AVAILABLE,
EntityUsage,
HmPlatform,
Expand Down Expand Up @@ -748,11 +750,15 @@ async def test_central_services(
) -> None:
"""Test central fetch sysvar and programs."""
central, mock_client, _ = central_client_factory
await central.fetch_program_data()
assert mock_client.method_calls[-1] == call.get_all_programs(include_internal=False)
await central.fetch_program_data(scheduled=True)
assert mock_client.method_calls[-1] == call.get_all_programs(
include_internal=DEFAULT_INCLUDE_INTERNAL_PROGRAMS
)

await central.fetch_sysvar_data()
assert mock_client.method_calls[-1] == call.get_all_system_variables(include_internal=True)
await central.fetch_sysvar_data(scheduled=True)
assert mock_client.method_calls[-1] == call.get_all_system_variables(
include_internal=DEFAULT_INCLUDE_INTERNAL_SYSVARS
)

assert len(mock_client.method_calls) == 39
await central.load_and_refresh_entity_data(paramset_key=ParamsetKey.MASTER)
Expand Down

0 comments on commit 8134d13

Please sign in to comment.