예제 #1
0
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)))
예제 #2
0
    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)}")
예제 #3
0
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)))
예제 #4
0
    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
예제 #5
0
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)))
예제 #6
0
 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)
예제 #7
0
    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)
예제 #8
0
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)
예제 #9
0
    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)
예제 #10
0
    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)
예제 #11
0
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)))
예제 #12
0
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)))
예제 #13
0
    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