Fixed #define typo.
Made usermod Auto Save runtime configurable. String optimisations.
This commit is contained in:
parent
6404071a01
commit
6a096fbb27
@ -23,6 +23,9 @@
|
||||
#define USERMOD_DALLASTEMPERATURE_FIRST_MEASUREMENT_AT 20000
|
||||
#endif
|
||||
|
||||
// strings
|
||||
const char _um_Temperature[] PROGMEM = "Temperature";
|
||||
|
||||
class UsermodTemperature : public Usermod {
|
||||
|
||||
private:
|
||||
@ -148,10 +151,10 @@ class UsermodTemperature : public Usermod {
|
||||
// dont add temperature to info if we are disabled
|
||||
if (disabled) return;
|
||||
|
||||
JsonObject user = root[F("u")];
|
||||
if (user.isNull()) user = root.createNestedObject(F("u"));
|
||||
JsonObject user = root["u"];
|
||||
if (user.isNull()) user = root.createNestedObject("u");
|
||||
|
||||
JsonArray temp = user.createNestedArray(F("Temperature"));
|
||||
JsonArray temp = user.createNestedArray(FPSTR(_um_Temperature));
|
||||
|
||||
if (!getTemperatureComplete) {
|
||||
// if we haven't read the sensor yet, let the user know
|
||||
@ -191,7 +194,7 @@ class UsermodTemperature : public Usermod {
|
||||
void readFromJsonState(JsonObject &root) {
|
||||
if (!initDone) return; // prevent crash on boot applyPreset()
|
||||
if (root[F("Temperature_pin")] != nullptr) {
|
||||
int8_t pin = (int)root[F("Temperature_pin")];
|
||||
int8_t pin = min(39,max(0,(int)root[F("Temperature_pin")]));
|
||||
if (pin != temperaturePin) {
|
||||
// deallocate pin and release memory
|
||||
delete sensor;
|
||||
@ -226,9 +229,9 @@ class UsermodTemperature : public Usermod {
|
||||
*/
|
||||
void addToConfig(JsonObject &root) {
|
||||
// we add JSON object: {"Temperature": {"pin": 0, "degC": true}}
|
||||
JsonObject top = root.createNestedObject(F("Temperature")); // usermodname
|
||||
top["pin"] = temperaturePin; // usermodparam
|
||||
top[F("degC")] = degC; // usermodparam
|
||||
JsonObject top = root.createNestedObject(FPSTR(_um_Temperature)); // usermodname
|
||||
top["pin"] = temperaturePin; // usermodparam
|
||||
top["degC"] = degC; // usermodparam
|
||||
}
|
||||
|
||||
/**
|
||||
@ -236,12 +239,12 @@ class UsermodTemperature : public Usermod {
|
||||
*/
|
||||
void readFromConfig(JsonObject &root) {
|
||||
// we look for JSON object: {"Temperature": {"pin": 0, "degC": true}}
|
||||
JsonObject top = root[F("Temperature")];
|
||||
JsonObject top = root[FPSTR(_um_Temperature)];
|
||||
if (!top.isNull() && top["pin"] != nullptr) {
|
||||
temperaturePin = (int)top["pin"];
|
||||
degC = top[F("degC")] != nullptr ? top[F("degC")] : true;
|
||||
degC = top["degC"] != nullptr ? top["degC"] : true;
|
||||
} else {
|
||||
DEBUG_PRINTLN(F("No Temperature sensor config found. (Using defaults.)"));
|
||||
DEBUG_PRINTLN(F("No config found. (Using defaults.)"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ This file should be placed in the same directory as `platformio.ini`.
|
||||
### Define Your Options
|
||||
|
||||
* `USERMOD_AUTO_SAVE` - define this to have this the Auto Save usermod included wled00\usermods_list.cpp
|
||||
* `USERMOD_FOUR_LINE_DISLAY` - define this to have this the Four Line Display mod included wled00\usermods_list.cpp - also tells this usermod that the display is available (see the Four Line Display usermod `readme.md` for more details)
|
||||
* `USERMOD_FOUR_LINE_DISPLAY` - define this to have this the Four Line Display mod included wled00\usermods_list.cpp - also tells this usermod that the display is available (see the Four Line Display usermod `readme.md` for more details)
|
||||
* `AUTOSAVE_SETTLE_MS` - Minimum time to wave before auto saving, defaults to 10000 (10s)
|
||||
* `AUTOSAVE_PRESET_NUM` - Preset number to auto-save to, auto-load at startup from, defaults to 99
|
||||
|
||||
|
@ -29,21 +29,24 @@
|
||||
// ignore Default brightness and Apply N preset at boot when
|
||||
// the AutoSaveUsermod is installed.
|
||||
|
||||
//How long to wait after settings change to auto-save
|
||||
#ifndef AUTOSAVE_SETTLE_MS
|
||||
#define AUTOSAVE_SETTLE_MS 10*1000
|
||||
#endif
|
||||
|
||||
//Preset number to save to
|
||||
#ifndef AUTOSAVE_PRESET_NUM
|
||||
#define AUTOSAVE_PRESET_NUM 99
|
||||
#endif
|
||||
|
||||
// "Auto save MM-DD HH:MM:SS"
|
||||
// "~ MM-DD HH:MM:SS ~"
|
||||
#define PRESET_NAME_BUFFER_SIZE 25
|
||||
|
||||
// strings
|
||||
const char _um_AutoSave[] PROGMEM = "Autosave";
|
||||
const char _autoSaveAfterSec[] PROGMEM = "autoSaveAfterSec";
|
||||
const char _autoSavePreset[] PROGMEM = "autoSavePreset";
|
||||
const char _autoSaveApplyOnBoot[] PROGMEM = "autoSaveApplyOnBoot";
|
||||
|
||||
class AutoSaveUsermod : public Usermod {
|
||||
|
||||
private:
|
||||
|
||||
unsigned long autoSaveAfterSec = 15; // 15s by default
|
||||
uint8_t autoSavePreset = 250; // last possible preset
|
||||
bool initDone = false;
|
||||
bool applyAutoSaveOnBoot = false;
|
||||
|
||||
// If we've detected the need to auto save, this will
|
||||
// be non zero.
|
||||
unsigned long autoSaveAfter = 0;
|
||||
@ -58,19 +61,39 @@ class AutoSaveUsermod : public Usermod {
|
||||
uint8_t knownMode = 0;
|
||||
uint8_t knownPalette = 0;
|
||||
|
||||
#ifdef USERMOD_FOUR_LINE_DISLAY
|
||||
#ifdef USERMOD_FOUR_LINE_DISPLAY
|
||||
FourLineDisplayUsermod* display;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void inline saveSettings() {
|
||||
updateLocalTime();
|
||||
sprintf_P(presetNameBuffer,
|
||||
PSTR("~ %02d-%02d %02d:%02d:%02d ~"),
|
||||
month(localTime), day(localTime),
|
||||
hour(localTime), minute(localTime), second(localTime));
|
||||
savePreset(autoSavePreset, true, presetNameBuffer);
|
||||
}
|
||||
|
||||
void inline displayOverlay() {
|
||||
#ifdef USERMOD_FOUR_LINE_DISPLAY
|
||||
if (display != nullptr) {
|
||||
display->wakeDisplay();
|
||||
display->overlay("Settings", "Auto Saved", 1500);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// gets called once at boot. Do all initialization that doesn't depend on
|
||||
// network here
|
||||
void setup() {
|
||||
#ifdef USERMOD_FOUR_LINE_DISLAY
|
||||
// This Usermod has enhanced funcionality if
|
||||
// FourLineDisplayUsermod is available.
|
||||
display = (FourLineDisplayUsermod*) usermods.lookup(USERMOD_ID_FOUR_LINE_DISP);
|
||||
#endif
|
||||
#ifdef USERMOD_FOUR_LINE_DISPLAY
|
||||
// This Usermod has enhanced funcionality if
|
||||
// FourLineDisplayUsermod is available.
|
||||
display = (FourLineDisplayUsermod*) usermods.lookup(USERMOD_ID_FOUR_LINE_DISP);
|
||||
#endif
|
||||
initDone = true;
|
||||
}
|
||||
|
||||
// gets called every time WiFi is (re-)connected. Initialize own network
|
||||
@ -81,12 +104,14 @@ class AutoSaveUsermod : public Usermod {
|
||||
* Da loop.
|
||||
*/
|
||||
void loop() {
|
||||
if (!autoSaveAfterSec || !bri) return; // setting 0 as autosave seconds disables autosave as does 0 brightness
|
||||
|
||||
unsigned long now = millis();
|
||||
uint8_t currentMode = strip.getMode();
|
||||
uint8_t currentPalette = strip.getSegment(0).palette;
|
||||
if (firstLoop) {
|
||||
firstLoop = false;
|
||||
applyPreset(AUTOSAVE_PRESET_NUM);
|
||||
if (applyAutoSaveOnBoot) applyPreset(autoSavePreset);
|
||||
knownBrightness = bri;
|
||||
knownEffectSpeed = effectSpeed;
|
||||
knownEffectIntensity = effectIntensity;
|
||||
@ -95,7 +120,7 @@ class AutoSaveUsermod : public Usermod {
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned long wouldAutoSaveAfter = now + AUTOSAVE_SETTLE_MS;
|
||||
unsigned long wouldAutoSaveAfter = now + autoSaveAfterSec*1000;
|
||||
if (knownBrightness != bri) {
|
||||
knownBrightness = bri;
|
||||
autoSaveAfter = wouldAutoSaveAfter;
|
||||
@ -121,36 +146,41 @@ class AutoSaveUsermod : public Usermod {
|
||||
}
|
||||
}
|
||||
|
||||
void saveSettings() {
|
||||
updateLocalTime();
|
||||
sprintf(presetNameBuffer,
|
||||
"Auto save %02d-%02d %02d:%02d:%02d",
|
||||
month(localTime), day(localTime),
|
||||
hour(localTime), minute(localTime), second(localTime));
|
||||
savePreset(AUTOSAVE_PRESET_NUM, true, presetNameBuffer);
|
||||
}
|
||||
|
||||
void displayOverlay() {
|
||||
#ifdef USERMOD_FOUR_LINE_DISLAY
|
||||
if (display != nullptr) {
|
||||
display->wakeDisplay();
|
||||
display->overlay("Settings", "Auto Saved", 1500);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* addToJsonInfo() can be used to add custom entries to the /json/info part of the JSON API.
|
||||
* Creating an "u" object allows you to add custom key/value pairs to the Info section of the WLED web UI.
|
||||
* Below it is shown how this could be used for e.g. a light sensor
|
||||
*/
|
||||
//void addToJsonInfo(JsonObject& root) {
|
||||
//JsonObject user = root["u"];
|
||||
//if (user.isNull()) user = root.createNestedObject("u");
|
||||
//JsonArray data = user.createNestedArray(F("Autosave"));
|
||||
//data.add(F("Loaded."));
|
||||
//}
|
||||
|
||||
/*
|
||||
* addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object).
|
||||
* Values in the state object may be modified by connected clients
|
||||
*/
|
||||
void addToJsonState(JsonObject& root) {
|
||||
}
|
||||
//void addToJsonState(JsonObject& root) {
|
||||
//}
|
||||
|
||||
/*
|
||||
* readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object).
|
||||
* Values in the state object may be modified by connected clients
|
||||
*/
|
||||
void readFromJsonState(JsonObject& root) {
|
||||
if (!initDone) return; // prevent crash on boot applyPreset()
|
||||
|
||||
if (root[F("Autosave_autoSaveAfterSec")] != nullptr) {
|
||||
autoSaveAfterSec = min(60,max(0,(int)root[F("Autosave_autoSaveAfterSec")]));
|
||||
}
|
||||
if (root[F("Autosave_autoSavePreset")] != nullptr) {
|
||||
autoSavePreset = min(250,max(0,(int)root[F("Autosave_autoSavePreset")]));
|
||||
}
|
||||
if (root[F("Autosave_autoSaveApplyOnBoot")] != nullptr) {
|
||||
applyAutoSaveOnBoot = (bool)root[F("Autosave_autoSaveApplyOnBoot")];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -168,6 +198,11 @@ class AutoSaveUsermod : public Usermod {
|
||||
* I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
|
||||
*/
|
||||
void addToConfig(JsonObject& root) {
|
||||
// we add JSON object: {"Autosave": {"autoSaveAfterSec": 10, "autoSavePreset": 99}}
|
||||
JsonObject top = root.createNestedObject(FPSTR(_um_AutoSave)); // usermodname
|
||||
top[FPSTR(_autoSaveAfterSec)] = autoSaveAfterSec; // usermodparam
|
||||
top[FPSTR(_autoSavePreset)] = autoSavePreset; // usermodparam
|
||||
top[FPSTR(_autoSaveApplyOnBoot)] = applyAutoSaveOnBoot;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -179,7 +214,16 @@ class AutoSaveUsermod : public Usermod {
|
||||
* If you don't know what that is, don't fret. It most likely doesn't affect your use case :)
|
||||
*/
|
||||
void readFromConfig(JsonObject& root) {
|
||||
}
|
||||
// we look for JSON object: {"Autosave": {"autoSaveAfterSec": 10, "autoSavePreset": 99}}
|
||||
JsonObject top = root[FPSTR(_um_AutoSave)];
|
||||
if (!top.isNull() && top[FPSTR(_autoSaveAfterSec)] != nullptr) {
|
||||
autoSaveAfterSec = (int) top[FPSTR(_autoSaveAfterSec)];
|
||||
autoSavePreset = (int) top[FPSTR(_autoSavePreset)];
|
||||
applyAutoSaveOnBoot = (bool)top[FPSTR(_autoSaveApplyOnBoot)];
|
||||
} else {
|
||||
DEBUG_PRINTLN(F("No config found. (Using defaults.)"));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!).
|
||||
|
@ -19,7 +19,7 @@ This file should be placed in the same directory as `platformio.ini`.
|
||||
|
||||
### Define Your Options
|
||||
|
||||
* `USERMOD_FOUR_LINE_DISLAY` - define this to have this the Four Line Display mod included wled00\usermods_list.cpp - also tells Rotary Encoder usermod, if installed, that the display is available
|
||||
* `USERMOD_FOUR_LINE_DISPLAY` - define this to have this the Four Line Display mod included wled00\usermods_list.cpp - also tells Rotary Encoder usermod, if installed, that the display is available
|
||||
* `FLD_PIN_SCL` - The display SCL pin, defaults to 5
|
||||
* `FLD_PIN_SDA` - The display SDA pin, defaults to 4
|
||||
* `FLIP_MODE` - Set to 0 or 1
|
||||
|
@ -67,6 +67,15 @@ typedef enum {
|
||||
SH1106 // U8X8_SH1106_128X64_WINSTAR_HW_I2C
|
||||
} DisplayType;
|
||||
|
||||
// strings
|
||||
const char _um_4LineDisplay[] PROGMEM = "4LineDisplay";
|
||||
const char _4LD_contrast[] PROGMEM = "contrast";
|
||||
const char _4LD_refreshRate[] PROGMEM = "refreshRate";
|
||||
const char _4LD_screenTimeOut[] PROGMEM = "screenTimeOut";
|
||||
const char _4LD_flip[] PROGMEM = "flip";
|
||||
const char _4LD_sleepMode[] PROGMEM = "sleepMode";
|
||||
const char _4LD_clockMode[] PROGMEM = "clockMode";
|
||||
|
||||
class FourLineDisplayUsermod : public Usermod {
|
||||
|
||||
private:
|
||||
@ -140,8 +149,7 @@ class FourLineDisplayUsermod : public Usermod {
|
||||
setFlipMode(flip);
|
||||
setContrast(contrast); //Contrast setup will help to preserve OLED lifetime. In case OLED need to be brighter increase number up to 255
|
||||
setPowerSave(0);
|
||||
String loading = String(F("Loading..."));
|
||||
drawString(0, 0, loading.c_str());
|
||||
drawString(0, 0, "Loading...");
|
||||
initDone = true;
|
||||
}
|
||||
|
||||
@ -153,7 +161,7 @@ class FourLineDisplayUsermod : public Usermod {
|
||||
* Da loop.
|
||||
*/
|
||||
void loop() {
|
||||
if (millis() - lastUpdate < refreshRate) {
|
||||
if (millis() - lastUpdate < (clockMode?1000:refreshRate)) {
|
||||
return;
|
||||
}
|
||||
lastUpdate = millis();
|
||||
@ -602,12 +610,12 @@ class FourLineDisplayUsermod : public Usermod {
|
||||
* Creating an "u" object allows you to add custom key/value pairs to the Info section of the WLED web UI.
|
||||
* Below it is shown how this could be used for e.g. a light sensor
|
||||
*/
|
||||
void addToJsonInfo(JsonObject& root) {
|
||||
//void addToJsonInfo(JsonObject& root) {
|
||||
//JsonObject user = root["u"];
|
||||
//if (user.isNull()) user = root.createNestedObject("u");
|
||||
//JsonArray data = user.createNestedArray(F("4LineDisplay"));
|
||||
//data.add(F("Loaded."));
|
||||
}
|
||||
//}
|
||||
|
||||
/*
|
||||
* addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object).
|
||||
@ -623,41 +631,32 @@ class FourLineDisplayUsermod : public Usermod {
|
||||
void readFromJsonState(JsonObject& root) {
|
||||
if (!initDone) return; // prevent crash on boot applyPreset()
|
||||
DisplayType newType = type;
|
||||
uint8_t newScl = sclPin;
|
||||
uint8_t newSda = sdaPin;
|
||||
int8_t newScl = sclPin;
|
||||
int8_t newSda = sdaPin;
|
||||
|
||||
// just to reduce memory
|
||||
String str4LineDisplay_type = String(F("4LineDisplay_type"));
|
||||
String str4LineDisplay_pin = String(F("4LineDisplay_pin"));
|
||||
String str4LineDisplay_contrast = String(F("4LineDisplay_contrast"));
|
||||
String str4LineDisplay_refreshRate = String(F("4LineDisplay_refreshRate"));
|
||||
String str4LineDisplay_screenTimeOut = String(F("4LineDisplay_screenTimeOut"));
|
||||
String str4LineDisplay_flip = String(F("4LineDisplay_flip"));
|
||||
String str4LineDisplay_sleepMode = String(F("4LineDisplay_sleepMode"));
|
||||
String str4LineDisplay_clockMode = String(F("4LineDisplay_clockMode"));
|
||||
|
||||
if (root[str4LineDisplay_type] != nullptr) newType = (DisplayType)root[str4LineDisplay_type];
|
||||
if (root[str4LineDisplay_pin] != nullptr) {
|
||||
newScl = (int)root[str4LineDisplay_pin][0];
|
||||
newSda = (int)root[str4LineDisplay_pin][1];
|
||||
if (root[F("4LineDisplay_type")] != nullptr) newType = (DisplayType)root[F("4LineDisplay_type")];
|
||||
if (root[F("4LineDisplay_pin")] != nullptr) {
|
||||
newScl = min(39,max(0,(int)root[F("4LineDisplay_pin")][0]));
|
||||
newSda = min(39,max(0,(int)root[F("4LineDisplay_pin")][1]));
|
||||
if (newScl==newSda) newScl = newSda = -1;
|
||||
}
|
||||
if (root[str4LineDisplay_contrast] != nullptr) {
|
||||
contrast = (int)root[str4LineDisplay_contrast];
|
||||
if (root[F("4LineDisplay_contrast")] != nullptr) {
|
||||
contrast = min(255,max(1,(int)root[F("4LineDisplay_contrast")]));
|
||||
setContrast(contrast);
|
||||
}
|
||||
if (root[str4LineDisplay_refreshRate] != nullptr) refreshRate = (int)root[str4LineDisplay_refreshRate]*1000;
|
||||
if (root[str4LineDisplay_screenTimeOut] != nullptr) screenTimeout = (int)root[str4LineDisplay_screenTimeOut]*1000;
|
||||
if (root[str4LineDisplay_flip] != nullptr) {
|
||||
String str = root[str4LineDisplay_flip]; // checkbox -> off or on
|
||||
if (root[F("4LineDisplay_refreshRate")] != nullptr) refreshRate = min(60,max(1,(int)root[F("4LineDisplay_refreshRate")]))*1000;
|
||||
if (root[F("4LineDisplay_screenTimeOut")] != nullptr) screenTimeout = min(900,max(0,(int)root[F("4LineDisplay_screenTimeOut")]))*1000;
|
||||
if (root[F("4LineDisplay_flip")] != nullptr) {
|
||||
String str = root[F("4LineDisplay_flip")]; // checkbox -> off or on
|
||||
flip = (bool)(str!="off"); // off is guaranteed to be present
|
||||
setFlipMode(flip);
|
||||
}
|
||||
if (root[str4LineDisplay_sleepMode] != nullptr) {
|
||||
String str = root[str4LineDisplay_sleepMode]; // checkbox -> off or on
|
||||
if (root[F("4LineDisplay_sleepMode")] != nullptr) {
|
||||
String str = root[F("4LineDisplay_sleepMode")]; // checkbox -> off or on
|
||||
sleepMode = (bool)(str!="off"); // off is guaranteed to be present
|
||||
}
|
||||
if (root[str4LineDisplay_clockMode] != nullptr) {
|
||||
String str = root[str4LineDisplay_clockMode]; // checkbox -> off or on
|
||||
if (root[F("4LineDisplay_clockMode")] != nullptr) {
|
||||
String str = root[F("4LineDisplay_clockMode")]; // checkbox -> off or on
|
||||
clockMode = (bool)(str!="off"); // off is guaranteed to be present
|
||||
setLineThreeType(clockMode ? FLD_LINE_3_MODE : FLD_LINE_3_BRIGHTNESS);
|
||||
}
|
||||
@ -669,7 +668,11 @@ class FourLineDisplayUsermod : public Usermod {
|
||||
pinManager.deallocatePin(sdaPin);
|
||||
sclPin = newScl;
|
||||
sdaPin = newSda;
|
||||
type = newType;
|
||||
if (newScl<0 || newSda<0) {
|
||||
type = NONE;
|
||||
return;
|
||||
} else
|
||||
type = newType;
|
||||
lineHeight = type==SH1106 ? 2 : 1;
|
||||
setup();
|
||||
}
|
||||
@ -691,17 +694,17 @@ class FourLineDisplayUsermod : public Usermod {
|
||||
* I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
|
||||
*/
|
||||
void addToConfig(JsonObject& root) {
|
||||
JsonObject top = root.createNestedObject(F("4LineDisplay"));
|
||||
JsonObject top = root.createNestedObject(FPSTR(_um_4LineDisplay));
|
||||
JsonArray i2c_pin = top.createNestedArray("pin");
|
||||
i2c_pin.add(sclPin);
|
||||
i2c_pin.add(sdaPin);
|
||||
top["type"] = type;
|
||||
top[F("flip")] = (bool) flip;
|
||||
top[F("contrast")] = contrast;
|
||||
top[F("refreshRate")] = refreshRate/1000;
|
||||
top[F("screenTimeOut")] = screenTimeout/1000;
|
||||
top[F("sleepMode")] = (bool) sleepMode;
|
||||
top[F("clockMode")] = (bool) clockMode;
|
||||
top[FPSTR(_4LD_flip)] = (bool) flip;
|
||||
top[FPSTR(_4LD_contrast)] = contrast;
|
||||
top[FPSTR(_4LD_refreshRate)] = refreshRate/1000;
|
||||
top[FPSTR(_4LD_screenTimeOut)] = screenTimeout/1000;
|
||||
top[FPSTR(_4LD_sleepMode)] = (bool) sleepMode;
|
||||
top[FPSTR(_4LD_clockMode)] = (bool) clockMode;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -713,18 +716,18 @@ class FourLineDisplayUsermod : public Usermod {
|
||||
* If you don't know what that is, don't fret. It most likely doesn't affect your use case :)
|
||||
*/
|
||||
void readFromConfig(JsonObject& root) {
|
||||
JsonObject top = root[F("4LineDisplay")];
|
||||
JsonObject top = root[FPSTR(_um_4LineDisplay)];
|
||||
if (!top.isNull() && top["pin"] != nullptr) {
|
||||
sclPin = top["pin"][0] | FLD_PIN_SCL;
|
||||
sdaPin = top["pin"][1] | FLD_PIN_SDA;
|
||||
type = top["type"] | SSD1306;
|
||||
lineHeight = type==SH1106 ? 2 : 1;
|
||||
flip = top[F("flip")] | false ;
|
||||
contrast = top[F("contrast")] | 10;
|
||||
refreshRate = int(top[F("refreshRate")])*1000 | USER_LOOP_REFRESH_RATE_MS;
|
||||
screenTimeout = int(top[F("screenTimeOut")])*1000 | SCREEN_TIMEOUT_MS;
|
||||
sleepMode = top[F("sleepMode")] | true;
|
||||
clockMode = top[F("clockMode")] | false;
|
||||
sclPin = top["pin"][0];
|
||||
sdaPin = top["pin"][1];
|
||||
type = top["type"];
|
||||
lineHeight = type==SH1106 ? 2 : 1;
|
||||
flip = top[FPSTR(_4LD_flip)];
|
||||
contrast = top[FPSTR(_4LD_contrast)];
|
||||
refreshRate = int(top[FPSTR(_4LD_refreshRate)])*1000;
|
||||
screenTimeout = int(top[FPSTR(_4LD_screenTimeOut)])*1000;
|
||||
sleepMode = top[FPSTR(_4LD_sleepMode)];
|
||||
clockMode = top[FPSTR(_4LD_clockMode)];
|
||||
} else {
|
||||
DEBUG_PRINTLN(F("No config found. (Using defaults.)"));
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ build_unflags = ${common.build_unflags}
|
||||
build_flags =
|
||||
${common.build_flags_esp32}
|
||||
-D USERMOD_MODE_SORT
|
||||
-D USERMOD_FOUR_LINE_DISLAY -D FLD_PIN_SCL=22 -D FLD_PIN_SDA=21
|
||||
-D USERMOD_FOUR_LINE_DISPLAY -D FLD_PIN_SCL=22 -D FLD_PIN_SDA=21
|
||||
-D USERMOD_ROTARY_ENCODER_UI -D ENCODER_DT_PIN=18 -D ENCODER_CLK_PIN=5 -D ENCODER_SW_PIN=19
|
||||
-D USERMOD_AUTO_SAVE -D AUTOSAVE_PRESET_NUM=1
|
||||
-D LEDPIN=16 -D BTNPIN=13
|
||||
@ -28,7 +28,7 @@ build_unflags = ${common.build_unflags}
|
||||
build_flags =
|
||||
${common.build_flags_esp8266}
|
||||
-D USERMOD_MODE_SORT
|
||||
-D USERMOD_FOUR_LINE_DISLAY -D FLD_PIN_SCL=5 -D FLD_PIN_SDA=4
|
||||
-D USERMOD_FOUR_LINE_DISPLAY -D FLD_PIN_SCL=5 -D FLD_PIN_SDA=4
|
||||
-D USERMOD_ROTARY_ENCODER_UI -D ENCODER_DT_PIN=12 -D ENCODER_CLK_PIN=14 -D ENCODER_SW_PIN=13
|
||||
-D USERMOD_AUTO_SAVE -D AUTOSAVE_PRESET_NUM=1
|
||||
-D LEDPIN=3 -D BTNPIN=0
|
||||
|
@ -16,7 +16,7 @@ This file should be placed in the same directory as `platformio.ini`.
|
||||
### Define Your Options
|
||||
|
||||
* `USERMOD_ROTARY_ENCODER_UI` - define this to have this user mod included wled00\usermods_list.cpp
|
||||
* `USERMOD_FOUR_LINE_DISLAY` - define this to have this the Four Line Display mod included wled00\usermods_list.cpp - also tells this usermod that the display is available (see the Four Line Display usermod `readme.md` for more details)
|
||||
* `USERMOD_FOUR_LINE_DISPLAY` - define this to have this the Four Line Display mod included wled00\usermods_list.cpp - also tells this usermod that the display is available (see the Four Line Display usermod `readme.md` for more details)
|
||||
* `ENCODER_DT_PIN` - The encoders DT pin, defaults to 12
|
||||
* `ENCODER_CLK_PIN` - The encoders CLK pin, defaults to 14
|
||||
* `ENCODER_SW_PIN` - The encoders SW pin, defaults to 13
|
||||
|
@ -37,7 +37,7 @@
|
||||
#define ENCODER_SW_PIN 13
|
||||
#endif
|
||||
|
||||
#ifndef USERMOD_FOUR_LINE_DISLAY
|
||||
#ifndef USERMOD_FOUR_LINE_DISPLAY
|
||||
// These constants won't be defined if we aren't using FourLineDisplay.
|
||||
#define FLD_LINE_3_BRIGHTNESS 0
|
||||
#define FLD_LINE_3_EFFECT_SPEED 0
|
||||
@ -62,7 +62,7 @@ private:
|
||||
unsigned char button_state = HIGH;
|
||||
unsigned char prev_button_state = HIGH;
|
||||
|
||||
#ifdef USERMOD_FOUR_LINE_DISLAY
|
||||
#ifdef USERMOD_FOUR_LINE_DISPLAY
|
||||
FourLineDisplayUsermod *display;
|
||||
#else
|
||||
void* display = nullptr;
|
||||
@ -96,7 +96,7 @@ public:
|
||||
modes_alpha_indexes = modeSortUsermod->getModesAlphaIndexes();
|
||||
palettes_alpha_indexes = modeSortUsermod->getPalettesAlphaIndexes();
|
||||
|
||||
#ifdef USERMOD_FOUR_LINE_DISLAY
|
||||
#ifdef USERMOD_FOUR_LINE_DISPLAY
|
||||
// This Usermod uses FourLineDisplayUsermod for the best experience.
|
||||
// But it's optional. But you want it.
|
||||
display = (FourLineDisplayUsermod*) usermods.lookup(USERMOD_ID_FOUR_LINE_DISP);
|
||||
@ -248,7 +248,7 @@ public:
|
||||
}
|
||||
|
||||
boolean changeState(const char *stateName, byte lineThreeMode, byte markedLine) {
|
||||
#ifdef USERMOD_FOUR_LINE_DISLAY
|
||||
#ifdef USERMOD_FOUR_LINE_DISPLAY
|
||||
if (display != nullptr) {
|
||||
if (display->wakeDisplay()) {
|
||||
// Throw away wake up input
|
||||
@ -272,7 +272,7 @@ public:
|
||||
}
|
||||
|
||||
void changeBrightness(bool increase) {
|
||||
#ifdef USERMOD_FOUR_LINE_DISLAY
|
||||
#ifdef USERMOD_FOUR_LINE_DISPLAY
|
||||
if (display && display->wakeDisplay()) {
|
||||
// Throw away wake up input
|
||||
return;
|
||||
@ -288,7 +288,7 @@ public:
|
||||
}
|
||||
|
||||
void changeEffect(bool increase) {
|
||||
#ifdef USERMOD_FOUR_LINE_DISLAY
|
||||
#ifdef USERMOD_FOUR_LINE_DISPLAY
|
||||
if (display && display->wakeDisplay()) {
|
||||
// Throw away wake up input
|
||||
return;
|
||||
@ -305,7 +305,7 @@ public:
|
||||
}
|
||||
|
||||
void changeEffectSpeed(bool increase) {
|
||||
#ifdef USERMOD_FOUR_LINE_DISLAY
|
||||
#ifdef USERMOD_FOUR_LINE_DISPLAY
|
||||
if (display && display->wakeDisplay()) {
|
||||
// Throw away wake up input
|
||||
return;
|
||||
@ -321,7 +321,7 @@ public:
|
||||
}
|
||||
|
||||
void changeEffectIntensity(bool increase) {
|
||||
#ifdef USERMOD_FOUR_LINE_DISLAY
|
||||
#ifdef USERMOD_FOUR_LINE_DISPLAY
|
||||
if (display && display->wakeDisplay()) {
|
||||
// Throw away wake up input
|
||||
return;
|
||||
@ -337,7 +337,7 @@ public:
|
||||
}
|
||||
|
||||
void changePalette(bool increase) {
|
||||
#ifdef USERMOD_FOUR_LINE_DISLAY
|
||||
#ifdef USERMOD_FOUR_LINE_DISPLAY
|
||||
if (display && display->wakeDisplay()) {
|
||||
// Throw away wake up input
|
||||
return;
|
||||
|
@ -194,13 +194,13 @@ void deserializeConfig() {
|
||||
|
||||
JsonObject light_tr = light[F("tr")];
|
||||
CJSON(fadeTransition, light_tr[F("mode")]);
|
||||
int tdd = light_tr[F("dur")] | -1;
|
||||
int tdd = light_tr["dur"] | -1;
|
||||
if (tdd >= 0) transitionDelayDefault = tdd * 100;
|
||||
CJSON(strip.paletteFade, light_tr[F("pal")]);
|
||||
CJSON(strip.paletteFade, light_tr["pal"]);
|
||||
|
||||
JsonObject light_nl = light["nl"];
|
||||
CJSON(nightlightMode, light_nl[F("mode")]);
|
||||
CJSON(nightlightDelayMinsDefault, light_nl[F("dur")]);
|
||||
CJSON(nightlightDelayMinsDefault, light_nl["dur"]);
|
||||
nightlightDelayMins = nightlightDelayMinsDefault;
|
||||
|
||||
CJSON(nightlightTargetBri, light_nl[F("tbri")]);
|
||||
@ -217,7 +217,7 @@ void deserializeConfig() {
|
||||
CJSON(presetCycleMin, def_cy[F("range")][0]);
|
||||
CJSON(presetCycleMax, def_cy[F("range")][1]);
|
||||
|
||||
tdd = def_cy[F("dur")] | -1;
|
||||
tdd = def_cy["dur"] | -1;
|
||||
if (tdd > 0) presetCycleTime = tdd;
|
||||
|
||||
JsonObject interfaces = doc["if"];
|
||||
@ -229,7 +229,7 @@ void deserializeConfig() {
|
||||
JsonObject if_sync_recv = if_sync["recv"];
|
||||
CJSON(receiveNotificationBrightness, if_sync_recv["bri"]);
|
||||
CJSON(receiveNotificationColor, if_sync_recv["col"]);
|
||||
CJSON(receiveNotificationEffects, if_sync_recv[F("fx")]);
|
||||
CJSON(receiveNotificationEffects, if_sync_recv["fx"]);
|
||||
receiveNotifications = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects);
|
||||
|
||||
JsonObject if_sync_send = if_sync["send"];
|
||||
@ -317,7 +317,7 @@ void deserializeConfig() {
|
||||
CJSON(countdownMode, ol[F("cntdwn")]);
|
||||
overlayCurrent = overlayDefault;
|
||||
|
||||
CJSON(overlayMin, ol[F("min")]);
|
||||
CJSON(overlayMin, ol["min"]);
|
||||
CJSON(overlayMax, ol[F("max")]);
|
||||
CJSON(analogClock12pixel, ol[F("o12pix")]);
|
||||
CJSON(analogClock5MinuteMarks, ol[F("o5m")]);
|
||||
@ -342,7 +342,7 @@ void deserializeConfig() {
|
||||
if (it > 9) break;
|
||||
if (it<8 && timer[F("hour")]==255) it=8; // hour==255 -> sunrise/sunset
|
||||
CJSON(timerHours[it], timer[F("hour")]);
|
||||
CJSON(timerMinutes[it], timer[F("min")]);
|
||||
CJSON(timerMinutes[it], timer["min"]);
|
||||
CJSON(timerMacro[it], timer[F("macro")]);
|
||||
|
||||
byte dowPrev = timerWeekday[it];
|
||||
@ -517,12 +517,12 @@ void serializeConfig() {
|
||||
|
||||
JsonObject light_tr = light.createNestedObject("tr");
|
||||
light_tr[F("mode")] = fadeTransition;
|
||||
light_tr[F("dur")] = transitionDelayDefault / 100;
|
||||
light_tr[F("pal")] = strip.paletteFade;
|
||||
light_tr["dur"] = transitionDelayDefault / 100;
|
||||
light_tr["pal"] = strip.paletteFade;
|
||||
|
||||
JsonObject light_nl = light.createNestedObject("nl");
|
||||
light_nl[F("mode")] = nightlightMode;
|
||||
light_nl[F("dur")] = nightlightDelayMinsDefault;
|
||||
light_nl["dur"] = nightlightDelayMinsDefault;
|
||||
light_nl[F("tbri")] = nightlightTargetBri;
|
||||
light_nl[F("macro")] = macroNl;
|
||||
|
||||
@ -539,7 +539,7 @@ void serializeConfig() {
|
||||
JsonArray def_cy_range = def_cy.createNestedArray(F("range"));
|
||||
def_cy_range.add(presetCycleMin);
|
||||
def_cy_range.add(presetCycleMax);
|
||||
def_cy[F("dur")] = presetCycleTime;
|
||||
def_cy["dur"] = presetCycleTime;
|
||||
}
|
||||
|
||||
JsonObject interfaces = doc.createNestedObject("if");
|
||||
@ -551,7 +551,7 @@ void serializeConfig() {
|
||||
JsonObject if_sync_recv = if_sync.createNestedObject("recv");
|
||||
if_sync_recv["bri"] = receiveNotificationBrightness;
|
||||
if_sync_recv["col"] = receiveNotificationColor;
|
||||
if_sync_recv[F("fx")] = receiveNotificationEffects;
|
||||
if_sync_recv["fx"] = receiveNotificationEffects;
|
||||
|
||||
JsonObject if_sync_send = if_sync.createNestedObject("send");
|
||||
if_sync_send[F("dir")] = notifyDirect;
|
||||
@ -631,7 +631,7 @@ void serializeConfig() {
|
||||
ol[F("clock")] = overlayDefault;
|
||||
ol[F("cntdwn")] = countdownMode;
|
||||
|
||||
ol[F("min")] = overlayMin;
|
||||
ol["min"] = overlayMin;
|
||||
ol[F("max")] = overlayMax;
|
||||
ol[F("o12pix")] = analogClock12pixel;
|
||||
ol[F("o5m")] = analogClock5MinuteMarks;
|
||||
@ -652,7 +652,7 @@ void serializeConfig() {
|
||||
JsonObject timers_ins0 = timers_ins.createNestedObject();
|
||||
timers_ins0["en"] = (timerWeekday[i] & 0x01);
|
||||
timers_ins0[F("hour")] = timerHours[i];
|
||||
timers_ins0[F("min")] = timerMinutes[i];
|
||||
timers_ins0["min"] = timerMinutes[i];
|
||||
timers_ins0[F("macro")] = timerMacro[i];
|
||||
timers_ins0[F("dow")] = timerWeekday[i] >> 1;
|
||||
}
|
||||
@ -674,7 +674,6 @@ void serializeConfig() {
|
||||
for (byte i = 0; i < 15; i++)
|
||||
dmx_fixmap.add(DMXFixtureMap[i]);
|
||||
#endif
|
||||
//}
|
||||
|
||||
JsonObject usermods_settings = doc.createNestedObject("um");
|
||||
usermods.addToConfig(usermods_settings);
|
||||
|
@ -127,16 +127,16 @@ void deserializeSegment(JsonObject elem, byte it)
|
||||
|
||||
//temporary, strip object gets updated via colorUpdated()
|
||||
if (id == strip.getMainSegmentId()) {
|
||||
effectCurrent = elem[F("fx")] | effectCurrent;
|
||||
effectCurrent = elem["fx"] | effectCurrent;
|
||||
effectSpeed = elem[F("sx")] | effectSpeed;
|
||||
effectIntensity = elem[F("ix")] | effectIntensity;
|
||||
effectPalette = elem[F("pal")] | effectPalette;
|
||||
effectPalette = elem["pal"] | effectPalette;
|
||||
} else { //permanent
|
||||
byte fx = elem[F("fx")] | seg.mode;
|
||||
byte fx = elem["fx"] | seg.mode;
|
||||
if (fx != seg.mode && fx < strip.getModeCount()) strip.setMode(id, fx);
|
||||
seg.speed = elem[F("sx")] | seg.speed;
|
||||
seg.intensity = elem[F("ix")] | seg.intensity;
|
||||
seg.palette = elem[F("pal")] | seg.palette;
|
||||
seg.palette = elem["pal"] | seg.palette;
|
||||
}
|
||||
|
||||
JsonArray iarr = elem[F("i")]; //set individual LEDs
|
||||
@ -218,14 +218,14 @@ bool deserializeState(JsonObject root)
|
||||
int cy = root[F("pl")] | -2;
|
||||
if (cy > -2) presetCyclingEnabled = (cy >= 0);
|
||||
JsonObject ccnf = root["ccnf"];
|
||||
presetCycleMin = ccnf[F("min")] | presetCycleMin;
|
||||
presetCycleMin = ccnf["min"] | presetCycleMin;
|
||||
presetCycleMax = ccnf[F("max")] | presetCycleMax;
|
||||
tr = ccnf[F("time")] | -1;
|
||||
if (tr >= 2) presetCycleTime = tr;
|
||||
|
||||
JsonObject nl = root["nl"];
|
||||
nightlightActive = nl["on"] | nightlightActive;
|
||||
nightlightDelayMins = nl[F("dur")] | nightlightDelayMins;
|
||||
nightlightDelayMins = nl["dur"] | nightlightDelayMins;
|
||||
nightlightMode = nl[F("fade")] | nightlightMode; //deprecated, remove for v0.13.0
|
||||
nightlightMode = nl[F("mode")] | nightlightMode;
|
||||
nightlightTargetBri = nl[F("tbri")] | nightlightTargetBri;
|
||||
@ -376,10 +376,10 @@ void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id, bool fo
|
||||
}
|
||||
}
|
||||
|
||||
root[F("fx")] = seg.mode;
|
||||
root["fx"] = seg.mode;
|
||||
root[F("sx")] = seg.speed;
|
||||
root[F("ix")] = seg.intensity;
|
||||
root[F("pal")] = seg.palette;
|
||||
root["pal"] = seg.palette;
|
||||
root[F("sel")] = seg.isSelected();
|
||||
root["rev"] = seg.getOption(SEG_OPTION_REVERSED);
|
||||
root[F("mi")] = seg.getOption(SEG_OPTION_MIRROR);
|
||||
@ -398,17 +398,18 @@ void serializeState(JsonObject root, bool forPreset, bool includeBri, bool segme
|
||||
|
||||
root[F("ps")] = currentPreset;
|
||||
root[F("pl")] = (presetCyclingEnabled) ? 0: -1;
|
||||
|
||||
usermods.addToJsonState(root);
|
||||
|
||||
//temporary for preset cycle
|
||||
JsonObject ccnf = root.createNestedObject("ccnf");
|
||||
ccnf[F("min")] = presetCycleMin;
|
||||
ccnf["min"] = presetCycleMin;
|
||||
ccnf[F("max")] = presetCycleMax;
|
||||
ccnf[F("time")] = presetCycleTime;
|
||||
|
||||
JsonObject nl = root.createNestedObject("nl");
|
||||
nl["on"] = nightlightActive;
|
||||
nl[F("dur")] = nightlightDelayMins;
|
||||
nl["dur"] = nightlightDelayMins;
|
||||
nl[F("fade")] = (nightlightMode > NL_MODE_SET); //deprecated
|
||||
nl[F("mode")] = nightlightMode;
|
||||
nl[F("tbri")] = nightlightTargetBri;
|
||||
@ -788,7 +789,7 @@ void serveJson(AsyncWebServerRequest* request, uint8_t versionAPI)
|
||||
request->send_P(200, "application/json", JSON_mode_names);
|
||||
return;
|
||||
}
|
||||
else if (url.indexOf(F("pal")) > 0) {
|
||||
else if (url.indexOf("pal") > 0) {
|
||||
request->send_P(200, "application/json", JSON_palette_names);
|
||||
return;
|
||||
}
|
||||
|
@ -136,7 +136,6 @@ void publishMqtt()
|
||||
|
||||
bool initMqtt()
|
||||
{
|
||||
lastMqttReconnectAttempt = millis();
|
||||
if (!mqttEnabled || mqttServer[0] == 0 || !WLED_CONNECTED) return false;
|
||||
|
||||
if (mqtt == nullptr) {
|
||||
|
@ -31,7 +31,7 @@
|
||||
#ifdef USERMOD_BME280
|
||||
#include "../usermods/BME280_v2/usermod_bme280.h"
|
||||
#endif
|
||||
#ifdef USERMOD_FOUR_LINE_DISLAY
|
||||
#ifdef USERMOD_FOUR_LINE_DISPLAY
|
||||
#include "../usermods/usermod_v2_four_line_display/usermod_v2_four_line_display.h"
|
||||
#endif
|
||||
#ifdef USERMOD_ROTARY_ENCODER_UI
|
||||
@ -67,24 +67,24 @@ void registerUsermods()
|
||||
#ifdef USERMOD_BME280
|
||||
usermods.add(new UsermodBME280());
|
||||
#endif
|
||||
#ifdef USERMOD_SENSORSTOMQTT
|
||||
#ifdef USERMOD_SENSORSTOMQTT
|
||||
usermods.add(new UserMod_SensorsToMQTT());
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef USERMOD_MODE_SORT
|
||||
#ifdef USERMOD_MODE_SORT
|
||||
usermods.add(new ModeSortUsermod());
|
||||
#endif
|
||||
#ifdef USERMOD_FOUR_LINE_DISLAY
|
||||
#endif
|
||||
#ifdef USERMOD_FOUR_LINE_DISPLAY
|
||||
usermods.add(new FourLineDisplayUsermod());
|
||||
#endif
|
||||
#ifdef USERMOD_ROTARY_ENCODER_UI
|
||||
usermods.add(new RotaryEncoderUIUsermod());
|
||||
#endif
|
||||
#ifdef USERMOD_AUTO_SAVE
|
||||
usermods.add(new AutoSaveUsermod());
|
||||
#endif
|
||||
#endif
|
||||
#ifdef USERMOD_ROTARY_ENCODER_UI
|
||||
usermods.add(new RotaryEncoderUIUsermod()); // can use USERMOD_FOUR_LINE_DISPLAY
|
||||
#endif
|
||||
#ifdef USERMOD_AUTO_SAVE
|
||||
usermods.add(new AutoSaveUsermod()); // can use USERMOD_FOUR_LINE_DISPLAY
|
||||
#endif
|
||||
|
||||
#ifdef USERMOD_DHT
|
||||
usermods.add(new UsermodDHT());
|
||||
#endif
|
||||
#ifdef USERMOD_DHT
|
||||
usermods.add(new UsermodDHT());
|
||||
#endif
|
||||
}
|
@ -239,7 +239,7 @@ void WLED::loop()
|
||||
lastMqttReconnectAttempt = 0;
|
||||
}
|
||||
if (millis() - lastMqttReconnectAttempt > 30000) {
|
||||
// lastMqttReconnectAttempt = millis(); // don't do it in initMqtt()
|
||||
lastMqttReconnectAttempt = millis(); // don't do it in initMqtt() since MQTT may be disabled
|
||||
initMqtt();
|
||||
yield();
|
||||
// refresh WLED nodes list
|
||||
|
@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
// version code in format yymmddb (b = daily build)
|
||||
#define VERSION 2104111
|
||||
#define VERSION 2104121
|
||||
|
||||
//uncomment this if you have a "my_config.h" file you'd like to use
|
||||
//#define WLED_USE_MY_CONFIG
|
||||
|
@ -417,10 +417,10 @@ void deEEP() {
|
||||
for (byte j = 0; j < numChannels; j++) colX.add(EEPROM.read(memloc + j));
|
||||
}
|
||||
|
||||
segObj[F("fx")] = EEPROM.read(i+10);
|
||||
segObj["fx"] = EEPROM.read(i+10);
|
||||
segObj[F("sx")] = EEPROM.read(i+11);
|
||||
segObj[F("ix")] = EEPROM.read(i+16);
|
||||
segObj[F("pal")] = EEPROM.read(i+17);
|
||||
segObj["pal"] = EEPROM.read(i+17);
|
||||
} else {
|
||||
WS2812FX::Segment* seg = strip.getSegments();
|
||||
memcpy(seg, EEPROM.getDataPtr() +i+2, 240);
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include "wled.h"
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* Sending XML status files to client
|
||||
|
Loading…
Reference in New Issue
Block a user