async def test_off_command(self): """Test an OFF message.""" state_values = {} def state_updated(value, group, name, address): """Run when the state is updated.""" nonlocal state_values state_values[group] = value address = random_address() device = DimmableLightingControl_KeypadLinc_8(address, 0x01, 0x02, 0x03, "Test", "KPL") for button in device.groups: device.groups[button].set_value(255) device.groups[button].subscribe(state_updated) cmd1 = 0x13 cmd2 = 0x00 target = device.address user_data = None ack = "ack.{}.1.{}.direct".format(device.address.id, OFF) direct_ack = "{}.{}.direct_ack".format(device.address.id, OFF) responses = [ TopicItem(ack, cmd_kwargs(cmd1, cmd2, user_data), 0.25), TopicItem(direct_ack, cmd_kwargs(cmd1, cmd2, user_data, target), 0.25), ] send_topics(responses) response = await device.async_off(fast=False) assert response == ResponseStatus.SUCCESS assert state_values.get(1) == cmd2 for button in device.groups: if button == 1: continue assert state_values.get(2) is None
async def test_off_and_off_cleanup(self): """Test one off and one off cleanup => on_level = 255 and call_count = 1.""" kwargs0 = cmd_kwargs(0x13, 0x00, None, self.target, hops_left=3) kwargs1 = cmd_kwargs(0x13, 0x00, None, self.target, hops_left=3) topics = [ self.create_topic(OFF, MessageFlagType.ALL_LINK_BROADCAST, 6, kwargs0, 0.1), self.create_topic(OFF, MessageFlagType.ALL_LINK_CLEANUP, 6, kwargs1, 0.3), ] await self.run_test(topics, 0, 1)
async def test_on_then_off(self): """Test one on and one off message => on_level = 0 & call_count = 2.""" kwargs0 = cmd_kwargs(0x11, 0x00, None, self.target, hops_left=3) kwargs1 = cmd_kwargs(0x13, 0x00, None, self.target, hops_left=3) topics = [ self.create_topic(ON, MessageFlagType.ALL_LINK_BROADCAST, 6, kwargs0, 0.1), self.create_topic(OFF, MessageFlagType.ALL_LINK_BROADCAST, 6, kwargs1, 0.3), ] await self.run_test(topics, 0, 2)
async def test_off_fast_2_msg_reduce_hops(self): """Test two Off_fast messages within 2 sec => on_level = 255 & call_count = 1.""" kwargs0 = cmd_kwargs(0x14, 0x00, None, self.target, hops_left=3) kwargs1 = cmd_kwargs(0x14, 0x00, None, self.target, hops_left=2) topics = [ self.create_topic(OFF_FAST, MessageFlagType.ALL_LINK_BROADCAST, 6, kwargs0, 0.1), self.create_topic(OFF_FAST, MessageFlagType.ALL_LINK_BROADCAST, 6, kwargs1, 0.3), ] await self.run_test(topics, 0, 1)
async def test_id_device(self): """Test device identification.""" address = Address("040404") _, ack, dir_ack, response = self._set_topics(address) topic_item_1 = TopicItem(ack, cmd_kwargs(0x10, 0x00, None, None), 1) topic_item_2 = TopicItem( dir_ack, cmd_kwargs(0x10, 0x00, None, self._modem_address), 0.5 ) topic_item_3 = TopicItem( response, cmd_kwargs(0x10, 0x12, None, self._target), 0.5 ) topic_data = [topic_item_1, topic_item_2, topic_item_3] send_topics(topic_data) device_id = await self._id_mgr.async_id_device(address) assert device_id.cat == self._cat
async def test_off_fast(self): """Test Off message => on_level = 0 & call_count = 1.""" kwargs = cmd_kwargs(0x14, 0x00, None, self.target, hops_left=3) topics = [ self.create_topic(OFF_FAST, MessageFlagType.ALL_LINK_BROADCAST, 6, kwargs, 0.1) ] await self.run_test(topics, 0, 1)
async def test_on(self): """Test On message => on_level = 255 & call_count = 1.""" kwargs = cmd_kwargs(0x11, 0x00, None, self.target, hops_left=3) topics = [ self.create_topic(ON, MessageFlagType.ALL_LINK_BROADCAST, 6, kwargs, 0.1) ] await self.run_test(topics, 255, 1)
async def test_on_fast_cleanup(self): """Test On_fast All-Link Cleanup message => on_level = 255 & call_count = 1.""" kwargs = cmd_kwargs(0x12, 0x00, None, self.target, hops_left=3) topics = [ self.create_topic(ON_FAST, MessageFlagType.ALL_LINK_CLEANUP, 6, kwargs, 0.1) ] await self.run_test(topics, 255, 1)
async def test_off_cleanup(self): """Test Off All-Link Cleanup message => on_level = 0 & call_count = 1.""" kwargs = cmd_kwargs(0x13, 0x00, None, self.target, hops_left=3) topics = [ self.create_topic(OFF, MessageFlagType.ALL_LINK_CLEANUP, 6, kwargs, 0.1) ] await self.run_test(topics, 0, 1)
async def test_off_command(self): """Test an ON message.""" self.device.groups[1].value = 255 cmd1 = 0x22 cmd2 = 0x23 target = Address("4d5e6f") user_data = None ack = "ack.{}.1.{}.direct".format(self.device.address.id, OFF) direct_ack = "{}.{}.direct_ack".format(self.device.address.id, OFF) responses = [ TopicItem(ack, cmd_kwargs(cmd1, cmd2, user_data), 0.25), TopicItem(direct_ack, cmd_kwargs(cmd1, cmd2, user_data, target), 0.25), ] send_topics(responses) response = await self.device.async_off(fast=False) assert response == ResponseStatus.SUCCESS assert self.state_value == 0x00
def create_topic(self, group, hops, delay): """Create a TopicItem.""" group = 3 cmd1 = 0x11 cmd2 = 0x00 target = "0000{:02d}".format(group) kwargs = cmd_kwargs( cmd1=cmd1, cmd2=cmd2, user_data=None, target=target, hops_left=hops ) return TopicItem(ON_MSG.format(self.address, group), kwargs=kwargs, delay=delay)
async def test_on_fast_command(self): """Test an ON message.""" await self.async_setup() self.device.groups[1].value = 0 cmd1 = 0x22 cmd2 = 0x23 target = Address("4d5e6f") user_data = None ack = "ack.{}.1.{}.direct".format(self.device.address.id, ON_FAST) direct_ack = "{}.{}.direct_ack".format(self.device.address.id, ON_FAST) responses = [ TopicItem(ack, cmd_kwargs(cmd1, cmd2, user_data), 0.25), TopicItem(direct_ack, cmd_kwargs(cmd1, cmd2, user_data, target), 0.25), ] send_topics(responses) response = await self.device.async_on(on_level=cmd2, fast=True) assert response == ResponseStatus.SUCCESS assert self.state_value == cmd2
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 create_topic(topic, address, group, hops, delay): """Create a TopicItem.""" cmd1 = 0x11 cmd2 = 0x00 target = "0000{:02d}".format(group) kwargs = cmd_kwargs(cmd1=cmd1, cmd2=cmd2, user_data=None, target=target, hops_left=hops) if topic in [ASSIGN_TO_ALL_LINK_GROUP, DELETE_FROM_ALL_LINK_GROUP]: msg_topic = MSG_NO_GROUP.format(address.id, topic) else: msg_topic = MSG.format(address.id, group, topic) return TopicItem(msg_topic, kwargs=kwargs, delay=delay)
async def test_data_update(self): """Test data updates.""" self._properties["prop3"] = self._epm.create("prop3", 1, 3, None, None) self._properties["prop4"] = self._epm.create("prop4", 1, 4, None, None) self._properties["prop5"] = self._epm.create("prop5", 1, 5, None, None) self._properties["prop6"] = self._epm.create("prop6", 1, 6, None, None) self._properties["prop7"] = self._epm.create("prop7", 1, 7, None, None) self._properties["prop8"] = self._epm.create("prop8", 1, 8, None, None) self._properties["prop9"] = self._epm.create("prop9", 1, 9, None, None) self._properties["prop100"] = self._epm.create("prop100", 1, 10, 0, None) self._properties["prop101"] = self._epm.create("prop101", 1, 10, 1, None) self._properties["prop102"] = self._epm.create("prop102", 1, 10, 2, None) self._properties["prop103"] = self._epm.create("prop103", 1, 10, 3, None) user_data = UserData({ "d1": 0x01, "d2": 0x01, "d3": 0x03, "d4": 0x04, "d5": 0x05, "d6": 0x06, "d7": 0x07, "d8": 0x08, "d9": 0x09, "d10": 0x0A, "d11": 0x0B, "d12": 0x0C, "d13": 0x0D, "d14": 0x0E, }) ack = build_topic( prefix="ack", topic=EXTENDED_GET_SET, address=self._address, message_type="direct", ) dir_ack = build_topic(topic=EXTENDED_GET_SET, address=self._address, message_type="direct_ack") resp = build_topic(topic=EXTENDED_GET_RESPONSE, address=self._address, message_type="direct") topic_ack = TopicItem( ack, cmd_kwargs(0x2E, 0x00, UserData({ "d1": 0, "d2": 1 })), 1) topic_dir_ack = TopicItem( dir_ack, cmd_kwargs(0x2E, 0x00, None, target="030405"), 0.1) topic_resp = TopicItem( resp, cmd_kwargs(0x2E, 0x00, user_data, target="030405"), 0.2) send_topics([topic_ack, topic_dir_ack, topic_resp]) result = await self._epm.async_read(group=1) assert int(result) == 1 await asyncio.sleep(1) assert self._properties["prop3"].value == 0x03 assert self._properties["prop9"].value == 0x09 assert self._properties["prop101"].value assert not self._properties["prop102"].value
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