Exemple #1
0
def create_std_ext_msg(address, flags, cmd1, cmd2, user_data=None, target=None, ack=0):
    """Create a standard or extended message."""
    from pyinsteon.protocol.messages.user_data import UserData

    address = Address(address)
    data = bytearray()
    data.append(0x02)
    if target:
        target = Address(target)
        msg_type = 0x51 if user_data else 0x50
    else:
        msg_type = 0x62
    data.append(msg_type)
    data.append(address.high)
    data.append(address.middle)
    data.append(address.low)
    if target:
        data.append(target.high)
        data.append(target.middle)
        data.append(target.low)
    data.append(flags)
    data.append(cmd1)
    data.append(cmd2)
    if user_data:
        user_data = UserData(user_data)
        for byte in user_data:
            data.append(user_data[byte])
    if ack:
        data.append(ack)
    return bytes(data)
Exemple #2
0
 def setUp(self):
     """Set up the test."""
     self._id_mgr = DeviceIdManager()
     self._test_response = None
     self._modem_address = Address("4d5e6f")
     self._cat = 0x01
     self._subcat = 0x02
     self._firmware = 0x03
     self._target = Address(bytearray([self._cat, self._subcat, self._firmware]))
Exemple #3
0
def cmd_kwargs(cmd1, cmd2, user_data, target=None, address=None, hops_left=3):
    """Return a kwargs dict for a standard messsage command."""

    kwargs = {"cmd1": cmd1, "cmd2": cmd2, "user_data": user_data}
    if target:
        kwargs["target"] = Address(target)
        kwargs["hops_left"] = hops_left
    if address:
        kwargs["address"] = Address(address)
    return kwargs
Exemple #4
0
 def setUp(self):
     """Set up the tests."""
     self.hex = "010203"
     self.address = Address(self.hex)
     self.address_bytes = Address(bytearray(unhexlify(self.hex)))
     set_log_levels(
         logger="info",
         logger_pyinsteon="info",
         logger_messages="info",
         logger_topics=False,
     )
    async def async_load(self, *args, **kwargs):
        """Load the mock devices."""
        if self._connected:
            addr0 = Address("AA.AA.AA")
            addr1 = Address("11.11.11")
            addr2 = Address("22.22.22")
            addr3 = Address("33.33.33")
            self._devices[addr0] = Hub(addr0, 0x03, 0x00, 0x00, "Hub AA.AA.AA",
                                       "0")
            self._devices[addr1] = MockSwitchLinc(addr1, 0x02, 0x00, 0x00,
                                                  "Device 11.11.11", "1")
            self._devices[addr2] = GeneralController(addr2, 0x00, 0x00, 0x00,
                                                     "Device 22.22.22", "2")
            self._devices[addr3] = DimmableLightingControl_KeypadLinc_8(
                addr3, 0x02, 0x00, 0x00, "Device 33.33.33", "3")

            for device in [
                    self._devices[addr] for addr in [addr1, addr2, addr3]
            ]:
                device.async_read_config = AsyncMock()
                device.aldb.async_write = AsyncMock()
                device.aldb.async_load = AsyncMock()
                device.async_add_default_links = AsyncMock()
                device.async_read_op_flags = AsyncMock(
                    return_value=ResponseStatus.SUCCESS)
                device.async_read_ext_properties = AsyncMock(
                    return_value=ResponseStatus.SUCCESS)
                device.async_write_op_flags = AsyncMock(
                    return_value=ResponseStatus.SUCCESS)
                device.async_write_ext_properties = AsyncMock(
                    return_value=ResponseStatus.SUCCESS)

            for device in [self._devices[addr] for addr in [addr2, addr3]]:
                device.async_status = AsyncMock()
            self._devices[addr1].async_status = AsyncMock(
                side_effect=AttributeError)
            self._devices[addr0].aldb.async_load = AsyncMock()

            self._devices[addr2].async_read_op_flags = AsyncMock(
                return_value=ResponseStatus.FAILURE)
            self._devices[addr2].async_read_ext_properties = AsyncMock(
                return_value=ResponseStatus.FAILURE)
            self._devices[addr2].async_write_op_flags = AsyncMock(
                return_value=ResponseStatus.FAILURE)
            self._devices[addr2].async_write_ext_properties = AsyncMock(
                return_value=ResponseStatus.FAILURE)

            self.modem = self._devices[addr0]
 async def test_append(self):
     """Test appending an address to the list of devices to ID."""
     self._id_mgr = DeviceIdManager()
     address = Address("020202")
     self._id_mgr.append(address)
     assert self._id_mgr[address] is not None
     assert self._id_mgr[address].cat is None
