示例#1
0
async def main():
    """Search for a Tunnelling device, walk through all possible channels and disconnect them."""
    xknx = XKNX()
    gatewayscanner = GatewayScanner(xknx)
    gateways = await gatewayscanner.scan()

    if not gateways:
        print("No Gateways found")
        return

    gateway = gateways[0]

    if not gateway.supports_tunnelling:
        print("Gateway does not support tunneling")
        return

    udp_client = UDPClient(xknx, (gateway.local_ip, 0), (gateway.ip_addr, gateway.port))

    await udp_client.connect()

    for i in range(0, 255):

        conn_state = ConnectionState(xknx, udp_client, communication_channel_id=i)

        await conn_state.start()

        if conn_state.success:
            print("Disconnecting ", i)
            disconnect = Disconnect(xknx, udp_client, communication_channel_id=i)

            await disconnect.start()

            if disconnect.success:
                print("Disconnected ", i)
示例#2
0
    def test_tunnelling(self):
        """Test tunnelling from KNX bus."""
        # pylint: disable=too-many-locals
        xknx = XKNX(loop=self.loop)
        communication_channel_id = 23
        udp_client = UDPClient(xknx, ("192.168.1.1", 0), ("192.168.1.2", 1234))
        telegram = Telegram(GroupAddress('1/2/3'),
                            payload=DPTArray((0x1, 0x2, 0x3)))
        sequence_counter = 42
        src_address = PhysicalAddress('2.2.2')
        tunnelling = Tunnelling(xknx, udp_client, telegram, src_address,
                                sequence_counter, communication_channel_id)
        tunnelling.timeout_in_seconds = 0

        self.assertEqual(tunnelling.awaited_response_class, TunnellingAck)
        self.assertEqual(tunnelling.communication_channel_id,
                         communication_channel_id)

        # Expected KNX/IP-Frame:
        exp_knxipframe = KNXIPFrame(xknx)
        exp_knxipframe.init(KNXIPServiceType.TUNNELLING_REQUEST)
        exp_knxipframe.body.cemi.telegram = telegram
        exp_knxipframe.body.cemi.src_addr = src_address
        exp_knxipframe.body.communication_channel_id = communication_channel_id
        exp_knxipframe.body.sequence_counter = sequence_counter
        exp_knxipframe.normalize()
        print(exp_knxipframe)
        with patch('xknx.io.UDPClient.send') as mock_udp_send, \
                patch('xknx.io.UDPClient.getsockname') as mock_udp_getsockname:
            mock_udp_getsockname.return_value = ("192.168.1.3", 4321)
            self.loop.run_until_complete(asyncio.Task(tunnelling.start()))
            mock_udp_send.assert_called_with(exp_knxipframe)

        # Response KNX/IP-Frame with wrong type
        wrong_knxipframe = KNXIPFrame(xknx)
        wrong_knxipframe.init(KNXIPServiceType.CONNECTIONSTATE_REQUEST)
        with patch('logging.Logger.warning') as mock_warning:
            tunnelling.response_rec_callback(wrong_knxipframe, None)
            mock_warning.assert_called_with('Cant understand knxipframe')

        # Response KNX/IP-Frame with error:
        err_knxipframe = KNXIPFrame(xknx)
        err_knxipframe.init(KNXIPServiceType.TUNNELLING_ACK)
        err_knxipframe.body.status_code = ErrorCode.E_CONNECTION_ID
        with patch('logging.Logger.warning') as mock_warning:
            tunnelling.response_rec_callback(err_knxipframe, None)
            mock_warning.assert_called_with(
                "Error: KNX bus responded to request of type '%s' with error in '%s': %s",
                type(tunnelling).__name__,
                type(err_knxipframe.body).__name__, ErrorCode.E_CONNECTION_ID)

        # Correct Response KNX/IP-Frame:
        res_knxipframe = KNXIPFrame(xknx)
        res_knxipframe.init(KNXIPServiceType.TUNNELLING_ACK)
        with patch('logging.Logger.debug') as mock_debug:
            tunnelling.response_rec_callback(res_knxipframe, None)
            mock_debug.assert_called_with(
                'Success: received correct answer from KNX bus: %s',
                ErrorCode.E_NO_ERROR)
            self.assertTrue(tunnelling.success)
