Skip to content

Commit

Permalink
Add support for listening group addresses to RemoteValue (#441)
Browse files Browse the repository at this point in the history
* Add support for listening group addresses to RemoteValue (and subclasses)

* Apply suggestions from code review

Co-authored-by: Matthias Alphart <farmio@alphart.net>

* Review: Use passive_group_addresses

Co-authored-by: Matthias Alphart <farmio@alphart.net>
  • Loading branch information
marvin-w and farmio committed Oct 2, 2020
1 parent 5528527 commit 53050ba
Show file tree
Hide file tree
Showing 13 changed files with 86 additions and 2 deletions.
21 changes: 21 additions & 0 deletions test/remote_value_tests/remote_value_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,27 @@ def test_read_state_none(self):
"State",
)

def test_process_listening_address(self):
"""Test if listening group addresses are processed."""
xknx = XKNX()
remote_value = RemoteValue(
xknx, group_address="1/2/3", passive_group_addresses=["1/1/1"]
)
self.assertTrue(remote_value.writable)
self.assertFalse(remote_value.readable)
# RemoteValue is initialized with only passive group address
self.assertTrue(remote_value.initialized)
with patch("xknx.remote_value.RemoteValue.payload_valid") as patch_valid:
patch_valid.return_value = True
test_payload = DPTArray((0x01, 0x02))
telegram = Telegram(GroupAddress("1/1/1"), payload=test_payload)
self.assertTrue(
self.loop.run_until_complete(
asyncio.Task(remote_value.process(telegram))
)
)
self.assertEqual(remote_value.payload, test_payload)

def test_eq(self):
"""Test __eq__ operator."""
xknx = XKNX()
Expand Down
27 changes: 25 additions & 2 deletions xknx/remote_value/remote_value.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- or a group of both representing the same value.
"""
import logging
from typing import List

from xknx.exceptions import CouldNotParseTelegram
from xknx.telegram import GroupAddress, Telegram, TelegramType
Expand All @@ -27,10 +28,14 @@ def __init__(
device_name=None,
feature_name=None,
after_update_cb=None,
passive_group_addresses: List[str] = None,
):
"""Initialize RemoteValue class."""
# pylint: disable=too-many-arguments
self.xknx = xknx
self.passive_group_addresses = RemoteValue.get_passive_group_addresses(
passive_group_addresses
)
if group_address is not None:
group_address = GroupAddress(group_address)
if group_address_state is not None:
Expand Down Expand Up @@ -58,7 +63,11 @@ def __del__(self):
@property
def initialized(self):
"""Evaluate if remote value is initialized with group address."""
return bool(self.group_address_state or self.group_address)
return bool(
self.group_address_state
or self.group_address
or self.passive_group_addresses
)

@property
def readable(self):
Expand All @@ -72,7 +81,14 @@ def writable(self):

def has_group_address(self, group_address):
"""Test if device has given group address."""
return group_address in [self.group_address, self.group_address_state]

def _internal_addresses():
"""Yield all group_addresses."""
yield self.group_address
yield self.group_address_state
yield from self.passive_group_addresses

return group_address in _internal_addresses()

def payload_valid(self, payload):
"""Test if telegram payload may be parsed - to be implemented in derived class.."""
Expand Down Expand Up @@ -219,3 +235,10 @@ def __eq__(self, other):
if key not in self.__dict__:
return False
return True

@staticmethod
def get_passive_group_addresses(passive_group_addresses: List[str]) -> List:
"""Obtain passive state group addresses."""
if passive_group_addresses is None:
return []
return [GroupAddress(ga) for ga in passive_group_addresses]
3 changes: 3 additions & 0 deletions xknx/remote_value/remote_value_climate_mode.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
DPT .
"""
from enum import Enum
from typing import List

