Added new mode: Scheduler -- clock based switching of lights
This commit is contained in:
parent
626fe42a90
commit
4aeebe1b33
|
@ -1,28 +1,39 @@
|
||||||
let addColor = ffi('void addColor(char *,int,int,int)');
|
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 addAnimationStep = ffi('void addAnimationStep(int, char *, int)');
|
||||||
let LEDMode_on=1, LEDMode_off=2, LEDMode_blink=3, LEDMode_tv=4, LEDMode_fire=5;
|
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_init = ffi('void LEDStateEngine_init(int, int)');
|
||||||
let LEDStateEngine_start = ffi('void startLEDStateEngine(void)');
|
let LEDStateEngine_start = ffi('void startLEDStateEngine(void)');
|
||||||
let LEDStateEngine_pause = ffi('void pauseLEDStateEngine(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_getRed = ffi('int LEDState_getLedRed(int)');
|
||||||
let LEDState_getGreen = ffi('int LEDState_getLedGreen(int)');
|
let LEDState_getGreen = ffi('int LEDState_getLedGreen(int)');
|
||||||
let LEDState_getBlue = ffi('int LEDState_getLedBlue(int)');
|
let LEDState_getBlue = ffi('int LEDState_getLedBlue(int)');
|
||||||
let LEDState_getColorName = ffi('char * LEDState_getLedColorName(int)');
|
let LEDState_getColorName = ffi('char * LEDState_getLedColorName(int)');
|
||||||
let LEDState_getNextTick = ffi('int LEDState_getNextTick(int)');
|
let LEDState_getNextTick = ffi('int LEDState_getNextTick(int)');
|
||||||
let LEDState_getCurrentTick = ffi('int LEDState_getCurrentTick(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_getLevel = ffi('char *LEDDefinition_getLevel(int)');
|
||||||
let LEDDefinition_getRoom = ffi('char *LEDDefinition_getRoom(int)');
|
let LEDDefinition_getRoom = ffi('char *LEDDefinition_getRoom(int)');
|
||||||
let LEDDefinition_getId = ffi('char *LEDDefinition_getId(int)');
|
let LEDDefinition_getId = ffi('char *LEDDefinition_getId(int)');
|
||||||
let LEDDefinition_getOnColorRed = ffi('int LEDDefinition_getOnColorRed(int)');
|
let LEDDefinition_getOnColorRed = ffi('int LEDDefinition_getOnColorRed(int)');
|
||||||
let LEDDefinition_getOnColorGreen = ffi('int LEDDefinition_getOnColorGreen(int)');
|
let LEDDefinition_getOnColorGreen = ffi('int LEDDefinition_getOnColorGreen(int)');
|
||||||
let LEDDefinition_getOnColorBlue = ffi('int LEDDefinition_getOnColorBlue(int)');
|
let LEDDefinition_getOnColorBlue = ffi('int LEDDefinition_getOnColorBlue(int)');
|
||||||
|
|
||||||
let getTicks = ffi('int getTicks(void)');
|
let getTicks = ffi('int getTicks(void)');
|
||||||
let printColor = ffi('void printColor(char *)');
|
let printColor = ffi('void printColor(char *)');
|
||||||
|
|
||||||
let NeoPixel_show = ffi('void NeoPixel_show(void)');
|
let NeoPixel_show = ffi('void NeoPixel_show(void)');
|
||||||
let NeoPixel_clear = ffi('void NeoPixel_clear(void)');
|
let NeoPixel_clear = ffi('void NeoPixel_clear(void)');
|
||||||
let NeoPixel_set = ffi('void NeoPixel_set(int,int,int,int)');
|
let NeoPixel_set = ffi('void NeoPixel_set(int,int,int,int)');
|
||||||
let LEDStateEngine_getMinTickTime = ffi('double LEDStateEngine_getMinTickTime(void)');
|
let NeoPixel_getBrightness = ffi('int NeoPixel_getBrightness(void)');
|
||||||
let LEDStateEngine_getMaxTickTime = ffi('double LEDStateEngine_getMaxTickTime(void)');
|
let NeoPixel_setBrightness = ffi('void NeoPixel_setBrightness(int)');
|
||||||
let LEDStateEngine_getBrightness = ffi('int LEDStateEngine_getBrightness(void)');
|
|
||||||
let LEDStateEngine_setBrightness = ffi('void LEDStateEngine_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)');
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
[
|
[
|
||||||
{"name": "off", "red": 0, "green": 0, "blue": 0},
|
{"name": "off", "red": 0, "green": 0, "blue": 0},
|
||||||
{"name": "candle", "red": 30, "green": 15, "blue": 4},
|
{"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": "red", "red": 50, "green": 5, "blue": 5},
|
||||||
{"name": "green", "red": 5, "green": 50, "blue": 5},
|
{"name": "green", "red": 5, "green": 50, "blue": 5},
|
||||||
{"name": "blue", "red": 5, "green": 5, "blue": 80},
|
{"name": "blue", "red": 5, "green": 5, "blue": 80},
|
||||||
|
|
|
@ -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"}
|
||||||
|
]
|
||||||
|
}
|
72
fs/init.js
72
fs/init.js
|
@ -61,6 +61,8 @@ let configNumLeds = Cfg.get('led.count');
|
||||||
let colorFile = Cfg.get('led.colorFile');
|
let colorFile = Cfg.get('led.colorFile');
|
||||||
let animationFile = Cfg.get('led.animationFile');
|
let animationFile = Cfg.get('led.animationFile');
|
||||||
let lampsFile = Cfg.get('led.lampsFile');
|
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 useDefaults = Cfg.get('led.useDefaults');
|
||||||
let tickDuration = Cfg.get('led.tickDuration');
|
let tickDuration = Cfg.get('led.tickDuration');
|
||||||
let numberOfLeds = configNumLeds, numberOfLedDefs = 0; // from config files, count led definition entries
|
let numberOfLeds = configNumLeds, numberOfLedDefs = 0; // from config files, count led definition entries
|
||||||
|
@ -155,6 +157,41 @@ function loadAnimDefs() {
|
||||||
json = null;
|
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() {
|
function initialize() {
|
||||||
print('***** Start initialization', getInfo());
|
print('***** Start initialization', getInfo());
|
||||||
let i;
|
let i;
|
||||||
|
@ -165,19 +202,11 @@ function initialize() {
|
||||||
startLEDStateEngine();
|
startLEDStateEngine();
|
||||||
} else {
|
} else {
|
||||||
loadColorDefs();
|
loadColorDefs();
|
||||||
|
if (dynamicMode === "animation") {
|
||||||
loadLedDefs();
|
loadLedDefs();
|
||||||
loadAnimDefs();
|
loadAnimDefs();
|
||||||
// Initialize LED State Engine
|
// Initialize LED State Engine
|
||||||
LEDStateEngine_init(pin, numberOfLeds);
|
LEDStateEngine_init(pin, numberOfLeds);
|
||||||
}
|
|
||||||
allLedOff();
|
|
||||||
print('***** End of initialization', getInfo());
|
|
||||||
print('_______________________________________________________');
|
|
||||||
print('LedPin:', pin);
|
|
||||||
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('LED', 'Color', 'R', 'G', 'B', 'Tick', 'Level', 'Room', 'Id');
|
||||||
print('---', '-----', '---', '---', '-----', '---', '-----', '----', '--');
|
print('---', '-----', '---', '---', '-----', '---', '-----', '----', '--');
|
||||||
for (i=0; i<numberOfLeds; ++i) {
|
for (i=0; i<numberOfLeds; ++i) {
|
||||||
|
@ -191,6 +220,21 @@ function initialize() {
|
||||||
LEDDefinition_getRoom(i),
|
LEDDefinition_getRoom(i),
|
||||||
LEDDefinition_getId(i));
|
LEDDefinition_getId(i));
|
||||||
}
|
}
|
||||||
|
} else if (dynamicMode === "schedule") {
|
||||||
|
loadScheduleDefs();
|
||||||
|
} else {
|
||||||
|
print("**** ERROR: Unknown dynamic mode", dynamicMode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
allLedOff();
|
||||||
|
print('***** End of initialization', getInfo());
|
||||||
|
print('_______________________________________________________');
|
||||||
|
print('LedPin:', pin);
|
||||||
|
print('NumLEDs:', numberOfLeds);
|
||||||
|
print('Ticks:', getTicks());
|
||||||
|
print('Tick duration:', tickDuration, 'ms');
|
||||||
|
print('Brightness:', NeoPixel_getBrightness(), '%');
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer.set(300, false, function() {
|
Timer.set(300, false, function() {
|
||||||
|
@ -200,8 +244,14 @@ Timer.set(300, false, function() {
|
||||||
allLedOff();
|
allLedOff();
|
||||||
print('***** LED test pattern', getInfo());
|
print('***** LED test pattern', getInfo());
|
||||||
showLedTestPattern();
|
showLedTestPattern();
|
||||||
|
if (dynamicMode === "animation") {
|
||||||
print('***** Start LED state engine and LED-update timer', getInfo());
|
print('***** Start LED state engine and LED-update timer', getInfo());
|
||||||
LEDStateEngine_start();
|
LEDStateEngine_start();
|
||||||
|
} else if (dynamicMode === "schedule") {
|
||||||
|
print('***** Start schedule based animation', getInfo());
|
||||||
|
NeoPixel_clear();
|
||||||
|
LEDScheduler_run();
|
||||||
|
}
|
||||||
Timer.set(30000, true, function() {
|
Timer.set(30000, true, function() {
|
||||||
print("Timer: minTickTime =", LEDStateEngine_getMinTickTime(),
|
print("Timer: minTickTime =", LEDStateEngine_getMinTickTime(),
|
||||||
"ms, maxTickTime =", LEDStateEngine_getMaxTickTime(), "ms");
|
"ms, maxTickTime =", LEDStateEngine_getMaxTickTime(), "ms");
|
||||||
|
@ -215,7 +265,7 @@ RPC.addHandler('led.setBrightness', function(args) {
|
||||||
// print(args);
|
// print(args);
|
||||||
if (args !== undefined && args.level !== undefined) {
|
if (args !== undefined && args.level !== undefined) {
|
||||||
if (args.level > 0 && args.level <= 100) {
|
if (args.level > 0 && args.level <= 100) {
|
||||||
LEDStateEngine_setBrightness(args.level);
|
NeoPixel_setBrightness(args.level);
|
||||||
return { result: 'ok' };
|
return { result: 'ok' };
|
||||||
} else {
|
} else {
|
||||||
return { error: 'Brightness level must be in the range 1..100' };
|
return { error: 'Brightness level must be in the range 1..100' };
|
||||||
|
@ -226,7 +276,7 @@ RPC.addHandler('led.setBrightness', function(args) {
|
||||||
}, "{level: %d}");
|
}, "{level: %d}");
|
||||||
print(' led.getBrightness');
|
print(' led.getBrightness');
|
||||||
RPC.addHandler('led.getBrightness', function(args) {
|
RPC.addHandler('led.getBrightness', function(args) {
|
||||||
let brightness = LEDStateEngine_getBrightness();
|
let brightness = NeoPixel_getBrightness();
|
||||||
return { result: 'ok', brightness: brightness };
|
return { result: 'ok', brightness: brightness };
|
||||||
}, null);
|
}, null);
|
||||||
print(' led.pause');
|
print(' led.pause');
|
||||||
|
|
|
@ -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"}
|
||||||
|
]
|
||||||
|
}
|
2
mos.yml
2
mos.yml
|
@ -39,6 +39,8 @@ config_schema:
|
||||||
- ["led.colorFile", "s", "colors.cfg", {title: "File name containing color definitions"}]
|
- ["led.colorFile", "s", "colors.cfg", {title: "File name containing color definitions"}]
|
||||||
- ["led.lampsFile", "s", "lamps.cfg", {title: "File name containing lamp definitions"}]
|
- ["led.lampsFile", "s", "lamps.cfg", {title: "File name containing lamp definitions"}]
|
||||||
- ["led.animationFile", "s", "animations.cfg", {title: "File name containing animation definitions"}]
|
- ["led.animationFile", "s", "animations.cfg", {title: "File name containing animation definitions"}]
|
||||||
|
- ["led.mode", "s", "schedule", {title: "Mode = animation (use lampsFile + animationFile) | schedule (use scheduleFile)"}]
|
||||||
|
- ["led.scheduleFile", "s", "demoschedule.cfg", {title: "File name containing schedule definitions"}]
|
||||||
build_vars:
|
build_vars:
|
||||||
MGOS_ENABLE_ONEWIRE: 1
|
MGOS_ENABLE_ONEWIRE: 1
|
||||||
cflags: []
|
cflags: []
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
|
|
||||||
static LEDStateEngine theLEDStateEngine;
|
static LEDStateEngine theLEDStateEngine;
|
||||||
static int ticks = 0;
|
static int ticks = 0;
|
||||||
static int brightness = 50;
|
|
||||||
|
|
||||||
int getTicks(void) { return ticks; }
|
int getTicks(void) { return ticks; }
|
||||||
|
|
||||||
|
@ -27,7 +26,6 @@ void LEDStateEngine_setNumberOfLeds(int numberOfLeds) {
|
||||||
void LEDStateEngine_init(int ledPin, int numberOfLeds) {
|
void LEDStateEngine_init(int ledPin, int numberOfLeds) {
|
||||||
theLEDStateEngine.comment = "";
|
theLEDStateEngine.comment = "";
|
||||||
theLEDStateEngine.pin = ledPin;
|
theLEDStateEngine.pin = ledPin;
|
||||||
brightness = mgos_sys_config_get_led_brightness();
|
|
||||||
LEDStateEngine_setNumberOfLeds(numberOfLeds);
|
LEDStateEngine_setNumberOfLeds(numberOfLeds);
|
||||||
for (int i=0; i<numberOfLeds; ++i) {
|
for (int i=0; i<numberOfLeds; ++i) {
|
||||||
LEDState_init(i, LEDDefinition_get(i));
|
LEDState_init(i, LEDDefinition_get(i));
|
||||||
|
@ -61,24 +59,11 @@ void LEDStateEngine_tick() {
|
||||||
double LEDStateEngine_getMinTickTime() { return 1000 * minTickTime; }
|
double LEDStateEngine_getMinTickTime() { return 1000 * minTickTime; }
|
||||||
double LEDStateEngine_getMaxTickTime() { return 1000 * maxTickTime; }
|
double LEDStateEngine_getMaxTickTime() { return 1000 * maxTickTime; }
|
||||||
|
|
||||||
static uint8_t adjustBrightness(uint8_t value) {
|
|
||||||
return (value * brightness)/100;
|
|
||||||
}
|
|
||||||
|
|
||||||
int LEDStateEngine_getBrightness() { return brightness; }
|
|
||||||
void LEDStateEngine_setBrightness(int newBrightness) {
|
|
||||||
if (newBrightness > 0 && newBrightness <= 100) {
|
|
||||||
brightness = newBrightness;
|
|
||||||
} else {
|
|
||||||
LOG(LL_ERROR, ("invalid brightness value %d", newBrightness));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void updateLedDisplay(LEDState *state) {
|
static void updateLedDisplay(LEDState *state) {
|
||||||
NeoPixel_set(state->index,
|
NeoPixel_set(state->index,
|
||||||
adjustBrightness(state->currentColor.red),
|
state->currentColor.red,
|
||||||
adjustBrightness(state->currentColor.green),
|
state->currentColor.green,
|
||||||
adjustBrightness(state->currentColor.blue));
|
state->currentColor.blue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LEDState_tick(int ledNum) {
|
void LEDState_tick(int ledNum) {
|
||||||
|
|
|
@ -3,12 +3,28 @@
|
||||||
#include "mgos_bitbang.h"
|
#include "mgos_bitbang.h"
|
||||||
#include "mgos_gpio.h"
|
#include "mgos_gpio.h"
|
||||||
#include "mgos_system.h"
|
#include "mgos_system.h"
|
||||||
|
#include "mgos_sys_config.h"
|
||||||
#include "NeoPixel.h"
|
#include "NeoPixel.h"
|
||||||
|
|
||||||
static int NeoPixel_pin = 0;
|
static int NeoPixel_pin = 0;
|
||||||
static int NeoPixel_numPixels = 0;
|
static int NeoPixel_numPixels = 0;
|
||||||
static uint8_t *NeoPixel_leds = NULL; // pointer to allocated memory
|
static uint8_t *NeoPixel_leds = NULL; // pointer to allocated memory
|
||||||
static enum NeoPixel_ColorOrder NeoPixel_colorOrder = NeoPixel_colorOrder_RGB;
|
static enum NeoPixel_ColorOrder NeoPixel_colorOrder = NeoPixel_colorOrder_GRB;
|
||||||
|
static int brightness = 50;
|
||||||
|
|
||||||
|
static uint8_t adjustBrightness(uint8_t value) {
|
||||||
|
return (value * brightness)/100;
|
||||||
|
}
|
||||||
|
|
||||||
|
int NeoPixel_getBrightness() { return brightness; }
|
||||||
|
void NeoPixel_setBrightness(int newBrightness) {
|
||||||
|
if (newBrightness > 0 && newBrightness <= 100) {
|
||||||
|
brightness = newBrightness;
|
||||||
|
} else {
|
||||||
|
LOG(LL_ERROR, ("invalid brightness value %d", newBrightness));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ## **`NeoPixel_clear()`**
|
// ## **`NeoPixel_clear()`**
|
||||||
// Clear in-memory values of the pixels.
|
// Clear in-memory values of the pixels.
|
||||||
|
@ -44,7 +60,8 @@ void NeoPixel_create(uint8_t pin, uint8_t numPixels, enum NeoPixel_ColorOrder or
|
||||||
mgos_gpio_set_mode(pin, MGOS_GPIO_MODE_OUTPUT);
|
mgos_gpio_set_mode(pin, MGOS_GPIO_MODE_OUTPUT);
|
||||||
// GPIO.write(pin, 0); // Keep in reset.
|
// GPIO.write(pin, 0); // Keep in reset.
|
||||||
mgos_gpio_write(pin, false);
|
mgos_gpio_write(pin, false);
|
||||||
LOG(LL_INFO, ("pin=%d, numPixels=%d, colorOrder=%d", pin, numPixels, order));
|
brightness = mgos_sys_config_get_led_brightness();
|
||||||
|
LOG(LL_INFO, ("pin=%d, numPixels=%d, colorOrder=%d, brightness=%d", pin, numPixels, order, brightness));
|
||||||
NeoPixel_clear();
|
NeoPixel_clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,9 +95,9 @@ void NeoPixel_set(int pixel, int red, int green, int blue) {
|
||||||
} else if (NeoPixel_colorOrder == NeoPixel_colorOrder_BGR) {
|
} else if (NeoPixel_colorOrder == NeoPixel_colorOrder_BGR) {
|
||||||
v0 = blue; v1 = green; v2 = red;
|
v0 = blue; v1 = green; v2 = red;
|
||||||
} else return;
|
} else return;
|
||||||
NeoPixel_leds[3*pixel] = v0;
|
NeoPixel_leds[3*pixel] = adjustBrightness(v0);
|
||||||
NeoPixel_leds[3*pixel+1] = v1;
|
NeoPixel_leds[3*pixel+1] = adjustBrightness(v1);
|
||||||
NeoPixel_leds[3*pixel+2] = v2;
|
NeoPixel_leds[3*pixel+2] = adjustBrightness(v2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ## **`NeoPixel_show()`**
|
// ## **`NeoPixel_show()`**
|
||||||
|
|
|
@ -11,5 +11,7 @@ extern void NeoPixel_release();
|
||||||
extern void NeoPixel_create(uint8_t pin, uint8_t numPixels, enum NeoPixel_ColorOrder order);
|
extern void NeoPixel_create(uint8_t pin, uint8_t numPixels, enum NeoPixel_ColorOrder order);
|
||||||
extern void NeoPixel_set(int pixel, int red, int green, int blue);
|
extern void NeoPixel_set(int pixel, int red, int green, int blue);
|
||||||
extern void NeoPixel_show();
|
extern void NeoPixel_show();
|
||||||
|
extern int NeoPixel_getBrightness();
|
||||||
|
extern void NeoPixel_setBrightness(int newBrightness);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
#include "Scheduler.h"
|
||||||
|
#include "LEDDefinition.h"
|
||||||
|
#include "NeoPixel.h"
|
||||||
|
#include "mgos_timers.h"
|
||||||
|
|
||||||
|
enum ScheduleItemMode {
|
||||||
|
ScheduleItemMode_OnOff,
|
||||||
|
ScheduleItemMode_NeonOn,
|
||||||
|
ScheduleItemMode_tv_bw,
|
||||||
|
ScheduleItemMode_tv_color
|
||||||
|
};
|
||||||
|
|
||||||
|
static enum ScheduleItemMode modeFromName(char *name) {
|
||||||
|
if (strcmp(name, "OnOff") == 0) return ScheduleItemMode_OnOff;
|
||||||
|
if (strcmp(name, "NeonOn") == 0) return ScheduleItemMode_NeonOn;
|
||||||
|
if (strcmp(name, "TV_BW") == 0) return ScheduleItemMode_tv_bw;
|
||||||
|
if (strcmp(name, "TV_Color") == 0) return ScheduleItemMode_tv_color;
|
||||||
|
LOG(LL_ERROR, ("Invalid mode name: %s", name));
|
||||||
|
return ScheduleItemMode_OnOff;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct Schedule_t {
|
||||||
|
uint8_t h;
|
||||||
|
uint8_t m;
|
||||||
|
uint8_t led;
|
||||||
|
enum ScheduleItemMode mode;
|
||||||
|
LEDColor *color;
|
||||||
|
} Schedule;
|
||||||
|
static Schedule *schedule = NULL;
|
||||||
|
static int numScheduleItems = 0;
|
||||||
|
static int loadedScheduleItems = 0;
|
||||||
|
static int numberOfLeds = 0;
|
||||||
|
static int currentHour = 0;
|
||||||
|
static int currentMinute = 0;
|
||||||
|
static int clockSpeed = 1; // # seconds for every real time minute
|
||||||
|
static bool clockRunning = false;
|
||||||
|
static mgos_timer_id clockTimer = 0;
|
||||||
|
|
||||||
|
static void executeScheduleItem(Schedule *s) {
|
||||||
|
LOG(LL_INFO, ("%d:%d LED #%d / mode=%d / color=%s", s->h, s->m, s->led, s->mode, s->color->name));
|
||||||
|
if (s->mode == ScheduleItemMode_OnOff) {
|
||||||
|
NeoPixel_set(s->led, s->color->red, s->color->green, s->color->blue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void LEDScheduler_timerTick() {
|
||||||
|
bool ledsNeedUpdate = false;
|
||||||
|
|
||||||
|
if (clockRunning) {
|
||||||
|
currentMinute++;
|
||||||
|
if (currentMinute >= 60) {
|
||||||
|
currentMinute = 0;
|
||||||
|
currentHour++;
|
||||||
|
if (currentHour >= 24) {
|
||||||
|
currentHour = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i=0; i<loadedScheduleItems; ++i) {
|
||||||
|
if (schedule[i].h == currentHour && schedule[i].m == currentMinute) {
|
||||||
|
// ACTION!
|
||||||
|
executeScheduleItem(&schedule[i]);
|
||||||
|
ledsNeedUpdate = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ledsNeedUpdate) {
|
||||||
|
NeoPixel_show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LEDScheduler_init(int setNumScheduleItems, int setNumberOfLeds, int ledPin) {
|
||||||
|
if (schedule != NULL) free(schedule);
|
||||||
|
numScheduleItems = setNumScheduleItems;
|
||||||
|
loadedScheduleItems = 0;
|
||||||
|
numberOfLeds = setNumberOfLeds;
|
||||||
|
schedule = malloc(numScheduleItems * sizeof(Schedule));
|
||||||
|
NeoPixel_release();
|
||||||
|
NeoPixel_create(ledPin, numberOfLeds, NeoPixel_colorOrder_GRB);
|
||||||
|
clockRunning = false;
|
||||||
|
clockTimer = mgos_set_timer(1000, true, LEDScheduler_timerTick, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LEDScheduler_addItem(int h, int m, int led, char *mode, char *colorName) {
|
||||||
|
if (loadedScheduleItems >= numScheduleItems) {
|
||||||
|
LOG(LL_ERROR, ("Cannot load schedule item as storage is already full, %d:%d LED #%d", h, m, led));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
schedule[loadedScheduleItems].h = h;
|
||||||
|
schedule[loadedScheduleItems].m = m;
|
||||||
|
schedule[loadedScheduleItems].led = led;
|
||||||
|
schedule[loadedScheduleItems].mode = modeFromName(mode);
|
||||||
|
schedule[loadedScheduleItems].color = LEDColor_get(colorName);;
|
||||||
|
schedule[loadedScheduleItems].h = h;
|
||||||
|
++loadedScheduleItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LEDScheduler_run() { clockRunning = true; }
|
||||||
|
void LEDScheduler_pause() { clockRunning = false; }
|
||||||
|
|
||||||
|
void LEDScheduler_setWatch(int h, int m, int speed) {
|
||||||
|
currentHour = h;
|
||||||
|
currentMinute = m;
|
||||||
|
clockSpeed = speed;
|
||||||
|
LOG(LL_INFO, ("set time %d:%d and speed to %d real-time seconds for a model minute", h, m, speed));
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
extern void LEDScheduler_init(int, int, int);
|
||||||
|
extern void LEDScheduler_run();
|
||||||
|
extern void LEDScheduler_pause();
|
||||||
|
extern void LEDScheduler_addItem(int h, int m, int led, char *mode, char *colorName);
|
||||||
|
extern void LEDScheduler_setWatch(int h, int m, int speed);
|
|
@ -52,6 +52,7 @@ static void stateEngineTickTimer() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void delayed_boot() {
|
static void delayed_boot() {
|
||||||
LOG(LL_INFO, ("*** Start timer for LED state engine ticks"));
|
LOG(LL_INFO, ("*** Start timer for LED state engine ticks"));
|
||||||
mgos_set_timer(mgos_sys_config_get_led_tickDuration(), true, stateEngineTickTimer, NULL);
|
mgos_set_timer(mgos_sys_config_get_led_tickDuration(), true, stateEngineTickTimer, NULL);
|
||||||
|
|
Loading…
Reference in New Issue