diff --git a/lifx/client.py b/lifx/client.py index dc397a8..8360b88 100644 --- a/lifx/client.py +++ b/lifx/client.py @@ -169,11 +169,12 @@ def poll_devices(self): for device in filter(lambda x:x.seen_ago > poll_delta, self._devices.values()): device.send_poll_packet() - def get_devices(self, max_seen=None): + def get_devices(self, max_seen=None, refine=None): """ Get a list of all responding devices. :param max_seen: The number of seconds since the device was last seen, defaults to 3 times the devicepoll interval. + :param refine: Filter list of devices using this function """ if max_seen is None: max_seen = self._devicepolltime * MISSED_POLLS @@ -182,6 +183,19 @@ def get_devices(self, max_seen=None): devices = filter(lambda x:x.seen_ago < seen_delta, self._devices.values()) + if refine is None: + refine = lambda x: True + + alive = [] + for d in devices: + try: + d.label + if refine(d): + alive.append(d) + except device.DeviceTimeoutError: + pass + devices = alive + # Sort by device id to ensure consistent ordering return sorted(devices, key=lambda k:k.id) @@ -227,7 +241,7 @@ def by_label(self, label): :param by_label: The label we are looking for. :returns: list -- The devices that match criteria """ - return filter(lambda d: d.label == label, self.get_devices()) + return self.get_devices(refine=lambda d: d.label == label) def by_id(self, id): """ @@ -236,7 +250,7 @@ def by_id(self, id): :param id: The device id :returns: Device -- The device with the matching id. """ - return filter(lambda d: d.id == id, self.get_devices())[0] + return self.get_devices(refine=lambda d: d.id == id) def by_power(self, power): """ @@ -245,7 +259,7 @@ def by_power(self, power): :param power: True returns all devices that are on, False returns ones that are off. :returns: list -- The devices that match criteria """ - return filter(lambda d: d.power == power, self.get_devices()) + return self.get_devices(refine=lambda d: d.power == power) def by_group_id(self, group_id): """ @@ -254,7 +268,7 @@ def by_group_id(self, group_id): :param group_id: The group id to match on each light. :returns: list -- The devices that match criteria """ - return filter(lambda d: d.group_id == group_id, self.get_devices()) + return self.get_devices(refine=lambda d: d.group_id == group_id) def by_location_id(self, location_id): """ @@ -263,7 +277,7 @@ def by_location_id(self, location_id): :param group_id: The group id to match on each light. :returns: list -- The devices that match criteria """ - return filter(lambda d: d.location_id == location_id, self.get_devices()) + return self.get_devices(refine=lambda d: d.location_id == location_id) def __getitem__(self, key): return self.get_devices()[key] diff --git a/lifx/device.py b/lifx/device.py index 230f978..a580571 100644 --- a/lifx/device.py +++ b/lifx/device.py @@ -27,6 +27,7 @@ def __init__(self, device_id, host, client): # Our Device self._device_id = device_id self._host = host + self._label = None # Services self._services = {} @@ -51,6 +52,7 @@ def _seq(self): def _packethandler(self, host, port, packet): self._seen() + self._host = host # If it was a service packet if packet.protocol_header.pkt_type == protocol.TYPE_STATESERVICE: @@ -257,13 +259,16 @@ def label(self): """ The label for the device, setting this will change the label on the device. """ - response = self._block_for_response(pkt_type=protocol.TYPE_GETLABEL) - return protocol.bytes_to_label(response.label) + if self._label is None: + response = self._block_for_response(pkt_type=protocol.TYPE_GETLABEL) + self._label = protocol.bytes_to_label(response.label) + return self._label @label.setter def label(self, label): newlabel = bytearray(label.encode('utf-8')[0:protocol.LABEL_MAXLEN]) + self._label = newlabel return self._block_for_ack(newlabel, pkt_type=protocol.TYPE_SETLABEL) def fade_power(self, power, duration=DEFAULT_DURATION):