class InfoPoints(enum.Enum): """ Enum used to determine what information is required for what keys """ # We need to know what kind of product the device is to get the label correctly VERSION = Point(DeviceMessages.GetVersion(), ["label", "product_id", "cap"], None) # We get Label from LIGHT_STATE for lights and from STATE_LABEL for non lights LIGHT_STATE = Point( LightMessages.GetColor(), ["label", "power", "hue", "saturation", "brightness", "kelvin"], 10, # Non lights are unimportant enough at this time to risk sending too many messages to them condition=lambda device: device.product_type is not DeviceType.NON_LIGHT, ) LABEL = Point( DeviceMessages.GetLabel(), ["label"], 10, condition=lambda device: device.product_type is DeviceType.NON_LIGHT, ) FIRMWARE = Point(DeviceMessages.GetHostFirmware(), ["firmware_version"], 300) GROUP = Point(DeviceMessages.GetGroup(), ["group_id", "group_name"], 60) LOCATION = Point(DeviceMessages.GetLocation(), ["location_id", "location_name"], 60)
class InfoPoints(enum.Enum): """ Enum used to determine what information is required for what keys """ LIGHT_STATE = Point( LightMessages.GetColor(), ["label", "power", "hue", "saturation", "brightness", "kelvin"]) VERSION = Point(DeviceMessages.GetVersion(), ["product_id", "product_identifier", "cap"]) FIRMWARE = Point(DeviceMessages.GetHostFirmware(), ["firmware_version"]) GROUP = Point(DeviceMessages.GetGroup(), ["group_id", "group_name"]) LOCATION = Point(DeviceMessages.GetLocation(), ["location_id", "location_name"])
"product_name": "LIFX A19", "product_type": "light", "group_name": "g1", "location_id": "bb000000000000000000000000000000", "location_name": "l1", } for device in V.devices: if device is V.d3: V.devices.store(device).assertIncoming( DiscoveryMessages.GetService(), LightMessages.GetColor(), DeviceMessages.GetVersion(), DeviceMessages.GetHostFirmware(), DeviceMessages.GetGroup(), DeviceMessages.GetLocation(), ) elif device is V.d4: V.devices.store(device).assertIncoming( DiscoveryMessages.GetService(), DeviceMessages.GetVersion(), LightMessages.GetColor(), DeviceMessages.GetLabel(), ) else: V.devices.store(device).assertIncoming( DiscoveryMessages.GetService(), DeviceMessages.GetVersion(), LightMessages.GetColor(), ) V.devices.store(device).clear()
async def checker(): info = {"serial": V.fake_device.serial} await futs[1] assert V.device.info == info await asyncio.wait(all_futs) assert V.t.time == len(all_futs) - 1 V.received(*msgs) info.update( { "label": "kitchen", "power": "off", "hue": 0.0, "saturation": 1.0, "brightness": 1.0, "kelvin": 3500, "firmware_version": "2.80", "product_id": 27, "product_identifier": "lifx_a19", "cap": [ "color", "not_chain", "not_ir", "not_matrix", "not_multizone", "variable_color_temp", ], "group_id": "aa000000000000000000000000000000", "group_name": "g1", } ) assert V.device.info == info await asyncio.wait([Futs.color]) V.received( LightMessages.GetColor(), keep_duplicates=True, ) if V.t.time == 16: V.t.set(15) assert V.t.time == len(all_futs) + 10 await asyncio.wait([Futs.group, Futs.location]) V.received( *([LightMessages.GetColor()] * 3), DeviceMessages.GetGroup(), DeviceMessages.GetLocation(), keep_duplicates=True, ) # First location was at t=4 # We then wait until at least 64 # 60 is at 12 rounds, and next location after that is after 5 assert V.t.time >= 69 assert V.device.point_futures[InfoPoints.LIGHT_STATE].result() == 61 await asyncio.wait([Futs.color]) V.received( LightMessages.GetColor(), keep_duplicates=True, ) assert V.t.time <= 76 await asyncio.wait([Futs.firmware]) # First firmware was at t=2 # So next refresh after 102 # So needs a full cycle after that assert V.t.time >= 107 V.received( LightMessages.GetColor(), LightMessages.GetColor(), DeviceMessages.GetHostFirmware(), keep_duplicates=True, )
async def checker(ff, l): info = {"serial": V.fake_device.serial, "product_type": "unknown"} assert V.device.info == info await hp.wait_for_all_futures( *[V.device.point_futures[kls] for kls in InfoPoints if kls is not InfoPoints.LABEL] ) found = [] for kls in list(InfoPoints): if kls is not InfoPoints.LABEL: found.append(V.device.point_futures[kls].result()) assert found == [1, 2, 3, 4, 5] assert V.t.time == 5 V.received(*msgs) info.update( { "label": "kitchen", "power": "off", "hue": 0.0, "saturation": 0.0, "brightness": 1.0, "kelvin": 3500, "firmware_version": "2.80", "product_id": 27, "product_name": "LIFX A19", "product_type": "light", "cap": pytest.helpers.has_caps_list("color", "variable_color_temp"), "group_id": "aa000000000000000000000000000000", "group_name": "g1", "location_id": "bb000000000000000000000000000000", "location_name": "l1", } ) assert V.device.info == info await hp.wait_for_all_futures(Futs.color) V.received(LightMessages.GetColor(), keep_duplicates=True) assert V.t.time == 12 await hp.wait_for_all_futures(Futs.group, Futs.location) V.received( *([LightMessages.GetColor()] * 5), DeviceMessages.GetGroup(), DeviceMessages.GetLocation(), keep_duplicates=True, ) # First location was at t=5 # We then wait another 60 # 60 is at 12 rounds, and next location after that is after 5 assert V.t.time == 65 # Now we remove knowledge of the device # And expect the information loop to end assert V.device.serial in V.sender.found async with V.fake_device.offline(): with assertRaises(FoundNoDevices): await FoundSerials().find(V.sender, timeout=1) assert V.device.serial not in V.sender.found assert not l.done() # This will timeout if it hasn't ended await l ff.cancel()
async def checker(ff): info = {"serial": V.fake_device.serial, "product_type": "unknown"} assert V.device.info == info await hp.wait_for_all_futures( *[ V.device.point_futures[kls] for kls in InfoPoints if kls is not InfoPoints.LIGHT_STATE ] ) found = [] for kls in list(InfoPoints): if kls is not InfoPoints.LIGHT_STATE: found.append(V.device.point_futures[kls].result()) assert found == [1, 2, 3, 4, 5] assert V.t.time == 5 V.received(*msgs) info.update( { "label": "switcharoo", "firmware_version": "3.90", "product_id": 89, "product_name": "LIFX Switch", "product_type": "non_light", "cap": pytest.helpers.has_caps_list("buttons", "unhandled", "relays"), "group_id": "aa000000000000000000000000000000", "group_name": "g1", "location_id": "bb000000000000000000000000000000", "location_name": "l1", } ) assert V.device.info == info await hp.wait_for_all_futures(Futs.label) V.received(DeviceMessages.GetLabel(), keep_duplicates=True) assert V.t.time == 12 await hp.wait_for_all_futures(Futs.group, Futs.location) V.received( *([DeviceMessages.GetLabel()] * 5), DeviceMessages.GetGroup(), DeviceMessages.GetLocation(), keep_duplicates=True, ) # First location was at t=5 # We then wait another 60 # 60 is at 12 rounds, and next location after that is after 5 assert V.t.time == 65 assert V.device.point_futures[InfoPoints.LABEL].result() == 62 await hp.wait_for_all_futures(Futs.label) V.received(DeviceMessages.GetLabel(), keep_duplicates=True) # 62 + 10 = 72 assert V.t.time == 72 await hp.wait_for_all_futures(Futs.firmware) assert V.device.point_futures[InfoPoints.LABEL].result() == 102 assert V.t.time == 103 V.received( DeviceMessages.GetLabel(), DeviceMessages.GetLabel(), DeviceMessages.GetLabel(), DeviceMessages.GetHostFirmware(), keep_duplicates=True, ) ff.cancel()
async def checker(ff): info = {"serial": V.fake_device.serial, "product_type": "unknown"} assert V.device.info == info await hp.wait_for_all_futures( *[V.device.point_futures[kls] for kls in InfoPoints if kls is not InfoPoints.LABEL] ) found = [] for kls in list(InfoPoints): if kls is not InfoPoints.LABEL: found.append(V.device.point_futures[kls].result()) assert found == [1, 2, 3, 4, 5] assert V.t.time == 5 V.received(*msgs) info.update( { "label": "kitchen", "power": "off", "hue": 0.0, "saturation": 0.0, "brightness": 1.0, "kelvin": 3500, "firmware_version": "2.80", "product_id": 27, "product_name": "LIFX A19", "product_type": "light", "cap": pytest.helpers.has_caps_list("color", "variable_color_temp"), "group_id": "aa000000000000000000000000000000", "group_name": "g1", "location_id": "bb000000000000000000000000000000", "location_name": "l1", } ) assert V.device.info == info await hp.wait_for_all_futures(Futs.color) V.received(LightMessages.GetColor(), keep_duplicates=False) assert V.t.time == 12 await hp.wait_for_all_futures(Futs.group, Futs.location) V.received( *([LightMessages.GetColor()] * 5), DeviceMessages.GetGroup(), DeviceMessages.GetLocation(), keep_duplicates=True, ) # First location was at t=5 # We then wait another 60 # 60 is at 12 rounds, and next location after that is after 5 assert V.t.time == 65 assert V.device.point_futures[InfoPoints.LIGHT_STATE].result() == 62 await hp.wait_for_all_futures(Futs.color) V.received(LightMessages.GetColor(), keep_duplicates=True) # 62 + 10 = 72 assert V.t.time == 72 await hp.wait_for_all_futures(Futs.firmware) assert V.device.point_futures[InfoPoints.LIGHT_STATE].result() == 102 assert V.t.time == 103 V.received( LightMessages.GetColor(), LightMessages.GetColor(), LightMessages.GetColor(), DeviceMessages.GetHostFirmware(), keep_duplicates=True, ) ff.cancel()
async it "responds to group", device: getter = DeviceMessages.GetGroup() state = DeviceMessages.StateGroup(group="abcd", label="gl", updated_at=1) await device.assertResponse(getter, [state]) setter = DeviceMessages.SetGroup.empty_normalise( group="dcba", label="gl2", updated_at=3 ) state = DeviceMessages.StateGroup(group=setter.group, label="gl2", updated_at=3) await device.assertResponse( setter, [state], group_label="gl2", group_uuid=setter.group, group_updated_at=3 ) await device.assertResponse(getter, [state]) async it "responds to location", device: getter = DeviceMessages.GetLocation() state = DeviceMessages.StateLocation(location="efef", label="ll", updated_at=2) await device.assertResponse(getter, [state]) setter = DeviceMessages.SetLocation.empty_normalise( location="fefe", label="ll2", updated_at=6 ) state = DeviceMessages.StateLocation( location=setter.location, label="ll2", updated_at=6 ) await device.assertResponse( setter, [state], location_label="ll2", location_uuid=setter.location, location_updated_at=6,