Esempio n. 1
0
    async def test_respond_to_read(self):
        """Test respond_to_read function."""
        xknx = XKNX()
        responding = NumericValue(
            xknx,
            "TestSensor1",
            group_address="1/1/1",
            respond_to_read=True,
            value_type="volume_liquid_litre",
        )
        non_responding = NumericValue(
            xknx,
            "TestSensor2",
            group_address="1/1/1",
            respond_to_read=False,
            value_type="volume_liquid_litre",
        )
        responding_multiple = NumericValue(
            xknx,
            "TestSensor3",
            group_address=["1/1/1", "3/3/3"],
            group_address_state="2/2/2",
            respond_to_read=True,
            value_type="volume_liquid_litre",
        )
        #  set initial payload of NumericValue
        responding.sensor_value.value = 256
        non_responding.sensor_value.value = 256
        responding_multiple.sensor_value.value = 256

        read_telegram = Telegram(destination_address=GroupAddress("1/1/1"),
                                 payload=GroupValueRead())
        # verify no response when respond is False
        await non_responding.process(read_telegram)
        assert xknx.telegrams.qsize() == 0

        # verify response when respond is True
        await responding.process(read_telegram)
        assert xknx.telegrams.qsize() == 1
        response = xknx.telegrams.get_nowait()
        assert response == Telegram(
            destination_address=GroupAddress("1/1/1"),
            payload=GroupValueResponse(DPTArray((0x00, 0x00, 0x01, 0x00))),
        )
        # verify no response when GroupValueRead request is not for group_address
        await responding_multiple.process(read_telegram)
        assert xknx.telegrams.qsize() == 1
        response = xknx.telegrams.get_nowait()
        assert response == Telegram(
            destination_address=GroupAddress("1/1/1"),
            payload=GroupValueResponse(DPTArray((0x00, 0x00, 0x01, 0x00))),
        )
        await responding_multiple.process(
            Telegram(destination_address=GroupAddress("2/2/2"),
                     payload=GroupValueRead()))
        await responding_multiple.process(
            Telegram(destination_address=GroupAddress("3/3/3"),
                     payload=GroupValueRead()))
        assert xknx.telegrams.qsize() == 0
Esempio n. 2
0
    async def test_respond_to_read(self):
        """Test respond_to_read function."""
        xknx = XKNX()
        responding = Switch(
            xknx,
            "TestSensor1",
            group_address="1/1/1",
            respond_to_read=True,
        )
        non_responding = Switch(
            xknx,
            "TestSensor2",
            group_address="1/1/1",
            respond_to_read=False,
        )
        responding_multiple = Switch(
            xknx,
            "TestSensor3",
            group_address=["1/1/1", "3/3/3"],
            group_address_state="2/2/2",
            respond_to_read=True,
        )
        #  set initial payload of Switch
        responding.switch.value = True
        non_responding.switch.value = True
        responding_multiple.switch.value = True

        read_telegram = Telegram(destination_address=GroupAddress("1/1/1"),
                                 payload=GroupValueRead())
        # verify no response when respond is False
        await non_responding.process(read_telegram)
        assert xknx.telegrams.qsize() == 0

        # verify response when respond is True
        await responding.process(read_telegram)
        assert xknx.telegrams.qsize() == 1
        response = xknx.telegrams.get_nowait()
        assert response == Telegram(
            destination_address=GroupAddress("1/1/1"),
            payload=GroupValueResponse(DPTBinary(True)),
        )
        # verify no response when GroupValueRead request is not for group_address
        await responding_multiple.process(read_telegram)
        assert xknx.telegrams.qsize() == 1
        response = xknx.telegrams.get_nowait()
        assert response == Telegram(
            destination_address=GroupAddress("1/1/1"),
            payload=GroupValueResponse(DPTBinary(True)),
        )
        await responding_multiple.process(
            Telegram(destination_address=GroupAddress("2/2/2"),
                     payload=GroupValueRead()))
        await responding_multiple.process(
            Telegram(destination_address=GroupAddress("3/3/3"),
                     payload=GroupValueRead()))
        assert xknx.telegrams.qsize() == 0
