diff --git a/changelog.md b/changelog.md
index 43f43cedd..9474a6564 100644
--- a/changelog.md
+++ b/changelog.md
@@ -10,6 +10,8 @@
- renamed "PhysicalAddress" to "IndividualAddress"
- Telegram: `group_address` renamed to `destination_address`, to prepare support for other APCI services and add `source_address`
+- Telegram: remove `Telegram.telegramtype` and replace with payload object derived from `xknx.telegram.apci.APCI`.
+- CEMIFrame: remove `CEMIFrame.cmd`, which can be derived from `CEMIFrame.payload`.
- Farewell Travis CI; Welcome Github Actions!
## 0.15.6 Bugfix for StateUpater 2020-11-26
diff --git a/examples/example_tunnel.py b/examples/example_tunnel.py
index c54505685..979adde32 100644
--- a/examples/example_tunnel.py
+++ b/examples/example_tunnel.py
@@ -5,6 +5,7 @@
from xknx.dpt import DPTBinary
from xknx.io import GatewayScanner, Tunnel
from xknx.telegram import GroupAddress, IndividualAddress, Telegram
+from xknx.telegram.apci import GroupValueWrite
async def main():
@@ -38,11 +39,17 @@ async def main():
await tunnel.connect()
await tunnel.send_telegram(
- Telegram(destination_address=GroupAddress("1/0/15"), payload=DPTBinary(1))
+ Telegram(
+ destination_address=GroupAddress("1/0/15"),
+ payload=GroupValueWrite(DPTBinary(1)),
+ )
)
await asyncio.sleep(2)
await tunnel.send_telegram(
- Telegram(destination_address=GroupAddress("1/0/15"), payload=DPTBinary(0))
+ Telegram(
+ destination_address=GroupAddress("1/0/15"),
+ payload=GroupValueWrite(DPTBinary(0)),
+ )
)
await asyncio.sleep(2)
diff --git a/home-assistant-plugin/custom_components/xknx/__init__.py b/home-assistant-plugin/custom_components/xknx/__init__.py
index 4b82e1d31..44142025b 100644
--- a/home-assistant-plugin/custom_components/xknx/__init__.py
+++ b/home-assistant-plugin/custom_components/xknx/__init__.py
@@ -14,6 +14,7 @@
ConnectionType,
)
from xknx.telegram import AddressFilter, GroupAddress, Telegram
+from xknx.telegram.apci import GroupValueResponse, GroupValueWrite
from homeassistant.const import (
CONF_ENTITY_ID,
@@ -322,14 +323,20 @@ def async_create_exposures(self):
async def telegram_received_cb(self, telegram):
"""Call invoked after a KNX telegram was received."""
+ data = None
+
+ # Not all telegrams have serializable data.
+ if isinstance(telegram, (GroupValueWrite, GroupValueResponse)):
+ data = telegram.dpt.value
+
self.hass.bus.async_fire(
"knx_event",
{
- "data": telegram.payload.value,
+ "data": data,
"destination": str(telegram.destination_address),
"direction": telegram.direction.value,
"source": str(telegram.source_address),
- "telegramtype": telegram.telegramtype.value,
+ "telegramtype": telegram.payload.__class__.__name__,
},
)
diff --git a/test/core_tests/telegram_queue_test.py b/test/core_tests/telegram_queue_test.py
index 4460ec296..6ab5f98cc 100644
--- a/test/core_tests/telegram_queue_test.py
+++ b/test/core_tests/telegram_queue_test.py
@@ -7,6 +7,7 @@
from xknx.dpt import DPTBinary
from xknx.exceptions import CouldNotParseTelegram
from xknx.telegram import AddressFilter, GroupAddress, Telegram, TelegramDirection
+from xknx.telegram.apci import GroupValueWrite
class AsyncMock(MagicMock):
@@ -40,7 +41,7 @@ def test_start(self):
telegram_in = Telegram(
destination_address=GroupAddress("1/2/3"),
direction=TelegramDirection.INCOMING,
- payload=DPTBinary(1),
+ payload=GroupValueWrite(DPTBinary(1)),
)
self.loop.run_until_complete(xknx.telegram_queue.start())
@@ -75,14 +76,12 @@ async def async_none():
telegram_in = Telegram(
direction=TelegramDirection.INCOMING,
- payload=DPTBinary(1),
- destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
telegram_out = Telegram(
direction=TelegramDirection.OUTGOING,
- payload=DPTBinary(1),
- destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
self.loop.run_until_complete(xknx.telegram_queue.start())
@@ -120,7 +119,7 @@ async def async_telegram_received_cb(device):
telegram = Telegram(
destination_address=GroupAddress("1/2/3"),
direction=TelegramDirection.INCOMING,
- payload=DPTBinary(1),
+ payload=GroupValueWrite(DPTBinary(1)),
)
self.loop.run_until_complete(
xknx.telegram_queue.process_telegram_incoming(telegram)
@@ -144,7 +143,7 @@ def test_unregister(self):
telegram = Telegram(
destination_address=GroupAddress("1/2/3"),
direction=TelegramDirection.INCOMING,
- payload=DPTBinary(1),
+ payload=GroupValueWrite(DPTBinary(1)),
)
self.loop.run_until_complete(
xknx.telegram_queue.process_telegram_incoming(telegram)
@@ -170,7 +169,7 @@ def test_process_to_device(self, devices_by_ga_mock):
telegram = Telegram(
destination_address=GroupAddress("1/2/3"),
direction=TelegramDirection.INCOMING,
- payload=DPTBinary(1),
+ payload=GroupValueWrite(DPTBinary(1)),
)
self.loop.run_until_complete(
xknx.telegram_queue.process_telegram_incoming(telegram)
@@ -193,7 +192,7 @@ def test_process_to_callback(self, devices_process):
telegram = Telegram(
destination_address=GroupAddress("1/2/3"),
direction=TelegramDirection.INCOMING,
- payload=DPTBinary(1),
+ payload=GroupValueWrite(DPTBinary(1)),
)
self.loop.run_until_complete(
xknx.telegram_queue.process_telegram_incoming(telegram)
@@ -215,7 +214,7 @@ def test_outgoing(self, logger_warning_mock, if_mock):
telegram = Telegram(
destination_address=GroupAddress("1/2/3"),
direction=TelegramDirection.OUTGOING,
- payload=DPTBinary(1),
+ payload=GroupValueWrite(DPTBinary(1)),
)
# log a warning if there is no KNXIP interface instanciated
@@ -249,7 +248,7 @@ async def process_exception():
telegram = Telegram(
destination_address=GroupAddress("1/2/3"),
direction=TelegramDirection.INCOMING,
- payload=DPTBinary(1),
+ payload=GroupValueWrite(DPTBinary(1)),
)
xknx.telegrams.put_nowait(telegram)
@@ -279,12 +278,12 @@ def test_process_all_telegrams(
telegram_in = Telegram(
destination_address=GroupAddress("1/2/3"),
direction=TelegramDirection.INCOMING,
- payload=DPTBinary(1),
+ payload=GroupValueWrite(DPTBinary(1)),
)
telegram_out = Telegram(
destination_address=GroupAddress("1/2/3"),
direction=TelegramDirection.OUTGOING,
- payload=DPTBinary(1),
+ payload=GroupValueWrite(DPTBinary(1)),
)
xknx.telegrams.put_nowait(telegram_in)
@@ -314,7 +313,7 @@ async def async_telegram_received_cb(device):
telegram = Telegram(
destination_address=GroupAddress("1/2/3"),
direction=TelegramDirection.INCOMING,
- payload=DPTBinary(1),
+ payload=GroupValueWrite(DPTBinary(1)),
)
xknx.telegrams.put_nowait(telegram)
self.loop.run_until_complete(xknx.telegram_queue._process_all_telegrams())
@@ -343,7 +342,7 @@ async def async_telegram_received_cb(device):
telegram = Telegram(
destination_address=GroupAddress("1/2/3"),
direction=TelegramDirection.INCOMING,
- payload=DPTBinary(1),
+ payload=GroupValueWrite(DPTBinary(1)),
)
xknx.telegrams.put_nowait(telegram)
self.loop.run_until_complete(xknx.telegram_queue._process_all_telegrams())
@@ -372,7 +371,7 @@ async def async_telegram_received_cb(device):
telegram = Telegram(
destination_address=GroupAddress("1/2/3"),
direction=TelegramDirection.INCOMING,
- payload=DPTBinary(1),
+ payload=GroupValueWrite(DPTBinary(1)),
)
xknx.telegrams.put_nowait(telegram)
self.loop.run_until_complete(xknx.telegram_queue._process_all_telegrams())
diff --git a/test/core_tests/value_reader_test.py b/test/core_tests/value_reader_test.py
index 901739227..5f5ee7971 100644
--- a/test/core_tests/value_reader_test.py
+++ b/test/core_tests/value_reader_test.py
@@ -6,7 +6,8 @@
from xknx import XKNX
from xknx.core import ValueReader
from xknx.dpt import DPTBinary
-from xknx.telegram import GroupAddress, Telegram, TelegramDirection, TelegramType
+from xknx.telegram import GroupAddress, Telegram, TelegramDirection
+from xknx.telegram.apci import GroupValueRead, GroupValueResponse, GroupValueWrite
class TestValueReader(unittest.TestCase):
@@ -28,9 +29,8 @@ def test_value_reader_read_success(self, timeout_mock):
test_group_address = GroupAddress("0/0/0")
response_telegram = Telegram(
destination_address=test_group_address,
- telegramtype=TelegramType.GROUP_RESPONSE,
direction=TelegramDirection.INCOMING,
- payload=DPTBinary(1),
+ payload=GroupValueResponse(DPTBinary(1)),
)
value_reader = ValueReader(xknx, test_group_address)
@@ -94,8 +94,7 @@ def test_value_reader_send_group_read(self):
self.assertEqual(
telegram,
Telegram(
- destination_address=GroupAddress("0/0/0"),
- telegramtype=TelegramType.GROUP_READ,
+ destination_address=GroupAddress("0/0/0"), payload=GroupValueRead()
),
)
@@ -105,27 +104,23 @@ def test_value_reader_telegram_received(self):
test_group_address = GroupAddress("0/0/0")
expected_telegram_1 = Telegram(
destination_address=test_group_address,
- telegramtype=TelegramType.GROUP_RESPONSE,
direction=TelegramDirection.INCOMING,
- payload=DPTBinary(1),
+ payload=GroupValueResponse(DPTBinary(1)),
)
expected_telegram_2 = Telegram(
destination_address=test_group_address,
- telegramtype=TelegramType.GROUP_WRITE,
direction=TelegramDirection.INCOMING,
- payload=DPTBinary(1),
+ payload=GroupValueWrite(DPTBinary(1)),
)
telegram_wrong_address = Telegram(
destination_address=GroupAddress("0/0/1"),
- telegramtype=TelegramType.GROUP_RESPONSE,
direction=TelegramDirection.INCOMING,
- payload=DPTBinary(1),
+ payload=GroupValueResponse(DPTBinary(1)),
)
telegram_wrong_type = Telegram(
destination_address=test_group_address,
- telegramtype=TelegramType.GROUP_READ,
direction=TelegramDirection.INCOMING,
- payload=DPTBinary(1),
+ payload=GroupValueRead(),
)
value_reader = ValueReader(xknx, test_group_address)
diff --git a/test/devices_tests/binary_sensor_test.py b/test/devices_tests/binary_sensor_test.py
index 33649836f..58a336fa5 100644
--- a/test/devices_tests/binary_sensor_test.py
+++ b/test/devices_tests/binary_sensor_test.py
@@ -7,7 +7,8 @@
from xknx.devices import Action, BinarySensor, Switch
from xknx.dpt import DPTArray, DPTBinary
from xknx.exceptions import CouldNotParseTelegram
-from xknx.telegram import GroupAddress, Telegram, TelegramType
+from xknx.telegram import GroupAddress, Telegram
+from xknx.telegram.apci import GroupValueResponse, GroupValueWrite
class AsyncMock(MagicMock):
@@ -38,14 +39,16 @@ def test_process(self):
self.assertEqual(binaryinput.state, None)
telegram_on = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
self.loop.run_until_complete(binaryinput.process(telegram_on))
self.assertEqual(binaryinput.state, True)
telegram_off = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(0)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(0)),
)
self.loop.run_until_complete(binaryinput.process(telegram_off))
self.assertEqual(binaryinput.state, False)
@@ -54,7 +57,8 @@ def test_process(self):
self.assertEqual(binaryinput2.state, None)
telegram_off2 = Telegram(
- destination_address=GroupAddress("1/2/4"), payload=DPTBinary(0)
+ destination_address=GroupAddress("1/2/4"),
+ payload=GroupValueWrite(DPTBinary(0)),
)
self.loop.run_until_complete(binaryinput2.process(telegram_off2))
self.assertEqual(binaryinput2.state, False)
@@ -67,14 +71,16 @@ def test_process_invert(self):
self.assertEqual(bs_invert.state, None)
telegram_on = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(0)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(0)),
)
self.loop.run_until_complete(bs_invert.process(telegram_on))
self.assertEqual(bs_invert.state, True)
telegram_off = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
self.loop.run_until_complete(bs_invert.process(telegram_off))
self.assertEqual(bs_invert.state, False)
@@ -92,7 +98,8 @@ def test_process_reset_after(self):
device_updated_cb=async_after_update_callback,
)
telegram_on = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
self.loop.run_until_complete(binaryinput.process(telegram_on))
@@ -131,7 +138,8 @@ def test_process_action(self):
self.assertEqual(switch.state, None)
telegram_on = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
self.loop.run_until_complete(binary_sensor.process(telegram_on))
# process outgoing telegram from queue
@@ -141,7 +149,8 @@ def test_process_action(self):
self.assertEqual(switch.state, True)
telegram_off = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(0)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(0)),
)
self.loop.run_until_complete(binary_sensor.process(telegram_off))
self.loop.run_until_complete(switch.process(xknx.telegrams.get_nowait()))
@@ -164,7 +173,8 @@ def test_process_action_ignore_internal_state(self):
self.assertEqual(switch.state, None)
telegram_on = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
with patch("time.time") as mock_time, patch(
@@ -197,7 +207,8 @@ def test_process_wrong_payload(self):
xknx = XKNX()
binary_sensor = BinarySensor(xknx, "Warning", group_address_state="1/2/3")
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTArray((0x1, 0x2, 0x3))
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray((0x1, 0x2, 0x3))),
)
with self.assertRaises(CouldNotParseTelegram):
self.loop.run_until_complete(binary_sensor.process(telegram))
@@ -245,7 +256,8 @@ def test_process_callback(self):
switch.register_device_updated_cb(async_after_update_callback)
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
self.loop.run_until_complete(switch.process(telegram))
# no _context_task started because ignore_internal_state is False
@@ -273,7 +285,8 @@ def test_process_callback_ignore_internal_state(self):
switch.register_device_updated_cb(async_after_update_callback)
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
self.assertEqual(switch.counter, 0)
@@ -315,7 +328,8 @@ def test_process_callback_ignore_internal_state_no_counter(self):
switch.register_device_updated_cb(async_after_update_callback)
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
self.loop.run_until_complete(switch.process(telegram))
# no _context_task started because context_timeout is False
@@ -342,12 +356,14 @@ def test_process_group_value_response(self):
switch.register_device_updated_cb(async_after_update_callback)
write_telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
response_telegram = Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTBinary(1),
- telegramtype=TelegramType.GROUP_RESPONSE,
+ payload=GroupValueResponse(
+ DPTBinary(1),
+ ),
)
self.assertIsNone(switch.state)
# initial GroupValueResponse changes state and runs callback
diff --git a/test/devices_tests/climate_test.py b/test/devices_tests/climate_test.py
index 7d9587b52..19dcfeecb 100644
--- a/test/devices_tests/climate_test.py
+++ b/test/devices_tests/climate_test.py
@@ -19,7 +19,8 @@
)
from xknx.dpt.dpt_hvac_mode import HVACControllerMode
from xknx.exceptions import CouldNotParseTelegram, DeviceIllegalValue
-from xknx.telegram import GroupAddress, Telegram, TelegramType
+from xknx.telegram import GroupAddress, Telegram
+from xknx.telegram.apci import GroupValueRead, GroupValueWrite
DPT_20102_MODES = [
HVACOperationMode.AUTO,
@@ -233,7 +234,7 @@ async def async_after_update_callback(device):
telegram = Telegram(
destination_address=GroupAddress("1/2/1"),
- payload=DPTArray(DPTTemperature.to_knx(23)),
+ payload=GroupValueWrite(DPTArray(DPTTemperature.to_knx(23))),
)
self.loop.run_until_complete(climate.process(telegram))
after_update_callback.assert_called_with(climate)
@@ -241,7 +242,7 @@ async def async_after_update_callback(device):
telegram = Telegram(
destination_address=GroupAddress("1/2/2"),
- payload=DPTArray(DPTTemperature.to_knx(23)),
+ payload=GroupValueWrite(DPTArray(DPTTemperature.to_knx(23))),
)
self.loop.run_until_complete(climate.process(telegram))
after_update_callback.assert_called_with(climate)
@@ -249,7 +250,7 @@ async def async_after_update_callback(device):
telegram = Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTArray(DPTValue1Count.to_knx(-4)),
+ payload=GroupValueWrite(DPTArray(DPTValue1Count.to_knx(-4))),
)
self.loop.run_until_complete(climate.process(telegram))
after_update_callback.assert_called_with(climate)
@@ -276,7 +277,8 @@ async def async_after_update_callback(device):
# Note: the climate object processes the telegram, but the cb
# is called with the climate_mode object.
telegram = Telegram(
- destination_address=GroupAddress("1/2/4"), payload=DPTArray(1)
+ destination_address=GroupAddress("1/2/4"),
+ payload=GroupValueWrite(DPTArray(1)),
)
self.loop.run_until_complete(climate.process(telegram))
after_update_callback.assert_called_with(climate_mode)
@@ -303,7 +305,9 @@ def test_set_operation_mode(self):
telegram,
Telegram(
destination_address=GroupAddress("1/2/4"),
- payload=DPTArray(DPTHVACMode.to_knx(operation_mode)),
+ payload=GroupValueWrite(
+ DPTArray(DPTHVACMode.to_knx(operation_mode))
+ ),
),
)
@@ -325,7 +329,9 @@ def test_set_controller_operation_mode(self):
telegram,
Telegram(
destination_address=GroupAddress("1/2/4"),
- payload=DPTArray(DPTHVACContrMode.to_knx(controller_mode)),
+ payload=GroupValueWrite(
+ DPTArray(DPTHVACContrMode.to_knx(controller_mode))
+ ),
),
)
@@ -367,7 +373,9 @@ def test_set_operation_mode_with_controller_status(self):
telegram,
Telegram(
destination_address=GroupAddress("1/2/4"),
- payload=DPTArray(DPTControllerStatus.to_knx(operation_mode)),
+ payload=GroupValueWrite(
+ DPTArray(DPTControllerStatus.to_knx(operation_mode))
+ ),
),
)
@@ -393,15 +401,21 @@ def test_set_operation_mode_with_separate_addresses(self):
telegrams.append(xknx.telegrams.get_nowait())
test_telegrams = [
- Telegram(destination_address=GroupAddress("1/2/4"), payload=DPTArray(1)),
Telegram(
- destination_address=GroupAddress("1/2/5"), payload=DPTBinary(False)
+ destination_address=GroupAddress("1/2/4"),
+ payload=GroupValueWrite(DPTArray(1)),
+ ),
+ Telegram(
+ destination_address=GroupAddress("1/2/5"),
+ payload=GroupValueWrite(DPTBinary(False)),
),
Telegram(
- destination_address=GroupAddress("1/2/6"), payload=DPTBinary(False)
+ destination_address=GroupAddress("1/2/6"),
+ payload=GroupValueWrite(DPTBinary(False)),
),
Telegram(
- destination_address=GroupAddress("1/2/7"), payload=DPTBinary(True)
+ destination_address=GroupAddress("1/2/7"),
+ payload=GroupValueWrite(DPTBinary(True)),
),
]
@@ -425,7 +439,8 @@ def test_set_heat_cool_binary(self):
self.assertEqual(
telegram,
Telegram(
- destination_address=GroupAddress("1/2/14"), payload=DPTBinary(True)
+ destination_address=GroupAddress("1/2/14"),
+ payload=GroupValueWrite(DPTBinary(True)),
),
)
self.loop.run_until_complete(
@@ -436,7 +451,8 @@ def test_set_heat_cool_binary(self):
self.assertEqual(
telegram,
Telegram(
- destination_address=GroupAddress("1/2/14"), payload=DPTBinary(False)
+ destination_address=GroupAddress("1/2/14"),
+ payload=GroupValueWrite(DPTBinary(False)),
),
)
@@ -533,7 +549,10 @@ def test_target_temperature_up(self):
self.assertEqual(
_telegram,
# DEFAULT_TEMPERATURE_STEP is 0.1 -> payload = setpoint_shift * 10
- Telegram(destination_address=GroupAddress("1/2/3"), payload=DPTArray(30)),
+ Telegram(
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray(30)),
+ ),
)
self.loop.run_until_complete(xknx.devices.process(_telegram))
@@ -544,7 +563,7 @@ def test_target_temperature_up(self):
_telegram,
Telegram(
destination_address=GroupAddress("1/2/2"),
- payload=DPTArray(DPT2ByteFloat().to_knx(23.00)),
+ payload=GroupValueWrite(DPTArray(DPT2ByteFloat().to_knx(23.00))),
),
)
self.loop.run_until_complete(xknx.devices.process(_telegram))
@@ -556,7 +575,10 @@ def test_target_temperature_up(self):
_telegram = xknx.telegrams.get_nowait()
self.assertEqual(
_telegram,
- Telegram(destination_address=GroupAddress("1/2/3"), payload=DPTArray(40)),
+ Telegram(
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray(40)),
+ ),
)
self.loop.run_until_complete(xknx.devices.process(_telegram))
_telegram = xknx.telegrams.get_nowait()
@@ -564,7 +586,7 @@ def test_target_temperature_up(self):
_telegram,
Telegram(
destination_address=GroupAddress("1/2/2"),
- payload=DPTArray(DPT2ByteFloat().to_knx(24.00)),
+ payload=GroupValueWrite(DPTArray(DPT2ByteFloat().to_knx(24.00))),
),
)
self.loop.run_until_complete(xknx.devices.process(_telegram))
@@ -576,7 +598,10 @@ def test_target_temperature_up(self):
_telegram = xknx.telegrams.get_nowait()
self.assertEqual(
_telegram,
- Telegram(destination_address=GroupAddress("1/2/3"), payload=DPTArray(35)),
+ Telegram(
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray(35)),
+ ),
)
self.loop.run_until_complete(xknx.devices.process(_telegram))
_telegram = xknx.telegrams.get_nowait()
@@ -584,7 +609,7 @@ def test_target_temperature_up(self):
_telegram,
Telegram(
destination_address=GroupAddress("1/2/2"),
- payload=DPTArray(DPT2ByteFloat().to_knx(23.50)),
+ payload=GroupValueWrite(DPTArray(DPT2ByteFloat().to_knx(23.50))),
),
)
self.loop.run_until_complete(xknx.devices.process(_telegram))
@@ -619,7 +644,10 @@ def test_target_temperature_down(self):
self.assertEqual(
_telegram,
# DEFAULT_TEMPERATURE_STEP is 0.1 -> payload = setpoint_shift * 10
- Telegram(destination_address=GroupAddress("1/2/3"), payload=DPTArray(10)),
+ Telegram(
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray(10)),
+ ),
)
self.loop.run_until_complete(xknx.devices.process(_telegram))
@@ -630,7 +658,7 @@ def test_target_temperature_down(self):
_telegram,
Telegram(
destination_address=GroupAddress("1/2/2"),
- payload=DPTArray(DPT2ByteFloat().to_knx(23.00)),
+ payload=GroupValueWrite(DPTArray(DPT2ByteFloat().to_knx(23.00))),
),
)
self.loop.run_until_complete(xknx.devices.process(_telegram))
@@ -642,7 +670,10 @@ def test_target_temperature_down(self):
_telegram = xknx.telegrams.get_nowait()
self.assertEqual(
_telegram,
- Telegram(destination_address=GroupAddress("1/2/3"), payload=DPTArray(0xF1)),
+ Telegram(
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray(0xF1)),
+ ),
) # -15
self.loop.run_until_complete(xknx.devices.process(_telegram))
_telegram = xknx.telegrams.get_nowait()
@@ -650,7 +681,7 @@ def test_target_temperature_down(self):
_telegram,
Telegram(
destination_address=GroupAddress("1/2/2"),
- payload=DPTArray(DPT2ByteFloat().to_knx(20.50)),
+ payload=GroupValueWrite(DPTArray(DPT2ByteFloat().to_knx(20.50))),
),
)
self.loop.run_until_complete(xknx.devices.process(_telegram))
@@ -662,7 +693,10 @@ def test_target_temperature_down(self):
_telegram = xknx.telegrams.get_nowait()
self.assertEqual(
_telegram,
- Telegram(destination_address=GroupAddress("1/2/3"), payload=DPTArray(0xE2)),
+ Telegram(
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray(0xE2)),
+ ),
) # -30
self.loop.run_until_complete(xknx.devices.process(_telegram))
_telegram = xknx.telegrams.get_nowait()
@@ -670,7 +704,7 @@ def test_target_temperature_down(self):
_telegram,
Telegram(
destination_address=GroupAddress("1/2/2"),
- payload=DPTArray(DPT2ByteFloat().to_knx(19.00)),
+ payload=GroupValueWrite(DPTArray(DPT2ByteFloat().to_knx(19.00))),
),
)
self.loop.run_until_complete(xknx.devices.process(_telegram))
@@ -709,7 +743,10 @@ def test_target_temperature_modified_step(self):
self.assertEqual(
_telegram,
# temperature_step is 0.5 -> payload = setpoint_shift * 2
- Telegram(destination_address=GroupAddress("1/2/3"), payload=DPTArray(6)),
+ Telegram(
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray(6)),
+ ),
)
self.loop.run_until_complete(climate.target_temperature.set(23.00))
@@ -720,7 +757,7 @@ def test_target_temperature_modified_step(self):
_telegram,
Telegram(
destination_address=GroupAddress("1/2/2"),
- payload=DPTArray(DPT2ByteFloat().to_knx(23.00)),
+ payload=GroupValueWrite(DPTArray(DPT2ByteFloat().to_knx(23.00))),
),
)
self.assertEqual(climate.base_temperature, 20.00)
@@ -730,7 +767,10 @@ def test_target_temperature_modified_step(self):
self.loop.run_until_complete(xknx.devices.process(_telegram))
self.assertEqual(
_telegram,
- Telegram(destination_address=GroupAddress("1/2/3"), payload=DPTArray(8)),
+ Telegram(
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray(8)),
+ ),
)
_telegram = xknx.telegrams.get_nowait()
self.loop.run_until_complete(xknx.devices.process(_telegram))
@@ -738,7 +778,7 @@ def test_target_temperature_modified_step(self):
_telegram,
Telegram(
destination_address=GroupAddress("1/2/2"),
- payload=DPTArray(DPT2ByteFloat().to_knx(24.00)),
+ payload=GroupValueWrite(DPTArray(DPT2ByteFloat().to_knx(24.00))),
),
)
self.assertEqual(climate.target_temperature.value, 24.00)
@@ -771,7 +811,7 @@ def test_base_temperature(self):
_telegram,
Telegram(
destination_address=GroupAddress("1/2/2"),
- payload=DPTArray(DPT2ByteFloat().to_knx(21.00)),
+ payload=GroupValueWrite(DPTArray(DPT2ByteFloat().to_knx(21.00))),
),
)
self.assertFalse(climate.initialized_for_setpoint_shift_calculations)
@@ -785,7 +825,10 @@ def test_base_temperature(self):
self.assertEqual(
_telegram,
# DEFAULT_TEMPERATURE_STEP is 0.1 -> payload = setpoint_shift * 10
- Telegram(destination_address=GroupAddress("1/2/3"), payload=DPTArray(10)),
+ Telegram(
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray(10)),
+ ),
)
self.assertTrue(climate.initialized_for_setpoint_shift_calculations)
self.assertEqual(climate.base_temperature, 20.00)
@@ -799,7 +842,10 @@ def test_base_temperature(self):
self.assertEqual(
_telegram,
# DEFAULT_TEMPERATURE_STEP is 0.1 -> payload = setpoint_shift * 10
- Telegram(destination_address=GroupAddress("1/2/3"), payload=DPTArray(20)),
+ Telegram(
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray(20)),
+ ),
)
_telegram = xknx.telegrams.get_nowait()
self.loop.run_until_complete(xknx.devices.process(_telegram))
@@ -826,7 +872,7 @@ def test_target_temperature_step_mode_9002(self):
climate.target_temperature.process(
Telegram(
destination_address=GroupAddress("1/2/2"),
- payload=DPTArray(DPT2ByteFloat().to_knx(20.00)),
+ payload=GroupValueWrite(DPTArray(DPT2ByteFloat().to_knx(20.00))),
)
)
)
@@ -841,7 +887,7 @@ def test_target_temperature_step_mode_9002(self):
_telegram,
Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTArray((0x00, 0x00)),
+ payload=GroupValueWrite(DPTArray((0x00, 0x00))),
),
) # 0
# - 0.6 °C = 19.4
@@ -853,7 +899,7 @@ def test_target_temperature_step_mode_9002(self):
_telegram,
Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTArray((0x87, 0xC4)),
+ payload=GroupValueWrite(DPTArray((0x87, 0xC4))),
),
) # -0.6
# simulate incoming new target temperature for next calculation
@@ -861,7 +907,7 @@ def test_target_temperature_step_mode_9002(self):
climate.target_temperature.process(
Telegram(
destination_address=GroupAddress("1/2/2"),
- payload=DPTArray(DPT2ByteFloat().to_knx(19.40)),
+ payload=GroupValueWrite(DPTArray(DPT2ByteFloat().to_knx(19.40))),
)
)
)
@@ -874,7 +920,7 @@ def test_target_temperature_step_mode_9002(self):
_telegram,
Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTArray((0x01, 0x5E)),
+ payload=GroupValueWrite(DPTArray((0x01, 0x5E))),
),
) # +3.5
@@ -927,11 +973,7 @@ def test_sync(self):
self.assertEqual(xknx.telegrams.qsize(), 1)
telegram1 = xknx.telegrams.get_nowait()
self.assertEqual(
- telegram1,
- Telegram(
- destination_address=GroupAddress("1/2/3"),
- telegramtype=TelegramType.GROUP_READ,
- ),
+ telegram1, Telegram(GroupAddress("1/2/3"), payload=GroupValueRead())
)
def test_sync_operation_mode(self):
@@ -947,11 +989,7 @@ def test_sync_operation_mode(self):
self.assertEqual(xknx.telegrams.qsize(), 1)
telegram1 = xknx.telegrams.get_nowait()
self.assertEqual(
- telegram1,
- Telegram(
- destination_address=GroupAddress("1/2/4"),
- telegramtype=TelegramType.GROUP_READ,
- ),
+ telegram1, Telegram(GroupAddress("1/2/4"), payload=GroupValueRead())
)
def test_sync_controller_status(self):
@@ -967,11 +1005,7 @@ def test_sync_controller_status(self):
self.assertEqual(xknx.telegrams.qsize(), 1)
telegram1 = xknx.telegrams.get_nowait()
self.assertEqual(
- telegram1,
- Telegram(
- destination_address=GroupAddress("1/2/24"),
- telegramtype=TelegramType.GROUP_READ,
- ),
+ telegram1, Telegram(GroupAddress("1/2/24"), payload=GroupValueRead())
)
def test_sync_controller_mode(self):
@@ -987,11 +1021,7 @@ def test_sync_controller_mode(self):
self.assertEqual(xknx.telegrams.qsize(), 1)
telegram1 = xknx.telegrams.get_nowait()
self.assertEqual(
- telegram1,
- Telegram(
- destination_address=GroupAddress("1/2/14"),
- telegramtype=TelegramType.GROUP_READ,
- ),
+ telegram1, Telegram(GroupAddress("1/2/14"), payload=GroupValueRead())
)
def test_sync_operation_mode_state(self):
@@ -1013,22 +1043,13 @@ def test_sync_operation_mode_state(self):
telegrams = []
for _ in range(3):
telegrams.append(xknx.telegrams.get_nowait())
- self.assertSetEqual(
- set(telegrams),
- {
- Telegram(
- destination_address=GroupAddress("1/2/5"),
- telegramtype=TelegramType.GROUP_READ,
- ),
- Telegram(
- destination_address=GroupAddress("1/2/6"),
- telegramtype=TelegramType.GROUP_READ,
- ),
- Telegram(
- destination_address=GroupAddress("1/2/14"),
- telegramtype=TelegramType.GROUP_READ,
- ),
- },
+ self.assertListEqual(
+ telegrams,
+ [
+ Telegram(GroupAddress("1/2/5"), payload=GroupValueRead()),
+ Telegram(GroupAddress("1/2/6"), payload=GroupValueRead()),
+ Telegram(GroupAddress("1/2/14"), payload=GroupValueRead()),
+ ],
)
def test_sync_heat_cool(self):
@@ -1044,11 +1065,7 @@ def test_sync_heat_cool(self):
self.assertEqual(xknx.telegrams.qsize(), 1)
telegram1 = xknx.telegrams.get_nowait()
self.assertEqual(
- telegram1,
- Telegram(
- destination_address=GroupAddress("1/2/15"),
- telegramtype=TelegramType.GROUP_READ,
- ),
+ telegram1, Telegram(GroupAddress("1/2/15"), payload=GroupValueRead())
)
#
@@ -1059,8 +1076,10 @@ def test_process_temperature(self):
xknx = XKNX()
climate = Climate(xknx, "TestClimate", group_address_temperature="1/2/3")
- telegram = Telegram(destination_address=GroupAddress("1/2/3"))
- telegram.payload = DPTArray(DPTTemperature().to_knx(21.34))
+ telegram = Telegram(
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray(DPTTemperature().to_knx(21.34))),
+ )
self.loop.run_until_complete(climate.process(telegram))
self.assertEqual(climate.temperature.value, 21.34)
@@ -1074,15 +1093,21 @@ def test_process_operation_mode(self):
group_address_controller_status="1/2/3",
)
for operation_mode in DPT_20102_MODES:
- telegram = Telegram(destination_address=GroupAddress("1/2/5"))
- telegram.payload = DPTArray(DPTHVACMode.to_knx(operation_mode))
+ telegram = Telegram(
+ destination_address=GroupAddress("1/2/5"),
+ payload=GroupValueWrite(DPTArray(DPTHVACMode.to_knx(operation_mode))),
+ )
self.loop.run_until_complete(climate_mode.process(telegram))
self.assertEqual(climate_mode.operation_mode, operation_mode)
for operation_mode in DPT_20102_MODES:
if operation_mode == HVACOperationMode.AUTO:
continue
- telegram = Telegram(destination_address=GroupAddress("1/2/3"))
- telegram.payload = DPTArray(DPTControllerStatus.to_knx(operation_mode))
+ telegram = Telegram(
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(
+ DPTArray(DPTControllerStatus.to_knx(operation_mode))
+ ),
+ )
self.loop.run_until_complete(climate_mode.process(telegram))
self.assertEqual(climate_mode.operation_mode, operation_mode)
@@ -1093,8 +1118,12 @@ def test_process_controller_mode(self):
xknx, "TestClimate", group_address_controller_mode="1/2/5"
)
for _, controller_mode in DPTHVACContrMode.SUPPORTED_MODES.items():
- telegram = Telegram(destination_address=GroupAddress("1/2/5"))
- telegram.payload = DPTArray(DPTHVACContrMode.to_knx(controller_mode))
+ telegram = Telegram(
+ destination_address=GroupAddress("1/2/5"),
+ payload=GroupValueWrite(
+ DPTArray(DPTHVACContrMode.to_knx(controller_mode))
+ ),
+ )
self.loop.run_until_complete(climate_mode.process(telegram))
self.assertEqual(climate_mode.controller_mode, controller_mode)
@@ -1108,7 +1137,8 @@ def test_process_controller_status_wrong_payload(self):
group_address_controller_status="1/2/3",
)
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
with self.assertRaises(CouldNotParseTelegram):
self.loop.run_until_complete(climate_mode.process(telegram))
@@ -1123,7 +1153,8 @@ def test_process_controller_status_payload_invalid_length(self):
group_address_controller_status="1/2/3",
)
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTArray((23, 24))
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray((23, 24))),
)
with self.assertRaises(CouldNotParseTelegram):
self.loop.run_until_complete(climate_mode.process(telegram))
@@ -1138,7 +1169,8 @@ def test_process_operation_mode_wrong_payload(self):
group_address_controller_status="1/2/3",
)
telegram = Telegram(
- destination_address=GroupAddress("1/2/5"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/5"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
with self.assertRaises(CouldNotParseTelegram):
self.loop.run_until_complete(climate_mode.process(telegram))
@@ -1153,7 +1185,8 @@ def test_process_operation_mode_payload_invalid_length(self):
group_address_controller_status="1/2/3",
)
telegram = Telegram(
- destination_address=GroupAddress("1/2/5"), payload=DPTArray((23, 24))
+ destination_address=GroupAddress("1/2/5"),
+ payload=GroupValueWrite(DPTArray((23, 24))),
)
with self.assertRaises(CouldNotParseTelegram):
self.loop.run_until_complete(climate_mode.process(telegram))
@@ -1172,8 +1205,10 @@ async def async_after_update_callback(device):
climate.register_device_updated_cb(async_after_update_callback)
- telegram = Telegram(destination_address=GroupAddress("1/2/3"))
- telegram.payload = DPTArray(DPTTemperature().to_knx(21.34))
+ telegram = Telegram(
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray(DPTTemperature().to_knx(21.34))),
+ )
self.loop.run_until_complete(climate.process(telegram))
after_update_callback.assert_called_with(climate)
@@ -1187,13 +1222,17 @@ def test_process_heat_cool(self):
group_address_heat_cool_state="1/2/15",
)
- telegram = Telegram(destination_address=GroupAddress("1/2/14"))
- telegram.payload = DPTBinary(False)
+ telegram = Telegram(
+ destination_address=GroupAddress("1/2/14"),
+ payload=GroupValueWrite(DPTBinary(False)),
+ )
self.loop.run_until_complete(climate_mode.process(telegram))
self.assertEqual(climate_mode.controller_mode, HVACControllerMode.COOL)
- telegram = Telegram(destination_address=GroupAddress("1/2/14"))
- telegram.payload = DPTBinary(True)
+ telegram = Telegram(
+ destination_address=GroupAddress("1/2/14"),
+ payload=GroupValueWrite(DPTBinary(True)),
+ )
self.loop.run_until_complete(climate_mode.process(telegram))
self.assertEqual(climate_mode.controller_mode, HVACControllerMode.HEAT)
@@ -1349,16 +1388,20 @@ def test_process_power_status(self):
"""Test process / reading telegrams from telegram queue. Test if DPT20.105 controller mode is set correctly."""
xknx = XKNX()
climate = Climate(xknx, "TestClimate", group_address_on_off="1/2/2")
- telegram = Telegram(destination_address=GroupAddress("1/2/2"))
- telegram.payload = DPTBinary(1)
+ telegram = Telegram(
+ destination_address=GroupAddress("1/2/2"),
+ payload=GroupValueWrite(DPTBinary(1)),
+ )
self.loop.run_until_complete(climate.process(telegram))
self.assertEqual(climate.is_on, True)
climate_inv = Climate(
xknx, "TestClimate", group_address_on_off="1/2/2", on_off_invert=True
)
- telegram = Telegram(destination_address=GroupAddress("1/2/2"))
- telegram.payload = DPTBinary(1)
+ telegram = Telegram(
+ destination_address=GroupAddress("1/2/2"),
+ payload=GroupValueWrite(DPTBinary(1)),
+ )
self.loop.run_until_complete(climate_inv.process(telegram))
self.assertEqual(climate_inv.is_on, False)
@@ -1373,7 +1416,8 @@ def test_power_on_off(self):
self.assertEqual(
_telegram,
Telegram(
- destination_address=GroupAddress("1/2/2"), payload=DPTBinary(True)
+ destination_address=GroupAddress("1/2/2"),
+ payload=GroupValueWrite(DPTBinary(True)),
),
)
self.loop.run_until_complete(climate.turn_off())
@@ -1383,7 +1427,8 @@ def test_power_on_off(self):
self.assertEqual(
_telegram,
Telegram(
- destination_address=GroupAddress("1/2/2"), payload=DPTBinary(False)
+ destination_address=GroupAddress("1/2/2"),
+ payload=GroupValueWrite(DPTBinary(False)),
),
)
@@ -1397,7 +1442,8 @@ def test_power_on_off(self):
self.assertEqual(
_telegram,
Telegram(
- destination_address=GroupAddress("1/2/2"), payload=DPTBinary(False)
+ destination_address=GroupAddress("1/2/2"),
+ payload=GroupValueWrite(DPTBinary(False)),
),
)
self.loop.run_until_complete(climate_inv.turn_off())
@@ -1407,6 +1453,7 @@ def test_power_on_off(self):
self.assertEqual(
_telegram,
Telegram(
- destination_address=GroupAddress("1/2/2"), payload=DPTBinary(True)
+ destination_address=GroupAddress("1/2/2"),
+ payload=GroupValueWrite(DPTBinary(True)),
),
)
diff --git a/test/devices_tests/cover_test.py b/test/devices_tests/cover_test.py
index c70353379..cce88dccd 100644
--- a/test/devices_tests/cover_test.py
+++ b/test/devices_tests/cover_test.py
@@ -7,7 +7,8 @@
from xknx import XKNX
from xknx.devices import Cover
from xknx.dpt import DPTArray, DPTBinary
-from xknx.telegram import GroupAddress, Telegram, TelegramType
+from xknx.telegram import GroupAddress, Telegram
+from xknx.telegram.apci import GroupValueRead, GroupValueWrite
class TestCover(unittest.TestCase):
@@ -129,8 +130,7 @@ def test_sync(self):
self.assertEqual(
telegram1,
Telegram(
- destination_address=GroupAddress("1/2/3"),
- telegramtype=TelegramType.GROUP_READ,
+ destination_address=GroupAddress("1/2/3"), payload=GroupValueRead()
),
)
@@ -151,8 +151,7 @@ def test_sync_state(self):
self.assertEqual(
telegram1,
Telegram(
- destination_address=GroupAddress("1/2/4"),
- telegramtype=TelegramType.GROUP_READ,
+ destination_address=GroupAddress("1/2/4"), payload=GroupValueRead()
),
)
@@ -173,16 +172,14 @@ def test_sync_angle(self):
self.assertEqual(
telegram1,
Telegram(
- destination_address=GroupAddress("1/2/3"),
- telegramtype=TelegramType.GROUP_READ,
+ destination_address=GroupAddress("1/2/3"), payload=GroupValueRead()
),
)
telegram2 = xknx.telegrams.get_nowait()
self.assertEqual(
telegram2,
Telegram(
- destination_address=GroupAddress("1/2/4"),
- telegramtype=TelegramType.GROUP_READ,
+ destination_address=GroupAddress("1/2/4"), payload=GroupValueRead()
),
)
@@ -203,8 +200,7 @@ def test_sync_angle_state(self):
self.assertEqual(
telegram1,
Telegram(
- destination_address=GroupAddress("1/2/4"),
- telegramtype=TelegramType.GROUP_READ,
+ destination_address=GroupAddress("1/2/4"), payload=GroupValueRead()
),
)
@@ -228,7 +224,10 @@ def test_set_up(self):
# DPT 1.008 - 0:up 1:down
self.assertEqual(
telegram,
- Telegram(destination_address=GroupAddress("1/2/1"), payload=DPTBinary(0)),
+ Telegram(
+ destination_address=GroupAddress("1/2/1"),
+ payload=GroupValueWrite(DPTBinary(0)),
+ ),
)
#
@@ -250,7 +249,10 @@ def test_set_short_down(self):
telegram = xknx.telegrams.get_nowait()
self.assertEqual(
telegram,
- Telegram(destination_address=GroupAddress("1/2/1"), payload=DPTBinary(1)),
+ Telegram(
+ destination_address=GroupAddress("1/2/1"),
+ payload=GroupValueWrite(DPTBinary(1)),
+ ),
)
#
@@ -273,7 +275,10 @@ def test_set_down_inverted(self):
telegram = xknx.telegrams.get_nowait()
self.assertEqual(
telegram,
- Telegram(destination_address=GroupAddress("1/2/1"), payload=DPTBinary(0)),
+ Telegram(
+ destination_address=GroupAddress("1/2/1"),
+ payload=GroupValueWrite(DPTBinary(0)),
+ ),
)
#
@@ -296,7 +301,10 @@ def test_set_short_up(self):
# DPT 1.008 - 0:up 1:down
self.assertEqual(
telegram,
- Telegram(destination_address=GroupAddress("1/2/2"), payload=DPTBinary(0)),
+ Telegram(
+ destination_address=GroupAddress("1/2/2"),
+ payload=GroupValueWrite(DPTBinary(0)),
+ ),
)
#
@@ -320,7 +328,10 @@ def test_set_up_inverted(self):
# DPT 1.008 - 0:up 1:down
self.assertEqual(
telegram,
- Telegram(destination_address=GroupAddress("1/2/2"), payload=DPTBinary(1)),
+ Telegram(
+ destination_address=GroupAddress("1/2/2"),
+ payload=GroupValueWrite(DPTBinary(1)),
+ ),
)
#
@@ -343,7 +354,10 @@ def test_set_down(self):
# DPT 1.008 - 0:up 1:down
self.assertEqual(
telegram,
- Telegram(destination_address=GroupAddress("1/2/2"), payload=DPTBinary(1)),
+ Telegram(
+ destination_address=GroupAddress("1/2/2"),
+ payload=GroupValueWrite(DPTBinary(1)),
+ ),
)
#
@@ -365,7 +379,10 @@ def test_stop(self):
telegram = xknx.telegrams.get_nowait()
self.assertEqual(
telegram,
- Telegram(destination_address=GroupAddress("1/2/2"), payload=DPTBinary(1)),
+ Telegram(
+ destination_address=GroupAddress("1/2/2"),
+ payload=GroupValueWrite(DPTBinary(1)),
+ ),
)
cover_manual_stop = Cover(
@@ -382,7 +399,10 @@ def test_stop(self):
telegram = xknx.telegrams.get_nowait()
self.assertEqual(
telegram,
- Telegram(destination_address=GroupAddress("1/2/0"), payload=DPTBinary(1)),
+ Telegram(
+ destination_address=GroupAddress("1/2/0"),
+ payload=GroupValueWrite(DPTBinary(1)),
+ ),
)
#
@@ -404,7 +424,10 @@ def test_position(self):
telegram = xknx.telegrams.get_nowait()
self.assertEqual(
telegram,
- Telegram(destination_address=GroupAddress("1/2/3"), payload=DPTArray(0x80)),
+ Telegram(
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray(0x80)),
+ ),
)
def test_position_without_position_address_up(self):
@@ -424,7 +447,10 @@ def test_position_without_position_address_up(self):
# DPT 1.008 - 0:up 1:down
self.assertEqual(
telegram,
- Telegram(destination_address=GroupAddress("1/2/1"), payload=DPTBinary(0)),
+ Telegram(
+ destination_address=GroupAddress("1/2/1"),
+ payload=GroupValueWrite(DPTBinary(0)),
+ ),
)
self.assertEqual(cover.travelcalculator.travel_to_position, 50)
self.assertTrue(cover.is_opening())
@@ -449,7 +475,10 @@ def test_position_without_position_address_down(self):
telegram = xknx.telegrams.get_nowait()
self.assertEqual(
telegram,
- Telegram(destination_address=GroupAddress("1/2/1"), payload=DPTBinary(1)),
+ Telegram(
+ destination_address=GroupAddress("1/2/1"),
+ payload=GroupValueWrite(DPTBinary(1)),
+ ),
)
self.assertEqual(cover.travelcalculator.travel_to_position, 80)
self.assertTrue(cover.is_closing())
@@ -480,7 +509,10 @@ def test_position_without_position_address_uninitialized_up(self):
telegram = xknx.telegrams.get_nowait()
self.assertEqual(
telegram,
- Telegram(destination_address=GroupAddress("1/2/1"), payload=DPTBinary(0)),
+ Telegram(
+ destination_address=GroupAddress("1/2/1"),
+ payload=GroupValueWrite(DPTBinary(0)),
+ ),
)
def test_position_without_position_address_uninitialized_down(self):
@@ -506,7 +538,10 @@ def test_position_without_position_address_uninitialized_down(self):
telegram = xknx.telegrams.get_nowait()
self.assertEqual(
telegram,
- Telegram(destination_address=GroupAddress("1/2/1"), payload=DPTBinary(1)),
+ Telegram(
+ destination_address=GroupAddress("1/2/1"),
+ payload=GroupValueWrite(DPTBinary(1)),
+ ),
)
def test_angle(self):
@@ -528,7 +563,8 @@ def test_angle(self):
self.assertEqual(
telegram,
Telegram(
- destination_address=GroupAddress("1/4/18"), payload=DPTArray(0x80)
+ destination_address=GroupAddress("1/4/18"),
+ payload=GroupValueWrite(DPTArray(0x80)),
),
)
@@ -564,14 +600,14 @@ def test_process_position(self):
)
# initial position process - position is unknown so this is the new state - not moving
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTArray(213)
+ GroupAddress("1/2/3"), payload=GroupValueWrite(DPTArray(213))
)
self.loop.run_until_complete(cover.process(telegram))
self.assertEqual(cover.current_position(), 84)
self.assertFalse(cover.is_traveling())
# state telegram updates current position - we are not moving so this is new state - not moving
telegram = Telegram(
- destination_address=GroupAddress("1/2/4"), payload=DPTArray(42)
+ GroupAddress("1/2/4"), payload=GroupValueWrite(DPTArray(42))
)
self.loop.run_until_complete(cover.process(telegram))
self.assertEqual(cover.current_position(), 16)
@@ -579,7 +615,7 @@ def test_process_position(self):
self.assertEqual(cover.travelcalculator.travel_to_position, 16)
# new position - movement starts
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTArray(255)
+ GroupAddress("1/2/3"), payload=GroupValueWrite(DPTArray(255))
)
self.loop.run_until_complete(cover.process(telegram))
self.assertEqual(cover.current_position(), 16)
@@ -587,7 +623,7 @@ def test_process_position(self):
self.assertEqual(cover.travelcalculator.travel_to_position, 100)
# new state while moving - movement goes on; travelcalculator updated
telegram = Telegram(
- destination_address=GroupAddress("1/2/4"), payload=DPTArray(213)
+ GroupAddress("1/2/4"), payload=GroupValueWrite(DPTArray(213))
)
self.loop.run_until_complete(cover.process(telegram))
self.assertEqual(cover.current_position(), 84)
@@ -606,7 +642,7 @@ def test_process_angle(self):
group_address_angle_state="1/2/4",
)
telegram = Telegram(
- destination_address=GroupAddress("1/2/4"), payload=DPTArray(42)
+ GroupAddress("1/2/4"), payload=GroupValueWrite(DPTArray(42))
)
self.loop.run_until_complete(cover.process(telegram))
self.assertEqual(cover.current_angle(), 16)
@@ -620,7 +656,7 @@ def test_process_up(self):
cover.travelcalculator.set_position(50)
self.assertFalse(cover.is_traveling())
telegram = Telegram(
- destination_address=GroupAddress("1/2/1"), payload=DPTBinary(0)
+ GroupAddress("1/2/1"), payload=GroupValueWrite(DPTBinary(0))
)
self.loop.run_until_complete(cover.process(telegram))
self.assertTrue(cover.is_opening())
@@ -634,7 +670,7 @@ def test_process_down(self):
cover.travelcalculator.set_position(50)
self.assertFalse(cover.is_traveling())
telegram = Telegram(
- destination_address=GroupAddress("1/2/1"), payload=DPTBinary(1)
+ GroupAddress("1/2/1"), payload=GroupValueWrite(DPTBinary(1))
)
self.loop.run_until_complete(cover.process(telegram))
self.assertTrue(cover.is_closing())
@@ -652,7 +688,7 @@ def test_process_stop(self):
self.loop.run_until_complete(cover.set_down())
self.assertTrue(cover.is_traveling())
telegram = Telegram(
- destination_address=GroupAddress("1/2/2"), payload=DPTBinary(1)
+ GroupAddress("1/2/2"), payload=GroupValueWrite(DPTBinary(1))
)
self.loop.run_until_complete(cover.process(telegram))
self.assertFalse(cover.is_traveling())
@@ -670,7 +706,7 @@ def test_process_short_stop(self):
self.loop.run_until_complete(cover.set_down())
self.assertTrue(cover.is_traveling())
telegram = Telegram(
- destination_address=GroupAddress("1/2/2"), payload=DPTBinary(1)
+ GroupAddress("1/2/2"), payload=GroupValueWrite(DPTBinary(1))
)
self.loop.run_until_complete(cover.process(telegram))
self.assertFalse(cover.is_traveling())
@@ -708,14 +744,15 @@ async def async_after_update_callback(device):
]:
with self.subTest(address=address, feature=feature):
telegram = Telegram(
- destination_address=GroupAddress(address), payload=payload
+ destination_address=GroupAddress(address),
+ payload=GroupValueWrite(payload),
)
self.loop.run_until_complete(cover.process(telegram))
after_update_callback.assert_called_with(cover)
after_update_callback.reset_mock()
# Stop only when cover is travelling
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ GroupAddress("1/2/3"), payload=GroupValueWrite(DPTBinary(1))
)
self.loop.run_until_complete(cover.process(telegram))
after_update_callback.assert_not_called()
diff --git a/test/devices_tests/datetime_test.py b/test/devices_tests/datetime_test.py
index c47cbece6..ecd9aae50 100644
--- a/test/devices_tests/datetime_test.py
+++ b/test/devices_tests/datetime_test.py
@@ -7,7 +7,8 @@
from xknx import XKNX
from xknx.devices import DateTime
from xknx.dpt import DPTArray
-from xknx.telegram import GroupAddress, Telegram, TelegramType
+from xknx.telegram import GroupAddress, Telegram
+from xknx.telegram.apci import GroupValueRead, GroupValueResponse, GroupValueWrite
class TestDateTime(unittest.TestCase):
@@ -43,10 +44,10 @@ def test_sync_datetime(self):
self.assertEqual(xknx.telegrams.qsize(), 1)
telegram = xknx.telegrams.get_nowait()
self.assertEqual(telegram.destination_address, GroupAddress("1/2/3"))
- self.assertEqual(telegram.telegramtype, TelegramType.GROUP_WRITE)
- self.assertEqual(len(telegram.payload.value), 8)
+ self.assertEqual(len(telegram.payload.value.value), 8)
self.assertEqual(
- telegram.payload.value, (0x75, 0x01, 0x07, 0xE9, 0x0D, 0x0E, 0x20, 0x80)
+ telegram.payload.value.value,
+ (0x75, 0x01, 0x07, 0xE9, 0x0D, 0x0E, 0x20, 0x80),
)
#
@@ -69,9 +70,8 @@ def test_sync_date(self):
telegram = xknx.telegrams.get_nowait()
self.assertEqual(telegram.destination_address, GroupAddress("1/2/3"))
- self.assertEqual(telegram.telegramtype, TelegramType.GROUP_WRITE)
- self.assertEqual(len(telegram.payload.value), 3)
- self.assertEqual(telegram.payload.value, (0x07, 0x01, 0x11))
+ self.assertEqual(len(telegram.payload.value.value), 3)
+ self.assertEqual(telegram.payload.value.value, (0x07, 0x01, 0x11))
#
# SYNC Time
@@ -93,9 +93,8 @@ def test_sync_time(self):
telegram = xknx.telegrams.get_nowait()
self.assertEqual(telegram.destination_address, GroupAddress("1/2/3"))
- self.assertEqual(telegram.telegramtype, TelegramType.GROUP_WRITE)
- self.assertEqual(len(telegram.payload.value), 3)
- self.assertEqual(telegram.payload.value, (0xE9, 0x0D, 0x0E))
+ self.assertEqual(len(telegram.payload.value.value), 3)
+ self.assertEqual(telegram.payload.value.value, (0xE9, 0x0D, 0x0E))
#
# PROCESS
@@ -111,8 +110,7 @@ def test_process_read(self):
)
telegram_read = Telegram(
- destination_address=GroupAddress("1/2/3"),
- telegramtype=TelegramType.GROUP_READ,
+ destination_address=GroupAddress("1/2/3"), payload=GroupValueRead()
)
with patch("time.localtime") as mock_time:
mock_time.return_value = time.struct_time([2017, 1, 7, 9, 13, 14, 6, 0, 0])
@@ -127,8 +125,7 @@ def test_process_read(self):
telegram,
Telegram(
destination_address=GroupAddress("1/2/3"),
- telegramtype=TelegramType.GROUP_RESPONSE,
- payload=DPTArray((0xE9, 0xD, 0xE)),
+ payload=GroupValueResponse(DPTArray((0xE9, 0xD, 0xE))),
),
)
diff --git a/test/devices_tests/device_test.py b/test/devices_tests/device_test.py
index c925e0b43..ea607f58c 100644
--- a/test/devices_tests/device_test.py
+++ b/test/devices_tests/device_test.py
@@ -6,7 +6,8 @@
from xknx import XKNX
from xknx.devices import Device, Sensor
from xknx.dpt import DPTArray
-from xknx.telegram import GroupAddress, Telegram, TelegramType
+from xknx.telegram import GroupAddress, Telegram
+from xknx.telegram.apci import GroupValueRead, GroupValueResponse, GroupValueWrite
class TestDevice(unittest.TestCase):
@@ -102,9 +103,7 @@ def test_process(self):
fut.set_result(None)
mock_group_read.return_value = fut
telegram = Telegram(
- destination_address=GroupAddress("1/2/1"),
- payload=DPTArray((0x01, 0x02)),
- telegramtype=TelegramType.GROUP_READ,
+ destination_address=GroupAddress("1/2/1"), payload=GroupValueRead()
)
self.loop.run_until_complete(device.process(telegram))
mock_group_read.assert_called_with(telegram)
@@ -115,8 +114,7 @@ def test_process(self):
mock_group_write.return_value = fut
telegram = Telegram(
destination_address=GroupAddress("1/2/1"),
- payload=DPTArray((0x01, 0x02)),
- telegramtype=TelegramType.GROUP_WRITE,
+ payload=GroupValueWrite(DPTArray((0x01, 0x02))),
)
self.loop.run_until_complete(device.process(telegram))
mock_group_write.assert_called_with(telegram)
@@ -127,8 +125,7 @@ def test_process(self):
mock_group_response.return_value = fut
telegram = Telegram(
destination_address=GroupAddress("1/2/1"),
- payload=DPTArray((0x01, 0x02)),
- telegramtype=TelegramType.GROUP_RESPONSE,
+ payload=GroupValueResponse(DPTArray((0x01, 0x02))),
)
self.loop.run_until_complete(device.process(telegram))
mock_group_response.assert_called_with(telegram)
diff --git a/test/devices_tests/expose_sensor_test.py b/test/devices_tests/expose_sensor_test.py
index c7fbafe17..86cbe57fd 100644
--- a/test/devices_tests/expose_sensor_test.py
+++ b/test/devices_tests/expose_sensor_test.py
@@ -6,7 +6,8 @@
from xknx import XKNX
from xknx.devices import ExposeSensor
from xknx.dpt import DPTArray, DPTBinary
-from xknx.telegram import GroupAddress, Telegram, TelegramType
+from xknx.telegram import GroupAddress, Telegram
+from xknx.telegram.apci import GroupValueRead, GroupValueResponse, GroupValueWrite
class TestExposeSensor(unittest.TestCase):
@@ -73,8 +74,7 @@ def test_set_binary(self):
telegram,
Telegram(
destination_address=GroupAddress("1/2/3"),
- telegramtype=TelegramType.GROUP_WRITE,
- payload=DPTBinary(0),
+ payload=GroupValueWrite(DPTBinary(0)),
),
)
@@ -92,8 +92,7 @@ def test_set_percent(self):
telegram,
Telegram(
destination_address=GroupAddress("1/2/3"),
- telegramtype=TelegramType.GROUP_WRITE,
- payload=DPTArray((0xBF,)),
+ payload=GroupValueWrite(DPTArray((0xBF,))),
),
)
@@ -110,8 +109,7 @@ def test_set_temperature(self):
telegram,
Telegram(
destination_address=GroupAddress("1/2/3"),
- telegramtype=TelegramType.GROUP_WRITE,
- payload=DPTArray((0x0C, 0x1A)),
+ payload=GroupValueWrite(DPTArray((0x0C, 0x1A))),
),
)
@@ -126,8 +124,7 @@ def test_process_binary(self):
)
expose_sensor.sensor_value.payload = DPTBinary(1)
- telegram = Telegram(destination_address=GroupAddress("1/2/3"))
- telegram.telegramtype = TelegramType.GROUP_READ
+ telegram = Telegram(GroupAddress("1/2/3"), payload=GroupValueRead())
self.loop.run_until_complete(expose_sensor.process(telegram))
self.assertEqual(xknx.telegrams.qsize(), 1)
telegram = xknx.telegrams.get_nowait()
@@ -135,8 +132,7 @@ def test_process_binary(self):
telegram,
Telegram(
destination_address=GroupAddress("1/2/3"),
- telegramtype=TelegramType.GROUP_RESPONSE,
- payload=DPTBinary(True),
+ payload=GroupValueResponse(DPTBinary(True)),
),
)
@@ -148,8 +144,7 @@ def test_process_percent(self):
)
expose_sensor.sensor_value.payload = DPTArray((0x40,))
- telegram = Telegram(destination_address=GroupAddress("1/2/3"))
- telegram.telegramtype = TelegramType.GROUP_READ
+ telegram = Telegram(GroupAddress("1/2/3"), payload=GroupValueRead())
self.loop.run_until_complete(expose_sensor.process(telegram))
self.assertEqual(xknx.telegrams.qsize(), 1)
telegram = xknx.telegrams.get_nowait()
@@ -157,8 +152,7 @@ def test_process_percent(self):
telegram,
Telegram(
destination_address=GroupAddress("1/2/3"),
- telegramtype=TelegramType.GROUP_RESPONSE,
- payload=DPTArray((0x40,)),
+ payload=GroupValueResponse(DPTArray((0x40,))),
),
)
@@ -170,8 +164,7 @@ def test_process_temperature(self):
)
expose_sensor.sensor_value.payload = DPTArray((0x0C, 0x1A))
- telegram = Telegram(destination_address=GroupAddress("1/2/3"))
- telegram.telegramtype = TelegramType.GROUP_READ
+ telegram = Telegram(GroupAddress("1/2/3"), payload=GroupValueRead())
self.loop.run_until_complete(expose_sensor.process(telegram))
self.assertEqual(xknx.telegrams.qsize(), 1)
telegram = xknx.telegrams.get_nowait()
@@ -179,8 +172,7 @@ def test_process_temperature(self):
telegram,
Telegram(
destination_address=GroupAddress("1/2/3"),
- telegramtype=TelegramType.GROUP_RESPONSE,
- payload=DPTArray((0x0C, 0x1A)),
+ payload=GroupValueResponse(DPTArray((0x0C, 0x1A))),
),
)
diff --git a/test/devices_tests/fan_test.py b/test/devices_tests/fan_test.py
index f9715e6ba..0e7a7767f 100644
--- a/test/devices_tests/fan_test.py
+++ b/test/devices_tests/fan_test.py
@@ -7,7 +7,8 @@
from xknx.devices import Fan
from xknx.dpt import DPTArray, DPTBinary
from xknx.exceptions import CouldNotParseTelegram
-from xknx.telegram import GroupAddress, Telegram, TelegramType
+from xknx.telegram import GroupAddress, Telegram
+from xknx.telegram.apci import GroupValueRead, GroupValueWrite
class TestFan(unittest.TestCase):
@@ -39,8 +40,7 @@ def test_sync(self):
self.assertEqual(
telegram1,
Telegram(
- destination_address=GroupAddress("1/2/3"),
- telegramtype=TelegramType.GROUP_READ,
+ destination_address=GroupAddress("1/2/3"), payload=GroupValueRead()
),
)
@@ -64,8 +64,7 @@ def test_sync_state_address(self):
self.assertEqual(
telegram1,
Telegram(
- destination_address=GroupAddress("1/2/4"),
- telegramtype=TelegramType.GROUP_READ,
+ destination_address=GroupAddress("1/2/4"), payload=GroupValueRead()
),
)
@@ -83,7 +82,10 @@ def test_set_speed(self):
# 140 is 55% as byte (0...255)
self.assertEqual(
telegram,
- Telegram(destination_address=GroupAddress("1/2/3"), payload=DPTArray(140)),
+ Telegram(
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray(140)),
+ ),
)
#
@@ -97,7 +99,8 @@ def test_process_speed(self):
# 140 is 55% as byte (0...255)
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTArray(140)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray(140)),
)
self.loop.run_until_complete(fan.process(telegram))
self.assertEqual(fan.current_speed, 55)
@@ -107,7 +110,8 @@ def test_process_speed_wrong_payload(self): # pylint: disable=invalid-name
xknx = XKNX()
fan = Fan(xknx, name="TestFan", group_address_speed="1/2/3")
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
with self.assertRaises(CouldNotParseTelegram):
self.loop.run_until_complete(fan.process(telegram))
@@ -118,7 +122,8 @@ def test_process_fan_payload_invalid_length(self):
xknx = XKNX()
fan = Fan(xknx, name="TestFan", group_address_speed="1/2/3")
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTArray((23, 24))
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray((23, 24))),
)
with self.assertRaises(CouldNotParseTelegram):
self.loop.run_until_complete(fan.process(telegram))
diff --git a/test/devices_tests/light_test.py b/test/devices_tests/light_test.py
index 0d6e8b104..2e54fb9d5 100644
--- a/test/devices_tests/light_test.py
+++ b/test/devices_tests/light_test.py
@@ -7,7 +7,8 @@
from xknx.devices import Light
from xknx.dpt import DPTArray, DPTBinary
from xknx.exceptions import CouldNotParseTelegram
-from xknx.telegram import GroupAddress, Telegram, TelegramType
+from xknx.telegram import GroupAddress, Telegram
+from xknx.telegram.apci import GroupValueRead, GroupValueWrite
class TestLight(unittest.TestCase):
@@ -156,33 +157,27 @@ def test_sync(self):
test_telegrams = [
Telegram(
- destination_address=GroupAddress("1/2/3"),
- telegramtype=TelegramType.GROUP_READ,
+ destination_address=GroupAddress("1/2/3"), payload=GroupValueRead()
),
Telegram(
- destination_address=GroupAddress("1/2/5"),
- telegramtype=TelegramType.GROUP_READ,
+ destination_address=GroupAddress("1/2/5"), payload=GroupValueRead()
),
Telegram(
- destination_address=GroupAddress("1/2/6"),
- telegramtype=TelegramType.GROUP_READ,
+ destination_address=GroupAddress("1/2/6"), payload=GroupValueRead()
),
Telegram(
- destination_address=GroupAddress("1/2/7"),
- telegramtype=TelegramType.GROUP_READ,
+ destination_address=GroupAddress("1/2/9"), payload=GroupValueRead()
),
Telegram(
- destination_address=GroupAddress("1/2/8"),
- telegramtype=TelegramType.GROUP_READ,
+ destination_address=GroupAddress("1/2/7"), payload=GroupValueRead()
),
Telegram(
- destination_address=GroupAddress("1/2/9"),
- telegramtype=TelegramType.GROUP_READ,
+ destination_address=GroupAddress("1/2/8"), payload=GroupValueRead()
),
]
- self.assertEqual(len(set(telegrams)), 6)
- self.assertEqual(set(telegrams), set(test_telegrams))
+ self.assertEqual(len(telegrams), 6)
+ self.assertListEqual(telegrams, test_telegrams)
#
# SYNC WITH STATE ADDRESS
@@ -216,33 +211,27 @@ def test_sync_state_address(self):
test_telegrams = [
Telegram(
- destination_address=GroupAddress("1/2/4"),
- telegramtype=TelegramType.GROUP_READ,
+ destination_address=GroupAddress("1/2/4"), payload=GroupValueRead()
),
Telegram(
- destination_address=GroupAddress("1/2/6"),
- telegramtype=TelegramType.GROUP_READ,
+ destination_address=GroupAddress("1/2/6"), payload=GroupValueRead()
),
Telegram(
- destination_address=GroupAddress("1/2/8"),
- telegramtype=TelegramType.GROUP_READ,
+ destination_address=GroupAddress("1/2/8"), payload=GroupValueRead()
),
Telegram(
- destination_address=GroupAddress("1/2/10"),
- telegramtype=TelegramType.GROUP_READ,
+ destination_address=GroupAddress("1/2/14"), payload=GroupValueRead()
),
Telegram(
- destination_address=GroupAddress("1/2/12"),
- telegramtype=TelegramType.GROUP_READ,
+ destination_address=GroupAddress("1/2/10"), payload=GroupValueRead()
),
Telegram(
- destination_address=GroupAddress("1/2/14"),
- telegramtype=TelegramType.GROUP_READ,
+ destination_address=GroupAddress("1/2/12"), payload=GroupValueRead()
),
]
- self.assertEqual(len(set(telegrams)), 6)
- self.assertEqual(set(telegrams), set(test_telegrams))
+ self.assertEqual(len(telegrams), 6)
+ self.assertListEqual(telegrams, test_telegrams)
#
# TEST SET ON
@@ -261,7 +250,10 @@ def test_set_on(self):
telegram = xknx.telegrams.get_nowait()
self.assertEqual(
telegram,
- Telegram(destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)),
+ Telegram(
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
+ ),
)
#
@@ -281,7 +273,10 @@ def test_set_off(self):
telegram = xknx.telegrams.get_nowait()
self.assertEqual(
telegram,
- Telegram(destination_address=GroupAddress("1/2/3"), payload=DPTBinary(0)),
+ Telegram(
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(0)),
+ ),
)
#
@@ -301,7 +296,10 @@ def test_set_brightness(self):
telegram = xknx.telegrams.get_nowait()
self.assertEqual(
telegram,
- Telegram(destination_address=GroupAddress("1/2/5"), payload=DPTArray(23)),
+ Telegram(
+ destination_address=GroupAddress("1/2/5"),
+ payload=GroupValueWrite(DPTArray(23)),
+ ),
)
def test_set_brightness_not_dimmable(self):
@@ -335,7 +333,7 @@ def test_set_color(self):
telegram,
Telegram(
destination_address=GroupAddress("1/2/5"),
- payload=DPTArray((23, 24, 25)),
+ payload=GroupValueWrite(DPTArray((23, 24, 25))),
),
)
self.loop.run_until_complete(xknx.devices.process(telegram))
@@ -373,7 +371,7 @@ def test_set_color_rgbw(self):
telegram,
Telegram(
destination_address=GroupAddress("1/2/5"),
- payload=DPTArray((23, 24, 25, 26, 0, 15)),
+ payload=GroupValueWrite(DPTArray((23, 24, 25, 26, 0, 15))),
),
)
self.loop.run_until_complete(xknx.devices.process(telegram))
@@ -414,7 +412,10 @@ def test_set_tw(self):
telegram = xknx.telegrams.get_nowait()
self.assertEqual(
telegram,
- Telegram(destination_address=GroupAddress("1/2/5"), payload=DPTArray(23)),
+ Telegram(
+ destination_address=GroupAddress("1/2/5"),
+ payload=GroupValueWrite(DPTArray(23)),
+ ),
)
def test_set_tw_unsupported(self):
@@ -448,10 +449,12 @@ def test_set_color_temp(self):
telegram,
Telegram(
destination_address=GroupAddress("1/2/5"),
- payload=DPTArray(
- (
- 0x0F,
- 0xA0,
+ payload=GroupValueWrite(
+ DPTArray(
+ (
+ 0x0F,
+ 0xA0,
+ )
)
),
),
@@ -484,13 +487,15 @@ def test_process_switch(self):
self.assertEqual(light.state, None)
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
self.loop.run_until_complete(light.process(telegram))
self.assertEqual(light.state, True)
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(0)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(0)),
)
self.loop.run_until_complete(light.process(telegram))
self.assertEqual(light.state, False)
@@ -515,7 +520,8 @@ async def async_after_update_callback(device):
light.register_device_updated_cb(async_after_update_callback)
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
self.loop.run_until_complete(light.process(telegram))
@@ -533,7 +539,8 @@ def test_process_dimm(self):
self.assertEqual(light.current_brightness, None)
telegram = Telegram(
- destination_address=GroupAddress("1/2/5"), payload=DPTArray(23)
+ destination_address=GroupAddress("1/2/5"),
+ payload=GroupValueWrite(DPTArray(23)),
)
self.loop.run_until_complete(light.process(telegram))
self.assertEqual(light.current_brightness, 23)
@@ -548,7 +555,8 @@ def test_process_dimm_wrong_payload(self):
group_address_brightness="1/2/5",
)
telegram = Telegram(
- destination_address=GroupAddress("1/2/5"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/5"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
with self.assertRaises(CouldNotParseTelegram):
self.loop.run_until_complete(light.process(telegram))
@@ -564,7 +572,8 @@ def test_process_dimm_payload_invalid_length(self):
group_address_brightness="1/2/5",
)
telegram = Telegram(
- destination_address=GroupAddress("1/2/5"), payload=DPTArray((23, 24))
+ destination_address=GroupAddress("1/2/5"),
+ payload=GroupValueWrite(DPTArray((23, 24))),
)
with self.assertRaises(CouldNotParseTelegram):
self.loop.run_until_complete(light.process(telegram))
@@ -580,7 +589,8 @@ def test_process_color(self):
)
self.assertEqual(light.current_color, (None, None))
telegram = Telegram(
- destination_address=GroupAddress("1/2/5"), payload=DPTArray((23, 24, 25))
+ destination_address=GroupAddress("1/2/5"),
+ payload=GroupValueWrite(DPTArray((23, 24, 25))),
)
self.loop.run_until_complete(light.process(telegram))
self.assertEqual(light.current_color, ((23, 24, 25), None))
@@ -598,7 +608,7 @@ def test_process_color_rgbw(self):
self.assertEqual(light.current_color, (None, None))
telegram = Telegram(
destination_address=GroupAddress("1/2/5"),
- payload=DPTArray((23, 24, 25, 26, 0, 15)),
+ payload=GroupValueWrite(DPTArray((23, 24, 25, 26, 0, 15))),
)
self.loop.run_until_complete(light.process(telegram))
self.assertEqual(light.current_color, ([23, 24, 25], 26))
@@ -615,7 +625,8 @@ def test_process_tunable_white(self):
self.assertEqual(light.current_tunable_white, None)
telegram = Telegram(
- destination_address=GroupAddress("1/2/5"), payload=DPTArray(23)
+ destination_address=GroupAddress("1/2/5"),
+ payload=GroupValueWrite(DPTArray(23)),
)
self.loop.run_until_complete(light.process(telegram))
self.assertEqual(light.current_tunable_white, 23)
@@ -630,7 +641,8 @@ def test_process_tunable_white_wrong_payload(self):
group_address_tunable_white="1/2/5",
)
telegram = Telegram(
- destination_address=GroupAddress("1/2/5"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/5"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
with self.assertRaises(CouldNotParseTelegram):
self.loop.run_until_complete(light.process(telegram))
@@ -646,7 +658,8 @@ def test_process_tunable_white_payload_invalid_length(self):
group_address_tunable_white="1/2/5",
)
telegram = Telegram(
- destination_address=GroupAddress("1/2/5"), payload=DPTArray((23, 24))
+ destination_address=GroupAddress("1/2/5"),
+ payload=GroupValueWrite(DPTArray((23, 24))),
)
with self.assertRaises(CouldNotParseTelegram):
self.loop.run_until_complete(light.process(telegram))
@@ -664,10 +677,12 @@ def test_process_color_temperature(self):
telegram = Telegram(
destination_address=GroupAddress("1/2/5"),
- payload=DPTArray(
- (
- 0x0F,
- 0xA0,
+ payload=GroupValueWrite(
+ DPTArray(
+ (
+ 0x0F,
+ 0xA0,
+ )
)
),
)
@@ -684,7 +699,8 @@ def test_process_color_temperature_wrong_payload(self):
group_address_color_temperature="1/2/5",
)
telegram = Telegram(
- destination_address=GroupAddress("1/2/5"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/5"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
with self.assertRaises(CouldNotParseTelegram):
self.loop.run_until_complete(light.process(telegram))
@@ -700,7 +716,8 @@ def test_process_color_temperature_payload_invalid_length(self):
group_address_color_temperature="1/2/5",
)
telegram = Telegram(
- destination_address=GroupAddress("1/2/5"), payload=DPTArray(23)
+ destination_address=GroupAddress("1/2/5"),
+ payload=GroupValueWrite(DPTArray(23)),
)
with self.assertRaises(CouldNotParseTelegram):
self.loop.run_until_complete(light.process(telegram))
diff --git a/test/devices_tests/notification_test.py b/test/devices_tests/notification_test.py
index 31e5a22c0..c5a1bf4e0 100644
--- a/test/devices_tests/notification_test.py
+++ b/test/devices_tests/notification_test.py
@@ -7,7 +7,8 @@
from xknx.devices import Notification
from xknx.dpt import DPTArray, DPTBinary, DPTString
from xknx.exceptions import CouldNotParseTelegram
-from xknx.telegram import GroupAddress, Telegram, TelegramType
+from xknx.telegram import GroupAddress, Telegram
+from xknx.telegram.apci import GroupValueRead, GroupValueWrite
class TestNotification(unittest.TestCase):
@@ -37,8 +38,7 @@ def test_sync_state(self):
self.assertEqual(
telegram,
Telegram(
- destination_address=GroupAddress("1/2/4"),
- telegramtype=TelegramType.GROUP_READ,
+ destination_address=GroupAddress("1/2/4"), payload=GroupValueRead()
),
)
@@ -51,14 +51,14 @@ def test_process(self):
notification = Notification(xknx, "Warning", group_address="1/2/3")
telegram_set = Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTArray(DPTString().to_knx("Ein Prosit!")),
+ payload=GroupValueWrite(DPTArray(DPTString().to_knx("Ein Prosit!"))),
)
self.loop.run_until_complete(notification.process(telegram_set))
self.assertEqual(notification.message, "Ein Prosit!")
telegram_unset = Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTArray(DPTString().to_knx("")),
+ payload=GroupValueWrite(DPTArray(DPTString().to_knx(""))),
)
self.loop.run_until_complete(notification.process(telegram_unset))
self.assertEqual(notification.message, "")
@@ -77,7 +77,7 @@ async def async_after_update_callback(device):
notification.register_device_updated_cb(async_after_update_callback)
telegram_set = Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTArray(DPTString().to_knx("Ein Prosit!")),
+ payload=GroupValueWrite(DPTArray(DPTString().to_knx("Ein Prosit!"))),
)
self.loop.run_until_complete(notification.process(telegram_set))
after_update_callback.assert_called_with(notification)
@@ -88,7 +88,8 @@ def test_process_payload_invalid_length(self):
xknx = XKNX()
notification = Notification(xknx, "Warning", group_address="1/2/3")
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTArray((23, 24))
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray((23, 24))),
)
with self.assertRaises(CouldNotParseTelegram):
self.loop.run_until_complete(notification.process(telegram))
@@ -98,7 +99,8 @@ def test_process_wrong_payload(self):
xknx = XKNX()
notification = Notification(xknx, "Warning", group_address="1/2/3")
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
with self.assertRaises(CouldNotParseTelegram):
self.loop.run_until_complete(notification.process(telegram))
@@ -117,7 +119,7 @@ def test_set(self):
telegram,
Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTArray(DPTString().to_knx("Ein Prosit!")),
+ payload=GroupValueWrite(DPTArray(DPTString().to_knx("Ein Prosit!"))),
),
)
# test if message longer than 14 chars gets cropped
@@ -129,7 +131,7 @@ def test_set(self):
telegram,
Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTArray(DPTString().to_knx("This is too lo")),
+ payload=GroupValueWrite(DPTArray(DPTString().to_knx("This is too lo"))),
),
)
diff --git a/test/devices_tests/scene_test.py b/test/devices_tests/scene_test.py
index 671b94003..9898bfc69 100644
--- a/test/devices_tests/scene_test.py
+++ b/test/devices_tests/scene_test.py
@@ -8,6 +8,7 @@
from xknx.devices import Scene
from xknx.dpt import DPTArray
from xknx.telegram import GroupAddress, Telegram
+from xknx.telegram.apci import GroupValueWrite
class TestScene(unittest.TestCase):
@@ -46,7 +47,10 @@ def test_run(self):
telegram = xknx.telegrams.get_nowait()
self.assertEqual(
telegram,
- Telegram(destination_address=GroupAddress("1/2/1"), payload=DPTArray(0x16)),
+ Telegram(
+ destination_address=GroupAddress("1/2/1"),
+ payload=GroupValueWrite(DPTArray(0x16)),
+ ),
)
def test_do(self):
@@ -58,7 +62,10 @@ def test_do(self):
telegram = xknx.telegrams.get_nowait()
self.assertEqual(
telegram,
- Telegram(destination_address=GroupAddress("1/2/1"), payload=DPTArray(0x16)),
+ Telegram(
+ destination_address=GroupAddress("1/2/1"),
+ payload=GroupValueWrite(DPTArray(0x16)),
+ ),
)
def test_wrong_do(self):
diff --git a/test/devices_tests/sensor_expose_loop_test.py b/test/devices_tests/sensor_expose_loop_test.py
index db73175b9..e910a390d 100644
--- a/test/devices_tests/sensor_expose_loop_test.py
+++ b/test/devices_tests/sensor_expose_loop_test.py
@@ -5,7 +5,8 @@
from xknx import XKNX
from xknx.devices import BinarySensor, ExposeSensor, Sensor
from xknx.dpt import DPTArray, DPTBinary
-from xknx.telegram import GroupAddress, Telegram, TelegramDirection, TelegramType
+from xknx.telegram import GroupAddress, Telegram, TelegramDirection
+from xknx.telegram.apci import GroupValueWrite
class SensorExposeLoopTest(unittest.TestCase):
@@ -1460,9 +1461,8 @@ def test_array_sensor_loop(self):
incoming_telegram = Telegram(
destination_address=GroupAddress("1/1/1"),
- telegramtype=TelegramType.GROUP_WRITE,
direction=TelegramDirection.INCOMING,
- payload=test_payload,
+ payload=GroupValueWrite(test_payload),
)
self.loop.run_until_complete(sensor.process(incoming_telegram))
@@ -1482,9 +1482,8 @@ def test_array_sensor_loop(self):
outgoing_telegram,
Telegram(
destination_address=GroupAddress("2/2/2"),
- telegramtype=TelegramType.GROUP_WRITE,
direction=TelegramDirection.OUTGOING,
- payload=test_payload,
+ payload=GroupValueWrite(test_payload),
),
)
@@ -1510,9 +1509,8 @@ def test_binary_sensor_loop(self):
incoming_telegram = Telegram(
destination_address=GroupAddress("1/1/1"),
- telegramtype=TelegramType.GROUP_WRITE,
direction=TelegramDirection.INCOMING,
- payload=test_payload,
+ payload=GroupValueWrite(test_payload),
)
self.loop.run_until_complete(sensor.process(incoming_telegram))
@@ -1526,8 +1524,7 @@ def test_binary_sensor_loop(self):
outgoing_telegram,
Telegram(
destination_address=GroupAddress("2/2/2"),
- telegramtype=TelegramType.GROUP_WRITE,
direction=TelegramDirection.OUTGOING,
- payload=test_payload,
+ payload=GroupValueWrite(test_payload),
),
)
diff --git a/test/devices_tests/sensor_test.py b/test/devices_tests/sensor_test.py
index 7157ce386..ad928f3cf 100644
--- a/test/devices_tests/sensor_test.py
+++ b/test/devices_tests/sensor_test.py
@@ -6,7 +6,8 @@
from xknx import XKNX
from xknx.devices import Sensor
from xknx.dpt import DPTArray
-from xknx.telegram import GroupAddress, Telegram, TelegramType
+from xknx.telegram import GroupAddress, Telegram
+from xknx.telegram.apci import GroupValueRead, GroupValueResponse, GroupValueWrite
class TestSensor(unittest.TestCase):
@@ -78,11 +79,12 @@ async def async_after_update_callback(device):
# set initial payload of sensor
sensor.sensor_value.payload = payload
- telegram = Telegram(destination_address=GroupAddress("1/2/3"), payload=payload)
+ telegram = Telegram(
+ destination_address=GroupAddress("1/2/3"), payload=GroupValueWrite(payload)
+ )
response_telegram = Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=payload,
- telegramtype=TelegramType.GROUP_RESPONSE,
+ payload=GroupValueResponse(payload),
)
# verify not called when always_callback is False
@@ -2642,8 +2644,7 @@ def test_sync(self):
self.assertEqual(
telegram,
Telegram(
- destination_address=GroupAddress("1/2/3"),
- telegramtype=TelegramType.GROUP_READ,
+ destination_address=GroupAddress("1/2/3"), payload=GroupValueRead()
),
)
@@ -2669,8 +2670,10 @@ def test_process(self):
xknx, "TestSensor", value_type="temperature", group_address_state="1/2/3"
)
- telegram = Telegram(destination_address=GroupAddress("1/2/3"))
- telegram.payload = DPTArray((0x06, 0xA0))
+ telegram = Telegram(
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray((0x06, 0xA0))),
+ )
self.loop.run_until_complete(sensor.process(telegram))
self.assertEqual(sensor.sensor_value.payload, DPTArray((0x06, 0xA0)))
self.assertEqual(sensor.resolve_state(), 16.96)
@@ -2691,7 +2694,9 @@ async def async_after_update_callback(device):
sensor.register_device_updated_cb(async_after_update_callback)
- telegram = Telegram(destination_address=GroupAddress("1/2/3"))
- telegram.payload = DPTArray((0x01, 0x02))
+ telegram = Telegram(
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray((0x01, 0x02))),
+ )
self.loop.run_until_complete(sensor.process(telegram))
after_update_callback.assert_called_with(sensor)
diff --git a/test/devices_tests/switch_test.py b/test/devices_tests/switch_test.py
index 2ed54db4d..a26e0c233 100644
--- a/test/devices_tests/switch_test.py
+++ b/test/devices_tests/switch_test.py
@@ -6,7 +6,8 @@
from xknx import XKNX
from xknx.devices import Switch
from xknx.dpt import DPTBinary
-from xknx.telegram import GroupAddress, Telegram, TelegramType
+from xknx.telegram import GroupAddress, Telegram
+from xknx.telegram.apci import GroupValueRead, GroupValueResponse, GroupValueWrite
class AsyncMock(MagicMock):
@@ -44,8 +45,7 @@ def test_sync(self):
self.assertEqual(
telegram,
Telegram(
- destination_address=GroupAddress("1/2/3"),
- telegramtype=TelegramType.GROUP_READ,
+ destination_address=GroupAddress("1/2/3"), payload=GroupValueRead()
),
)
@@ -63,8 +63,7 @@ def test_sync_state_address(self):
self.assertEqual(
telegram,
Telegram(
- destination_address=GroupAddress("1/2/4"),
- telegramtype=TelegramType.GROUP_READ,
+ destination_address=GroupAddress("1/2/4"), payload=GroupValueRead()
),
)
@@ -87,10 +86,12 @@ def test_process(self):
callback_mock.assert_not_called()
telegram_on = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
telegram_off = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(0)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(0)),
)
self.loop.run_until_complete(switch1.process(telegram_on))
@@ -136,13 +137,11 @@ def test_process_state(self):
telegram_on = Telegram(
destination_address=GroupAddress("1/2/4"),
- payload=DPTBinary(1),
- telegramtype=TelegramType.GROUP_RESPONSE,
+ payload=GroupValueResponse(DPTBinary(1)),
)
telegram_off = Telegram(
destination_address=GroupAddress("1/2/4"),
- payload=DPTBinary(0),
- telegramtype=TelegramType.GROUP_RESPONSE,
+ payload=GroupValueResponse(DPTBinary(0)),
)
self.loop.run_until_complete(switch1.process(telegram_on))
@@ -170,10 +169,12 @@ def test_process_invert(self):
self.assertEqual(switch.state, None)
telegram_inv_on = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(0)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(0)),
)
telegram_inv_off = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
self.loop.run_until_complete(switch.process(telegram_inv_on))
@@ -189,7 +190,8 @@ def test_process_reset_after(self):
xknx, "TestInput", group_address="1/2/3", reset_after=reset_after_sec
)
telegram_on = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
self.loop.run_until_complete(switch.process(telegram_on))
@@ -208,7 +210,8 @@ def test_process_reset_after_cancel_existing(self):
xknx, "TestInput", group_address="1/2/3", reset_after=reset_after_sec
)
telegram_on = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueResponse(DPTBinary(1)),
)
self.loop.run_until_complete(switch.process(telegram_on))
@@ -238,7 +241,8 @@ async def async_after_update_callback(device):
switch.register_device_updated_cb(async_after_update_callback)
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
self.loop.run_until_complete(switch.process(telegram))
@@ -256,7 +260,10 @@ def test_set_on(self):
telegram = xknx.telegrams.get_nowait()
self.assertEqual(
telegram,
- Telegram(destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)),
+ Telegram(
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
+ ),
)
#
@@ -271,7 +278,10 @@ def test_set_off(self):
telegram = xknx.telegrams.get_nowait()
self.assertEqual(
telegram,
- Telegram(destination_address=GroupAddress("1/2/3"), payload=DPTBinary(0)),
+ Telegram(
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(0)),
+ ),
)
#
@@ -287,7 +297,10 @@ def test_set_invert(self):
telegram = xknx.telegrams.get_nowait()
self.assertEqual(
telegram,
- Telegram(destination_address=GroupAddress("1/2/3"), payload=DPTBinary(0)),
+ Telegram(
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(0)),
+ ),
)
self.loop.run_until_complete(switch.set_off())
@@ -295,7 +308,10 @@ def test_set_invert(self):
telegram = xknx.telegrams.get_nowait()
self.assertEqual(
telegram,
- Telegram(destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)),
+ Telegram(
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
+ ),
)
#
diff --git a/test/io_tests/tunnelling_test.py b/test/io_tests/tunnelling_test.py
index 198fe70e4..47ffd17dc 100644
--- a/test/io_tests/tunnelling_test.py
+++ b/test/io_tests/tunnelling_test.py
@@ -8,6 +8,7 @@
from xknx.io import Tunnelling, UDPClient
from xknx.knxip import ErrorCode, KNXIPFrame, KNXIPServiceType, TunnellingAck
from xknx.telegram import GroupAddress, IndividualAddress, Telegram
+from xknx.telegram.apci import GroupValueWrite
class TestTunnelling(unittest.TestCase):
@@ -29,7 +30,8 @@ def test_tunnelling(self):
communication_channel_id = 23
udp_client = UDPClient(xknx, ("192.168.1.1", 0), ("192.168.1.2", 1234))
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTArray((0x1, 0x2, 0x3))
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray((0x1, 0x2, 0x3))),
)
sequence_counter = 42
src_address = IndividualAddress("2.2.2")
diff --git a/test/knxip_tests/cemi_frame_test.py b/test/knxip_tests/cemi_frame_test.py
index c3804a2ca..84993d928 100644
--- a/test/knxip_tests/cemi_frame_test.py
+++ b/test/knxip_tests/cemi_frame_test.py
@@ -6,8 +6,9 @@
from xknx.dpt import DPTBinary, DPTComparator
from xknx.exceptions import ConversionError, CouldNotParseKNXIP, UnsupportedCEMIMessage
from xknx.knxip.cemi_frame import CEMIFrame
-from xknx.knxip.knxip_enum import APCICommand, CEMIFlags, CEMIMessageCode
+from xknx.knxip.knxip_enum import CEMIFlags, CEMIMessageCode
from xknx.telegram import GroupAddress, IndividualAddress, Telegram
+from xknx.telegram.apci import GroupValueRead
def get_data(code, adil, flags, src, dst, mpdu_len, tpci_apci, payload):
@@ -40,10 +41,9 @@ def test_valid_command(frame):
"""Test for valid frame parsing"""
packet_len = frame.from_knx(get_data(0x29, 0, 0, 0, 0, 1, 0, []))
assert frame.code == CEMIMessageCode.L_DATA_IND
- assert frame.cmd == APCICommand.GROUP_READ
assert frame.flags == 0
assert frame.mpdu_len == 1
- assert frame.payload == DPTBinary(0)
+ assert frame.payload == GroupValueRead()
assert frame.src_addr == IndividualAddress(0)
assert frame.dst_addr == IndividualAddress(0)
assert packet_len == 11
@@ -64,10 +64,9 @@ def test_invalid_apdu_len(frame):
def test_invalid_src_addr(frame):
"""Test for invalid src addr"""
frame.code = CEMIMessageCode.L_DATA_IND
- frame.cmd = APCICommand.GROUP_READ
frame.flags = 0
frame.mpdu_len = 1
- frame.payload = DPTBinary(0)
+ frame.payload = GroupValueRead()
frame.src_addr = None
frame.dst_addr = IndividualAddress(0)
@@ -78,10 +77,9 @@ def test_invalid_src_addr(frame):
def test_invalid_dst_addr(frame):
"""Test for invalid dst addr"""
frame.code = CEMIMessageCode.L_DATA_IND
- frame.cmd = APCICommand.GROUP_READ
frame.flags = 0
frame.mpdu_len = 1
- frame.payload = DPTBinary(0)
+ frame.payload = GroupValueRead()
frame.src_addr = IndividualAddress(0)
frame.dst_addr = None
@@ -89,24 +87,9 @@ def test_invalid_dst_addr(frame):
frame.to_knx()
-def test_no_payload(frame):
- """Test for having no payload set"""
- frame.code = CEMIMessageCode.L_DATA_IND
- frame.cmd = APCICommand.GROUP_READ
- frame.flags = 0
- frame.mpdu_len = 1
- frame.payload = None
- frame.src_addr = IndividualAddress(0)
- frame.dst_addr = IndividualAddress(0)
-
- assert [41, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0] == frame.to_knx()
- assert 11 == frame.calculated_length()
-
-
def test_invalid_payload(frame):
"""Test for having wrong payload set"""
frame.code = CEMIMessageCode.L_DATA_IND
- frame.cmd = APCICommand.GROUP_READ
frame.flags = 0
frame.mpdu_len = 1
frame.payload = DPTComparator()
@@ -134,21 +117,6 @@ def test_from_knx_with_not_implemented_cemi(frame):
)
-def test_invalid_telegram(frame):
- """Test for invalid telegram type"""
- packet_len = frame.from_knx(get_data(0x29, 0, 0, 0, 0, 1, 0, []))
- frame.cmd = None
- with raises(ConversionError, match=r".*Telegram not implemented for.*"):
- tg = frame.telegram
-
-
-def test_set_invalid_telegram(frame):
- """Test for setting invalid telegram type"""
- tg = Telegram(telegramtype=None)
- with raises(TypeError):
- frame.telegram = tg
-
-
def test_invalid_invalid_len(frame):
"""Test for invalid cemi len"""
with raises(UnsupportedCEMIMessage, match=r".*CEMI too small.*"):
diff --git a/test/knxip_tests/routing_indication_test.py b/test/knxip_tests/routing_indication_test.py
index fed7dda78..4a2dc6f03 100644
--- a/test/knxip_tests/routing_indication_test.py
+++ b/test/knxip_tests/routing_indication_test.py
@@ -6,7 +6,8 @@
from xknx import XKNX
from xknx.dpt import DPTArray, DPTBinary, DPTTemperature, DPTTime
from xknx.knxip import CEMIFrame, KNXIPFrame, KNXIPServiceType, RoutingIndication
-from xknx.telegram import GroupAddress, IndividualAddress, Telegram, TelegramType
+from xknx.telegram import GroupAddress, IndividualAddress, Telegram
+from xknx.telegram.apci import GroupValueRead, GroupValueResponse, GroupValueWrite
class Test_KNXIP(unittest.TestCase):
@@ -36,8 +37,8 @@ def test_from_knx(self):
self.assertEqual(knxipframe.body.cemi.src_addr, IndividualAddress("1.2.2"))
self.assertEqual(knxipframe.body.cemi.dst_addr, GroupAddress(337))
- self.assertEqual(len(knxipframe.body.cemi.payload.value), 1)
- self.assertEqual(knxipframe.body.cemi.payload.value[0], 0xF0)
+ self.assertEqual(len(knxipframe.body.cemi.payload.value.value), 1)
+ self.assertEqual(knxipframe.body.cemi.payload.value.value[0], 0xF0)
def test_from_knx_to_knx(self):
"""Test parsing and streaming CEMIFrame KNX/IP."""
@@ -61,7 +62,9 @@ def test_telegram_set(self):
telegram = Telegram(
destination_address=GroupAddress(337),
- payload=DPTArray(DPTTime().to_knx(time.strptime("13:23:42", "%H:%M:%S"))),
+ payload=GroupValueWrite(
+ DPTArray(DPTTime().to_knx(time.strptime("13:23:42", "%H:%M:%S")))
+ ),
)
knxipframe.body.cemi.telegram = telegram
@@ -86,8 +89,8 @@ def test_telegram_get(self):
self.assertEqual(telegram.destination_address, GroupAddress(337))
- self.assertEqual(len(telegram.payload.value), 1)
- self.assertEqual(telegram.payload.value[0], 0xF0)
+ self.assertEqual(len(telegram.payload.value.value), 1)
+ self.assertEqual(telegram.payload.value.value[0], 0xF0)
#
# End-tox-End tests:
@@ -109,7 +112,7 @@ def test_EndTOEnd_group_write_binary_on(self):
telegram,
Telegram(
destination_address=GroupAddress("329"),
- payload=DPTBinary(1),
+ payload=GroupValueWrite(DPTBinary(1)),
source_address=IndividualAddress("15.15.249"),
),
)
@@ -137,7 +140,7 @@ def test_EndTOEnd_group_write_binary_off(self):
telegram,
Telegram(
destination_address=GroupAddress("329"),
- payload=DPTBinary(0),
+ payload=GroupValueWrite(DPTBinary(0)),
source_address=IndividualAddress("15.15.249"),
),
)
@@ -165,7 +168,7 @@ def test_EndTOEnd_group_write_1byte(self):
telegram,
Telegram(
destination_address=GroupAddress("331"),
- payload=DPTArray(0x65),
+ payload=GroupValueWrite(DPTArray(0x65)),
source_address=IndividualAddress("15.15.249"),
),
)
@@ -193,7 +196,7 @@ def test_EndTOEnd_group_write_2bytes(self):
telegram,
Telegram(
destination_address=GroupAddress("2049"),
- payload=DPTArray(DPTTemperature().to_knx(19.85)),
+ payload=GroupValueWrite(DPTArray(DPTTemperature().to_knx(19.85))),
source_address=IndividualAddress("1.4.2"),
),
)
@@ -221,7 +224,7 @@ def test_EndTOEnd_group_read(self):
telegram,
Telegram(
destination_address=GroupAddress("440"),
- telegramtype=TelegramType.GROUP_READ,
+ payload=GroupValueRead(),
source_address=IndividualAddress("15.15.249"),
),
)
@@ -249,8 +252,7 @@ def test_EndTOEnd_group_response(self):
telegram,
Telegram(
destination_address=GroupAddress("392"),
- telegramtype=TelegramType.GROUP_RESPONSE,
- payload=DPTBinary(1),
+ payload=GroupValueResponse(DPTBinary(1)),
source_address=IndividualAddress("1.3.1"),
),
)
@@ -270,7 +272,7 @@ def test_maximum_apci(self):
"""Test parsing and streaming CEMIFrame KNX/IP packet, testing maximum APCI."""
telegram = Telegram(
destination_address=GroupAddress(337),
- payload=DPTBinary(DPTBinary.APCI_MAX_VALUE),
+ payload=GroupValueWrite(DPTBinary(DPTBinary.APCI_MAX_VALUE)),
source_address=IndividualAddress("1.3.1"),
)
xknx = XKNX()
diff --git a/test/knxip_tests/tunnelling_request_test.py b/test/knxip_tests/tunnelling_request_test.py
index d13eca7ad..8cbc92d57 100644
--- a/test/knxip_tests/tunnelling_request_test.py
+++ b/test/knxip_tests/tunnelling_request_test.py
@@ -7,6 +7,7 @@
from xknx.exceptions import CouldNotParseKNXIP
from xknx.knxip import CEMIFrame, KNXIPFrame, KNXIPServiceType, TunnellingRequest
from xknx.telegram import GroupAddress, Telegram
+from xknx.telegram.apci import GroupValueWrite
class Test_KNXIP_TunnelingReq(unittest.TestCase):
@@ -59,13 +60,17 @@ def test_connect_request(self):
self.assertEqual(
knxipframe.body.cemi.telegram,
- Telegram(destination_address=GroupAddress("9/0/8"), payload=DPTBinary(1)),
+ Telegram(
+ destination_address=GroupAddress("9/0/8"),
+ payload=GroupValueWrite(DPTBinary(1)),
+ ),
)
knxipframe2 = KNXIPFrame(xknx)
knxipframe2.init(KNXIPServiceType.TUNNELLING_REQUEST)
knxipframe2.body.cemi.telegram = Telegram(
- destination_address=GroupAddress("9/0/8"), payload=DPTBinary(1)
+ destination_address=GroupAddress("9/0/8"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
knxipframe2.body.sequence_counter = 23
knxipframe2.normalize()
diff --git a/test/remote_value_tests/remote_value_1count_test.py b/test/remote_value_tests/remote_value_1count_test.py
index bcf5b4112..ab4a9052b 100644
--- a/test/remote_value_tests/remote_value_1count_test.py
+++ b/test/remote_value_tests/remote_value_1count_test.py
@@ -7,6 +7,7 @@
from xknx.exceptions import CouldNotParseTelegram
from xknx.remote_value import RemoteValue1Count
from xknx.telegram import GroupAddress, Telegram
+from xknx.telegram.apci import GroupValueWrite
class TestRemoteValue1Count(unittest.TestCase):
@@ -43,7 +44,8 @@ def test_set(self):
self.assertEqual(
telegram,
Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTArray((0x64,))
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray((0x64,))),
),
)
self.loop.run_until_complete(
@@ -56,7 +58,8 @@ def test_set(self):
self.assertEqual(
telegram,
Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTArray((0x65,))
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray((0x65,))),
),
)
@@ -65,7 +68,8 @@ def test_process(self):
xknx = XKNX()
remote_value = RemoteValue1Count(xknx, group_address=GroupAddress("1/2/3"))
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTArray((0x64,))
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray((0x64,))),
)
self.loop.run_until_complete(remote_value.process(telegram))
self.assertEqual(remote_value.value, 100)
@@ -76,16 +80,19 @@ def test_to_process_error(self):
remote_value = RemoteValue1Count(xknx, group_address=GroupAddress("1/2/3"))
with self.assertRaises(CouldNotParseTelegram):
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
self.loop.run_until_complete(remote_value.process(telegram))
with self.assertRaises(CouldNotParseTelegram):
telegram = Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTArray(
- (
- 0x64,
- 0x65,
+ payload=GroupValueWrite(
+ DPTArray(
+ (
+ 0x64,
+ 0x65,
+ )
)
),
)
diff --git a/test/remote_value_tests/remote_value_climate_mode_test.py b/test/remote_value_tests/remote_value_climate_mode_test.py
index 2f745e363..4ce93b59a 100644
--- a/test/remote_value_tests/remote_value_climate_mode_test.py
+++ b/test/remote_value_tests/remote_value_climate_mode_test.py
@@ -13,6 +13,7 @@
)
from xknx.remote_value.remote_value_climate_mode import _RemoteValueBinaryClimateMode
from xknx.telegram import GroupAddress, Telegram
+from xknx.telegram.apci import GroupValueWrite
class TestRemoteValueDptValue1Ucount(unittest.TestCase):
@@ -178,7 +179,8 @@ def test_set_operation_mode(self):
self.assertEqual(
telegram,
Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTArray((0x03,))
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray((0x03,))),
),
)
self.loop.run_until_complete(
@@ -189,7 +191,8 @@ def test_set_operation_mode(self):
self.assertEqual(
telegram,
Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTArray((0x04,))
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray((0x04,))),
),
)
@@ -207,7 +210,8 @@ def test_set_binary(self):
self.assertEqual(
telegram,
Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(True)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(True)),
),
)
self.loop.run_until_complete(
@@ -218,7 +222,8 @@ def test_set_binary(self):
self.assertEqual(
telegram,
Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(False)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(False)),
),
)
@@ -231,7 +236,8 @@ def test_process_operation_mode(self):
climate_mode_type=RemoteValueClimateMode.ClimateModeType.HVAC_MODE,
)
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTArray((0x00,))
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray((0x00,))),
)
self.loop.run_until_complete(remote_value.process(telegram))
self.assertEqual(remote_value.value, HVACOperationMode.AUTO)
@@ -245,7 +251,8 @@ def test_process_binary(self):
operation_mode=HVACOperationMode.FROST_PROTECTION,
)
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(True)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(True)),
)
self.loop.run_until_complete(remote_value.process(telegram))
self.assertEqual(remote_value.value, HVACOperationMode.FROST_PROTECTION)
@@ -260,16 +267,19 @@ def test_to_process_error_operation_mode(self):
)
with self.assertRaises(CouldNotParseTelegram):
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
self.loop.run_until_complete(remote_value.process(telegram))
with self.assertRaises(CouldNotParseTelegram):
telegram = Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTArray(
- (
- 0x64,
- 0x65,
+ payload=GroupValueWrite(
+ DPTArray(
+ (
+ 0x64,
+ 0x65,
+ )
)
),
)
@@ -285,16 +295,19 @@ def test_to_process_error_heat_cool(self):
)
with self.assertRaises(CouldNotParseTelegram):
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTArray((0x01,))
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray((0x01,))),
)
self.loop.run_until_complete(remote_value.process(telegram))
with self.assertRaises(CouldNotParseTelegram):
telegram = Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTArray(
- (
- 0x64,
- 0x65,
+ payload=GroupValueWrite(
+ DPTArray(
+ (
+ 0x64,
+ 0x65,
+ )
)
),
)
diff --git a/test/remote_value_tests/remote_value_color_rgb_test.py b/test/remote_value_tests/remote_value_color_rgb_test.py
index e6c33dd02..6c1026801 100644
--- a/test/remote_value_tests/remote_value_color_rgb_test.py
+++ b/test/remote_value_tests/remote_value_color_rgb_test.py
@@ -7,6 +7,7 @@
from xknx.exceptions import ConversionError, CouldNotParseTelegram
from xknx.remote_value import RemoteValueColorRGB
from xknx.telegram import GroupAddress, Telegram
+from xknx.telegram.apci import GroupValueWrite
class TestRemoteValueColorRGB(unittest.TestCase):
@@ -66,7 +67,7 @@ def test_set(self):
telegram,
Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTArray((0x64, 0x65, 0x66)),
+ payload=GroupValueWrite(DPTArray((0x64, 0x65, 0x66))),
),
)
self.loop.run_until_complete(remote_value.set((100, 101, 104)))
@@ -76,7 +77,7 @@ def test_set(self):
telegram,
Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTArray((0x64, 0x65, 0x68)),
+ payload=GroupValueWrite(DPTArray((0x64, 0x65, 0x68))),
),
)
@@ -86,7 +87,7 @@ def test_process(self):
remote_value = RemoteValueColorRGB(xknx, group_address=GroupAddress("1/2/3"))
telegram = Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTArray((0x64, 0x65, 0x66)),
+ payload=GroupValueWrite(DPTArray((0x64, 0x65, 0x66))),
)
self.loop.run_until_complete(remote_value.process(telegram))
self.assertEqual(remote_value.value, (100, 101, 102))
@@ -97,12 +98,13 @@ def test_to_process_error(self):
remote_value = RemoteValueColorRGB(xknx, group_address=GroupAddress("1/2/3"))
with self.assertRaises(CouldNotParseTelegram):
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
self.loop.run_until_complete(remote_value.process(telegram))
with self.assertRaises(CouldNotParseTelegram):
telegram = Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTArray((0x64, 0x65, 0x66, 0x67)),
+ payload=GroupValueWrite(DPTArray((0x64, 0x65, 0x66, 0x67))),
)
self.loop.run_until_complete(remote_value.process(telegram))
diff --git a/test/remote_value_tests/remote_value_color_rgbw_test.py b/test/remote_value_tests/remote_value_color_rgbw_test.py
index 5b929b23b..5eba8f4fa 100644
--- a/test/remote_value_tests/remote_value_color_rgbw_test.py
+++ b/test/remote_value_tests/remote_value_color_rgbw_test.py
@@ -7,6 +7,7 @@
from xknx.exceptions import ConversionError, CouldNotParseTelegram
from xknx.remote_value import RemoteValueColorRGBW
from xknx.telegram import GroupAddress, Telegram
+from xknx.telegram.apci import GroupValueWrite
class TestRemoteValueColorRGBW(unittest.TestCase):
@@ -94,7 +95,7 @@ def test_set(self):
telegram,
Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTArray((0x64, 0x65, 0x66, 0x67, 0x00, 0x0F)),
+ payload=GroupValueWrite(DPTArray((0x64, 0x65, 0x66, 0x67, 0x00, 0x0F))),
),
)
self.loop.run_until_complete(remote_value.set((100, 101, 104, 105)))
@@ -104,7 +105,7 @@ def test_set(self):
telegram,
Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTArray((0x64, 0x65, 0x68, 0x69, 0x00, 0x0F)),
+ payload=GroupValueWrite(DPTArray((0x64, 0x65, 0x68, 0x69, 0x00, 0x0F))),
),
)
@@ -114,7 +115,7 @@ def test_process(self):
remote_value = RemoteValueColorRGBW(xknx, group_address=GroupAddress("1/2/3"))
telegram = Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTArray((0x64, 0x65, 0x66, 0x67, 0x00, 0x0F)),
+ payload=GroupValueWrite(DPTArray((0x64, 0x65, 0x66, 0x67, 0x00, 0x0F))),
)
self.loop.run_until_complete(remote_value.process(telegram))
self.assertEqual(remote_value.value, [100, 101, 102, 103])
@@ -125,18 +126,21 @@ def test_to_process_error(self):
remote_value = RemoteValueColorRGBW(xknx, group_address=GroupAddress("1/2/3"))
with self.assertRaises(CouldNotParseTelegram):
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
self.loop.run_until_complete(remote_value.process(telegram))
with self.assertRaises(CouldNotParseTelegram):
telegram = Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTArray((0x64, 0x65, 0x66)),
+ payload=GroupValueWrite(DPTArray((0x64, 0x65, 0x66))),
)
self.loop.run_until_complete(remote_value.process(telegram))
with self.assertRaises(CouldNotParseTelegram):
telegram = Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTArray((0x00, 0x00, 0x0F, 0x64, 0x65, 0x66, 0x67)),
+ payload=GroupValueWrite(
+ DPTArray((0x00, 0x00, 0x0F, 0x64, 0x65, 0x66, 0x67))
+ ),
)
self.loop.run_until_complete(remote_value.process(telegram))
diff --git a/test/remote_value_tests/remote_value_dpt_2_byte_unsigned_test.py b/test/remote_value_tests/remote_value_dpt_2_byte_unsigned_test.py
index e34c8dcc0..ffcd3f88d 100644
--- a/test/remote_value_tests/remote_value_dpt_2_byte_unsigned_test.py
+++ b/test/remote_value_tests/remote_value_dpt_2_byte_unsigned_test.py
@@ -7,6 +7,7 @@
from xknx.exceptions import ConversionError, CouldNotParseTelegram
from xknx.remote_value import RemoteValueDpt2ByteUnsigned
from xknx.telegram import GroupAddress, Telegram
+from xknx.telegram.apci import GroupValueWrite
class TestRemoteValueDptValue2Ucount(unittest.TestCase):
@@ -55,7 +56,7 @@ def test_set(self):
telegram,
Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTArray((0x0A, 0x0B)),
+ payload=GroupValueWrite(DPTArray((0x0A, 0x0B))),
),
)
self.loop.run_until_complete(remote_value.set(5500))
@@ -65,10 +66,12 @@ def test_set(self):
telegram,
Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTArray(
- (
- 0x15,
- 0x7C,
+ payload=GroupValueWrite(
+ DPTArray(
+ (
+ 0x15,
+ 0x7C,
+ )
)
),
),
@@ -81,7 +84,8 @@ def test_process(self):
xknx, group_address=GroupAddress("1/2/3")
)
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTArray((0x0A, 0x0B))
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray((0x0A, 0x0B))),
)
self.loop.run_until_complete(remote_value.process(telegram))
self.assertEqual(remote_value.value, 2571)
@@ -94,22 +98,26 @@ def test_to_process_error(self):
)
with self.assertRaises(CouldNotParseTelegram):
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
self.loop.run_until_complete(remote_value.process(telegram))
with self.assertRaises(CouldNotParseTelegram):
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTArray((0x64,))
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray((0x64,))),
)
self.loop.run_until_complete(remote_value.process(telegram))
with self.assertRaises(CouldNotParseTelegram):
telegram = Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTArray(
- (
- 0x64,
- 0x53,
- 0x42,
+ payload=GroupValueWrite(
+ DPTArray(
+ (
+ 0x64,
+ 0x53,
+ 0x42,
+ )
)
),
)
diff --git a/test/remote_value_tests/remote_value_dpt_value_1_ucount_test.py b/test/remote_value_tests/remote_value_dpt_value_1_ucount_test.py
index 5f3ae1eb0..dbf5d2302 100644
--- a/test/remote_value_tests/remote_value_dpt_value_1_ucount_test.py
+++ b/test/remote_value_tests/remote_value_dpt_value_1_ucount_test.py
@@ -7,6 +7,7 @@
from xknx.exceptions import ConversionError, CouldNotParseTelegram
from xknx.remote_value import RemoteValueDptValue1Ucount
from xknx.telegram import GroupAddress, Telegram
+from xknx.telegram.apci import GroupValueWrite
class TestRemoteValueDptValue1Ucount(unittest.TestCase):
@@ -54,7 +55,8 @@ def test_set(self):
self.assertEqual(
telegram,
Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTArray((0x0A,))
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray((0x0A,))),
),
)
self.loop.run_until_complete(remote_value.set(11))
@@ -63,7 +65,8 @@ def test_set(self):
self.assertEqual(
telegram,
Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTArray((0x0B,))
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray((0x0B,))),
),
)
@@ -74,7 +77,8 @@ def test_process(self):
xknx, group_address=GroupAddress("1/2/3")
)
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTArray((0x0A,))
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray((0x0A,))),
)
self.loop.run_until_complete(remote_value.process(telegram))
self.assertEqual(remote_value.value, 10)
@@ -87,16 +91,19 @@ def test_to_process_error(self):
)
with self.assertRaises(CouldNotParseTelegram):
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
self.loop.run_until_complete(remote_value.process(telegram))
with self.assertRaises(CouldNotParseTelegram):
telegram = Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTArray(
- (
- 0x64,
- 0x65,
+ payload=GroupValueWrite(
+ DPTArray(
+ (
+ 0x64,
+ 0x65,
+ )
)
),
)
diff --git a/test/remote_value_tests/remote_value_scene_number_test.py b/test/remote_value_tests/remote_value_scene_number_test.py
index a356bd7c0..303e12db9 100644
--- a/test/remote_value_tests/remote_value_scene_number_test.py
+++ b/test/remote_value_tests/remote_value_scene_number_test.py
@@ -7,6 +7,7 @@
from xknx.exceptions import ConversionError, CouldNotParseTelegram
from xknx.remote_value import RemoteValueSceneNumber
from xknx.telegram import GroupAddress, Telegram
+from xknx.telegram.apci import GroupValueWrite
class TestRemoteValueSceneNumber(unittest.TestCase):
@@ -52,7 +53,8 @@ def test_set(self):
self.assertEqual(
telegram,
Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTArray((0x0A,))
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray((0x0A,))),
),
)
self.loop.run_until_complete(remote_value.set(12))
@@ -61,7 +63,8 @@ def test_set(self):
self.assertEqual(
telegram,
Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTArray((0x0B,))
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray((0x0B,))),
),
)
@@ -70,7 +73,8 @@ def test_process(self):
xknx = XKNX()
remote_value = RemoteValueSceneNumber(xknx, group_address=GroupAddress("1/2/3"))
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTArray((0x0A,))
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray((0x0A,))),
)
self.loop.run_until_complete(remote_value.process(telegram))
self.assertEqual(remote_value.value, 11)
@@ -81,16 +85,19 @@ def test_to_process_error(self):
remote_value = RemoteValueSceneNumber(xknx, group_address=GroupAddress("1/2/3"))
with self.assertRaises(CouldNotParseTelegram):
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
self.loop.run_until_complete(remote_value.process(telegram))
with self.assertRaises(CouldNotParseTelegram):
telegram = Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTArray(
- (
- 0x64,
- 0x65,
+ payload=GroupValueWrite(
+ DPTArray(
+ (
+ 0x64,
+ 0x65,
+ )
)
),
)
diff --git a/test/remote_value_tests/remote_value_step_test.py b/test/remote_value_tests/remote_value_step_test.py
index 5a326954e..6f8f923be 100644
--- a/test/remote_value_tests/remote_value_step_test.py
+++ b/test/remote_value_tests/remote_value_step_test.py
@@ -7,6 +7,7 @@
from xknx.exceptions import ConversionError, CouldNotParseTelegram
from xknx.remote_value import RemoteValueStep
from xknx.telegram import GroupAddress, Telegram
+from xknx.telegram.apci import GroupValueWrite
class TestRemoteValueStep(unittest.TestCase):
@@ -81,14 +82,20 @@ def test_set(self):
telegram = xknx.telegrams.get_nowait()
self.assertEqual(
telegram,
- Telegram(destination_address=GroupAddress("1/2/3"), payload=DPTBinary(0)),
+ Telegram(
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(0)),
+ ),
)
self.loop.run_until_complete(remote_value.increase())
self.assertEqual(xknx.telegrams.qsize(), 1)
telegram = xknx.telegrams.get_nowait()
self.assertEqual(
telegram,
- Telegram(destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)),
+ Telegram(
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
+ ),
)
def test_process(self):
@@ -96,7 +103,8 @@ def test_process(self):
xknx = XKNX()
remote_value = RemoteValueStep(xknx, group_address=GroupAddress("1/2/3"))
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(0)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(0)),
)
self.assertEqual(remote_value.value, None)
self.loop.run_until_complete(remote_value.process(telegram))
@@ -108,12 +116,14 @@ def test_to_process_error(self):
remote_value = RemoteValueStep(xknx, group_address=GroupAddress("1/2/3"))
with self.assertRaises(CouldNotParseTelegram):
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTArray(0x01)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray(0x01)),
)
self.loop.run_until_complete(remote_value.process(telegram))
with self.assertRaises(CouldNotParseTelegram):
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(3)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(3)),
)
self.loop.run_until_complete(remote_value.process(telegram))
# pylint: disable=pointless-statement
diff --git a/test/remote_value_tests/remote_value_string_test.py b/test/remote_value_tests/remote_value_string_test.py
index 78ac49491..f34b47db1 100644
--- a/test/remote_value_tests/remote_value_string_test.py
+++ b/test/remote_value_tests/remote_value_string_test.py
@@ -7,6 +7,7 @@
from xknx.exceptions import ConversionError, CouldNotParseTelegram
from xknx.remote_value import RemoteValueString
from xknx.telegram import GroupAddress, Telegram
+from xknx.telegram.apci import GroupValueWrite
class TestRemoteValueString(unittest.TestCase):
@@ -93,7 +94,9 @@ def test_set(self):
telegram,
Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTArray((97, 115, 100, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)),
+ payload=GroupValueWrite(
+ DPTArray((97, 115, 100, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
+ ),
),
)
self.loop.run_until_complete(remote_value.set("ASDF"))
@@ -103,7 +106,9 @@ def test_set(self):
telegram,
Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTArray((65, 83, 68, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)),
+ payload=GroupValueWrite(
+ DPTArray((65, 83, 68, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
+ ),
),
)
@@ -113,22 +118,24 @@ def test_process(self):
remote_value = RemoteValueString(xknx, group_address=GroupAddress("1/2/3"))
telegram = Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTArray(
- (
- 0x41,
- 0x41,
- 0x41,
- 0x41,
- 0x41,
- 0x42,
- 0x42,
- 0x42,
- 0x42,
- 0x42,
- 0x43,
- 0x43,
- 0x43,
- 0x43,
+ payload=GroupValueWrite(
+ DPTArray(
+ (
+ 0x41,
+ 0x41,
+ 0x41,
+ 0x41,
+ 0x41,
+ 0x42,
+ 0x42,
+ 0x42,
+ 0x42,
+ 0x42,
+ 0x43,
+ 0x43,
+ 0x43,
+ 0x43,
+ )
)
),
)
@@ -141,16 +148,19 @@ def test_to_process_error(self):
remote_value = RemoteValueString(xknx, group_address=GroupAddress("1/2/3"))
with self.assertRaises(CouldNotParseTelegram):
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
self.loop.run_until_complete(remote_value.process(telegram))
with self.assertRaises(CouldNotParseTelegram):
telegram = Telegram(
destination_address=GroupAddress("1/2/3"),
- payload=DPTArray(
- (
- 0x64,
- 0x65,
+ payload=GroupValueWrite(
+ DPTArray(
+ (
+ 0x64,
+ 0x65,
+ )
)
),
)
diff --git a/test/remote_value_tests/remote_value_switch_test.py b/test/remote_value_tests/remote_value_switch_test.py
index 325dc0426..bd088a7a6 100644
--- a/test/remote_value_tests/remote_value_switch_test.py
+++ b/test/remote_value_tests/remote_value_switch_test.py
@@ -7,6 +7,7 @@
from xknx.exceptions import ConversionError, CouldNotParseTelegram
from xknx.remote_value import RemoteValueSwitch
from xknx.telegram import GroupAddress, Telegram
+from xknx.telegram.apci import GroupValueWrite
class TestRemoteValueSwitch(unittest.TestCase):
@@ -65,14 +66,20 @@ def test_set(self):
telegram = xknx.telegrams.get_nowait()
self.assertEqual(
telegram,
- Telegram(destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)),
+ Telegram(
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
+ ),
)
self.loop.run_until_complete(remote_value.off())
self.assertEqual(xknx.telegrams.qsize(), 1)
telegram = xknx.telegrams.get_nowait()
self.assertEqual(
telegram,
- Telegram(destination_address=GroupAddress("1/2/3"), payload=DPTBinary(0)),
+ Telegram(
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(0)),
+ ),
)
def test_process(self):
@@ -80,7 +87,8 @@ def test_process(self):
xknx = XKNX()
remote_value = RemoteValueSwitch(xknx, group_address=GroupAddress("1/2/3"))
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
self.assertEqual(remote_value.value, None)
self.loop.run_until_complete(remote_value.process(telegram))
@@ -92,7 +100,8 @@ def test_process_off(self):
xknx = XKNX()
remote_value = RemoteValueSwitch(xknx, group_address=GroupAddress("1/2/3"))
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(0)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(0)),
)
self.assertEqual(remote_value.value, None)
self.loop.run_until_complete(remote_value.process(telegram))
@@ -105,12 +114,14 @@ def test_to_process_error(self):
remote_value = RemoteValueSwitch(xknx, group_address=GroupAddress("1/2/3"))
with self.assertRaises(CouldNotParseTelegram):
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTArray(0x01)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray(0x01)),
)
self.loop.run_until_complete(remote_value.process(telegram))
with self.assertRaises(CouldNotParseTelegram):
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(3)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(3)),
)
self.loop.run_until_complete(remote_value.process(telegram))
# pylint: disable=pointless-statement
diff --git a/test/remote_value_tests/remote_value_test.py b/test/remote_value_tests/remote_value_test.py
index 44c528a0c..4ac9071a6 100644
--- a/test/remote_value_tests/remote_value_test.py
+++ b/test/remote_value_tests/remote_value_test.py
@@ -8,6 +8,7 @@
from xknx.exceptions import CouldNotParseTelegram
from xknx.remote_value import RemoteValue, RemoteValueSwitch
from xknx.telegram import GroupAddress, Telegram
+from xknx.telegram.apci import GroupValueWrite
class TestRemoteValue(unittest.TestCase):
@@ -84,6 +85,26 @@ def test_default_value_unit(self):
remote_value = RemoteValue(xknx)
self.assertEqual(remote_value.unit_of_measurement, None)
+ def test_process_unsupported_payload(self):
+ """Test if exception is raised when processing telegram with unsupported payload."""
+ xknx = XKNX()
+ remote_value = RemoteValue(xknx)
+ with patch("xknx.remote_value.RemoteValue.payload_valid") as patch_valid, patch(
+ "xknx.remote_value.RemoteValue.has_group_address"
+ ) as patch_has_group_address:
+ patch_valid.return_value = False
+ patch_has_group_address.return_value = True
+
+ telegram = Telegram(
+ destination_address=GroupAddress("1/2/1"),
+ payload=object(),
+ )
+ with self.assertRaisesRegex(
+ CouldNotParseTelegram,
+ r".*payload not a GroupValueWrite or GroupValueResponse.*",
+ ):
+ self.loop.run_until_complete(remote_value.process(telegram))
+
def test_process_invalid_payload(self):
"""Test if exception is raised when processing telegram with invalid payload."""
xknx = XKNX()
@@ -96,9 +117,9 @@ def test_process_invalid_payload(self):
telegram = Telegram(
destination_address=GroupAddress("1/2/1"),
- payload=DPTArray((0x01, 0x02)),
+ payload=GroupValueWrite(DPTArray((0x01, 0x02))),
)
- with self.assertRaises(CouldNotParseTelegram):
+ with self.assertRaisesRegex(CouldNotParseTelegram, r".*payload invalid.*"):
self.loop.run_until_complete(remote_value.process(telegram))
def test_read_state(self):
@@ -113,7 +134,8 @@ def test_read_state(self):
fut = asyncio.Future()
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
fut.set_result(telegram)
patch_read.return_value = fut
@@ -158,7 +180,8 @@ def test_process_listening_address(self):
patch_valid.return_value = True
test_payload = DPTArray((0x01, 0x02))
telegram = Telegram(
- destination_address=GroupAddress("1/1/1"), payload=test_payload
+ destination_address=GroupAddress("1/1/1"),
+ payload=GroupValueWrite(test_payload),
)
self.assertTrue(
self.loop.run_until_complete(
diff --git a/test/remote_value_tests/remote_value_updown_test.py b/test/remote_value_tests/remote_value_updown_test.py
index 303c9fb45..04483779a 100644
--- a/test/remote_value_tests/remote_value_updown_test.py
+++ b/test/remote_value_tests/remote_value_updown_test.py
@@ -7,6 +7,7 @@
from xknx.exceptions import ConversionError, CouldNotParseTelegram
from xknx.remote_value import RemoteValueUpDown
from xknx.telegram import GroupAddress, Telegram
+from xknx.telegram.apci import GroupValueWrite
class TestRemoteValueUpDown(unittest.TestCase):
@@ -81,14 +82,20 @@ def test_set(self):
telegram = xknx.telegrams.get_nowait()
self.assertEqual(
telegram,
- Telegram(destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)),
+ Telegram(
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
+ ),
)
self.loop.run_until_complete(remote_value.up())
self.assertEqual(xknx.telegrams.qsize(), 1)
telegram = xknx.telegrams.get_nowait()
self.assertEqual(
telegram,
- Telegram(destination_address=GroupAddress("1/2/3"), payload=DPTBinary(0)),
+ Telegram(
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(0)),
+ ),
)
def test_process(self):
@@ -96,7 +103,8 @@ def test_process(self):
xknx = XKNX()
remote_value = RemoteValueUpDown(xknx, group_address=GroupAddress("1/2/3"))
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(1)),
)
self.assertEqual(remote_value.value, None)
self.loop.run_until_complete(remote_value.process(telegram))
@@ -108,12 +116,14 @@ def test_to_process_error(self):
remote_value = RemoteValueUpDown(xknx, group_address=GroupAddress("1/2/3"))
with self.assertRaises(CouldNotParseTelegram):
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTArray(0x01)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTArray(0x01)),
)
self.loop.run_until_complete(remote_value.process(telegram))
with self.assertRaises(CouldNotParseTelegram):
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(3)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(3)),
)
self.loop.run_until_complete(remote_value.process(telegram))
# pylint: disable=pointless-statement
diff --git a/test/str_test.py b/test/str_test.py
index 7972402fe..2d95776a6 100644
--- a/test/str_test.py
+++ b/test/str_test.py
@@ -56,6 +56,7 @@
)
from xknx.remote_value import RemoteValue
from xknx.telegram import GroupAddress, IndividualAddress, Telegram, TelegramDirection
+from xknx.telegram.apci import GroupValueWrite
# pylint: disable=too-many-public-methods,invalid-name
@@ -283,7 +284,7 @@ def test_sensor(self):
telegram = Telegram(
destination_address=GroupAddress("1/2/3"),
direction=TelegramDirection.INCOMING,
- payload=DPTArray(0x40),
+ payload=GroupValueWrite(DPTArray(0x40)),
)
self.loop.run_until_complete(sensor.process_group_write(telegram))
self.assertEqual(
@@ -352,7 +353,7 @@ def test_weather(self):
telegram = Telegram(
destination_address=GroupAddress("7/0/10"),
direction=TelegramDirection.INCOMING,
- payload=DPTBinary(1),
+ payload=GroupValueWrite(DPTBinary(1)),
)
self.loop.run_until_complete(weather.process_group_write(telegram))
@@ -469,12 +470,13 @@ def test_dpt_binary(self):
def test_telegram(self):
"""Test string representation of Telegram."""
telegram = Telegram(
- destination_address=GroupAddress("1/2/3"), payload=DPTBinary(7)
+ destination_address=GroupAddress("1/2/3"),
+ payload=GroupValueWrite(DPTBinary(7)),
)
self.assertEqual(
str(telegram),
- '" />',
+ '" />" />',
)
def test_dib_generic(self):
@@ -642,7 +644,7 @@ def test_tunnelling_request(self):
self.assertEqual(
str(tunnelling_request),
'" />',
+ ' DestinationAddress="GroupAddress("0/0/0")" Flags=" 0" payload="None" />" />',
)
def test_tunnelling_ack(self):
@@ -662,12 +664,13 @@ def test_cemi_frame(self):
cemi_frame = CEMIFrame(xknx)
cemi_frame.src_addr = GroupAddress("1/2/3")
cemi_frame.telegram = Telegram(
- destination_address=GroupAddress("1/2/5"), payload=DPTBinary(7)
+ destination_address=GroupAddress("1/2/5"),
+ payload=GroupValueWrite(DPTBinary(7)),
)
self.assertEqual(
str(cemi_frame),
- '" />',
+ '" />" />',
)
def test_knxip_frame(self):
@@ -710,5 +713,5 @@ def test_routing_indication_str(self):
ri = RoutingIndication(xknx)
self.assertEqual(
str(ri),
- '" />',
+ '" />',
)
diff --git a/test/telegram_tests/apci_test.py b/test/telegram_tests/apci_test.py
new file mode 100644
index 000000000..7cb42ea80
--- /dev/null
+++ b/test/telegram_tests/apci_test.py
@@ -0,0 +1,172 @@
+"""Unit test for APCI objects."""
+import unittest
+
+from pytest import raises
+from xknx.dpt import DPTArray, DPTBinary
+from xknx.exceptions import ConversionError
+from xknx.telegram.apci import APCI, GroupValueRead, GroupValueResponse, GroupValueWrite
+
+
+class TestAPCI(unittest.TestCase):
+ """Test class for APCI objects."""
+
+ def test_resolve_apci(self):
+ """Test resolve_apci for supported services."""
+ test_cases = [
+ (GroupValueRead.code.value, GroupValueRead),
+ (GroupValueWrite.code.value, GroupValueWrite),
+ (GroupValueResponse.code.value, GroupValueResponse),
+ ]
+
+ for code, clazz in test_cases:
+ self.assertIsInstance(APCI.resolve_apci(code), clazz)
+
+ def test_resolve_apci_unsupported(self):
+ """Test resolve_apci for unsupported services."""
+
+ with raises(ConversionError, match=r".*Class not implemented for APCI.*"):
+ APCI.resolve_apci(0x0100)
+
+ with raises(
+ ConversionError, match=r".*Class not implemented for extended APCI.*"
+ ):
+ APCI.resolve_apci(0x03C0)
+
+
+class TestGroupValueRead(unittest.TestCase):
+ """Test class for GroupValueRead objects."""
+
+ def test_calculated_length(self):
+ """Test the test_calculated_length method."""
+ payload = GroupValueRead()
+
+ self.assertEqual(payload.calculated_length(), 1)
+
+ def test_from_knx(self):
+ """Test the from_knx method."""
+ payload = GroupValueRead()
+ payload.from_knx(bytes([0x00, 0x00]))
+
+ self.assertEqual(payload, GroupValueRead())
+
+ def test_to_knx(self):
+ """Test the to_knx method."""
+ payload = GroupValueRead()
+
+ self.assertEqual(payload.to_knx(), bytes([0x00, 0x00]))
+
+ def test_str(self):
+ """Test the __str__ method."""
+ payload = GroupValueRead()
+
+ self.assertEqual(str(payload), "")
+
+
+class TestGroupValueWrite(unittest.TestCase):
+ """Test class for GroupValueWrite objects."""
+
+ def test_calculated_length(self):
+ """Test the test_calculated_length method."""
+ payload_a = GroupValueWrite(DPTArray((0x01, 0x02, 0x03)))
+ payload_b = GroupValueWrite(DPTBinary(1))
+
+ self.assertEqual(payload_a.calculated_length(), 4)
+ self.assertEqual(payload_b.calculated_length(), 1)
+
+ def test_calculated_length_exception(self):
+ """Test the test_calculated_length method for unsupported dpt."""
+ payload = GroupValueWrite(object())
+
+ with self.assertRaises(TypeError):
+ payload.calculated_length()
+
+ def test_from_knx(self):
+ """Test the from_knx method."""
+ payload_a = GroupValueWrite()
+ payload_a.from_knx(bytes([0x00, 0x80, 0x05, 0x04, 0x03, 0x02, 0x01]))
+ payload_b = GroupValueWrite()
+ payload_b.from_knx(bytes([0x00, 0x82]))
+
+ self.assertEqual(
+ payload_a, GroupValueWrite(DPTArray((0x05, 0x04, 0x03, 0x02, 0x01)))
+ )
+ self.assertEqual(payload_b, GroupValueWrite(DPTBinary(0x02)))
+
+ def test_to_knx(self):
+ """Test the to_knx method."""
+
+ payload_a = GroupValueWrite(DPTArray((0x01, 0x02, 0x03)))
+ payload_b = GroupValueWrite(DPTBinary(1))
+
+ self.assertEqual(payload_a.to_knx(), bytes([0x00, 0x80, 0x01, 0x02, 0x03]))
+ self.assertEqual(payload_b.to_knx(), bytes([0x00, 0x81]))
+
+ def test_to_knx_exception(self):
+ """Test the to_knx method for unsupported dpt."""
+ payload = GroupValueWrite(object())
+
+ with self.assertRaises(TypeError):
+ payload.to_knx()
+
+ def test_str(self):
+ """Test the __str__ method."""
+ payload = GroupValueWrite(DPTBinary(1))
+
+ self.assertEqual(
+ str(payload), '" />'
+ )
+
+
+class TestGroupValueResponse(unittest.TestCase):
+ """Test class for TestGroupValueResponse objects."""
+
+ def test_calculated_length(self):
+ """Test the test_calculated_length method."""
+ payload_a = GroupValueResponse(DPTArray((0x01, 0x02, 0x03)))
+ payload_b = GroupValueResponse(DPTBinary(1))
+
+ self.assertEqual(payload_a.calculated_length(), 4)
+ self.assertEqual(payload_b.calculated_length(), 1)
+
+ def test_calculated_length_exception(self):
+ """Test the test_calculated_length method for unsupported dpt."""
+ payload = GroupValueResponse(object())
+
+ with self.assertRaises(TypeError):
+ payload.calculated_length()
+
+ def test_from_knx(self):
+ """Test the from_knx method."""
+ payload_a = GroupValueResponse()
+ payload_a.from_knx(bytes([0x00, 0x80, 0x05, 0x04, 0x03, 0x02, 0x01]))
+ payload_b = GroupValueResponse()
+ payload_b.from_knx(bytes([0x00, 0x82]))
+
+ self.assertEqual(
+ payload_a, GroupValueResponse(DPTArray((0x05, 0x04, 0x03, 0x02, 0x01)))
+ )
+ self.assertEqual(payload_b, GroupValueResponse(DPTBinary(0x02)))
+
+ def test_to_knx(self):
+ """Test the to_knx method."""
+
+ payload_a = GroupValueResponse(DPTArray((0x01, 0x02, 0x03)))
+ payload_b = GroupValueResponse(DPTBinary(1))
+
+ self.assertEqual(payload_a.to_knx(), bytes([0x00, 0x40, 0x01, 0x02, 0x03]))
+ self.assertEqual(payload_b.to_knx(), bytes([0x00, 0x41]))
+
+ def test_to_knx_exception(self):
+ """Test the to_knx method for unsupported dpt."""
+ payload = GroupValueResponse(object())
+
+ with self.assertRaises(TypeError):
+ payload.to_knx()
+
+ def test_str(self):
+ """Test the __str__ method."""
+ payload = GroupValueResponse(DPTBinary(1))
+
+ self.assertEqual(
+ str(payload), '" />'
+ )
diff --git a/test/telegram_tests/telegram_test.py b/test/telegram_tests/telegram_test.py
index 37e759935..d41c8949b 100644
--- a/test/telegram_tests/telegram_test.py
+++ b/test/telegram_tests/telegram_test.py
@@ -1,7 +1,9 @@
"""Unit test for Telegram objects."""
import unittest
-from xknx.telegram import GroupAddress, Telegram, TelegramDirection, TelegramType
+from xknx.dpt import DPTBinary
+from xknx.telegram import GroupAddress, Telegram, TelegramDirection
+from xknx.telegram.apci import GroupValueRead, GroupValueWrite
class TestTelegram(unittest.TestCase):
@@ -13,25 +15,25 @@ class TestTelegram(unittest.TestCase):
def test_telegram_equal(self):
"""Test equals operator."""
self.assertEqual(
- Telegram(GroupAddress("1/2/3"), TelegramType.GROUP_READ),
- Telegram(GroupAddress("1/2/3"), TelegramType.GROUP_READ),
+ Telegram(GroupAddress("1/2/3"), payload=GroupValueRead()),
+ Telegram(GroupAddress("1/2/3"), payload=GroupValueRead()),
)
def test_telegram_not_equal(self):
"""Test not equals operator."""
self.assertNotEqual(
- Telegram(GroupAddress("1/2/3"), TelegramType.GROUP_READ),
- Telegram(GroupAddress("1/2/4"), TelegramType.GROUP_READ),
+ Telegram(GroupAddress("1/2/3"), payload=GroupValueRead()),
+ Telegram(GroupAddress("1/2/4"), payload=GroupValueRead()),
)
self.assertNotEqual(
- Telegram(GroupAddress("1/2/3"), TelegramType.GROUP_READ),
- Telegram(GroupAddress("1/2/3"), TelegramType.GROUP_WRITE),
+ Telegram(GroupAddress("1/2/3"), payload=GroupValueRead()),
+ Telegram(GroupAddress("1/2/3"), payload=GroupValueWrite(DPTBinary(1))),
)
self.assertNotEqual(
- Telegram(GroupAddress("1/2/3"), TelegramType.GROUP_READ),
+ Telegram(GroupAddress("1/2/3"), payload=GroupValueRead()),
Telegram(
GroupAddress("1/2/3"),
- TelegramType.GROUP_READ,
TelegramDirection.INCOMING,
+ payload=GroupValueRead(),
),
)
diff --git a/xknx/core/telegram_queue.py b/xknx/core/telegram_queue.py
index 5d8eb94f7..5981bdd4f 100644
--- a/xknx/core/telegram_queue.py
+++ b/xknx/core/telegram_queue.py
@@ -11,7 +11,8 @@
import logging
from xknx.exceptions import CommunicationError, XKNXException
-from xknx.telegram import TelegramDirection, TelegramType
+from xknx.telegram import TelegramDirection
+from xknx.telegram.apci import GroupValueWrite
logger = logging.getLogger("xknx.log")
telegram_logger = logging.getLogger("xknx.telegram")
@@ -133,7 +134,7 @@ async def process_telegram_outgoing(self, telegram):
telegram_logger.debug(telegram)
if self.xknx.knxip_interface is not None:
await self.xknx.knxip_interface.send_telegram(telegram)
- if telegram.telegramtype == TelegramType.GROUP_WRITE:
+ if isinstance(telegram.payload, GroupValueWrite):
await self.xknx.devices.process(telegram)
else:
logger.warning("No KNXIP interface defined")
diff --git a/xknx/core/value_reader.py b/xknx/core/value_reader.py
index 6c3ea6f62..928d05d9a 100644
--- a/xknx/core/value_reader.py
+++ b/xknx/core/value_reader.py
@@ -10,7 +10,8 @@
import asyncio
import logging
-from xknx.telegram import Telegram, TelegramType
+from xknx.telegram import Telegram
+from xknx.telegram.apci import GroupValueRead, GroupValueResponse, GroupValueWrite
logger = logging.getLogger("xknx.log")
@@ -49,19 +50,14 @@ async def read(self):
async def send_group_read(self):
"""Send group read."""
telegram = Telegram(
- destination_address=self.group_address, telegramtype=TelegramType.GROUP_READ
+ destination_address=self.group_address, payload=GroupValueRead()
)
await self.xknx.telegrams.put(telegram)
async def telegram_received(self, telegram):
"""Test if telegram has correct group address and trigger event."""
- if (
- telegram.destination_address == self.group_address
- and telegram.telegramtype
- in (
- TelegramType.GROUP_RESPONSE,
- TelegramType.GROUP_WRITE,
- )
+ if telegram.destination_address == self.group_address and isinstance(
+ telegram.payload, (GroupValueResponse, GroupValueWrite)
):
self.success = True
self.received_telegram = telegram
diff --git a/xknx/devices/device.py b/xknx/devices/device.py
index 6d33b2e7e..72c44bb55 100644
--- a/xknx/devices/device.py
+++ b/xknx/devices/device.py
@@ -5,7 +5,7 @@
"""
import logging
-from xknx.telegram import TelegramType
+from xknx.telegram.apci import GroupValueRead, GroupValueResponse, GroupValueWrite
logger = logging.getLogger("xknx.log")
@@ -51,11 +51,11 @@ async def sync(self, wait_for_result=False):
async def process(self, telegram):
"""Process incoming telegram."""
- if telegram.telegramtype == TelegramType.GROUP_WRITE:
+ if isinstance(telegram.payload, GroupValueWrite):
await self.process_group_write(telegram)
- elif telegram.telegramtype == TelegramType.GROUP_RESPONSE:
+ elif isinstance(telegram.payload, GroupValueResponse):
await self.process_group_response(telegram)
- elif telegram.telegramtype == TelegramType.GROUP_READ:
+ elif isinstance(telegram.payload, GroupValueRead):
await self.process_group_read(telegram)
async def process_group_read(self, telegram):
@@ -69,7 +69,7 @@ async def process_group_response(self, telegram):
async def process_group_write(self, telegram):
"""Process incoming GroupValueWrite telegrams."""
- # The dafault is, that devices dont process group writes
+ # The default is, that devices dont process group writes
def get_name(self):
"""Return name of device."""
diff --git a/xknx/dpt/__init__.py b/xknx/dpt/__init__.py
index b5bfff829..0141d90e0 100644
--- a/xknx/dpt/__init__.py
+++ b/xknx/dpt/__init__.py
@@ -170,3 +170,161 @@
from .dpt_scaling import DPTAngle, DPTScaling
from .dpt_string import DPTString
from .dpt_time import DPTTime
+
+__all__ = [
+ "DPT2ByteFloat",
+ "DPT2ByteSigned",
+ "DPT2ByteUnsigned",
+ "DPT2Ucount",
+ "DPT4ByteFloat",
+ "DPT4ByteSigned",
+ "DPT4ByteUnsigned",
+ "DPTAbsoluteTemperature",
+ "DPTAcceleration",
+ "DPTAccelerationAngular",
+ "DPTActivationEnergy",
+ "DPTActiveEnergy",
+ "DPTActiveEnergykWh",
+ "DPTActivity",
+ "DPTAmplitude",
+ "DPTAngle",
+ "DPTAngleDeg",
+ "DPTAngleRad",
+ "DPTAngularFrequency",
+ "DPTAngularMomentum",
+ "DPTAngularVelocity",
+ "DPTApparantEnergy",
+ "DPTApparantEnergykVAh",
+ "DPTArea",
+ "DPTArray",
+ "DPTBase",
+ "DPTBinary",
+ "DPTBrightness",
+ "DPTCapacitance",
+ "DPTChargeDensitySurface",
+ "DPTChargeDensityVolume",
+ "DPTColorTemperature",
+ "DPTCommonTemperature",
+ "DPTComparator",
+ "DPTCompressibility",
+ "DPTConductance",
+ "DPTControllerStatus",
+ "DPTCurrent",
+ "DPTDate",
+ "DPTDateTime",
+ "DPTDecimalFactor",
+ "DPTDeltaTimeHrs",
+ "DPTDeltaTimeMin",
+ "DPTDeltaTimeMsec",
+ "DPTDeltaTimeSec",
+ "DPTDensity",
+ "DPTElectricalConductivity",
+ "DPTElectricCharge",
+ "DPTElectricCurrent",
+ "DPTElectricCurrentDensity",
+ "DPTElectricDipoleMoment",
+ "DPTElectricDisplacement",
+ "DPTElectricFieldStrength",
+ "DPTElectricFlux",
+ "DPTElectricFluxDensity",
+ "DPTElectricPolarization",
+ "DPTElectricPotential",
+ "DPTElectricPotentialDifference",
+ "DPTElectromagneticMoment",
+ "DPTElectromotiveForce",
+ "DPTEnergy",
+ "DPTEnthalpy",
+ "DPTFlowRateM3H",
+ "DPTForce",
+ "DPTFrequency",
+ "DPTHeatCapacity",
+ "DPTHeatFlowRate",
+ "DPTHeatQuantity",
+ "DPTHumidity",
+ "DPTHVACContrMode",
+ "DPTHVACMode",
+ "DPTImpedance",
+ "DPTKelvinPerPercent",
+ "DPTLength",
+ "DPTLengthMm",
+ "DPTLightQuantity",
+ "DPTLongDeltaTimeSec",
+ "DPTLuminance",
+ "DPTLuminousFlux",
+ "DPTLuminousIntensity",
+ "DPTLux",
+ "DPTMagneticFieldStrength",
+ "DPTMagneticFlux",
+ "DPTMagneticFluxDensity",
+ "DPTMagneticMoment",
+ "DPTMagneticPolarization",
+ "DPTMagnetization",
+ "DPTMagnetomotiveForce",
+ "DPTMass",
+ "DPTMassFlux",
+ "DPTMol",
+ "DPTMomentum",
+ "DPTPartsPerMillion",
+ "DPTPercentU8",
+ "DPTPercentV16",
+ "DPTPercentV8",
+ "DPTPhaseAngleDeg",
+ "DPTPhaseAngleRad",
+ "DPTPower",
+ "DPTPower2Byte",
+ "DPTPowerDensity",
+ "DPTPowerFactor",
+ "DPTPressure",
+ "DPTPressure2Byte",
+ "DPTRainAmount",
+ "DPTReactance",
+ "DPTReactiveEnergy",
+ "DPTReactiveEnergykVARh",
+ "DPTResistance",
+ "DPTResistivity",
+ "DPTRotationAngle",
+ "DPTScaling",
+ "DPTSceneNumber",
+ "DPTSelfInductance",
+ "DPTSignedRelativeValue",
+ "DPTSolidAngle",
+ "DPTSoundIntensity",
+ "DPTSpeed",
+ "DPTStress",
+ "DPTString",
+ "DPTSurfaceTension",
+ "DPTTariff",
+ "DPTTemperature",
+ "DPTTemperatureA",
+ "DPTTemperatureDifference",
+ "DPTTemperatureDifference2Byte",
+ "DPTTemperatureF",
+ "DPTThermalCapacity",
+ "DPTThermalConductivity",
+ "DPTThermoelectricPower",
+ "DPTTime",
+ "DPTTime1",
+ "DPTTime2",
+ "DPTTimePeriod100Msec",
+ "DPTTimePeriod10Msec",
+ "DPTTimePeriodHrs",
+ "DPTTimePeriodMin",
+ "DPTTimePeriodMsec",
+ "DPTTimePeriodSec",
+ "DPTTimeSeconds",
+ "DPTTorque",
+ "DPTUElCurrentmA",
+ "DPTValue1ByteUnsigned",
+ "DPTValue1Count",
+ "DPTValue1Ucount",
+ "DPTValue2Count",
+ "DPTValue4Count",
+ "DPTVoltage",
+ "DPTVolume",
+ "DPTVolumeFlow",
+ "DPTVolumeFlux",
+ "DPTWeight",
+ "DPTWork",
+ "DPTWsp",
+ "DPTWspKmh",
+]
diff --git a/xknx/dpt/dpt.py b/xknx/dpt/dpt.py
index f462ddca0..c6c42abfa 100644
--- a/xknx/dpt/dpt.py
+++ b/xknx/dpt/dpt.py
@@ -1,4 +1,6 @@
"""Implementation of Basic KNX datatypes."""
+from typing import Union
+
from xknx.exceptions import ConversionError
@@ -126,7 +128,7 @@ class DPTBinary:
APCI_BITMASK = 0x3F
APCI_MAX_VALUE = APCI_BITMASK
- def __init__(self, value):
+ def __init__(self, value) -> None:
"""Initialize DPTBinary class."""
if not isinstance(value, int):
raise TypeError()
@@ -148,7 +150,7 @@ class DPTArray:
"""The DPTArray is a base class for all datatypes appended to the KNX telegram."""
# pylint: disable=too-few-public-methods
- def __init__(self, value):
+ def __init__(self, value: Union[int, list, bytes, tuple]) -> None:
"""Initialize DPTArray class."""
if isinstance(value, int):
self.value = (value,)
diff --git a/xknx/io/routing.py b/xknx/io/routing.py
index 57776ffb8..3fbd4aa0d 100644
--- a/xknx/io/routing.py
+++ b/xknx/io/routing.py
@@ -6,7 +6,6 @@
import logging
from xknx.knxip import (
- APCICommand,
CEMIFrame,
CEMIMessageCode,
KNXIPFrame,
@@ -49,12 +48,6 @@ def response_rec_callback(self, knxipframe, _):
return
elif knxipframe.body.cemi.src_addr == self.xknx.own_address:
logger.debug("Ignoring own packet")
- elif knxipframe.body.cemi.cmd not in (
- APCICommand.GROUP_READ,
- APCICommand.GROUP_WRITE,
- APCICommand.GROUP_RESPONSE,
- ):
- logger.warning("APCI not implemented: %s", knxipframe)
else:
telegram = knxipframe.body.cemi.telegram
telegram.direction = TelegramDirection.INCOMING
diff --git a/xknx/knxip/__init__.py b/xknx/knxip/__init__.py
index cb8edbaf5..0b1d000b9 100644
--- a/xknx/knxip/__init__.py
+++ b/xknx/knxip/__init__.py
@@ -14,7 +14,6 @@
from .hpai import HPAI
from .knxip import KNXIPFrame
from .knxip_enum import (
- APCICommand,
CEMIFlags,
CEMIMessageCode,
ConnectRequestType,
diff --git a/xknx/knxip/cemi_frame.py b/xknx/knxip/cemi_frame.py
index c26dd1e64..f3c820396 100644
--- a/xknx/knxip/cemi_frame.py
+++ b/xknx/knxip/cemi_frame.py
@@ -13,11 +13,11 @@
"""
from typing import Union
-from xknx.dpt import DPTArray, DPTBinary
from xknx.exceptions import ConversionError, CouldNotParseKNXIP, UnsupportedCEMIMessage
-from xknx.telegram import GroupAddress, IndividualAddress, Telegram, TelegramType
+from xknx.telegram import GroupAddress, IndividualAddress, Telegram
+from xknx.telegram.apci import APCI
-from .knxip_enum import APCICommand, CEMIFlags, CEMIMessageCode
+from .knxip_enum import CEMIFlags, CEMIMessageCode
class CEMIFrame:
@@ -30,7 +30,6 @@ def __init__(
xknx,
code: CEMIMessageCode = CEMIMessageCode.L_DATA_IND,
flags: int = 0,
- cmd: APCICommand = APCICommand.GROUP_READ,
src_addr: IndividualAddress = IndividualAddress(None),
dst_addr: Union[GroupAddress, IndividualAddress] = GroupAddress(None),
mpdu_len: int = 0,
@@ -40,7 +39,6 @@ def __init__(
self.xknx = xknx
self.code = code
self.flags = flags
- self.cmd = cmd
self.src_addr = src_addr
self.dst_addr = dst_addr
self.mpdu_len = mpdu_len
@@ -63,19 +61,8 @@ def init_from_telegram(
def telegram(self) -> Telegram:
"""Return telegram."""
- def resolve_telegram_type(cmd):
- """Return telegram type from APCI Command."""
- if cmd == APCICommand.GROUP_WRITE:
- return TelegramType.GROUP_WRITE
- if cmd == APCICommand.GROUP_READ:
- return TelegramType.GROUP_READ
- if cmd == APCICommand.GROUP_RESPONSE:
- return TelegramType.GROUP_RESPONSE
- raise ConversionError(f"Telegram not implemented for {self.cmd}")
-
return Telegram(
destination_address=self.dst_addr,
- telegramtype=resolve_telegram_type(self.cmd),
payload=self.payload,
source_address=self.src_addr,
)
@@ -105,19 +92,6 @@ def telegram(self, telegram: Telegram):
else:
raise TypeError()
- # TODO: use telegram.direction
- def resolve_cmd(telegramtype: TelegramType) -> APCICommand:
- """Resolve APCICommand from TelegramType."""
- if telegramtype == TelegramType.GROUP_READ:
- return APCICommand.GROUP_READ
- if telegramtype == TelegramType.GROUP_WRITE:
- return APCICommand.GROUP_WRITE
- if telegramtype == TelegramType.GROUP_RESPONSE:
- return APCICommand.GROUP_RESPONSE
- raise TypeError()
-
- self.cmd = resolve_cmd(telegram.telegramtype)
-
def set_hops(self, hops: int):
"""Set hops."""
# Resetting hops
@@ -127,13 +101,9 @@ def set_hops(self, hops: int):
def calculated_length(self) -> int:
"""Get length of KNX/IP body."""
- if self.payload is None:
- return 11
- if isinstance(self.payload, DPTBinary):
- return 11
- if isinstance(self.payload, DPTArray):
- return 11 + len(self.payload.value)
- raise TypeError()
+ if not isinstance(self.payload, APCI):
+ raise TypeError()
+ return 10 + self.payload.calculated_length()
def from_knx(self, raw) -> int:
"""Parse/deserialize from KNX/IP raw data."""
@@ -188,35 +158,31 @@ def from_knx_data_link_layer(self, cemi) -> int:
# TPCI (transport layer control information) -> First 14 bit
# APCI (application layer control information) -> Last 10 bit
- tpci_apci = cemi[9 + addil] * 256 + cemi[10 + addil]
-
- try:
- self.cmd = APCICommand(tpci_apci & 0xFFC0)
- except ValueError:
- raise UnsupportedCEMIMessage(
- "APCI not supported: {:#012b} in CEMI: {}".format(
- tpci_apci & 0xFFC0, cemi.hex()
- )
- )
-
- apdu = cemi[10 + addil :]
- if len(apdu) != self.mpdu_len:
+ apdu = cemi[9 + addil :]
+ if len(apdu) != (self.mpdu_len + 1):
raise CouldNotParseKNXIP(
"APDU LEN should be {} but is {} in CEMI: {}".format(
self.mpdu_len, len(apdu), cemi.hex()
)
)
- if len(apdu) == 1:
- apci = tpci_apci & DPTBinary.APCI_BITMASK
- self.payload = DPTBinary(apci)
- else:
- self.payload = DPTArray(cemi[11 + addil :])
+ tpci_apci = (apdu[0] << 8) + apdu[1]
+
+ try:
+ self.payload = APCI.resolve_apci(tpci_apci & 0x03FF)
+ except ConversionError:
+ raise UnsupportedCEMIMessage(
+ "APCI not supported: {:#012b}".format(tpci_apci & 0x03FF)
+ )
+
+ self.payload.from_knx(apdu)
- return 10 + addil + len(apdu)
+ return 10 + addil + self.mpdu_len
def to_knx(self):
"""Serialize to KNX/IP raw data."""
+ if not isinstance(self.payload, APCI):
+ raise TypeError()
if not isinstance(self.src_addr, (GroupAddress, IndividualAddress)):
raise ConversionError("src_addr not set")
if not isinstance(self.dst_addr, (GroupAddress, IndividualAddress)):
@@ -230,42 +196,19 @@ def to_knx(self):
data.append(self.flags & 255)
data.extend(self.src_addr.to_knx())
data.extend(self.dst_addr.to_knx())
+ data.append(self.payload.calculated_length())
+ data.extend(self.payload.to_knx())
- def encode_cmd_and_payload(cmd, encoded_payload=0, appended_payload=None):
- """Encode cmd and payload."""
- if appended_payload is None:
- appended_payload = []
- data = [
- 1 + len(appended_payload),
- (cmd.value >> 8) & 0xFF,
- (cmd.value & 0xFF) | (encoded_payload & DPTBinary.APCI_BITMASK),
- ]
- data.extend(appended_payload)
- return data
-
- if self.payload is None:
- data.extend(encode_cmd_and_payload(self.cmd))
- elif isinstance(self.payload, DPTBinary):
- data.extend(
- encode_cmd_and_payload(self.cmd, encoded_payload=self.payload.value)
- )
- elif isinstance(self.payload, DPTArray):
- data.extend(
- encode_cmd_and_payload(self.cmd, appended_payload=self.payload.value)
- )
- else:
- raise TypeError()
return data
def __str__(self):
"""Return object as readable string."""
return (
''.format(
+ 'Flags="{:16b}" payload="{}" />'.format(
self.src_addr.__repr__(),
self.dst_addr.__repr__(),
self.flags,
- self.cmd,
self.payload,
)
)
diff --git a/xknx/knxip/knxip_enum.py b/xknx/knxip/knxip_enum.py
index 127a76e9e..f4d1e060c 100644
--- a/xknx/knxip/knxip_enum.py
+++ b/xknx/knxip/knxip_enum.py
@@ -49,14 +49,6 @@ class CEMIMessageCode(Enum):
L_RAW_CON = 0x2F
-class APCICommand(Enum):
- """Enum class for KNX/IP APCI Commands."""
-
- GROUP_READ = 0x00
- GROUP_WRITE = 0x80
- GROUP_RESPONSE = 0x40
-
-
class CEMIFlags:
"""Enum class for KNX/IP CEMI Flags."""
diff --git a/xknx/remote_value/remote_value.py b/xknx/remote_value/remote_value.py
index 88f86ee31..dc7a298c3 100644
--- a/xknx/remote_value/remote_value.py
+++ b/xknx/remote_value/remote_value.py
@@ -10,7 +10,8 @@
from typing import List
from xknx.exceptions import CouldNotParseTelegram
-from xknx.telegram import GroupAddress, Telegram, TelegramType
+from xknx.telegram import GroupAddress, Telegram
+from xknx.telegram.apci import GroupValueResponse, GroupValueWrite
logger = logging.getLogger("xknx.log")
@@ -112,17 +113,37 @@ async def process(self, telegram, always_callback=False):
"""Process incoming or outgoing telegram."""
if not self.has_group_address(telegram.destination_address):
return False
- if not self.payload_valid(telegram.payload):
+ if not isinstance(
+ telegram.payload,
+ (
+ GroupValueWrite,
+ GroupValueResponse,
+ ),
+ ):
+ raise CouldNotParseTelegram(
+ "payload not a GroupValueWrite or GroupValueResponse",
+ payload=telegram.payload,
+ destination_address=telegram.destination_address,
+ source_address=telegram.source_address,
+ device_name=self.device_name,
+ feature_name=self.feature_name,
+ )
+ if not self.payload_valid(telegram.payload.value):
raise CouldNotParseTelegram(
"payload invalid",
payload=telegram.payload,
- address=telegram.destination_address,
+ destination_address=telegram.destination_address,
+ source_address=telegram.source_address,
device_name=self.device_name,
feature_name=self.feature_name,
)
self.xknx.state_updater.update_received(self)
- if self.payload is None or always_callback or self.payload != telegram.payload:
- self.payload = telegram.payload
+ if (
+ self.payload is None
+ or always_callback
+ or self.payload != telegram.payload.value
+ ):
+ self.payload = telegram.payload.value
if self.after_update_cb is not None:
await self.after_update_cb()
return True
@@ -138,10 +159,9 @@ async def _send(self, payload, response=False):
"""Send payload as telegram to KNX bus."""
telegram = Telegram(
destination_address=self.group_address,
- telegramtype=(
- TelegramType.GROUP_RESPONSE if response else TelegramType.GROUP_WRITE
+ payload=(
+ GroupValueResponse(payload) if response else GroupValueWrite(payload)
),
- payload=payload,
)
await self.xknx.telegrams.put(telegram)
diff --git a/xknx/telegram/__init__.py b/xknx/telegram/__init__.py
index b47b5fd09..1b222e1d5 100644
--- a/xknx/telegram/__init__.py
+++ b/xknx/telegram/__init__.py
@@ -8,4 +8,4 @@
# flake8: noqa
from .address import GroupAddress, GroupAddressType, IndividualAddress
from .address_filter import AddressFilter
-from .telegram import Telegram, TelegramDirection, TelegramType
+from .telegram import Telegram, TelegramDirection
diff --git a/xknx/telegram/apci.py b/xknx/telegram/apci.py
new file mode 100644
index 000000000..c5075ba2c
--- /dev/null
+++ b/xknx/telegram/apci.py
@@ -0,0 +1,207 @@
+"""
+Module for serialization and deserialization of APCI payloads.
+
+APCI stands for Application Layer Protocol Control Information.
+
+An APCI payload contains a service and payload. For example, a GroupValueWrite
+is a service that takes a DPT as a value.
+"""
+from abc import ABC, abstractmethod
+from enum import Enum
+from typing import ClassVar, Optional, Union, cast
+
+from xknx.dpt import DPTArray, DPTBinary
+from xknx.exceptions import ConversionError
+
+
+def encode_cmd_and_payload(
+ cmd: "APCICommand",
+ encoded_payload: int = 0,
+ appended_payload: Optional[bytes] = None,
+) -> bytes:
+ """Encode cmd and payload."""
+ if appended_payload is None:
+ appended_payload = bytes()
+
+ data = bytearray(
+ [
+ (cmd.value >> 8) & 0xFF,
+ (cmd.value & 0xFF) | (encoded_payload & DPTBinary.APCI_BITMASK),
+ ]
+ )
+ data.extend(appended_payload)
+ return data
+
+
+class APCICommand(Enum):
+ """Enum class for APCI services."""
+
+ GROUP_READ = 0x0000
+ GROUP_RESPONSE = 0x0040
+ GROUP_WRITE = 0x0080
+
+ ESCAPE = 0x03C0
+
+
+class APCIExtendedCommand(Enum):
+ """Enum class for extended APCI services."""
+
+
+class APCI(ABC):
+ """
+ Base class for ACPI services.
+
+ This base class is only the interface for the derived classes.
+ """
+
+ code: ClassVar[APCICommand] = cast(APCICommand, None)
+
+ @abstractmethod
+ def calculated_length(self) -> int:
+ """Get length of APCI payload - to be implemented in derived class."""
+
+ @abstractmethod
+ def from_knx(self, raw: bytes) -> None:
+ """Parse/deserialize from KNX/IP raw data - to be implemented in derived class."""
+
+ @abstractmethod
+ def to_knx(self) -> bytes:
+ """Serialize to KNX/IP raw data - to be implemented in derived class."""
+
+ def __eq__(self, other: object) -> bool:
+ """Equal operator."""
+ return self.__dict__ == other.__dict__
+
+ @staticmethod
+ def resolve_apci(apci: int) -> "APCI":
+ """Return APCI instance from APCI command."""
+ extended = (apci & APCICommand.ESCAPE.value) == APCICommand.ESCAPE.value
+
+ if extended:
+ raise ConversionError(
+ f"Class not implemented for extended APCI {apci:#012b}."
+ )
+
+ apci = apci & 0x03C0
+
+ if apci == APCICommand.GROUP_READ.value:
+ return GroupValueRead()
+ if apci == APCICommand.GROUP_WRITE.value:
+ return GroupValueWrite()
+ if apci == APCICommand.GROUP_RESPONSE.value:
+ return GroupValueResponse()
+ raise ConversionError(f"Class not implemented for APCI {apci:#012b}.")
+
+
+class GroupValueRead(APCI):
+ """
+ GroupValueRead service.
+
+ Does not have any payload.
+ """
+
+ code = APCICommand.GROUP_READ
+
+ def calculated_length(self) -> int:
+ """Get length of APCI payload."""
+ return 1
+
+ def from_knx(self, raw: bytes) -> None:
+ """Parse/deserialize from KNX/IP raw data."""
+
+ # Nothing to parse, but must be implemented explicitly.
+ return
+
+ def to_knx(self) -> bytes:
+ """Serialize to KNX/IP raw data."""
+ return encode_cmd_and_payload(self.code)
+
+ def __str__(self) -> str:
+ """Return object as readable string."""
+ return ""
+
+
+class GroupValueWrite(APCI):
+ """
+ GroupValueRead service.
+
+ Takes a value (DPT) as payload.
+ """
+
+ code = APCICommand.GROUP_WRITE
+
+ def __init__(self, value: Optional[Union[DPTBinary, DPTArray]] = None) -> None:
+ """Initialize a new instance of GroupValueWrite."""
+ self.value = value
+
+ def calculated_length(self) -> int:
+ """Get length of APCI payload."""
+ if isinstance(self.value, DPTBinary):
+ return 1
+ if isinstance(self.value, DPTArray):
+ return 1 + len(self.value.value)
+ raise TypeError()
+
+ def from_knx(self, raw: bytes) -> None:
+ """Parse/deserialize from KNX/IP raw data."""
+ if len(raw) == 2:
+ self.value = DPTBinary(raw[1] & DPTBinary.APCI_BITMASK)
+ else:
+ self.value = DPTArray(raw[2:])
+
+ def to_knx(self) -> bytes:
+ """Serialize to KNX/IP raw data."""
+ if isinstance(self.value, DPTBinary):
+ return encode_cmd_and_payload(self.code, encoded_payload=self.value.value)
+ if isinstance(self.value, DPTArray):
+ return encode_cmd_and_payload(
+ self.code, appended_payload=bytes(self.value.value)
+ )
+ raise TypeError()
+
+ def __str__(self) -> str:
+ """Return object as readable string."""
+ return f''
+
+
+class GroupValueResponse(APCI):
+ """
+ GroupValueResponse service.
+
+ Takes a value (DPT) as payload.
+ """
+
+ code = APCICommand.GROUP_RESPONSE
+
+ def __init__(self, value: Optional[Union[DPTBinary, DPTArray]] = None) -> None:
+ """Initialize a new instance of GroupValueResponse."""
+ self.value = value
+
+ def calculated_length(self) -> int:
+ """Get length of APCI payload."""
+ if isinstance(self.value, DPTBinary):
+ return 1
+ if isinstance(self.value, DPTArray):
+ return 1 + len(self.value.value)
+ raise TypeError()
+
+ def from_knx(self, raw: bytes) -> None:
+ """Parse/deserialize from KNX/IP raw data."""
+ if len(raw) == 2:
+ self.value = DPTBinary(raw[1] & DPTBinary.APCI_BITMASK)
+ else:
+ self.value = DPTArray(raw[2:])
+
+ def to_knx(self) -> bytes:
+ """Serialize to KNX/IP raw data."""
+ if isinstance(self.value, DPTBinary):
+ return encode_cmd_and_payload(self.code, encoded_payload=self.value.value)
+ if isinstance(self.value, DPTArray):
+ return encode_cmd_and_payload(
+ self.code, appended_payload=bytes(self.value.value)
+ )
+ raise TypeError()
+
+ def __str__(self) -> str:
+ """Return object as readable string."""
+ return f''
diff --git a/xknx/telegram/telegram.py b/xknx/telegram/telegram.py
index 759bc6e0a..3b4280c29 100644
--- a/xknx/telegram/telegram.py
+++ b/xknx/telegram/telegram.py
@@ -8,10 +8,9 @@
It contains
-* the telegram type (e.g. GROUP_WRITE)
* the direction (incoming or outgoing)
* the group address (e.g. 1/2/3)
-* and the payload (e.g. "12%" or "23.23 C".
+* and the payload (e.g. GroupValueWrite("12%")).
"""
from enum import Enum
@@ -27,14 +26,6 @@ class TelegramDirection(Enum):
OUTGOING = "Outgoing"
-class TelegramType(Enum):
- """Enum class for type of telegram."""
-
- GROUP_READ = "GroupValueRead"
- GROUP_WRITE = "GroupValueWrite"
- GROUP_RESPONSE = "GroupValueResponse"
-
-
class Telegram:
"""Class for KNX telegrams."""
@@ -45,14 +36,12 @@ def __init__(
destination_address: Union[GroupAddress, IndividualAddress] = GroupAddress(
None
),
- telegramtype: TelegramType = TelegramType.GROUP_WRITE,
direction: TelegramDirection = TelegramDirection.OUTGOING,
payload: Any = None,
source_address: IndividualAddress = IndividualAddress(None),
) -> None:
"""Initialize Telegram class."""
self.destination_address = destination_address
- self.telegramtype = telegramtype
self.direction = direction
self.payload = payload
self.source_address = source_address
@@ -60,10 +49,9 @@ def __init__(
def __str__(self) -> str:
"""Return object as readable string."""
return (
- ''.format(
self.direction.value,
- self.telegramtype.value,
self.source_address,
self.destination_address,
self.payload,