/* animateLights.js * LED animation for house lightning */ load('api_rpc.js'); load("api_neopixel.js"); load("api_file.js"); let floor = ffi('double floor(double)'); let colors = { black: {r:0, g:0, b:0}, red: {r:255, g:0, b:0}, green: {r:0, g:255, b:0}, blue: {r:0, g:0, b:255}, yellow: {r:255, g:255, b:0}, orange: {r:255, g:127, b:0}, purple: {r:255, g:0, b:255}, white: {r:255, g:255, b:255}, dimmedWhite: {r:50, g:50, b:50} }; let LightAnimation = { numberOfBulbs: 22, ledPin: 2, that: this, running: false, mode: "demo", // "demo", "stop", "animate" generalBrightness: 30, // percentage, value 0..100 description: "Default house lightning", defaultColor: colors.dimmedWhite, defaultMode: "demo", tickResolution: 1000, // number of milliseconds between ticks currentTick: 0, animationConfig: {}, // overwritten when loading animationConfig.js colorSequence: [ colors.dimmedWhite, colors.red, colors.green, colors.blue, colors.yellow, colors.orange, colors.purple, colors.red, colors.red, colors.green, colors.green, colors.white, colors.white ], adjustBrightness: function (value) { return floor(value / LightAnimation.generalBrightness); }, changeMode: function (newMode) { if (newMode === "animate") { LightAnimation.running = true; LightAnimation.mode = "start-animate"; // through transient mode start-animate to animate } else if (newMode === "stop") { LightAnimation.running = true; // first we want to turn off LEDs, thus needs stop-mode but running LightAnimation.mode = "stop"; } else if (newMode === "demo") { LightAnimation.mode = "demo"; LightAnimation.running = true; } else if (newMode === "cycle") { LightAnimation.mode = "cycle"; LightAnimation.running = true; } else { print("IGNORED: changeMode called with invalid mode = ", newMode); } }, updateAnimationConfig: function (config) { LightAnimation.animationConfig = JSON.parse(config); return LightAnimation.verifyAnimationConfig(); }, verifyAnimationConfig: function() { if (LightAnimation.animationConfig.comment === undefined) { return {error: 'config is incomplete or invalid / comment not found'}; } if (LightAnimation.animationConfig.lights === undefined) { return {error: 'config is incomplete or invalid / lights definition not found'}; } if (LightAnimation.animationConfig.lights[0] === undefined) { return {error: 'config is incomplete or invalid / lights is not an array?'}; } let i; for (i=0; i= LEDstate[i].nextTick) { // update this animated bulb } // strip.setPixel called in animateBulb // strip.setPixel(i, LightAnimation.adjustBrightness(LEDstate[i].currentRed), LightAnimation.adjustBrightness(LEDstate[i].currentGreen), LightAnimation.adjustBrightness(LEDstate[i].currentBlue)); } strip.show(); } else print("*** Unknown LightAnimation.mode =", LightAnimation.mode); } } // Garbage collection before startup, full=true --> reclaim RAM to OS gc(true); print("Initialize timer, start in 5 seconds"); // Show start pattern for 5 seconds, then switch to default colors Timer.set(5000 /* msec */, false /* repeat */, function() { print("START animation"); for (i=0; i