dlite/src/Scheduler.c

106 lines
3.2 KiB
C

#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));
}