from xknx.dpt import (
DPTArray,
Expand Down Expand Up @@ -38,6 +39,7 @@ def __init__(
feature_name="Climate Mode",
climate_mode_type=None,
after_update_cb=None,
passive_group_addresses: List[str] = None,
):
"""Initialize remote value of KNX climate mode."""
# pylint: disable=too-many-arguments
Expand All @@ -49,6 +51,7 @@ def __init__(
device_name=device_name,
feature_name=feature_name,
after_update_cb=after_update_cb,
passive_group_addresses=passive_group_addresses,
)
if not isinstance(climate_mode_type, self.ClimateModeType):
raise ConversionError(
Expand Down
4 changes: 4 additions & 0 deletions xknx/remote_value/remote_value_color_rgb.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
DPT 232.600.
"""
from typing import List

from xknx.dpt import DPTArray
from xknx.exceptions import ConversionError

Expand All @@ -20,6 +22,7 @@ def __init__(
device_name=None,
feature_name="Color RGB",
after_update_cb=None,
passive_group_addresses: List[str] = None,
):
"""Initialize remote value of KNX DPT 232.600 (DPT_Color_RGB)."""
# pylint: disable=too-many-arguments
Expand All @@ -30,6 +33,7 @@ def __init__(
device_name=device_name,
feature_name=feature_name,
after_update_cb=after_update_cb,
passive_group_addresses=passive_group_addresses,
)

def payload_valid(self, payload):
Expand Down
4 changes: 4 additions & 0 deletions xknx/remote_value/remote_value_color_rgbw.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
DPT 251.600.
"""
from typing import List

from xknx.dpt import DPTArray
from xknx.exceptions import ConversionError

Expand All @@ -20,6 +22,7 @@ def __init__(
device_name=None,
feature_name="Color RGBW",
after_update_cb=None,
passive_group_addresses: List[str] = None,
):
"""Initialize remote value of KNX DPT 251.600 (DPT_Color_RGBW)."""
# pylint: disable=too-many-arguments
Expand All @@ -30,6 +33,7 @@ def __init__(
device_name=device_name,
feature_name=feature_name,
after_update_cb=after_update_cb,
passive_group_addresses=passive_group_addresses,
)
self.previous_value = (0, 0, 0, 0)

Expand Down
3 changes: 3 additions & 0 deletions xknx/remote_value/remote_value_datetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"""
from enum import Enum
import time
from typing import List

from xknx.dpt import DPTArray, DPTDate, DPTDateTime, DPTTime
from xknx.exceptions import ConversionError
Expand Down Expand Up @@ -33,6 +34,7 @@ def __init__(
device_name=None,
feature_name="DateTime",
after_update_cb=None,
passive_group_addresses: List[str] = None,
):
"""Initialize RemoteValueSensor class."""
# pylint: disable=too-many-arguments
Expand All @@ -53,6 +55,7 @@ def __init__(
device_name=device_name,
feature_name=feature_name,
after_update_cb=after_update_cb,
passive_group_addresses=passive_group_addresses,
)

def payload_valid(self, payload):
Expand Down
4 changes: 4 additions & 0 deletions xknx/remote_value/remote_value_dpt_2_byte_unsigned.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
DPT 7.001.
"""
from typing import List

from xknx.dpt import DPT2ByteUnsigned, DPTArray

from .remote_value import RemoteValue
Expand All @@ -19,6 +21,7 @@ def __init__(
device_name=None,
feature_name="Value",
after_update_cb=None,
passive_group_addresses: List[str] = None,
):
"""Initialize remote value of KNX DPT 7.001."""
# pylint: disable=too-many-arguments
Expand All @@ -29,6 +32,7 @@ def __init__(
device_name=device_name,
feature_name=feature_name,
after_update_cb=after_update_cb,
passive_group_addresses=passive_group_addresses,
)

def payload_valid(self, payload):
Expand Down
4 changes: 4 additions & 0 deletions xknx/remote_value/remote_value_scaling.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
DPT 5.001.
"""
from typing import List

from xknx.dpt import DPTArray

from .remote_value import RemoteValue
Expand All @@ -21,6 +23,7 @@ def __init__(
after_update_cb=None,
range_from=0,
range_to=100,
passive_group_addresses: List[str] = None,
):
"""Initialize remote value of KNX DPT 5.001 (DPT_Scaling)."""
# pylint: disable=too-many-arguments
Expand All @@ -31,6 +34,7 @@ def __init__(
device_name=device_name,
feature_name=feature_name,
after_update_cb=after_update_cb,
passive_group_addresses=passive_group_addresses,
)
self.range_from = range_from
self.range_to = range_to
Expand Down
4 changes: 4 additions & 0 deletions xknx/remote_value/remote_value_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
The module maps a given value_type to a DPT class and uses this class
for serialization and deserialization of the KNX value.
"""
from typing import List

from xknx.dpt import DPTArray, DPTBase
from xknx.exceptions import ConversionError

Expand All @@ -23,6 +25,7 @@ def __init__(
device_name=None,
feature_name="Value",
after_update_cb=None,
passive_group_addresses: List[str] = None,
):
"""Initialize RemoteValueSensor class."""
# pylint: disable=too-many-arguments
Expand All @@ -40,6 +43,7 @@ def __init__(
device_name=device_name,
feature_name=feature_name,
after_update_cb=after_update_cb,
passive_group_addresses=passive_group_addresses,
)

def payload_valid(self, payload):
Expand Down
4 changes: 4 additions & 0 deletions xknx/remote_value/remote_value_setpoint_shift.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
DPT 6.010.
"""
from typing import List

from xknx.remote_value import RemoteValue1Count


Expand All @@ -17,6 +19,7 @@ def __init__(
device_name=None,
after_update_cb=None,
setpoint_shift_step=0.1,
passive_group_addresses: List[str] = None,
):
"""Initialize RemoteValueSetpointShift class."""
# pylint: disable=too-many-arguments
Expand All @@ -27,6 +30,7 @@ def __init__(
device_name=device_name,
feature_name="Setpoint shift value",
after_update_cb=after_update_cb,
passive_group_addresses=passive_group_addresses,
)

self.setpoint_shift_step = setpoint_shift_step
Expand Down
3 changes: 3 additions & 0 deletions xknx/remote_value/remote_value_step.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
DPT 1.007.
"""
from enum import Enum
from typing import List

from xknx.dpt import DPTBinary
from xknx.exceptions import ConversionError, CouldNotParseTelegram
Expand All @@ -29,6 +30,7 @@ def __init__(
feature_name="Step",
after_update_cb=None,
invert=False,
passive_group_addresses: List[str] = None,
):
"""Initialize remote value of KNX DPT 1.007."""
# pylint: disable=too-many-arguments
Expand All @@ -39,6 +41,7 @@ def __init__(
device_name=device_name,
feature_name=feature_name,
after_update_cb=after_update_cb,
passive_group_addresses=passive_group_addresses,
)
self.invert = invert

Expand Down
4 changes: 4 additions & 0 deletions xknx/remote_value/remote_value_switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
DPT 1.001.
"""
from typing import List

from xknx.dpt import DPTBinary
from xknx.exceptions import ConversionError, CouldNotParseTelegram

Expand All @@ -22,6 +24,7 @@ def __init__(
feature_name="State",
after_update_cb=None,
invert=False,
passive_group_addresses: List[str] = None,
):
"""Initialize remote value of KNX DPT 1.001."""
# pylint: disable=too-many-arguments
Expand All @@ -33,6 +36,7 @@ def __init__(
device_name=device_name,
feature_name=feature_name,
after_update_cb=after_update_cb,
passive_group_addresses=passive_group_addresses,
)
self.invert = invert

Expand Down
3 changes: 3 additions & 0 deletions xknx/remote_value/remote_value_updown.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
DPT 1.008.
"""
from enum import Enum
from typing import List

from xknx.dpt import DPTBinary
from xknx.exceptions import ConversionError, CouldNotParseTelegram
Expand All @@ -30,6 +31,7 @@ def __init__(
feature_name="Up/Down",
after_update_cb=None,
invert=False,
passive_group_addresses: List[str] = None,
):
"""Initialize remote value of KNX DPT 1.008."""
# pylint: disable=too-many-arguments
Expand All @@ -40,6 +42,7 @@ def __init__(
device_name=device_name,
feature_name=feature_name,
after_update_cb=after_update_cb,
passive_group_addresses=passive_group_addresses,
)
self.invert = invert

Expand Down

0 comments on commit 53050ba

Please sign in to comment.