diff --git a/usermods/Temperature/usermod_temperature.h b/usermods/Temperature/usermod_temperature.h index f7586e444..5b6b21d8c 100644 --- a/usermods/Temperature/usermod_temperature.h +++ b/usermods/Temperature/usermod_temperature.h @@ -57,7 +57,10 @@ class UsermodTemperature : public Usermod { static const char _parasite[]; static const char _parasitePin[]; static const char _domoticzIDX[]; - + static const char _sensor[]; + static const char _temperature[]; + static const char _Temperature[]; + //Dallas sensor quick (& dirty) reading. Credit to - Author: Peter Scargill, August 17th, 2013 float readDallas(); void requestTemperatures(); @@ -191,9 +194,9 @@ void UsermodTemperature::publishHomeAssistantAutodiscovery() { sprintf_P(buf, PSTR("%s Temperature"), serverDescription); json[F("name")] = buf; strcpy(buf, mqttDeviceTopic); - strcat_P(buf, PSTR("/temperature")); + strcat_P(buf, _Temperature); json[F("state_topic")] = buf; - json[F("device_class")] = F("temperature"); + json[F("device_class")] = FPSTR(_temperature); json[F("unique_id")] = escapedMac.c_str(); json[F("unit_of_measurement")] = F("°C"); payload_size = serializeJson(json, json_str); @@ -272,7 +275,7 @@ void UsermodTemperature::loop() { // dont publish super low temperature as the graph will get messed up // the DallasTemperature library returns -127C or -196.6F when problem // reading the sensor - strcat_P(subuf, PSTR("/temperature")); + strcat_P(subuf, _Temperature); mqtt->publish(subuf, 0, false, String(getTemperatureC()).c_str()); strcat_P(subuf, PSTR("_f")); mqtt->publish(subuf, 0, false, String(getTemperatureF()).c_str()); @@ -335,9 +338,9 @@ void UsermodTemperature::addToJsonInfo(JsonObject& root) { temp.add(getTemperature()); temp.add(getTemperatureUnit()); - JsonObject sensor = root[F("sensor")]; - if (sensor.isNull()) sensor = root.createNestedObject(F("sensor")); - temp = sensor.createNestedArray(F("temperature")); + JsonObject sensor = root[FPSTR(_sensor)]; + if (sensor.isNull()) sensor = root.createNestedObject(FPSTR(_sensor)); + temp = sensor.createNestedArray(FPSTR(_temperature)); temp.add(getTemperature()); temp.add(getTemperatureUnit()); } @@ -367,7 +370,7 @@ void UsermodTemperature::addToConfig(JsonObject &root) { JsonObject top = root.createNestedObject(FPSTR(_name)); // usermodname top[FPSTR(_enabled)] = enabled; top["pin"] = temperaturePin; // usermodparam - top["degC"] = degC; // usermodparam + top[F("degC")] = degC; // usermodparam top[FPSTR(_readInterval)] = readingInterval / 1000; top[FPSTR(_parasite)] = parasite; top[FPSTR(_parasitePin)] = parasitePin; @@ -393,7 +396,7 @@ bool UsermodTemperature::readFromConfig(JsonObject &root) { enabled = top[FPSTR(_enabled)] | enabled; newTemperaturePin = top["pin"] | newTemperaturePin; - degC = top["degC"] | degC; + degC = top[F("degC")] | degC; readingInterval = top[FPSTR(_readInterval)] | readingInterval/1000; readingInterval = min(120,max(10,(int)readingInterval)) * 1000; // convert to ms parasite = top[FPSTR(_parasite)] | parasite; @@ -444,3 +447,6 @@ const char UsermodTemperature::_readInterval[] PROGMEM = "read-interval-s"; const char UsermodTemperature::_parasite[] PROGMEM = "parasite-pwr"; const char UsermodTemperature::_parasitePin[] PROGMEM = "parasite-pwr-pin"; const char UsermodTemperature::_domoticzIDX[] PROGMEM = "domoticz-idx"; +const char UsermodTemperature::_sensor[] PROGMEM = "sensor"; +const char UsermodTemperature::_temperature[] PROGMEM = "temperature"; +const char UsermodTemperature::_Temperature[] PROGMEM = "/temperature"; \ No newline at end of file diff --git a/usermods/multi_relay/usermod_multi_relay.h b/usermods/multi_relay/usermod_multi_relay.h index e13cf4775..cb1eec8e1 100644 --- a/usermods/multi_relay/usermod_multi_relay.h +++ b/usermods/multi_relay/usermod_multi_relay.h @@ -104,6 +104,9 @@ class MultiRelay : public Usermod { static const char _HAautodiscovery[]; static const char _pcf8574[]; static const char _pcfAddress[]; + static const char _switch[]; + static const char _toggle[]; + static const char _Command[]; void handleOffTimer(); void InitHtmlAPIHandle(); @@ -261,7 +264,7 @@ void MultiRelay::handleOffTimer() { void MultiRelay::InitHtmlAPIHandle() { // https://github.com/me-no-dev/ESPAsyncWebServer DEBUG_PRINTLN(F("Relays: Initialize HTML API")); - server.on("/relays", HTTP_GET, [this](AsyncWebServerRequest *request) { + server.on(SET_F("/relays"), HTTP_GET, [this](AsyncWebServerRequest *request) { DEBUG_PRINTLN(F("Relays: HTML API")); String janswer; String error = ""; @@ -271,9 +274,9 @@ void MultiRelay::InitHtmlAPIHandle() { // https://github.com/me-no-dev/ESPAsync if (getActiveRelayCount()) { // Commands - if(request->hasParam("switch")) { + if (request->hasParam(FPSTR(_switch))) { /**** Switch ****/ - AsyncWebParameter* p = request->getParam("switch"); + AsyncWebParameter* p = request->getParam(FPSTR(_switch)); // Get Values for (int i=0; ivalue(), ',', i); @@ -284,9 +287,9 @@ void MultiRelay::InitHtmlAPIHandle() { // https://github.com/me-no-dev/ESPAsync if (_relay[i].external) switchRelay(i, (bool)value); } } - } else if(request->hasParam("toggle")) { + } else if (request->hasParam(FPSTR(_toggle))) { /**** Toggle ****/ - AsyncWebParameter* p = request->getParam("toggle"); + AsyncWebParameter* p = request->getParam(FPSTR(_toggle)); // Get Values for (int i=0;ivalue(), ',', i); @@ -314,7 +317,7 @@ void MultiRelay::InitHtmlAPIHandle() { // https://github.com/me-no-dev/ESPAsync janswer += error; janswer += F("\","); janswer += F("\"SW Version\":\""); - janswer += String(GEOGABVERSION); + janswer += String(F(GEOGABVERSION)); janswer += F("\"}"); request->send(200, "application/json", janswer); }); @@ -420,7 +423,7 @@ uint8_t MultiRelay::getActiveRelayCount() { * topic should look like: /relay/X/command; where X is relay number, 0 based */ bool MultiRelay::onMqttMessage(char* topic, char* payload) { - if (strlen(topic) > 8 && strncmp_P(topic, PSTR("/relay/"), 7) == 0 && strncmp_P(topic+8, PSTR("/command"), 8) == 0) { + if (strlen(topic) > 8 && strncmp_P(topic, PSTR("/relay/"), 7) == 0 && strncmp_P(topic+8, _Command, 8) == 0) { uint8_t relay = strtoul(topic+7, NULL, 10); if (relaysubscribe(buf, 0); json[F("stat_t")] = "~"; @@ -675,8 +678,8 @@ void MultiRelay::addToJsonInfo(JsonObject &root) { uiDomString += F(",on:"); uiDomString += _relay[i].state ? "false" : "true"; uiDomString += F("}});\">"); - uiDomString += F(""); infoArr.add(uiDomString); } @@ -836,3 +839,6 @@ const char MultiRelay::_broadcast[] PROGMEM = "broadcast-sec"; const char MultiRelay::_HAautodiscovery[] PROGMEM = "HA-autodiscovery"; const char MultiRelay::_pcf8574[] PROGMEM = "use-PCF8574"; const char MultiRelay::_pcfAddress[] PROGMEM = "PCF8574-address"; +const char MultiRelay::_switch[] PROGMEM = "switch"; +const char MultiRelay::_toggle[] PROGMEM = "toggle"; +const char MultiRelay::_Command[] PROGMEM = "/command"; diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h index 47a8173cc..20ac21129 100644 --- a/wled00/fcn_declare.h +++ b/wled00/fcn_declare.h @@ -112,6 +112,10 @@ bool readObjectFromFileUsingId(const char* file, uint16_t id, JsonDocument* dest bool readObjectFromFile(const char* file, const char* key, JsonDocument* dest); void updateFSInfo(); void closeFile(); +inline bool writeObjectToFileUsingId(const String &file, uint16_t id, JsonDocument* content) { return writeObjectToFileUsingId(file.c_str(), id, content); }; +inline bool writeObjectToFile(const String &file, const char* key, JsonDocument* content) { return writeObjectToFile(file.c_str(), key, content); }; +inline bool readObjectFromFileUsingId(const String &file, uint16_t id, JsonDocument* dest) { return readObjectFromFileUsingId(file.c_str(), id, dest); }; +inline bool readObjectFromFile(const String &file, const char* key, JsonDocument* dest) { return readObjectFromFile(file.c_str(), key, dest); }; //hue.cpp void handleHue(); @@ -225,6 +229,7 @@ void handlePlaylist(); void serializePlaylist(JsonObject obj); //presets.cpp +const char *getPresetsFileName(bool persistent = true); void initPresetsFile(); void handlePresets(); bool applyPreset(byte index, byte callMode = CALL_MODE_DIRECT_CHANGE); diff --git a/wled00/file.cpp b/wled00/file.cpp index 4ae05f0b0..bf90d1f47 100644 --- a/wled00/file.cpp +++ b/wled00/file.cpp @@ -416,7 +416,7 @@ static const uint8_t *getPresetCache(size_t &size) { } if (!presetsCached) { - File file = WLED_FS.open("/presets.json", "r"); + File file = WLED_FS.open(FPSTR(getPresetsFileName()), "r"); if (file) { presetsCachedTime = presetsModifiedTime; presetsCachedSize = 0; @@ -446,7 +446,7 @@ bool handleFileRead(AsyncWebServerRequest* request, String path){ return true; }*/ #if defined(BOARD_HAS_PSRAM) && defined(WLED_USE_PSRAM) - if (path.endsWith("/presets.json")) { + if (path.endsWith(FPSTR(getPresetsFileName()))) { size_t psize; const uint8_t *presets = getPresetCache(psize); if (presets) { diff --git a/wled00/ntp.cpp b/wled00/ntp.cpp index 219a738ff..0b2cf3665 100644 --- a/wled00/ntp.cpp +++ b/wled00/ntp.cpp @@ -317,7 +317,8 @@ void getTimeString(char* out) sprintf_P(out,PSTR("%i-%i-%i, %02d:%02d:%02d"),year(localTime), month(localTime), day(localTime), hr, minute(localTime), second(localTime)); if (useAMPM) { - strcat(out,(hour(localTime) > 11)? " PM":" AM"); + strcat_P(out,PSTR(" ")); + strcat(out,(hour(localTime) > 11)? "PM":"AM"); } } diff --git a/wled00/pin_manager.cpp b/wled00/pin_manager.cpp index b9ec2d2b8..044dc6c92 100644 --- a/wled00/pin_manager.cpp +++ b/wled00/pin_manager.cpp @@ -109,7 +109,7 @@ bool PinManagerClass::allocateMultiplePins(const managed_pin_type * mptArray, by #ifdef WLED_DEBUG DEBUG_PRINT(F("PIN ALLOC: Invalid pin attempted to be allocated: GPIO ")); DEBUG_PRINT(gpio); - DEBUG_PRINT(F(" as ")); DEBUG_PRINT(mptArray[i].isOutput ? "output": "input"); + DEBUG_PRINT(F(" as ")); DEBUG_PRINT(mptArray[i].isOutput ? F("output"): F("input")); DEBUG_PRINTLN(F("")); #endif shouldFail = true; diff --git a/wled00/presets.cpp b/wled00/presets.cpp index 80335ad3b..4897251e7 100644 --- a/wled00/presets.cpp +++ b/wled00/presets.cpp @@ -16,13 +16,14 @@ static char quickLoad[9]; static char saveName[33]; static bool includeBri = true, segBounds = true, selectedOnly = false, playlistSave = false;; -static const char *getFileName(bool persist = true) { - return persist ? "/presets.json" : "/tmp.json"; +static const char presets_json[] PROGMEM = "/presets.json"; +static const char tmp_json[] PROGMEM = "/tmp.json"; +const char *getPresetsFileName(bool persistent) { + return persistent ? presets_json : tmp_json; } static void doSaveState() { bool persist = (presetToSave < 251); - const char *filename = getFileName(persist); unsigned long start = millis(); while (strip.isUpdating() && millis()-start < (2*FRAMETIME_FIXED)+1) yield(); // wait 2 frames @@ -63,11 +64,11 @@ static void doSaveState() { if (tmpRAMbuffer!=nullptr) { serializeJson(*fileDoc, tmpRAMbuffer, len); } else { - writeObjectToFileUsingId(filename, presetToSave, fileDoc); + writeObjectToFileUsingId(FPSTR(getPresetsFileName(persist)), presetToSave, fileDoc); } } else #endif - writeObjectToFileUsingId(filename, presetToSave, fileDoc); + writeObjectToFileUsingId(FPSTR(getPresetsFileName(persist)), presetToSave, fileDoc); if (persist) presetsModifiedTime = toki.second(); //unix time releaseJSONBufferLock(); @@ -85,8 +86,7 @@ bool getPresetName(byte index, String& name) { if (!requestJSONBufferLock(19)) return false; bool presetExists = false; - if (readObjectFromFileUsingId(getFileName(), index, pDoc)) - { + if (readObjectFromFileUsingId(FPSTR(getPresetsFileName()), index, pDoc)) { JsonObject fdo = pDoc->as(); if (fdo["n"]) { name = (const char*)(fdo["n"]); @@ -99,12 +99,12 @@ bool getPresetName(byte index, String& name) void initPresetsFile() { - if (WLED_FS.exists(getFileName())) return; + if (WLED_FS.exists(FPSTR(getPresetsFileName()))) return; StaticJsonDocument<64> doc; JsonObject sObj = doc.to(); sObj.createNestedObject("0"); - File f = WLED_FS.open(getFileName(), "w"); + File f = WLED_FS.open(FPSTR(getPresetsFileName()), "w"); if (!f) { errorFlag = ERR_FS_GENERAL; return; @@ -147,7 +147,6 @@ void handlePresets() uint8_t tmpMode = callModeToApply; JsonObject fdo; - const char *filename = getFileName(tmpPreset < 255); // allocate buffer if (!requestJSONBufferLock(9)) return; // will also assign fileDoc @@ -165,7 +164,7 @@ void handlePresets() } else #endif { - errorFlag = readObjectFromFileUsingId(filename, tmpPreset, fileDoc) ? ERR_NONE : ERR_FS_PLOAD; + errorFlag = readObjectFromFileUsingId(FPSTR(getPresetsFileName(tmpPreset < 255)), tmpPreset, fileDoc) ? ERR_NONE : ERR_FS_PLOAD; } fdo = fileDoc->as(); @@ -234,7 +233,7 @@ void savePreset(byte index, const char* pname, JsonObject sObj) sObj.remove(F("psave")); if (sObj["n"].isNull()) sObj["n"] = saveName; initPresetsFile(); // just in case if someone deleted presets.json using /edit - writeObjectToFileUsingId(getFileName(index<255), index, fileDoc); + writeObjectToFileUsingId(FPSTR(getPresetsFileName()), index, fileDoc); presetsModifiedTime = toki.second(); //unix time updateFSInfo(); } else { @@ -248,7 +247,7 @@ void savePreset(byte index, const char* pname, JsonObject sObj) void deletePreset(byte index) { StaticJsonDocument<24> empty; - writeObjectToFileUsingId(getFileName(), index, &empty); + writeObjectToFileUsingId(FPSTR(getPresetsFileName()), index, &empty); presetsModifiedTime = toki.second(); //unix time updateFSInfo(); } \ No newline at end of file diff --git a/wled00/wled.cpp b/wled00/wled.cpp index 3c5669215..fc1b9f5ce 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -328,7 +328,7 @@ void WLED::setup() DEBUG_PRINTLN(); DEBUG_PRINT(F("---WLED ")); DEBUG_PRINT(versionString); - DEBUG_PRINT(" "); + DEBUG_PRINT(F(" ")); DEBUG_PRINT(VERSION); DEBUG_PRINTLN(F(" INIT---")); #ifdef ARDUINO_ARCH_ESP32 diff --git a/wled00/wled.h b/wled00/wled.h index 571d4f54b..2c619a9fd 100755 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -8,7 +8,7 @@ */ // version code in format yymmddb (b = daily build) -#define VERSION 2402170 +#define VERSION 2402250 //uncomment this if you have a "my_config.h" file you'd like to use //#define WLED_USE_MY_CONFIG diff --git a/wled00/wled_eeprom.cpp b/wled00/wled_eeprom.cpp index 89e5d65c4..4f2c14d47 100755 --- a/wled00/wled_eeprom.cpp +++ b/wled00/wled_eeprom.cpp @@ -365,7 +365,7 @@ void applyMacro(byte index) { // De-EEPROM routine, upgrade from previous versions to v0.11 void deEEP() { - if (WLED_FS.exists("/presets.json")) return; + if (WLED_FS.exists(FPSTR(getPresetsFileName()))) return; DEBUG_PRINTLN(F("Preset file not found, attempting to load from EEPROM")); DEBUGFS_PRINTLN(F("Allocating saving buffer for dEEP")); @@ -442,7 +442,7 @@ void deEEP() { EEPROM.end(); - File f = WLED_FS.open("/presets.json", "w"); + File f = WLED_FS.open(FPSTR(getPresetsFileName()), "w"); if (!f) { errorFlag = ERR_FS_GENERAL; releaseJSONBufferLock(); diff --git a/wled00/wled_server.cpp b/wled00/wled_server.cpp index 9fdaa20b5..a1ba28159 100644 --- a/wled00/wled_server.cpp +++ b/wled00/wled_server.cpp @@ -170,7 +170,7 @@ static void handleUpload(AsyncWebServerRequest *request, const String& filename, request->_tempFile = WLED_FS.open(finalname, "w"); DEBUG_PRINT(F("Uploading ")); DEBUG_PRINTLN(finalname); - if (finalname.equals(F("/presets.json"))) presetsModifiedTime = toki.second(); + if (finalname.equals(FPSTR(getPresetsFileName()))) presetsModifiedTime = toki.second(); } if (len) { request->_tempFile.write(data,len); @@ -249,17 +249,19 @@ void initServer() }); // "/settings/settings.js&p=x" request also handled by serveSettings() - - server.on(SET_F("/style.css"), HTTP_GET, [](AsyncWebServerRequest *request) { - handleStaticContent(request, F("/style.css"), 200, FPSTR(s_css), PAGE_settingsCss, PAGE_settingsCss_length); + static const char _style_css[] PROGMEM = "/style.css"; + server.on(_style_css, HTTP_GET, [](AsyncWebServerRequest *request) { + handleStaticContent(request, FPSTR(_style_css), 200, FPSTR(s_css), PAGE_settingsCss, PAGE_settingsCss_length); }); - server.on(SET_F("/favicon.ico"), HTTP_GET, [](AsyncWebServerRequest *request) { - handleStaticContent(request, F("/favicon.ico"), 200, F("image/x-icon"), favicon, favicon_length, false); + static const char _favicon_ico[] PROGMEM = "/favicon.ico"; + server.on(_favicon_ico, HTTP_GET, [](AsyncWebServerRequest *request) { + handleStaticContent(request, FPSTR(_favicon_ico), 200, F("image/x-icon"), favicon, favicon_length, false); }); - server.on(SET_F("/skin.css"), HTTP_GET, [](AsyncWebServerRequest *request) { - if (handleFileRead(request, F("/skin.css"))) return; + static const char _skin_css[] PROGMEM = "/skin.css"; + server.on(_skin_css, HTTP_GET, [](AsyncWebServerRequest *request) { + if (handleFileRead(request, FPSTR(_skin_css))) return; AsyncWebServerResponse *response = request->beginResponse(200, FPSTR(s_css)); request->send(response); }); @@ -363,15 +365,17 @@ void initServer() createEditHandler(correctPIN); #ifndef WLED_DISABLE_OTA + static const char _update[] PROGMEM = "/update"; + //init ota page - server.on(SET_F("/update"), HTTP_GET, [](AsyncWebServerRequest *request){ + server.on(_update, HTTP_GET, [](AsyncWebServerRequest *request){ if (otaLock) { serveMessage(request, 401, FPSTR(s_accessdenied), FPSTR(s_unlock_ota), 254); } else serveSettings(request); // checks for "upd" in URL and handles PIN }); - server.on(SET_F("/update"), HTTP_POST, [](AsyncWebServerRequest *request){ + server.on(_update, HTTP_POST, [](AsyncWebServerRequest *request){ if (!correctPIN) { serveSettings(request, true); // handle PIN page POST request return; @@ -417,7 +421,7 @@ void initServer() } }); #else - server.on(SET_F("/update"), HTTP_GET, [](AsyncWebServerRequest *request){ + server.on(_update, HTTP_GET, [](AsyncWebServerRequest *request){ serveMessage(request, 501, FPSTR(s_notimplemented), F("OTA updating is disabled in this build."), 254); }); #endif @@ -443,19 +447,22 @@ void initServer() }); #ifdef WLED_ENABLE_PIXART - server.on(SET_F("/pixart.htm"), HTTP_GET, [](AsyncWebServerRequest *request) { - handleStaticContent(request, F("/pixart.htm"), 200, FPSTR(s_html), PAGE_pixart, PAGE_pixart_L); + static const char _pixart_htm[] PROGMEM = "/pixart.htm"; + server.on(_pixart_htm, HTTP_GET, [](AsyncWebServerRequest *request) { + handleStaticContent(request, FPSTR(_pixart_htm), 200, FPSTR(s_html), PAGE_pixart, PAGE_pixart_L); }); #endif #ifndef WLED_DISABLE_PXMAGIC - server.on(SET_F("/pxmagic.htm"), HTTP_GET, [](AsyncWebServerRequest *request) { - handleStaticContent(request, F("/pxmagic.htm"), 200, FPSTR(s_html), PAGE_pxmagic, PAGE_pxmagic_L); + static const char _pxmagic_htm[] PROGMEM = "/pxmagic.htm"; + server.on(_pxmagic_htm, HTTP_GET, [](AsyncWebServerRequest *request) { + handleStaticContent(request, FPSTR(_pxmagic_htm), 200, FPSTR(s_html), PAGE_pxmagic, PAGE_pxmagic_L); }); #endif - server.on(SET_F("/cpal.htm"), HTTP_GET, [](AsyncWebServerRequest *request) { - handleStaticContent(request, F("/cpal.htm"), 200, FPSTR(s_html), PAGE_cpal, PAGE_cpal_L); + static const char _cpal_htm[] PROGMEM = "/cpal.htm"; + server.on(_cpal_htm, HTTP_GET, [](AsyncWebServerRequest *request) { + handleStaticContent(request, FPSTR(_cpal_htm), 200, FPSTR(s_html), PAGE_cpal, PAGE_cpal_L); }); #ifdef WLED_ENABLE_WEBSOCKETS