Skip to content

Commit

Permalink
Save if in service in context var
Browse files Browse the repository at this point in the history
  • Loading branch information
SukramJ committed Oct 1, 2024
1 parent 592bb9c commit 3f52b34
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 11 deletions.
3 changes: 3 additions & 0 deletions hahomematic/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from __future__ import annotations

import asyncio
from contextvars import ContextVar
import logging
import signal
import sys
Expand All @@ -16,6 +17,8 @@

from hahomematic import central as hmcu

IN_SERVICE_VAR: ContextVar[bool] = ContextVar("in_service_var", default=False)

if sys.stdout.isatty():
logging.basicConfig(level=logging.INFO)

Expand Down
2 changes: 1 addition & 1 deletion hahomematic/client/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ async def get_link_peers(self, address: str) -> tuple[str, ...] | None:
f"GET_LINK_PEERS failed with for: {address}: {reduce_args(args=ex.args)}"
) from ex

@service(level=logging.NOTSET)
@service(log_level=logging.NOTSET)
async def get_value(
self,
channel_address: str,
Expand Down
18 changes: 14 additions & 4 deletions hahomematic/platforms/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
from __future__ import annotations

from collections.abc import Awaitable, Callable
from contextvars import Token
from datetime import datetime
from enum import Enum
from functools import wraps
import logging
from typing import Any, ParamSpec, TypeVar

import hahomematic
from hahomematic.exceptions import BaseHomematicException
from hahomematic.support import reduce_args

Expand Down Expand Up @@ -129,7 +131,7 @@ def get_public_attributes_for_state_property(data_object: Any) -> dict[str, Any]
)


def service(level: int = logging.ERROR) -> Callable:
def service(log_level: int = logging.ERROR) -> Callable:
"""Mark function as service call and log exceptions."""

def service_decorator(func: Callable[P, Awaitable[T]]) -> Callable[P, Awaitable[T]]:
Expand All @@ -138,12 +140,20 @@ def service_decorator(func: Callable[P, Awaitable[T]]) -> Callable[P, Awaitable[
@wraps(func)
async def service_wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
"""Wrap service to log exception."""
token: Token | None = None
if not hahomematic.IN_SERVICE_VAR.get():
token = hahomematic.IN_SERVICE_VAR.set(True)
try:
return await func(*args, **kwargs)
return_value = await func(*args, **kwargs)
if token:
hahomematic.IN_SERVICE_VAR.reset(token)
return return_value # noqa: TRY300
except BaseHomematicException as bhe:
if level > logging.NOTSET:
if token:
hahomematic.IN_SERVICE_VAR.reset(token)
if not hahomematic.IN_SERVICE_VAR.get() and log_level > logging.NOTSET:
logging.getLogger(args[0].__module__).log(
level=level, msg=reduce_args(args=bhe.args)
level=log_level, msg=reduce_args(args=bhe.args)
)
raise

Expand Down
28 changes: 22 additions & 6 deletions hahomematic/platforms/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from abc import ABC, abstractmethod
from collections.abc import Callable, Mapping
from contextvars import Token
from datetime import datetime
from functools import partial, wraps
from inspect import getfullargspec
Expand All @@ -12,6 +13,7 @@

import voluptuous as vol

import hahomematic
from hahomematic import central as hmcu, client as hmcl, support as hms
from hahomematic.async_support import loop_check
from hahomematic.config import WAIT_FOR_CALLBACK
Expand Down Expand Up @@ -750,9 +752,8 @@ def __init__(self, client: hmcl.Client) -> None:
"""Init the generator."""
self._client: Final = client
self._central: Final = client.central
self._paramsets: Final[
dict[ParamsetKey, dict[int, dict[str, dict[str, Any]]]]
] = {} # {"VALUES": {50: {"00021BE9957782:3": {"STATE3": True}}}}
# {"VALUES": {50: {"00021BE9957782:3": {"STATE3": True}}}}
self._paramsets: Final[dict[ParamsetKey, dict[int, dict[str, dict[str, Any]]]]] = {}

def add_entity(
self,
Expand Down Expand Up @@ -833,16 +834,25 @@ def bind_decorator[_CallableT: Callable[..., Any]](func: _CallableT) -> _Callabl
@wraps(func)
async def bind_wrapper(*args: Any, **kwargs: Any) -> Any:
"""Wrap method to add collector."""
token: Token | None = None
if not hahomematic.IN_SERVICE_VAR.get():
token = hahomematic.IN_SERVICE_VAR.set(True)
try:
if not enabled:
return await func(*args, **kwargs)
return_value = await func(*args, **kwargs)
if token:
hahomematic.IN_SERVICE_VAR.reset(token)
return return_value
try:
collector_exists = args[argument_index] is not None
except IndexError:
collector_exists = kwargs.get(_COLLECTOR_ARGUMENT_NAME) is not None

if collector_exists:
return await func(*args, **kwargs)
return_value = await func(*args, **kwargs)
if token:
hahomematic.IN_SERVICE_VAR.reset(token)
return return_value
collector = CallParameterCollector(client=args[0].channel.device.client)
kwargs[_COLLECTOR_ARGUMENT_NAME] = collector
return_value = await func(*args, **kwargs)
Expand All @@ -851,12 +861,18 @@ async def bind_wrapper(*args: Any, **kwargs: Any) -> Any:
use_command_queue=use_command_queue,
use_put_paramset=use_put_paramset,
)
if token:
hahomematic.IN_SERVICE_VAR.reset(token)
return return_value # noqa:TRY300
except BaseHomematicException as bhe:
if log_level > logging.NOTSET:
if token:
hahomematic.IN_SERVICE_VAR.reset(token)
in_service = hahomematic.IN_SERVICE_VAR.get()
if not in_service and log_level > logging.NOTSET:
logging.getLogger(args[0].__module__).log(
level=log_level, msg=reduce_args(args=bhe.args)
)

return None

setattr(bind_wrapper, "ha_service", True)
Expand Down

0 comments on commit 3f52b34

Please sign in to comment.