Exemple #7
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
Exemple #8
0
 async def async_validate_values(self, topic=pub.AUTO_TOPIC, **kwargs):
     """Validate what should be returned from the handler."""
     if not topic.name.startswith("handler"):
         return
     self._call_count += 1
     for test in self._assert_tests:
         if kwargs.get(test) is None:
             continue
         try:
             if test == "address" or test == "target":
                 self._assert_tests[test] = Address(self._assert_tests[test])
             elif str(self._assert_tests[test]).startswith("0x"):
                 self._assert_tests[test] = int.from_bytes(
                     unhexlify(self._assert_tests[test]), "big"
                 )
             if type(self._assert_tests[test]) == "float":
                 self._assert_tests[test] = round(self._assert_tests[test], 1)
             if test == "data":
                 for k, v in self._assert_tests[test].items():
                     assert kwargs[test][k] == v
             else:
                 assert kwargs.get(test) == self._assert_tests[test]
         except (AssertionError, KeyError):
             self._assert_result = False
             raise AssertionError(
                 "Failed test '{}' with argument '{}' value {} vs expected value {}".format(
                     self._current_test,
                     test,
                     kwargs.get(test),
                     self._assert_tests[test],
                 )
             )
Exemple #9
0
    def setUp(self):
        """Test set up."""
        self.hex = "0262010203140506a1a2a3a4a5a6a7a8a9aaabacadae"
        self.message_id = MessageId.SEND_EXTENDED
        self.address = Address("010203")
        self.flags = MessageFlags(0x14)
        self.cmd1 = int(0x05)
        self.cmd2 = int(0x06)
        self.user_data = UserData(unhexlify(self.hex)[8:])

        kwargs = {
            "address": self.address,
            "flags": self.flags,
            "cmd1": self.cmd1,
            "cmd2": self.cmd2,
            "user_data": self.user_data,
        }

        super(TestSendExtended, self).base_setup(MessageId.SEND_EXTENDED,
                                                 unhexlify(self.hex), **kwargs)
        set_log_levels(
            logger="info",
            logger_pyinsteon="info",
            logger_messages="info",
            logger_topics=False,
        )
Exemple #10
0
 async def async_remove_device_override(address):
     """Remove an Insten device and associated entities."""
     address = Address(address)
     await async_remove_device(address)
     devices.set_id(address, None, None, None)
     await devices.async_identify_device(address)
     await async_srv_save_devices()
    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()
Exemple #12
0
 def test_set_device_id(self):
     """Test setting the device ID."""
     address = Address("030303")
     self._id_mgr.set_device_id(address, self._cat, self._subcat, self._firmware)
     assert self._id_mgr[address].cat == self._cat
     assert self._id_mgr[address].subcat == self._subcat
     assert self._id_mgr[address].firmware == self._firmware
Exemple #13
0
    def setUp(self):
        """Test set up."""
        self.hex = "026F400405060708090a0b"
        self.action = ManageAllLinkRecordAction(0x40)
        self.flags = AllLinkRecordFlags(0x04)
        self.group = int(0x05)
        self.target = Address("060708")
        self.data1 = int(0x09)
        self.data2 = int(0x0A)
        self.data3 = int(0x0B)

        kwargs = {
            "action": self.action,
            "flags": self.flags,
            "group": self.group,
            "target": self.target,
            "data1": self.data1,
            "data2": self.data2,
            "data3": self.data3,
        }

        super(TestManageAllLinkRecord,
              self).base_setup(MessageId.MANAGE_ALL_LINK_RECORD,
                               unhexlify(self.hex), **kwargs)
        set_log_levels(
            logger="info",
            logger_pyinsteon="info",
            logger_messages="info",
            logger_topics=False,
        )
