Added new mode: Scheduler -- clock based switching of lights

This commit is contained in:
2017-12-09 22:10:59 +01:00
parent 626fe42a90
commit 4aeebe1b33
12 changed files with 290 additions and 50 deletions

View File

@@ -1,28 +1,39 @@
let addColor = ffi('void addColor(char *,int,int,int)');
let LEDDefinition_addByName = ffi('void LEDDefinition_addByName(char *, char *, char *, char *)');
let addAnimationStep = ffi('void addAnimationStep(int, char *, int)');
let LEDMode_on=1, LEDMode_off=2, LEDMode_blink=3, LEDMode_tv=4, LEDMode_fire=5;
let LEDStateEngine_init = ffi('void LEDStateEngine_init(int, int)');
let LEDStateEngine_start = ffi('void startLEDStateEngine(void)');
let LEDStateEngine_pause = ffi('void pauseLEDStateEngine(void)');
let LEDStateEngine_getMinTickTime = ffi('double LEDStateEngine_getMinTickTime(void)');
let LEDStateEngine_getMaxTickTime = ffi('double LEDStateEngine_getMaxTickTime(void)');
let LEDState_getRed = ffi('int LEDState_getLedRed(int)');
let LEDState_getGreen = ffi('int LEDState_getLedGreen(int)');
let LEDState_getBlue = ffi('int LEDState_getLedBlue(int)');
let LEDState_getColorName = ffi('char * LEDState_getLedColorName(int)');
let LEDState_getNextTick = ffi('int LEDState_getNextTick(int)');
let LEDState_getCurrentTick = ffi('int LEDState_getCurrentTick(int)');
let LEDDefinition_addByName = ffi('void LEDDefinition_addByName(char *, char *, char *, char *)');
let LEDDefinition_getLevel = ffi('char *LEDDefinition_getLevel(int)');
let LEDDefinition_getRoom = ffi('char *LEDDefinition_getRoom(int)');
let LEDDefinition_getId = ffi('char *LEDDefinition_getId(int)');
let LEDDefinition_getOnColorRed = ffi('int LEDDefinition_getOnColorRed(int)');
let LEDDefinition_getOnColorGreen = ffi('int LEDDefinition_getOnColorGreen(int)');
let LEDDefinition_getOnColorBlue = ffi('int LEDDefinition_getOnColorBlue(int)');
let getTicks = ffi('int getTicks(void)');
let printColor = ffi('void printColor(char *)');
let NeoPixel_show = ffi('void NeoPixel_show(void)');
let NeoPixel_clear = ffi('void NeoPixel_clear(void)');
let NeoPixel_set = ffi('void NeoPixel_set(int,int,int,int)');
let LEDStateEngine_getMinTickTime = ffi('double LEDStateEngine_getMinTickTime(void)');
let LEDStateEngine_getMaxTickTime = ffi('double LEDStateEngine_getMaxTickTime(void)');
let LEDStateEngine_getBrightness = ffi('int LEDStateEngine_getBrightness(void)');
let LEDStateEngine_setBrightness = ffi('void LEDStateEngine_setBrightness(int)');
let NeoPixel_getBrightness = ffi('int NeoPixel_getBrightness(void)');
let NeoPixel_setBrightness = ffi('void NeoPixel_setBrightness(int)');
let LEDScheduler_init = ffi('void LEDScheduler_init(int, int, int)');
let LEDScheduler_run = ffi('void LEDScheduler_run(void)');
let LEDScheduler_pause = ffi('void LEDScheduler_pause(void)');
let LEDScheduler_addItem = ffi('void LEDScheduler_addItem(int, int, int, char *, char *)');
let LEDScheduler_setWatch = ffi('void LEDScheduler_setWatch(int, int, int)');

View File

