Skip to content

Commit

Permalink
Check rx_mode (#1679)
Browse files Browse the repository at this point in the history
* Add RxMode to device

* Fix

* Fix

* Check rx_mode

* Update changelog.md
  • Loading branch information
SukramJ authored Aug 29, 2024
1 parent bee0b6c commit fe7cba9
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 24 deletions.
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Version 2024.8.15 (2024-08-26)

- Avoid permanent cache save on remove device
- Check rx_mode
- Ensure only one load/save of cache file at time
- Small definition fix for DALI
- Use ParameterData for paramset descriptions
Expand Down
35 changes: 25 additions & 10 deletions hahomematic/client/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
VIRTUAL_REMOTE_TYPES,
Backend,
CallSource,
CommandRxMode,
Description,
DeviceDescription,
ForcedDeviceAvailability,
Expand All @@ -42,7 +43,13 @@
from hahomematic.performance import measure_execution_time
from hahomematic.platforms.device import HmDevice
from hahomematic.platforms.support import convert_value
from hahomematic.support import build_headers, build_xml_rpc_uri, get_device_address, reduce_args
from hahomematic.support import (
build_headers,
build_xml_rpc_uri,
get_device_address,
reduce_args,
supports_rx_mode,
)

_LOGGER: Final = logging.getLogger(__name__)

Expand Down Expand Up @@ -427,7 +434,7 @@ async def _set_value(
parameter: str,
value: Any,
wait_for_callback: int | None,
rx_mode: str | None = None,
rx_mode: CommandRxMode | None = None,
check_against_pd: bool = False,
) -> set[ENTITY_KEY]:
"""Set single value on paramset VALUES."""
Expand All @@ -443,8 +450,12 @@ async def _set_value(
else value
)
_LOGGER.debug("SET_VALUE: %s, %s, %s", channel_address, parameter, checked_value)
if rx_mode:
await self._proxy.setValue(channel_address, parameter, checked_value, rx_mode)
if rx_mode and (device := self.central.get_device(address=channel_address)):
if supports_rx_mode(command_rx_mode=rx_mode, rx_modes=device.rx_modes):
await self._proxy.setValue(channel_address, parameter, checked_value, rx_mode)
else:
_LOGGER.warning("SET_VALUE failed: unsupported rx_mode: %s", rx_mode)
return set()
else:
await self._proxy.setValue(channel_address, parameter, checked_value)
# store the send value in the last_value_send_cache
Expand Down Expand Up @@ -493,7 +504,7 @@ async def set_value(
parameter: str,
value: Any,
wait_for_callback: int | None = WAIT_FOR_CALLBACK,
rx_mode: str | None = None,
rx_mode: CommandRxMode | None = None,
check_against_pd: bool = False,
) -> set[ENTITY_KEY]:
"""Set single value on paramset VALUES."""
Expand Down Expand Up @@ -546,7 +557,7 @@ async def put_paramset(
paramset_key: ParamsetKey,
values: dict[str, Any],
wait_for_callback: int | None = WAIT_FOR_CALLBACK,
rx_mode: str | None = None,
rx_mode: CommandRxMode | None = None,
check_against_pd: bool = False,
) -> set[ENTITY_KEY]:
"""
Expand All @@ -566,10 +577,14 @@ async def put_paramset(
_LOGGER.debug(
"PUT_PARAMSET: %s, %s, %s", channel_address, paramset_key, checked_values
)
if rx_mode:
await self._proxy.putParamset(
channel_address, paramset_key, checked_values, rx_mode
)
if rx_mode and (device := self.central.get_device(address=channel_address)):
if supports_rx_mode(command_rx_mode=rx_mode, rx_modes=device.rx_modes):
await self._proxy.putParamset(
channel_address, paramset_key, checked_values, rx_mode
)
else:
_LOGGER.warning("PUT_PARAMSET failed: unsupported rx_mode: %s", rx_mode)
return set()
else:
await self._proxy.putParamset(channel_address, paramset_key, checked_values)
# store the send value in the last_value_send_cache
Expand Down
32 changes: 20 additions & 12 deletions hahomematic/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,24 +124,14 @@ class DataOperationResult(Enum):
class Description(StrEnum):
"""Enum with homematic device/paramset description attributes."""

ADDRESS = "ADDRESS"
AVAILABLE_FIRMWARE = "AVAILABLE_FIRMWARE"
CHILDREN = "CHILDREN"
DEFAULT = "DEFAULT"
FIRMWARE = "FIRMWARE"
FIRMWARE_UPDATABLE = "UPDATABLE"
FIRMWARE_UPDATE_STATE = "FIRMWARE_UPDATE_STATE"
FLAGS = "FLAGS"
MAX = "MAX"
MIN = "MIN"
NAME = "NAME"
ID = "ID"
OPERATIONS = "OPERATIONS"
PARAMSETS = "PARAMSETS"
PARENT = "PARENT"
PARENT_TYPE = "PARENT_TYPE"
SPECIAL = "SPECIAL" # Which has the following keys
SUBTYPE = "SUBTYPE"
SPECIAL = "SPECIAL"
TYPE = "TYPE"
UNIT = "UNIT"
VALUE_LIST = "VALUE_LIST"
Expand Down Expand Up @@ -401,6 +391,24 @@ class ProxyInitState(Enum):
DE_INIT_SKIPPED = 16


class RxMode(IntEnum):
"""Enum for homematic rx modes."""

UNDEFINED = 0
ALWAYS = 1
BURST = 2
CONFIG = 4
WAKEUP = 8
LAZY_CONFIG = 10


class CommandRxMode(StrEnum):
"""Enum for homematic rx modes for commands."""

BURST = "BURST"
WAKEUP = "WAKEUP"


class SysvarType(StrEnum):
"""Enum for homematic sysvar types."""

Expand Down Expand Up @@ -606,4 +614,4 @@ class DeviceDescription(TypedDict, total=False):
# TEAM_CHANNELS: list
INTERFACE: str | None
# ROAMING: int | None
RX_MODE: int | None
RX_MODE: int
8 changes: 8 additions & 0 deletions hahomematic/platforms/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
ParameterData,
ParamsetKey,
ProductGroup,
RxMode,
)
from hahomematic.exceptions import BaseHomematicException
from hahomematic.platforms.custom import definition as hmed, entity as hmce
Expand All @@ -56,6 +57,7 @@
check_or_create_directory,
device_paramset_description_export_converter,
get_entity_key,
get_rx_modes,
reduce_args,
)

Expand Down Expand Up @@ -98,6 +100,7 @@ def __init__(self, central: hmcu.CentralUnit, interface_id: str, device_address:
)
self._device_type: Final = device_description["TYPE"]
self._sub_type: Final = device_description.get("SUBTYPE")
self._rx_modes: Final = get_rx_modes(mode=device_description.get("RX_MODE", 0))

self._ignore_for_custom_entity: Final[bool] = (
central.parameter_visibility.device_type_is_ignored(device_type=self._device_type)
Expand Down Expand Up @@ -290,6 +293,11 @@ def rooms(self) -> set[str]:
"""Return all rooms of the device."""
return self._rooms

@config_property
def rx_modes(self) -> tuple[RxMode, ...]:
"""Return the rx mode."""
return self._rx_modes

@config_property
def sub_type(self) -> str | None:
"""Return the sub_type of the device."""
Expand Down
29 changes: 29 additions & 0 deletions hahomematic/support.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@
INIT_DATETIME,
MAX_CACHE_AGE,
NO_CACHE_ENTRY,
CommandRxMode,
ParameterData,
ParamsetKey,
RxMode,
SysvarType,
)
from hahomematic.exceptions import BaseHomematicException, HaHomematicException
Expand Down Expand Up @@ -480,3 +482,30 @@ def _make_value_hashable(value: Any) -> Any:
return tuple(sorted(_make_value_hashable(e) for e in value))

return value


def get_rx_modes(mode: int) -> tuple[RxMode, ...]:
"""Convert int to rx modes."""
rx_modes: set[RxMode] = set()
if mode == 10:
rx_modes.add(RxMode.LAZY_CONFIG)
return tuple(rx_modes)
if mode & RxMode.WAKEUP:
mode -= RxMode.WAKEUP
rx_modes.add(RxMode.WAKEUP)
if mode & RxMode.CONFIG:
mode -= RxMode.CONFIG
rx_modes.add(RxMode.CONFIG)
if mode & RxMode.BURST:
mode -= RxMode.BURST
rx_modes.add(RxMode.BURST)
if mode & RxMode.ALWAYS:
rx_modes.add(RxMode.ALWAYS)
return tuple(rx_modes)


def supports_rx_mode(command_rx_mode: CommandRxMode, rx_modes: tuple[RxMode, ...]) -> bool:
"""Check if rx mode is supported."""
return (command_rx_mode == CommandRxMode.BURST and RxMode.BURST in rx_modes) or (
command_rx_mode == CommandRxMode.WAKEUP and RxMode.WAKEUP in rx_modes
)
5 changes: 3 additions & 2 deletions hahomematic_support/client_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
DEFAULT_ENCODING,
ENTITY_KEY,
CallSource,
CommandRxMode,
InterfaceName,
ParameterData,
ParamsetKey,
Expand Down Expand Up @@ -203,7 +204,7 @@ async def set_value(
parameter: str,
value: Any,
wait_for_callback: int | None = WAIT_FOR_CALLBACK,
rx_mode: str | None = None,
rx_mode: CommandRxMode | None = None,
check_against_pd: bool = False,
) -> set[ENTITY_KEY]:
"""Set single value on paramset VALUES."""
Expand Down Expand Up @@ -262,7 +263,7 @@ async def put_paramset(
paramset_key: ParamsetKey,
values: Any,
wait_for_callback: int | None = WAIT_FOR_CALLBACK,
rx_mode: str | None = None,
rx_mode: CommandRxMode | None = None,
check_against_pd: bool = False,
) -> set[ENTITY_KEY]:
"""
Expand Down

0 comments on commit fe7cba9

Please sign in to comment.