Added new mode: Scheduler -- clock based switching of lights
This commit is contained in:
105
src/Scheduler.c
Normal file
105
src/Scheduler.c
Normal file
@@ -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));
|
||||
}
|
||||
Reference in New Issue
Block a user