Esempio n. 3
0
    async def test_process_state(self):
        """Test process / reading telegrams from telegram queue. Test if device was updated."""
        xknx = XKNX()
        callback_mock = AsyncMock()

        switch1 = Switch(
            xknx,
            "TestOutlet",
            group_address="1/2/3",
            group_address_state="1/2/4",
            device_updated_cb=callback_mock,
        )
        switch2 = Switch(
            xknx,
            "TestOutlet",
            group_address="1/2/3",
            group_address_state="1/2/4",
            device_updated_cb=callback_mock,
        )
        assert switch1.state is None
        assert switch2.state is None
        callback_mock.assert_not_called()

        telegram_on = Telegram(
            destination_address=GroupAddress("1/2/4"),
            payload=GroupValueResponse(DPTBinary(1)),
        )
        telegram_off = Telegram(
            destination_address=GroupAddress("1/2/4"),
            payload=GroupValueResponse(DPTBinary(0)),
        )

        await switch1.process(telegram_on)
        assert switch1.state is True
        callback_mock.assert_called_once()
        callback_mock.reset_mock()
        await switch1.process(telegram_off)
        assert switch1.state is False
        callback_mock.assert_called_once()
        callback_mock.reset_mock()
        # test setting switch2 to False with first telegram
        await switch2.process(telegram_off)
        assert switch2.state is False
        callback_mock.assert_called_once()
        callback_mock.reset_mock()
        await switch2.process(telegram_on)
        assert switch2.state is True
        callback_mock.assert_called_once()
        callback_mock.reset_mock()
Esempio n. 4
0
    async def test_always_callback_sensor(self):
        """Test always callback sensor."""
        xknx = XKNX()
        sensor = Sensor(
            xknx,
            "TestSensor",
            group_address_state="1/2/3",
            always_callback=False,
            value_type="volume_liquid_litre",
        )
        after_update_callback = AsyncMock()
        sensor.register_device_updated_cb(after_update_callback)
        payload = DPTArray((0x00, 0x00, 0x01, 0x00))
        #  set initial payload of sensor
        sensor.sensor_value.value = 256
        telegram = Telegram(destination_address=GroupAddress("1/2/3"),
                            payload=GroupValueWrite(payload))
        response_telegram = Telegram(
            destination_address=GroupAddress("1/2/3"),
            payload=GroupValueResponse(payload),
        )
        # verify not called when always_callback is False
        await sensor.process(telegram)
        after_update_callback.assert_not_called()
        after_update_callback.reset_mock()

        sensor.always_callback = True
        # verify called when always_callback is True
        await sensor.process(telegram)
        after_update_callback.assert_called_once()
        after_update_callback.reset_mock()

        # verify not called when processing read responses
        await sensor.process(response_telegram)
        after_update_callback.assert_not_called()
Esempio n. 5
0
    async def test_process(self):
        """Test if telegram is handled by the correct process_* method."""
        xknx = XKNX()
        device = Device(xknx, "TestDevice")

        with patch("xknx.devices.Device.process_group_read",
                   new_callable=AsyncMock) as mock_group_read:
            telegram = Telegram(destination_address=GroupAddress("1/2/1"),
                                payload=GroupValueRead())
            await device.process(telegram)
            mock_group_read.assert_called_with(telegram)

        with patch("xknx.devices.Device.process_group_write",
                   new_callable=AsyncMock) as mock_group_write:
            telegram = Telegram(
                destination_address=GroupAddress("1/2/1"),
                payload=GroupValueWrite(DPTArray((0x01, 0x02))),
            )
            await device.process(telegram)
            mock_group_write.assert_called_with(telegram)

        with patch("xknx.devices.Device.process_group_response",
                   new_callable=AsyncMock) as mock_group_response:
            telegram = Telegram(
                destination_address=GroupAddress("1/2/1"),
                payload=GroupValueResponse(DPTArray((0x01, 0x02))),
            )
            await device.process(telegram)
            mock_group_response.assert_called_with(telegram)
