Repository: XKNX/xknx
Pull request #510 (2020-11-25 23:41:45)

Rename `Telegram.group_address` to `Telegram.destination_address`.
## Description
This PR is a part of #253, for easier reviewing.

In this PR, I refactored `Telegram.group_address` to ~~`Telegram.address`~~ `telegram.destination_address`. Based on the type of address, the CEMIFrame is build with the proper flags set. This changes allows for the other changes of #253 to support non-broadcast APCI services.

All high-level devices still use `group_address`, which still makes sense over there. They just update a `Telegram.destination_address` with their `group_address`.

## Type of change

- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [x] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] This change requires a documentation update

## Checklist:

- [x] I have performed a self-review of my own code
- [ ] The documentation has been adjusted accordingly
- [x] The changes generate no new warnings
- [x] Tests have been added that prove the fix is effective or that the feature works
- [x] The changes are documented in the changelog
- [ ] The Homeassistant plugin has been adjusted in case of new config options


basilfx: I'm aware of the hint, but in this case I did it directly since the change was so small ;-)

Next time I'll do a fixup commit and then squash once approved.
marvin-w: Cool! :+1: 

And yes, it was really small :dancers: 

No need to manually squash. We can just squash the whole PR when merging.
coveralls: 
[![Coverage Status](https://coveralls.io/builds/35255420/badge)](https://coveralls.io/builds/35255420)

Coverage decreased (-0.01%) to 94.481% when pulling **767540e05e1b1dadc5a7a80c5b5fb1287ea3ae48 on basilfx:feature/telegram_address** into **be4008d6e19d9cde0178e6654cd2f7d5ff0a8128 on XKNX:master**.

farmio: Since a Telegram has a destination address and a source address it would be nice to call it eg. one of "destination_address", "dest_address", "destination".
I know our Telegram object currently doesn't contain the source address, but I'd like to add it for eg. #497 and I can imagine other useful cases.
basilfx: @farmio Yes, that would be awesome. But I would prefer to do it in another PR. It's quite some work to adapt it, and it doesn't 'help' me to achieve the goal of #253.
farmio: Just to get this straight: I just want to avoid renaming Telegram.group_address twice. 
Adding source to Telegram should definitely be done in another PR (whenever and by whoever likes to)
basilfx: That's fine. So let's call it `destination_address` address then? That should be OK to adapt :)
farmio: Great! Descriptive is always nice. 😃
basilfx: Rebased the PR and adapted `Telegram.address` to `Telegram.destination_address`.
marvin-w: @basilfx Please fix the merge conflicts and the linting error (black formatting). 

https://travis-ci.org/github/XKNX/xknx/jobs/746142703#L349

Pre-commit will do this automatically for you.
basilfx: Pushed one more to changelog.md since the field was renamed.

Patch:
diff --git a/changelog.md b/changelog.md
index c7451d16..f1c1fa1a 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,11 @@
 # Changelog
 
+## Unreleased changes
+
+### Internals
+
+- Telegram: `group_address` renamed to `destination_address`, to prepare support for other APCI services.
+
 ## 0.15.6 Bugfix for StateUpater 2020-11-26
 
 ### Bugfixes
diff --git a/home-assistant-plugin/custom_components/xknx/__init__.py b/home-assistant-plugin/custom_components/xknx/__init__.py
index 517b4ff1..5a788491 100644
--- a/home-assistant-plugin/custom_components/xknx/__init__.py
+++ b/home-assistant-plugin/custom_components/xknx/__init__.py
@@ -324,7 +324,10 @@ class KNXModule:
         """Call invoked after a KNX telegram was received."""
         self.hass.bus.async_fire(
             "knx_event",
-            {"address": str(telegram.group_address), "data": telegram.payload.value},
+            {
+                "address": str(telegram.destination_address),
+                "data": telegram.payload.value,
+            },
         )
 
     async def service_send_to_knx_bus(self, call):
@@ -344,10 +347,10 @@ class KNXModule:
                 return DPTBinary(attr_payload)
             return DPTArray(attr_payload)
 
-        payload = calculate_payload(attr_payload)
-        address = GroupAddress(attr_address)
-
-        telegram = Telegram(group_address=address, payload=payload)
+        telegram = Telegram(
+            destination_address=GroupAddress(attr_address),
+            payload=calculate_payload(attr_payload),
+        )
         await self.xknx.telegrams.put(telegram)
 
 
diff --git a/xknx/core/telegram_queue.py b/xknx/core/telegram_queue.py
index b4b9a1b3..5d8eb94f 100644
--- a/xknx/core/telegram_queue.py
+++ b/xknx/core/telegram_queue.py
@@ -35,7 +35,7 @@ class TelegramQueue:
             if self.address_filters is None:
                 return True
             for address_filter in self.address_filters:
-                if address_filter.match(telegram.group_address):
+                if address_filter.match(telegram.destination_address):
                     return True
             return False
 
diff --git a/xknx/core/value_reader.py b/xknx/core/value_reader.py
index d30c7ac9..3ef0f778 100644
--- a/xknx/core/value_reader.py
+++ b/xknx/core/value_reader.py
@@ -53,9 +53,13 @@ class ValueReader:
 
     async def telegram_received(self, telegram):
         """Test if telegram has correct group address and trigger event."""
-        if telegram.group_address == self.group_address and telegram.telegramtype in (
-            TelegramType.GROUP_RESPONSE,
-            TelegramType.GROUP_WRITE,
+        if (
+            telegram.destination_address == self.group_address
+            and telegram.telegramtype
+            in (
+                TelegramType.GROUP_RESPONSE,
+                TelegramType.GROUP_WRITE,
+            )
         ):
             self.success = True
             self.received_telegram = telegram
diff --git a/xknx/devices/devices.py b/xknx/devices/devices.py
index 0954df53..db241627 100644
--- a/xknx/devices/devices.py
+++ b/xknx/devices/devices.py
@@ -66,7 +66,7 @@ class Devices:
 
     async def process(self, telegram):
         """Process telegram."""
-        for device in self.devices_by_group_address(telegram.group_address):
+        for device in self.devices_by_group_address(telegram.destination_address):
             await device.process(telegram)
 
     async def sync(self):
diff --git a/xknx/knxip/cemi_frame.py b/xknx/knxip/cemi_frame.py
index 29065cff..44b7dedb 100644
--- a/xknx/knxip/cemi_frame.py
+++ b/xknx/knxip/cemi_frame.py
@@ -74,7 +74,7 @@ class CEMIFrame:
             raise ConversionError(f"Telegram not implemented for {self.cmd}")
 
         return Telegram(
-            group_address=self.dst_addr,
+            destination_address=self.dst_addr,
             payload=self.payload,
             telegramtype=resolve_telegram_type(self.cmd),
         )
@@ -82,7 +82,7 @@ class CEMIFrame:
     @telegram.setter
     def telegram(self, telegram: Telegram):
         """Set telegram."""
-        self.dst_addr = telegram.group_address
+        self.dst_addr = telegram.destination_address
         self.payload = telegram.payload
 
         # TODO: Move to separate function, together with setting of
@@ -94,10 +94,16 @@ class CEMIFrame:
             | CEMIFlags.PRIORITY_LOW
             | CEMIFlags.NO_ACK_REQUESTED
             | CEMIFlags.CONFIRM_NO_ERROR
-            | CEMIFlags.DESTINATION_GROUP_ADDRESS
             | CEMIFlags.HOP_COUNT_1ST
         )
 
+        if isinstance(telegram.destination_address, GroupAddress):
+            self.flags |= CEMIFlags.DESTINATION_GROUP_ADDRESS
+        elif isinstance(telegram.destination_address, PhysicalAddress):
+            self.flags |= CEMIFlags.DESTINATION_INDIVIDUAL_ADDRESS
+        else:
+            raise TypeError()
+
         # TODO: use telegram.direction
         def resolve_cmd(telegramtype: TelegramType) -> APCICommand:
             """Resolve APCICommand from TelegramType."""
diff --git a/xknx/remote_value/remote_value.py b/xknx/remote_value/remote_value.py
index abab2bbe..88f86ee3 100644
--- a/xknx/remote_value/remote_value.py
+++ b/xknx/remote_value/remote_value.py
@@ -110,13 +110,13 @@ class RemoteValue:
 
     async def process(self, telegram, always_callback=False):
         """Process incoming or outgoing telegram."""
-        if not self.has_group_address(telegram.group_address):
+        if not self.has_group_address(telegram.destination_address):
             return False
         if not self.payload_valid(telegram.payload):
             raise CouldNotParseTelegram(
                 "payload invalid",
                 payload=telegram.payload,
-                group_address=telegram.group_address,
+                address=telegram.destination_address,
                 device_name=self.device_name,
                 feature_name=self.feature_name,
             )
@@ -137,7 +137,7 @@ class RemoteValue:
     async def _send(self, payload, response=False):
         """Send payload as telegram to KNX bus."""
         telegram = Telegram(
-            group_address=self.group_address,
+            destination_address=self.group_address,
             telegramtype=(
                 TelegramType.GROUP_RESPONSE if response else TelegramType.GROUP_WRITE
             ),
diff --git a/xknx/telegram/telegram.py b/xknx/telegram/telegram.py
index 9e3cc5d5..492db070 100644
--- a/xknx/telegram/telegram.py
+++ b/xknx/telegram/telegram.py
@@ -15,9 +15,9 @@ It contains
 
 """
 from enum import Enum
-from typing import Any
+from typing import Any, Union
 
-from .address import GroupAddress
+from .address import GroupAddress, PhysicalAddress
 
 
 class TelegramDirection(Enum):
@@ -42,7 +42,7 @@ class Telegram:
 
     def __init__(
         self,
-        group_address: GroupAddress = GroupAddress(None),
+        destination_address: Union[GroupAddress, PhysicalAddress] = GroupAddress(None),
         telegramtype: TelegramType = TelegramType.GROUP_WRITE,
         direction: TelegramDirection = TelegramDirection.OUTGOING,
         payload: Any = None,
@@ -50,15 +50,15 @@ class Telegram:
         """Initialize Telegram class."""
         self.direction = direction
         self.telegramtype = telegramtype
-        self.group_address = group_address
+        self.destination_address = destination_address
         self.payload = payload
 
     def __str__(self) -> str:
         """Return object as readable string."""
         return (
-            '<Telegram group_address="{}", payload="{}" '
+            '<Telegram destination_address="{}", payload="{}" '
             'telegramtype="{}" direction="{}" />'.format(
-                self.group_address.__repr__(),
+                self.destination_address.__repr__(),
                 self.payload,
                 self.telegramtype,
                 self.direction,


Test patch:
diff --git a/test/core_tests/telegram_queue_test.py b/test/core_tests/telegram_queue_test.py
index 299aa3b1..4460ec29 100644
--- a/test/core_tests/telegram_queue_test.py
+++ b/test/core_tests/telegram_queue_test.py
@@ -38,9 +38,9 @@ class TestTelegramQueue(unittest.TestCase):
         xknx = XKNX()
 
         telegram_in = Telegram(
+            destination_address=GroupAddress("1/2/3"),
             direction=TelegramDirection.INCOMING,
             payload=DPTBinary(1),
-            group_address=GroupAddress("1/2/3"),
         )
 
         self.loop.run_until_complete(xknx.telegram_queue.start())
@@ -76,13 +76,13 @@ class TestTelegramQueue(unittest.TestCase):
         telegram_in = Telegram(
             direction=TelegramDirection.INCOMING,
             payload=DPTBinary(1),
-            group_address=GroupAddress("1/2/3"),
+            destination_address=GroupAddress("1/2/3"),
         )
 
         telegram_out = Telegram(
             direction=TelegramDirection.OUTGOING,
             payload=DPTBinary(1),
-            group_address=GroupAddress("1/2/3"),
+            destination_address=GroupAddress("1/2/3"),
         )
 
         self.loop.run_until_complete(xknx.telegram_queue.start())
@@ -118,9 +118,9 @@ class TestTelegramQueue(unittest.TestCase):
         xknx.telegram_queue.register_telegram_received_cb(async_telegram_received_cb)
 
         telegram = Telegram(
+            destination_address=GroupAddress("1/2/3"),
             direction=TelegramDirection.INCOMING,
             payload=DPTBinary(1),
-            group_address=GroupAddress("1/2/3"),
         )
         self.loop.run_until_complete(
             xknx.telegram_queue.process_telegram_incoming(telegram)
@@ -142,9 +142,9 @@ class TestTelegramQueue(unittest.TestCase):
         xknx.telegram_queue.unregister_telegram_received_cb(callback)
 
         telegram = Telegram(
+            destination_address=GroupAddress("1/2/3"),
             direction=TelegramDirection.INCOMING,
             payload=DPTBinary(1),
-            group_address=GroupAddress("1/2/3"),
         )
         self.loop.run_until_complete(
             xknx.telegram_queue.process_telegram_incoming(telegram)
@@ -168,9 +168,9 @@ class TestTelegramQueue(unittest.TestCase):
         devices_by_ga_mock.return_value = [test_device]
 
         telegram = Telegram(
+            destination_address=GroupAddress("1/2/3"),
             direction=TelegramDirection.INCOMING,
             payload=DPTBinary(1),
-            group_address=GroupAddress("1/2/3"),
         )
         self.loop.run_until_complete(
             xknx.telegram_queue.process_telegram_incoming(telegram)
@@ -191,9 +191,9 @@ class TestTelegramQueue(unittest.TestCase):
         )
 
         telegram = Telegram(
+            destination_address=GroupAddress("1/2/3"),
             direction=TelegramDirection.INCOMING,
             payload=DPTBinary(1),
-            group_address=GroupAddress("1/2/3"),
         )
         self.loop.run_until_complete(
             xknx.telegram_queue.process_telegram_incoming(telegram)
@@ -213,9 +213,9 @@ class TestTelegramQueue(unittest.TestCase):
         if_mock.send_telegram.return_value = async_if_send_telegram
 
         telegram = Telegram(
+            destination_address=GroupAddress("1/2/3"),
             direction=TelegramDirection.OUTGOING,
             payload=DPTBinary(1),
-            group_address=GroupAddress("1/2/3"),
         )
 
         # log a warning if there is no KNXIP interface instanciated
@@ -247,9 +247,9 @@ class TestTelegramQueue(unittest.TestCase):
         process_tg_in_mock.return_value = asyncio.ensure_future(process_exception())
 
         telegram = Telegram(
+            destination_address=GroupAddress("1/2/3"),
             direction=TelegramDirection.INCOMING,
             payload=DPTBinary(1),
-            group_address=GroupAddress("1/2/3"),
         )
 
         xknx.telegrams.put_nowait(telegram)
@@ -277,14 +277,14 @@ class TestTelegramQueue(unittest.TestCase):
         process_telegram_outgoing_mock.return_value = async_process_mock
 
         telegram_in = Telegram(
+            destination_address=GroupAddress("1/2/3"),
             direction=TelegramDirection.INCOMING,
             payload=DPTBinary(1),
-            group_address=GroupAddress("1/2/3"),
         )
         telegram_out = Telegram(
+            destination_address=GroupAddress("1/2/3"),
             direction=TelegramDirection.OUTGOING,
             payload=DPTBinary(1),
-            group_address=GroupAddress("1/2/3"),
         )
 
         xknx.telegrams.put_nowait(telegram_in)
@@ -312,9 +312,9 @@ class TestTelegramQueue(unittest.TestCase):
         xknx.telegram_queue.register_telegram_received_cb(async_telegram_received_cb)
 
         telegram = Telegram(
+            destination_address=GroupAddress("1/2/3"),
             direction=TelegramDirection.INCOMING,
             payload=DPTBinary(1),
-            group_address=GroupAddress("1/2/3"),
         )
         xknx.telegrams.put_nowait(telegram)
         self.loop.run_until_complete(xknx.telegram_queue._process_all_telegrams())
@@ -341,9 +341,9 @@ class TestTelegramQueue(unittest.TestCase):
         )
 
         telegram = Telegram(
+            destination_address=GroupAddress("1/2/3"),
             direction=TelegramDirection.INCOMING,
             payload=DPTBinary(1),
-            group_address=GroupAddress("1/2/3"),
         )
         xknx.telegrams.put_nowait(telegram)
         self.loop.run_until_complete(xknx.telegram_queue._process_all_telegrams())
@@ -370,9 +370,9 @@ class TestTelegramQueue(unittest.TestCase):
         )
 
         telegram = Telegram(
+            destination_address=GroupAddress("1/2/3"),
             direction=TelegramDirection.INCOMING,
             payload=DPTBinary(1),
-            group_address=GroupAddress("1/2/3"),
         )
         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 85efd967..90173922 100644
--- a/test/core_tests/value_reader_test.py
+++ b/test/core_tests/value_reader_test.py
@@ -27,7 +27,7 @@ class TestValueReader(unittest.TestCase):
         xknx = XKNX()
         test_group_address = GroupAddress("0/0/0")
         response_telegram = Telegram(
-            group_address=test_group_address,
+            destination_address=test_group_address,
             telegramtype=TelegramType.GROUP_RESPONSE,
             direction=TelegramDirection.INCOMING,
             payload=DPTBinary(1),
@@ -94,7 +94,7 @@ class TestValueReader(unittest.TestCase):
         self.assertEqual(
             telegram,
             Telegram(
-                group_address=GroupAddress("0/0/0"),
+                destination_address=GroupAddress("0/0/0"),
                 telegramtype=TelegramType.GROUP_READ,
             ),
         )
@@ -104,25 +104,25 @@ class TestValueReader(unittest.TestCase):
         xknx = XKNX()
         test_group_address = GroupAddress("0/0/0")
         expected_telegram_1 = Telegram(
-            group_address=test_group_address,
+            destination_address=test_group_address,
             telegramtype=TelegramType.GROUP_RESPONSE,
             direction=TelegramDirection.INCOMING,
             payload=DPTBinary(1),
         )
         expected_telegram_2 = Telegram(
-            group_address=test_group_address,
+            destination_address=test_group_address,
             telegramtype=TelegramType.GROUP_WRITE,
             direction=TelegramDirection.INCOMING,
             payload=DPTBinary(1),
         )
         telegram_wrong_address = Telegram(
-            group_address=GroupAddress("0/0/1"),
+            destination_address=GroupAddress("0/0/1"),
             telegramtype=TelegramType.GROUP_RESPONSE,
             direction=TelegramDirection.INCOMING,
             payload=DPTBinary(1),
         )
         telegram_wrong_type = Telegram(
-            group_address=test_group_address,
+            destination_address=test_group_address,
             telegramtype=TelegramType.GROUP_READ,
             direction=TelegramDirection.INCOMING,
             payload=DPTBinary(1),
diff --git a/test/devices_tests/binary_sensor_test.py b/test/devices_tests/binary_sensor_test.py
index 59e48332..4eb71932 100644
--- a/test/devices_tests/binary_sensor_test.py
+++ b/test/devices_tests/binary_sensor_test.py
@@ -38,14 +38,14 @@ class TestBinarySensor(unittest.TestCase):
         self.assertEqual(binaryinput.state, None)
 
         telegram_on = Telegram(
-            group_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+            destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
         )
         self.loop.run_until_complete(binaryinput.process(telegram_on))
 
         self.assertEqual(binaryinput.state, True)
 
         telegram_off = Telegram(
-            group_address=GroupAddress("1/2/3"), payload=DPTBinary(0)
+            destination_address=GroupAddress("1/2/3"), payload=DPTBinary(0)
         )
         self.loop.run_until_complete(binaryinput.process(telegram_off))
         self.assertEqual(binaryinput.state, False)
@@ -54,7 +54,7 @@ class TestBinarySensor(unittest.TestCase):
         self.assertEqual(binaryinput2.state, None)
 
         telegram_off2 = Telegram(
-            group_address=GroupAddress("1/2/4"), payload=DPTBinary(0)
+            destination_address=GroupAddress("1/2/4"), payload=DPTBinary(0)
         )
         self.loop.run_until_complete(binaryinput2.process(telegram_off2))
         self.assertEqual(binaryinput2.state, False)
@@ -67,14 +67,14 @@ class TestBinarySensor(unittest.TestCase):
         self.assertEqual(bs_invert.state, None)
 
         telegram_on = Telegram(
-            group_address=GroupAddress("1/2/3"), payload=DPTBinary(0)
+            destination_address=GroupAddress("1/2/3"), payload=DPTBinary(0)
         )
         self.loop.run_until_complete(bs_invert.process(telegram_on))
 
         self.assertEqual(bs_invert.state, True)
 
         telegram_off = Telegram(
-            group_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+            destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
         )
         self.loop.run_until_complete(bs_invert.process(telegram_off))
         self.assertEqual(bs_invert.state, False)
@@ -92,7 +92,7 @@ class TestBinarySensor(unittest.TestCase):
             device_updated_cb=async_after_update_callback,
         )
         telegram_on = Telegram(
-            group_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+            destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
         )
 
         self.loop.run_until_complete(binaryinput.process(telegram_on))
@@ -131,7 +131,7 @@ class TestBinarySensor(unittest.TestCase):
         self.assertEqual(switch.state, None)
 
         telegram_on = Telegram(
-            group_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+            destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
         )
         self.loop.run_until_complete(binary_sensor.process(telegram_on))
         # process outgoing telegram from queue
@@ -141,7 +141,7 @@ class TestBinarySensor(unittest.TestCase):
         self.assertEqual(switch.state, True)
 
         telegram_off = Telegram(
-            group_address=GroupAddress("1/2/3"), payload=DPTBinary(0)
+            destination_address=GroupAddress("1/2/3"), payload=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 +164,7 @@ class TestBinarySensor(unittest.TestCase):
         self.assertEqual(switch.state, None)
 
         telegram_on = Telegram(
-            group_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+            destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
         )
 
         with patch("time.time") as mock_time, patch(
@@ -242,7 +242,9 @@ class TestBinarySensor(unittest.TestCase):
 
         switch.register_device_updated_cb(async_after_update_callback)
 
-        telegram = Telegram(group_address=GroupAddress("1/2/3"), payload=DPTBinary(1))
+        telegram = Telegram(
+            destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+        )
         self.loop.run_until_complete(switch.process(telegram))
         # no _context_task started because ignore_internal_state is False
         self.assertIsNone(switch._context_task)
@@ -268,7 +270,9 @@ class TestBinarySensor(unittest.TestCase):
 
         switch.register_device_updated_cb(async_after_update_callback)
 
-        telegram = Telegram(group_address=GroupAddress("1/2/3"), payload=DPTBinary(1))
+        telegram = Telegram(
+            destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+        )
         self.assertEqual(switch.counter, 0)
 
         self.loop.run_until_complete(switch.process(telegram))
@@ -308,7 +312,9 @@ class TestBinarySensor(unittest.TestCase):
 
         switch.register_device_updated_cb(async_after_update_callback)
 
-        telegram = Telegram(group_address=GroupAddress("1/2/3"), payload=DPTBinary(1))
+        telegram = Telegram(
+            destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+        )
         self.loop.run_until_complete(switch.process(telegram))
         # no _context_task started because context_timeout is False
         self.assertIsNone(switch._context_task)
@@ -334,10 +340,10 @@ class TestBinarySensor(unittest.TestCase):
         switch.register_device_updated_cb(async_after_update_callback)
 
         write_telegram = Telegram(
-            group_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+            destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
         )
         response_telegram = Telegram(
-            group_address=GroupAddress("1/2/3"),
+            destination_address=GroupAddress("1/2/3"),
             payload=DPTBinary(1),
             telegramtype=TelegramType.GROUP_RESPONSE,
         )
diff --git a/test/devices_tests/datetime_test.py b/test/devices_tests/datetime_test.py
index fecea699..c47cbece 100644
--- a/test/devices_tests/datetime_test.py
+++ b/test/devices_tests/datetime_test.py
@@ -42,7 +42,7 @@ class TestDateTime(unittest.TestCase):
 
         self.assertEqual(xknx.telegrams.qsize(), 1)
         telegram = xknx.telegrams.get_nowait()
-        self.assertEqual(telegram.group_address, GroupAddress("1/2/3"))
+        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(
@@ -68,7 +68,7 @@ class TestDateTime(unittest.TestCase):
         _throwaway_initial = xknx.telegrams.get_nowait()
 
         telegram = xknx.telegrams.get_nowait()
-        self.assertEqual(telegram.group_address, GroupAddress("1/2/3"))
+        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))
@@ -92,7 +92,7 @@ class TestDateTime(unittest.TestCase):
         _throwaway_initial = xknx.telegrams.get_nowait()
 
         telegram = xknx.telegrams.get_nowait()
-        self.assertEqual(telegram.group_address, GroupAddress("1/2/3"))
+        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))
@@ -111,7 +111,8 @@ class TestDateTime(unittest.TestCase):
         )
 
         telegram_read = Telegram(
-            group_address=GroupAddress("1/2/3"), telegramtype=TelegramType.GROUP_READ
+            destination_address=GroupAddress("1/2/3"),
+            telegramtype=TelegramType.GROUP_READ,
         )
         with patch("time.localtime") as mock_time:
             mock_time.return_value = time.struct_time([2017, 1, 7, 9, 13, 14, 6, 0, 0])
@@ -125,7 +126,7 @@ class TestDateTime(unittest.TestCase):
         self.assertEqual(
             telegram,
             Telegram(
-                group_address=GroupAddress("1/2/3"),
+                destination_address=GroupAddress("1/2/3"),
                 telegramtype=TelegramType.GROUP_RESPONSE,
                 payload=DPTArray((0xE9, 0xD, 0xE)),
             ),
diff --git a/test/devices_tests/sensor_test.py b/test/devices_tests/sensor_test.py
index f7a976e2..5394a1d8 100644
--- a/test/devices_tests/sensor_test.py
+++ b/test/devices_tests/sensor_test.py
@@ -78,9 +78,9 @@ class TestSensor(unittest.TestCase):
         #  set initial payload of sensor
         sensor.sensor_value.payload = payload
 
-        telegram = Telegram(group_address=GroupAddress("1/2/3"), payload=payload)
+        telegram = Telegram(destination_address=GroupAddress("1/2/3"), payload=payload)
         response_telegram = Telegram(
-            group_address=GroupAddress("1/2/3"),
+            destination_address=GroupAddress("1/2/3"),
             payload=payload,
             telegramtype=TelegramType.GROUP_RESPONSE,
         )
diff --git a/test/devices_tests/switch_test.py b/test/devices_tests/switch_test.py
index a315a7a1..08525bb7 100644
--- a/test/devices_tests/switch_test.py
+++ b/test/devices_tests/switch_test.py
@@ -79,10 +79,10 @@ class TestSwitch(unittest.TestCase):
         callback_mock.assert_not_called()
 
         telegram_on = Telegram(
-            group_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+            destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
         )
         telegram_off = Telegram(
-            group_address=GroupAddress("1/2/3"), payload=DPTBinary(0)
+            destination_address=GroupAddress("1/2/3"), payload=DPTBinary(0)
         )
 
         self.loop.run_until_complete(switch1.process(telegram_on))
@@ -127,12 +127,12 @@ class TestSwitch(unittest.TestCase):
         callback_mock.assert_not_called()
 
         telegram_on = Telegram(
-            group_address=GroupAddress("1/2/4"),
+            destination_address=GroupAddress("1/2/4"),
             payload=DPTBinary(1),
             telegramtype=TelegramType.GROUP_RESPONSE,
         )
         telegram_off = Telegram(
-            group_address=GroupAddress("1/2/4"),
+            destination_address=GroupAddress("1/2/4"),
             payload=DPTBinary(0),
             telegramtype=TelegramType.GROUP_RESPONSE,
         )
@@ -162,10 +162,10 @@ class TestSwitch(unittest.TestCase):
         self.assertEqual(switch.state, None)
 
         telegram_inv_on = Telegram(
-            group_address=GroupAddress("1/2/3"), payload=DPTBinary(0)
+            destination_address=GroupAddress("1/2/3"), payload=DPTBinary(0)
         )
         telegram_inv_off = Telegram(
-            group_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+            destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
         )
 
         self.loop.run_until_complete(switch.process(telegram_inv_on))
@@ -181,7 +181,7 @@ class TestSwitch(unittest.TestCase):
             xknx, "TestInput", group_address="1/2/3", reset_after=reset_after_sec
         )
         telegram_on = Telegram(
-            group_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+            destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
         )
 
         self.loop.run_until_complete(switch.process(telegram_on))
@@ -200,7 +200,7 @@ class TestSwitch(unittest.TestCase):
             xknx, "TestInput", group_address="1/2/3", reset_after=reset_after_sec
         )
         telegram_on = Telegram(
-            group_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+            destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
         )
 
         self.loop.run_until_complete(switch.process(telegram_on))
@@ -229,7 +229,9 @@ class TestSwitch(unittest.TestCase):
 
         switch.register_device_updated_cb(async_after_update_callback)
 
-        telegram = Telegram(group_address=GroupAddress("1/2/3"), payload=DPTBinary(1))
+        telegram = Telegram(
+            destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+        )
         self.loop.run_until_complete(switch.process(telegram))
 
         after_update_callback.assert_called_with(switch)
diff --git a/test/knxip_tests/cemi_frame_test.py b/test/knxip_tests/cemi_frame_test.py
index b911f8fb..912e4f89 100644
--- a/test/knxip_tests/cemi_frame_test.py
+++ b/test/knxip_tests/cemi_frame_test.py
@@ -6,8 +6,8 @@ from pytest import fixture, raises
 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, CEMIMessageCode
-from xknx.telegram import PhysicalAddress, Telegram
+from xknx.knxip.knxip_enum import APCICommand, CEMIFlags, CEMIMessageCode
+from xknx.telegram import GroupAddress, PhysicalAddress, Telegram
 
 
 def get_data(code, adil, flags, src, dst, mpdu_len, tpci_apci, payload):
@@ -153,3 +153,41 @@ def test_invalid_invalid_len(frame):
     """Test for invalid cemi len"""
     with raises(UnsupportedCEMIMessage, match=r".*CEMI too small.*"):
         frame.from_knx_data_link_layer(get_data(0x29, 0, 0, 0, 0, 2, 0, [])[:5])
+
+
+def test_from_knx_group_address(frame):
+    """Test conversion for a cemi with a group address as destination"""
+    frame.from_knx(get_data(0x29, 0, 0x80, 0, 0, 1, 0, []))
+
+    assert frame.dst_addr == GroupAddress(0)
+
+
+def test_from_knx_physical_address(frame):
+    """Test conversion for a cemi with a physical address as destination"""
+    frame.from_knx(get_data(0x29, 0, 0x00, 0, 0, 1, 0, []))
+
+    assert frame.dst_addr == PhysicalAddress(0)
+
+
+def test_telegram_group_address(frame):
+    """Test telegram conversion flags with a group address"""
+    frame.telegram = Telegram(destination_address=GroupAddress(0))
+
+    assert (
+        frame.flags & CEMIFlags.DESTINATION_GROUP_ADDRESS
+    ) == CEMIFlags.DESTINATION_GROUP_ADDRESS
+
+
+def test_telegram_physical_address(frame):
+    """Test telegram conversion flags with a physical address"""
+    frame.telegram = Telegram(destination_address=PhysicalAddress(0))
+
+    assert (
+        frame.flags & CEMIFlags.DESTINATION_INDIVIDUAL_ADDRESS
+    ) == CEMIFlags.DESTINATION_INDIVIDUAL_ADDRESS
+
+
+def test_telegram_unsupported_address(frame):
+    """Test telegram conversion flags with an unsupported address"""
+    with raises(TypeError):
+        frame.telegram = Telegram(destination_address=object())
diff --git a/test/knxip_tests/routing_indication_test.py b/test/knxip_tests/routing_indication_test.py
index e9939b58..c5f43e5f 100644
--- a/test/knxip_tests/routing_indication_test.py
+++ b/test/knxip_tests/routing_indication_test.py
@@ -60,7 +60,7 @@ class Test_KNXIP(unittest.TestCase):
         knxipframe.body.cemi.src_addr = PhysicalAddress("1.2.2")
 
         telegram = Telegram(
-            group_address=GroupAddress(337),
+            destination_address=GroupAddress(337),
             payload=DPTArray(DPTTime().to_knx(time.strptime("13:23:42", "%H:%M:%S"))),
         )
 
@@ -84,7 +84,7 @@ class Test_KNXIP(unittest.TestCase):
 
         telegram = knxipframe.body.cemi.telegram
 
-        self.assertEqual(telegram.group_address, GroupAddress(337))
+        self.assertEqual(telegram.destination_address, GroupAddress(337))
 
         self.assertEqual(len(telegram.payload.value), 1)
         self.assertEqual(telegram.payload.value[0], 0xF0)
@@ -240,7 +240,8 @@ class Test_KNXIP(unittest.TestCase):
     def test_maximum_apci(self):
         """Test parsing and streaming CEMIFrame KNX/IP packet, testing maximum APCI."""
         telegram = Telegram(
-            group_address=GroupAddress(337), payload=DPTBinary(DPTBinary.APCI_MAX_VALUE)
+            destination_address=GroupAddress(337),
+            payload=DPTBinary(DPTBinary.APCI_MAX_VALUE),
         )
         xknx = XKNX()
         knxipframe = KNXIPFrame(xknx)
diff --git a/test/remote_value_tests/remote_value_1count_test.py b/test/remote_value_tests/remote_value_1count_test.py
index 6a3ad382..29a734ba 100644
--- a/test/remote_value_tests/remote_value_1count_test.py
+++ b/test/remote_value_tests/remote_value_1count_test.py
@@ -59,7 +59,7 @@ class TestRemoteValue1Count(unittest.TestCase):
         xknx = XKNX()
         remote_value = RemoteValue1Count(xknx, group_address=GroupAddress("1/2/3"))
         telegram = Telegram(
-            group_address=GroupAddress("1/2/3"), payload=DPTArray((0x64,))
+            destination_address=GroupAddress("1/2/3"), payload=DPTArray((0x64,))
         )
         self.loop.run_until_complete(remote_value.process(telegram))
         self.assertEqual(remote_value.value, 100)
@@ -70,12 +70,12 @@ class TestRemoteValue1Count(unittest.TestCase):
         remote_value = RemoteValue1Count(xknx, group_address=GroupAddress("1/2/3"))
         with self.assertRaises(CouldNotParseTelegram):
             telegram = Telegram(
-                group_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+                destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
             )
             self.loop.run_until_complete(remote_value.process(telegram))
         with self.assertRaises(CouldNotParseTelegram):
             telegram = Telegram(
-                group_address=GroupAddress("1/2/3"),
+                destination_address=GroupAddress("1/2/3"),
                 payload=DPTArray(
                     (
                         0x64,
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 923130ac..c30c4a80 100644
--- a/test/remote_value_tests/remote_value_climate_mode_test.py
+++ b/test/remote_value_tests/remote_value_climate_mode_test.py
@@ -219,7 +219,7 @@ class TestRemoteValueDptValue1Ucount(unittest.TestCase):
             climate_mode_type=RemoteValueClimateMode.ClimateModeType.HVAC_MODE,
         )
         telegram = Telegram(
-            group_address=GroupAddress("1/2/3"), payload=DPTArray((0x00,))
+            destination_address=GroupAddress("1/2/3"), payload=DPTArray((0x00,))
         )
         self.loop.run_until_complete(remote_value.process(telegram))
         self.assertEqual(remote_value.value, HVACOperationMode.AUTO)
@@ -233,7 +233,7 @@ class TestRemoteValueDptValue1Ucount(unittest.TestCase):
             operation_mode=HVACOperationMode.FROST_PROTECTION,
         )
         telegram = Telegram(
-            group_address=GroupAddress("1/2/3"), payload=DPTBinary(True)
+            destination_address=GroupAddress("1/2/3"), payload=DPTBinary(True)
         )
         self.loop.run_until_complete(remote_value.process(telegram))
         self.assertEqual(remote_value.value, HVACOperationMode.FROST_PROTECTION)
@@ -248,12 +248,12 @@ class TestRemoteValueDptValue1Ucount(unittest.TestCase):
         )
         with self.assertRaises(CouldNotParseTelegram):
             telegram = Telegram(
-                group_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+                destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
             )
             self.loop.run_until_complete(remote_value.process(telegram))
         with self.assertRaises(CouldNotParseTelegram):
             telegram = Telegram(
-                group_address=GroupAddress("1/2/3"),
+                destination_address=GroupAddress("1/2/3"),
                 payload=DPTArray(
                     (
                         0x64,
@@ -273,12 +273,12 @@ class TestRemoteValueDptValue1Ucount(unittest.TestCase):
         )
         with self.assertRaises(CouldNotParseTelegram):
             telegram = Telegram(
-                group_address=GroupAddress("1/2/3"), payload=DPTArray((0x01,))
+                destination_address=GroupAddress("1/2/3"), payload=DPTArray((0x01,))
             )
             self.loop.run_until_complete(remote_value.process(telegram))
         with self.assertRaises(CouldNotParseTelegram):
             telegram = Telegram(
-                group_address=GroupAddress("1/2/3"),
+                destination_address=GroupAddress("1/2/3"),
                 payload=DPTArray(
                     (
                         0x64,
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 57af5763..b75b3c19 100644
--- a/test/remote_value_tests/remote_value_color_rgb_test.py
+++ b/test/remote_value_tests/remote_value_color_rgb_test.py
@@ -79,7 +79,8 @@ class TestRemoteValueColorRGB(unittest.TestCase):
         xknx = XKNX()
         remote_value = RemoteValueColorRGB(xknx, group_address=GroupAddress("1/2/3"))
         telegram = Telegram(
-            group_address=GroupAddress("1/2/3"), payload=DPTArray((0x64, 0x65, 0x66))
+            destination_address=GroupAddress("1/2/3"),
+            payload=DPTArray((0x64, 0x65, 0x66)),
         )
         self.loop.run_until_complete(remote_value.process(telegram))
         self.assertEqual(remote_value.value, (100, 101, 102))
@@ -90,12 +91,12 @@ class TestRemoteValueColorRGB(unittest.TestCase):
         remote_value = RemoteValueColorRGB(xknx, group_address=GroupAddress("1/2/3"))
         with self.assertRaises(CouldNotParseTelegram):
             telegram = Telegram(
-                group_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+                destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
             )
             self.loop.run_until_complete(remote_value.process(telegram))
         with self.assertRaises(CouldNotParseTelegram):
             telegram = Telegram(
-                group_address=GroupAddress("1/2/3"),
+                destination_address=GroupAddress("1/2/3"),
                 payload=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 d5eb2c2c..79f966c1 100644
--- a/test/remote_value_tests/remote_value_color_rgbw_test.py
+++ b/test/remote_value_tests/remote_value_color_rgbw_test.py
@@ -113,7 +113,7 @@ class TestRemoteValueColorRGBW(unittest.TestCase):
         xknx = XKNX()
         remote_value = RemoteValueColorRGBW(xknx, group_address=GroupAddress("1/2/3"))
         telegram = Telegram(
-            group_address=GroupAddress("1/2/3"),
+            destination_address=GroupAddress("1/2/3"),
             payload=DPTArray((0x64, 0x65, 0x66, 0x67, 0x00, 0x0F)),
         )
         self.loop.run_until_complete(remote_value.process(telegram))
@@ -125,18 +125,18 @@ class TestRemoteValueColorRGBW(unittest.TestCase):
         remote_value = RemoteValueColorRGBW(xknx, group_address=GroupAddress("1/2/3"))
         with self.assertRaises(CouldNotParseTelegram):
             telegram = Telegram(
-                group_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+                destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
             )
             self.loop.run_until_complete(remote_value.process(telegram))
         with self.assertRaises(CouldNotParseTelegram):
             telegram = Telegram(
-                group_address=GroupAddress("1/2/3"),
+                destination_address=GroupAddress("1/2/3"),
                 payload=DPTArray((0x64, 0x65, 0x66)),
             )
             self.loop.run_until_complete(remote_value.process(telegram))
         with self.assertRaises(CouldNotParseTelegram):
             telegram = Telegram(
-                group_address=GroupAddress("1/2/3"),
+                destination_address=GroupAddress("1/2/3"),
                 payload=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 7b67a870..0ac5b746 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
@@ -77,7 +77,7 @@ class TestRemoteValueDptValue2Ucount(unittest.TestCase):
             xknx, group_address=GroupAddress("1/2/3")
         )
         telegram = Telegram(
-            group_address=GroupAddress("1/2/3"), payload=DPTArray((0x0A, 0x0B))
+            destination_address=GroupAddress("1/2/3"), payload=DPTArray((0x0A, 0x0B))
         )
         self.loop.run_until_complete(remote_value.process(telegram))
         self.assertEqual(remote_value.value, 2571)
@@ -90,17 +90,17 @@ class TestRemoteValueDptValue2Ucount(unittest.TestCase):
         )
         with self.assertRaises(CouldNotParseTelegram):
             telegram = Telegram(
-                group_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+                destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
             )
             self.loop.run_until_complete(remote_value.process(telegram))
         with self.assertRaises(CouldNotParseTelegram):
             telegram = Telegram(
-                group_address=GroupAddress("1/2/3"), payload=DPTArray((0x64,))
+                destination_address=GroupAddress("1/2/3"), payload=DPTArray((0x64,))
             )
             self.loop.run_until_complete(remote_value.process(telegram))
         with self.assertRaises(CouldNotParseTelegram):
             telegram = Telegram(
-                group_address=GroupAddress("1/2/3"),
+                destination_address=GroupAddress("1/2/3"),
                 payload=DPTArray(
                     (
                         0x64,
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 3d1c56ae..09b82151 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
@@ -68,7 +68,7 @@ class TestRemoteValueDptValue1Ucount(unittest.TestCase):
             xknx, group_address=GroupAddress("1/2/3")
         )
         telegram = Telegram(
-            group_address=GroupAddress("1/2/3"), payload=DPTArray((0x0A,))
+            destination_address=GroupAddress("1/2/3"), payload=DPTArray((0x0A,))
         )
         self.loop.run_until_complete(remote_value.process(telegram))
         self.assertEqual(remote_value.value, 10)
@@ -81,12 +81,12 @@ class TestRemoteValueDptValue1Ucount(unittest.TestCase):
         )
         with self.assertRaises(CouldNotParseTelegram):
             telegram = Telegram(
-                group_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+                destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
             )
             self.loop.run_until_complete(remote_value.process(telegram))
         with self.assertRaises(CouldNotParseTelegram):
             telegram = Telegram(
-                group_address=GroupAddress("1/2/3"),
+                destination_address=GroupAddress("1/2/3"),
                 payload=DPTArray(
                     (
                         0x64,
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 e16057e3..7bd34074 100644
--- a/test/remote_value_tests/remote_value_scene_number_test.py
+++ b/test/remote_value_tests/remote_value_scene_number_test.py
@@ -64,7 +64,7 @@ class TestRemoteValueSceneNumber(unittest.TestCase):
         xknx = XKNX()
         remote_value = RemoteValueSceneNumber(xknx, group_address=GroupAddress("1/2/3"))
         telegram = Telegram(
-            group_address=GroupAddress("1/2/3"), payload=DPTArray((0x0A,))
+            destination_address=GroupAddress("1/2/3"), payload=DPTArray((0x0A,))
         )
         self.loop.run_until_complete(remote_value.process(telegram))
         self.assertEqual(remote_value.value, 11)
@@ -75,12 +75,12 @@ class TestRemoteValueSceneNumber(unittest.TestCase):
         remote_value = RemoteValueSceneNumber(xknx, group_address=GroupAddress("1/2/3"))
         with self.assertRaises(CouldNotParseTelegram):
             telegram = Telegram(
-                group_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+                destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
             )
             self.loop.run_until_complete(remote_value.process(telegram))
         with self.assertRaises(CouldNotParseTelegram):
             telegram = Telegram(
-                group_address=GroupAddress("1/2/3"),
+                destination_address=GroupAddress("1/2/3"),
                 payload=DPTArray(
                     (
                         0x64,
diff --git a/test/remote_value_tests/remote_value_step_test.py b/test/remote_value_tests/remote_value_step_test.py
index 43a46f60..71bf7207 100644
--- a/test/remote_value_tests/remote_value_step_test.py
+++ b/test/remote_value_tests/remote_value_step_test.py
@@ -93,7 +93,9 @@ class TestRemoteValueStep(unittest.TestCase):
         """Test process telegram."""
         xknx = XKNX()
         remote_value = RemoteValueStep(xknx, group_address=GroupAddress("1/2/3"))
-        telegram = Telegram(group_address=GroupAddress("1/2/3"), payload=DPTBinary(0))
+        telegram = Telegram(
+            destination_address=GroupAddress("1/2/3"), payload=DPTBinary(0)
+        )
         self.assertEqual(remote_value.value, None)
         self.loop.run_until_complete(remote_value.process(telegram))
         self.assertEqual(remote_value.value, RemoteValueStep.Direction.DECREASE)
@@ -104,12 +106,12 @@ class TestRemoteValueStep(unittest.TestCase):
         remote_value = RemoteValueStep(xknx, group_address=GroupAddress("1/2/3"))
         with self.assertRaises(CouldNotParseTelegram):
             telegram = Telegram(
-                group_address=GroupAddress("1/2/3"), payload=DPTArray(0x01)
+                destination_address=GroupAddress("1/2/3"), payload=DPTArray(0x01)
             )
             self.loop.run_until_complete(remote_value.process(telegram))
         with self.assertRaises(CouldNotParseTelegram):
             telegram = Telegram(
-                group_address=GroupAddress("1/2/3"), payload=DPTBinary(3)
+                destination_address=GroupAddress("1/2/3"), payload=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 45057f8c..305cec59 100644
--- a/test/remote_value_tests/remote_value_string_test.py
+++ b/test/remote_value_tests/remote_value_string_test.py
@@ -112,7 +112,7 @@ class TestRemoteValueString(unittest.TestCase):
         xknx = XKNX()
         remote_value = RemoteValueString(xknx, group_address=GroupAddress("1/2/3"))
         telegram = Telegram(
-            group_address=GroupAddress("1/2/3"),
+            destination_address=GroupAddress("1/2/3"),
             payload=DPTArray(
                 (
                     0x41,
@@ -141,12 +141,12 @@ class TestRemoteValueString(unittest.TestCase):
         remote_value = RemoteValueString(xknx, group_address=GroupAddress("1/2/3"))
         with self.assertRaises(CouldNotParseTelegram):
             telegram = Telegram(
-                group_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+                destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
             )
             self.loop.run_until_complete(remote_value.process(telegram))
         with self.assertRaises(CouldNotParseTelegram):
             telegram = Telegram(
-                group_address=GroupAddress("1/2/3"),
+                destination_address=GroupAddress("1/2/3"),
                 payload=DPTArray(
                     (
                         0x64,
diff --git a/test/remote_value_tests/remote_value_switch_test.py b/test/remote_value_tests/remote_value_switch_test.py
index 13d409f3..ae16d07b 100644
--- a/test/remote_value_tests/remote_value_switch_test.py
+++ b/test/remote_value_tests/remote_value_switch_test.py
@@ -77,7 +77,9 @@ class TestRemoteValueSwitch(unittest.TestCase):
         """Test process telegram."""
         xknx = XKNX()
         remote_value = RemoteValueSwitch(xknx, group_address=GroupAddress("1/2/3"))
-        telegram = Telegram(group_address=GroupAddress("1/2/3"), payload=DPTBinary(1))
+        telegram = Telegram(
+            destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+        )
         self.assertEqual(remote_value.value, None)
         self.loop.run_until_complete(remote_value.process(telegram))
         self.assertIsNotNone(remote_value.payload)
@@ -87,7 +89,9 @@ class TestRemoteValueSwitch(unittest.TestCase):
         """Test process OFF telegram."""
         xknx = XKNX()
         remote_value = RemoteValueSwitch(xknx, group_address=GroupAddress("1/2/3"))
-        telegram = Telegram(group_address=GroupAddress("1/2/3"), payload=DPTBinary(0))
+        telegram = Telegram(
+            destination_address=GroupAddress("1/2/3"), payload=DPTBinary(0)
+        )
         self.assertEqual(remote_value.value, None)
         self.loop.run_until_complete(remote_value.process(telegram))
         self.assertIsNotNone(remote_value.payload)
@@ -99,12 +103,12 @@ class TestRemoteValueSwitch(unittest.TestCase):
         remote_value = RemoteValueSwitch(xknx, group_address=GroupAddress("1/2/3"))
         with self.assertRaises(CouldNotParseTelegram):
             telegram = Telegram(
-                group_address=GroupAddress("1/2/3"), payload=DPTArray(0x01)
+                destination_address=GroupAddress("1/2/3"), payload=DPTArray(0x01)
             )
             self.loop.run_until_complete(remote_value.process(telegram))
         with self.assertRaises(CouldNotParseTelegram):
             telegram = Telegram(
-                group_address=GroupAddress("1/2/3"), payload=DPTBinary(3)
+                destination_address=GroupAddress("1/2/3"), payload=DPTBinary(3)
             )
             self.loop.run_until_complete(remote_value.process(telegram))
             # pylint: disable=pointless-statement
diff --git a/test/remote_value_tests/remote_value_updown_test.py b/test/remote_value_tests/remote_value_updown_test.py
index 74653130..9898b5c8 100644
--- a/test/remote_value_tests/remote_value_updown_test.py
+++ b/test/remote_value_tests/remote_value_updown_test.py
@@ -93,7 +93,9 @@ class TestRemoteValueUpDown(unittest.TestCase):
         """Test process telegram."""
         xknx = XKNX()
         remote_value = RemoteValueUpDown(xknx, group_address=GroupAddress("1/2/3"))
-        telegram = Telegram(group_address=GroupAddress("1/2/3"), payload=DPTBinary(1))
+        telegram = Telegram(
+            destination_address=GroupAddress("1/2/3"), payload=DPTBinary(1)
+        )
         self.assertEqual(remote_value.value, None)
         self.loop.run_until_complete(remote_value.process(telegram))
         self.assertEqual(remote_value.value, RemoteValueUpDown.Direction.DOWN)
@@ -104,12 +106,12 @@ class TestRemoteValueUpDown(unittest.TestCase):
         remote_value = RemoteValueUpDown(xknx, group_address=GroupAddress("1/2/3"))
         with self.assertRaises(CouldNotParseTelegram):
             telegram = Telegram(
-                group_address=GroupAddress("1/2/3"), payload=DPTArray(0x01)
+                destination_address=GroupAddress("1/2/3"), payload=DPTArray(0x01)
             )
             self.loop.run_until_complete(remote_value.process(telegram))
         with self.assertRaises(CouldNotParseTelegram):
             telegram = Telegram(
-                group_address=GroupAddress("1/2/3"), payload=DPTBinary(3)
+                destination_address=GroupAddress("1/2/3"), payload=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 9efccd2a..539876cc 100644
--- a/test/str_test.py
+++ b/test/str_test.py
@@ -281,7 +281,7 @@ class TestStringRepresentations(unittest.TestCase):
         )
         # self.loop.run_until_complete(sensor.sensor_value.set(25))
         telegram = Telegram(
-            group_address=GroupAddress("1/2/3"),
+            destination_address=GroupAddress("1/2/3"),
             direction=TelegramDirection.INCOMING,
             payload=DPTArray(0x40),
         )
@@ -350,7 +350,7 @@ class TestStringRepresentations(unittest.TestCase):
         )
 
         telegram = Telegram(
-            group_address=GroupAddress("7/0/10"),
+            destination_address=GroupAddress("7/0/10"),
             direction=TelegramDirection.INCOMING,
             payload=DPTBinary(1),
         )
@@ -468,10 +468,12 @@ class TestStringRepresentations(unittest.TestCase):
 
     def test_telegram(self):
         """Test string representation of Telegram."""
-        telegram = Telegram(group_address=GroupAddress("1/2/3"), payload=DPTBinary(7))
+        telegram = Telegram(
+            destination_address=GroupAddress("1/2/3"), payload=DPTBinary(7)
+        )
         self.assertEqual(
             str(telegram),
-            '<Telegram group_address="GroupAddress("1/2/3")", payload="<DPTBinary value="7" />" telegramtype="TelegramType.GROUP_WRITE" direction='
+            '<Telegram destination_address="GroupAddress("1/2/3")", payload="<DPTBinary value="7" />" telegramtype="TelegramType.GROUP_WRITE" direction='
             '"TelegramDirection.OUTGOING" />',
         )
 
@@ -660,7 +662,7 @@ class TestStringRepresentations(unittest.TestCase):
         cemi_frame = CEMIFrame(xknx)
         cemi_frame.src_addr = GroupAddress("1/2/3")
         cemi_frame.telegram = Telegram(
-            group_address=GroupAddress("1/2/5"), payload=DPTBinary(7)
+            destination_address=GroupAddress("1/2/5"), payload=DPTBinary(7)
         )
         self.assertEqual(
             str(cemi_frame),