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_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_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_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_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_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_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 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_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_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_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_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_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
def setUp(self): """Set up the test.""" set_log_levels( logger="debug", logger_pyinsteon="info", logger_messages="info", logger_topics=False, ) _LOGGER.debug("Running setUp") self.record = 0 addr = random_address() self.topics = [ TopicItem( ALL_LINK_RECORD_RESPONSE, fill_rec(0x2E, 0x01, addr.id, 0x02, 0x03, 0x04), 0.2, ), TopicItem( ALL_LINK_RECORD_RESPONSE, fill_rec(0x2E, 0x02, addr.id, 0x02, 0x03, 0x04), 0.2, ), TopicItem( ALL_LINK_RECORD_RESPONSE, fill_rec(0x2E, 0x03, addr.id, 0x02, 0x03, 0x04), 0.2, ), TopicItem( ALL_LINK_RECORD_RESPONSE, fill_rec(0x2E, 0x04, addr.id, 0x02, 0x03, 0x04), 0.2, ), TopicItem( ALL_LINK_RECORD_RESPONSE, fill_rec(0x2E, 0x05, addr.id, 0x02, 0x03, 0x04), 0.2, ), TopicItem( ALL_LINK_RECORD_RESPONSE, fill_rec(0x2E, 0x06, addr.id, 0x02, 0x03, 0x04), 0.2, ), TopicItem( ALL_LINK_RECORD_RESPONSE, fill_rec(0x2E, 0x07, addr.id, 0x02, 0x03, 0x04), 0.2, ), TopicItem( ALL_LINK_RECORD_RESPONSE, fill_rec(0x2E, 0x08, addr.id, 0x02, 0x03, 0x04), 0.2, ), ]
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_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_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_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
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_x10_on_off(self): """Test X10 On Off device.""" set_log_levels( logger="info", logger_pyinsteon="info", logger_messages="info", logger_topics=False, ) device = X10OnOff("b", 2) ack = "ack.{}".format(X10_SEND) hc_uc = (HC_LOOKUP["b"] << 4) + UC_LOOKUP[2] uc_msg = {"raw_x10": hc_uc, "x10_flag": X10CommandType.UNITCODE} hc_cmd = (HC_LOOKUP["b"] << 4) + X10Commands.ON cmd_msg = {"raw_x10": hc_cmd, "x10_flag": X10CommandType.COMMAND} msgs = [ TopicItem(ack, uc_msg, 0.1), TopicItem(ack, cmd_msg, 0.1), ] send_topics(msgs) result = await device.async_on() assert result == ResponseStatus.SUCCESS assert device.groups[1].value == 0xFF
def convert_response(response, address): """Convert a response dict to a topic.""" topic = str(response["topic"]) topic = topic.replace("<address>", repr(address)) cmd1 = convert_to_int(response["cmd1"]) cmd2 = convert_to_int(response["cmd2"]) target = Address(response["target"]) kwargs = { "cmd1": cmd1, "cmd2": cmd2, "target": target, "user_data": None, "hops_left": 3, } topic_item = TopicItem(topic, kwargs, 0.02) return topic_item
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_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()