Esempio n. 6
0
    async def service_send_to_knx_bus(self, call: ServiceCall) -> None:
        """Service for sending an arbitrary KNX message to the KNX bus."""
        attr_address = call.data[KNX_ADDRESS]
        attr_payload = call.data[SERVICE_KNX_ATTR_PAYLOAD]
        attr_type = call.data.get(SERVICE_KNX_ATTR_TYPE)
        attr_response = call.data[SERVICE_KNX_ATTR_RESPONSE]

        payload: DPTBinary | DPTArray
        if attr_type is not None:
            transcoder = DPTBase.parse_transcoder(attr_type)
            if transcoder is None:
                raise ValueError(
                    f"Invalid type for knx.send service: {attr_type}")
            payload = DPTArray(transcoder.to_knx(attr_payload))
        elif isinstance(attr_payload, int):
            payload = DPTBinary(attr_payload)
        else:
            payload = DPTArray(attr_payload)

        for address in attr_address:
            telegram = Telegram(
                destination_address=parse_device_group_address(address),
                payload=GroupValueResponse(payload)
                if attr_response else GroupValueWrite(payload),
            )
            await self.xknx.telegrams.put(telegram)
Esempio n. 7
0
    def test_EndTOEnd_group_response(self):
        """Test parsing and streaming CEMIFrame KNX/IP packet, group response."""
        # Incoming state
        raw = bytes.fromhex("0610053000112900BCD013010188010041")
        xknx = XKNX()
        knxipframe = KNXIPFrame(xknx)
        knxipframe.from_knx(raw)
        telegram = knxipframe.body.cemi.telegram
        self.assertEqual(
            telegram,
            Telegram(
                destination_address=GroupAddress("392"),
                payload=GroupValueResponse(DPTBinary(1)),
                source_address=IndividualAddress("1.3.1"),
            ),
        )

        cemi = CEMIFrame(xknx, src_addr=IndividualAddress("1.3.1"))
        cemi.telegram = telegram
        cemi.set_hops(5)
        routing_indication = RoutingIndication(xknx, cemi=cemi)
        knxipframe2 = KNXIPFrame.init_from_body(routing_indication)

        self.assertEqual(knxipframe2.header.to_knx(), list(raw[0:6]))
        self.assertEqual(knxipframe2.body.to_knx(), list(raw[6:]))
        self.assertEqual(knxipframe2.to_knx(), list(raw))
Esempio n. 8
0
    def test_process_read(self):
        """Test test process a read telegram from KNX bus."""
        xknx = XKNX()
        datetime = DateTime(xknx,
                            "TestDateTime",
                            group_address="1/2/3",
                            broadcast_type="TIME")

        telegram_read = Telegram(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])
            self.loop.run_until_complete(datetime.process(telegram_read))

        # initial Telegram from broadcasting on init
        self.assertEqual(xknx.telegrams.qsize(), 2)
        _throwaway_initial = xknx.telegrams.get_nowait()

        telegram = xknx.telegrams.get_nowait()
        self.assertEqual(
            telegram,
            Telegram(
                destination_address=GroupAddress("1/2/3"),
                payload=GroupValueResponse(DPTArray((0xE9, 0xD, 0xE))),
            ),
        )
Esempio n. 9
0
    async def test_process_group_value_response(self):
        """Test precess of GroupValueResponse telegrams."""
        xknx = XKNX()
        switch = BinarySensor(
            xknx,
            "TestInput",
            group_address_state="1/2/3",
            ignore_internal_state=True,
        )
        async_after_update_callback = AsyncMock()

        switch.register_device_updated_cb(async_after_update_callback)

        write_telegram = Telegram(
            destination_address=GroupAddress("1/2/3"),
            payload=GroupValueWrite(DPTBinary(1)),
        )
        response_telegram = Telegram(
            destination_address=GroupAddress("1/2/3"),
            payload=GroupValueResponse(DPTBinary(1), ),
        )
        assert switch.state is None
        # initial GroupValueResponse changes state and runs callback
        await switch.process(response_telegram)
        assert switch.state
        async_after_update_callback.assert_called_once_with(switch)
        # GroupValueWrite with same payload runs callback because of `ignore_internal_state`
        async_after_update_callback.reset_mock()
        await switch.process(write_telegram)
        assert switch.state
        async_after_update_callback.assert_called_once_with(switch)
        # GroupValueResponse should not run callback when state has not changed
        async_after_update_callback.reset_mock()
        await switch.process(response_telegram)
        async_after_update_callback.assert_not_called()
