async def test_status_command(self): """Test Status Request command.""" cmd1 = 0x19 cmd2 = 0x00 db_version = 0x22 status = 0x33 topics = [ TopicItem(self.ack_topic, { "cmd1": cmd1, "cmd2": cmd2, "user_data": None }, 0.5), TopicItem( self.direct_ack_topic, { "cmd1": db_version, "cmd2": status, "target": "112233", "user_data": None, "hops_left": 3, }, 0.5, ), ] send_topics(topics) assert await self.status_command.async_send() await asyncio.sleep(1) assert self._db_version == db_version assert self._status == status
async def test_on_level_nak(self): """Test the ON command.""" await self.async_setup() cmd1 = 0x11 cmd2 = 0xAA ack_topic = "ack.{}.{}.on.direct".format(self._address.id, 3) direct_nak_topic = "{}.on.direct_nak".format(self._address.id) topics = [ TopicItem( ack_topic, {"cmd1": cmd1, "cmd2": cmd2, "user_data": {"d1": 3}}, 0.5 ), TopicItem( direct_nak_topic, { "cmd1": cmd1, "cmd2": cmd2, "target": "4d5e6f", "user_data": None, "hops_left": 3, }, 0.5, ), ] send_topics(topics) response = await self.handler3.async_send(on_level=cmd2) assert response == ResponseStatus.UNCLEAR
async def _execute_command(self, device_type, command, config): address = random_address() params = config["params"] for param in params: params[param] = convert_to_int(params[param]) if config.get("response"): topic_item = convert_response(config["response"], address) else: topic_item = None device_class = getattr(device_types, device_type) try: device = device_class(address=address, cat=0x01, subcat=0x02, description=device_type) method = getattr(device, command) if topic_item: send_topics([topic_item]) result = await method(**params) assert int(result) == 1 # pylint: disable=broad-except except Exception as ex: _LOGGER.error("Failed: device: %s command: %s", device_type, command) _LOGGER.error(ex) assert False
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_status_request_hub(self): """Test a status request coming from the Hub. This starts with an ACK message rather than a send() command. """ cmd1 = 0x19 cmd2 = 0x00 db_version = 0x44 status = 0x55 topics = [ TopicItem(self.ack_topic, { "cmd1": cmd1, "cmd2": cmd2, "user_data": None }, 0.1), TopicItem( self.direct_ack_topic, { "cmd1": db_version, "cmd2": status, "target": "aabbcc", "user_data": None, "hops_left": 3, }, 0.2, ), ] send_topics(topics) await asyncio.sleep(0.5) assert self._db_version == db_version assert self._status == status
async def test_other_status(self): """Test other status command and confirm first handler does not handle.""" status_type = 1 status_1_command = StatusRequestCommand(self._address, status_type=status_type) status_1_command.subscribe(self.set_status_1) cmd1 = 0x19 cmd2 = 0x01 db_version = 0x66 status = 0x77 topics = [ TopicItem(self.ack_topic, { "cmd1": cmd1, "cmd2": cmd2, "user_data": None }, 0.5), TopicItem( self.direct_ack_topic, { "cmd1": db_version, "cmd2": status, "target": "112233", "user_data": None, "hops_left": 3, }, 0.5, ), ] send_topics(topics) assert await status_1_command.async_send() await asyncio.sleep(1) assert self._db_version_1 == db_version assert self._status_1 == status assert self._db_version is None assert self._status is None
async def test_on_level_group(self): """Test the ON command.""" await self.async_setup() cmd1 = 0x11 cmd2 = 0xAA self._on_level_1 = None self._on_level_2 = None self._on_level_3 = None ack_topic = "ack.{}.{}.on.direct".format(self._address.id, 2) direct_ack_topic = "{}.on.direct_ack".format(self._address.id) topics = [ TopicItem( ack_topic, {"cmd1": cmd1, "cmd2": cmd2, "user_data": {"d1": 2}}, 0.5 ), TopicItem( direct_ack_topic, { "cmd1": cmd1, "cmd2": cmd2, "target": "4d5e6f", "user_data": None, "hops_left": 3, }, 0.5, ), ] send_topics(topics) assert await self.handler2.async_send(on_level=cmd2) assert self._on_level_1 is None assert self._on_level_2 == cmd2 assert self._on_level_3 is None
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
async def test_x10_dimmable(self): """Test X10 Dimmable device.""" set_log_levels( logger="info", logger_pyinsteon="info", logger_messages="info", logger_topics=False, ) device = X10Dimmable("c", 3) ack = "ack.{}".format(X10_SEND) hc_uc = bytes(bytearray([HC_LOOKUP["c"], UC_LOOKUP[3]])) uc_msg = {"raw_x10": hc_uc, "x10_flag": X10CommandType.UNITCODE} hc_cmd = bytes(bytearray([HC_LOOKUP["c"], int(X10Commands.BRIGHT)])) cmd_msg = {"raw_x10": hc_cmd, "x10_flag": X10CommandType.COMMAND} msgs = [ TopicItem(ack, uc_msg, 0.1), TopicItem(ack, cmd_msg, 0.1), TopicItem(ack, uc_msg, 0.1), TopicItem(ack, cmd_msg, 0.1), TopicItem(ack, uc_msg, 0.1), TopicItem(ack, cmd_msg, 0.1), TopicItem(ack, uc_msg, 0.1), TopicItem(ack, cmd_msg, 0.1), ] send_topics(msgs) result = await device.async_on(on_level=45) assert result == ResponseStatus.SUCCESS assert device.groups[1].value == 44
async def test_id_request_nak(self): """Test the ON command.""" await self.async_setup() cmd1 = 0x99 cmd2 = 0xAA topics = [ TopicItem(self.ack_topic, { "cmd1": cmd1, "cmd2": cmd2, "user_data": None }, 0.5), TopicItem( self.direct_nak_topic, { "cmd1": cmd1, "cmd2": cmd2, "target": "aabbcc", "user_data": None, "hops_left": 3, }, 0.5, ), ] send_topics(topics) result = await self.id_handler.async_send() assert result == ResponseStatus.UNCLEAR
async def test_dup_on_same_hops_gt_1_sec(self): """Test two messages same hops gt 1 seconds => 2 calls.""" topics = [self.create_topic(3, 2, 0.1), self.create_topic(3, 2, 1.1)] on_handler = OnLevelInbound(self.address, 3) on_handler.subscribe(self.handle_on_topic) send_topics(topics) await sleep(1.3) assert self.call_count == 2
async def test_dup_on_reduce_hops_gt_2_sec(self): """Test two messages with hops reduction gt two seconds => 2 calls.""" topics = [self.create_topic(3, 3, 0.1), self.create_topic(3, 2, 2.1)] on_handler = OnLevelInbound(self.address, 3) on_handler.subscribe(self.handle_on_topic) send_topics(topics) await sleep(2.4) assert self.call_count == 2
async def test_dup_on_gt_2_sec(self): """Test two messages outside two seconds => 2 calls.""" topics = [self.create_topic(3, 3, 0.1), self.create_topic(3, 3, 2.2)] on_handler = OnLevelInbound(self.address, 3) on_handler.subscribe(self.handle_on_topic) send_topics(topics) await sleep(2.5) assert self.call_count == 2
async def test_dup_on(self): """Test two messages with Hops reduction within 2 seconds => 1 call.""" topics = [self.create_topic(3, 3, 0.1), self.create_topic(3, 2, 0.9)] on_handler = OnLevelInbound(self.address, 3) on_handler.subscribe(self.handle_on_topic) send_topics(topics) await sleep(2) assert self.call_count == 1
async def test_dup_on_increase_hops_lt_2_sec(self): """Test two messages increase hops within 2 seconds => 2 calls.""" topics = [self.create_topic(3, 2, 0.1), self.create_topic(3, 3, 0.9)] on_handler = OnLevelInbound(self.address, 3) on_handler.subscribe(self.handle_on_topic) send_topics(topics) await sleep(1.3) assert self.call_count == 2
async def run_test(self, topics, on_level_expected, call_count_expected): """Run the test and validate outcomes.""" sleep_for = 0.2 for topic in topics: sleep_for += topic.delay send_topics(topics) await sleep(sleep_for) assert self.on_level == on_level_expected assert self.call_count == call_count_expected
async def test_async_send(self): """Test the async_send method.""" topics = [ TopicItem(self.ack_message, { "mode": AllLinkMode.CONTROLLER, "group": 0x01 }, 0.5) ] send_topics(topics) assert await self.handler.async_send(mode=AllLinkMode.CONTROLLER, group=0x01)
async def test_async_send(self): """Test the async_send method.""" topics = [ TopicItem( "ack.send_all_link_command", {"group": 0x01, "cmd1": 0x11, "cmd2": 0x00}, 0.5, ) ] send_topics(topics) assert await self.handler.async_send(group=0x01, cmd1=0x11, cmd2=0x00)
async def test_async_send(self): """Test the async_send method.""" self.handler = SendAllLinkCommandHandler() topics = [ TopicItem( "ack.send_all_link_command", {"group": 0x01, "cmd1": 0x11, "cmd2": 0x00}, 0.5, ) ] send_topics(topics) response = await self.handler.async_send(group=0x01, cmd1=0x11, cmd2=0x00) assert response == ResponseStatus.SUCCESS
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_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)
async def test_hb_off(self): """Test the heartbeat on message.""" off = TopicItem( self._off_topic, { "cmd1": 0x13, "cmd2": 0x00, "target": Address("000004"), "user_data": None, "hops_left": 3, }, 0.05, ) send_topics([off]) await asyncio.sleep(0.1) assert not self._heartbeat assert not self._heartbeat_off assert self._heartbeat_on is None
async def test_no_direct_ack(self): """Test no direct ACK received.""" orig_timeout = pyinsteon.handlers.TIMEOUT pyinsteon.handlers.TIMEOUT = 0.1 cmd1 = 0x99 cmd2 = 0xAA topics = [ TopicItem(self.ack_topic, { "cmd1": cmd1, "cmd2": cmd2, "user_data": None }, 0.2) ] send_topics(topics) assert await self.handler.async_send(on_level=cmd2 ) == ResponseStatus.FAILURE assert self._on_level is None pyinsteon.handlers.TIMEOUT = orig_timeout
async def test_hb_on(self): """Test the heartbeat on message.""" await self.async_setup() on = TopicItem( self._on_topic, { "cmd1": 0x11, "cmd2": 0xFF, "target": Address("000004"), "user_data": None, "hops_left": 3, }, 0.05, ) send_topics([on]) await asyncio.sleep(0.1) assert not self._heartbeat assert self._heartbeat_on assert self._heartbeat_off is None
async def test_status_with_fast_direct_ack(self): """Test STATUS REQUEST with fast direct ack response.""" response_called = False def handle_status_response(db_version, status): """Handle the ON command response.""" nonlocal response_called response_called = True set_log_levels(logger_topics=True) address = random_address() target = random_address() status_type = randint(0, 10) cmd = StatusRequestCommand(address, status_type) cmd.subscribe(handle_status_response) ack_topic = build_topic(STATUS_REQUEST, "ack", address, None, MessageFlagType.DIRECT) direct_ack_topic = build_topic(ON, None, address, None, MessageFlagType.DIRECT_ACK) ack_topic_item = TopicItem( topic=ack_topic, kwargs={ "cmd1": 0x19, "cmd2": status_type, "user_data": None }, delay=0.1, ) direct_ack_topic_item = TopicItem( topic=direct_ack_topic, kwargs={ "cmd1": 0x11, "cmd2": 0x02, "target": target, "user_data": None, "hops_left": 0, }, delay=0, ) send_topics([ack_topic_item, direct_ack_topic_item]) await asyncio.sleep(0.2) assert response_called
async def test_on_with_fast_direct_ack(self): """Test ON with fast direct ack response.""" response_called = False def handle_on_response(on_level): """Handle the ON command response.""" nonlocal response_called response_called = True set_log_levels(logger_topics=True) address = random_address() target = random_address() group = randint(0, 10) cmd = OnLevelCommand(address, group) cmd.subscribe(handle_on_response) ack_topic = build_topic(ON, "ack", address, group, MessageFlagType.DIRECT) direct_ack_topic = build_topic(ON, None, address, None, MessageFlagType.DIRECT_ACK) ack_topic_item = TopicItem( topic=ack_topic, kwargs={ "cmd1": 0x11, "cmd2": 0xFF, "user_data": None }, delay=0.1, ) direct_ack_topic_item = TopicItem( topic=direct_ack_topic, kwargs={ "cmd1": 0x11, "cmd2": 0xFF, "target": target, "user_data": None, "hops_left": 0, }, delay=0, ) send_topics([ack_topic_item, direct_ack_topic_item]) await asyncio.sleep(0.2) assert response_called
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
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_request(self): """Test ID Request command.""" await self.async_setup() cmd1 = 0x99 cmd2 = 0xAA topics = [ TopicItem(self.ack_topic, { "cmd1": cmd1, "cmd2": cmd2, "user_data": None }, 0.5), TopicItem( self.direct_ack_topic, { "cmd1": cmd1, "cmd2": cmd2, "target": "112233", "user_data": None, "hops_left": 3, }, 0.5, ), TopicItem( self.id_response_topic, { "cmd1": cmd1, "cmd2": cmd2, "target": Address("010203"), "user_data": None, "hops_left": 3, }, 0.5, ), ] send_topics(topics) assert await self.id_handler.async_send() await asyncio.sleep(1) assert self._cat == 1 assert self._subcat == 2 assert self._firmware == 3
async def test_x10_sensor(self): """Test X10 Sensor device.""" set_log_levels( logger="info", logger_pyinsteon="info", logger_messages="info", logger_topics=False, ) device = X10OnOffSensor("a", 1) hc_uc = (HC_LOOKUP["a"] << 4) + UC_LOOKUP[1] uc_msg = {"raw_x10": hc_uc, "x10_flag": X10CommandType.UNITCODE} hc_cmd = (HC_LOOKUP["a"] << 4) + int(X10Commands.ON) cmd_msg = {"raw_x10": hc_cmd, "x10_flag": X10CommandType.COMMAND} msgs = [ TopicItem(X10_RECEIVED, uc_msg, 0.1), TopicItem(X10_RECEIVED, cmd_msg, 0.1), ] send_topics(msgs) await asyncio.sleep(1) assert device.groups[1].value == 0xFF