LED Ring

Homey has an LED Ring, consisting of 24 RGB LED's. You can control Homey's LED Ring to give visual feedback when your app is doing something. It is also possible to take control of the LED Ring when Homey is idling, this is called a screensaver.

Playing a LED Ring animation

To keep the user interaction of Homey consistent, you can play a system-provided animation.

/app.js

let mySystemAnimation = new Homey.LedringAnimationSystem('pulse');
    mySystemAnimation.register()
        .then(() => {
            mySystemAnimation.start();
        })
        .catch( this.error )

Creating your own LED Ring animation

An animation is essentially a JavaScript object with frames and settings about the frame speed and rotation speed.

/app.js

const Homey = require('homey');

let myAnimation = new Homey.LedringAnimation({
    options: {
        fps     : 1,     // real frames per second
        tfps    : 60,     // target frames per second. this means that every frame will be interpolated 60 times
        rpm     : 0,    // rotations per minute
    },
    frames    : [],
    priority: 'INFORMATIVE', // or FEEDBACK, or CRITICAL
    duration: 3000 // duration in ms, or keep empty for infinite
})

// register the animation with Homey
myAnimation
    .on('start', () => {
        // The animation has started playing
    })
    .on('stop', () => {
        // The animation has stopped playing
    })
    .register()
        .then( () => {
            this.log('Animation registered!');

            animation.start();
        })
        .catch( this.error )

The animation object is an Array, which contains frames. A frame is an Array with 24 Object values, that represent the color of that pixel. The pixel object is contains the properties r, g and b, respectively red, green and blue on a scale of 0 - 255.

For example, to create a spinning red dot:

let frames = [];
let frame = [];

// for every pixel...
for( let pixelIndex = 0; pixelIndex < 24; pixelIndex++ ) {

    let colors = {
        r: 0,
        g: 0,
        b: 0
    };

    // set the first pixel to red
    if( pixelIndex === 0 ) {
        colors.r = 255;
    }

    frame.push( colors );
}

// and finally, add the generated frame to the frames array
frames.push(frame);

Screensaver

Your app can register a screensaver, which can be chosen by going to Settings → LED Ring, and executed when Homey is idling.

Define your screensaver(s) in your app.json as follows:

/app.json

"id": "com.athom.weather",
...,
"screensavers": [
    {
        "name": "weather",
        "title": {
            "en": "Weather",
            "nl": "Weer"
        }
    }
]

And from within your app, register your animation instance as follows:

/app.js

// If this animation is also a screensaver, we must register it first.
// 'weather' is the screensaver name defined in our app.json
myAnimation.registerScreensaver( 'weather' )
    .then( this.log )
    .catch( this.error )

For live animations, simply update your animation using LedringAnimation#updateFrames when needed.

Testing from the command-line

Using athom-cli, you can run animations from the command line for faster testing.

Create a file (e.g. myanim.js) that exports an object with two properties: options and frames. Then run athom ledring --run myanim.js to test your animation.

myanim.js

var frames = [];
var frame = [];

// for every pixel...
for( var pixel = 0; pixel < 24; pixel++ ) {

    if( pixel < 8 ) {
        frame.push({
            r: 255,
            g: 0,
            b: 0
        });
    } else
    if( pixel < 16 ) {
        frame.push({
            r: 0,
            g: 255,
            b: 0
        });
    } else if( pixel < 24 ) {
        frame.push({
            r: 0,
            g: 0,
            b: 255
        });
    }
}

frames.push(frame);

module.exports = {
    options: {
        fps     : 1,
        tfps    : 60,
        rpm     : 50,
    },
    frames: frames
}