Esempio n. 10
0
    def test_value_reader_telegram_received(self):
        """Test value reader: telegram_received."""
        xknx = XKNX()
        test_group_address = GroupAddress("0/0/0")
        expected_telegram_1 = Telegram(
            destination_address=test_group_address,
            direction=TelegramDirection.INCOMING,
            payload=GroupValueResponse(DPTBinary(1)),
        )
        expected_telegram_2 = Telegram(
            destination_address=test_group_address,
            direction=TelegramDirection.INCOMING,
            payload=GroupValueWrite(DPTBinary(1)),
        )
        telegram_wrong_address = Telegram(
            destination_address=GroupAddress("0/0/1"),
            direction=TelegramDirection.INCOMING,
            payload=GroupValueResponse(DPTBinary(1)),
        )
        telegram_wrong_type = Telegram(
            destination_address=test_group_address,
            direction=TelegramDirection.INCOMING,
            payload=GroupValueRead(),
        )

        value_reader = ValueReader(xknx, test_group_address)

        def async_telegram_received(test_telegram):
            return self.loop.run_until_complete(
                value_reader.telegram_received(test_telegram)
            )

        async_telegram_received(telegram_wrong_address)
        self.assertIsNone(value_reader.received_telegram)
        self.assertFalse(value_reader.success)

        async_telegram_received(telegram_wrong_type)
        self.assertIsNone(value_reader.received_telegram)
        self.assertFalse(value_reader.success)

        async_telegram_received(expected_telegram_1)
        self.assertEqual(value_reader.received_telegram, expected_telegram_1)
        self.assertTrue(value_reader.success)

        async_telegram_received(expected_telegram_2)
        self.assertEqual(value_reader.received_telegram, expected_telegram_2)
        self.assertTrue(value_reader.success)
Esempio n. 11
0
    async def test_array_sensor_loop(self, value_type, test_payload, test_value):
        """Test sensor and expose_sensor with different values."""
        xknx = XKNX()
        xknx.knxip_interface = AsyncMock()
        xknx.rate_limit = False
        await xknx.telegram_queue.start()

        expose = ExposeSensor(
            xknx,
            "TestExpose",
            group_address="1/1/1",
            value_type=value_type,
        )
        assert expose.resolve_state() is None
        # set a value from expose - HA sends strings for new values
        stringified_value = str(test_value)
        await expose.set(stringified_value)

        outgoing_telegram = Telegram(
            destination_address=GroupAddress("1/1/1"),
            direction=TelegramDirection.OUTGOING,
            payload=GroupValueWrite(test_payload),
        )
        await xknx.telegrams.join()
        xknx.knxip_interface.send_telegram.assert_called_with(outgoing_telegram)
        assert expose.resolve_state() == test_value

        # init sensor after expose is set - with same group address
        sensor = Sensor(
            xknx,
            "TestSensor",
            group_address_state="1/1/1",
            value_type=value_type,
        )
        assert sensor.resolve_state() is None

        # read sensor state (from expose as it has the same GA)
        # wait_for_result so we don't have to await self.xknx.telegrams.join()
        await sensor.sync(wait_for_result=True)
        read_telegram = Telegram(
            destination_address=GroupAddress("1/1/1"),
            direction=TelegramDirection.OUTGOING,
            payload=GroupValueRead(),
        )
        response_telegram = Telegram(
            destination_address=GroupAddress("1/1/1"),
            direction=TelegramDirection.OUTGOING,
            payload=GroupValueResponse(test_payload),
        )
        xknx.knxip_interface.send_telegram.assert_has_calls(
            [
                call(read_telegram),
                call(response_telegram),
            ]
        )
        # test if Sensor has successfully read from ExposeSensor
        assert sensor.resolve_state() == test_value
        assert expose.resolve_state() == sensor.resolve_state()
        await xknx.telegram_queue.stop()
