Esempio n. 1
0
    async def test_send_on_topic(self):
        """Test sending the ON command."""
        async with async_protocol_manager():
            received_topic = ""

            def expected_topic_received(cmd1,
                                        cmd2,
                                        user_data,
                                        topic=pub.AUTO_TOPIC):
                nonlocal received_topic
                received_topic = topic.name

            address = random_address()
            on_topic = "send.{}.1.direct".format(ON)
            topics = [
                TopicItem(on_topic, {
                    "address": address,
                    "on_level": 0xFF,
                    "group": 0
                }, 0)
            ]

            self._last_topic = None
            expected_topic = "ack.{}.1.on.direct".format(address.id)
            pub.subscribe(expected_topic_received, expected_topic)
            send_topics(topics)
            await asyncio.sleep(0.05)
            assert received_topic == expected_topic
Esempio n. 2
0
    async def test_send_on_all_link_broadcast_topic(self):
        """Test sending the broadcast ON command."""
        from pyinsteon.handlers.to_device.on_level_all_link_broadcast import (
            OnLevelAllLinkBroadcastCommand, )

        topic_lock = asyncio.Lock()
        async with async_protocol_manager():
            last_topic = None

            def topic_received(cmd1, cmd2, user_data, topic=pub.AUTO_TOPIC):
                """Receive the OFF topic for a device."""
                nonlocal last_topic
                last_topic = topic.name
                if topic_lock.locked():
                    topic_lock.release()

            group = 3
            target = Address(bytearray([0x00, 0x00, group]))
            ack_topic = "ack.{}.on.all_link_broadcast".format(target.id)
            pub.subscribe(topic_received, ack_topic)
            cmd = OnLevelAllLinkBroadcastCommand(group=group)
            await topic_lock.acquire()
            await cmd.async_send()  # Mock transport auto sends ACK/NAK
            try:
                await asyncio.wait_for(topic_lock.acquire(), 2)
                assert last_topic == ack_topic
            except asyncio.TimeoutError:
                assert ack_topic is None
            if topic_lock.locked():
                topic_lock.release()
Esempio n. 3
0
    async def test_receive_on_msg(self):
        """Test receiving an ON message."""
        async with async_protocol_manager() as protocol:
            last_topic = None

            def topic_received(cmd1,
                               cmd2,
                               target,
                               user_data,
                               hops_left,
                               topic=pub.AUTO_TOPIC):
                """Receive the OFF topic for a device."""
                nonlocal last_topic
                last_topic = topic.name

            address = random_address()
            byte_data = create_std_ext_msg(address,
                                           0x80,
                                           0x11,
                                           0xFF,
                                           target=Address("000001"))
            expected_topic = "{}.{}.on.broadcast".format(address.id, 1)
            pub.subscribe(topic_received, expected_topic)
            on_cmd = DataItem(byte_data, 0)
            data = [on_cmd]
            send_data(data, protocol.read_queue)
            await asyncio.sleep(0.05)
            assert last_topic == expected_topic
Esempio n. 4
0
    async def test_message_to_topic(self):
        """Test converting a message to a topic."""
        async with async_protocol_manager() as protocol:
            tests = await import_commands()

            for test_info in tests:
                self._topic = None
                address = repr(random_address())
                curr_test = tests[test_info]
                if curr_test.get("address"):
                    curr_test["address"] = address
                msgs = [create_message(curr_test)]
                curr_topic = curr_test["topic"].format(address)
                pub.subscribe(self.capture_topic, curr_topic)
                send_data(msgs, protocol.read_queue)
                await sleep(0.07)
                try:
                    assert self._topic.name == curr_topic
                except (AssertionError, AttributeError):
                    raise AssertionError(
                        "Failed test {} with message topic {} and test topic {}".format(
                            test_info, self._topic.name, curr_test.get("topic")
                        )
                    )
                finally:
                    pub.unsubscribe(self.capture_topic, curr_topic)
Esempio n. 5
0
 def setUp(self):
     """Set up the test."""
     self.ack_message = "ack.{}".format(START_ALL_LINKING)
     self.handler = StartAllLinkingCommandHandler()
     self.received = False
     pub.subscribe(self.send_listener, START_ALL_LINKING)
     self._sent = False