示例#3
0
    def test_create_knxipframe_err(self):
        """Test if create_knxipframe of base class raises an exception."""
        xknx = XKNX(loop=self.loop)
        udp_client = UDPClient(xknx, ("192.168.1.1", 0), ("192.168.1.2", 1234))
        request_response = RequestResponse(xknx, udp_client, DisconnectResponse)
        request_response.timeout_in_seconds = 0

        with self.assertRaises(NotImplementedError):
            self.loop.run_until_complete(asyncio.Task(request_response.start()))
示例#4
0
    async def test_create_knxipframe_err(self):
        """Test if create_knxipframe of base class raises an exception."""
        xknx = XKNX()
        udp_client = UDPClient(xknx, ("192.168.1.1", 0), ("192.168.1.2", 1234))
        request_response = RequestResponse(xknx, udp_client,
                                           DisconnectResponse)
        request_response.timeout_in_seconds = 0

        with pytest.raises(NotImplementedError):
            await request_response.start()
示例#5
0
    def test_connect(self):
        """Test connecting from KNX bus."""
        xknx = XKNX()
        udp_client = UDPClient(xknx, ("192.168.1.1", 0), ("192.168.1.2", 1234))
        connect = Connect(xknx, udp_client, route_back=False)
        connect.timeout_in_seconds = 0

        self.assertEqual(connect.awaited_response_class, ConnectResponse)

        # Expected KNX/IP-Frame:
        exp_knxipframe = KNXIPFrame.init_from_body(
            ConnectRequest(
                xknx,
                request_type=ConnectRequestType.TUNNEL_CONNECTION,
                control_endpoint=HPAI(ip_addr="192.168.1.3", port=4321),
                data_endpoint=HPAI(ip_addr="192.168.1.3", port=4321),
            )
        )

        with patch("xknx.io.UDPClient.send") as mock_udp_send, patch(
            "xknx.io.UDPClient.getsockname"
        ) as mock_udp_getsockname:
            mock_udp_getsockname.return_value = ("192.168.1.3", 4321)
            self.loop.run_until_complete(connect.start())
            mock_udp_send.assert_called_with(exp_knxipframe)

        # Response KNX/IP-Frame with wrong type
        wrong_knxipframe = KNXIPFrame(xknx)
        wrong_knxipframe.init(KNXIPServiceType.CONNECTIONSTATE_REQUEST)
        with patch("logging.Logger.warning") as mock_warning:
            connect.response_rec_callback(wrong_knxipframe, None)
            mock_warning.assert_called_with("Could not understand knxipframe")

        # Response KNX/IP-Frame with error:
        err_knxipframe = KNXIPFrame(xknx)
        err_knxipframe.init(KNXIPServiceType.CONNECT_RESPONSE)
        err_knxipframe.body.status_code = ErrorCode.E_CONNECTION_ID
        with patch("logging.Logger.debug") as mock_warning:
            connect.response_rec_callback(err_knxipframe, None)
            mock_warning.assert_called_with(
                "Error: KNX bus responded to request of type '%s' with error in '%s': %s",
                type(connect).__name__,
                type(err_knxipframe.body).__name__,
                ErrorCode.E_CONNECTION_ID,
            )

        # Correct Response KNX/IP-Frame:
        res_knxipframe = KNXIPFrame(xknx)
        res_knxipframe.init(KNXIPServiceType.CONNECT_RESPONSE)
        res_knxipframe.body.communication_channel = 23
        res_knxipframe.body.identifier = 7
        connect.response_rec_callback(res_knxipframe, None)
        self.assertTrue(connect.success)
        self.assertEqual(connect.communication_channel, 23)
        self.assertEqual(connect.identifier, 7)
示例#6
0
 async def test_request_response_cancelled(self, _send_request_mock):
     """Test RequestResponse: task cancelled. No callback shall be left."""
     xknx = XKNX()
     udp_client = UDPClient(xknx, ("192.168.1.1", 0), ("192.168.1.2", 1234))
     requ_resp = RequestResponse(xknx, udp_client, KNXIPBody)
     requ_resp.response_received_event.wait = MagicMock(
         side_effect=asyncio.CancelledError())
     with pytest.raises(asyncio.CancelledError):
         await requ_resp.start()
     # Callback was removed again
     assert udp_client.callbacks == []
示例#7
0
 def test_request_response_cancelled(self, _send_request_mock):
     """Test RequestResponse: task cancelled. No callback shall be left."""
     xknx = XKNX()
     udp_client = UDPClient(xknx, ("192.168.1.1", 0), ("192.168.1.2", 1234))
     requ_resp = RequestResponse(xknx, udp_client, KNXIPBody)
     requ_resp.response_received_or_timeout.wait = MagicMock(
         side_effect=asyncio.CancelledError())
     with self.assertRaises(asyncio.CancelledError):
         self.loop.run_until_complete(requ_resp.start())
     # Callback was removed again
     self.assertEqual(udp_client.callbacks, [])