Esempio n. 12
0
    async def test_value_reader_telegram_received(self):
        """Test value reader: telegram_received."""
        xknx = XKNX()
        test_group_address = GroupAddress("0/0/0")
        expected_telegram_1 = Telegram(
            destination_address=test_group_address,
            direction=TelegramDirection.INCOMING,
            payload=GroupValueResponse(DPTBinary(1)),
        )
        expected_telegram_2 = Telegram(
            destination_address=test_group_address,
            direction=TelegramDirection.INCOMING,
            payload=GroupValueWrite(DPTBinary(1)),
        )
        telegram_wrong_address = Telegram(
            destination_address=GroupAddress("0/0/1"),
            direction=TelegramDirection.INCOMING,
            payload=GroupValueResponse(DPTBinary(1)),
        )
        telegram_wrong_type = Telegram(
            destination_address=test_group_address,
            direction=TelegramDirection.INCOMING,
            payload=GroupValueRead(),
        )

        value_reader = ValueReader(xknx, test_group_address)

        await value_reader.telegram_received(telegram_wrong_address)
        assert value_reader.received_telegram is None
        assert not value_reader.response_received_event.is_set()

        await value_reader.telegram_received(telegram_wrong_type)
        assert value_reader.received_telegram is None
        assert not value_reader.response_received_event.is_set()

        await value_reader.telegram_received(expected_telegram_1)
        assert value_reader.received_telegram == expected_telegram_1
        assert value_reader.response_received_event.is_set()

        await value_reader.telegram_received(expected_telegram_2)
        assert value_reader.received_telegram == expected_telegram_2
        assert value_reader.response_received_event.is_set()
Esempio n. 13
0
 async def _send(self,
                 payload: "DPTPayload",
                 response: bool = False) -> None:
     """Send payload as telegram to KNX bus."""
     if self.group_address is not None:
         telegram = Telegram(
             destination_address=self.group_address,
             payload=(GroupValueResponse(payload)
                      if response else GroupValueWrite(payload)),
         )
         await self.xknx.telegrams.put(telegram)
Esempio n. 14
0
    def test_process_temperature(self):
        """Test reading temperature expose sensor from bus."""
        xknx = XKNX()
        expose_sensor = ExposeSensor(
            xknx, "TestSensor", value_type="temperature", group_address="1/2/3"
        )
        expose_sensor.sensor_value.payload = DPTArray((0x0C, 0x1A))

        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()
        self.assertEqual(
            telegram,
            Telegram(
                destination_address=GroupAddress("1/2/3"),
                payload=GroupValueResponse(DPTArray((0x0C, 0x1A))),
            ),
        )
Esempio n. 15
0
    async def test_process_read(self):
        """Test test process a read telegram from KNX bus."""
        xknx = XKNX()
        self.datetime = DateTime(xknx,
                                 "TestDateTime",
                                 group_address="1/2/3",
                                 broadcast_type="TIME")

        telegram_read = Telegram(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])
            await self.datetime.process(telegram_read)

        telegram = xknx.telegrams.get_nowait()
        assert telegram == Telegram(
            destination_address=GroupAddress("1/2/3"),
            payload=GroupValueResponse(DPTArray((0xE9, 0xD, 0xE))),
        )
Esempio n. 16
0
    def test_process_reset_after_cancel_existing(self):
        """Test process reset_after cancels existing reset tasks."""
        xknx = XKNX()
        reset_after_sec = 0.01
        switch = Switch(
            xknx, "TestInput", group_address="1/2/3", reset_after=reset_after_sec
        )
        telegram_on = Telegram(
            destination_address=GroupAddress("1/2/3"),
            payload=GroupValueResponse(DPTBinary(1)),
        )

        self.loop.run_until_complete(switch.process(telegram_on))
        self.assertTrue(switch.state)
        self.assertEqual(xknx.telegrams.qsize(), 0)
        self.loop.run_until_complete(asyncio.sleep(reset_after_sec / 2))
        # half way through the reset timer
        self.loop.run_until_complete(switch.process(telegram_on))
        self.assertTrue(switch.state)

        self.loop.run_until_complete(asyncio.sleep(reset_after_sec / 2))
        self.assertEqual(xknx.telegrams.qsize(), 0)
Esempio n. 17
0
    async def test_process_temperature(self):
        """Test reading temperature expose sensor from bus."""
        xknx = XKNX()
        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))),
            ))

        telegram = Telegram(GroupAddress("1/2/3"), payload=GroupValueRead())
        await expose_sensor.process(telegram)
        assert xknx.telegrams.qsize() == 1
        telegram = xknx.telegrams.get_nowait()
        assert telegram == Telegram(
            destination_address=GroupAddress("1/2/3"),
            payload=GroupValueResponse(DPTArray((0x0C, 0x1A))),
        )
