First version with demo mode
This commit is contained in:
155
fs/animateLights.js
Executable file
155
fs/animateLights.js
Executable file
@@ -0,0 +1,155 @@
|
||||
load('api_rpc.js');
|
||||
load("api_neopixel.js");
|
||||
load("api_file.js");
|
||||
|
||||
|
||||
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: 3,
|
||||
ledPin: 4,
|
||||
running: false,
|
||||
mode: "demo",
|
||||
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
|
||||
]
|
||||
};
|
||||
|
||||
// Add RPC handlers
|
||||
|
||||
RPC.addHandler('HouseLightning.Start', function(args) {
|
||||
LightAnimation.running = true;
|
||||
return {result: 'ok'};
|
||||
}, null);
|
||||
|
||||
RPC.addHandler('HouseLightning.Stop', function(args) {
|
||||
LightAnimation.running = false;
|
||||
return {result: 'ok'};
|
||||
}, null);
|
||||
|
||||
RPC.addHandler('HouseLightning.DemoMode', function(args) {
|
||||
LightAnimation.mode = "demo";
|
||||
LightAnimation.running = true;
|
||||
return {result: 'ok'};
|
||||
}, null);
|
||||
|
||||
RPC.addHandler('HouseLightning.CycleMode', function(args) {
|
||||
LightAnimation.mode = "cycle";
|
||||
LightAnimation.running = true;
|
||||
return {result: 'ok'};
|
||||
}, null);
|
||||
|
||||
RPC.addHandler('HouseLightning.GetAnimationConfig', function(args) {
|
||||
return LightAnimation.animationConfig;
|
||||
}, null);
|
||||
|
||||
RPC.addHandler('HouseLightning.SetAnimationConfig', function(args) {
|
||||
if (args !== undefined && args.config !== undefined) {
|
||||
LightAnimation.animationConfig = JSON.parse(args.config);
|
||||
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 not an array?'};
|
||||
}
|
||||
let i;
|
||||
for (i=0; i<LightAnimation.animationConfig.lights.length; ++i) {
|
||||
if (LightAnimation.animationConfig.lights[i].level === undefined) {
|
||||
return {error: 'config is incomplete or invalid / level missing in lights definition'};
|
||||
}
|
||||
if (LightAnimation.animationConfig.lights[i].room === undefined) {
|
||||
return {error: 'config is incomplete or invalid / room missing in lights definition'};
|
||||
}
|
||||
if (LightAnimation.animationConfig.lights[i].on === undefined) {
|
||||
return {error: 'config is incomplete or invalid / on missing in lights definition'};
|
||||
}
|
||||
if (LightAnimation.animationConfig.lights[i].on[0] === undefined) {
|
||||
return {error: 'config is incomplete or invalid / on not an array in lights definition?'};
|
||||
}
|
||||
if (LightAnimation.animationConfig.lights[i].on.length !== 3) {
|
||||
return {error: 'config is incomplete or invalid / on must have 3 elements for R/G/B in lights definition?'};
|
||||
}
|
||||
if (LightAnimation.animationConfig.lights[i].id === undefined) {
|
||||
return {error: 'config is incomplete or invalid / id missing in lights definition'};
|
||||
}
|
||||
}
|
||||
return {result: 'ok'};
|
||||
} else {
|
||||
return {error: 'parameter config is required'};
|
||||
}
|
||||
}, null);
|
||||
|
||||
function runNeopixel(strip, shiftBy) {
|
||||
let i=0, colorIndex=0, color;
|
||||
|
||||
for (i=0; i<LightAnimation.numberOfBulbs; ++i) {
|
||||
colorIndex = shiftBy % LightAnimation.colorSequence.length;
|
||||
color = LightAnimation.colorSequence[colorIndex];
|
||||
strip.setPixel(i, color.r, color.g, color.b);
|
||||
// print("runNeo shift =", shiftBy, ", colorIndex =", colorIndex, ", r =", color.r, ", g =", color.g, ", b =", color.b);
|
||||
shiftBy++;
|
||||
}
|
||||
strip.show();
|
||||
}
|
||||
|
||||
// initialize module
|
||||
let configString = "";
|
||||
configString = File.read("lights.cfg");
|
||||
if (configString === "" || configString === null) configString = "***default***";
|
||||
// print("configString = ", configString);
|
||||
LightAnimation.animationConfig = JSON.parse(configString);
|
||||
|
||||
|
||||
// initialize neoPixel
|
||||
let colorOrder = NeoPixel.GRB;
|
||||
let strip = NeoPixel.create(LightAnimation.ledPin, LightAnimation.numberOfBulbs, colorOrder);
|
||||
strip.clear();
|
||||
strip.show();
|
||||
// initialize test pattern
|
||||
let i = 0;
|
||||
for (i=0; i<LightAnimation.numberOfBulbs; ++i) {
|
||||
if (i % 2) {
|
||||
strip.setPixel(i, 80, 20, 20);
|
||||
} else {
|
||||
strip.setPixel(i, 20, 80, 20);
|
||||
}
|
||||
}
|
||||
strip.show();
|
||||
|
||||
let shiftAnimation = 1;
|
||||
|
||||
Timer.set(1990 /* msec */, true /* repeat */, function() {
|
||||
if (LightAnimation.running) {
|
||||
if (LightAnimation.mode === "demo") {
|
||||
runNeopixel(strip, shiftAnimation);
|
||||
shiftAnimation++;
|
||||
print("*** demo-mode, next shift=", shiftAnimation);
|
||||
} else print("*** no-ack, mode =", LightAnimation.mode);
|
||||
} else print("*** stopped");
|
||||
}, null);
|
||||
Reference in New Issue
Block a user