From 5462d1e9f865db4a200905d2ce398e1f4fae5376 Mon Sep 17 00:00:00 2001 From: Blaz Kristan Date: Sat, 11 Dec 2021 23:17:47 +0100 Subject: [PATCH] Bugfix - incorrect bus length - invalid relay state - preset JSON corruption on network call - iro & rangetouch serving --- usermods/multi_relay/usermod_multi_relay.h | 23 +++++++++++++++++----- wled00/bus_manager.h | 4 ++-- wled00/presets.cpp | 10 +++++++++- wled00/wled_server.cpp | 2 -- 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/usermods/multi_relay/usermod_multi_relay.h b/usermods/multi_relay/usermod_multi_relay.h index 9a92d4e22..70719f9ef 100644 --- a/usermods/multi_relay/usermod_multi_relay.h +++ b/usermods/multi_relay/usermod_multi_relay.h @@ -45,6 +45,9 @@ class MultiRelay : public Usermod { // status of initialisation bool initDone = false; + uint16_t periodicBroadcastSec = 60; + unsigned long lastBroadcast = 0; + // strings to reduce flash memory usage (used more than twice) static const char _name[]; static const char _enabled[]; @@ -53,7 +56,7 @@ class MultiRelay : public Usermod { static const char _activeHigh[]; static const char _external[]; static const char _button[]; - + static const char _broadcast[]; void publishMqtt(const char* state, int relay) { //Check if MQTT Connected, otherwise it will crash the 8266 @@ -68,15 +71,19 @@ class MultiRelay : public Usermod { * switch off the strip if the delay has elapsed */ void handleOffTimer() { + unsigned long now = millis(); bool activeRelays = false; for (uint8_t i=0; i 0 && millis() - _switchTimerStart > (_relay[i].delay*1000)) { + if (_relay[i].active && _switchTimerStart > 0 && now - _switchTimerStart > (_relay[i].delay*1000)) { if (!_relay[i].external) toggleRelay(i); _relay[i].active = false; + } else if (periodicBroadcastSec && now - lastBroadcast > (periodicBroadcastSec*1000)) { + if (_relay[i].pin>=0) publishMqtt(_relay[i].state ? "on" : "off", i); } activeRelays = activeRelays || _relay[i].active; } if (!activeRelays) _switchTimerStart = 0; + if (periodicBroadcastSec && now - lastBroadcast > (periodicBroadcastSec*1000)) lastBroadcast = now; } /** @@ -266,7 +273,7 @@ class MultiRelay : public Usermod { if (!pinManager.allocatePin(_relay[i].pin,true, PinOwner::UM_MultiRelay)) { _relay[i].pin = -1; // allocation failed } else { - if (!_relay[i].external) _relay[i].state = offMode; + if (!_relay[i].external) _relay[i].state = !offMode; switchRelay(i, _relay[i].state); _relay[i].active = false; } @@ -477,6 +484,7 @@ class MultiRelay : public Usermod { JsonObject top = root.createNestedObject(FPSTR(_name)); top[FPSTR(_enabled)] = enabled; + top[FPSTR(_broadcast)] = periodicBroadcastSec; for (uint8_t i=0; i=0 && pinManager.allocatePin(_relay[i].pin, true, PinOwner::UM_MultiRelay)) { if (!_relay[i].external) { - switchRelay(i, offMode); + _relay[i].state = !offMode; + switchRelay(i, _relay[i].state); + _oldMode = offMode; } } else { _relay[i].pin = -1; @@ -549,7 +561,7 @@ class MultiRelay : public Usermod { DEBUG_PRINTLN(F(" config (re)loaded.")); } // use "return !top["newestParameter"].isNull();" when updating Usermod with new features - return !top[F("relay-0")][FPSTR(_button)].isNull(); + return !top[FPSTR(_broadcast)].isNull(); } /** @@ -570,3 +582,4 @@ const char MultiRelay::_delay_str[] PROGMEM = "delay-s"; const char MultiRelay::_activeHigh[] PROGMEM = "active-high"; const char MultiRelay::_external[] PROGMEM = "external"; const char MultiRelay::_button[] PROGMEM = "button"; +const char MultiRelay::_broadcast[] PROGMEM = "broadcast-sec"; diff --git a/wled00/bus_manager.h b/wled00/bus_manager.h index c449ffabb..00f4993f0 100644 --- a/wled00/bus_manager.h +++ b/wled00/bus_manager.h @@ -91,7 +91,7 @@ class Bus { virtual void setBrightness(uint8_t b) {} virtual void cleanup() {} virtual uint8_t getPins(uint8_t* pinArray) { return 0; } - inline uint16_t getLength() { return _len; } + virtual uint16_t getLength() { return _len; } virtual void setColorOrder() {} virtual uint8_t getColorOrder() { return COL_ORDER_RGB; } virtual uint8_t skippedLeds() { return 0; } @@ -220,7 +220,7 @@ class BusDigital : public Bus { return _colorOrder; } - inline uint16_t getLength() { + uint16_t getLength() { return _len - _skip; } diff --git a/wled00/presets.cpp b/wled00/presets.cpp index 0e65000b0..d5e3f5aec 100644 --- a/wled00/presets.cpp +++ b/wled00/presets.cpp @@ -12,7 +12,15 @@ bool applyPreset(byte index, byte callMode) const char *filename = index < 255 ? "/presets.json" : "/tmp.json"; - if (fileDoc) { + uint8_t core = 1; + //crude way to determine if this was called by a network request + #ifdef ARDUINO_ARCH_ESP32 + core = xPortGetCoreID(); + #endif + + //only allow use of fileDoc from the core responsible for network requests + //do not use active network request doc from preset called by main loop (playlist, schedule, ...) + if (fileDoc && core) { errorFlag = readObjectFromFileUsingId(filename, index, fileDoc) ? ERR_NONE : ERR_FS_PLOAD; JsonObject fdo = fileDoc->as(); if (fdo["ps"] == index) fdo.remove("ps"); //remove load request for same presets to prevent recursive crash diff --git a/wled00/wled_server.cpp b/wled00/wled_server.cpp index e5f2d85a3..535a233aa 100644 --- a/wled00/wled_server.cpp +++ b/wled00/wled_server.cpp @@ -202,7 +202,6 @@ void initServer() }); server.on("/iro.js", HTTP_GET, [](AsyncWebServerRequest *request){ - if (handleIfNoneMatchCacheHeader(request)) return; AsyncWebServerResponse *response = request->beginResponse_P(200, "application/javascript", iroJs, iroJs_length); response->addHeader(F("Content-Encoding"),"gzip"); setStaticContentCacheHeaders(response); @@ -210,7 +209,6 @@ void initServer() }); server.on("/rangetouch.js", HTTP_GET, [](AsyncWebServerRequest *request){ - if (handleIfNoneMatchCacheHeader(request)) return; AsyncWebServerResponse *response = request->beginResponse_P(200, "application/javascript", rangetouchJs, rangetouchJs_length); response->addHeader(F("Content-Encoding"),"gzip"); setStaticContentCacheHeaders(response);