Custom

Custom animations are just Python functions, but they allow you to do limitless things with your LEDs.

File Location

The default location for custom animation files is /etc/mqttany/led-anim/, but you can specify multiple other locations using the anim dir option in the config file.

File Header

You will likely want to add the following to the top of each of your files to get the best experience writing your own animations. This will provide type hints and autocompletion while creating animations.

import typing as t

if t.TYPE_CHECKING:
    import threading, sys

    sys.path.append("/opt/mqttany")
    from mqttany.modules.led.anim import parse_color, parse_pixel
    from mqttany.modules.led.array.base import baseArray
    from mqttany.modules.led.common import Color
    from mqttany.logger import mqttanyLogger

    log: mqttanyLogger
    FRAME_MS: float

If you did not install MQTTany in the default /opt/mqttany directory you will need to modify the path in the above header or otherwise ensure that the imports are available.

Function Naming

Only functions with names starting with anim_ will be imported as animations. They will be added to the animation dictionary as filename.func_name, func_name will have the anim_ prefix removed.

Ex. An animation function called anim_blink in a file named example.py will be known as example.blink when triggering via MQTT or from other animations.

Looping

Animation functions should not loop to repeat the same action themselves, this is done by the animation manager for the array based on the repeat parameter. Animation functions should NEVER run an infinite loop, always use repeat: 0 to accomplish this.

Function Signature

Your animation function must have the following signature for it to work reliably:

def anim_blink(
    array,  # type: baseArray
    cancel,  # type: threading.Event
    **kwargs,  # type: t.Any
) -> None:

Parameter

Description

array

This is the LED array object subclassed from led.array.base.baseArray. All operations to change the LEDs are done using this object. See array Object for details.

cancel

This is a threading.Event object that is used to signal to a running animation that it should stop what it is doing and return as soon as possible.

**kwargs

You should always use **kwargs instead of specific keyword arguments because no introspection is done by the LED module to see if all arguments have been provided.

Arguments can be pulled from kwargs without errors if they don’t exist using get(key, default). You can provide defaults or later check if all required arguments have been provided.

# sets 'value' to None if 'key' is not in 'kwargs'
value = kwargs.get("key", None)

array Object

The array object provides methods to get information about the array and set LED colors. The array object received will be subclassed from modules.led.array.base.baseArray.

Method / Property

Description

show()

Outputs the current state of LEDs in memory. This should be called when you are done setting LEDs and want to display those changes on the physical array.

setPixelColor(pixel, color: Color)

Sets the specified pixel value of the Color instance passed.

getPixelColor(pixel) -> Color

Returns a Color instance with r, g, b, and w properties representing the pixel color.

setPixelColorRGB (pixel, red, green, blue, white=0)

Sets the specified pixel to the provided red, green, blue, and white values.

getPixelColorRGB(pixel) -> tuple

Returns a tuple of red, green, blue, and white integers representing the pixel color.

setPixel(pixel, color: int)

Sets the specified pixel to a 24-bit RRGGBB or 32-bit WWRRGGBB value.

getPixel(pixel) -> int

Returns a 24-bit RRGGBB or 32-bit WWRRGGBB value representing the pixel color.

setBrightness(brightness: int)

Sets the brightness for the array. Also available as the property brightness.

getBrightness() -> int

Returns the current brightness for the array. Also available as the property brightness.

numPixels() -> int

Returns the number of pixels in the array. Also available as the property count.

numColors() -> int

Returns the number of color channels (3 for RGB or 4 for RGBW). Also available as the property colors.

brightness

Can be use to get or set the array brightness.

count

Returns the number of pixels in the array.

colors

Returns the number of color channels.

anims

Is a dictionary containing all known animations. You can use this to run other animations by name from within your animation function. For example setting the array off after your animation finishes:

array.anims["off"](array, cancel)

Globals

Some useful values and functions are inserted into the globals for all animations and can be used as if they had been defined or imported in your animation file.

Property

Description

log

This gives you a logger that logs to mqttany.led.anim.{anim name} for outputting log messages. It will be an instance of logger.mqttanyLogger.

FRAME_MIN

The configuration value anim fps is used to calulate the duration of each frame in milliseconds and is made available as FRAME_MIN to help with the frame timing of animations. See the built in fade animations to see how you might use this value.

class Color(t.NamedTuple):
    r: int
    g: int
    b: int
    w: int = 0

    def asInt(self) -> int: ...

    @classmethod
    def fromInt(
        cls, color: int
    ) -> Color: ...

    @staticmethod
    def getIntFromRGB(
        r: int,
        g: int,
        b: int,
        w: int = 0,
    ) -> int: ...

    @staticmethod
    def getRGBFromInt(
        color: int,
    ) -> t.Tuple[
        int, int, int, int
    ]: ...

The Color class is used by some of the baseArray methods and the utility function parse_color. It is also injected into each animation so you can make use of it as well. It provides easy access to each of the color components and can convert those components into a single integer (WWRRGGBB format). There is an alternate constructor to create a Color instance from a color stored as an integer (fromInt). There are also static methods to convert from components to single value and vice versa (getIntFromRGB and getRGBFromInt).

parse_color(
    array,
    color = None,
    r = -1,
    g = -1,
    b = -1,
    w = -1,
    pixel = None,
)

This function can be used to get a Color instance from the animation arguments color, red, green, blue, and white as used in the set.array animation. If pixel is provided, any component with a value of -1 (must provide at least 1 new value) will use the current channel value from the specified pixel. It will return None if it cannot determine a color from the values provided.

parse_pixel(
    array,
    p,
)

This can be used to parse various pixel range arguments as used with the pixel argument for the set.pixel animation. It will return a list of all pixel indices specified or an empty list if it is unable to parse the input.

Pixels may be specified in any of the following ways:

# single index
    "pixel": 2

# range string
    "pixel": "4-6"

# list
    "pixel": [
        2,      # pixel 2
        "4-6",  # pixels 4, 5 and 6
        [10, 5] # pixels 10, 11, 12, 13, and 14
    ]