示例#8
0
    def test_connectionstate(self):
        """Test connectionstateing from KNX bus."""
        xknx = XKNX(loop=self.loop)
        communication_channel_id = 23
        udp_client = UDPClient(xknx, ("192.168.1.1", 0), ("192.168.1.2", 1234))
        connectionstate = ConnectionState(xknx, udp_client,
                                          communication_channel_id)
        connectionstate.timeout_in_seconds = 0

        self.assertEqual(connectionstate.awaited_response_class,
                         ConnectionStateResponse)
        self.assertEqual(connectionstate.communication_channel_id,
                         communication_channel_id)

        # Expected KNX/IP-Frame:
        exp_knxipframe = KNXIPFrame(xknx)
        exp_knxipframe.init(KNXIPServiceType.CONNECTIONSTATE_REQUEST)
        exp_knxipframe.body.communication_channel_id = communication_channel_id
        exp_knxipframe.body.control_endpoint = HPAI(ip_addr='192.168.1.3',
                                                    port=4321)
        exp_knxipframe.normalize()
        with patch('xknx.io.UDPClient.send') as mock_udp_send, \
                patch('xknx.io.UDPClient.getsockname') as mock_udp_getsockname:
            mock_udp_getsockname.return_value = ("192.168.1.3", 4321)
            self.loop.run_until_complete(asyncio.Task(connectionstate.start()))
            mock_udp_send.assert_called_with(exp_knxipframe)

        # Response KNX/IP-Frame with wrong type
        wrong_knxipframe = KNXIPFrame(xknx)
        wrong_knxipframe.init(KNXIPServiceType.CONNECTIONSTATE_REQUEST)
        with patch('logging.Logger.warning') as mock_warning:
            connectionstate.response_rec_callback(wrong_knxipframe, None)
            mock_warning.assert_called_with('Cant understand knxipframe')

        # Response KNX/IP-Frame with error:
        err_knxipframe = KNXIPFrame(xknx)
        err_knxipframe.init(KNXIPServiceType.CONNECTIONSTATE_RESPONSE)
        err_knxipframe.body.status_code = ErrorCode.E_CONNECTION_ID
        with patch('logging.Logger.warning') as mock_warning:
            connectionstate.response_rec_callback(err_knxipframe, None)
            mock_warning.assert_called_with(
                'Error: reading rading group address from KNX bus failed: %s',
                ErrorCode.E_CONNECTION_ID)

        # Correct Response KNX/IP-Frame:
        res_knxipframe = KNXIPFrame(xknx)
        res_knxipframe.init(KNXIPServiceType.CONNECTIONSTATE_RESPONSE)
        with patch('logging.Logger.info') as mock_info:
            connectionstate.response_rec_callback(res_knxipframe, None)
            mock_info.assert_called_with(
                'Success: received correct answer from KNX bus: %s',
                ErrorCode.E_NO_ERROR)
            self.assertTrue(connectionstate.success)
