kopia lustrzana https://github.com/Aircoookie/WLED
Add scheduleing (kinda replaceing macros?)
rodzic
b7bfd6fc67
commit
bd0b620b47
|
@ -178,6 +178,11 @@
|
|||
Countdown Goal:<br>
|
||||
Date: <nowrap>20<input name="CY" class="xs" type="number" min="0" max="99" required>-<input name="CI" class="xs" type="number" min="1" max="12" required>-<input name="CD" class="xs" type="number" min="1" max="31" required></nowrap><br>
|
||||
Time: <nowrap><input name="CH" class="xs" type="number" min="0" max="23" required>:<input name="CM" class="xs" type="number" min="0" max="59" required>:<input name="CS" class="xs" type="number" min="0" max="59" required></nowrap><br>
|
||||
<h3>Upload Schedule JSON</h3>
|
||||
<input type="file" name="scheduleFile" id="scheduleFile" accept=".json">
|
||||
<input type="button" value="Upload" onclick="uploadFile(d.Sf.scheduleFile, '/schedule.json');">
|
||||
<br>
|
||||
<a class="btn lnk" id="bckschedule" href="/schedule.json" download="schedule">Backup schedule</a><br>
|
||||
<h3>Macro presets</h3>
|
||||
<b>Macros have moved!</b><br>
|
||||
<i>Presets now also can be used as macros to save both JSON and HTTP API commands.<br>
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
// schedule.cpp
|
||||
|
||||
//TODO: make schedule.json trigger loadshedule(); on upload istead of just once a min (line 50)
|
||||
|
||||
#include "schedule.h"
|
||||
#include <WLED.h>
|
||||
#include <time.h>
|
||||
|
||||
#define SCHEDULE_FILE "/schedule.json"
|
||||
|
||||
ScheduleEvent scheduleEvents[MAX_SCHEDULE_EVENTS];
|
||||
uint8_t numScheduleEvents = 0;
|
||||
|
||||
bool isTodayInRange(uint8_t sm, uint8_t sd, uint8_t em, uint8_t ed, uint8_t cm, uint8_t cd)
|
||||
{
|
||||
if (sm < em || (sm == em && sd <= ed))
|
||||
{
|
||||
return (cm > sm || (cm == sm && cd >= sd)) &&
|
||||
(cm < em || (cm == em && cd <= ed));
|
||||
}
|
||||
else
|
||||
{
|
||||
return (cm > sm || (cm == sm && cd >= sd)) ||
|
||||
(cm < em || (cm == em && cd <= ed));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Checks the schedule and applies any events that match the current time and date.
|
||||
|
||||
void checkSchedule() {
|
||||
static int lastMinute = -1;
|
||||
|
||||
time_t now = localTime;
|
||||
if (now < 100000) return;
|
||||
|
||||
struct tm* timeinfo = localtime(&now);
|
||||
int thisMinute = timeinfo->tm_min + timeinfo->tm_hour * 60;
|
||||
|
||||
if (thisMinute == lastMinute) return;
|
||||
lastMinute = thisMinute;
|
||||
|
||||
|
||||
uint8_t cm = timeinfo->tm_mon + 1; // months since Jan (0-11)
|
||||
uint8_t cd = timeinfo->tm_mday;
|
||||
uint8_t wday = timeinfo->tm_wday; // days since Sunday (0-6)
|
||||
uint8_t hr = timeinfo->tm_hour;
|
||||
uint8_t min = timeinfo->tm_min;
|
||||
|
||||
loadSchedule();
|
||||
DEBUG_PRINTF_P(PSTR("[Schedule] Checking schedule at %02u:%02u\n"), hr, min);
|
||||
|
||||
for (uint8_t i = 0; i < numScheduleEvents; i++)
|
||||
{
|
||||
const ScheduleEvent &e = scheduleEvents[i];
|
||||
if (e.hour != hr || e.minute != min)
|
||||
continue;
|
||||
|
||||
bool match = false;
|
||||
if (e.repeatMask && ((e.repeatMask >> wday) & 0x01))
|
||||
match = true;
|
||||
if (e.startMonth)
|
||||
{
|
||||
if (isTodayInRange(e.startMonth, e.startDay, e.endMonth, e.endDay, cm, cd))
|
||||
match = true;
|
||||
}
|
||||
|
||||
if (match)
|
||||
applyPreset(e.presetId);
|
||||
DEBUG_PRINTF_P(PSTR("[Schedule] Applying preset %u at %02u:%02u\n"), e.presetId, hr, min);
|
||||
DEBUG_PRINTF_P(PSTR("[Schedule] Checked event %u: match=%d\n"), i, match);
|
||||
}
|
||||
}
|
||||
|
||||
void loadSchedule()
|
||||
{
|
||||
if (!WLED_FS.exists(SCHEDULE_FILE))
|
||||
return;
|
||||
File file = WLED_FS.open(SCHEDULE_FILE, "r");
|
||||
if (!file)
|
||||
return;
|
||||
|
||||
DynamicJsonDocument doc(4096);
|
||||
if (deserializeJson(doc, file))
|
||||
{
|
||||
file.close();
|
||||
return;
|
||||
}
|
||||
file.close();
|
||||
|
||||
numScheduleEvents = 0;
|
||||
for (JsonObject e : doc.as<JsonArray>())
|
||||
{
|
||||
if (numScheduleEvents >= MAX_SCHEDULE_EVENTS)
|
||||
break;
|
||||
scheduleEvents[numScheduleEvents++] = {
|
||||
(uint8_t)e["sm"], (uint8_t)e["sd"], // start month, day
|
||||
(uint8_t)e["em"], (uint8_t)e["ed"], // end month, day
|
||||
(uint8_t)e["r"], (uint8_t)e["h"], // repeat mask, hour
|
||||
(uint8_t)e["m"], (uint8_t)e["p"]}; // minute, preset
|
||||
}
|
||||
DEBUG_PRINTF_P(PSTR("[Schedule] Loaded %u schedule entries from schedule.json\n"), numScheduleEvents);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
// schedule.h
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define MAX_SCHEDULE_EVENTS 32
|
||||
|
||||
struct ScheduleEvent {
|
||||
uint8_t startMonth;
|
||||
uint8_t startDay;
|
||||
uint8_t endMonth;
|
||||
uint8_t endDay;
|
||||
uint8_t repeatMask;
|
||||
uint8_t hour;
|
||||
uint8_t minute;
|
||||
uint8_t presetId;
|
||||
};
|
||||
|
||||
void loadSchedule();
|
||||
void checkSchedule();
|
|
@ -54,6 +54,7 @@ void WLED::loop()
|
|||
#endif
|
||||
|
||||
handleTime();
|
||||
checkSchedule();
|
||||
#ifndef WLED_DISABLE_INFRARED
|
||||
handleIR(); // 2nd call to function needed for ESP32 to return valid results -- should be good for ESP8266, too
|
||||
#endif
|
||||
|
@ -526,6 +527,8 @@ void WLED::setup()
|
|||
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_DISABLE_BROWNOUT_DET)
|
||||
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 1); //enable brownout detector
|
||||
#endif
|
||||
|
||||
loadSchedule();
|
||||
}
|
||||
|
||||
void WLED::beginStrip()
|
||||
|
|
|
@ -66,6 +66,8 @@
|
|||
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
#include "schedule.h"
|
||||
|
||||
|
||||
// Library inclusions.
|
||||
#include <Arduino.h>
|
||||
|
|
Ładowanie…
Reference in New Issue