@@ -1,6 +1,12 @@
[
{"name": "off", "red": 0, "green": 0, "blue": 0},
{"name": "candle", "red": 30, "green": 15, "blue": 4},
{"name": "25w", "red": 35, "green": 15, "blue": 6},
{"name": "40w", "red": 50, "green": 25, "blue": 10},
{"name": "60w", "red": 70, "green": 45, "blue": 20},
{"name": "75w", "red": 80, "green": 70, "blue": 30},
{"name": "100w", "red": 100, "green": 85, "blue": 50},
{"name": "neon", "red": 100, "green": 95, "blue": 70},
{"name": "red", "red": 50, "green": 5, "blue": 5},
{"name": "green", "red": 5, "green": 50, "blue": 5},
{"name": "blue", "red": 5, "green": 5, "blue": 80},

26
fs/demoschedule.cfg Normal file
View File

@@ -0,0 +1,26 @@
{
"comment": "7-LED development board",
"lampmapping": [
"lamp-1", "lamp-2", "lamp-3", "lamp-4", "lamp-5", "lamp-6", "lamp-7"
],
"mrclock": "N-RE",
"clock_starttime": {"h": 2, "m": 0},
"clock_speed": 1,
"schedule": [
{"time": {"h": 2, "m": 30}, "lamp": "lamp-1", "color": "25w", "mode": "OnOff"},
{"time": {"h": 2, "m": 31}, "lamp": "lamp-2", "color": "25w", "mode": "OnOff"},
{"time": {"h": 2, "m": 32}, "lamp": "lamp-3", "color": "25w", "mode": "OnOff"},
{"time": {"h": 2, "m": 45}, "lamp": "lamp-3", "color": "off", "mode": "OnOff"},
{"time": {"h": 2, "m": 46}, "lamp": "lamp-2", "color": "off", "mode": "OnOff"},
{"time": {"h": 2, "m": 47}, "lamp": "lamp-1", "color": "off", "mode": "OnOff"},
{"time": {"h": 4, "m": 2}, "lamp": "lamp-1", "color": "25w", "mode": "OnOff"},
{"time": {"h": 4, "m": 4}, "lamp": "lamp-2", "color": "25w", "mode": "OnOff"},
{"time": {"h": 4, "m": 4}, "lamp": "lamp-3", "color": "25w", "mode": "OnOff"},
{"time": {"h": 4, "m": 18}, "lamp": "lamp-3", "color": "off", "mode": "OnOff"},
{"time": {"h": 4, "m": 28}, "lamp": "lamp-1", "color": "off", "mode": "OnOff"},
{"time": {"h": 4, "m": 29}, "lamp": "lamp-4", "color": "40w", "mode": "OnOff"},
{"time": {"h": 4, "m": 30}, "lamp": "lamp-5", "color": "40w", "mode": "OnOff"},
{"time": {"h": 4, "m": 31}, "lamp": "lamp-6", "color": "40w", "mode": "OnOff"},
{"time": {"h": 4, "m": 32}, "lamp": "lamp-7", "color": "60w", "mode": "OnOff"}
]
}

View File

@@ -61,6 +61,8 @@ let configNumLeds = Cfg.get('led.count');
let colorFile = Cfg.get('led.colorFile');
let animationFile = Cfg.get('led.animationFile');
let lampsFile = Cfg.get('led.lampsFile');
let scheduleFile = Cfg.get('led.scheduleFile');
let dynamicMode = Cfg.get('led.mode');
let useDefaults = Cfg.get('led.useDefaults');
let tickDuration = Cfg.get('led.tickDuration');
let numberOfLeds = configNumLeds, numberOfLedDefs = 0; // from config files, count led definition entries
@@ -155,6 +157,41 @@ function loadAnimDefs() {
json = null;
}
function loadScheduleDefs() {
// Load Animation Definitions
let json = File.read(scheduleFile);
let scheduleDef = [];
print('scheduleFile =', json);
if (json === '') {
print('ERROR: Schedule definition file does not exist!');
} else {
scheduleDef = JSON.parse(json);
}
LEDScheduler_init(scheduleDef.schedule.length, numberOfLeds, pin);
LEDScheduler_setWatch(2, 0, 1); // time 02:00, clock speed = 1 real time second per model minute
let ledMapping = scheduleDef.lampmapping;
let mapLed = function (name) {
for (let i=0; i<ledMapping.length; ++i) {
if (ledMapping[i] === name) return i;
}
print("**** ERROR in schedule definition file: no lamp mapping found for lamp", name);
return 0;
};
for (i=0; i<scheduleDef.schedule.length; ++i) {
print('- addScheduleItem', scheduleDef.schedule[i].time.h, ":", scheduleDef.schedule[i].time.m, "/",
scheduleDef.schedule[i].lamp, "=", mapLed(scheduleDef.schedule[i].lamp), "/",
scheduleDef.schedule[i].mode, "/",
scheduleDef.schedule[i].color);
LEDScheduler_addItem(scheduleDef.schedule[i].time.h, scheduleDef.schedule[i].time.m,
mapLed(scheduleDef.schedule[i].lamp),
scheduleDef.schedule[i].mode,
scheduleDef.schedule[i].color);
}
json = null;
}
function initialize() {
print('***** Start initialization', getInfo());
let i;
@@ -165,10 +202,30 @@ function initialize() {
startLEDStateEngine();
} else {
loadColorDefs();
loadLedDefs();
loadAnimDefs();
// Initialize LED State Engine
LEDStateEngine_init(pin, numberOfLeds);
if (dynamicMode === "animation") {
loadLedDefs();
loadAnimDefs();
// Initialize LED State Engine
LEDStateEngine_init(pin, numberOfLeds);
print('LED', 'Color', 'R', 'G', 'B', 'Tick', 'Level', 'Room', 'Id');
print('---', '-----', '---', '---', '-----', '---', '-----', '----', '--');
for (i=0; i<numberOfLeds; ++i) {
// print(i, LEDState_getRed(i), LEDState_getGreen(i), LEDState_getBlue(i), LEDState_getCurrentTick(i), LEDDefinition_getLevel(i), LEDDefinition_getRoom(i), LEDDefinition_getId(i))
print(i, LEDState_getColorName(i),
LEDDefinition_getOnColorRed(i),
LEDDefinition_getOnColorGreen(i),
LEDDefinition_getOnColorBlue(i),
LEDState_getCurrentTick(i),
LEDDefinition_getLevel(i),
LEDDefinition_getRoom(i),
LEDDefinition_getId(i));
}
} else if (dynamicMode === "schedule") {
loadScheduleDefs();
} else {
print("**** ERROR: Unknown dynamic mode", dynamicMode);
return;
}
}
allLedOff();
print('***** End of initialization', getInfo());
@@ -177,20 +234,7 @@ function initialize() {
print('NumLEDs:', numberOfLeds);
print('Ticks:', getTicks());
print('Tick duration:', tickDuration, 'ms');
print('Brightness:', LEDStateEngine_getBrightness(), '%');
print('LED', 'Color', 'R', 'G', 'B', 'Tick', 'Level', 'Room', 'Id');
print('---', '-----', '---', '---', '-----', '---', '-----', '----', '--');
for (i=0; i<numberOfLeds; ++i) {
// print(i, LEDState_getRed(i), LEDState_getGreen(i), LEDState_getBlue(i), LEDState_getCurrentTick(i), LEDDefinition_getLevel(i), LEDDefinition_getRoom(i), LEDDefinition_getId(i))
print(i, LEDState_getColorName(i),
LEDDefinition_getOnColorRed(i),
LEDDefinition_getOnColorGreen(i),
LEDDefinition_getOnColorBlue(i),
LEDState_getCurrentTick(i),
LEDDefinition_getLevel(i),
LEDDefinition_getRoom(i),
LEDDefinition_getId(i));
}
print('Brightness:', NeoPixel_getBrightness(), '%');
}
Timer.set(300, false, function() {
@@ -200,8 +244,14 @@ Timer.set(300, false, function() {
allLedOff();
print('***** LED test pattern', getInfo());
showLedTestPattern();
print('***** Start LED state engine and LED-update timer', getInfo());
LEDStateEngine_start();
if (dynamicMode === "animation") {
print('***** Start LED state engine and LED-update timer', getInfo());
LEDStateEngine_start();
} else if (dynamicMode === "schedule") {
print('***** Start schedule based animation', getInfo());
NeoPixel_clear();
LEDScheduler_run();
}
Timer.set(30000, true, function() {
print("Timer: minTickTime =", LEDStateEngine_getMinTickTime(),
"ms, maxTickTime =", LEDStateEngine_getMaxTickTime(), "ms");
@@ -215,7 +265,7 @@ RPC.addHandler('led.setBrightness', function(args) {
// print(args);
if (args !== undefined && args.level !== undefined) {
if (args.level > 0 && args.level <= 100) {
LEDStateEngine_setBrightness(args.level);
NeoPixel_setBrightness(args.level);
return { result: 'ok' };
} else {
return { error: 'Brightness level must be in the range 1..100' };
@@ -226,7 +276,7 @@ RPC.addHandler('led.setBrightness', function(args) {
}, "{level: %d}");
print(' led.getBrightness');
RPC.addHandler('led.getBrightness', function(args) {
let brightness = LEDStateEngine_getBrightness();
let brightness = NeoPixel_getBrightness();
return { result: 'ok', brightness: brightness };
}, null);
print(' led.pause');

30
fs/schedule.cfg Normal file
View File

@@ -0,0 +1,30 @@
{
"comment": "Company office building with facility manager appartement",
"lampmapping": [
"eg-1.1", "eg-1.2", "eg-3.1", "eg-4", "eg-5", "eg-8", "eg-7, "eg-6", "eg-3.2", "eg-2.2", "eg-2.1",
"og-1.1", "og-1.2", "og-3.1", "og-4", "og-5", "og-8", "og-7, "og-6", "og-3.2", "og-2.2", "og-2.1",
"dg-1", "dg-2", "dg-3", "dg-4", "dg-5", "dg-6", "dg-7", "dg-8"
],
"mrclock": "N-RE",
"clock_starttime": {"h": 2, "m": 0},
"clock_speed": 1,
"schedule": [
{"time": {"h": 2, "m": 30}, "lamp": "dg-5", "color": "25w", "mode": "OnOff"},
{"time": {"h": 2, "m": 31}, "lamp": "dg-8", "color": "25w", "mode": "OnOff"},
{"time": {"h": 2, "m": 32}, "lamp": "dg-7", "color": "25w", "mode": "OnOff"},
{"time": {"h": 2, "m": 45}, "lamp": "dg-7", "color": "off", "mode": "OnOff"},
{"time": {"h": 2, "m": 46}, "lamp": "dg-8", "color": "off", "mode": "OnOff"},
{"time": {"h": 2, "m": 47}, "lamp": "dg-5", "color": "off", "mode": "OnOff"},
{"time": {"h": 4, "m": 2}, "lamp": "dg-5", "color": "25w", "mode": "OnOff"},
{"time": {"h": 4, "m": 4}, "lamp": "dg-8", "color": "25w", "mode": "OnOff"},
{"time": {"h": 4, "m": 4}, "lamp": "dg-7", "color": "25w", "mode": "OnOff"},
{"time": {"h": 4, "m": 18}, "lamp": "dg-7", "color": "off", "mode": "OnOff"},
{"time": {"h": 4, "m": 28}, "lamp": "dg-5", "color": "off", "mode": "OnOff"},
{"time": {"h": 4, "m": 29}, "lamp": "dg-3", "color": "40w", "mode": "OnOff"},
{"time": {"h": 4, "m": 30}, "lamp": "og-3.2", "color": "40w", "mode": "OnOff"},
{"time": {"h": 4, "m": 30}, "lamp": "eg-3.2", "color": "40w", "mode": "OnOff"},
{"time": {"h": 4, "m": 30}, "lamp": "eg-4", "color": "60w", "mode": "OnOff"},
{"time": {"h": 4, "m": 45}, "lamp": "eg-3.1", "color": "40w", "mode": "OnOff"},
{"time": {"h": 4, "m": 47}, "lamp": "eg-1.1", "color": "60w", "mode": "OnOff"}
]
}