示例#9
0
    def test_disconnect(self):
        """Test disconnecting from KNX bus."""
        xknx = XKNX(loop=self.loop)
        communication_channel_id = 23
        udp_client = UDPClient(xknx, ("192.168.1.1", 0), ("192.168.1.2", 1234))
        disconnect = Disconnect(xknx, udp_client, communication_channel_id)
        disconnect.timeout_in_seconds = 0

        self.assertEqual(disconnect.awaited_response_class, DisconnectResponse)
        self.assertEqual(disconnect.communication_channel_id,
                         communication_channel_id)

        # Expected KNX/IP-Frame:
        exp_knxipframe = KNXIPFrame(xknx)
        exp_knxipframe.init(KNXIPServiceType.DISCONNECT_REQUEST)
        exp_knxipframe.body.communication_channel_id = communication_channel_id
        exp_knxipframe.body.control_endpoint = HPAI(ip_addr='192.168.1.3',
                                                    port=4321)
        exp_knxipframe.normalize()
        with patch('xknx.io.UDPClient.send') as mock_udp_send, \
                patch('xknx.io.UDPClient.getsockname') as mock_udp_getsockname:
            mock_udp_getsockname.return_value = ("192.168.1.3", 4321)
            self.loop.run_until_complete(asyncio.Task(disconnect.start()))
            mock_udp_send.assert_called_with(exp_knxipframe)

        # Response KNX/IP-Frame with wrong type
        wrong_knxipframe = KNXIPFrame(xknx)
        wrong_knxipframe.init(KNXIPServiceType.DISCONNECT_REQUEST)
        with patch('logging.Logger.warning') as mock_warning:
            disconnect.response_rec_callback(wrong_knxipframe, None)
            mock_warning.assert_called_with('Cant understand knxipframe')

        # Response KNX/IP-Frame with error:
        err_knxipframe = KNXIPFrame(xknx)
        err_knxipframe.init(KNXIPServiceType.DISCONNECT_RESPONSE)
        err_knxipframe.body.status_code = ErrorCode.E_CONNECTION_ID
        with patch('logging.Logger.warning') as mock_warning:
            disconnect.response_rec_callback(err_knxipframe, None)
            mock_warning.assert_called_with(
                "Error: KNX bus responded to request of type '%s' with error in '%s': %s",
                type(disconnect).__name__,
                type(err_knxipframe.body).__name__, ErrorCode.E_CONNECTION_ID)

        # Correct Response KNX/IP-Frame:
        res_knxipframe = KNXIPFrame(xknx)
        res_knxipframe.init(KNXIPServiceType.DISCONNECT_RESPONSE)
        with patch('logging.Logger.debug') as mock_debug:
            disconnect.response_rec_callback(res_knxipframe, None)
            mock_debug.assert_called_with(
                'Success: received correct answer from KNX bus: %s',
                ErrorCode.E_NO_ERROR)
            self.assertTrue(disconnect.success)
示例#10
0
    async def test_disconnect(self):
        """Test disconnecting from KNX bus."""
        xknx = XKNX()
        communication_channel_id = 23
        udp_client = UDPClient(xknx, ("192.168.1.1", 0), ("192.168.1.2", 1234))
        disconnect = Disconnect(xknx,
                                udp_client,
                                communication_channel_id,
                                route_back=False)
        disconnect.timeout_in_seconds = 0

        assert disconnect.awaited_response_class == DisconnectResponse
        assert disconnect.communication_channel_id == communication_channel_id

        # Expected KNX/IP-Frame:
        exp_knxipframe = KNXIPFrame.init_from_body(
            DisconnectRequest(
                xknx,
                communication_channel_id=communication_channel_id,
                control_endpoint=HPAI(ip_addr="192.168.1.3", port=4321),
            ))
        with patch("xknx.io.UDPClient.send") as mock_udp_send, patch(
                "xknx.io.UDPClient.getsockname") as mock_udp_getsockname:
            mock_udp_getsockname.return_value = ("192.168.1.3", 4321)
            await disconnect.start()
            mock_udp_send.assert_called_with(exp_knxipframe)

        # Response KNX/IP-Frame with wrong type
        wrong_knxipframe = KNXIPFrame(xknx)
        wrong_knxipframe.init(KNXIPServiceType.DISCONNECT_REQUEST)
        with patch("logging.Logger.warning") as mock_warning:
            disconnect.response_rec_callback(wrong_knxipframe, None)
            mock_warning.assert_called_with("Could not understand knxipframe")

        # Response KNX/IP-Frame with error:
        err_knxipframe = KNXIPFrame(xknx)
        err_knxipframe.init(KNXIPServiceType.DISCONNECT_RESPONSE)
        err_knxipframe.body.status_code = ErrorCode.E_CONNECTION_ID
        with patch("logging.Logger.debug") as mock_warning:
            disconnect.response_rec_callback(err_knxipframe, None)
            mock_warning.assert_called_with(
                "Error: KNX bus responded to request of type '%s' with error in '%s': %s",
                type(disconnect).__name__,
                type(err_knxipframe.body).__name__,
                ErrorCode.E_CONNECTION_ID,
            )

        # Correct Response KNX/IP-Frame:
        res_knxipframe = KNXIPFrame(xknx)
        res_knxipframe.init(KNXIPServiceType.DISCONNECT_RESPONSE)
        disconnect.response_rec_callback(res_knxipframe, None)
        assert disconnect.success