Exemple #14
0
def add_device_override(config_data, new_override):
    """Add a new device override."""
    try:
        address = str(Address(new_override[CONF_ADDRESS]))
        cat = normalize_byte_entry_to_int(new_override[CONF_CAT])
        subcat = normalize_byte_entry_to_int(new_override[CONF_SUBCAT])
    except ValueError as err:
        raise ValueError("Incorrect values") from err

    overrides = config_data.get(CONF_OVERRIDE, [])
    curr_override = {}

    # If this address has an override defined, remove it
    for override in overrides:
        if override[CONF_ADDRESS] == address:
            curr_override = override
            break
    if curr_override:
        overrides.remove(curr_override)

    curr_override[CONF_ADDRESS] = address
    curr_override[CONF_CAT] = cat
    curr_override[CONF_SUBCAT] = subcat
    overrides.append(curr_override)
    config_data[CONF_OVERRIDE] = overrides
    return config_data
Exemple #15
0
def convert_yaml_to_config_flow(yaml_config):
    """Convert the YAML based configuration to a config flow configuration."""
    config = {}
    if yaml_config.get(CONF_HOST):
        hub_version = yaml_config.get(CONF_HUB_VERSION, 2)
        default_port = PORT_HUB_V2 if hub_version == 2 else PORT_HUB_V1
        config[CONF_HOST] = yaml_config.get(CONF_HOST)
        config[CONF_PORT] = yaml_config.get(CONF_PORT, default_port)
        config[CONF_HUB_VERSION] = hub_version
        if hub_version == 2:
            config[CONF_USERNAME] = yaml_config[CONF_USERNAME]
            config[CONF_PASSWORD] = yaml_config[CONF_PASSWORD]
    else:
        config[CONF_DEVICE] = yaml_config[CONF_PORT]

    options = {}
    for old_override in yaml_config.get(CONF_OVERRIDE, []):
        override = {}
        override[CONF_ADDRESS] = str(Address(old_override[CONF_ADDRESS]))
        override[CONF_CAT] = normalize_byte_entry_to_int(
            old_override[CONF_CAT])
        override[CONF_SUBCAT] = normalize_byte_entry_to_int(
            old_override[CONF_SUBCAT])
        options = add_device_override(options, override)

    for x10_device in yaml_config.get(CONF_X10, []):
        options = add_x10_device(options, x10_device)

    return config, options
Exemple #16
0
def add_device_override(config_data, new_override):
    """Add a new device override."""
    try:
        address = str(Address(new_override[CONF_ADDRESS]))
        cat = normalize_byte_entry_to_int(new_override[CONF_CAT])
        subcat = normalize_byte_entry_to_int(new_override[CONF_SUBCAT])
    except ValueError as err:
        raise ValueError("Incorrect values") from err

    overrides = []

    for override in config_data.get(CONF_OVERRIDE, []):
        if override[CONF_ADDRESS] != address:
            overrides.append(override)

    curr_override = {}
    curr_override[CONF_ADDRESS] = address
    curr_override[CONF_CAT] = cat
    curr_override[CONF_SUBCAT] = subcat
    overrides.append(curr_override)

    new_config = {}
    if config_data.get(CONF_X10):
        new_config[CONF_X10] = config_data[CONF_X10]
    new_config[CONF_OVERRIDE] = overrides
    return new_config
Exemple #17
0
async def test_import_options(opp: OpenPeerPower):
    """Test setting up the entry from YAML including options."""
    config = {}
    config[DOMAIN] = MOCK_IMPORT_FULL_CONFIG_PLM

    with patch.object(
        insteon, "async_connect", new=mock_successful_connection
    ), patch.object(insteon, "close_insteon_connection"), patch.object(
        insteon, "devices", new=MockDevices()
    ), patch(
        PATCH_CONNECTION, new=mock_successful_connection
    ):
        assert await async_setup_component(
            opp,
            insteon.DOMAIN,
            config,
        )
        await opp.async_block_till_done()
        await asyncio.sleep(0.01)  # Need to yield to async processes
        # pylint: disable=no-member
        assert insteon.devices.add_x10_device.call_count == 2
        assert insteon.devices.set_id.call_count == 1
    options = opp.config_entries.async_entries(DOMAIN)[0].options
    assert len(options[CONF_OVERRIDE]) == 1
    assert options[CONF_OVERRIDE][0][CONF_ADDRESS] == str(Address(MOCK_ADDRESS))
    assert options[CONF_OVERRIDE][0][CONF_CAT] == MOCK_CAT
    assert options[CONF_OVERRIDE][0][CONF_SUBCAT] == MOCK_SUBCAT

    assert len(options[CONF_X10]) == 2
    assert options[CONF_X10][0] == MOCK_IMPORT_FULL_CONFIG_PLM[CONF_X10][0]
    assert options[CONF_X10][1] == MOCK_IMPORT_FULL_CONFIG_PLM[CONF_X10][1]
