Repository: XKNX/xknx
Pull request #1092 (2022-11-29 12:55:59)

Add `respond_to_read` to ExposeSensor
<!--
  You are awesome! Thanks for contributing to our project!
  Please, DO NOT DELETE ANY TEXT from this template!.
-->
## Description
<!--
Please include a summary of the change and which issue is fixed.
Please also include relevant motivation and context.
List any dependencies that are required for this change.
-->
Add respond_to_read to ExposeSensor. Default to `True`

Fixes # (issue)

## Type of change
<!--
Please tick the applicable options.
NOTE: Ticking multiple options most likely indicates
that your change is to big and it is suggested to split it into several smaller PRs.
-->

- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] This change requires a documentation update

## Checklist:

- [ ] The documentation has been adjusted accordingly
- [x] Tests have been added that prove the fix is effective or that the feature works
- [x] The changes are documented in the changelog (docs/changelog.md)


Patch:
diff --git a/docs/changelog.md b/docs/changelog.md
index 6ca38d12..48e694f9 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -10,7 +10,7 @@ nav_order: 2
 
 ### Devices
 
-- Notification: Add `respond_to_read` option.
+- ExposeSensor and Notification: Add `respond_to_read` option.
 - Notification: Rename `self._message` to `self.remote_value`.
 
 # 2.0.0 Find and Connect 2022-11-25
diff --git a/xknx/devices/expose_sensor.py b/xknx/devices/expose_sensor.py
index f6b9e4f8..af7a90a5 100644
--- a/xknx/devices/expose_sensor.py
+++ b/xknx/devices/expose_sensor.py
@@ -37,12 +37,13 @@ class ExposeSensor(Device):
         xknx: XKNX,
         name: str,
         group_address: GroupAddressesType | None = None,
+        respond_to_read: bool = True,
         value_type: int | str | None = None,
         device_updated_cb: DeviceCallbackType[ExposeSensor] | None = None,
     ):
         """Initialize Sensor class."""
         super().__init__(xknx, name, device_updated_cb)
-
+        self.respond_to_read = respond_to_read
         self.sensor_value: RemoteValueSensor | RemoteValueSwitch
         if value_type == "binary":
             self.sensor_value = RemoteValueSwitch(
@@ -66,13 +67,14 @@ class ExposeSensor(Device):
         """Iterate the devices RemoteValue classes."""
         yield self.sensor_value
 
-    async def process_group_write(self, telegram: "Telegram") -> None:
+    async def process_group_write(self, telegram: Telegram) -> None:
         """Process incoming and outgoing GROUP WRITE telegram."""
         await self.sensor_value.process(telegram)
 
-    async def process_group_read(self, telegram: "Telegram") -> None:
+    async def process_group_read(self, telegram: Telegram) -> None:
         """Process incoming GROUP READ telegram."""
-        await self.sensor_value.respond()
+        if self.respond_to_read:
+            await self.sensor_value.respond()
 
     async def set(self, value: Any) -> None:
         """Set new value."""
@@ -91,6 +93,6 @@ class ExposeSensor(Device):
         return (
             f'<ExposeSensor name="{self.name}" '
             f"sensor={self.sensor_value.group_addr_str()} "
-            f"value={self.resolve_state().__repr__()} "
+            f"value={repr(self.sensor_value.value)} "
             f'unit="{self.unit_of_measurement()}"/>'
         )


Test patch:
diff --git a/test/devices_tests/expose_sensor_test.py b/test/devices_tests/expose_sensor_test.py
index 04a4585e..49323bcf 100644
--- a/test/devices_tests/expose_sensor_test.py
+++ b/test/devices_tests/expose_sensor_test.py
@@ -119,13 +119,7 @@ class TestExposeSensor:
         expose_sensor = ExposeSensor(
             xknx, "TestSensor", value_type="binary", group_address="1/2/3"
         )
-
-        await expose_sensor.process(
-            Telegram(
-                destination_address=GroupAddress("1/2/3"),
-                payload=GroupValueWrite(DPTBinary(True)),
-            )
-        )
+        expose_sensor.sensor_value.value = True
 
         telegram = Telegram(GroupAddress("1/2/3"), payload=GroupValueRead())
         await expose_sensor.process(telegram)
@@ -165,13 +159,7 @@ class TestExposeSensor:
         expose_sensor = ExposeSensor(
             xknx, "TestSensor", value_type="temperature", group_address="1/2/3"
         )
-
-        await expose_sensor.process(
-            Telegram(
-                destination_address=GroupAddress("1/2/3"),
-                payload=GroupValueWrite(DPTArray((0x0C, 0x1A))),
-            )
-        )
+        expose_sensor.sensor_value.value = 21.0
 
         telegram = Telegram(GroupAddress("1/2/3"), payload=GroupValueRead())
         await expose_sensor.process(telegram)
@@ -182,6 +170,22 @@ class TestExposeSensor:
             payload=GroupValueResponse(DPTArray((0x0C, 0x1A))),
         )
 
+    async def test_process_no_respond_to_read(self):
+        """Test expose sensor with respond_to_read set to False."""
+        xknx = XKNX()
+        expose_sensor = ExposeSensor(
+            xknx,
+            "TestSensor",
+            value_type="temperature",
+            group_address="1/2/3",
+            respond_to_read=False,
+        )
+        expose_sensor.sensor_value.value = 21.0
+
+        telegram = Telegram(GroupAddress("1/2/3"), payload=GroupValueRead())
+        await expose_sensor.process(telegram)
+        assert xknx.telegrams.qsize() == 0
+
     #
     # HAS GROUP ADDRESS
     #