diff --git a/usermods/EXAMPLE_v2/usermod_v2_example.h b/usermods/EXAMPLE_v2/usermod_v2_example.h index e67ef8da..ef68e907 100644 --- a/usermods/EXAMPLE_v2/usermod_v2_example.h +++ b/usermods/EXAMPLE_v2/usermod_v2_example.h @@ -103,7 +103,43 @@ class MyExampleUsermod : public Usermod { userVar0 = root["user0"] | userVar0; //if "user0" key exists in JSON, update, else keep old value //if (root["bri"] == 255) Serial.println(F("Don't burn down your garage!")); } - + + + /* + * addToConfig() can be used to add custom persistent settings to the cfg.json file in the "um" (usermod) object. + * It will be called by WLED when settings are actually saved (for example, LED settings are saved) + * If you want to force saving the current state, use serializeConfig() in your loop(). + * + * CAUTION: serializeConfig() will initiate a filesystem write operation. + * It might cause the LEDs to stutter and will cause flash wear if called too often. + * Use it sparingly and always in the loop, never in network callbacks! + * + * addToConfig() will also not yet add your setting to one of the settings pages automatically. + * To make that work you still have to add the setting to the HTML, xml.cpp and set.cpp manually. + * + * 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("exampleUsermod"); + top["great"] = userVar0; //save this var persistently whenever settings are saved + } + + + /* + * readFromConfig() can be used to read back the custom settings you added with addToConfig(). + * This is called by WLED when settings are loaded (currently this only happens once immediately after boot) + * + * readFromConfig() is called BEFORE setup(). This means you can use your persistent values in setup() (e.g. pin assignments, buffer sizes), + * but also that if you want to write persistent values to a dynamic buffer, you'd need to allocate it here instead of in setup. + * 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["top"]; + userVar0 = top["great"] | 42; //The value right of the pipe "|" is the default value in case your setting was not present in cfg.json (e.g. first boot) + } + /* * getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!). diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index 824299bd..2199b055 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -313,6 +313,9 @@ void deserializeConfig() { it++; } #endif + + JsonObject usermods_settings = doc["um"]; + usermods.readFromConfig(usermods_settings); } void serializeConfig() { @@ -592,6 +595,9 @@ void serializeConfig() { #endif //} + JsonObject usermods_settings = doc.createNestedObject("um"); + usermods.addToConfig(usermods_settings); + File f = WLED_FS.open("/cfg.json", "w"); if (f) serializeJson(doc, f); f.close(); diff --git a/wled00/const.h b/wled00/const.h index a9a10a50..3afc3167 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -89,7 +89,8 @@ #define TYPE_GS8608 23 //same driver as WS2812, but will require signal 2x per second (else displays test pattern) #define TYPE_WS2811_400KHZ 24 //half-speed WS2812 protocol, used by very old WS2811 units #define TYPE_SK6812_RGBW 30 -//Analog types (PWM) (32-47) +//"Analog" types (PWM) (32-47) +#define TYPE_ONOFF 40 //binary output (relays etc.) #define TYPE_ANALOG_1CH 41 //single channel PWM. Uses value of brightest RGBW channel #define TYPE_ANALOG_2CH 42 //analog WW + CW #define TYPE_ANALOG_3CH 43 //analog RGB diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h index edb674c5..035a4728 100644 --- a/wled00/fcn_declare.h +++ b/wled00/fcn_declare.h @@ -175,6 +175,8 @@ class Usermod { virtual void addToJsonState(JsonObject& obj) {} virtual void addToJsonInfo(JsonObject& obj) {} virtual void readFromJsonState(JsonObject& obj) {} + virtual void addToConfig(JsonObject& obj) {} + virtual void readFromConfig(JsonObject& obj) {} virtual uint16_t getId() {return USERMOD_ID_UNSPECIFIED;} }; @@ -193,6 +195,9 @@ class UsermodManager { void addToJsonInfo(JsonObject& obj); void readFromJsonState(JsonObject& obj); + void addToConfig(JsonObject& obj); + void readFromConfig(JsonObject& obj); + bool add(Usermod* um); byte getModCount(); }; diff --git a/wled00/um_manager.cpp b/wled00/um_manager.cpp index 011bc58c..cec7d613 100644 --- a/wled00/um_manager.cpp +++ b/wled00/um_manager.cpp @@ -12,6 +12,8 @@ void UsermodManager::connected() { for (byte i = 0; i < numMods; i++) ums[i]->co void UsermodManager::addToJsonState(JsonObject& obj) { for (byte i = 0; i < numMods; i++) ums[i]->addToJsonState(obj); } void UsermodManager::addToJsonInfo(JsonObject& obj) { for (byte i = 0; i < numMods; i++) ums[i]->addToJsonInfo(obj); } void UsermodManager::readFromJsonState(JsonObject& obj) { for (byte i = 0; i < numMods; i++) ums[i]->readFromJsonState(obj); } +void UsermodManager::addToConfig(JsonObject& obj) { for (byte i = 0; i < numMods; i++) ums[i]->addToConfig(obj); } +void UsermodManager::readFromConfig(JsonObject& obj) { for (byte i = 0; i < numMods; i++) ums[i]->readFromConfig(obj); } bool UsermodManager::add(Usermod* um) {