Exemple #18
0
    def setUp(self):
        """Test set up."""
        self.hex_data = "0250010203040506070809"
        self.bytes_data = bytearray(unhexlify(self.hex_data))
        self.message_id = 0x50
        self.address = Address("010203")
        self.target = Address("040506")
        self.flags = MessageFlags(0x07)
        self.cmd1 = int(0x08)
        self.cmd2 = int(0x09)

        self.msg, self.msg_bytes = hex_to_inbound_message(self.hex_data)
        set_log_levels(
            logger="info",
            logger_pyinsteon="info",
            logger_messages="info",
            logger_topics=False,
        )
Exemple #19
0
def random_address():
    """Generate a random address."""
    address = ""
    for _ in range(0, 3):
        rand_int = randint(1, 255)
        if address:
            address = f"{address}."
        address = f"{address}{rand_int:02x}"
    return Address(address)
def _compare_records(aldb_rec, dict_rec):
    """Compare a record in the ALDB to the dictionary record."""
    assert aldb_rec.is_in_use == dict_rec["in_use"]
    assert aldb_rec.is_controller == (dict_rec["is_controller"])
    assert not aldb_rec.is_high_water_mark
    assert aldb_rec.group == dict_rec["group"]
    assert aldb_rec.target == Address(dict_rec["target"])
    assert aldb_rec.data1 == dict_rec["data1"]
    assert aldb_rec.data2 == dict_rec["data2"]
    assert aldb_rec.data3 == dict_rec["data3"]
    def setUp(self):
        """Set up the test."""
        self.hex_data = "0251112233445566778899a1a2a3a4a5a6a7a8a9aaabacadae"
        self.message_id = 0x51
        self.bytes_data = bytearray(unhexlify(self.hex_data))
        self.address = Address("112233")
        self.target = Address("445566")
        self.flags = MessageFlags(0x77)
        self.cmd1 = int(0x88)
        self.cmd2 = int(0x99)
        self.user_data = UserData(unhexlify("a1a2a3a4a5a6a7a8a9aaabacadae"))

        self.msg, self.msg_bytes = hex_to_inbound_message(self.hex_data)
        set_log_levels(
            logger="info",
            logger_pyinsteon="info",
            logger_messages="info",
            logger_topics=False,
        )
 def setUp(self):
     """Set up the test."""
     self._address = Address("010203")
     self._properties = {}
     set_log_levels(
         logger="info",
         logger_pyinsteon="info",
         logger_messages="info",
         logger_topics=False,
     )
async def test_notify_on_aldb_record_added(hass, hass_ws_client, aldb_data):
    """Test getting an Insteon device's All-Link Database."""
    ws_client, devices = await _setup(hass, hass_ws_client, aldb_data)

    with patch.object(insteon.api.aldb, "devices", devices):
        await ws_client.send_json({
            ID: 2,
            TYPE: "insteon/aldb/notify",
            DEVICE_ADDRESS: "33.33.33",
        })
        msg = await ws_client.receive_json()
        assert msg["success"]

        pub.sendMessage(
            f"{DEVICE_LINK_CONTROLLER_CREATED}.333333",
            controller=Address("11.11.11"),
            responder=Address("33.33.33"),
            group=100,
        )
        msg = await ws_client.receive_json()
        assert msg["event"]["type"] == "record_loaded"
Exemple #24
0
def make_command_response_messages(
    address, topic, cmd1, cmd2, target="000000", user_data=None
):
    """Return a colleciton of ACK and Direct ACK responses to commands."""

    address = Address(address)
    ack = "ack.{}.{}".format(address.id, topic)
    direct_ack = "{}.{}.direct_ack".format(address.id, topic)
    return [
        TopicItem(ack, cmd_kwargs(cmd1, cmd2, user_data), 0.25),
        TopicItem(direct_ack, cmd_kwargs(cmd1, cmd2, user_data, target), 0.25),
    ]
