mirror of
https://github.com/OpenEPaperLink/OpenEPaperLink.git
synced 2026-03-21 00:04:28 +01:00
Add ap_date and ap_time vars (#142)
* Add ap_date and ap_time vars * Add convenience creation function for Timer * Optimize timer * Document timer
This commit is contained in:
4
ESP32_AP-Flasher/.vscode/settings.json
vendored
4
ESP32_AP-Flasher/.vscode/settings.json
vendored
@@ -50,6 +50,8 @@
|
||||
"stdexcept": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"typeinfo": "cpp"
|
||||
"typeinfo": "cpp",
|
||||
"chrono": "cpp",
|
||||
"ratio": "cpp"
|
||||
}
|
||||
}
|
||||
@@ -108,7 +108,14 @@ extern void clearPending(tagRecord* taginfo);
|
||||
extern void initAPconfig();
|
||||
extern void saveAPconfig();
|
||||
extern HwType getHwType(const uint8_t id);
|
||||
extern bool setVarDB(const std::string& key, const String& value);
|
||||
/// @brief Update a variable with the given key and value
|
||||
///
|
||||
/// @param key Variable key
|
||||
/// @param value Variable value
|
||||
/// @param notify Should the change be notified (true, default) or not (false)
|
||||
/// @return true If variable was created/updated
|
||||
/// @return false If not
|
||||
extern bool setVarDB(const std::string& key, const String& value, const bool notify = true);
|
||||
extern void cleanupCurrent();
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "system.h"
|
||||
#include "web.h"
|
||||
|
||||
/// @brief Different utility functions
|
||||
namespace util {
|
||||
|
||||
/// @brief Can be used to wrap a stream and see what's going on
|
||||
@@ -125,26 +126,46 @@ static bool isSleeping(int sleeptime1, int sleeptime2) {
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief Get the time_t for midnight
|
||||
/// @return time_t for midnight
|
||||
inline time_t getMidnightTime() {
|
||||
struct tm time_info;
|
||||
getLocalTime(&time_info);
|
||||
time_info.tm_hour = time_info.tm_min = time_info.tm_sec = 0;
|
||||
time_info.tm_mday++;
|
||||
return mktime(&time_info);
|
||||
}
|
||||
|
||||
/// @brief Timer for kind of scheduling things
|
||||
class Timer {
|
||||
public:
|
||||
Timer(unsigned long interval) : interval_(interval), previousMillis_(0) {}
|
||||
/// @brief Construct a timer
|
||||
/// @param interval Interval in ms at which @ref doRun() returns true
|
||||
/// @param delay Delay in ms until first execution to defer start
|
||||
Timer(const unsigned long interval, const unsigned long delay = 0) : m_interval(interval), m_nextMillis(millis() + delay) {}
|
||||
|
||||
void setInterval(unsigned long interval) {
|
||||
interval_ = interval;
|
||||
/// @brief Change the interval
|
||||
/// @param interval New interval in ms
|
||||
void setInterval(const unsigned long interval) {
|
||||
m_interval = interval;
|
||||
}
|
||||
|
||||
bool doRun() {
|
||||
unsigned long currentMillis = millis();
|
||||
if (currentMillis - previousMillis_ >= interval_) {
|
||||
previousMillis_ = currentMillis;
|
||||
/// @brief Check if interval is met
|
||||
/// @param currentMillis Optionally provide the current time in millis
|
||||
/// @return True if interval is met, false if not
|
||||
bool doRun(const unsigned long currentMillis = millis()) {
|
||||
if (currentMillis >= m_nextMillis) {
|
||||
m_nextMillis = currentMillis + m_interval;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned long interval_;
|
||||
unsigned long previousMillis_;
|
||||
/// @brief Timer interval in ms
|
||||
unsigned long m_interval;
|
||||
/// @brief Next timeer interval in ms
|
||||
unsigned long m_nextMillis;
|
||||
};
|
||||
|
||||
/// @brief Create a String from format
|
||||
@@ -163,3 +184,10 @@ inline String formatString(char buffer[bufSize], const char *format, ...) {
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
|
||||
/// @brief Converts seconds to milliseconds
|
||||
#define seconds(s) s * 1000
|
||||
/// @brief Converts minutes to milliseconds
|
||||
#define minutes(m) seconds(m * 60)
|
||||
/// @brief Converts hours to milliseconds
|
||||
#define hours(m) minutes(m * 60)
|
||||
|
||||
@@ -178,12 +178,6 @@ void drawNew(const uint8_t mac[8], const bool buttonPressed, tagRecord *&taginfo
|
||||
}
|
||||
#endif
|
||||
|
||||
struct tm time_info;
|
||||
getLocalTime(&time_info);
|
||||
time_info.tm_hour = time_info.tm_min = time_info.tm_sec = 0;
|
||||
time_info.tm_mday++;
|
||||
const time_t midnight = mktime(&time_info);
|
||||
|
||||
DynamicJsonDocument doc(500);
|
||||
deserializeJson(doc, taginfo->modeConfigJson);
|
||||
JsonObject cfgobj = doc.as<JsonObject>();
|
||||
@@ -193,7 +187,6 @@ void drawNew(const uint8_t mac[8], const bool buttonPressed, tagRecord *&taginfo
|
||||
taginfo->nextupdate = now + 60;
|
||||
|
||||
imgParam imageParams;
|
||||
|
||||
imageParams.width = hwdata.width;
|
||||
imageParams.height = hwdata.height;
|
||||
imageParams.bpp = hwdata.bpp;
|
||||
@@ -280,12 +273,12 @@ void drawNew(const uint8_t mac[8], const bool buttonPressed, tagRecord *&taginfo
|
||||
case 1: // Today
|
||||
|
||||
drawDate(filename, taginfo, imageParams);
|
||||
taginfo->nextupdate = midnight;
|
||||
updateTagImage(filename, mac, (midnight - now) / 60 - 10, taginfo, imageParams);
|
||||
taginfo->nextupdate = util::getMidnightTime();
|
||||
updateTagImage(filename, mac, (taginfo->nextupdate - now) / 60 - 10, taginfo, imageParams);
|
||||
break;
|
||||
|
||||
case 2: // CountDays
|
||||
drawCounter(mac, buttonPressed, taginfo, cfgobj, filename, imageParams, midnight, 15);
|
||||
drawCounter(mac, buttonPressed, taginfo, cfgobj, filename, imageParams, util::getMidnightTime(), 15);
|
||||
break;
|
||||
|
||||
case 3: // CountHours
|
||||
@@ -509,11 +502,19 @@ void replaceVariables(String &format) {
|
||||
size_t startIndex = 0;
|
||||
size_t openBraceIndex, closeBraceIndex;
|
||||
|
||||
time_t now;
|
||||
time(&now);
|
||||
struct tm timedef;
|
||||
localtime_r(&now, &timedef);
|
||||
char timeBuffer[80];
|
||||
strftime(timeBuffer, sizeof(timeBuffer), "%H:%M:%S", &timedef);
|
||||
setVarDB("ap_time", timeBuffer, false);
|
||||
|
||||
while ((openBraceIndex = format.indexOf('{', startIndex)) != -1 &&
|
||||
(closeBraceIndex = format.indexOf('}', openBraceIndex + 1)) != -1) {
|
||||
const std::string variableName = format.substring(openBraceIndex + 1, closeBraceIndex).c_str();
|
||||
const std::string varKey = "{" + variableName + "}";
|
||||
auto var = varDB.find(variableName);
|
||||
const auto var = varDB.find(variableName);
|
||||
if (var != varDB.end()) {
|
||||
format.replace(varKey.c_str(), var->second.value);
|
||||
}
|
||||
|
||||
@@ -23,10 +23,15 @@
|
||||
#include "util.h"
|
||||
#include "web.h"
|
||||
|
||||
util::Timer intervalSysinfo(3000);
|
||||
util::Timer intervalVars(10000);
|
||||
util::Timer intervalSaveDB(300000);
|
||||
util::Timer intervalContentRunner(1000);
|
||||
util::Timer intervalContentRunner(seconds(1));
|
||||
util::Timer intervalSysinfo(seconds(3));
|
||||
util::Timer intervalVars(seconds(10));
|
||||
util::Timer intervalSaveDB(minutes(5));
|
||||
util::Timer intervalCheckDate(minutes(5));
|
||||
|
||||
#ifdef OPENEPAPERLINK_PCB
|
||||
util::Timer tagConnectTimer(seconds(1));
|
||||
#endif
|
||||
|
||||
SET_LOOP_TASK_STACK_SIZE(16 * 1024);
|
||||
|
||||
@@ -158,6 +163,21 @@ void loop() {
|
||||
if (intervalContentRunner.doRun() && apInfo.state == AP_STATE_ONLINE) {
|
||||
contentRunner();
|
||||
}
|
||||
if (intervalCheckDate.doRun() && config.runStatus == RUNSTATUS_RUN) {
|
||||
static uint8_t day = 0;
|
||||
|
||||
time_t now;
|
||||
time(&now);
|
||||
struct tm timedef;
|
||||
localtime_r(&now, &timedef);
|
||||
|
||||
if (day != timedef.tm_mday) {
|
||||
day = timedef.tm_mday;
|
||||
char timeBuffer[80];
|
||||
strftime(timeBuffer, sizeof(timeBuffer), "%d-%m-%Y", &timedef);
|
||||
setVarDB("ap_date", timeBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef YELLOW_IPS_AP
|
||||
extern void yellow_ap_display_loop(void);
|
||||
@@ -165,21 +185,17 @@ void loop() {
|
||||
#endif
|
||||
|
||||
#ifdef OPENEPAPERLINK_PCB
|
||||
time_t tagConnectTimer = 0;
|
||||
if (millis() - tagConnectTimer > 1000) {
|
||||
tagConnectTimer = millis();
|
||||
if (extTagConnected()) {
|
||||
flashCountDown(3);
|
||||
if (tagConnectTimer.doRun() && extTagConnected()) {
|
||||
flashCountDown(3);
|
||||
|
||||
pinMode(FLASHER_EXT_TEST, OUTPUT);
|
||||
digitalWrite(FLASHER_EXT_TEST, LOW);
|
||||
pinMode(FLASHER_EXT_TEST, OUTPUT);
|
||||
digitalWrite(FLASHER_EXT_TEST, LOW);
|
||||
|
||||
doTagFlash();
|
||||
doTagFlash();
|
||||
|
||||
vTaskDelay(10000 / portTICK_PERIOD_MS);
|
||||
pinMode(FLASHER_EXT_TEST, INPUT);
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
vTaskDelay(10000 / portTICK_PERIOD_MS);
|
||||
pinMode(FLASHER_EXT_TEST, INPUT);
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -330,7 +330,9 @@ void prepareExternalDataAvail(struct pendingData* pending, IPAddress remoteIP) {
|
||||
}
|
||||
|
||||
void processBlockRequest(struct espBlockRequest* br) {
|
||||
if (config.runStatus == RUNSTATUS_STOP) return;
|
||||
if (config.runStatus == RUNSTATUS_STOP) {
|
||||
return;
|
||||
}
|
||||
if (!checkCRC(br, sizeof(struct espBlockRequest))) {
|
||||
Serial.print("Failed CRC on a blockrequest received by the AP");
|
||||
return;
|
||||
@@ -372,7 +374,9 @@ void processBlockRequest(struct espBlockRequest* br) {
|
||||
}
|
||||
|
||||
void processXferComplete(struct espXferComplete* xfc, bool local) {
|
||||
if (config.runStatus == RUNSTATUS_STOP) return;
|
||||
if (config.runStatus == RUNSTATUS_STOP) {
|
||||
return;
|
||||
}
|
||||
char buffer[64];
|
||||
sprintf(buffer, "< %02X%02X%02X%02X%02X%02X%02X%02X reports xfer complete\n\0", xfc->src[7], xfc->src[6], xfc->src[5], xfc->src[4], xfc->src[3], xfc->src[2], xfc->src[1], xfc->src[0]);
|
||||
wsLog((String)buffer);
|
||||
@@ -416,7 +420,9 @@ void processXferComplete(struct espXferComplete* xfc, bool local) {
|
||||
}
|
||||
|
||||
void processXferTimeout(struct espXferComplete* xfc, bool local) {
|
||||
if (config.runStatus == RUNSTATUS_STOP) return;
|
||||
if (config.runStatus == RUNSTATUS_STOP) {
|
||||
return;
|
||||
}
|
||||
char buffer[64];
|
||||
sprintf(buffer, "< %02X%02X%02X%02X%02X%02X%02X%02X xfer timeout\n\0", xfc->src[7], xfc->src[6], xfc->src[5], xfc->src[4], xfc->src[3], xfc->src[2], xfc->src[1], xfc->src[0]);
|
||||
wsErr((String)buffer);
|
||||
@@ -440,7 +446,9 @@ void processXferTimeout(struct espXferComplete* xfc, bool local) {
|
||||
}
|
||||
|
||||
void processDataReq(struct espAvailDataReq* eadr, bool local, IPAddress remoteIP) {
|
||||
if (config.runStatus == RUNSTATUS_STOP) return;
|
||||
if (config.runStatus == RUNSTATUS_STOP) {
|
||||
return;
|
||||
}
|
||||
char buffer[64];
|
||||
|
||||
tagRecord* taginfo = tagRecord::findByMAC(eadr->src);
|
||||
|
||||
@@ -256,7 +256,7 @@ void C6firmwareUpdateTask(void* parameter) {
|
||||
|
||||
if (result) {
|
||||
setAPstate(false, AP_STATE_OFFLINE);
|
||||
|
||||
|
||||
wsSerial("Finishing config...");
|
||||
vTaskDelay(3000 / portTICK_PERIOD_MS);
|
||||
|
||||
|
||||
@@ -26,7 +26,9 @@ void initTime(void* parameter) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (config.runStatus = RUNSTATUS_INIT) config.runStatus = RUNSTATUS_RUN;
|
||||
if (config.runStatus == RUNSTATUS_INIT) {
|
||||
config.runStatus = RUNSTATUS_RUN;
|
||||
}
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
@@ -264,7 +264,7 @@ uint32_t getTagCount(uint32_t& timeoutcount) {
|
||||
// not initialised, timeout if not seen last 10 minutes
|
||||
if (timeout > 600) timeoutcount++;
|
||||
} else if (now - taginfo->expectedNextCheckin > 600) {
|
||||
//expected checkin is behind, timeout if not seen last 10 minutes
|
||||
// expected checkin is behind, timeout if not seen last 10 minutes
|
||||
if (timeout > 600) timeoutcount++;
|
||||
}
|
||||
}
|
||||
@@ -383,19 +383,19 @@ HwType getHwType(const uint8_t id) {
|
||||
}
|
||||
}
|
||||
|
||||
bool setVarDB(const std::string& key, const String& value) {
|
||||
bool setVarDB(const std::string& key, const String& value, const bool notify) {
|
||||
auto it = varDB.find(key);
|
||||
if (it == varDB.end()) {
|
||||
varStruct newVar;
|
||||
newVar.value = value;
|
||||
newVar.changed = true;
|
||||
newVar.changed = notify;
|
||||
varDB[key] = newVar;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (it->second.value != value) {
|
||||
it->second.value = value;
|
||||
it->second.changed = true;
|
||||
it->second.changed = notify;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
#include "udp.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <WiFi.h>
|
||||
|
||||
#include "AsyncUDP.h"
|
||||
#include "commstructs.h"
|
||||
#include "newproto.h"
|
||||
#include "serialap.h"
|
||||
#include "tag_db.h"
|
||||
#include "web.h"
|
||||
#include "serialap.h"
|
||||
#include "udp.h"
|
||||
|
||||
#define UDPIP IPAddress(239, 10, 0, 1)
|
||||
#define UDPPORT 16033
|
||||
@@ -41,8 +42,9 @@ void UDPcomm::init() {
|
||||
}
|
||||
|
||||
void UDPcomm::processPacket(AsyncUDPPacket packet) {
|
||||
|
||||
if (config.runStatus == RUNSTATUS_STOP) return;
|
||||
if (config.runStatus == RUNSTATUS_STOP) {
|
||||
return;
|
||||
}
|
||||
IPAddress senderIP = packet.remoteIP();
|
||||
|
||||
switch (packet.data()[0]) {
|
||||
@@ -127,7 +129,7 @@ void autoselect(void* pvParameters) {
|
||||
}
|
||||
if (curChannel.channel == 0) {
|
||||
curChannel.channel = 11;
|
||||
}
|
||||
}
|
||||
config.channel = curChannel.channel;
|
||||
do {
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
|
||||
Reference in New Issue
Block a user