Esempio n. 6
0
 def setUp(self):
     """Set up the test."""
     self.ack_message = "ack.send_all_link_command"
     self.received = False
     pub.subscribe(self.send_listener, "send_all_link_command")
     self._sent = False
     set_log_levels(logger_topics=True)
Esempio n. 7
0
 def setUp(self):
     """Set up the test."""
     self.ack_message = "ack.send_all_link_command"
     self.handler = SendAllLinkCommandHandler()
     self.received = False
     pub.subscribe(self.send_listener, "send_all_link_command")
     self._sent = False
Esempio n. 8
0
 async def test_x10_all_lights_on(self):
     """Test X10 message received."""
     handler = X10Received()
     pub.subscribe(self.x10_subscriber, "x10c")
     handler.subscribe(self.x10_subscriber)
     # Receive housecode C All Lights On
     handler.handle_x10_received(0x21, 0x80)
     assert self._x10_receieved == "x10c.all_lights_on"
Esempio n. 9
0
 async def test_x10_off_received(self):
     """Test X10 message received."""
     handler = X10Received()
     pub.subscribe(self.x10_subscriber, "x10a03")
     handler.subscribe(self.x10_subscriber)
     # Receive housecode A unitcode 3
     handler.handle_x10_received(0x62, 0x00)
     # Receive housecode A command Off
     handler.handle_x10_received(0x63, 0x80)
     assert self._x10_receieved == "x10a03.off"
Esempio n. 10
0
 async def test_x10_on_received(self):
     """Test X10 message received."""
     handler = X10Received()
     pub.subscribe(self.x10_subscriber, "x10g09")
     handler.subscribe(self.x10_subscriber)
     # Receive housecode G unitcode 9
     handler.handle_x10_received(0x57, 0x00)
     # Receive housecode G command On
     handler.handle_x10_received(0x52, 0x80)
     assert self._x10_receieved == "x10g09.on"
Esempio n. 11
0
    async def test_data_received(self):
        """Test the data_received method."""
        def dummy_nak_listener(*args, **kwargs):
            """Listen for NAK.

            This ensures we send the NAK rather than resend the message.
            """

        data = [
            {
                "data": "025003040506070809110b",
                "topic": "030405.1.on.direct"
            },
            {
                "data": "02500304050607",
                "topic": None
            },
            {
                "data": "0809130b",
                "topic": "030405.1.off.direct"
            },
        ]

        with patch("pyinsteon.protocol.protocol.publish_topic",
                   self.mock_publish_topic):
            async with async_protocol_manager(auto_ack=False) as protocol:
                for test in data:
                    self.topic = None
                    protocol.data_received(unhexlify(test["data"]))
                    await asyncio.sleep(0.1)
                    try:
                        assert self.topic == test["topic"]
                    except AssertionError:
                        raise AssertionError(
                            f"Failed with data {test['data']}: Topic: {self.topic}  Expected: {test['topic']}"
                        )

                # Test when the modem only responds with a NAK rather than the original message.
                nak_topic = "nak.0a0b0c.1.on.direct"
                pub.subscribe(dummy_nak_listener, nak_topic)
                protocol.write(unhexlify("02620a0b0c09110b"))
                await asyncio.sleep(0.1)
                self.topic = None
                protocol.data_received(unhexlify("15"))
                await asyncio.sleep(0.1)
                assert self.topic == nak_topic

                # Test that a NAK is resent rather than published as a topic.
                self.topic = None
                protocol.data_received(unhexlify("02620d0e0f09110b15"))
                await asyncio.sleep(0.1)
                assert self.topic is None
Esempio n. 12
0
def set_log_levels(
    logger="info", logger_pyinsteon="info", logger_messages="info", logger_topics=False
):
    """Set the log levels of the three logs."""
    _setup_logger(_LOGGER, logger)
    _setup_logger(_LOGGER_PYINSTEON, logger_pyinsteon)
    _setup_logger(_LOGGER_MESSAGES, logger_messages)
    if logger_topics:
        _setup_logger(_LOGGER_TOPICS, "info")
        pub.subscribe(_log_all_topics, pub.ALL_TOPICS)
    else:
        _setup_logger(_LOGGER_TOPICS, "fatal")
        pub.unsubscribe(_log_all_topics, pub.ALL_TOPICS)