Esempio n. 18
0
    async def test_process_binary(self):
        """Test reading binary expose sensor from bus."""
        xknx = XKNX()
        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)),
            ))

        telegram = Telegram(GroupAddress("1/2/3"), payload=GroupValueRead())
        await expose_sensor.process(telegram)
        assert xknx.telegrams.qsize() == 1
        telegram = xknx.telegrams.get_nowait()
        assert telegram == Telegram(
            destination_address=GroupAddress("1/2/3"),
            payload=GroupValueResponse(DPTBinary(True)),
        )
Esempio n. 19
0
    async def test_process_reset_after_cancel_existing(self, time_travel):
        """Test process reset_after cancels existing reset tasks."""
        xknx = XKNX()
        reset_after_sec = 0.01
        switch = Switch(xknx,
                        "TestInput",
                        group_address="1/2/3",
                        reset_after=reset_after_sec)
        telegram_on = Telegram(
            destination_address=GroupAddress("1/2/3"),
            payload=GroupValueResponse(DPTBinary(1)),
        )

        await switch.process(telegram_on)
        assert switch.state
        assert xknx.telegrams.qsize() == 0
        await time_travel(reset_after_sec / 2)
        # half way through the reset timer
        await switch.process(telegram_on)
        assert switch.state

        await time_travel(reset_after_sec / 2)
        assert xknx.telegrams.qsize() == 0
Esempio n. 20
0
    def test_end_to_end_group_response(self):
        """Test parsing and streaming CEMIFrame KNX/IP packet, group response."""
        # Incoming state
        raw = bytes.fromhex(
            "06 10 05 30 00 11 29 00 bc d0 13 01 01 88 01 00 41")
        knxipframe = KNXIPFrame()
        knxipframe.from_knx(raw)
        telegram = knxipframe.body.cemi.telegram
        assert telegram == Telegram(
            destination_address=GroupAddress("392"),
            payload=GroupValueResponse(DPTBinary(1)),
            source_address=IndividualAddress("1.3.1"),
        )

        cemi = CEMIFrame(src_addr=IndividualAddress("1.3.1"))
        cemi.telegram = telegram
        cemi.set_hops(5)
        routing_indication = RoutingIndication(cemi=cemi)
        knxipframe2 = KNXIPFrame.init_from_body(routing_indication)

        assert knxipframe2.header.to_knx() == raw[0:6]
        assert knxipframe2.body.to_knx() == raw[6:]
        assert knxipframe2.to_knx() == raw
Esempio n. 21
0
    def test_value_reader_read_success(self):
        """Test value reader: successfull read."""
        xknx = XKNX()
        test_group_address = GroupAddress("0/0/0")
        response_telegram = Telegram(
            destination_address=test_group_address,
            direction=TelegramDirection.INCOMING,
            payload=GroupValueResponse(DPTBinary(1)),
        )

        value_reader = ValueReader(xknx, test_group_address)
        # receive the response
        self.loop.run_until_complete(value_reader.telegram_received(response_telegram))
        # and yield the result
        successfull_read = self.loop.run_until_complete(value_reader.read())

        # GroupValueRead telegram is still in the queue because we are not actually processing it
        self.assertEqual(xknx.telegrams.qsize(), 1)
        # Callback was removed again
        self.assertEqual(xknx.telegram_queue.telegram_received_cbs, [])
        # Telegram was received
        self.assertEqual(value_reader.received_telegram, response_telegram)
        # Successfull read() returns the telegram
        self.assertEqual(successfull_read, response_telegram)
Esempio n. 22
0
    async def test_value_reader_read_success(self):
        """Test value reader: successfull read."""
        xknx = XKNX()
        test_group_address = GroupAddress("0/0/0")
        response_telegram = Telegram(
            destination_address=test_group_address,
            direction=TelegramDirection.INCOMING,
            payload=GroupValueResponse(DPTBinary(1)),
        )

        value_reader = ValueReader(xknx, test_group_address)
        # receive the response
        await value_reader.telegram_received(response_telegram)
        # and yield the result
        successfull_read = await value_reader.read()

        # GroupValueRead telegram is still in the queue because we are not actually processing it
        assert xknx.telegrams.qsize() == 1
        # Callback was removed again
        assert not xknx.telegram_queue.telegram_received_cbs
        # Telegram was received
        assert value_reader.received_telegram == response_telegram
        # Successfull read() returns the telegram
        assert successfull_read == response_telegram
