Multiple fixes

- compile time button configuration #3792
- remove IR config if not compiled
- additional string optimisations
This commit is contained in:
Blaz Kristan 2024-03-05 16:27:28 +01:00
parent a6d58ee360
commit da6d64e581
11 changed files with 97 additions and 68 deletions

View File

@ -286,13 +286,22 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
// new install/missing configuration (button 0 has defaults)
if (fromFS) {
// relies upon only being called once with fromFS == true, which is currently true.
uint8_t s = 0;
if (pinManager.allocatePin(btnPin[0], false, PinOwner::Button)) { // initialized to #define value BTNPIN, or zero if not defined(!)
++s; // do not clear default button if allocated successfully
}
for (; s<WLED_MAX_BUTTONS; s++) {
btnPin[s] = -1;
buttonType[s] = BTN_TYPE_NONE;
for (size_t s = 0; s < WLED_MAX_BUTTONS; s++) {
if (buttonType[s] == BTN_TYPE_NONE || btnPin[s] < 0 || !pinManager.allocatePin(btnPin[s], false, PinOwner::Button)) {
btnPin[s] = -1;
buttonType[s] = BTN_TYPE_NONE;
}
if (btnPin[s] >= 0) {
if (disablePullUp) {
pinMode(btnPin[s], INPUT);
} else {
#ifdef ESP32
pinMode(btnPin[s], buttonType[s]==BTN_TYPE_PUSH_ACT_HIGH ? INPUT_PULLDOWN : INPUT_PULLUP);
#else
pinMode(btnPin[s], INPUT_PULLUP);
#endif
}
}
macroButton[s] = 0;
macroLongPress[s] = 0;
macroDoublePress[s] = 0;
@ -302,6 +311,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
CJSON(touchThreshold,btn_obj[F("tt")]);
CJSON(buttonPublishMqtt,btn_obj["mqtt"]);
#ifndef WLED_DISABLE_INFRARED
int hw_ir_pin = hw["ir"]["pin"] | -2; // 4
if (hw_ir_pin > -2) {
pinManager.deallocatePin(irPin, PinOwner::IR);
@ -312,6 +322,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
}
}
CJSON(irEnabled, hw["ir"]["type"]);
#endif
CJSON(irApplyToAllSelected, hw["ir"]["sel"]);
JsonObject relay = hw[F("relay")];
@ -440,7 +451,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
if (if_sync_send[F("twice")]) udpNumRetries = 1; // import setting from 0.13 and earlier
CJSON(udpNumRetries, if_sync_send["ret"]);
JsonObject if_nodes = interfaces[F("nodes")];
JsonObject if_nodes = interfaces["nodes"];
CJSON(nodeListEnabled, if_nodes[F("list")]);
CJSON(nodeBroadcastEnabled, if_nodes[F("bcast")]);
@ -629,7 +640,7 @@ void deserializeConfigFromFS() {
DEBUG_PRINTLN(F("Reading settings from /cfg.json..."));
success = readObjectFromFile("/cfg.json", nullptr, pDoc);
success = readObjectFromFile(PSTR("/cfg.json"), nullptr, pDoc);
if (!success) { // if file does not exist, optionally try reading from EEPROM and then save defaults to FS
releaseJSONBufferLock();
#ifdef WLED_ADD_EEPROM_SUPPORT
@ -835,8 +846,10 @@ void serializeConfig() {
hw_btn["mqtt"] = buttonPublishMqtt;
JsonObject hw_ir = hw.createNestedObject("ir");
#ifndef WLED_DISABLE_INFRARED
hw_ir["pin"] = irPin;
hw_ir["type"] = irEnabled; // the byte 'irEnabled' does contain the IR-Remote Type ( 0=disabled )
#endif
hw_ir["sel"] = irApplyToAllSelected;
JsonObject hw_relay = hw.createNestedObject(F("relay"));
@ -913,7 +926,7 @@ void serializeConfig() {
if_sync_send["grp"] = syncGroups;
if_sync_send["ret"] = udpNumRetries;
JsonObject if_nodes = interfaces.createNestedObject(F("nodes"));
JsonObject if_nodes = interfaces.createNestedObject("nodes");
if_nodes[F("list")] = nodeListEnabled;
if_nodes[F("bcast")] = nodeBroadcastEnabled;
@ -1149,7 +1162,7 @@ void serializeConfigSec() {
ota[F("lock-wifi")] = wifiLock;
ota[F("aota")] = aOtaEnabled;
File f = WLED_FS.open("/wsec.json", "w");
File f = WLED_FS.open(SET_F("/wsec.json"), "w");
if (f) serializeJson(root, f);
f.close();
releaseJSONBufferLock();

View File

@ -93,6 +93,11 @@
#else
#define WLED_MAX_BUTTONS 4
#endif
#else
#if WLED_MAX_BUTTONS < 2
#undef WLED_MAX_BUTTONS
#define WLED_MAX_BUTTONS 2
#endif
#endif
#ifdef ESP8266

View File

@ -434,6 +434,7 @@ void handleSerial();
void updateBaudRate(uint32_t rate);
//wled_server.cpp
String getFileContentType(String &filename);
void createEditHandler(bool enable);
void initServer();
void serveMessage(AsyncWebServerRequest* request, uint16_t code, const String& headl, const String& subl="", byte optionT=255);

View File

@ -375,26 +375,6 @@ void updateFSInfo() {
#endif
}
//Un-comment any file types you need
static String getContentType(AsyncWebServerRequest* request, String filename){
if(request->hasArg(F("download"))) return SET_F("application/octet-stream");
else if(filename.endsWith(F(".htm"))) return SET_F("text/html");
else if(filename.endsWith(F(".html"))) return SET_F("text/html");
else if(filename.endsWith(F(".css"))) return SET_F("text/css");
else if(filename.endsWith(F(".js"))) return SET_F("application/javascript");
else if(filename.endsWith(F(".json"))) return SET_F("application/json");
else if(filename.endsWith(F(".png"))) return SET_F("image/png");
else if(filename.endsWith(F(".gif"))) return SET_F("image/gif");
else if(filename.endsWith(F(".jpg"))) return SET_F("image/jpeg");
else if(filename.endsWith(F(".ico"))) return SET_F("image/x-icon");
// else if(filename.endsWith(F(".xml"))) return SET_F("text/xml");
// else if(filename.endsWith(F(".pdf"))) return SET_F("application/x-pdf");
// else if(filename.endsWith(F(".zip"))) return SET_F("application/x-zip");
// else if(filename.endsWith(F(".gz"))) return SET_F("application/x-gzip");
return "text/plain";
}
#if defined(BOARD_HAS_PSRAM) && defined(WLED_USE_PSRAM)
// caching presets in PSRAM may prevent occasional flashes seen when HomeAssitant polls WLED
// original idea by @akaricchi (https://github.com/Akaricchi)
@ -440,7 +420,8 @@ bool handleFileRead(AsyncWebServerRequest* request, String path){
DEBUG_PRINT(F("WS FileRead: ")); DEBUG_PRINTLN(path);
if(path.endsWith("/")) path += "index.htm";
if(path.indexOf(F("sec")) > -1) return false;
String contentType = getContentType(request, path);
String contentType = getFileContentType(path);
if(request->hasArg(F("download"))) contentType = F("application/octet-stream");
/*String pathWithGz = path + ".gz";
if(WLED_FS.exists(pathWithGz)){
request->send(WLED_FS, pathWithGz, contentType);

View File

@ -974,7 +974,7 @@ void serializeNetworks(JsonObject root)
void serializeNodes(JsonObject root)
{
JsonArray nodes = root.createNestedArray(F("nodes"));
JsonArray nodes = root.createNestedArray("nodes");
for (NodesMap::iterator it = Nodes.begin(); it != Nodes.end(); ++it)
{
@ -1049,25 +1049,25 @@ void serveJson(AsyncWebServerRequest* request)
{
byte subJson = 0;
const String& url = request->url();
if (url.indexOf("state") > 0) subJson = JSON_PATH_STATE;
else if (url.indexOf("info") > 0) subJson = JSON_PATH_INFO;
else if (url.indexOf("si") > 0) subJson = JSON_PATH_STATE_INFO;
else if (url.indexOf("nodes") > 0) subJson = JSON_PATH_NODES;
else if (url.indexOf("eff") > 0) subJson = JSON_PATH_EFFECTS;
else if (url.indexOf("palx") > 0) subJson = JSON_PATH_PALETTES;
else if (url.indexOf("fxda") > 0) subJson = JSON_PATH_FXDATA;
else if (url.indexOf("net") > 0) subJson = JSON_PATH_NETWORKS;
if (url.indexOf("state") > 0) subJson = JSON_PATH_STATE;
else if (url.indexOf("info") > 0) subJson = JSON_PATH_INFO;
else if (url.indexOf("si") > 0) subJson = JSON_PATH_STATE_INFO;
else if (url.indexOf(F("nodes")) > 0) subJson = JSON_PATH_NODES;
else if (url.indexOf(F("eff")) > 0) subJson = JSON_PATH_EFFECTS;
else if (url.indexOf(F("palx")) > 0) subJson = JSON_PATH_PALETTES;
else if (url.indexOf(F("fxda")) > 0) subJson = JSON_PATH_FXDATA;
else if (url.indexOf(F("net")) > 0) subJson = JSON_PATH_NETWORKS;
#ifdef WLED_ENABLE_JSONLIVE
else if (url.indexOf("live") > 0) {
else if (url.indexOf("live") > 0) {
serveLiveLeds(request);
return;
}
#endif
else if (url.indexOf("pal") > 0) {
request->send_P(200, F("application/json"), JSON_palette_names);
request->send_P(200, "application/json", JSON_palette_names); // contentType defined in AsyncJson-v6.h
return;
}
else if (url.indexOf("cfg") > 0 && handleFileRead(request, F("/cfg.json"))) {
else if (url.indexOf(F("cfg")) > 0 && handleFileRead(request, F("/cfg.json"))) {
return;
}
else if (url.length() > 6) { //not just /json
@ -1184,7 +1184,7 @@ bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient)
#endif
oappend("}");
if (request) {
request->send(200, F("application/json"), buffer);
request->send(200, "application/json", buffer); // contentType defined in AsyncJson-v6.h
}
#ifdef WLED_ENABLE_WEBSOCKETS
else {

View File

@ -127,7 +127,7 @@ static bool remoteJson(int button)
JsonObject fdo = pDoc->as<JsonObject>();
if (fdo.isNull()) {
// the received button does not exist
//if (!WLED_FS.exists("/remote.json")) errorFlag = ERR_FS_RMLOAD; //warn if file itself doesn't exist
//if (!WLED_FS.exists(SET_F("/remote.json"))) errorFlag = ERR_FS_RMLOAD; //warn if file itself doesn't exist
releaseJSONBufferLock();
return parsed;
}

View File

@ -102,9 +102,11 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
if (rlyPin>=0 && pinManager.isPinAllocated(rlyPin, PinOwner::Relay)) {
pinManager.deallocatePin(rlyPin, PinOwner::Relay);
}
#ifndef WLED_DISABLE_INFRARED
if (irPin>=0 && pinManager.isPinAllocated(irPin, PinOwner::IR)) {
pinManager.deallocatePin(irPin, PinOwner::IR);
}
#endif
for (uint8_t s=0; s<WLED_MAX_BUTTONS; s++) {
if (btnPin[s]>=0 && pinManager.isPinAllocated(btnPin[s], PinOwner::Button)) {
pinManager.deallocatePin(btnPin[s], PinOwner::Button);
@ -218,6 +220,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
BusManager::updateColorOrderMap(com);
// update other pins
#ifndef WLED_DISABLE_INFRARED
int hw_ir_pin = request->arg(F("IR")).toInt();
if (pinManager.allocatePin(hw_ir_pin,false, PinOwner::IR)) {
irPin = hw_ir_pin;
@ -225,6 +228,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
irPin = -1;
}
irEnabled = request->arg(F("IT")).toInt();
#endif
irApplyToAllSelected = !request->hasArg(F("MSO"));
int hw_rly_pin = request->arg(F("RL")).toInt();

View File

@ -539,13 +539,13 @@ um_data_t* simulateSound(uint8_t simulationId)
return um_data;
}
static const char s_ledmap_tmpl[] PROGMEM = "ledmap%d.json";
// enumerate all ledmapX.json files on FS and extract ledmap names if existing
void enumerateLedmaps() {
ledMaps = 1;
for (size_t i=1; i<WLED_MAX_LEDMAPS; i++) {
char fileName[33];
sprintf_P(fileName, PSTR("/ledmap%d.json"), i);
char fileName[33] = "/";
sprintf_P(fileName+1, s_ledmap_tmpl, i);
bool isFile = WLED_FS.exists(fileName);
#ifndef ESP8266
@ -574,7 +574,7 @@ void enumerateLedmaps() {
}
if (!ledmapNames[i-1]) {
char tmp[33];
snprintf_P(tmp, 32, PSTR("ledmap%d.json"), i);
snprintf_P(tmp, 32, s_ledmap_tmpl, i);
len = strlen(tmp);
ledmapNames[i-1] = new char[len+1];
if (ledmapNames[i-1]) strlcpy(ledmapNames[i-1], tmp, 33);

View File

@ -423,8 +423,6 @@ void WLED::setup()
DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(ESP.getFreeHeap());
for (uint8_t i=1; i<WLED_MAX_BUTTONS; i++) btnPin[i] = -1;
bool fsinit = false;
DEBUGFS_PRINTLN(F("Mount FS"));
#ifdef ARDUINO_ARCH_ESP32

View File

@ -271,9 +271,10 @@ WLED_GLOBAL char otaPass[33] _INIT(DEFAULT_OTA_PASS);
// Hardware and pin config
#ifndef BTNPIN
WLED_GLOBAL int8_t btnPin[WLED_MAX_BUTTONS] _INIT({0});
#else
WLED_GLOBAL int8_t btnPin[WLED_MAX_BUTTONS] _INIT({BTNPIN});
#define BTNPIN 0,-1
#endif
#ifndef BTNTYPE
#define BTNTYPE BTN_TYPE_PUSH,BTN_TYPE_NONE
#endif
#ifndef RLYPIN
WLED_GLOBAL int8_t rlyPin _INIT(-1);
@ -287,9 +288,10 @@ WLED_GLOBAL bool rlyMde _INIT(true);
WLED_GLOBAL bool rlyMde _INIT(RLYMDE);
#endif
#ifndef IRPIN
WLED_GLOBAL int8_t irPin _INIT(-1);
#else
WLED_GLOBAL int8_t irPin _INIT(IRPIN);
#define IRPIN -1
#endif
#ifndef IRTYPE
#define IRTYPE 0
#endif
#if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S2) || (defined(RX) && defined(TX))
@ -374,13 +376,11 @@ WLED_GLOBAL NodesMap Nodes;
WLED_GLOBAL bool nodeListEnabled _INIT(true);
WLED_GLOBAL bool nodeBroadcastEnabled _INIT(true);
WLED_GLOBAL byte buttonType[WLED_MAX_BUTTONS] _INIT({BTN_TYPE_PUSH});
#if defined(IRTYPE) && defined(IRPIN)
#ifndef WLED_DISABLE_INFRARED
WLED_GLOBAL int8_t irPin _INIT(IRPIN);
WLED_GLOBAL byte irEnabled _INIT(IRTYPE); // Infrared receiver
#else
WLED_GLOBAL byte irEnabled _INIT(0); // Infrared receiver disabled
#endif
WLED_GLOBAL bool irApplyToAllSelected _INIT(true); //apply IR to all selected segments
WLED_GLOBAL bool irApplyToAllSelected _INIT(true); //apply IR or ESP-NOW to all selected segments
WLED_GLOBAL uint16_t udpPort _INIT(21324); // WLED notifier default port
WLED_GLOBAL uint16_t udpPort2 _INIT(65506); // WLED notifier supplemental port
@ -570,6 +570,8 @@ WLED_GLOBAL byte briLast _INIT(128); // brightness before
WLED_GLOBAL byte whiteLast _INIT(128); // white channel before turned off. Used for toggle function in ir.cpp
// button
WLED_GLOBAL int8_t btnPin[WLED_MAX_BUTTONS] _INIT({BTNPIN});
WLED_GLOBAL byte buttonType[WLED_MAX_BUTTONS] _INIT({BTNTYPE});
WLED_GLOBAL bool buttonPublishMqtt _INIT(false);
WLED_GLOBAL bool buttonPressedBefore[WLED_MAX_BUTTONS] _INIT({false});
WLED_GLOBAL bool buttonLongPressed[WLED_MAX_BUTTONS] _INIT({false});

View File

@ -19,10 +19,35 @@ static const char s_unlock_cfg [] PROGMEM = "Please unlock settings using PIN co
static const char s_notimplemented[] PROGMEM = "Not implemented";
static const char s_accessdenied[] PROGMEM = "Access Denied";
static const char s_javascript[] PROGMEM = "application/javascript";
static const char s_json[] PROGMEM = "application/json";
static const char s_json[] = "application/json"; // AsyncJson-v6.h
static const char s_html[] PROGMEM = "text/html";
static const char s_plain[] PROGMEM = "text/plain";
static const char s_plain[] = "text/plain"; // Espalexa.h
static const char s_css[] PROGMEM = "text/css";
static const char s_png[] PROGMEM = "image/png";
static const char s_gif[] PROGMEM = "image/gif";
static const char s_jpg[] PROGMEM = "image/jpeg";
static const char s_ico[] PROGMEM = "image/x-icon";
//static const char s_xml[] PROGMEM = "text/xml";
//static const char s_pdf[] PROGMEM = "application/x-pdf";
//static const char s_zip[] PROGMEM = "application/x-zip";
//static const char s_gz[] PROGMEM = "application/x-gzip";
String getFileContentType(String &filename) {
if (filename.endsWith(F(".htm"))) return FPSTR(s_html);
else if (filename.endsWith(F(".html"))) return FPSTR(s_html);
else if (filename.endsWith(F(".css"))) return FPSTR(s_css);
else if (filename.endsWith(F(".js"))) return FPSTR(s_javascript);
else if (filename.endsWith(F(".json"))) return s_json;
else if (filename.endsWith(F(".png"))) return FPSTR(s_png);
else if (filename.endsWith(F(".gif"))) return FPSTR(s_gif);
else if (filename.endsWith(F(".jpg"))) return FPSTR(s_jpg);
else if (filename.endsWith(F(".ico"))) return FPSTR(s_ico);
// else if (filename.endsWith(F(".xml"))) return FPSTR(s_xml);
// else if (filename.endsWith(F(".pdf"))) return FPSTR(s_pdf);
// else if (filename.endsWith(F(".zip"))) return FPSTR(s_zip);
// else if (filename.endsWith(F(".gz"))) return FPSTR(s_gz);
return s_plain;
}
//Is this an IP?
static bool isIp(String str) {
@ -302,7 +327,7 @@ void initServer()
if (root.containsKey("pin")) checkSettingsPIN(root["pin"].as<const char*>());
const String& url = request->url();
isConfig = url.indexOf("cfg") > -1;
isConfig = url.indexOf(F("cfg")) > -1;
if (!isConfig) {
/*
#ifdef WLED_DEBUG
@ -331,7 +356,7 @@ void initServer()
doSerializeConfig = true; //serializeConfig(); //Save new settings to FS
}
}
request->send(200, FPSTR(s_json), F("{\"success\":true}"));
request->send(200, s_json, F("{\"success\":true}"));
}, JSON_BUFFER_SIZE);
server.addHandler(handler);
@ -505,7 +530,7 @@ void serveJsonError(AsyncWebServerRequest* request, uint16_t code, uint16_t erro
{
AsyncJsonResponse *response = new AsyncJsonResponse(64);
if (error < ERR_NOT_IMPL) response->addHeader(F("Retry-After"), F("1"));
response->setContentType(FPSTR(s_json));
response->setContentType(s_json);
response->setCode(code);
JsonObject obj = response->getRoot();
obj[F("error")] = error;