Exemple #25
0
 async def async_setup(self):
     """Set up the test."""
     self.state_value = None
     self.address = Address("1a2b3c")
     self.device = DimmableLightingControl(self.address, 0x01, 0x02, 0x03,
                                           "Test", "Modem 1")
     self.device.groups[1].subscribe(self.state_updated)
     set_log_levels(
         logger="info",
         logger_pyinsteon="info",
         logger_messages="info",
         logger_topics=True,
     )
 async def async_load(self, *args, **kwargs):
     """Load the mock devices."""
     if self._connected:
         addr0 = Address("AA.AA.AA")
         addr1 = Address("11.11.11")
         addr2 = Address("22.22.22")
         addr3 = Address("33.33.33")
         self._devices[addr0] = Hub(addr0)
         self._devices[addr1] = MockSwitchLinc(addr1, 0x02, 0x00)
         self._devices[addr2] = GeneralController_MiniRemote_4(
             addr2, 0x00, 0x00)
         self._devices[addr3] = SwitchedLightingControl_SwitchLinc(
             addr3, 0x02, 0x00)
         for device in [
                 self._devices[addr] for addr in [addr1, addr2, addr3]
         ]:
             device.async_read_config = AsyncMock()
         for device in [self._devices[addr] for addr in [addr2, addr3]]:
             device.async_status = AsyncMock()
         self._devices[addr1].async_status = AsyncMock(
             side_effect=AttributeError)
         self.modem = self._devices[addr0]
 def setUp(self):
     """Set up the TestCancelAllLinking tests."""
     self.hex = "02620102030011ff"
     self.address = Address("010203")
     self.cmd1 = 0x11
     self.cmd2 = 0xFF
     kwargs = {
         "address": self.address,
         "cmd1": self.cmd1,
         "cmd2": self.cmd2
     }
     super(TestSendStandard, self).base_setup(MessageId.SEND_STANDARD,
                                              unhexlify(self.hex), **kwargs)
def fill_rec(flags, group, target, data1, data2, data3):
    """Fill an All-Link Record."""
    from pyinsteon.data_types.all_link_record_flags import AllLinkRecordFlags

    kwargs = {
        "flags": AllLinkRecordFlags(flags),
        "group": group,
        "target": Address(target),
        "data1": data1,
        "data2": data2,
        "data3": data3,
    }
    return kwargs
    async def test_id_awake_device(self):
        """Test an awake device is recognized."""
        self._id_mgr = DeviceIdManager()
        address = Address("010101")
        off, ack, dir_ack, response = self._set_topics(address)
        topic_item_1 = TopicItem(
            off, cmd_kwargs(0x10, 0x00, None, Address("000001")), 1)
        topic_item_2 = TopicItem(ack, cmd_kwargs(0x10, 0x00, None, None), 0.5)
        topic_item_3 = TopicItem(
            dir_ack, cmd_kwargs(0x10, 0x00, None, self._modem_address, None,
                                3), 0.5)
        topic_item_4 = TopicItem(
            response, cmd_kwargs(0x10, 0x12, None, self._target, None, 3), 0.5)
        topic_data = [topic_item_1, topic_item_2, topic_item_3, topic_item_4]

        self._id_mgr.start()
        self._id_mgr.append(address)
        send_topics(topic_data)
        await asyncio.sleep(3.5)
        device_id = self._id_mgr[address]
        assert device_id.cat == self._cat
        self._id_mgr.close()
        await asyncio.sleep(0.1)
    def fill_properties(self, address, props_dict):
        """Fill the operating flags and extended properties of a device."""
        device = self._devices[Address(address)]
        operating_flags = props_dict.get("operating_flags", {})
        properties = props_dict.get("properties", {})

        for flag in operating_flags:
            value = operating_flags[flag]
            if device.operating_flags.get(flag):
                device.operating_flags[flag].load(value)
        for flag in properties:
            value = properties[flag]
            if device.properties.get(flag):
                device.properties[flag].load(value)