示例#11
0
 async def test_request_response_timeout(self, _send_request_mock,
                                         logger_debug_mock):
     """Test RequestResponse: timeout. No callback shall be left."""
     xknx = XKNX()
     udp_client = UDPClient(xknx, ("192.168.1.1", 0), ("192.168.1.2", 1234))
     requ_resp = RequestResponse(xknx, udp_client, KNXIPBody)
     requ_resp.response_received_event.wait = MagicMock(
         side_effect=asyncio.TimeoutError())
     await requ_resp.start()
     # Debug message was logged
     logger_debug_mock.assert_called_once_with(
         "Error: KNX bus did not respond in time (%s secs) to request of type '%s'",
         1.0,
         "RequestResponse",
     )
     # Callback was removed again
     assert udp_client.callbacks == []
示例#12
0
    def test_tunnelling(self):
        """Test tunnelling from KNX bus."""
        # pylint: disable=too-many-locals
        xknx = XKNX()
        communication_channel_id = 23
        udp_client = UDPClient(xknx, ("192.168.1.1", 0), ("192.168.1.2", 1234))
        telegram = Telegram(
            destination_address=GroupAddress("1/2/3"),
            payload=GroupValueWrite(DPTArray((0x1, 0x2, 0x3))),
        )
        sequence_counter = 42
        src_address = IndividualAddress("2.2.2")
        tunnelling = Tunnelling(
            xknx,
            udp_client,
            telegram,
            src_address,
            sequence_counter,
            communication_channel_id,
        )
        tunnelling.timeout_in_seconds = 0

        self.assertEqual(tunnelling.awaited_response_class, TunnellingAck)
        self.assertEqual(tunnelling.communication_channel_id,
                         communication_channel_id)

        # Expected KNX/IP-Frame:
        tunnelling_request = TunnellingRequest(
            xknx,
            communication_channel_id=communication_channel_id,
            sequence_counter=sequence_counter,
        )
        tunnelling_request.cemi.telegram = telegram
        tunnelling_request.cemi.src_addr = src_address
        exp_knxipframe = KNXIPFrame.init_from_body(tunnelling_request)
        with patch("xknx.io.UDPClient.send") as mock_udp_send, patch(
                "xknx.io.UDPClient.getsockname") as mock_udp_getsockname:
            mock_udp_getsockname.return_value = ("192.168.1.3", 4321)
            self.loop.run_until_complete(tunnelling.start())
            mock_udp_send.assert_called_with(exp_knxipframe)

        # Response KNX/IP-Frame with wrong type
        wrong_knxipframe = KNXIPFrame(xknx)
        wrong_knxipframe.init(KNXIPServiceType.CONNECTIONSTATE_REQUEST)
        with patch("logging.Logger.warning") as mock_warning:
            tunnelling.response_rec_callback(wrong_knxipframe, None)
            mock_warning.assert_called_with("Could not understand knxipframe")

        # Response KNX/IP-Frame with error:
        err_knxipframe = KNXIPFrame(xknx)
        err_knxipframe.init(KNXIPServiceType.TUNNELLING_ACK)
        err_knxipframe.body.status_code = ErrorCode.E_CONNECTION_ID
        with patch("logging.Logger.debug") as mock_warning:
            tunnelling.response_rec_callback(err_knxipframe, None)
            mock_warning.assert_called_with(
                "Error: KNX bus responded to request of type '%s' with error in '%s': %s",
                type(tunnelling).__name__,
                type(err_knxipframe.body).__name__,
                ErrorCode.E_CONNECTION_ID,
            )

        # Correct Response KNX/IP-Frame:
        res_knxipframe = KNXIPFrame(xknx)
        res_knxipframe.init(KNXIPServiceType.TUNNELLING_ACK)
        tunnelling.response_rec_callback(res_knxipframe, None)
        self.assertTrue(tunnelling.success)
示例#13
0
gatewayscanner.start()
gatewayscanner.stop()

if not gatewayscanner.found:
    raise Exception("No Gateways found")

print("Connecting to {}:{} from {}".format(gatewayscanner.found_ip_addr,
                                           gatewayscanner.found_port,
                                           gatewayscanner.found_local_ip))

own_ip = "192.168.42.1"
gateway_ip = "192.168.42.10"
gateway_port = 3671

udp_client = UDPClient(
    xknx, (gatewayscanner.found_local_ip, 0),
    (gatewayscanner.found_ip_addr, gatewayscanner.found_port))

task = asyncio.Task(udp_client.connect())

xknx.loop.run_until_complete(task)

for i in range(0, 255):

    conn_state = ConnectionState(xknx, udp_client, communication_channel_id=i)

    conn_state.start()

    if conn_state.success:
        print("Disconnecting ", i)
        disconnect = Disconnect(xknx, udp_client, communication_channel_id=i)