async def attr(collector, target, reference, artifact, **kwargs): """ Send a message to your bulb and print out all the replies. This is the same as the get_attr and set_attr commands but doesn't prefix the wanted message with get or set ``target:attr d073d5000000 get_host_firmware`` """ protocol_register = collector.configuration["protocol_register"] if artifact in (None, "", sb.NotSpecified): raise BadOption( "Please specify what you want to get\nUsage: {0} <target>:get_attr <reference> <attr_to_get>" .format(sys.argv[0])) kls = find_packet(protocol_register, artifact, "") if kls is None: raise BadOption("Sorry, couldn't a class for this message", prefix="", want=artifact) photons_app = collector.photons_app extra = photons_app.extra_as_json if "extra_payload_kwargs" in kwargs: extra.update(kwargs["extra_payload_kwargs"]) msg = kls.normalise(Meta.empty(), extra) async for pkt in target.send(msg, reference, **kwargs): print("{0}: {1}".format(pkt.serial, repr(pkt.payload)))
async def execute_task(self, **kwargs): protocol_register = self.collector.configuration["protocol_register"] if self.artifact is sb.NotSpecified: raise BadOption( f"Please specify what you want to get\nUsage: {sys.argv[0]} <target>:attr <reference> <attr_to_get>" ) kls = find_packet(protocol_register, self.artifact, "") if kls is None: raise BadOption( "Sorry, couldn't a class for this message", prefix="", want=self.artifact ) extra = self.photons_app.extra_as_json if "extra_payload_kwargs" in kwargs: extra.update(kwargs["extra_payload_kwargs"]) msg = kls.create(extra) async with self.target.session() as sender: found, serials = await self.reference.find(sender, timeout=20) self.reference.raise_on_missing(found) msg = kls.create(extra) async for pkt in sender(msg, serials, **kwargs): if len(serials) == 1: print(repr(pkt.payload)) else: print(f"{pkt.serial}: {repr(pkt.payload)}")
async def set_attr(collector, target, reference, artifact, broadcast=False, **kwargs): """ Set attributes on your globes ``target:set_attr d073d5000000 color -- '{"hue": 360, "saturation": 1, "brightness": 1}'`` This does the same thing as ``get_attr`` but will look for ``Set<Attr>`` message and initiates it with the options found after the ``--``. So in this case it will create ``SetColor(hue=360, saturation=1, brightness=1)`` and send that to the device. """ protocol_register = collector.configuration["protocol_register"] if artifact in (None, "", NotSpecified): raise BadOption( "Please specify what you want to get\nUsage: {0} <target>:set_attr <reference> <attr_to_get> -- '{{<options>}}'" .format(sys.argv[0])) kls_name = "Set{0}".format("".join(part.capitalize() for part in artifact.split("_"))) setter = None for messages in protocol_register.message_register(1024): for kls in messages.by_type.values(): if kls.__name__ == kls_name: setter = kls break if setter is None: raise BadOption( "Sorry, couldn't find the message type {0}".format(kls_name)) photons_app = collector.configuration["photons_app"] extra = photons_app.extra_as_json if "extra_payload_kwargs" in kwargs: extra.update(kwargs["extra_payload_kwargs"]) script = target.script(setter.normalise(Meta.empty(), extra)) async for pkt, _, _ in script.run_with(reference, broadcast=broadcast): print("{0}: {1}".format(pkt.serial, repr(pkt.payload)))
def resolve_reference(self, collector, task_func, reference, target): """ If the task func needs a reference and none is specified then complain if we have special_reference turned on then: * Empty or _ is seen as all serials on the network * ``typ:options`` is given to the reference_resolver_register * otherwise we return a HardCodedSerials with the provided reference Otherwise we just return whatever reference is """ empty = lambda r: r in ("", None, sb.NotSpecified) if task_func.needs_reference and empty(reference): raise BadOption("This task requires you specify a reference, please do so!", action=self.action) if task_func.special_reference: if empty(reference) or reference == "_": reference = FoundSerials() if type(reference) is str: if ":" in reference: typ, options = reference.split(":", 1) reference = collector.configuration["reference_resolver_register"].resolve(typ, options, target) if not isinstance(reference, SpecialReference): return HardCodedSerials(reference) return reference
async def get_attr(collector, target, reference, artifact, **kwargs): """ Get attributes from your globes ``target:get_attr d073d5000000 color`` Where ``d073d5000000`` is replaced with the serial of the device you are addressing and ``color`` is replaced with the attribute you want. This task works by looking at all the loaded LIFX binary protocol messages defined for the 1024 protocol and looks for ``Get<Attr>``. So if you want the ``color`` attribute, it will look for the ``GetColor`` message and send that to the device and print out the reply packet we get back. """ protocol_register = collector.configuration["protocol_register"] if artifact in (None, "", NotSpecified): raise BadOption( "Please specify what you want to get\nUsage: {0} <target>:get_attr <reference> <attr_to_get>" .format(sys.argv[0])) kls_name = "Get{0}".format("".join(part.capitalize() for part in artifact.split("_"))) getter = None for messages in protocol_register.message_register(1024): for kls in messages.by_type.values(): if kls.__name__ == kls_name: getter = kls break if getter is None: raise BadOption( "Sorry, couldn't find the message type {0}".format(kls_name)) photons_app = collector.configuration["photons_app"] extra = photons_app.extra_as_json if "extra_payload_kwargs" in kwargs: extra.update(kwargs["extra_payload_kwargs"]) script = target.script(getter.normalise(Meta.empty(), extra)) async for pkt, _, _ in script.run_with(reference, **kwargs): print("{0}: {1}".format(pkt.serial, repr(pkt.payload)))
def extra_as_json(self): options = "{}" if self.extra in (None, "", sb.NotSpecified) else self.extra try: return json.loads(options) except (TypeError, ValueError) as error: raise BadOption("The options after -- wasn't valid json", error=error)
def normalise_empty(self, meta, val=sb.NotSpecified): if not self.mandatory: if self.special: return meta.everything["collector"].reference_object(val) return sb.NotSpecified raise BadOption( "This task requires you specify a reference, please do so!", meta=meta)
async def attr_actual(collector, target, reference, artifact, **kwargs): """ Same as the attr command but prints out the actual values on the replies rather than transformed values """ protocol_register = collector.configuration["protocol_register"] if artifact in (None, "", sb.NotSpecified): raise BadOption( "Please specify what you want to get\nUsage: {0} <target>:get_attr <reference> <attr_to_get>" .format(sys.argv[0])) kls = find_packet(protocol_register, artifact, "") if kls is None: raise BadOption("Sorry, couldn't a class for this message", prefix="", want=artifact) extra = collector.photons_app.extra_as_json if "extra_payload_kwargs" in kwargs: extra.update(kwargs["extra_payload_kwargs"]) def lines(pkt, indent=" "): for field in pkt.Meta.all_names: val = pkt[field] if isinstance(val, list): yield f"{indent}{field}:" for item in val: ind = f"{indent} " ls = list(lines(item, ind)) first = list(ls[0]) first[len(indent) + 2] = "*" ls[0] = "".join(first) yield from ls else: yield f"{indent}{field}: {pkt.actual(field)}" msg = kls.normalise(Meta.empty(), extra) async for pkt in target.send(msg, reference, **kwargs): print() print(f"""{"=" * 10}: {pkt.serial}""") for line in lines(pkt): print(line)
def extra_as_json(self): options = "{}" if self.extra in (None, "", sb.NotSpecified) else self.extra location = None if options.startswith("file://"): parsed = urlparse(options) location = os.path.abspath(f"{parsed.netloc}{unquote(parsed.path)}") if not os.path.exists(location): raise BadOption(f"The path {location} does not exist") with open(location, "r") as fle: options = fle.read() try: return json.loads(options) except (TypeError, ValueError) as error: kwargs = {"error": error} if location: kwargs["read_from"] = location raise BadOption("The options after -- wasn't valid json", **kwargs)
async def execute_task(self, **kwargs): protocol_register = self.collector.configuration["protocol_register"] if self.artifact is sb.NotSpecified: raise BadOption( f"Please specify what you want to get\nUsage: {sys.argv[0]} <target>:attr_actual <reference> <attr_to_get>" ) kls = find_packet(protocol_register, self.artifact, "") if kls is None: raise BadOption( "Sorry, couldn't a class for this message", prefix="", want=self.artifact ) extra = self.photons_app.extra_as_json if "extra_payload_kwargs" in kwargs: extra.update(kwargs["extra_payload_kwargs"]) def lines(pkt, indent=" "): for field in pkt.Meta.all_names: val = pkt[field] if isinstance(val, list): yield f"{indent}{field}:" for item in val: ind = f"{indent} " ls = list(lines(item, ind)) first = list(ls[0]) first[len(indent) + 2] = "*" ls[0] = "".join(first) yield from ls else: yield f"{indent}{field}: {pkt.actual(field)}" msg = kls.create(extra) async for pkt in self.target.send(msg, self.reference, **kwargs): print() print(f"""{"=" * 10}: {pkt.serial}""") for line in lines(pkt): print(line)
async def set_attr(collector, target, reference, artifact, broadcast=False, **kwargs): """ Set attributes on your globes ``target:set_attr d073d5000000 color -- '{"hue": 360, "saturation": 1, "brightness": 1}'`` This does the same thing as ``get_attr`` but will look for ``Set<Attr>`` message and initiates it with the options found after the ``--``. So in this case it will create ``SetColor(hue=360, saturation=1, brightness=1)`` and send that to the device. """ protocol_register = collector.configuration["protocol_register"] if artifact in (None, "", sb.NotSpecified): raise BadOption( "Please specify what you want to get\nUsage: {0} <target>:set_attr <reference> <attr_to_get> -- '{{<options>}}'" .format(sys.argv[0])) setter = find_packet(protocol_register, artifact, "Set") if setter is None: raise BadOption("Sorry, couldn't a class for this message", prefix="set", want=artifact) extra = collector.photons_app.extra_as_json if "extra_payload_kwargs" in kwargs: extra.update(kwargs["extra_payload_kwargs"]) msg = setter.normalise(Meta.empty(), extra) async for pkt in target.send(msg, reference, broadcast=broadcast): print("{0}: {1}".format(pkt.serial, repr(pkt.payload)))
async def get_attr(collector, target, reference, artifact, **kwargs): """ Get attributes from your globes ``target:get_attr d073d5000000 color`` Where ``d073d5000000`` is replaced with the serial of the device you are addressing and ``color`` is replaced with the attribute you want. This task works by looking at all the loaded LIFX binary protocol messages defined for the 1024 protocol and looks for ``Get<Attr>``. So if you want the ``color`` attribute, it will look for the ``GetColor`` message and send that to the device and print out the reply packet we get back. """ protocol_register = collector.configuration["protocol_register"] if artifact in (None, "", sb.NotSpecified): raise BadOption( "Please specify what you want to get\nUsage: {0} <target>:get_attr <reference> <attr_to_get>" .format(sys.argv[0])) getter = find_packet(protocol_register, artifact, "Get") if getter is None: raise BadOption("Sorry, couldn't a class for this message", prefix="get", want=artifact) extra = collector.photons_app.extra_as_json if "extra_payload_kwargs" in kwargs: extra.update(kwargs["extra_payload_kwargs"]) msg = getter.normalise(Meta.empty(), extra) async for pkt in target.send(msg, reference, **kwargs): print("{0}: {1}".format(pkt.serial, repr(pkt.payload)))
def resolve_reference(self, collector, task_func): """ If the task func needs a reference and none is specified then complain If the task wants a special_reference then we return one of those Otherwise we return reference as is. """ empty = lambda r: r in ("", None, sb.NotSpecified) reference = collector.photons_app.reference if task_func.needs_reference and empty(reference): raise BadOption( "This task requires you specify a reference, please do so!", action=self.action) if task_func.special_reference: return collector.reference_object(reference) return reference