Esempio n. 23
0
    def test_process(self):
        """Test if telegram is handled by the correct process_* method."""
        xknx = XKNX()
        device = Device(xknx, "TestDevice")

        with patch("xknx.devices.Device.process_group_read") as mock_group_read:
            fut = asyncio.Future()
            fut.set_result(None)
            mock_group_read.return_value = fut
            telegram = Telegram(
                destination_address=GroupAddress("1/2/1"), payload=GroupValueRead()
            )
            self.loop.run_until_complete(device.process(telegram))
            mock_group_read.assert_called_with(telegram)

        with patch("xknx.devices.Device.process_group_write") as mock_group_write:
            fut = asyncio.Future()
            fut.set_result(None)
            mock_group_write.return_value = fut
            telegram = Telegram(
                destination_address=GroupAddress("1/2/1"),
                payload=GroupValueWrite(DPTArray((0x01, 0x02))),
            )
            self.loop.run_until_complete(device.process(telegram))
            mock_group_write.assert_called_with(telegram)

        with patch("xknx.devices.Device.process_group_response") as mock_group_response:
            fut = asyncio.Future()
            fut.set_result(None)
            mock_group_response.return_value = fut
            telegram = Telegram(
                destination_address=GroupAddress("1/2/1"),
                payload=GroupValueResponse(DPTArray((0x01, 0x02))),
            )
            self.loop.run_until_complete(device.process(telegram))
            mock_group_response.assert_called_with(telegram)
Esempio n. 24
0
    async def test_binary_sensor_loop(self, value_type, test_payload, test_value):
        """Test binary_sensor and expose_sensor with binary values."""
        xknx = XKNX()
        xknx.knxip_interface = AsyncMock()
        xknx.rate_limit = False

        telegram_callback = AsyncMock()
        xknx.telegram_queue.register_telegram_received_cb(
            telegram_callback,
            address_filters=[AddressFilter("i-test")],
            match_for_outgoing=True,
        )
        await xknx.telegram_queue.start()

        expose = ExposeSensor(
            xknx,
            "TestExpose",
            group_address="i-test",
            value_type=value_type,
        )
        assert expose.resolve_state() is None

        await expose.set(test_value)
        await xknx.telegrams.join()
        outgoing_telegram = Telegram(
            destination_address=InternalGroupAddress("i-test"),
            direction=TelegramDirection.OUTGOING,
            payload=GroupValueWrite(test_payload),
        )
        # InternalGroupAddress isn't passed to knxip_interface
        xknx.knxip_interface.send_telegram.assert_not_called()
        telegram_callback.assert_called_with(outgoing_telegram)
        assert expose.resolve_state() == test_value

        bin_sensor = BinarySensor(xknx, "TestSensor", group_address_state="i-test")
        assert bin_sensor.state is None

        # read sensor state (from expose as it has the same GA)
        # wait_for_result so we don't have to await self.xknx.telegrams.join()
        await bin_sensor.sync(wait_for_result=True)
        read_telegram = Telegram(
            destination_address=InternalGroupAddress("i-test"),
            direction=TelegramDirection.OUTGOING,
            payload=GroupValueRead(),
        )
        response_telegram = Telegram(
            destination_address=InternalGroupAddress("i-test"),
            direction=TelegramDirection.OUTGOING,
            payload=GroupValueResponse(test_payload),
        )
        xknx.knxip_interface.send_telegram.assert_not_called()
        telegram_callback.assert_has_calls(
            [
                call(read_telegram),
                call(response_telegram),
            ]
        )
        # test if Sensor has successfully read from ExposeSensor
        assert bin_sensor.state == test_value
        assert expose.resolve_state() == bin_sensor.state
        await xknx.telegram_queue.stop()
Esempio n. 25
0
 async def receive_response(self, group_address: str,
                            payload: int | tuple[int, ...]) -> None:
     """Inject incoming GroupValueResponse telegram."""
     payload_value = self._payload_value(payload)
     await self._receive_telegram(group_address,
                                  GroupValueResponse(payload_value))