Esempio n. 13
0
    async def test_load_empty(self):
        """Test loading an empty modem ALDB."""
        async with LOCK:
            mgr = pub.getDefaultTopicMgr()
            mgr.delTopic(ALL_LINK_RECORD_RESPONSE)
            aldb = ModemALDB(random_address())
            pub.subscribe(send_nak_response, SEND_FIRST_TOPIC)

            response = await aldb.async_load()
            _LOGGER.debug("Done LOAD function.")
            _LOGGER.debug("Status: %s", response.name)
            assert aldb.is_loaded
            _LOGGER.debug("ALDB Record Count: %d", len(aldb))
            assert len(aldb) == 0
            pub.unsubscribe(send_nak_response, SEND_FIRST_TOPIC)
Esempio n. 14
0
    async def test_command(self):
        """Test direct command."""
        async with async_protocol_manager() as protocol:
            msgs = []

            def listen_for_ack():
                send_data(msgs, protocol.read_queue)

            tests = await import_commands()
            pub.subscribe(self.validate_values, pub.ALL_TOPICS)
            pub.subscribe(listen_for_ack, "ack")

            for test_info in tests:
                address = random_address()
                self._current_test = test_info
                test_command = tests[test_info]
                command = test_command.get("command")
                cmd_class = command.get("class")
                params = command.get("params")
                if params.get("address"):
                    params["address"] = address
                send_params = command.get("send_params")
                test_response = test_command.get("response")
                obj = get_class_or_method(commands, cmd_class)
                cmd = obj(**params)

                messages = test_command.get("messages")
                msgs = []
                for message in messages:
                    msg_dict = messages[message]
                    msg_dict["address"] = address
                    msgs.append(create_message(msg_dict))
                self._assert_tests = test_command.get("assert_tests")

                # send_data(msgs, self._read_queue)
                try:
                    response = await cmd.async_send(**send_params)
                except Exception as ex:
                    raise Exception("Failed test {} with error: {}".format(
                        self._current_test, str(ex)))
                if test_response:
                    try:
                        assert int(response) == test_response
                    except AssertionError:
                        raise AssertionError(
                            "Failed test: {} command response: {}".format(
                                self._current_test, response))
                await sleep(0.1)
Esempio n. 15
0
    async def test_all_lights_on(self):
        """Test the All Lights On command."""
        call_received = False

        def check_x10_call(raw_x10, x10_flag):
            """Check the X10 call params."""
            nonlocal call_received
            call_received = True
            assert raw_x10 == 0x61
            assert x10_flag == 0x80

        topic = "send.x10_send"
        pub.subscribe(check_x10_call, topic)
        await async_x10_all_lights_on(housecode="a")
        await asyncio.sleep(0.05)
        assert call_received
        pub.unsubscribe(check_x10_call, topic)
Esempio n. 16
0
    async def test_load_8_records_eeprom(self):
        """Test loading 8 records into the modem ALDB."""
        async with LOCK:
            mgr = pub.getDefaultTopicMgr()
            mgr.delTopic(ALL_LINK_RECORD_RESPONSE)
            pub.subscribe(self.send_eeprom_response, SEND_READ_EEPROM_TOPIC)

            aldb = ModemALDB(random_address())
            aldb.read_write_mode = ReadWriteMode.EEPROM
            response = await aldb.async_load()
            await asyncio.sleep(0.01)
            _LOGGER.debug("Done LOAD function.")
            _LOGGER.debug("Status: %s", response.name)
            assert aldb.is_loaded
            _LOGGER.debug("ALDB Record Count: %d", len(aldb))
            assert len(aldb) == 9  # Includes HWM record
            pub.unsubscribe(self.send_standard_response,
                            SEND_READ_EEPROM_TOPIC)
 async def test_async_send(self):
     """Test the async_send method."""
     self.handler = StartAllLinkingCommandHandler()
     self.received = False
     pub.subscribe(self.send_listener, START_ALL_LINKING)
     topics = [
         TopicItem(
             self.ack_message,
             {
                 "link_mode": AllLinkMode.CONTROLLER,
                 "group": 0x01
             },
             0.5,
         )
     ]
     send_topics(topics)
     assert await self.handler.async_send(link_mode=AllLinkMode.CONTROLLER,
                                          group=0x01)
Esempio n. 18
0
 def base_setup(self, message_id, bytes_data, **kwargs):
     """Init the OutboundBase class."""
     set_log_levels(
         logger="info",
         logger_pyinsteon="debug",
         logger_messages="debug",
         logger_topics=False,
     )
     register_outbound_handlers()
     self.msg = None
     self.message_id = message_id
     self.bytes_data = bytes_data
     pub.subscribe(self.receive_message, "send_message")
     topic = self.message_id.name.lower()
     if (topic == "send_standard" and kwargs.get("flags")
             and kwargs.get("flags").is_extended):
         topic = "send_extended"
     pub.sendMessage("send.{}".format(topic), **kwargs)
Esempio n. 19
0
def set_log_levels(logger="info",
                   logger_pyinsteon="info",
                   logger_messages="info",
                   logger_topics=False):
    """Set the log levels of the three logs."""
    try:
        assert os.environ["ALLOW_LOGGING"].lower() == "y"
    except (AssertionError, KeyError):
        return

    _setup_logger(_LOGGER, logger)
    _setup_logger(_LOGGER_PYINSTEON, logger_pyinsteon)
    _setup_logger(_LOGGER_MESSAGES, logger_messages)
    if logger_topics:
        _setup_logger(_LOGGER_TOPICS, "info")
        pub.subscribe(_log_all_topics, pub.ALL_TOPICS)
    else:
        _setup_logger(_LOGGER_TOPICS, "fatal")
        pub.unsubscribe(_log_all_topics, pub.ALL_TOPICS)
Esempio n. 20
0
    async def test_modem_inbound(self):
        """Test direct command."""
        async with async_protocol_manager(auto_ack=False) as protocol:

            tests = await import_modem_commands()
            pub.subscribe(self.validate_values, pub.ALL_TOPICS)

            for test_info in tests:
                self._current_test = test_info
                test_command = tests[test_info]
                command = test_command.get("command")
                cmd_class = command.get("class")
                inbound_message = command.get("inbound_message")["data"]
                self._assert_tests = test_command.get("assert_tests")
                obj = get_class_or_method(commands, cmd_class)
                cmd = obj()
                inbound_data = unhexlify(f"02{inbound_message}")
                ack_response_item = DataItem(inbound_data, 0)
                send_data([ack_response_item], protocol.read_queue)
                await sleep(0.1)
Esempio n. 21
0
    async def test_receive_on_msg(self):
        """Test receiving an ON message."""
        topic_lock = asyncio.Lock()
        async with async_protocol_manager() as protocol:
            last_topic = None

            def topic_received(cmd1,
                               cmd2,
                               target,
                               user_data,
                               hops_left,
                               topic=pub.AUTO_TOPIC):
                """Receive the OFF topic for a device."""
                nonlocal last_topic
                last_topic = topic.name
                if topic_lock.locked():
                    topic_lock.release()

            address = random_address()
            byte_data = create_std_ext_msg(address,
                                           0x80,
                                           0x11,
                                           0xFF,
                                           target=Address("000001"))
            expected_topic = "{}.{}.on.broadcast".format(address.id, 1)
            pub.subscribe(topic_received, expected_topic)
            on_cmd = DataItem(byte_data, 0)
            data = [on_cmd]
            await topic_lock.acquire()
            send_data(data, protocol.read_queue)
            try:
                await asyncio.wait_for(topic_lock.acquire(), 2)
                assert last_topic == expected_topic
            except asyncio.TimeoutError:
                assert expected_topic is None
            if topic_lock.locked():
                topic_lock.release()
Esempio n. 22
0
    async def test_send_on_topic(self):
        """Test sending the ON command."""
        topic_lock = asyncio.Lock()
        async with async_protocol_manager():
            received_topic = ""

            def expected_topic_received(cmd1,
                                        cmd2,
                                        user_data,
                                        topic=pub.AUTO_TOPIC):
                nonlocal received_topic
                received_topic = topic.name
                if topic_lock.locked():
                    topic_lock.release()

            address = random_address()
            on_topic = "send.{}.1.direct".format(ON)
            topics = [
                TopicItem(on_topic, {
                    "address": address,
                    "on_level": 0xFF,
                    "group": 0
                }, 0)
            ]

            self._last_topic = None
            expected_topic = "ack.{}.1.on.direct".format(address.id)
            pub.subscribe(expected_topic_received, expected_topic)
            await topic_lock.acquire()
            send_topics(topics)
            try:
                await asyncio.wait_for(topic_lock.acquire(), 2)
                assert received_topic == expected_topic
            except asyncio.TimeoutError:
                assert expected_topic is None
            if topic_lock.locked():
                topic_lock.release()
Esempio n. 23
0
    async def test_status_request_command(self):
        """Test an Status Request message."""
        status_received = False
        status_1_received = False
        state_values = {}

        def state_updated(value, group, name, address):
            """Run when the state is updated."""
            nonlocal state_values
            _LOGGER.info("Group %s updated: %s", str(group), str(value))
            state_values[group] = value

        def receive_status(db_version, status):
            """Run when the state is updated."""
            nonlocal status_received
            _LOGGER.info("Status received")
            status_received = True

        def receive_status_1(db_version, status):
            """Run when the state is updated."""
            nonlocal status_1_received
            _LOGGER.info("Status 1 received")
            status_1_received = True

        address = random_address()
        device = DimmableLightingControl_KeypadLinc_8(address, 0x01, 0x02,
                                                      0x03, "Test", "KPL")
        for button in device.groups:
            device.groups[button].set_value(0)
            device.groups[button].subscribe(state_updated)
        cmd1_status = random.randint(0, 255)
        cmd2_status = random.randint(0, 255)
        cmd1_status_1 = random.randint(0, 255)
        cmd2_status_1 = random.randint(0, 255)
        cmd1_on = 0x11
        cmd2_on = random.randint(0, 255)
        target = device.address
        user_data = None
        ack_status_0 = "ack.{}.{}.direct".format(device.address.id,
                                                 STATUS_REQUEST)
        ack_status_1 = "ack.{}.{}.direct".format(device.address.id,
                                                 STATUS_REQUEST)
        direct_ack_status = "{}.{}.direct_ack".format(device.address.id,
                                                      STATUS_REQUEST)
        ack_on = "ack.{}.1.{}.direct".format(device.address.id, ON)
        direct_ack_on = "{}.{}.direct_ack".format(device.address.id, ON)
        status_1_handler_topic = f"handler.{device.address.id}.1.status_request.direct"
        status_handler_topic = f"handler.{device.address.id}.2.status_request.direct"
        pub.subscribe(receive_status, status_handler_topic)
        pub.subscribe(receive_status_1, status_1_handler_topic)
        responses = [
            TopicItem(ack_status_0, cmd_kwargs(0x19, 0x02, user_data), 0.5),
            TopicItem(
                direct_ack_status,
                cmd_kwargs(cmd1_status, cmd2_status, user_data, target),
                0.25,
            ),
            TopicItem(ack_status_1, cmd_kwargs(0x19, 0x01, user_data), 0.25),
            TopicItem(
                direct_ack_status,
                cmd_kwargs(cmd1_status_1, cmd2_status_1, user_data, target),
                0.25,
            ),
            TopicItem(ack_on, cmd_kwargs(cmd1_on, cmd2_on, user_data), 0.25),
            TopicItem(direct_ack_on,
                      cmd_kwargs(cmd1_on, cmd2_on, user_data, target), 0.25),
        ]
        send_topics(responses)

        response = await device.async_status()
        assert response == ResponseStatus.SUCCESS
        assert status_received
        assert status_1_received
        assert state_values.get(1) == cmd2_status
        for bit in range(1, 8):
            bit_set = bit_is_set(cmd2_status_1, bit)
            button = bit + 1
            if bit_set:
                assert state_values.get(button)
            else:
                assert state_values.get(button) is None

        # Confirm that an ON command does not trigger the status handler again
        status_received = False
        status_1_received = False
        response = await device.async_on(on_level=cmd2_on, fast=False)
        assert response == ResponseStatus.SUCCESS
        assert not status_received
        assert not status_1_received
        assert state_values.get(1) == cmd2_on
        for bit in range(1, 8):
            bit_set = bit_is_set(cmd2_status_1, bit)
            button = bit + 1
            if bit_set:
                assert state_values.get(button)
            else:
                assert state_values.get(button) is None