From 52fb5b4faae4ae2e5aaf7c66e3c2530835c7808c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 27 Dec 2025 15:12:01 +0000 Subject: [PATCH 01/13] Initial plan From 6ee9524cab160bd4538d0367320bbcb96ce6f4de Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 27 Dec 2025 15:18:51 +0000 Subject: [PATCH 02/13] Add getName() method to base Usermod class and usermods with existing _name Co-authored-by: DedeHai <6280424+DedeHai@users.noreply.github.com> --- usermods/AHT10_v2/AHT10_v2.cpp | 5 + .../Animated_Staircase/Animated_Staircase.cpp | 5 + usermods/BH1750_v2/BH1750_v2.h | 189 +-- usermods/BME280_v2/BME280_v2.cpp | 5 + usermods/Battery/Battery.cpp | 5 + usermods/EXAMPLE/usermod_v2_example.cpp | 9 + usermods/INA226_v2/INA226_v2.cpp | 5 + .../Internal_Temperature_v2.cpp | 5 + usermods/LD2410_v2/LD2410_v2.cpp | 5 + .../LDR_Dusk_Dawn_v2/LDR_Dusk_Dawn_v2.cpp | 5 + usermods/MAX17048_v2/MAX17048_v2.cpp | 5 + .../PIR_sensor_switch/PIR_sensor_switch.cpp | 1153 +++++++++-------- usermods/PWM_fan/PWM_fan.cpp | 5 + usermods/boblight/boblight.cpp | 5 + usermods/deep_sleep/deep_sleep.cpp | 5 + usermods/mpu6050_imu/mpu6050_imu.cpp | 5 + usermods/multi_relay/multi_relay.cpp | 5 + .../quinled-an-penta/quinled-an-penta.cpp | 5 + .../rgb-rotary-encoder/rgb-rotary-encoder.cpp | 5 + usermods/sd_card/sd_card.cpp | 5 + usermods/udp_name_sync/udp_name_sync.cpp | 4 + .../usermod_v2_auto_save.cpp | 5 + .../usermod_v2_brightness_follow_sun.cpp | 5 + .../usermod_v2_klipper_percentage.cpp | 5 + .../usermod_v2_rotary_encoder_ui_ALT.cpp | 5 + wled00/fcn_declare.h | 2 + wled00/um_manager.cpp | 11 + 27 files changed, 807 insertions(+), 666 deletions(-) diff --git a/usermods/AHT10_v2/AHT10_v2.cpp b/usermods/AHT10_v2/AHT10_v2.cpp index f88bee1daa..c152351357 100644 --- a/usermods/AHT10_v2/AHT10_v2.cpp +++ b/usermods/AHT10_v2/AHT10_v2.cpp @@ -182,6 +182,11 @@ class UsermodAHT10 : public Usermod return USERMOD_ID_AHT10; } + const char* getName() override + { + return FPSTR(_name); + } + void addToJsonInfo(JsonObject &root) override { // if "u" object does not exist yet wee need to create it diff --git a/usermods/Animated_Staircase/Animated_Staircase.cpp b/usermods/Animated_Staircase/Animated_Staircase.cpp index 2d2d27cf43..6f9a327449 100644 --- a/usermods/Animated_Staircase/Animated_Staircase.cpp +++ b/usermods/Animated_Staircase/Animated_Staircase.cpp @@ -353,6 +353,11 @@ class Animated_Staircase : public Usermod { uint16_t getId() { return USERMOD_ID_ANIMATED_STAIRCASE; } + const char* getName() override + { + return FPSTR(_name); + } + #ifndef WLED_DISABLE_MQTT /** * handling of MQTT message diff --git a/usermods/BH1750_v2/BH1750_v2.h b/usermods/BH1750_v2/BH1750_v2.h index 22f51ce9ba..380bb332c7 100644 --- a/usermods/BH1750_v2/BH1750_v2.h +++ b/usermods/BH1750_v2/BH1750_v2.h @@ -1,92 +1,97 @@ - -#pragma once -#include "wled.h" -#include - -#ifdef WLED_DISABLE_MQTT -#error "This user mod requires MQTT to be enabled." -#endif - -// the max frequency to check photoresistor, 10 seconds -#ifndef USERMOD_BH1750_MAX_MEASUREMENT_INTERVAL -#define USERMOD_BH1750_MAX_MEASUREMENT_INTERVAL 10000 -#endif - -// the min frequency to check photoresistor, 500 ms -#ifndef USERMOD_BH1750_MIN_MEASUREMENT_INTERVAL -#define USERMOD_BH1750_MIN_MEASUREMENT_INTERVAL 500 -#endif - -// how many seconds after boot to take first measurement, 10 seconds -#ifndef USERMOD_BH1750_FIRST_MEASUREMENT_AT -#define USERMOD_BH1750_FIRST_MEASUREMENT_AT 10000 -#endif - -// only report if difference grater than offset value -#ifndef USERMOD_BH1750_OFFSET_VALUE -#define USERMOD_BH1750_OFFSET_VALUE 1 -#endif - -class Usermod_BH1750 : public Usermod -{ -private: - int8_t offset = USERMOD_BH1750_OFFSET_VALUE; - - unsigned long maxReadingInterval = USERMOD_BH1750_MAX_MEASUREMENT_INTERVAL; - unsigned long minReadingInterval = USERMOD_BH1750_MIN_MEASUREMENT_INTERVAL; - unsigned long lastMeasurement = UINT32_MAX - (USERMOD_BH1750_MAX_MEASUREMENT_INTERVAL - USERMOD_BH1750_FIRST_MEASUREMENT_AT); - unsigned long lastSend = UINT32_MAX - (USERMOD_BH1750_MAX_MEASUREMENT_INTERVAL - USERMOD_BH1750_FIRST_MEASUREMENT_AT); - // flag to indicate we have finished the first readLightLevel call - // allows this library to report to the user how long until the first - // measurement - bool getLuminanceComplete = false; - - // flag set at startup - bool enabled = true; - - // strings to reduce flash memory usage (used more than twice) - static const char _name[]; - static const char _enabled[]; - static const char _maxReadInterval[]; - static const char _minReadInterval[]; - static const char _offset[]; - static const char _HomeAssistantDiscovery[]; - - bool initDone = false; - bool sensorFound = false; - - // Home Assistant and MQTT - String mqttLuminanceTopic; - bool mqttInitialized = false; - bool HomeAssistantDiscovery = true; // Publish Home Assistant Discovery messages - - BH1750 lightMeter; - float lastLux = -1000; - - // set up Home Assistant discovery entries - void _mqttInitialize(); - - // Create an MQTT Sensor for Home Assistant Discovery purposes, this includes a pointer to the topic that is published to in the Loop. - void _createMqttSensor(const String &name, const String &topic, const String &deviceClass, const String &unitOfMeasurement); - -public: - void setup(); - void loop(); - inline float getIlluminance() { - return (float)lastLux; - } - - void addToJsonInfo(JsonObject &root); - - // (called from set.cpp) stores persistent properties to cfg.json - void addToConfig(JsonObject &root); - - // called before setup() to populate properties from values stored in cfg.json - bool readFromConfig(JsonObject &root); - - inline uint16_t getId() - { - return USERMOD_ID_BH1750; - } - -}; + +#pragma once +#include "wled.h" +#include + +#ifdef WLED_DISABLE_MQTT +#error "This user mod requires MQTT to be enabled." +#endif + +// the max frequency to check photoresistor, 10 seconds +#ifndef USERMOD_BH1750_MAX_MEASUREMENT_INTERVAL +#define USERMOD_BH1750_MAX_MEASUREMENT_INTERVAL 10000 +#endif + +// the min frequency to check photoresistor, 500 ms +#ifndef USERMOD_BH1750_MIN_MEASUREMENT_INTERVAL +#define USERMOD_BH1750_MIN_MEASUREMENT_INTERVAL 500 +#endif + +// how many seconds after boot to take first measurement, 10 seconds +#ifndef USERMOD_BH1750_FIRST_MEASUREMENT_AT +#define USERMOD_BH1750_FIRST_MEASUREMENT_AT 10000 +#endif + +// only report if difference grater than offset value +#ifndef USERMOD_BH1750_OFFSET_VALUE +#define USERMOD_BH1750_OFFSET_VALUE 1 +#endif + +class Usermod_BH1750 : public Usermod +{ +private: + int8_t offset = USERMOD_BH1750_OFFSET_VALUE; + + unsigned long maxReadingInterval = USERMOD_BH1750_MAX_MEASUREMENT_INTERVAL; + unsigned long minReadingInterval = USERMOD_BH1750_MIN_MEASUREMENT_INTERVAL; + unsigned long lastMeasurement = UINT32_MAX - (USERMOD_BH1750_MAX_MEASUREMENT_INTERVAL - USERMOD_BH1750_FIRST_MEASUREMENT_AT); + unsigned long lastSend = UINT32_MAX - (USERMOD_BH1750_MAX_MEASUREMENT_INTERVAL - USERMOD_BH1750_FIRST_MEASUREMENT_AT); + // flag to indicate we have finished the first readLightLevel call + // allows this library to report to the user how long until the first + // measurement + bool getLuminanceComplete = false; + + // flag set at startup + bool enabled = true; + + // strings to reduce flash memory usage (used more than twice) + static const char _name[]; + static const char _enabled[]; + static const char _maxReadInterval[]; + static const char _minReadInterval[]; + static const char _offset[]; + static const char _HomeAssistantDiscovery[]; + + bool initDone = false; + bool sensorFound = false; + + // Home Assistant and MQTT + String mqttLuminanceTopic; + bool mqttInitialized = false; + bool HomeAssistantDiscovery = true; // Publish Home Assistant Discovery messages + + BH1750 lightMeter; + float lastLux = -1000; + + // set up Home Assistant discovery entries + void _mqttInitialize(); + + // Create an MQTT Sensor for Home Assistant Discovery purposes, this includes a pointer to the topic that is published to in the Loop. + void _createMqttSensor(const String &name, const String &topic, const String &deviceClass, const String &unitOfMeasurement); + +public: + void setup(); + void loop(); + inline float getIlluminance() { + return (float)lastLux; + } + + void addToJsonInfo(JsonObject &root); + + // (called from set.cpp) stores persistent properties to cfg.json + void addToConfig(JsonObject &root); + + // called before setup() to populate properties from values stored in cfg.json + bool readFromConfig(JsonObject &root); + + inline uint16_t getId() + { + return USERMOD_ID_BH1750; + } + + const char* getName() override + { + return FPSTR(_name); + } + +}; diff --git a/usermods/BME280_v2/BME280_v2.cpp b/usermods/BME280_v2/BME280_v2.cpp index dd58590448..17ffd538bc 100644 --- a/usermods/BME280_v2/BME280_v2.cpp +++ b/usermods/BME280_v2/BME280_v2.cpp @@ -473,6 +473,11 @@ class UsermodBME280 : public Usermod uint16_t getId() { return USERMOD_ID_BME280; } + + const char* getName() override + { + return FPSTR(_name); + } }; const char UsermodBME280::_name[] PROGMEM = "BME280/BMP280"; diff --git a/usermods/Battery/Battery.cpp b/usermods/Battery/Battery.cpp index 5572f55024..0a84b2b1d4 100644 --- a/usermods/Battery/Battery.cpp +++ b/usermods/Battery/Battery.cpp @@ -604,6 +604,11 @@ class UsermodBattery : public Usermod return USERMOD_ID_BATTERY; } + const char* getName() override + { + return FPSTR(_name); + } + /** * get currently active battery type */ diff --git a/usermods/EXAMPLE/usermod_v2_example.cpp b/usermods/EXAMPLE/usermod_v2_example.cpp index 02e399fe08..fc6a864271 100644 --- a/usermods/EXAMPLE/usermod_v2_example.cpp +++ b/usermods/EXAMPLE/usermod_v2_example.cpp @@ -378,6 +378,15 @@ class MyExampleUsermod : public Usermod { return USERMOD_ID_EXAMPLE; } + /* + * getName() returns the name of the usermod. + * If your usermod has a _name string, return it here. + */ + const char* getName() override + { + return FPSTR(_name); + } + //More methods can be added in the future, this example will then be extended. //Your usermod will remain compatible as it does not need to implement all methods from the Usermod base class! }; diff --git a/usermods/INA226_v2/INA226_v2.cpp b/usermods/INA226_v2/INA226_v2.cpp index 26f92f4945..ca1b20ede6 100644 --- a/usermods/INA226_v2/INA226_v2.cpp +++ b/usermods/INA226_v2/INA226_v2.cpp @@ -359,6 +359,11 @@ class UsermodINA226 : public Usermod return USERMOD_ID_INA226; } + const char* getName() override + { + return FPSTR(_name); + } + void addToJsonInfo(JsonObject &root) override { JsonObject user = root["u"]; diff --git a/usermods/Internal_Temperature_v2/Internal_Temperature_v2.cpp b/usermods/Internal_Temperature_v2/Internal_Temperature_v2.cpp index 7c30985eea..bc59b10196 100644 --- a/usermods/Internal_Temperature_v2/Internal_Temperature_v2.cpp +++ b/usermods/Internal_Temperature_v2/Internal_Temperature_v2.cpp @@ -171,6 +171,11 @@ class InternalTemperatureUsermod : public Usermod { return USERMOD_ID_INTERNAL_TEMPERATURE; } + + const char* getName() override + { + return FPSTR(_name); + } }; const char InternalTemperatureUsermod::_name[] PROGMEM = "Internal Temperature"; diff --git a/usermods/LD2410_v2/LD2410_v2.cpp b/usermods/LD2410_v2/LD2410_v2.cpp index 095da12f25..27085b11fa 100644 --- a/usermods/LD2410_v2/LD2410_v2.cpp +++ b/usermods/LD2410_v2/LD2410_v2.cpp @@ -208,6 +208,11 @@ class LD2410Usermod : public Usermod { { return USERMOD_ID_LD2410; } + + const char* getName() override + { + return FPSTR(_name); + } }; diff --git a/usermods/LDR_Dusk_Dawn_v2/LDR_Dusk_Dawn_v2.cpp b/usermods/LDR_Dusk_Dawn_v2/LDR_Dusk_Dawn_v2.cpp index 9c5c835e9a..34708bf4b5 100644 --- a/usermods/LDR_Dusk_Dawn_v2/LDR_Dusk_Dawn_v2.cpp +++ b/usermods/LDR_Dusk_Dawn_v2/LDR_Dusk_Dawn_v2.cpp @@ -147,6 +147,11 @@ class LDR_Dusk_Dawn_v2 : public Usermod { uint16_t getId() { return USERMOD_ID_LDR_DUSK_DAWN; } + + const char* getName() override + { + return FPSTR(_name); + } }; const char LDR_Dusk_Dawn_v2::_name[] PROGMEM = "LDR_Dusk_Dawn_v2"; diff --git a/usermods/MAX17048_v2/MAX17048_v2.cpp b/usermods/MAX17048_v2/MAX17048_v2.cpp index 520f1a7b35..1e6558064f 100644 --- a/usermods/MAX17048_v2/MAX17048_v2.cpp +++ b/usermods/MAX17048_v2/MAX17048_v2.cpp @@ -268,6 +268,11 @@ class Usermod_MAX17048 : public Usermod { return USERMOD_ID_MAX17048; } + const char* getName() override + { + return FPSTR(_name); + } + }; diff --git a/usermods/PIR_sensor_switch/PIR_sensor_switch.cpp b/usermods/PIR_sensor_switch/PIR_sensor_switch.cpp index 6f09ce5be0..c7ea15d223 100644 --- a/usermods/PIR_sensor_switch/PIR_sensor_switch.cpp +++ b/usermods/PIR_sensor_switch/PIR_sensor_switch.cpp @@ -1,575 +1,580 @@ -#include "wled.h" - -#ifndef PIR_SENSOR_PIN - // compatible with QuinLED-Dig-Uno - #ifdef ARDUINO_ARCH_ESP32 - #define PIR_SENSOR_PIN 23 // Q4 - #else //ESP8266 boards - #define PIR_SENSOR_PIN 13 // Q4 (D7 on D1 mini) - #endif -#endif - -#ifndef PIR_SENSOR_OFF_SEC - #define PIR_SENSOR_OFF_SEC 600 -#endif - -#ifndef PIR_SENSOR_MAX_SENSORS - #define PIR_SENSOR_MAX_SENSORS 1 -#endif - -/* - * This usermod handles PIR sensor states. - * The strip will be switched on and the off timer will be resetted when the sensor goes HIGH. - * When the sensor state goes LOW, the off timer is started and when it expires, the strip is switched off. - * Maintained by: @blazoncek - * - * Usermods allow you to add own functionality to WLED more easily - * See: https://github.com/wled-dev/WLED/wiki/Add-own-functionality - * - * v2 usermods are class inheritance based and can (but don't have to) implement more functions, each of them is shown in this example. - * Multiple v2 usermods can be added to one compilation easily. - */ - -class PIRsensorSwitch : public Usermod -{ -public: - // constructor - PIRsensorSwitch() {} - // destructor - ~PIRsensorSwitch() {} - - //Enable/Disable the PIR sensor - inline void EnablePIRsensor(bool en) { enabled = en; } - - // Get PIR sensor enabled/disabled state - inline bool PIRsensorEnabled() { return enabled; } - -private: - - byte prevPreset = 0; - byte prevPlaylist = 0; - - volatile unsigned long offTimerStart = 0; // off timer start time - volatile bool PIRtriggered = false; // did PIR trigger? - bool initDone = false; // status of initialization - unsigned long lastLoop = 0; - bool sensorPinState[PIR_SENSOR_MAX_SENSORS] = {LOW}; // current PIR sensor pin state - - // configurable parameters -#if PIR_SENSOR_PIN < 0 - bool enabled = false; // PIR sensor disabled -#else - bool enabled = true; // PIR sensor enabled -#endif - int8_t PIRsensorPin[PIR_SENSOR_MAX_SENSORS] = {PIR_SENSOR_PIN}; // PIR sensor pin - uint32_t m_switchOffDelay = PIR_SENSOR_OFF_SEC*1000; // delay before switch off after the sensor state goes LOW (10min) - uint8_t m_onPreset = 0; // on preset - uint8_t m_offPreset = 0; // off preset - bool m_nightTimeOnly = false; // flag to indicate that PIR sensor should activate WLED during nighttime only - bool m_mqttOnly = false; // flag to send MQTT message only (assuming it is enabled) - // flag to enable triggering only if WLED is initially off (LEDs are not on, preventing running effect being overwritten by PIR) - bool m_offOnly = false; - bool m_offMode = offMode; - bool m_override = false; - - // Home Assistant - bool HomeAssistantDiscovery = false; // is HA discovery turned on - int16_t idx = -1; // Domoticz virtual switch idx - - // strings to reduce flash memory usage (used more than twice) - static const char _name[]; - static const char _switchOffDelay[]; - static const char _enabled[]; - static const char _onPreset[]; - static const char _offPreset[]; - static const char _nightTime[]; - static const char _mqttOnly[]; - static const char _offOnly[]; - static const char _haDiscovery[]; - static const char _override[]; - static const char _domoticzIDX[]; - - /** - * check if it is daytime - * if sunrise/sunset is not defined (no NTP or lat/lon) default to nighttime - */ - static bool isDayTime(); - - /** - * switch strip on/off - */ - void switchStrip(bool switchOn); - void publishMqtt(bool switchOn); - - // Create an MQTT Binary Sensor for Home Assistant Discovery purposes, this includes a pointer to the topic that is published to in the Loop. - void publishHomeAssistantAutodiscovery(); - - /** - * Read and update PIR sensor state. - * Initialize/reset switch off timer - */ - bool updatePIRsensorState(); - - /** - * switch off the strip if the delay has elapsed - */ - bool handleOffTimer(); - -public: - //Functions called by WLED - - /** - * setup() is called once at boot. WiFi is not yet connected at this point. - * You can use it to initialize variables, sensors or similar. - */ - void setup() override; - - /** - * connected() is called every time the WiFi is (re)connected - * Use it to initialize network interfaces - */ - //void connected(); - - /** - * onMqttConnect() is called when MQTT connection is established - */ - void onMqttConnect(bool sessionPresent) override; - - /** - * loop() is called continuously. Here you can check for events, read sensors, etc. - */ - void loop() override; - - /** - * addToJsonInfo() can be used to add custom entries to the /json/info part of the JSON API. - * - * Add PIR sensor state and switch off timer duration to jsoninfo - */ - void addToJsonInfo(JsonObject &root) override; - - /** - * onStateChanged() is used to detect WLED state change - */ - void onStateChange(uint8_t mode) override; - - /** - * 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); - - /** - * 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) override; - - /** - * provide the changeable values - */ - void addToConfig(JsonObject &root) override; - - /** - * provide UI information and allow extending UI options - */ - void appendConfigData() override; - - /** - * restore the changeable values - * readFromConfig() is called before setup() to populate properties from values stored in cfg.json - * - * The function should return true if configuration was successfully loaded or false if there was no configuration. - */ - bool readFromConfig(JsonObject &root) override; - - /** - * getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!). - * This could be used in the future for the system to determine whether your usermod is installed. - */ - uint16_t getId() override { return USERMOD_ID_PIRSWITCH; } -}; - -// strings to reduce flash memory usage (used more than twice) -const char PIRsensorSwitch::_name[] PROGMEM = "PIRsensorSwitch"; -const char PIRsensorSwitch::_enabled[] PROGMEM = "PIRenabled"; -const char PIRsensorSwitch::_switchOffDelay[] PROGMEM = "PIRoffSec"; -const char PIRsensorSwitch::_onPreset[] PROGMEM = "on-preset"; -const char PIRsensorSwitch::_offPreset[] PROGMEM = "off-preset"; -const char PIRsensorSwitch::_nightTime[] PROGMEM = "nighttime-only"; -const char PIRsensorSwitch::_mqttOnly[] PROGMEM = "mqtt-only"; -const char PIRsensorSwitch::_offOnly[] PROGMEM = "off-only"; -const char PIRsensorSwitch::_haDiscovery[] PROGMEM = "HA-discovery"; -const char PIRsensorSwitch::_override[] PROGMEM = "override"; -const char PIRsensorSwitch::_domoticzIDX[] PROGMEM = "domoticz-idx"; - -bool PIRsensorSwitch::isDayTime() { - updateLocalTime(); - uint8_t hr = hour(localTime); - uint8_t mi = minute(localTime); - - if (sunrise && sunset) { - if (hour(sunrise)
hr) { - return true; - } else { - if (hour(sunrise)==hr && minute(sunrise)mi) { - return true; - } - } - } - return false; -} - -void PIRsensorSwitch::switchStrip(bool switchOn) -{ - if (m_offOnly && bri && (switchOn || (!PIRtriggered && !switchOn))) return; //if lights on and off only, do nothing - if (PIRtriggered && switchOn) return; //if already on and triggered before, do nothing - PIRtriggered = switchOn; - DEBUG_PRINT(F("PIR: strip=")); DEBUG_PRINTLN(switchOn?"on":"off"); - if (switchOn) { - if (m_onPreset) { - if (currentPlaylist>0 && !offMode) { - prevPlaylist = currentPlaylist; - unloadPlaylist(); - } else if (currentPreset>0 && !offMode) { - prevPreset = currentPreset; - } else { - saveTemporaryPreset(); - prevPlaylist = 0; - prevPreset = 255; - } - applyPreset(m_onPreset, CALL_MODE_BUTTON_PRESET); - return; - } - // preset not assigned - if (bri == 0) { - bri = briLast; - stateUpdated(CALL_MODE_BUTTON); - } - } else { - if (m_offPreset) { - applyPreset(m_offPreset, CALL_MODE_BUTTON_PRESET); - return; - } else if (prevPlaylist) { - if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyPreset(prevPlaylist, CALL_MODE_BUTTON_PRESET); - prevPlaylist = 0; - return; - } else if (prevPreset) { - if (prevPreset<255) { if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyPreset(prevPreset, CALL_MODE_BUTTON_PRESET); } - else { if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyTemporaryPreset(); } - prevPreset = 0; - return; - } - // preset not assigned - if (bri != 0) { - briLast = bri; - bri = 0; - stateUpdated(CALL_MODE_BUTTON); - } - } -} - -void PIRsensorSwitch::publishMqtt(bool switchOn) -{ -#ifndef WLED_DISABLE_MQTT - //Check if MQTT Connected, otherwise it will crash the 8266 - if (WLED_MQTT_CONNECTED) { - char buf[128]; - sprintf_P(buf, PSTR("%s/motion"), mqttDeviceTopic); //max length: 33 + 7 = 40 - mqtt->publish(buf, 0, false, switchOn?"on":"off"); - // Domoticz formatted message - if (idx > 0) { - StaticJsonDocument <128> msg; - msg[F("idx")] = idx; - msg[F("RSSI")] = WiFi.RSSI(); - msg[F("command")] = F("switchlight"); - msg[F("switchcmd")] = switchOn ? F("On") : F("Off"); - serializeJson(msg, buf, 128); - mqtt->publish("domoticz/in", 0, false, buf); - } - } -#endif -} - -void PIRsensorSwitch::publishHomeAssistantAutodiscovery() -{ -#ifndef WLED_DISABLE_MQTT - if (WLED_MQTT_CONNECTED) { - StaticJsonDocument<600> doc; - char uid[24], json_str[1024], buf[128]; - - sprintf_P(buf, PSTR("%s Motion"), serverDescription); //max length: 33 + 7 = 40 - doc[F("name")] = buf; - sprintf_P(buf, PSTR("%s/motion"), mqttDeviceTopic); //max length: 33 + 7 = 40 - doc[F("stat_t")] = buf; - doc[F("pl_on")] = "on"; - doc[F("pl_off")] = "off"; - sprintf_P(uid, PSTR("%s_motion"), escapedMac.c_str()); - doc[F("uniq_id")] = uid; - doc[F("dev_cla")] = F("motion"); - doc[F("exp_aft")] = 1800; - - JsonObject device = doc.createNestedObject(F("device")); // attach the sensor to the same device - device[F("name")] = serverDescription; - device[F("ids")] = String(F("wled-sensor-")) + mqttClientID; - device[F("mf")] = F(WLED_BRAND); - device[F("mdl")] = F(WLED_PRODUCT_NAME); - device[F("sw")] = versionString; - - sprintf_P(buf, PSTR("homeassistant/binary_sensor/%s/config"), uid); - DEBUG_PRINTLN(buf); - size_t payload_size = serializeJson(doc, json_str); - DEBUG_PRINTLN(json_str); - - mqtt->publish(buf, 0, true, json_str, payload_size); // do we really need to retain? - } -#endif -} - -bool PIRsensorSwitch::updatePIRsensorState() -{ - bool stateChanged = false; - bool allOff = true; - for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) { - if (PIRsensorPin[i] < 0) continue; - - bool pinState = digitalRead(PIRsensorPin[i]); - if (pinState != sensorPinState[i]) { - sensorPinState[i] = pinState; // change previous state - stateChanged = true; - - if (sensorPinState[i] == HIGH) { - offTimerStart = 0; - allOff = false; - if (!m_mqttOnly && (!m_nightTimeOnly || (m_nightTimeOnly && !isDayTime()))) switchStrip(true); - } - } - } - if (stateChanged) { - publishMqtt(!allOff); - // start switch off timer - if (allOff) offTimerStart = millis(); - } - return stateChanged; -} - -bool PIRsensorSwitch::handleOffTimer() -{ - if (offTimerStart > 0 && millis() - offTimerStart > m_switchOffDelay) { - offTimerStart = 0; - if (!m_mqttOnly && (!m_nightTimeOnly || (m_nightTimeOnly && !isDayTime()) || PIRtriggered)) switchStrip(false); - return true; - } - return false; -} - -//Functions called by WLED - -void PIRsensorSwitch::setup() -{ - for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) { - sensorPinState[i] = LOW; - if (PIRsensorPin[i] < 0) continue; - // pin retrieved from cfg.json (readFromConfig()) prior to running setup() - if (PinManager::allocatePin(PIRsensorPin[i], false, PinOwner::UM_PIR)) { - // PIR Sensor mode INPUT_PULLDOWN - #ifdef ESP8266 - pinMode(PIRsensorPin[i], PIRsensorPin[i]==16 ? INPUT_PULLDOWN_16 : INPUT_PULLUP); // ESP8266 has INPUT_PULLDOWN on GPIO16 only - #else - pinMode(PIRsensorPin[i], INPUT_PULLDOWN); - #endif - sensorPinState[i] = digitalRead(PIRsensorPin[i]); - } else { - DEBUG_PRINT(F("PIRSensorSwitch pin ")); DEBUG_PRINTLN(i); DEBUG_PRINTLN(F(" allocation failed.")); - PIRsensorPin[i] = -1; // allocation failed - } - } - initDone = true; -} - -void PIRsensorSwitch::onMqttConnect(bool sessionPresent) -{ - if (HomeAssistantDiscovery) { - publishHomeAssistantAutodiscovery(); - } -} - -void PIRsensorSwitch::loop() -{ - // only check sensors 5x/s - if (!enabled || millis() - lastLoop < 200) return; - lastLoop = millis(); - - if (!updatePIRsensorState()) { - handleOffTimer(); - } -} - -void PIRsensorSwitch::addToJsonInfo(JsonObject &root) -{ - JsonObject user = root["u"]; - if (user.isNull()) user = root.createNestedObject("u"); - - bool state = LOW; - for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) - if (PIRsensorPin[i] >= 0) state |= sensorPinState[i]; - - JsonArray infoArr = user.createNestedArray(FPSTR(_name)); - - String uiDomString; - if (enabled) { - if (offTimerStart > 0) { - uiDomString = ""; - unsigned int offSeconds = (m_switchOffDelay - (millis() - offTimerStart)) / 1000; - if (offSeconds >= 3600) { - uiDomString += (offSeconds / 3600); - uiDomString += F("h "); - offSeconds %= 3600; - } - if (offSeconds >= 60) { - uiDomString += (offSeconds / 60); - offSeconds %= 60; - } else if (uiDomString.length() > 0) { - uiDomString += 0; - } - if (uiDomString.length() > 0) { - uiDomString += F("min "); - } - uiDomString += (offSeconds); - infoArr.add(uiDomString + F("s")); - } else { - infoArr.add(state ? F("sensor on") : F("inactive")); - } - } else { - infoArr.add(F("disabled")); - } - - uiDomString = F(" "); - infoArr.add(uiDomString); - - if (enabled) { - JsonObject sensor = root[F("sensor")]; - if (sensor.isNull()) sensor = root.createNestedObject(F("sensor")); - sensor[F("motion")] = state || offTimerStart>0 ? true : false; - } -} - -void PIRsensorSwitch::onStateChange(uint8_t mode) { - if (!initDone) return; - DEBUG_PRINT(F("PIR: offTimerStart=")); DEBUG_PRINTLN(offTimerStart); - if (m_override && PIRtriggered && offTimerStart) { // debounce - // checking PIRtriggered and offTimerStart will prevent cancellation upon On trigger - DEBUG_PRINTLN(F("PIR: Canceled.")); - offTimerStart = 0; - PIRtriggered = false; - } -} - -void PIRsensorSwitch::readFromJsonState(JsonObject &root) -{ - if (!initDone) return; // prevent crash on boot applyPreset() - JsonObject usermod = root[FPSTR(_name)]; - if (!usermod.isNull()) { - if (usermod[FPSTR(_enabled)].is()) { - enabled = usermod[FPSTR(_enabled)].as(); - } - } -} - -void PIRsensorSwitch::addToConfig(JsonObject &root) -{ - JsonObject top = root.createNestedObject(FPSTR(_name)); - top[FPSTR(_enabled)] = enabled; - top[FPSTR(_switchOffDelay)] = m_switchOffDelay / 1000; - JsonArray pinArray = top.createNestedArray("pin"); - for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) pinArray.add(PIRsensorPin[i]); - top[FPSTR(_onPreset)] = m_onPreset; - top[FPSTR(_offPreset)] = m_offPreset; - top[FPSTR(_nightTime)] = m_nightTimeOnly; - top[FPSTR(_mqttOnly)] = m_mqttOnly; - top[FPSTR(_offOnly)] = m_offOnly; - top[FPSTR(_override)] = m_override; - top[FPSTR(_haDiscovery)] = HomeAssistantDiscovery; - top[FPSTR(_domoticzIDX)] = idx; - DEBUG_PRINTLN(F("PIR config saved.")); -} - -void PIRsensorSwitch::appendConfigData() -{ - oappend(F("addInfo('PIRsensorSwitch:HA-discovery',1,'HA=Home Assistant');")); // 0 is field type, 1 is actual field - oappend(F("addInfo('PIRsensorSwitch:override',1,'Cancel timer on change');")); // 0 is field type, 1 is actual field - for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) { - char str[128]; - sprintf_P(str, PSTR("addInfo('PIRsensorSwitch:pin[]',%d,'','#%d');"), i, i); - oappend(str); - } -} - -bool PIRsensorSwitch::readFromConfig(JsonObject &root) -{ - int8_t oldPin[PIR_SENSOR_MAX_SENSORS]; - for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) { - oldPin[i] = PIRsensorPin[i]; - PIRsensorPin[i] = -1; - } - - DEBUG_PRINT(FPSTR(_name)); - JsonObject top = root[FPSTR(_name)]; - if (top.isNull()) { - DEBUG_PRINTLN(F(": No config found. (Using defaults.)")); - return false; - } - - JsonArray pins = top["pin"]; - if (!pins.isNull()) { - for (size_t i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) - if (i < pins.size()) PIRsensorPin[i] = pins[i] | PIRsensorPin[i]; - } else { - PIRsensorPin[0] = top["pin"] | oldPin[0]; - } - - enabled = top[FPSTR(_enabled)] | enabled; - - m_switchOffDelay = (top[FPSTR(_switchOffDelay)] | m_switchOffDelay/1000) * 1000; - - m_onPreset = top[FPSTR(_onPreset)] | m_onPreset; - m_onPreset = max(0,min(250,(int)m_onPreset)); - m_offPreset = top[FPSTR(_offPreset)] | m_offPreset; - m_offPreset = max(0,min(250,(int)m_offPreset)); - - m_nightTimeOnly = top[FPSTR(_nightTime)] | m_nightTimeOnly; - m_mqttOnly = top[FPSTR(_mqttOnly)] | m_mqttOnly; - m_offOnly = top[FPSTR(_offOnly)] | m_offOnly; - m_override = top[FPSTR(_override)] | m_override; - HomeAssistantDiscovery = top[FPSTR(_haDiscovery)] | HomeAssistantDiscovery; - idx = top[FPSTR(_domoticzIDX)] | idx; - - if (!initDone) { - // reading config prior to setup() - DEBUG_PRINTLN(F(" config loaded.")); - } else { - for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) - if (oldPin[i] >= 0) PinManager::deallocatePin(oldPin[i], PinOwner::UM_PIR); - setup(); - DEBUG_PRINTLN(F(" config (re)loaded.")); - } - // use "return !top["newestParameter"].isNull();" when updating Usermod with new features - return !(pins.isNull() || pins.size() != PIR_SENSOR_MAX_SENSORS); -} - - -static PIRsensorSwitch pir_sensor_switch; +#include "wled.h" + +#ifndef PIR_SENSOR_PIN + // compatible with QuinLED-Dig-Uno + #ifdef ARDUINO_ARCH_ESP32 + #define PIR_SENSOR_PIN 23 // Q4 + #else //ESP8266 boards + #define PIR_SENSOR_PIN 13 // Q4 (D7 on D1 mini) + #endif +#endif + +#ifndef PIR_SENSOR_OFF_SEC + #define PIR_SENSOR_OFF_SEC 600 +#endif + +#ifndef PIR_SENSOR_MAX_SENSORS + #define PIR_SENSOR_MAX_SENSORS 1 +#endif + +/* + * This usermod handles PIR sensor states. + * The strip will be switched on and the off timer will be resetted when the sensor goes HIGH. + * When the sensor state goes LOW, the off timer is started and when it expires, the strip is switched off. + * Maintained by: @blazoncek + * + * Usermods allow you to add own functionality to WLED more easily + * See: https://github.com/wled-dev/WLED/wiki/Add-own-functionality + * + * v2 usermods are class inheritance based and can (but don't have to) implement more functions, each of them is shown in this example. + * Multiple v2 usermods can be added to one compilation easily. + */ + +class PIRsensorSwitch : public Usermod +{ +public: + // constructor + PIRsensorSwitch() {} + // destructor + ~PIRsensorSwitch() {} + + //Enable/Disable the PIR sensor + inline void EnablePIRsensor(bool en) { enabled = en; } + + // Get PIR sensor enabled/disabled state + inline bool PIRsensorEnabled() { return enabled; } + +private: + + byte prevPreset = 0; + byte prevPlaylist = 0; + + volatile unsigned long offTimerStart = 0; // off timer start time + volatile bool PIRtriggered = false; // did PIR trigger? + bool initDone = false; // status of initialization + unsigned long lastLoop = 0; + bool sensorPinState[PIR_SENSOR_MAX_SENSORS] = {LOW}; // current PIR sensor pin state + + // configurable parameters +#if PIR_SENSOR_PIN < 0 + bool enabled = false; // PIR sensor disabled +#else + bool enabled = true; // PIR sensor enabled +#endif + int8_t PIRsensorPin[PIR_SENSOR_MAX_SENSORS] = {PIR_SENSOR_PIN}; // PIR sensor pin + uint32_t m_switchOffDelay = PIR_SENSOR_OFF_SEC*1000; // delay before switch off after the sensor state goes LOW (10min) + uint8_t m_onPreset = 0; // on preset + uint8_t m_offPreset = 0; // off preset + bool m_nightTimeOnly = false; // flag to indicate that PIR sensor should activate WLED during nighttime only + bool m_mqttOnly = false; // flag to send MQTT message only (assuming it is enabled) + // flag to enable triggering only if WLED is initially off (LEDs are not on, preventing running effect being overwritten by PIR) + bool m_offOnly = false; + bool m_offMode = offMode; + bool m_override = false; + + // Home Assistant + bool HomeAssistantDiscovery = false; // is HA discovery turned on + int16_t idx = -1; // Domoticz virtual switch idx + + // strings to reduce flash memory usage (used more than twice) + static const char _name[]; + static const char _switchOffDelay[]; + static const char _enabled[]; + static const char _onPreset[]; + static const char _offPreset[]; + static const char _nightTime[]; + static const char _mqttOnly[]; + static const char _offOnly[]; + static const char _haDiscovery[]; + static const char _override[]; + static const char _domoticzIDX[]; + + /** + * check if it is daytime + * if sunrise/sunset is not defined (no NTP or lat/lon) default to nighttime + */ + static bool isDayTime(); + + /** + * switch strip on/off + */ + void switchStrip(bool switchOn); + void publishMqtt(bool switchOn); + + // Create an MQTT Binary Sensor for Home Assistant Discovery purposes, this includes a pointer to the topic that is published to in the Loop. + void publishHomeAssistantAutodiscovery(); + + /** + * Read and update PIR sensor state. + * Initialize/reset switch off timer + */ + bool updatePIRsensorState(); + + /** + * switch off the strip if the delay has elapsed + */ + bool handleOffTimer(); + +public: + //Functions called by WLED + + /** + * setup() is called once at boot. WiFi is not yet connected at this point. + * You can use it to initialize variables, sensors or similar. + */ + void setup() override; + + /** + * connected() is called every time the WiFi is (re)connected + * Use it to initialize network interfaces + */ + //void connected(); + + /** + * onMqttConnect() is called when MQTT connection is established + */ + void onMqttConnect(bool sessionPresent) override; + + /** + * loop() is called continuously. Here you can check for events, read sensors, etc. + */ + void loop() override; + + /** + * addToJsonInfo() can be used to add custom entries to the /json/info part of the JSON API. + * + * Add PIR sensor state and switch off timer duration to jsoninfo + */ + void addToJsonInfo(JsonObject &root) override; + + /** + * onStateChanged() is used to detect WLED state change + */ + void onStateChange(uint8_t mode) override; + + /** + * 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); + + /** + * 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) override; + + /** + * provide the changeable values + */ + void addToConfig(JsonObject &root) override; + + /** + * provide UI information and allow extending UI options + */ + void appendConfigData() override; + + /** + * restore the changeable values + * readFromConfig() is called before setup() to populate properties from values stored in cfg.json + * + * The function should return true if configuration was successfully loaded or false if there was no configuration. + */ + bool readFromConfig(JsonObject &root) override; + + /** + * getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!). + * This could be used in the future for the system to determine whether your usermod is installed. + */ + uint16_t getId() override { return USERMOD_ID_PIRSWITCH; } + + const char* getName() override + { + return FPSTR(_name); + } +}; + +// strings to reduce flash memory usage (used more than twice) +const char PIRsensorSwitch::_name[] PROGMEM = "PIRsensorSwitch"; +const char PIRsensorSwitch::_enabled[] PROGMEM = "PIRenabled"; +const char PIRsensorSwitch::_switchOffDelay[] PROGMEM = "PIRoffSec"; +const char PIRsensorSwitch::_onPreset[] PROGMEM = "on-preset"; +const char PIRsensorSwitch::_offPreset[] PROGMEM = "off-preset"; +const char PIRsensorSwitch::_nightTime[] PROGMEM = "nighttime-only"; +const char PIRsensorSwitch::_mqttOnly[] PROGMEM = "mqtt-only"; +const char PIRsensorSwitch::_offOnly[] PROGMEM = "off-only"; +const char PIRsensorSwitch::_haDiscovery[] PROGMEM = "HA-discovery"; +const char PIRsensorSwitch::_override[] PROGMEM = "override"; +const char PIRsensorSwitch::_domoticzIDX[] PROGMEM = "domoticz-idx"; + +bool PIRsensorSwitch::isDayTime() { + updateLocalTime(); + uint8_t hr = hour(localTime); + uint8_t mi = minute(localTime); + + if (sunrise && sunset) { + if (hour(sunrise)
hr) { + return true; + } else { + if (hour(sunrise)==hr && minute(sunrise)mi) { + return true; + } + } + } + return false; +} + +void PIRsensorSwitch::switchStrip(bool switchOn) +{ + if (m_offOnly && bri && (switchOn || (!PIRtriggered && !switchOn))) return; //if lights on and off only, do nothing + if (PIRtriggered && switchOn) return; //if already on and triggered before, do nothing + PIRtriggered = switchOn; + DEBUG_PRINT(F("PIR: strip=")); DEBUG_PRINTLN(switchOn?"on":"off"); + if (switchOn) { + if (m_onPreset) { + if (currentPlaylist>0 && !offMode) { + prevPlaylist = currentPlaylist; + unloadPlaylist(); + } else if (currentPreset>0 && !offMode) { + prevPreset = currentPreset; + } else { + saveTemporaryPreset(); + prevPlaylist = 0; + prevPreset = 255; + } + applyPreset(m_onPreset, CALL_MODE_BUTTON_PRESET); + return; + } + // preset not assigned + if (bri == 0) { + bri = briLast; + stateUpdated(CALL_MODE_BUTTON); + } + } else { + if (m_offPreset) { + applyPreset(m_offPreset, CALL_MODE_BUTTON_PRESET); + return; + } else if (prevPlaylist) { + if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyPreset(prevPlaylist, CALL_MODE_BUTTON_PRESET); + prevPlaylist = 0; + return; + } else if (prevPreset) { + if (prevPreset<255) { if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyPreset(prevPreset, CALL_MODE_BUTTON_PRESET); } + else { if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyTemporaryPreset(); } + prevPreset = 0; + return; + } + // preset not assigned + if (bri != 0) { + briLast = bri; + bri = 0; + stateUpdated(CALL_MODE_BUTTON); + } + } +} + +void PIRsensorSwitch::publishMqtt(bool switchOn) +{ +#ifndef WLED_DISABLE_MQTT + //Check if MQTT Connected, otherwise it will crash the 8266 + if (WLED_MQTT_CONNECTED) { + char buf[128]; + sprintf_P(buf, PSTR("%s/motion"), mqttDeviceTopic); //max length: 33 + 7 = 40 + mqtt->publish(buf, 0, false, switchOn?"on":"off"); + // Domoticz formatted message + if (idx > 0) { + StaticJsonDocument <128> msg; + msg[F("idx")] = idx; + msg[F("RSSI")] = WiFi.RSSI(); + msg[F("command")] = F("switchlight"); + msg[F("switchcmd")] = switchOn ? F("On") : F("Off"); + serializeJson(msg, buf, 128); + mqtt->publish("domoticz/in", 0, false, buf); + } + } +#endif +} + +void PIRsensorSwitch::publishHomeAssistantAutodiscovery() +{ +#ifndef WLED_DISABLE_MQTT + if (WLED_MQTT_CONNECTED) { + StaticJsonDocument<600> doc; + char uid[24], json_str[1024], buf[128]; + + sprintf_P(buf, PSTR("%s Motion"), serverDescription); //max length: 33 + 7 = 40 + doc[F("name")] = buf; + sprintf_P(buf, PSTR("%s/motion"), mqttDeviceTopic); //max length: 33 + 7 = 40 + doc[F("stat_t")] = buf; + doc[F("pl_on")] = "on"; + doc[F("pl_off")] = "off"; + sprintf_P(uid, PSTR("%s_motion"), escapedMac.c_str()); + doc[F("uniq_id")] = uid; + doc[F("dev_cla")] = F("motion"); + doc[F("exp_aft")] = 1800; + + JsonObject device = doc.createNestedObject(F("device")); // attach the sensor to the same device + device[F("name")] = serverDescription; + device[F("ids")] = String(F("wled-sensor-")) + mqttClientID; + device[F("mf")] = F(WLED_BRAND); + device[F("mdl")] = F(WLED_PRODUCT_NAME); + device[F("sw")] = versionString; + + sprintf_P(buf, PSTR("homeassistant/binary_sensor/%s/config"), uid); + DEBUG_PRINTLN(buf); + size_t payload_size = serializeJson(doc, json_str); + DEBUG_PRINTLN(json_str); + + mqtt->publish(buf, 0, true, json_str, payload_size); // do we really need to retain? + } +#endif +} + +bool PIRsensorSwitch::updatePIRsensorState() +{ + bool stateChanged = false; + bool allOff = true; + for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) { + if (PIRsensorPin[i] < 0) continue; + + bool pinState = digitalRead(PIRsensorPin[i]); + if (pinState != sensorPinState[i]) { + sensorPinState[i] = pinState; // change previous state + stateChanged = true; + + if (sensorPinState[i] == HIGH) { + offTimerStart = 0; + allOff = false; + if (!m_mqttOnly && (!m_nightTimeOnly || (m_nightTimeOnly && !isDayTime()))) switchStrip(true); + } + } + } + if (stateChanged) { + publishMqtt(!allOff); + // start switch off timer + if (allOff) offTimerStart = millis(); + } + return stateChanged; +} + +bool PIRsensorSwitch::handleOffTimer() +{ + if (offTimerStart > 0 && millis() - offTimerStart > m_switchOffDelay) { + offTimerStart = 0; + if (!m_mqttOnly && (!m_nightTimeOnly || (m_nightTimeOnly && !isDayTime()) || PIRtriggered)) switchStrip(false); + return true; + } + return false; +} + +//Functions called by WLED + +void PIRsensorSwitch::setup() +{ + for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) { + sensorPinState[i] = LOW; + if (PIRsensorPin[i] < 0) continue; + // pin retrieved from cfg.json (readFromConfig()) prior to running setup() + if (PinManager::allocatePin(PIRsensorPin[i], false, PinOwner::UM_PIR)) { + // PIR Sensor mode INPUT_PULLDOWN + #ifdef ESP8266 + pinMode(PIRsensorPin[i], PIRsensorPin[i]==16 ? INPUT_PULLDOWN_16 : INPUT_PULLUP); // ESP8266 has INPUT_PULLDOWN on GPIO16 only + #else + pinMode(PIRsensorPin[i], INPUT_PULLDOWN); + #endif + sensorPinState[i] = digitalRead(PIRsensorPin[i]); + } else { + DEBUG_PRINT(F("PIRSensorSwitch pin ")); DEBUG_PRINTLN(i); DEBUG_PRINTLN(F(" allocation failed.")); + PIRsensorPin[i] = -1; // allocation failed + } + } + initDone = true; +} + +void PIRsensorSwitch::onMqttConnect(bool sessionPresent) +{ + if (HomeAssistantDiscovery) { + publishHomeAssistantAutodiscovery(); + } +} + +void PIRsensorSwitch::loop() +{ + // only check sensors 5x/s + if (!enabled || millis() - lastLoop < 200) return; + lastLoop = millis(); + + if (!updatePIRsensorState()) { + handleOffTimer(); + } +} + +void PIRsensorSwitch::addToJsonInfo(JsonObject &root) +{ + JsonObject user = root["u"]; + if (user.isNull()) user = root.createNestedObject("u"); + + bool state = LOW; + for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) + if (PIRsensorPin[i] >= 0) state |= sensorPinState[i]; + + JsonArray infoArr = user.createNestedArray(FPSTR(_name)); + + String uiDomString; + if (enabled) { + if (offTimerStart > 0) { + uiDomString = ""; + unsigned int offSeconds = (m_switchOffDelay - (millis() - offTimerStart)) / 1000; + if (offSeconds >= 3600) { + uiDomString += (offSeconds / 3600); + uiDomString += F("h "); + offSeconds %= 3600; + } + if (offSeconds >= 60) { + uiDomString += (offSeconds / 60); + offSeconds %= 60; + } else if (uiDomString.length() > 0) { + uiDomString += 0; + } + if (uiDomString.length() > 0) { + uiDomString += F("min "); + } + uiDomString += (offSeconds); + infoArr.add(uiDomString + F("s")); + } else { + infoArr.add(state ? F("sensor on") : F("inactive")); + } + } else { + infoArr.add(F("disabled")); + } + + uiDomString = F(" "); + infoArr.add(uiDomString); + + if (enabled) { + JsonObject sensor = root[F("sensor")]; + if (sensor.isNull()) sensor = root.createNestedObject(F("sensor")); + sensor[F("motion")] = state || offTimerStart>0 ? true : false; + } +} + +void PIRsensorSwitch::onStateChange(uint8_t mode) { + if (!initDone) return; + DEBUG_PRINT(F("PIR: offTimerStart=")); DEBUG_PRINTLN(offTimerStart); + if (m_override && PIRtriggered && offTimerStart) { // debounce + // checking PIRtriggered and offTimerStart will prevent cancellation upon On trigger + DEBUG_PRINTLN(F("PIR: Canceled.")); + offTimerStart = 0; + PIRtriggered = false; + } +} + +void PIRsensorSwitch::readFromJsonState(JsonObject &root) +{ + if (!initDone) return; // prevent crash on boot applyPreset() + JsonObject usermod = root[FPSTR(_name)]; + if (!usermod.isNull()) { + if (usermod[FPSTR(_enabled)].is()) { + enabled = usermod[FPSTR(_enabled)].as(); + } + } +} + +void PIRsensorSwitch::addToConfig(JsonObject &root) +{ + JsonObject top = root.createNestedObject(FPSTR(_name)); + top[FPSTR(_enabled)] = enabled; + top[FPSTR(_switchOffDelay)] = m_switchOffDelay / 1000; + JsonArray pinArray = top.createNestedArray("pin"); + for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) pinArray.add(PIRsensorPin[i]); + top[FPSTR(_onPreset)] = m_onPreset; + top[FPSTR(_offPreset)] = m_offPreset; + top[FPSTR(_nightTime)] = m_nightTimeOnly; + top[FPSTR(_mqttOnly)] = m_mqttOnly; + top[FPSTR(_offOnly)] = m_offOnly; + top[FPSTR(_override)] = m_override; + top[FPSTR(_haDiscovery)] = HomeAssistantDiscovery; + top[FPSTR(_domoticzIDX)] = idx; + DEBUG_PRINTLN(F("PIR config saved.")); +} + +void PIRsensorSwitch::appendConfigData() +{ + oappend(F("addInfo('PIRsensorSwitch:HA-discovery',1,'HA=Home Assistant');")); // 0 is field type, 1 is actual field + oappend(F("addInfo('PIRsensorSwitch:override',1,'Cancel timer on change');")); // 0 is field type, 1 is actual field + for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) { + char str[128]; + sprintf_P(str, PSTR("addInfo('PIRsensorSwitch:pin[]',%d,'','#%d');"), i, i); + oappend(str); + } +} + +bool PIRsensorSwitch::readFromConfig(JsonObject &root) +{ + int8_t oldPin[PIR_SENSOR_MAX_SENSORS]; + for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) { + oldPin[i] = PIRsensorPin[i]; + PIRsensorPin[i] = -1; + } + + DEBUG_PRINT(FPSTR(_name)); + JsonObject top = root[FPSTR(_name)]; + if (top.isNull()) { + DEBUG_PRINTLN(F(": No config found. (Using defaults.)")); + return false; + } + + JsonArray pins = top["pin"]; + if (!pins.isNull()) { + for (size_t i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) + if (i < pins.size()) PIRsensorPin[i] = pins[i] | PIRsensorPin[i]; + } else { + PIRsensorPin[0] = top["pin"] | oldPin[0]; + } + + enabled = top[FPSTR(_enabled)] | enabled; + + m_switchOffDelay = (top[FPSTR(_switchOffDelay)] | m_switchOffDelay/1000) * 1000; + + m_onPreset = top[FPSTR(_onPreset)] | m_onPreset; + m_onPreset = max(0,min(250,(int)m_onPreset)); + m_offPreset = top[FPSTR(_offPreset)] | m_offPreset; + m_offPreset = max(0,min(250,(int)m_offPreset)); + + m_nightTimeOnly = top[FPSTR(_nightTime)] | m_nightTimeOnly; + m_mqttOnly = top[FPSTR(_mqttOnly)] | m_mqttOnly; + m_offOnly = top[FPSTR(_offOnly)] | m_offOnly; + m_override = top[FPSTR(_override)] | m_override; + HomeAssistantDiscovery = top[FPSTR(_haDiscovery)] | HomeAssistantDiscovery; + idx = top[FPSTR(_domoticzIDX)] | idx; + + if (!initDone) { + // reading config prior to setup() + DEBUG_PRINTLN(F(" config loaded.")); + } else { + for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) + if (oldPin[i] >= 0) PinManager::deallocatePin(oldPin[i], PinOwner::UM_PIR); + setup(); + DEBUG_PRINTLN(F(" config (re)loaded.")); + } + // use "return !top["newestParameter"].isNull();" when updating Usermod with new features + return !(pins.isNull() || pins.size() != PIR_SENSOR_MAX_SENSORS); +} + + +static PIRsensorSwitch pir_sensor_switch; REGISTER_USERMOD(pir_sensor_switch); \ No newline at end of file diff --git a/usermods/PWM_fan/PWM_fan.cpp b/usermods/PWM_fan/PWM_fan.cpp index a0939f0854..4d8d5e4492 100644 --- a/usermods/PWM_fan/PWM_fan.cpp +++ b/usermods/PWM_fan/PWM_fan.cpp @@ -387,6 +387,11 @@ class PWMFanUsermod : public Usermod { uint16_t getId() override { return USERMOD_ID_PWM_FAN; } + + const char* getName() override + { + return FPSTR(_name); + } }; // strings to reduce flash memory usage (used more than twice) diff --git a/usermods/boblight/boblight.cpp b/usermods/boblight/boblight.cpp index 5980443d37..dd64b22792 100644 --- a/usermods/boblight/boblight.cpp +++ b/usermods/boblight/boblight.cpp @@ -359,6 +359,11 @@ class BobLightUsermod : public Usermod { uint16_t getId() override { return USERMOD_ID_BOBLIGHT; } + const char* getName() override + { + return FPSTR(_name); + } + }; // strings to reduce flash memory usage (used more than twice) diff --git a/usermods/deep_sleep/deep_sleep.cpp b/usermods/deep_sleep/deep_sleep.cpp index f6f3604fba..25e2de00cc 100644 --- a/usermods/deep_sleep/deep_sleep.cpp +++ b/usermods/deep_sleep/deep_sleep.cpp @@ -218,6 +218,11 @@ void addToConfig(JsonObject& root) override return USERMOD_ID_DEEP_SLEEP; } + const char* getName() override + { + return FPSTR(_name); + } + }; // add more strings here to reduce flash memory usage diff --git a/usermods/mpu6050_imu/mpu6050_imu.cpp b/usermods/mpu6050_imu/mpu6050_imu.cpp index 6df5d64e12..224c0538bb 100644 --- a/usermods/mpu6050_imu/mpu6050_imu.cpp +++ b/usermods/mpu6050_imu/mpu6050_imu.cpp @@ -432,6 +432,11 @@ class MPU6050Driver : public Usermod { return USERMOD_ID_IMU; } + const char* getName() override + { + return FPSTR(_name); + } + }; diff --git a/usermods/multi_relay/multi_relay.cpp b/usermods/multi_relay/multi_relay.cpp index 4cbdb2fe39..3a396b01e7 100644 --- a/usermods/multi_relay/multi_relay.cpp +++ b/usermods/multi_relay/multi_relay.cpp @@ -146,6 +146,11 @@ class MultiRelay : public Usermod { */ inline uint16_t getId() override { return USERMOD_ID_MULTI_RELAY; } + const char* getName() override + { + return FPSTR(_name); + } + /** * switch relay on/off */ diff --git a/usermods/quinled-an-penta/quinled-an-penta.cpp b/usermods/quinled-an-penta/quinled-an-penta.cpp index a3b452bf18..b99ffbc6eb 100644 --- a/usermods/quinled-an-penta/quinled-an-penta.cpp +++ b/usermods/quinled-an-penta/quinled-an-penta.cpp @@ -687,6 +687,11 @@ class QuinLEDAnPentaUsermod : public Usermod { return USERMOD_ID_QUINLED_AN_PENTA; } + + const char* getName() override + { + return FPSTR(_name); + } }; // strings to reduce flash memory usage (used more than twice) diff --git a/usermods/rgb-rotary-encoder/rgb-rotary-encoder.cpp b/usermods/rgb-rotary-encoder/rgb-rotary-encoder.cpp index 6be3a92640..ad41fc520d 100644 --- a/usermods/rgb-rotary-encoder/rgb-rotary-encoder.cpp +++ b/usermods/rgb-rotary-encoder/rgb-rotary-encoder.cpp @@ -328,6 +328,11 @@ class RgbRotaryEncoderUsermod : public Usermod return USERMOD_RGB_ROTARY_ENCODER; } + const char* getName() override + { + return FPSTR(_name); + } + //More methods can be added in the future, this example will then be extended. //Your usermod will remain compatible as it does not need to implement all methods from the Usermod base class! }; diff --git a/usermods/sd_card/sd_card.cpp b/usermods/sd_card/sd_card.cpp index 4e68b97a34..efabd69763 100644 --- a/usermods/sd_card/sd_card.cpp +++ b/usermods/sd_card/sd_card.cpp @@ -132,6 +132,11 @@ class UsermodSdCard : public Usermod { return USERMOD_ID_SD_CARD; } + const char* getName() override + { + return FPSTR(_name); + } + void addToConfig(JsonObject& root) { #ifdef WLED_USE_SD_SPI diff --git a/usermods/udp_name_sync/udp_name_sync.cpp b/usermods/udp_name_sync/udp_name_sync.cpp index b31b856983..1c2d291717 100644 --- a/usermods/udp_name_sync/udp_name_sync.cpp +++ b/usermods/udp_name_sync/udp_name_sync.cpp @@ -79,6 +79,10 @@ class UdpNameSync : public Usermod { DEBUG_PRINT(F("UdpNameSync: set segment name")); return true; } + + const char* getName() override { + return FPSTR(_name); + } }; static UdpNameSync udp_name_sync; diff --git a/usermods/usermod_v2_auto_save/usermod_v2_auto_save.cpp b/usermods/usermod_v2_auto_save/usermod_v2_auto_save.cpp index 1b97ea94da..c16cd43e29 100644 --- a/usermods/usermod_v2_auto_save/usermod_v2_auto_save.cpp +++ b/usermods/usermod_v2_auto_save/usermod_v2_auto_save.cpp @@ -265,6 +265,11 @@ class AutoSaveUsermod : public Usermod { uint16_t getId() { return USERMOD_ID_AUTO_SAVE; } + + const char* getName() override + { + return FPSTR(_name); + } }; // strings to reduce flash memory usage (used more than twice) diff --git a/usermods/usermod_v2_brightness_follow_sun/usermod_v2_brightness_follow_sun.cpp b/usermods/usermod_v2_brightness_follow_sun/usermod_v2_brightness_follow_sun.cpp index ff97cba468..d598777553 100644 --- a/usermods/usermod_v2_brightness_follow_sun/usermod_v2_brightness_follow_sun.cpp +++ b/usermods/usermod_v2_brightness_follow_sun/usermod_v2_brightness_follow_sun.cpp @@ -39,6 +39,11 @@ class UsermodBrightnessFollowSun : public Usermod return USERMOD_ID_BRIGHTNESS_FOLLOW_SUN; } + const char* getName() override + { + return FPSTR(_name); + } + void update() { if (sunrise == 0 || sunset == 0 || localTime == 0) diff --git a/usermods/usermod_v2_klipper_percentage/usermod_v2_klipper_percentage.cpp b/usermods/usermod_v2_klipper_percentage/usermod_v2_klipper_percentage.cpp index 71c5c45f3f..3e3b332f4f 100644 --- a/usermods/usermod_v2_klipper_percentage/usermod_v2_klipper_percentage.cpp +++ b/usermods/usermod_v2_klipper_percentage/usermod_v2_klipper_percentage.cpp @@ -215,6 +215,11 @@ class klipper_percentage : public Usermod { return USERMOD_ID_KLIPPER; } + + const char* getName() override + { + return FPSTR(_name); + } }; const char klipper_percentage::_name[] PROGMEM = "Klipper_Percentage"; const char klipper_percentage::_enabled[] PROGMEM = "enabled"; diff --git a/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.cpp b/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.cpp index 79ce3f85c9..60537bbb87 100644 --- a/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.cpp +++ b/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.cpp @@ -288,6 +288,11 @@ class RotaryEncoderUIUsermod : public Usermod { * This could be used in the future for the system to determine whether your usermod is installed. */ uint16_t getId() override { return USERMOD_ID_ROTARY_ENC_UI; } + + const char* getName() override + { + return FPSTR(_name); + } /** * Enable/Disable the usermod */ diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h index 4bbedfacb0..788e61dec0 100644 --- a/wled00/fcn_declare.h +++ b/wled00/fcn_declare.h @@ -321,6 +321,7 @@ class Usermod { virtual void onUpdateBegin(bool) {} // fired prior to and after unsuccessful firmware update virtual void onStateChange(uint8_t mode) {} // fired upon WLED state change virtual uint16_t getId() {return USERMOD_ID_UNSPECIFIED;} + virtual const char* getName() { return nullptr; } // get usermod name // API shims private: @@ -361,6 +362,7 @@ namespace UsermodManager { void onUpdateBegin(bool); void onStateChange(uint8_t); Usermod* lookup(uint16_t mod_id); + const char* getName(uint16_t mod_id); size_t getModCount(); }; diff --git a/wled00/um_manager.cpp b/wled00/um_manager.cpp index 647757ad6f..31329a04c1 100644 --- a/wled00/um_manager.cpp +++ b/wled00/um_manager.cpp @@ -87,6 +87,17 @@ Usermod* UsermodManager::lookup(uint16_t mod_id) { return nullptr; } +/* + * Get usermod name by ID. + */ +const char* UsermodManager::getName(uint16_t mod_id) { + Usermod* um = lookup(mod_id); + if (um != nullptr) { + return um->getName(); + } + return nullptr; +} + size_t UsermodManager::getModCount() { return getCount(); }; /* Usermod v2 interface shim for oappend */ From 39f03cab7c0f61c317f355a71b0c8766685ce7cd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 27 Dec 2025 15:25:11 +0000 Subject: [PATCH 03/13] Add _name[] string and getName() to all remaining usermods Co-authored-by: DedeHai <6280424+DedeHai@users.noreply.github.com> --- usermods/Analog_Clock/Analog_Clock.cpp | 10 +++++++++- usermods/BME68X_v2/BME68X_v2.cpp | 12 ++++++++++++ usermods/Cronixie/Cronixie.cpp | 10 +++++++++- usermods/DHT/DHT.cpp | 10 +++++++++- .../usermod_Fix_unreachable_netservices.cpp | 10 +++++++++- usermods/MY9291/MY9291.cpp | 10 +++++++++- usermods/RTC/RTC.cpp | 10 +++++++++- usermods/ST7789_display/ST7789_display.cpp | 10 +++++++++- usermods/VL53L0X_gestures/VL53L0X_gestures.cpp | 10 +++++++++- usermods/buzzer/buzzer.cpp | 10 +++++++++- usermods/pixels_dice_tray/pixels_dice_tray.cpp | 10 +++++++++- usermods/pwm_outputs/pwm_outputs.cpp | 10 +++++++++- usermods/sensors_to_mqtt/sensors_to_mqtt.cpp | 10 +++++++++- .../seven_segment_display/seven_segment_display.cpp | 10 +++++++++- .../seven_segment_display_reloaded.cpp | 6 ++++++ usermods/smartnest/smartnest.cpp | 10 +++++++++- usermods/stairway_wipe_basic/stairway_wipe_basic.cpp | 10 +++++++++- usermods/user_fx/user_fx.cpp | 10 +++++++++- .../usermod_rotary_brightness_color.cpp | 10 +++++++++- usermods/usermod_v2_RF433/usermod_v2_RF433.cpp | 10 +++++++++- .../usermod_v2_animartrix/usermod_v2_animartrix.cpp | 5 +++++ .../usermod_v2_ping_pong_clock.cpp | 10 +++++++++- .../usermod_v2_word_clock/usermod_v2_word_clock.cpp | 10 +++++++++- usermods/wireguard/wireguard.cpp | 10 +++++++++- usermods/wizlights/wizlights.cpp | 10 +++++++++- usermods/word-clock-matrix/word-clock-matrix.cpp | 10 +++++++++- 26 files changed, 230 insertions(+), 23 deletions(-) diff --git a/usermods/Analog_Clock/Analog_Clock.cpp b/usermods/Analog_Clock/Analog_Clock.cpp index d3a2b73b8d..16a43c28fe 100644 --- a/usermods/Analog_Clock/Analog_Clock.cpp +++ b/usermods/Analog_Clock/Analog_Clock.cpp @@ -7,7 +7,9 @@ extern Timezone* tz; class AnalogClockUsermod : public Usermod { private: - static constexpr uint32_t refreshRate = 50; // per second + + static const char _name[]; +static constexpr uint32_t refreshRate = 50; // per second static constexpr uint32_t refreshDelay = 1000 / refreshRate; struct Segment { @@ -252,8 +254,14 @@ class AnalogClockUsermod : public Usermod { uint16_t getId() override { return USERMOD_ID_ANALOG_CLOCK; } + + const char* getName() override { + return FPSTR(_name); + } }; +const char AnalogClockUsermod::_name[] PROGMEM = "Analog Clock"; + static AnalogClockUsermod analog_clock; REGISTER_USERMOD(analog_clock); \ No newline at end of file diff --git a/usermods/BME68X_v2/BME68X_v2.cpp b/usermods/BME68X_v2/BME68X_v2.cpp index 63bada5af0..370a8b67fa 100644 --- a/usermods/BME68X_v2/BME68X_v2.cpp +++ b/usermods/BME68X_v2/BME68X_v2.cpp @@ -74,6 +74,7 @@ private: /* Private: Functions */ + static const char _name[]; void HomeAssistantDiscovery(); void MQTT_PublishHASensor(const String& name, const String& deviceClass, const String& unitOfMeasurement, const int8_t& digs, const uint8_t& option = 0); void MQTT_publish(const char* topic, const float& value, const int8_t& dig); @@ -864,6 +865,15 @@ return USERMOD_ID_BME68X; } + /** + * @brief Called by WLED: Returns the user module name + * + * @return const char* User module name + */ + const char* UsermodBME68X::getName() { + return FPSTR(_name); + } + /** * @brief Returns the current temperature in the scale which is choosen in settings @@ -1110,5 +1120,7 @@ } + const char UsermodBME68X::_name[] PROGMEM = "BME68X"; + static UsermodBME68X bme68x_v2; REGISTER_USERMOD(bme68x_v2); \ No newline at end of file diff --git a/usermods/Cronixie/Cronixie.cpp b/usermods/Cronixie/Cronixie.cpp index e0a3bbee7a..dd05c5da04 100644 --- a/usermods/Cronixie/Cronixie.cpp +++ b/usermods/Cronixie/Cronixie.cpp @@ -2,7 +2,9 @@ class UsermodCronixie : public Usermod { private: - unsigned long lastTime = 0; + + static const char _name[]; +unsigned long lastTime = 0; char cronixieDisplay[7] = "HHMMSS"; byte _digitOut[6] = {10,10,10,10,10,10}; byte dP[6] = {255, 255, 255, 255, 255, 255}; @@ -297,7 +299,13 @@ class UsermodCronixie : public Usermod { { return USERMOD_ID_CRONIXIE; } + + const char* getName() override { + return FPSTR(_name); + } }; +const char UsermodCronixie::_name[] PROGMEM = "Cronixie"; + static UsermodCronixie cronixie; REGISTER_USERMOD(cronixie); \ No newline at end of file diff --git a/usermods/DHT/DHT.cpp b/usermods/DHT/DHT.cpp index 2ed3dd0ace..a66d3b7f0b 100644 --- a/usermods/DHT/DHT.cpp +++ b/usermods/DHT/DHT.cpp @@ -59,7 +59,9 @@ DHT_nonblocking dht_sensor(DHTPIN, DHTTYPE); class UsermodDHT : public Usermod { private: - unsigned long nextReadTime = 0; + + static const char _name[]; +unsigned long nextReadTime = 0; unsigned long lastReadTime = 0; float humidity, temperature = 0; bool initializing = true; @@ -242,8 +244,14 @@ class UsermodDHT : public Usermod { return USERMOD_ID_DHT; } + const char* getName() override { + return FPSTR(_name); + } + }; +const char UsermodDHT::_name[] PROGMEM = "DHT"; + static UsermodDHT dht; REGISTER_USERMOD(dht); \ No newline at end of file diff --git a/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp b/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp index 7fb8e97982..5738e3ec64 100644 --- a/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp +++ b/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp @@ -26,7 +26,9 @@ class FixUnreachableNetServices : public Usermod { private: - //Private class members. You can declare variables and functions only accessible to your usermod here + + static const char _name[]; +//Private class members. You can declare variables and functions only accessible to your usermod here unsigned long m_lastTime = 0; // declare required variables @@ -159,8 +161,14 @@ Delay > sequence_ {}; public: @@ -77,7 +79,13 @@ class BuzzerUsermod : public Usermod { { return USERMOD_ID_BUZZER; } + + const char* getName() override { + return FPSTR(_name); + } }; +const char BuzzerUsermod::_name[] PROGMEM = "Buzzer"; + static BuzzerUsermod buzzer; REGISTER_USERMOD(buzzer); \ No newline at end of file diff --git a/usermods/pixels_dice_tray/pixels_dice_tray.cpp b/usermods/pixels_dice_tray/pixels_dice_tray.cpp index 2e97aff650..1f109d6bc3 100644 --- a/usermods/pixels_dice_tray/pixels_dice_tray.cpp +++ b/usermods/pixels_dice_tray/pixels_dice_tray.cpp @@ -39,7 +39,9 @@ class PixelsDiceTrayUsermod : public Usermod { private: - bool enabled = true; + + static const char _name[]; +bool enabled = true; DiceUpdate dice_update; @@ -527,11 +529,17 @@ class PixelsDiceTrayUsermod : public Usermod { */ uint16_t getId() { return USERMOD_ID_PIXELS_DICE_TRAY; } + const char* getName() override { + return FPSTR(_name); + } + // More methods can be added in the future, this example will then be // extended. Your usermod will remain compatible as it does not need to // implement all methods from the Usermod base class! }; +const char PixelsDiceTrayUsermod::_name[] PROGMEM = "Pixels Dice Tray"; + static PixelsDiceTrayUsermod pixels_dice_tray; REGISTER_USERMOD(pixels_dice_tray); \ No newline at end of file diff --git a/usermods/pwm_outputs/pwm_outputs.cpp b/usermods/pwm_outputs/pwm_outputs.cpp index d94f1d848f..2664e4b746 100644 --- a/usermods/pwm_outputs/pwm_outputs.cpp +++ b/usermods/pwm_outputs/pwm_outputs.cpp @@ -211,8 +211,14 @@ class PwmOutputsUsermod : public Usermod { return USERMOD_ID_PWM_OUTPUTS; } + const char* getName() override { + return FPSTR(_name); + } + private: - PwmOutput pwms_[USERMOD_PWM_OUTPUT_PINS]; + + static const char _name[]; +PwmOutput pwms_[USERMOD_PWM_OUTPUT_PINS]; }; @@ -220,5 +226,7 @@ const char PwmOutputsUsermod::USERMOD_NAME[] PROGMEM = "PwmOutputs"; const char PwmOutputsUsermod::PWM_STATE_NAME[] PROGMEM = "pwm"; +const char PwmOutputsUsermod::_name[] PROGMEM = "PWM Outputs"; + static PwmOutputsUsermod pwm_outputs; REGISTER_USERMOD(pwm_outputs); \ No newline at end of file diff --git a/usermods/sensors_to_mqtt/sensors_to_mqtt.cpp b/usermods/sensors_to_mqtt/sensors_to_mqtt.cpp index 5f7da97a98..7c89dbdf77 100644 --- a/usermods/sensors_to_mqtt/sensors_to_mqtt.cpp +++ b/usermods/sensors_to_mqtt/sensors_to_mqtt.cpp @@ -9,6 +9,8 @@ #error "This user mod requires MQTT to be enabled." #endif +const char UserMod_SensorsToMQTT::_name[] PROGMEM = "Sensors to MQTT"; + static Adafruit_BMP280 bmp; static Adafruit_Si7021 si7021; static Adafruit_CCS811 ccs811; @@ -16,7 +18,9 @@ static Adafruit_CCS811 ccs811; class UserMod_SensorsToMQTT : public Usermod { private: - bool initialized = false; + + static const char _name[]; +bool initialized = false; bool mqttInitialized = false; float SensorPressure = 0; float SensorTemperature = 0; @@ -274,6 +278,10 @@ class UserMod_SensorsToMQTT : public Usermod } } } + + const char* getName() override { + return FPSTR(_name); + } }; diff --git a/usermods/seven_segment_display/seven_segment_display.cpp b/usermods/seven_segment_display/seven_segment_display.cpp index 13a6306be5..fbf7b00a43 100644 --- a/usermods/seven_segment_display/seven_segment_display.cpp +++ b/usermods/seven_segment_display/seven_segment_display.cpp @@ -10,7 +10,9 @@ class SevenSegmentDisplay : public Usermod #define WLED_SS_BUFFLEN 6 #define REFRESHTIME 497 private: - //Runtime variables. + + static const char _name[]; +//Runtime variables. unsigned long lastRefresh = 0; unsigned long lastCharacterStep = 0; String ssDisplayBuffer = ""; @@ -486,6 +488,10 @@ class SevenSegmentDisplay : public Usermod { return USERMOD_ID_SEVEN_SEGMENT_DISPLAY; } + + const char* getName() override { + return FPSTR(_name); + } }; const char SevenSegmentDisplay::_str_perSegment[] PROGMEM = "perSegment"; @@ -498,5 +504,7 @@ const char SevenSegmentDisplay::_str_displayMask[] PROGMEM = "displayMask"; const char SevenSegmentDisplay::_str_displayMsg[] PROGMEM = "displayMsg"; const char SevenSegmentDisplay::_str_sevenSeg[] PROGMEM = "sevenSeg"; +const char SevenSegmentDisplay::_name[] PROGMEM = "Seven Segment Display"; + static SevenSegmentDisplay seven_segment_display; REGISTER_USERMOD(seven_segment_display); \ No newline at end of file diff --git a/usermods/seven_segment_display_reloaded/seven_segment_display_reloaded.cpp b/usermods/seven_segment_display_reloaded/seven_segment_display_reloaded.cpp index 893e061bc8..dfc8123e3a 100644 --- a/usermods/seven_segment_display_reloaded/seven_segment_display_reloaded.cpp +++ b/usermods/seven_segment_display_reloaded/seven_segment_display_reloaded.cpp @@ -15,6 +15,7 @@ class UsermodSSDR : public Usermod { //#define REFRESHTIME 497 private: + static const char _name[]; //Runtime variables. unsigned long umSSDRLastRefresh = 0; unsigned long umSSDRResfreshTime = 3000; @@ -579,8 +580,13 @@ class UsermodSSDR : public Usermod { uint16_t getId() { return USERMOD_ID_SSDR; } + + const char* getName() { + return FPSTR(_name); + } }; +const char UsermodSSDR::_name[] PROGMEM = "Seven Segment Display Reloaded"; const char UsermodSSDR::_str_name[] PROGMEM = "UsermodSSDR"; const char UsermodSSDR::_str_timeEnabled[] PROGMEM = "enabled"; const char UsermodSSDR::_str_inverted[] PROGMEM = "inverted"; diff --git a/usermods/smartnest/smartnest.cpp b/usermods/smartnest/smartnest.cpp index d0cb92dcfd..e5160be24b 100644 --- a/usermods/smartnest/smartnest.cpp +++ b/usermods/smartnest/smartnest.cpp @@ -7,7 +7,9 @@ class Smartnest : public Usermod { private: - bool initialized = false; + + static const char _name[]; +bool initialized = false; unsigned long lastMqttReport = 0; unsigned long mqttReportInterval = 60000; // Report every minute @@ -171,6 +173,10 @@ class Smartnest : public Usermod return USERMOD_ID_SMARTNEST; } + const char* getName() override { + return FPSTR(_name); + } + /** * setup() is called once at startup to initialize the usermod. */ @@ -203,5 +209,7 @@ class Smartnest : public Usermod }; +const char Smartnest::_name[] PROGMEM = "Smartnest"; + static Smartnest smartnest; REGISTER_USERMOD(smartnest); \ No newline at end of file diff --git a/usermods/stairway_wipe_basic/stairway_wipe_basic.cpp b/usermods/stairway_wipe_basic/stairway_wipe_basic.cpp index cddd655d6d..bd80814f93 100644 --- a/usermods/stairway_wipe_basic/stairway_wipe_basic.cpp +++ b/usermods/stairway_wipe_basic/stairway_wipe_basic.cpp @@ -13,7 +13,9 @@ class StairwayWipeUsermod : public Usermod { private: - //Private class members. You can declare variables and functions only accessible to your usermod here + + static const char _name[]; +//Private class members. You can declare variables and functions only accessible to your usermod here unsigned long lastTime = 0; byte wipeState = 0; //0: inactive 1: wiping 2: solid unsigned long timeStaticStart = 0; @@ -89,6 +91,10 @@ void setup() { return USERMOD_ID_STAIRWAY_WIPE; } + const char* getName() override { + return FPSTR(_name); + } + void startWipe() { @@ -128,5 +134,7 @@ void setup() { }; +const char StairwayWipeUsermod::_name[] PROGMEM = "Stairway Wipe"; + static StairwayWipeUsermod stairway_wipe_basic; REGISTER_USERMOD(stairway_wipe_basic); \ No newline at end of file diff --git a/usermods/user_fx/user_fx.cpp b/usermods/user_fx/user_fx.cpp index da6937c87d..8c269666ab 100644 --- a/usermods/user_fx/user_fx.cpp +++ b/usermods/user_fx/user_fx.cpp @@ -95,7 +95,9 @@ static const char _data_FX_MODE_DIFFUSIONFIRE[] PROGMEM = "Diffusion Fire@!,Spar class UserFxUsermod : public Usermod { private: - public: + + static const char _name[]; +public: void setup() override { strip.addEffect(255, &mode_diffusionfire, _data_FX_MODE_DIFFUSIONFIRE); @@ -111,7 +113,13 @@ class UserFxUsermod : public Usermod { } void loop() override {} // nothing to do in the loop uint16_t getId() override { return USERMOD_ID_USER_FX; } + + const char* getName() override { + return FPSTR(_name); + } }; +const char UserFxUsermod::_name[] PROGMEM = "User FX"; + static UserFxUsermod user_fx; REGISTER_USERMOD(user_fx); diff --git a/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.cpp b/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.cpp index 0a485152f1..14891462f0 100644 --- a/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.cpp +++ b/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.cpp @@ -5,7 +5,9 @@ class RotaryEncoderBrightnessColor : public Usermod { private: - //Private class members. You can declare variables and functions only accessible to your usermod here + + static const char _name[]; +//Private class members. You can declare variables and functions only accessible to your usermod here unsigned long lastTime = 0; unsigned long currentTime; unsigned long loopTime; @@ -184,8 +186,14 @@ class RotaryEncoderBrightnessColor : public Usermod return configComplete; } + + const char* getName() override { + return FPSTR(_name); + } }; +const char RotaryEncoderBrightnessColor::_name[] PROGMEM = "Rotary Brightness Color"; + static RotaryEncoderBrightnessColor usermod_rotary_brightness_color; REGISTER_USERMOD(usermod_rotary_brightness_color); \ No newline at end of file diff --git a/usermods/usermod_v2_RF433/usermod_v2_RF433.cpp b/usermods/usermod_v2_RF433/usermod_v2_RF433.cpp index 9ac6c416d1..df9d28c9a8 100644 --- a/usermods/usermod_v2_RF433/usermod_v2_RF433.cpp +++ b/usermods/usermod_v2_RF433/usermod_v2_RF433.cpp @@ -7,7 +7,9 @@ class RF433Usermod : public Usermod { private: - RCSwitch mySwitch = RCSwitch(); + + static const char _name[]; +RCSwitch mySwitch = RCSwitch(); unsigned long lastCommand = 0; unsigned long lastTime = 0; @@ -118,6 +120,10 @@ class RF433Usermod : public Usermod return USERMOD_ID_RF433; } + const char* getName() override { + return FPSTR(_name); + } + // this function follows the same principle as decodeIRJson() / remoteJson() bool remoteJson433(int button) { @@ -179,5 +185,7 @@ const char RF433Usermod::_modName[] PROGMEM = "RF433 Remote"; const char RF433Usermod::_modEnabled[] PROGMEM = "Enabled"; const char RF433Usermod::_receivePin[] PROGMEM = "RX Pin"; +const char RF433Usermod::_name[] PROGMEM = "RF433"; + static RF433Usermod usermod_v2_RF433; REGISTER_USERMOD(usermod_v2_RF433); diff --git a/usermods/usermod_v2_animartrix/usermod_v2_animartrix.cpp b/usermods/usermod_v2_animartrix/usermod_v2_animartrix.cpp index d2968f2fbd..0373664006 100644 --- a/usermods/usermod_v2_animartrix/usermod_v2_animartrix.cpp +++ b/usermods/usermod_v2_animartrix/usermod_v2_animartrix.cpp @@ -448,6 +448,11 @@ class AnimartrixUsermod : public Usermod { return USERMOD_ID_ANIMARTRIX; } + const char* getName() + { + return _name; + } + }; static AnimartrixUsermod animartrix_module("Animartrix", false); diff --git a/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.cpp b/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.cpp index c6632b53a0..cd20225a35 100644 --- a/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.cpp +++ b/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.cpp @@ -3,7 +3,9 @@ class PingPongClockUsermod : public Usermod { private: - // Private class members. You can declare variables and functions only accessible to your usermod here + + static const char _name[]; +// Private class members. You can declare variables and functions only accessible to your usermod here unsigned long lastTime = 0; bool colonOn = true; @@ -114,8 +116,14 @@ class PingPongClockUsermod : public Usermod return USERMOD_ID_PING_PONG_CLOCK; } + const char* getName() override { + return FPSTR(_name); + } + }; +const char PingPongClockUsermod::_name[] PROGMEM = "Ping Pong Clock"; + static PingPongClockUsermod usermod_v2_ping_pong_clock; REGISTER_USERMOD(usermod_v2_ping_pong_clock); \ No newline at end of file diff --git a/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp b/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp index 5100da180d..1e0a24635c 100644 --- a/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp +++ b/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp @@ -15,7 +15,9 @@ class WordClockUsermod : public Usermod { private: - unsigned long lastTime = 0; + + static const char _name[]; +unsigned long lastTime = 0; int lastTimeMinutes = -1; // set your config variables to their boot default value (this can also be done in readFromConfig() or a constructor if you prefer) @@ -500,9 +502,15 @@ class WordClockUsermod : public Usermod return USERMOD_ID_WORDCLOCK; } + const char* getName() override { + return FPSTR(_name); + } + //More methods can be added in the future, this example will then be extended. //Your usermod will remain compatible as it does not need to implement all methods from the Usermod base class! }; +const char WordClockUsermod::_name[] PROGMEM = "Word Clock"; + static WordClockUsermod usermod_v2_word_clock; REGISTER_USERMOD(usermod_v2_word_clock); \ No newline at end of file diff --git a/usermods/wireguard/wireguard.cpp b/usermods/wireguard/wireguard.cpp index f88bfeb32b..4f5f90f919 100644 --- a/usermods/wireguard/wireguard.cpp +++ b/usermods/wireguard/wireguard.cpp @@ -111,8 +111,14 @@ class WireguardUsermod : public Usermod { uint16_t getId() { return USERMOD_ID_WIREGUARD; } + const char* getName() override { + return FPSTR(_name); + } + private: - WireGuard wg; + + static const char _name[]; +WireGuard wg; char preshared_key[45]; char private_key[45]; IPAddress local_ip; @@ -124,5 +130,7 @@ class WireguardUsermod : public Usermod { unsigned long lastTime = 0; }; +const char WireguardUsermod::_name[] PROGMEM = "Wireguard"; + static WireguardUsermod wireguard; REGISTER_USERMOD(wireguard); \ No newline at end of file diff --git a/usermods/wizlights/wizlights.cpp b/usermods/wizlights/wizlights.cpp index 3ac756b12a..a4a2025636 100644 --- a/usermods/wizlights/wizlights.cpp +++ b/usermods/wizlights/wizlights.cpp @@ -12,7 +12,9 @@ WiFiUDP UDP; class WizLightsUsermod : public Usermod { private: - unsigned long lastTime = 0; + + static const char _name[]; +unsigned long lastTime = 0; long updateInterval; long sendDelay; @@ -153,8 +155,14 @@ class WizLightsUsermod : public Usermod { String getJsonLabel(uint8_t i) {return "WiZ Light IP #" + String(i+1);} uint16_t getId(){return USERMOD_ID_WIZLIGHTS;} + + const char* getName() override { + return FPSTR(_name); + } }; +const char WizLightsUsermod::_name[] PROGMEM = "Wiz Lights"; + static WizLightsUsermod wizlights; REGISTER_USERMOD(wizlights); \ No newline at end of file diff --git a/usermods/word-clock-matrix/word-clock-matrix.cpp b/usermods/word-clock-matrix/word-clock-matrix.cpp index 24f69aadb7..fa632ddc71 100644 --- a/usermods/word-clock-matrix/word-clock-matrix.cpp +++ b/usermods/word-clock-matrix/word-clock-matrix.cpp @@ -10,7 +10,9 @@ class WordClockMatrix : public Usermod { private: - unsigned long lastTime = 0; + + static const char _name[]; +unsigned long lastTime = 0; uint8_t minuteLast = 99; int dayBrightness = 128; int nightBrightness = 16; @@ -332,9 +334,15 @@ class WordClockMatrix : public Usermod return 500; } + const char* getName() override { + return FPSTR(_name); + } + }; +const char WordClockMatrix::_name[] PROGMEM = "Word Clock Matrix"; + static WordClockMatrix word_clock_matrix; REGISTER_USERMOD(word_clock_matrix); \ No newline at end of file From 0a2de0c6429e5f630d458279644c446a51425abb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 27 Dec 2025 15:34:34 +0000 Subject: [PATCH 04/13] Fix code formatting issues in usermods after code review Co-authored-by: DedeHai <6280424+DedeHai@users.noreply.github.com> --- usermods/sensors_to_mqtt/sensors_to_mqtt.cpp | 4 ++-- usermods/user_fx/user_fx.cpp | 3 ++- .../usermod_rotary_brightness_color.cpp | 2 +- usermods/usermod_v2_RF433/usermod_v2_RF433.cpp | 2 +- .../usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.cpp | 2 +- usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp | 2 +- usermods/wireguard/wireguard.cpp | 2 +- usermods/wizlights/wizlights.cpp | 2 +- usermods/word-clock-matrix/word-clock-matrix.cpp | 2 +- 9 files changed, 11 insertions(+), 10 deletions(-) diff --git a/usermods/sensors_to_mqtt/sensors_to_mqtt.cpp b/usermods/sensors_to_mqtt/sensors_to_mqtt.cpp index 7c89dbdf77..9fa41d8fdf 100644 --- a/usermods/sensors_to_mqtt/sensors_to_mqtt.cpp +++ b/usermods/sensors_to_mqtt/sensors_to_mqtt.cpp @@ -9,8 +9,6 @@ #error "This user mod requires MQTT to be enabled." #endif -const char UserMod_SensorsToMQTT::_name[] PROGMEM = "Sensors to MQTT"; - static Adafruit_BMP280 bmp; static Adafruit_Si7021 si7021; static Adafruit_CCS811 ccs811; @@ -285,5 +283,7 @@ bool initialized = false; }; +const char UserMod_SensorsToMQTT::_name[] PROGMEM = "Sensors to MQTT"; + static UserMod_SensorsToMQTT sensors_to_mqtt; REGISTER_USERMOD(sensors_to_mqtt); \ No newline at end of file diff --git a/usermods/user_fx/user_fx.cpp b/usermods/user_fx/user_fx.cpp index 8c269666ab..7487975b72 100644 --- a/usermods/user_fx/user_fx.cpp +++ b/usermods/user_fx/user_fx.cpp @@ -97,7 +97,8 @@ class UserFxUsermod : public Usermod { private: static const char _name[]; -public: + + public: void setup() override { strip.addEffect(255, &mode_diffusionfire, _data_FX_MODE_DIFFUSIONFIRE); diff --git a/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.cpp b/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.cpp index 14891462f0..c1c0d06230 100644 --- a/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.cpp +++ b/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.cpp @@ -7,7 +7,7 @@ class RotaryEncoderBrightnessColor : public Usermod private: static const char _name[]; -//Private class members. You can declare variables and functions only accessible to your usermod here + //Private class members. You can declare variables and functions only accessible to your usermod here unsigned long lastTime = 0; unsigned long currentTime; unsigned long loopTime; diff --git a/usermods/usermod_v2_RF433/usermod_v2_RF433.cpp b/usermods/usermod_v2_RF433/usermod_v2_RF433.cpp index df9d28c9a8..881e63f85a 100644 --- a/usermods/usermod_v2_RF433/usermod_v2_RF433.cpp +++ b/usermods/usermod_v2_RF433/usermod_v2_RF433.cpp @@ -9,7 +9,7 @@ class RF433Usermod : public Usermod private: static const char _name[]; -RCSwitch mySwitch = RCSwitch(); + RCSwitch mySwitch = RCSwitch(); unsigned long lastCommand = 0; unsigned long lastTime = 0; diff --git a/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.cpp b/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.cpp index cd20225a35..1e6c358994 100644 --- a/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.cpp +++ b/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.cpp @@ -5,7 +5,7 @@ class PingPongClockUsermod : public Usermod private: static const char _name[]; -// Private class members. You can declare variables and functions only accessible to your usermod here + // Private class members. You can declare variables and functions only accessible to your usermod here unsigned long lastTime = 0; bool colonOn = true; diff --git a/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp b/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp index 1e0a24635c..89a0e50999 100644 --- a/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp +++ b/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp @@ -17,7 +17,7 @@ class WordClockUsermod : public Usermod private: static const char _name[]; -unsigned long lastTime = 0; + unsigned long lastTime = 0; int lastTimeMinutes = -1; // set your config variables to their boot default value (this can also be done in readFromConfig() or a constructor if you prefer) diff --git a/usermods/wireguard/wireguard.cpp b/usermods/wireguard/wireguard.cpp index 4f5f90f919..d3b0cab910 100644 --- a/usermods/wireguard/wireguard.cpp +++ b/usermods/wireguard/wireguard.cpp @@ -118,7 +118,7 @@ class WireguardUsermod : public Usermod { private: static const char _name[]; -WireGuard wg; + WireGuard wg; char preshared_key[45]; char private_key[45]; IPAddress local_ip; diff --git a/usermods/wizlights/wizlights.cpp b/usermods/wizlights/wizlights.cpp index a4a2025636..526f2ba7ed 100644 --- a/usermods/wizlights/wizlights.cpp +++ b/usermods/wizlights/wizlights.cpp @@ -14,7 +14,7 @@ class WizLightsUsermod : public Usermod { private: static const char _name[]; -unsigned long lastTime = 0; + unsigned long lastTime = 0; long updateInterval; long sendDelay; diff --git a/usermods/word-clock-matrix/word-clock-matrix.cpp b/usermods/word-clock-matrix/word-clock-matrix.cpp index fa632ddc71..a030e914b3 100644 --- a/usermods/word-clock-matrix/word-clock-matrix.cpp +++ b/usermods/word-clock-matrix/word-clock-matrix.cpp @@ -12,7 +12,7 @@ class WordClockMatrix : public Usermod private: static const char _name[]; -unsigned long lastTime = 0; + unsigned long lastTime = 0; uint8_t minuteLast = 99; int dayBrightness = 128; int nightBrightness = 16; From 20b388fd6043102bb67c85f9d068008d44f82f9c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 27 Dec 2025 15:36:06 +0000 Subject: [PATCH 05/13] Additional minor indentation fixes Co-authored-by: DedeHai <6280424+DedeHai@users.noreply.github.com> --- usermods/Analog_Clock/Analog_Clock.cpp | 2 +- usermods/Cronixie/Cronixie.cpp | 2 +- usermods/DHT/DHT.cpp | 2 +- .../usermod_Fix_unreachable_netservices.cpp | 2 +- usermods/MY9291/MY9291.cpp | 2 +- usermods/RTC/RTC.cpp | 2 +- usermods/VL53L0X_gestures/VL53L0X_gestures.cpp | 2 +- usermods/buzzer/buzzer.cpp | 2 +- usermods/pixels_dice_tray/pixels_dice_tray.cpp | 2 +- usermods/pwm_outputs/pwm_outputs.cpp | 2 +- usermods/sensors_to_mqtt/sensors_to_mqtt.cpp | 2 +- usermods/seven_segment_display/seven_segment_display.cpp | 2 +- usermods/smartnest/smartnest.cpp | 2 +- usermods/stairway_wipe_basic/stairway_wipe_basic.cpp | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/usermods/Analog_Clock/Analog_Clock.cpp b/usermods/Analog_Clock/Analog_Clock.cpp index 16a43c28fe..c02f83ea06 100644 --- a/usermods/Analog_Clock/Analog_Clock.cpp +++ b/usermods/Analog_Clock/Analog_Clock.cpp @@ -9,7 +9,7 @@ class AnalogClockUsermod : public Usermod { private: static const char _name[]; -static constexpr uint32_t refreshRate = 50; // per second + static constexpr uint32_t refreshRate = 50; // per second static constexpr uint32_t refreshDelay = 1000 / refreshRate; struct Segment { diff --git a/usermods/Cronixie/Cronixie.cpp b/usermods/Cronixie/Cronixie.cpp index dd05c5da04..2743e00fed 100644 --- a/usermods/Cronixie/Cronixie.cpp +++ b/usermods/Cronixie/Cronixie.cpp @@ -4,7 +4,7 @@ class UsermodCronixie : public Usermod { private: static const char _name[]; -unsigned long lastTime = 0; + unsigned long lastTime = 0; char cronixieDisplay[7] = "HHMMSS"; byte _digitOut[6] = {10,10,10,10,10,10}; byte dP[6] = {255, 255, 255, 255, 255, 255}; diff --git a/usermods/DHT/DHT.cpp b/usermods/DHT/DHT.cpp index a66d3b7f0b..698d905eed 100644 --- a/usermods/DHT/DHT.cpp +++ b/usermods/DHT/DHT.cpp @@ -61,7 +61,7 @@ class UsermodDHT : public Usermod { private: static const char _name[]; -unsigned long nextReadTime = 0; + unsigned long nextReadTime = 0; unsigned long lastReadTime = 0; float humidity, temperature = 0; bool initializing = true; diff --git a/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp b/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp index 5738e3ec64..591a7a3bea 100644 --- a/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp +++ b/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp @@ -28,7 +28,7 @@ class FixUnreachableNetServices : public Usermod private: static const char _name[]; -//Private class members. You can declare variables and functions only accessible to your usermod here + //Private class members. You can declare variables and functions only accessible to your usermod here unsigned long m_lastTime = 0; // declare required variables diff --git a/usermods/MY9291/MY9291.cpp b/usermods/MY9291/MY9291.cpp index c818e75298..a1adbe6bb3 100644 --- a/usermods/MY9291/MY9291.cpp +++ b/usermods/MY9291/MY9291.cpp @@ -15,7 +15,7 @@ class MY9291Usermod : public Usermod { private: static const char _name[]; -my92xx _my92xx = my92xx(MY92XX_MODEL, MY92XX_CHIPS, MY92XX_DI_PIN, MY92XX_DCKI_PIN, MY92XX_COMMAND_DEFAULT); + my92xx _my92xx = my92xx(MY92XX_MODEL, MY92XX_CHIPS, MY92XX_DI_PIN, MY92XX_DCKI_PIN, MY92XX_COMMAND_DEFAULT); public: diff --git a/usermods/RTC/RTC.cpp b/usermods/RTC/RTC.cpp index bc61c26b34..4ca2505d15 100644 --- a/usermods/RTC/RTC.cpp +++ b/usermods/RTC/RTC.cpp @@ -7,7 +7,7 @@ class RTCUsermod : public Usermod { private: static const char _name[]; -unsigned long lastTime = 0; + unsigned long lastTime = 0; bool disabled = false; public: diff --git a/usermods/VL53L0X_gestures/VL53L0X_gestures.cpp b/usermods/VL53L0X_gestures/VL53L0X_gestures.cpp index b3a6593aaa..958d2d64c0 100644 --- a/usermods/VL53L0X_gestures/VL53L0X_gestures.cpp +++ b/usermods/VL53L0X_gestures/VL53L0X_gestures.cpp @@ -38,7 +38,7 @@ class UsermodVL53L0XGestures : public Usermod { private: static const char _name[]; -//Private class members. You can declare variables and functions only accessible to your usermod here + //Private class members. You can declare variables and functions only accessible to your usermod here unsigned long lastTime = 0; VL53L0X sensor; bool enabled = true; diff --git a/usermods/buzzer/buzzer.cpp b/usermods/buzzer/buzzer.cpp index b7ce49f4ee..b754ae2423 100644 --- a/usermods/buzzer/buzzer.cpp +++ b/usermods/buzzer/buzzer.cpp @@ -22,7 +22,7 @@ class BuzzerUsermod : public Usermod { private: static const char _name[]; -unsigned long lastTime_ = 0; + unsigned long lastTime_ = 0; unsigned long delay_ = 0; std::deque> sequence_ {}; public: diff --git a/usermods/pixels_dice_tray/pixels_dice_tray.cpp b/usermods/pixels_dice_tray/pixels_dice_tray.cpp index 1f109d6bc3..bf129d190b 100644 --- a/usermods/pixels_dice_tray/pixels_dice_tray.cpp +++ b/usermods/pixels_dice_tray/pixels_dice_tray.cpp @@ -41,7 +41,7 @@ class PixelsDiceTrayUsermod : public Usermod { private: static const char _name[]; -bool enabled = true; + bool enabled = true; DiceUpdate dice_update; diff --git a/usermods/pwm_outputs/pwm_outputs.cpp b/usermods/pwm_outputs/pwm_outputs.cpp index 2664e4b746..6024575181 100644 --- a/usermods/pwm_outputs/pwm_outputs.cpp +++ b/usermods/pwm_outputs/pwm_outputs.cpp @@ -218,7 +218,7 @@ class PwmOutputsUsermod : public Usermod { private: static const char _name[]; -PwmOutput pwms_[USERMOD_PWM_OUTPUT_PINS]; + PwmOutput pwms_[USERMOD_PWM_OUTPUT_PINS]; }; diff --git a/usermods/sensors_to_mqtt/sensors_to_mqtt.cpp b/usermods/sensors_to_mqtt/sensors_to_mqtt.cpp index 9fa41d8fdf..d9a55b1aec 100644 --- a/usermods/sensors_to_mqtt/sensors_to_mqtt.cpp +++ b/usermods/sensors_to_mqtt/sensors_to_mqtt.cpp @@ -18,7 +18,7 @@ class UserMod_SensorsToMQTT : public Usermod private: static const char _name[]; -bool initialized = false; + bool initialized = false; bool mqttInitialized = false; float SensorPressure = 0; float SensorTemperature = 0; diff --git a/usermods/seven_segment_display/seven_segment_display.cpp b/usermods/seven_segment_display/seven_segment_display.cpp index fbf7b00a43..c2fcac9422 100644 --- a/usermods/seven_segment_display/seven_segment_display.cpp +++ b/usermods/seven_segment_display/seven_segment_display.cpp @@ -12,7 +12,7 @@ class SevenSegmentDisplay : public Usermod private: static const char _name[]; -//Runtime variables. + //Runtime variables. unsigned long lastRefresh = 0; unsigned long lastCharacterStep = 0; String ssDisplayBuffer = ""; diff --git a/usermods/smartnest/smartnest.cpp b/usermods/smartnest/smartnest.cpp index e5160be24b..c47723448a 100644 --- a/usermods/smartnest/smartnest.cpp +++ b/usermods/smartnest/smartnest.cpp @@ -9,7 +9,7 @@ class Smartnest : public Usermod private: static const char _name[]; -bool initialized = false; + bool initialized = false; unsigned long lastMqttReport = 0; unsigned long mqttReportInterval = 60000; // Report every minute diff --git a/usermods/stairway_wipe_basic/stairway_wipe_basic.cpp b/usermods/stairway_wipe_basic/stairway_wipe_basic.cpp index bd80814f93..56cb236e7c 100644 --- a/usermods/stairway_wipe_basic/stairway_wipe_basic.cpp +++ b/usermods/stairway_wipe_basic/stairway_wipe_basic.cpp @@ -15,7 +15,7 @@ class StairwayWipeUsermod : public Usermod { private: static const char _name[]; -//Private class members. You can declare variables and functions only accessible to your usermod here + //Private class members. You can declare variables and functions only accessible to your usermod here unsigned long lastTime = 0; byte wipeState = 0; //0: inactive 1: wiping 2: solid unsigned long timeStaticStart = 0; From 60dce26a6aa201be27a221252deb93680f5879b0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 27 Dec 2025 19:27:18 +0000 Subject: [PATCH 06/13] Add getName() to all remaining usermods and fix BH1750_v2.h unnecessary changes Co-authored-by: DedeHai <6280424+DedeHai@users.noreply.github.com> --- usermods/ADS1115_v2/ADS1115_v2.cpp | 8 + usermods/BH1750_v2/BH1750_v2.h | 194 +++--- usermods/EleksTube_IPS/EleksTube_IPS.cpp | 5 + usermods/SN_Photoresistor/SN_Photoresistor.h | 185 ++--- usermods/Si7021_MQTT_HA/Si7021_MQTT_HA.cpp | 5 + usermods/Temperature/UsermodTemperature.h | 5 + usermods/TetrisAI_v2/TetrisAI_v2.cpp | 8 + usermods/audioreactive/audio_reactive.cpp | 5 + usermods/mpu6050_imu/usermod_gyro_surge.h | 4 + usermods/pov_display/pov_display.cpp | 5 + usermods/sht/ShtUsermod.h | 5 + .../usermod_v2_HttpPullLightControl.h | 5 + .../usermod_v2_four_line_display.h | 633 +++++++++--------- 13 files changed, 566 insertions(+), 501 deletions(-) diff --git a/usermods/ADS1115_v2/ADS1115_v2.cpp b/usermods/ADS1115_v2/ADS1115_v2.cpp index bbf457f486..fe06f764be 100644 --- a/usermods/ADS1115_v2/ADS1115_v2.cpp +++ b/usermods/ADS1115_v2/ADS1115_v2.cpp @@ -118,7 +118,13 @@ class ADS1115Usermod : public Usermod { return USERMOD_ID_ADS1115; } + const char* getName() override + { + return FPSTR(_name); + } + private: + static const char _name[]; static const uint8_t channelsCount = 8; ChannelSettings channelSettings[channelsCount] = { @@ -252,5 +258,7 @@ class ADS1115Usermod : public Usermod { } }; +const char ADS1115Usermod::_name[] PROGMEM = "ADS1115"; + static ADS1115Usermod ads1115_v2; REGISTER_USERMOD(ads1115_v2); \ No newline at end of file diff --git a/usermods/BH1750_v2/BH1750_v2.h b/usermods/BH1750_v2/BH1750_v2.h index 380bb332c7..04c1ed2a52 100644 --- a/usermods/BH1750_v2/BH1750_v2.h +++ b/usermods/BH1750_v2/BH1750_v2.h @@ -1,97 +1,97 @@ - -#pragma once -#include "wled.h" -#include - -#ifdef WLED_DISABLE_MQTT -#error "This user mod requires MQTT to be enabled." -#endif - -// the max frequency to check photoresistor, 10 seconds -#ifndef USERMOD_BH1750_MAX_MEASUREMENT_INTERVAL -#define USERMOD_BH1750_MAX_MEASUREMENT_INTERVAL 10000 -#endif - -// the min frequency to check photoresistor, 500 ms -#ifndef USERMOD_BH1750_MIN_MEASUREMENT_INTERVAL -#define USERMOD_BH1750_MIN_MEASUREMENT_INTERVAL 500 -#endif - -// how many seconds after boot to take first measurement, 10 seconds -#ifndef USERMOD_BH1750_FIRST_MEASUREMENT_AT -#define USERMOD_BH1750_FIRST_MEASUREMENT_AT 10000 -#endif - -// only report if difference grater than offset value -#ifndef USERMOD_BH1750_OFFSET_VALUE -#define USERMOD_BH1750_OFFSET_VALUE 1 -#endif - -class Usermod_BH1750 : public Usermod -{ -private: - int8_t offset = USERMOD_BH1750_OFFSET_VALUE; - - unsigned long maxReadingInterval = USERMOD_BH1750_MAX_MEASUREMENT_INTERVAL; - unsigned long minReadingInterval = USERMOD_BH1750_MIN_MEASUREMENT_INTERVAL; - unsigned long lastMeasurement = UINT32_MAX - (USERMOD_BH1750_MAX_MEASUREMENT_INTERVAL - USERMOD_BH1750_FIRST_MEASUREMENT_AT); - unsigned long lastSend = UINT32_MAX - (USERMOD_BH1750_MAX_MEASUREMENT_INTERVAL - USERMOD_BH1750_FIRST_MEASUREMENT_AT); - // flag to indicate we have finished the first readLightLevel call - // allows this library to report to the user how long until the first - // measurement - bool getLuminanceComplete = false; - - // flag set at startup - bool enabled = true; - - // strings to reduce flash memory usage (used more than twice) - static const char _name[]; - static const char _enabled[]; - static const char _maxReadInterval[]; - static const char _minReadInterval[]; - static const char _offset[]; - static const char _HomeAssistantDiscovery[]; - - bool initDone = false; - bool sensorFound = false; - - // Home Assistant and MQTT - String mqttLuminanceTopic; - bool mqttInitialized = false; - bool HomeAssistantDiscovery = true; // Publish Home Assistant Discovery messages - - BH1750 lightMeter; - float lastLux = -1000; - - // set up Home Assistant discovery entries - void _mqttInitialize(); - - // Create an MQTT Sensor for Home Assistant Discovery purposes, this includes a pointer to the topic that is published to in the Loop. - void _createMqttSensor(const String &name, const String &topic, const String &deviceClass, const String &unitOfMeasurement); - -public: - void setup(); - void loop(); - inline float getIlluminance() { - return (float)lastLux; - } - - void addToJsonInfo(JsonObject &root); - - // (called from set.cpp) stores persistent properties to cfg.json - void addToConfig(JsonObject &root); - - // called before setup() to populate properties from values stored in cfg.json - bool readFromConfig(JsonObject &root); - - inline uint16_t getId() - { - return USERMOD_ID_BH1750; - } - - const char* getName() override - { - return FPSTR(_name); - } - -}; + +#pragma once +#include "wled.h" +#include + +#ifdef WLED_DISABLE_MQTT +#error "This user mod requires MQTT to be enabled." +#endif + +// the max frequency to check photoresistor, 10 seconds +#ifndef USERMOD_BH1750_MAX_MEASUREMENT_INTERVAL +#define USERMOD_BH1750_MAX_MEASUREMENT_INTERVAL 10000 +#endif + +// the min frequency to check photoresistor, 500 ms +#ifndef USERMOD_BH1750_MIN_MEASUREMENT_INTERVAL +#define USERMOD_BH1750_MIN_MEASUREMENT_INTERVAL 500 +#endif + +// how many seconds after boot to take first measurement, 10 seconds +#ifndef USERMOD_BH1750_FIRST_MEASUREMENT_AT +#define USERMOD_BH1750_FIRST_MEASUREMENT_AT 10000 +#endif + +// only report if difference grater than offset value +#ifndef USERMOD_BH1750_OFFSET_VALUE +#define USERMOD_BH1750_OFFSET_VALUE 1 +#endif + +class Usermod_BH1750 : public Usermod +{ +private: + int8_t offset = USERMOD_BH1750_OFFSET_VALUE; + + unsigned long maxReadingInterval = USERMOD_BH1750_MAX_MEASUREMENT_INTERVAL; + unsigned long minReadingInterval = USERMOD_BH1750_MIN_MEASUREMENT_INTERVAL; + unsigned long lastMeasurement = UINT32_MAX - (USERMOD_BH1750_MAX_MEASUREMENT_INTERVAL - USERMOD_BH1750_FIRST_MEASUREMENT_AT); + unsigned long lastSend = UINT32_MAX - (USERMOD_BH1750_MAX_MEASUREMENT_INTERVAL - USERMOD_BH1750_FIRST_MEASUREMENT_AT); + // flag to indicate we have finished the first readLightLevel call + // allows this library to report to the user how long until the first + // measurement + bool getLuminanceComplete = false; + + // flag set at startup + bool enabled = true; + + // strings to reduce flash memory usage (used more than twice) + static const char _name[]; + static const char _enabled[]; + static const char _maxReadInterval[]; + static const char _minReadInterval[]; + static const char _offset[]; + static const char _HomeAssistantDiscovery[]; + + bool initDone = false; + bool sensorFound = false; + + // Home Assistant and MQTT + String mqttLuminanceTopic; + bool mqttInitialized = false; + bool HomeAssistantDiscovery = true; // Publish Home Assistant Discovery messages + + BH1750 lightMeter; + float lastLux = -1000; + + // set up Home Assistant discovery entries + void _mqttInitialize(); + + // Create an MQTT Sensor for Home Assistant Discovery purposes, this includes a pointer to the topic that is published to in the Loop. + void _createMqttSensor(const String &name, const String &topic, const String &deviceClass, const String &unitOfMeasurement); + +public: + void setup(); + void loop(); + inline float getIlluminance() { + return (float)lastLux; + } + + void addToJsonInfo(JsonObject &root); + + // (called from set.cpp) stores persistent properties to cfg.json + void addToConfig(JsonObject &root); + + // called before setup() to populate properties from values stored in cfg.json + bool readFromConfig(JsonObject &root); + + inline uint16_t getId() + { + return USERMOD_ID_BH1750; + } + + inline const char* getName() + { + return FPSTR(_name); + } + +}; diff --git a/usermods/EleksTube_IPS/EleksTube_IPS.cpp b/usermods/EleksTube_IPS/EleksTube_IPS.cpp index e8637b0fe8..4b6a234957 100644 --- a/usermods/EleksTube_IPS/EleksTube_IPS.cpp +++ b/usermods/EleksTube_IPS/EleksTube_IPS.cpp @@ -149,6 +149,11 @@ class ElekstubeIPSUsermod : public Usermod { { return USERMOD_ID_ELEKSTUBE_IPS; } + + const char* getName() override + { + return FPSTR(_name); + } }; // strings to reduce flash memory usage (used more than twice) diff --git a/usermods/SN_Photoresistor/SN_Photoresistor.h b/usermods/SN_Photoresistor/SN_Photoresistor.h index 87836c0e49..8500d35a77 100644 --- a/usermods/SN_Photoresistor/SN_Photoresistor.h +++ b/usermods/SN_Photoresistor/SN_Photoresistor.h @@ -1,90 +1,95 @@ -#pragma once -#include "wled.h" - -// the frequency to check photoresistor, 10 seconds -#ifndef USERMOD_SN_PHOTORESISTOR_MEASUREMENT_INTERVAL -#define USERMOD_SN_PHOTORESISTOR_MEASUREMENT_INTERVAL 10000 -#endif - -// how many seconds after boot to take first measurement, 10 seconds -#ifndef USERMOD_SN_PHOTORESISTOR_FIRST_MEASUREMENT_AT -#define USERMOD_SN_PHOTORESISTOR_FIRST_MEASUREMENT_AT 10000 -#endif - -// supplied voltage -#ifndef USERMOD_SN_PHOTORESISTOR_REFERENCE_VOLTAGE -#define USERMOD_SN_PHOTORESISTOR_REFERENCE_VOLTAGE 5 -#endif - -// 10 bits -#ifndef USERMOD_SN_PHOTORESISTOR_ADC_PRECISION -#define USERMOD_SN_PHOTORESISTOR_ADC_PRECISION 1024.0f -#endif - -// resistor size 10K hms -#ifndef USERMOD_SN_PHOTORESISTOR_RESISTOR_VALUE -#define USERMOD_SN_PHOTORESISTOR_RESISTOR_VALUE 10000.0f -#endif - -// only report if difference grater than offset value -#ifndef USERMOD_SN_PHOTORESISTOR_OFFSET_VALUE -#define USERMOD_SN_PHOTORESISTOR_OFFSET_VALUE 5 -#endif - -class Usermod_SN_Photoresistor : public Usermod -{ -private: - float referenceVoltage = USERMOD_SN_PHOTORESISTOR_REFERENCE_VOLTAGE; - float resistorValue = USERMOD_SN_PHOTORESISTOR_RESISTOR_VALUE; - float adcPrecision = USERMOD_SN_PHOTORESISTOR_ADC_PRECISION; - int8_t offset = USERMOD_SN_PHOTORESISTOR_OFFSET_VALUE; - - unsigned long readingInterval = USERMOD_SN_PHOTORESISTOR_MEASUREMENT_INTERVAL; - // set last reading as "40 sec before boot", so first reading is taken after 20 sec - unsigned long lastMeasurement = UINT32_MAX - (USERMOD_SN_PHOTORESISTOR_MEASUREMENT_INTERVAL - USERMOD_SN_PHOTORESISTOR_FIRST_MEASUREMENT_AT); - // flag to indicate we have finished the first getTemperature call - // allows this library to report to the user how long until the first - // measurement - bool getLuminanceComplete = false; - uint16_t lastLDRValue = 65535; - - // flag set at startup - bool disabled = false; - - // strings to reduce flash memory usage (used more than twice) - static const char _name[]; - static const char _enabled[]; - static const char _readInterval[]; - static const char _referenceVoltage[]; - static const char _resistorValue[]; - static const char _adcPrecision[]; - static const char _offset[]; - - uint16_t getLuminance(); - -public: - void setup(); - void loop(); - - uint16_t getLastLDRValue() - { - return lastLDRValue; - } - - void addToJsonInfo(JsonObject &root); - - uint16_t getId() - { - return USERMOD_ID_SN_PHOTORESISTOR; - } - - /** - * addToConfig() (called from set.cpp) stores persistent properties to cfg.json - */ - void addToConfig(JsonObject &root); - - /** - * readFromConfig() is called before setup() to populate properties from values stored in cfg.json - */ - bool readFromConfig(JsonObject &root); -}; +#pragma once +#include "wled.h" + +// the frequency to check photoresistor, 10 seconds +#ifndef USERMOD_SN_PHOTORESISTOR_MEASUREMENT_INTERVAL +#define USERMOD_SN_PHOTORESISTOR_MEASUREMENT_INTERVAL 10000 +#endif + +// how many seconds after boot to take first measurement, 10 seconds +#ifndef USERMOD_SN_PHOTORESISTOR_FIRST_MEASUREMENT_AT +#define USERMOD_SN_PHOTORESISTOR_FIRST_MEASUREMENT_AT 10000 +#endif + +// supplied voltage +#ifndef USERMOD_SN_PHOTORESISTOR_REFERENCE_VOLTAGE +#define USERMOD_SN_PHOTORESISTOR_REFERENCE_VOLTAGE 5 +#endif + +// 10 bits +#ifndef USERMOD_SN_PHOTORESISTOR_ADC_PRECISION +#define USERMOD_SN_PHOTORESISTOR_ADC_PRECISION 1024.0f +#endif + +// resistor size 10K hms +#ifndef USERMOD_SN_PHOTORESISTOR_RESISTOR_VALUE +#define USERMOD_SN_PHOTORESISTOR_RESISTOR_VALUE 10000.0f +#endif + +// only report if difference grater than offset value +#ifndef USERMOD_SN_PHOTORESISTOR_OFFSET_VALUE +#define USERMOD_SN_PHOTORESISTOR_OFFSET_VALUE 5 +#endif + +class Usermod_SN_Photoresistor : public Usermod +{ +private: + float referenceVoltage = USERMOD_SN_PHOTORESISTOR_REFERENCE_VOLTAGE; + float resistorValue = USERMOD_SN_PHOTORESISTOR_RESISTOR_VALUE; + float adcPrecision = USERMOD_SN_PHOTORESISTOR_ADC_PRECISION; + int8_t offset = USERMOD_SN_PHOTORESISTOR_OFFSET_VALUE; + + unsigned long readingInterval = USERMOD_SN_PHOTORESISTOR_MEASUREMENT_INTERVAL; + // set last reading as "40 sec before boot", so first reading is taken after 20 sec + unsigned long lastMeasurement = UINT32_MAX - (USERMOD_SN_PHOTORESISTOR_MEASUREMENT_INTERVAL - USERMOD_SN_PHOTORESISTOR_FIRST_MEASUREMENT_AT); + // flag to indicate we have finished the first getTemperature call + // allows this library to report to the user how long until the first + // measurement + bool getLuminanceComplete = false; + uint16_t lastLDRValue = 65535; + + // flag set at startup + bool disabled = false; + + // strings to reduce flash memory usage (used more than twice) + static const char _name[]; + static const char _enabled[]; + static const char _readInterval[]; + static const char _referenceVoltage[]; + static const char _resistorValue[]; + static const char _adcPrecision[]; + static const char _offset[]; + + uint16_t getLuminance(); + +public: + void setup(); + void loop(); + + uint16_t getLastLDRValue() + { + return lastLDRValue; + } + + void addToJsonInfo(JsonObject &root); + + uint16_t getId() + { + return USERMOD_ID_SN_PHOTORESISTOR; + } + + const char* getName() override + { + return FPSTR(_name); + } + + /** + * addToConfig() (called from set.cpp) stores persistent properties to cfg.json + */ + void addToConfig(JsonObject &root); + + /** + * readFromConfig() is called before setup() to populate properties from values stored in cfg.json + */ + bool readFromConfig(JsonObject &root); +}; diff --git a/usermods/Si7021_MQTT_HA/Si7021_MQTT_HA.cpp b/usermods/Si7021_MQTT_HA/Si7021_MQTT_HA.cpp index 7845658ad1..8640733272 100644 --- a/usermods/Si7021_MQTT_HA/Si7021_MQTT_HA.cpp +++ b/usermods/Si7021_MQTT_HA/Si7021_MQTT_HA.cpp @@ -220,6 +220,11 @@ class Si7021_MQTT_HA : public Usermod { return USERMOD_ID_SI7021_MQTT_HA; } + + const char* getName() override + { + return FPSTR(_name); + } }; // strings to reduce flash memory usage (used more than twice) diff --git a/usermods/Temperature/UsermodTemperature.h b/usermods/Temperature/UsermodTemperature.h index 555b57cf7a..5f9aa20258 100644 --- a/usermods/Temperature/UsermodTemperature.h +++ b/usermods/Temperature/UsermodTemperature.h @@ -88,6 +88,11 @@ class UsermodTemperature : public Usermod { const char *getTemperatureUnit(); uint16_t getId() override { return USERMOD_ID_TEMPERATURE; } + const char* getName() override + { + return FPSTR(_name); + } + void setup() override; void loop() override; //void connected() override; diff --git a/usermods/TetrisAI_v2/TetrisAI_v2.cpp b/usermods/TetrisAI_v2/TetrisAI_v2.cpp index b51250b262..3eb82a2326 100644 --- a/usermods/TetrisAI_v2/TetrisAI_v2.cpp +++ b/usermods/TetrisAI_v2/TetrisAI_v2.cpp @@ -231,6 +231,7 @@ class TetrisAIUsermod : public Usermod { private: + static const char _name[]; public: void setup() @@ -247,8 +248,15 @@ class TetrisAIUsermod : public Usermod { return USERMOD_ID_TETRISAI; } + + const char* getName() override + { + return FPSTR(_name); + } }; +const char TetrisAIUsermod::_name[] PROGMEM = "Tetris AI"; + static TetrisAIUsermod tetrisai_v2; REGISTER_USERMOD(tetrisai_v2); \ No newline at end of file diff --git a/usermods/audioreactive/audio_reactive.cpp b/usermods/audioreactive/audio_reactive.cpp index d91e1bf2d3..a5b65197ea 100644 --- a/usermods/audioreactive/audio_reactive.cpp +++ b/usermods/audioreactive/audio_reactive.cpp @@ -1974,6 +1974,11 @@ class AudioReactive : public Usermod { { return USERMOD_ID_AUDIOREACTIVE; } + + const char* getName() override + { + return reinterpret_cast(FPSTR(_name)); + } }; void AudioReactive::removeAudioPalettes(void) { diff --git a/usermods/mpu6050_imu/usermod_gyro_surge.h b/usermods/mpu6050_imu/usermod_gyro_surge.h index c19358de74..a0255e149c 100644 --- a/usermods/mpu6050_imu/usermod_gyro_surge.h +++ b/usermods/mpu6050_imu/usermod_gyro_surge.h @@ -214,6 +214,10 @@ class GyroSurge : public Usermod { // TODO - multiple segment handling?? strip.getSegment(0).fadeToBlackBy(max - result); } + + const char* getName() { + return FPSTR(_name); + } }; const char GyroSurge::_name[] PROGMEM = "GyroSurge"; \ No newline at end of file diff --git a/usermods/pov_display/pov_display.cpp b/usermods/pov_display/pov_display.cpp index ac68e1b209..62b0f910f7 100644 --- a/usermods/pov_display/pov_display.cpp +++ b/usermods/pov_display/pov_display.cpp @@ -69,6 +69,11 @@ class PovDisplayUsermod : public Usermod { uint16_t getId() override { return USERMOD_ID_POV_DISPLAY; } + + const char* getName() override + { + return _name; + } }; static PovDisplayUsermod pov_display("POV Display", false); diff --git a/usermods/sht/ShtUsermod.h b/usermods/sht/ShtUsermod.h index 5dd83f46d6..bb6770bb86 100644 --- a/usermods/sht/ShtUsermod.h +++ b/usermods/sht/ShtUsermod.h @@ -68,4 +68,9 @@ class ShtUsermod : public Usermod const char* getUnitString(); uint16_t getId() { return USERMOD_ID_SHT; } + + const char* getName() override + { + return FPSTR(_name); + } }; diff --git a/usermods/usermod_v2_HttpPullLightControl/usermod_v2_HttpPullLightControl.h b/usermods/usermod_v2_HttpPullLightControl/usermod_v2_HttpPullLightControl.h index 187b2b0912..1071675675 100644 --- a/usermods/usermod_v2_HttpPullLightControl/usermod_v2_HttpPullLightControl.h +++ b/usermods/usermod_v2_HttpPullLightControl/usermod_v2_HttpPullLightControl.h @@ -86,6 +86,11 @@ class HttpPullLightControl : public Usermod { bool readFromConfig(JsonObject& root); void addToConfig(JsonObject& root); uint16_t getId() { return USERMOD_ID_HTTP_PULL_LIGHT_CONTROL; } + + const char* getName() override + { + return FPSTR(_name); + } inline void enable(bool enable) { enabled = enable; } // Enable or Disable the usermod inline bool isEnabled() { return enabled; } // Get usermod enabled or disabled state virtual ~HttpPullLightControl() { diff --git a/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display.h b/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display.h index 4fc963b9c1..93525d9e47 100644 --- a/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display.h +++ b/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display.h @@ -1,315 +1,320 @@ -#include "wled.h" -#undef U8X8_NO_HW_I2C // borrowed from WLEDMM: we do want I2C hardware drivers - if possible -#include // from https://github.com/olikraus/u8g2/ - -#pragma once - -#ifndef FLD_ESP32_NO_THREADS - #define FLD_ESP32_USE_THREADS // comment out to use 0.13.x behaviour without parallel update task - slower, but more robust. May delay other tasks like LEDs or audioreactive!! -#endif - -#ifndef FLD_PIN_CS - #define FLD_PIN_CS 15 -#endif - -#ifdef ARDUINO_ARCH_ESP32 - #ifndef FLD_PIN_DC - #define FLD_PIN_DC 19 - #endif - #ifndef FLD_PIN_RESET - #define FLD_PIN_RESET 26 - #endif -#else - #ifndef FLD_PIN_DC - #define FLD_PIN_DC 12 - #endif - #ifndef FLD_PIN_RESET - #define FLD_PIN_RESET 16 - #endif -#endif - -#ifndef FLD_TYPE - #ifndef FLD_SPI_DEFAULT - #define FLD_TYPE SSD1306 - #else - #define FLD_TYPE SSD1306_SPI - #endif -#endif - -// When to time out to the clock or blank the screen -// if SLEEP_MODE_ENABLED. -#define SCREEN_TIMEOUT_MS 60*1000 // 1 min - -// Minimum time between redrawing screen in ms -#define REFRESH_RATE_MS 1000 - -// Extra char (+1) for null -#define LINE_BUFFER_SIZE 16+1 -#define MAX_JSON_CHARS 19+1 -#define MAX_MODE_LINE_SPACE 13+1 - -typedef enum { - NONE = 0, - SSD1306, // U8X8_SSD1306_128X32_UNIVISION_HW_I2C - SH1106, // U8X8_SH1106_128X64_WINSTAR_HW_I2C - SSD1306_64, // U8X8_SSD1306_128X64_NONAME_HW_I2C - SSD1305, // U8X8_SSD1305_128X32_ADAFRUIT_HW_I2C - SSD1305_64, // U8X8_SSD1305_128X64_ADAFRUIT_HW_I2C - SSD1306_SPI, // U8X8_SSD1306_128X32_NONAME_HW_SPI - SSD1306_SPI64, // U8X8_SSD1306_128X64_NONAME_HW_SPI - SSD1309_SPI64, // U8X8_SSD1309_128X64_NONAME0_4W_HW_SPI - SSD1309_64 // U8X8_SSD1309_128X64_NONAME0_HW_I2C -} DisplayType; - -class FourLineDisplayUsermod : public Usermod { - #if defined(ARDUINO_ARCH_ESP32) && defined(FLD_ESP32_USE_THREADS) - public: - FourLineDisplayUsermod() { if (!instance) instance = this; } - static FourLineDisplayUsermod* getInstance(void) { return instance; } - #endif - - private: - - static FourLineDisplayUsermod *instance; - bool initDone = false; - volatile bool drawing = false; - volatile bool lockRedraw = false; - - // HW interface & configuration - U8X8 *u8x8 = nullptr; // pointer to U8X8 display object - - #ifndef FLD_SPI_DEFAULT - int8_t ioPin[3] = {-1, -1, -1}; // I2C pins: SCL, SDA - uint32_t ioFrequency = 400000; // in Hz (minimum is 100000, baseline is 400000 and maximum should be 3400000) - #else - int8_t ioPin[3] = {FLD_PIN_CS, FLD_PIN_DC, FLD_PIN_RESET}; // custom SPI pins: CS, DC, RST - uint32_t ioFrequency = 1000000; // in Hz (minimum is 500kHz, baseline is 1MHz and maximum should be 20MHz) - #endif - - DisplayType type = FLD_TYPE; // display type - bool flip = false; // flip display 180° - uint8_t contrast = 10; // screen contrast - uint8_t lineHeight = 1; // 1 row or 2 rows - uint16_t refreshRate = REFRESH_RATE_MS; // in ms - uint32_t screenTimeout = SCREEN_TIMEOUT_MS; // in ms - bool sleepMode = true; // allow screen sleep? - bool clockMode = false; // display clock - bool showSeconds = true; // display clock with seconds - bool enabled = true; - bool contrastFix = false; - - // Next variables hold the previous known values to determine if redraw is - // required. - String knownSsid = apSSID; - IPAddress knownIp = IPAddress(4, 3, 2, 1); - uint8_t knownBrightness = 0; - uint8_t knownEffectSpeed = 0; - uint8_t knownEffectIntensity = 0; - uint8_t knownMode = 0; - uint8_t knownPalette = 0; - uint8_t knownMinute = 99; - uint8_t knownHour = 99; - byte brightness100; - byte fxspeed100; - byte fxintensity100; - bool knownnightlight = nightlightActive; - bool wificonnected = interfacesInited; - bool powerON = true; - - bool displayTurnedOff = false; - unsigned long nextUpdate = 0; - unsigned long lastRedraw = 0; - unsigned long overlayUntil = 0; - - // Set to 2 or 3 to mark lines 2 or 3. Other values ignored. - byte markLineNum = 255; - byte markColNum = 255; - - // strings to reduce flash memory usage (used more than twice) - static const char _name[]; - static const char _enabled[]; - static const char _contrast[]; - static const char _refreshRate[]; - static const char _screenTimeOut[]; - static const char _flip[]; - static const char _sleepMode[]; - static const char _clockMode[]; - static const char _showSeconds[]; - static const char _busClkFrequency[]; - static const char _contrastFix[]; - - // If display does not work or looks corrupted check the - // constructor reference: - // https://github.com/olikraus/u8g2/wiki/u8x8setupcpp - // or check the gallery: - // https://github.com/olikraus/u8g2/wiki/gallery - - // some displays need this to properly apply contrast - void setVcomh(bool highContrast); - void startDisplay(); - - /** - * Wrappers for screen drawing - */ - void setFlipMode(uint8_t mode); - void setContrast(uint8_t contrast); - void drawString(uint8_t col, uint8_t row, const char *string, bool ignoreLH=false); - void draw2x2String(uint8_t col, uint8_t row, const char *string); - void drawGlyph(uint8_t col, uint8_t row, char glyph, const uint8_t *font, bool ignoreLH=false); - void draw2x2Glyph(uint8_t col, uint8_t row, char glyph, const uint8_t *font); - void draw2x2GlyphIcons(); - uint8_t getCols(); - void clear(); - void setPowerSave(uint8_t save); - void center(String &line, uint8_t width); - - /** - * Display the current date and time in large characters - * on the middle rows. Based 24 or 12 hour depending on - * the useAMPM configuration. - */ - void showTime(); - - /** - * Enable sleep (turn the display off) or clock mode. - */ - void sleepOrClock(bool enabled); - - public: - - // gets called once at boot. Do all initialization that doesn't depend on - // network here - void setup() override; - - // gets called every time WiFi is (re-)connected. Initialize own network - // interfaces here - void connected() override; - - /** - * Da loop. - */ - void loop() override; - - //function to update lastredraw - inline void updateRedrawTime() { lastRedraw = millis(); } - - /** - * Redraw the screen (but only if things have changed - * or if forceRedraw). - */ - void redraw(bool forceRedraw); - - void updateBrightness(); - void updateSpeed(); - void updateIntensity(); - void drawStatusIcons(); - - /** - * marks the position of the arrow showing - * the current setting being changed - * pass line and colum info - */ - void setMarkLine(byte newMarkLineNum, byte newMarkColNum); - - //Draw the arrow for the current setting being changed - void drawArrow(); - - //Display the current effect or palette (desiredEntry) - // on the appropriate line (row). - void showCurrentEffectOrPalette(int inputEffPal, const char *qstring, uint8_t row); - - /** - * If there screen is off or in clock is displayed, - * this will return true. This allows us to throw away - * the first input from the rotary encoder but - * to wake up the screen. - */ - bool wakeDisplay(); - - /** - * Allows you to show one line and a glyph as overlay for a period of time. - * Clears the screen and prints. - * Used in Rotary Encoder usermod. - */ - void overlay(const char* line1, long showHowLong, byte glyphType); - - /** - * Allows you to show Akemi WLED logo overlay for a period of time. - * Clears the screen and prints. - */ - void overlayLogo(long showHowLong); - - /** - * Allows you to show two lines as overlay for a period of time. - * Clears the screen and prints. - * Used in Auto Save usermod - */ - void overlay(const char* line1, const char* line2, long showHowLong); - - void networkOverlay(const char* line1, long showHowLong); - - /** - * handleButton() can be used to override default button behaviour. Returning true - * will prevent button working in a default way. - * Replicating button.cpp - */ - bool handleButton(uint8_t b); - - void onUpdateBegin(bool init) override; - - /* - * 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) override; - - /* - * 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) override; - - /* - * 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) override; - - void appendConfigData() override; - - /* - * 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) override; - - /* - * 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 :) - */ - bool readFromConfig(JsonObject& root) override; - - /* - * getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!). - * This could be used in the future for the system to determine whether your usermod is installed. - */ - uint16_t getId() override { - return USERMOD_ID_FOUR_LINE_DISP; - } - }; +#include "wled.h" +#undef U8X8_NO_HW_I2C // borrowed from WLEDMM: we do want I2C hardware drivers - if possible +#include // from https://github.com/olikraus/u8g2/ + +#pragma once + +#ifndef FLD_ESP32_NO_THREADS + #define FLD_ESP32_USE_THREADS // comment out to use 0.13.x behaviour without parallel update task - slower, but more robust. May delay other tasks like LEDs or audioreactive!! +#endif + +#ifndef FLD_PIN_CS + #define FLD_PIN_CS 15 +#endif + +#ifdef ARDUINO_ARCH_ESP32 + #ifndef FLD_PIN_DC + #define FLD_PIN_DC 19 + #endif + #ifndef FLD_PIN_RESET + #define FLD_PIN_RESET 26 + #endif +#else + #ifndef FLD_PIN_DC + #define FLD_PIN_DC 12 + #endif + #ifndef FLD_PIN_RESET + #define FLD_PIN_RESET 16 + #endif +#endif + +#ifndef FLD_TYPE + #ifndef FLD_SPI_DEFAULT + #define FLD_TYPE SSD1306 + #else + #define FLD_TYPE SSD1306_SPI + #endif +#endif + +// When to time out to the clock or blank the screen +// if SLEEP_MODE_ENABLED. +#define SCREEN_TIMEOUT_MS 60*1000 // 1 min + +// Minimum time between redrawing screen in ms +#define REFRESH_RATE_MS 1000 + +// Extra char (+1) for null +#define LINE_BUFFER_SIZE 16+1 +#define MAX_JSON_CHARS 19+1 +#define MAX_MODE_LINE_SPACE 13+1 + +typedef enum { + NONE = 0, + SSD1306, // U8X8_SSD1306_128X32_UNIVISION_HW_I2C + SH1106, // U8X8_SH1106_128X64_WINSTAR_HW_I2C + SSD1306_64, // U8X8_SSD1306_128X64_NONAME_HW_I2C + SSD1305, // U8X8_SSD1305_128X32_ADAFRUIT_HW_I2C + SSD1305_64, // U8X8_SSD1305_128X64_ADAFRUIT_HW_I2C + SSD1306_SPI, // U8X8_SSD1306_128X32_NONAME_HW_SPI + SSD1306_SPI64, // U8X8_SSD1306_128X64_NONAME_HW_SPI + SSD1309_SPI64, // U8X8_SSD1309_128X64_NONAME0_4W_HW_SPI + SSD1309_64 // U8X8_SSD1309_128X64_NONAME0_HW_I2C +} DisplayType; + +class FourLineDisplayUsermod : public Usermod { + #if defined(ARDUINO_ARCH_ESP32) && defined(FLD_ESP32_USE_THREADS) + public: + FourLineDisplayUsermod() { if (!instance) instance = this; } + static FourLineDisplayUsermod* getInstance(void) { return instance; } + #endif + + private: + + static FourLineDisplayUsermod *instance; + bool initDone = false; + volatile bool drawing = false; + volatile bool lockRedraw = false; + + // HW interface & configuration + U8X8 *u8x8 = nullptr; // pointer to U8X8 display object + + #ifndef FLD_SPI_DEFAULT + int8_t ioPin[3] = {-1, -1, -1}; // I2C pins: SCL, SDA + uint32_t ioFrequency = 400000; // in Hz (minimum is 100000, baseline is 400000 and maximum should be 3400000) + #else + int8_t ioPin[3] = {FLD_PIN_CS, FLD_PIN_DC, FLD_PIN_RESET}; // custom SPI pins: CS, DC, RST + uint32_t ioFrequency = 1000000; // in Hz (minimum is 500kHz, baseline is 1MHz and maximum should be 20MHz) + #endif + + DisplayType type = FLD_TYPE; // display type + bool flip = false; // flip display 180° + uint8_t contrast = 10; // screen contrast + uint8_t lineHeight = 1; // 1 row or 2 rows + uint16_t refreshRate = REFRESH_RATE_MS; // in ms + uint32_t screenTimeout = SCREEN_TIMEOUT_MS; // in ms + bool sleepMode = true; // allow screen sleep? + bool clockMode = false; // display clock + bool showSeconds = true; // display clock with seconds + bool enabled = true; + bool contrastFix = false; + + // Next variables hold the previous known values to determine if redraw is + // required. + String knownSsid = apSSID; + IPAddress knownIp = IPAddress(4, 3, 2, 1); + uint8_t knownBrightness = 0; + uint8_t knownEffectSpeed = 0; + uint8_t knownEffectIntensity = 0; + uint8_t knownMode = 0; + uint8_t knownPalette = 0; + uint8_t knownMinute = 99; + uint8_t knownHour = 99; + byte brightness100; + byte fxspeed100; + byte fxintensity100; + bool knownnightlight = nightlightActive; + bool wificonnected = interfacesInited; + bool powerON = true; + + bool displayTurnedOff = false; + unsigned long nextUpdate = 0; + unsigned long lastRedraw = 0; + unsigned long overlayUntil = 0; + + // Set to 2 or 3 to mark lines 2 or 3. Other values ignored. + byte markLineNum = 255; + byte markColNum = 255; + + // strings to reduce flash memory usage (used more than twice) + static const char _name[]; + static const char _enabled[]; + static const char _contrast[]; + static const char _refreshRate[]; + static const char _screenTimeOut[]; + static const char _flip[]; + static const char _sleepMode[]; + static const char _clockMode[]; + static const char _showSeconds[]; + static const char _busClkFrequency[]; + static const char _contrastFix[]; + + // If display does not work or looks corrupted check the + // constructor reference: + // https://github.com/olikraus/u8g2/wiki/u8x8setupcpp + // or check the gallery: + // https://github.com/olikraus/u8g2/wiki/gallery + + // some displays need this to properly apply contrast + void setVcomh(bool highContrast); + void startDisplay(); + + /** + * Wrappers for screen drawing + */ + void setFlipMode(uint8_t mode); + void setContrast(uint8_t contrast); + void drawString(uint8_t col, uint8_t row, const char *string, bool ignoreLH=false); + void draw2x2String(uint8_t col, uint8_t row, const char *string); + void drawGlyph(uint8_t col, uint8_t row, char glyph, const uint8_t *font, bool ignoreLH=false); + void draw2x2Glyph(uint8_t col, uint8_t row, char glyph, const uint8_t *font); + void draw2x2GlyphIcons(); + uint8_t getCols(); + void clear(); + void setPowerSave(uint8_t save); + void center(String &line, uint8_t width); + + /** + * Display the current date and time in large characters + * on the middle rows. Based 24 or 12 hour depending on + * the useAMPM configuration. + */ + void showTime(); + + /** + * Enable sleep (turn the display off) or clock mode. + */ + void sleepOrClock(bool enabled); + + public: + + // gets called once at boot. Do all initialization that doesn't depend on + // network here + void setup() override; + + // gets called every time WiFi is (re-)connected. Initialize own network + // interfaces here + void connected() override; + + /** + * Da loop. + */ + void loop() override; + + //function to update lastredraw + inline void updateRedrawTime() { lastRedraw = millis(); } + + /** + * Redraw the screen (but only if things have changed + * or if forceRedraw). + */ + void redraw(bool forceRedraw); + + void updateBrightness(); + void updateSpeed(); + void updateIntensity(); + void drawStatusIcons(); + + /** + * marks the position of the arrow showing + * the current setting being changed + * pass line and colum info + */ + void setMarkLine(byte newMarkLineNum, byte newMarkColNum); + + //Draw the arrow for the current setting being changed + void drawArrow(); + + //Display the current effect or palette (desiredEntry) + // on the appropriate line (row). + void showCurrentEffectOrPalette(int inputEffPal, const char *qstring, uint8_t row); + + /** + * If there screen is off or in clock is displayed, + * this will return true. This allows us to throw away + * the first input from the rotary encoder but + * to wake up the screen. + */ + bool wakeDisplay(); + + /** + * Allows you to show one line and a glyph as overlay for a period of time. + * Clears the screen and prints. + * Used in Rotary Encoder usermod. + */ + void overlay(const char* line1, long showHowLong, byte glyphType); + + /** + * Allows you to show Akemi WLED logo overlay for a period of time. + * Clears the screen and prints. + */ + void overlayLogo(long showHowLong); + + /** + * Allows you to show two lines as overlay for a period of time. + * Clears the screen and prints. + * Used in Auto Save usermod + */ + void overlay(const char* line1, const char* line2, long showHowLong); + + void networkOverlay(const char* line1, long showHowLong); + + /** + * handleButton() can be used to override default button behaviour. Returning true + * will prevent button working in a default way. + * Replicating button.cpp + */ + bool handleButton(uint8_t b); + + void onUpdateBegin(bool init) override; + + /* + * 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) override; + + /* + * 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) override; + + /* + * 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) override; + + void appendConfigData() override; + + /* + * 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) override; + + /* + * 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 :) + */ + bool readFromConfig(JsonObject& root) override; + + /* + * getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!). + * This could be used in the future for the system to determine whether your usermod is installed. + */ + uint16_t getId() override { + return USERMOD_ID_FOUR_LINE_DISP; + } + + const char* getName() override + { + return FPSTR(_name); + } + }; \ No newline at end of file From 897ce57b2dbe1c5b84512c71311c258a93bbb342 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 28 Dec 2025 06:03:16 +0000 Subject: [PATCH 07/13] Revert unnecessary formatting changes and match source file indentation Co-authored-by: DedeHai <6280424+DedeHai@users.noreply.github.com> --- usermods/Analog_Clock/Analog_Clock.cpp | 9 +- usermods/Cronixie/Cronixie.cpp | 9 +- usermods/DHT/DHT.cpp | 9 +- .../usermod_Fix_unreachable_netservices.cpp | 13 +- usermods/MY9291/MY9291.cpp | 9 +- .../PIR_sensor_switch/PIR_sensor_switch.cpp | 1158 ++++++++--------- usermods/RTC/RTC.cpp | 9 +- usermods/SN_Photoresistor/SN_Photoresistor.h | 190 +-- usermods/ST7789_display/ST7789_display.cpp | 5 +- .../VL53L0X_gestures/VL53L0X_gestures.cpp | 9 +- usermods/buzzer/buzzer.cpp | 9 +- .../pixels_dice_tray/pixels_dice_tray.cpp | 13 +- usermods/pwm_outputs/pwm_outputs.cpp | 9 +- usermods/sensors_to_mqtt/sensors_to_mqtt.cpp | 13 +- .../seven_segment_display.cpp | 13 +- usermods/smartnest/smartnest.cpp | 13 +- .../stairway_wipe_basic.cpp | 9 +- usermods/user_fx/user_fx.cpp | 12 +- .../usermod_rotary_brightness_color.cpp | 13 +- .../usermod_v2_RF433/usermod_v2_RF433.cpp | 13 +- .../usermod_v2_four_line_display.h | 637 +++++---- .../usermod_v2_ping_pong_clock.cpp | 13 +- usermods/wireguard/wireguard.cpp | 9 +- usermods/wizlights/wizlights.cpp | 9 +- .../word-clock-matrix/word-clock-matrix.cpp | 11 +- 25 files changed, 1076 insertions(+), 1140 deletions(-) diff --git a/usermods/Analog_Clock/Analog_Clock.cpp b/usermods/Analog_Clock/Analog_Clock.cpp index c02f83ea06..c544c0315e 100644 --- a/usermods/Analog_Clock/Analog_Clock.cpp +++ b/usermods/Analog_Clock/Analog_Clock.cpp @@ -7,8 +7,6 @@ extern Timezone* tz; class AnalogClockUsermod : public Usermod { private: - - static const char _name[]; static constexpr uint32_t refreshRate = 50; // per second static constexpr uint32_t refreshDelay = 1000 / refreshRate; @@ -255,13 +253,12 @@ class AnalogClockUsermod : public Usermod { return USERMOD_ID_ANALOG_CLOCK; } - const char* getName() override { - return FPSTR(_name); + const char* getName() override + { + return FPSTR(_name); } }; -const char AnalogClockUsermod::_name[] PROGMEM = "Analog Clock"; - static AnalogClockUsermod analog_clock; REGISTER_USERMOD(analog_clock); \ No newline at end of file diff --git a/usermods/Cronixie/Cronixie.cpp b/usermods/Cronixie/Cronixie.cpp index 2743e00fed..a62f72815a 100644 --- a/usermods/Cronixie/Cronixie.cpp +++ b/usermods/Cronixie/Cronixie.cpp @@ -2,8 +2,6 @@ class UsermodCronixie : public Usermod { private: - - static const char _name[]; unsigned long lastTime = 0; char cronixieDisplay[7] = "HHMMSS"; byte _digitOut[6] = {10,10,10,10,10,10}; @@ -300,12 +298,11 @@ class UsermodCronixie : public Usermod { return USERMOD_ID_CRONIXIE; } - const char* getName() override { - return FPSTR(_name); + const char* getName() override + { + return FPSTR(_name); } }; -const char UsermodCronixie::_name[] PROGMEM = "Cronixie"; - static UsermodCronixie cronixie; REGISTER_USERMOD(cronixie); \ No newline at end of file diff --git a/usermods/DHT/DHT.cpp b/usermods/DHT/DHT.cpp index 698d905eed..594e958422 100644 --- a/usermods/DHT/DHT.cpp +++ b/usermods/DHT/DHT.cpp @@ -59,8 +59,6 @@ DHT_nonblocking dht_sensor(DHTPIN, DHTTYPE); class UsermodDHT : public Usermod { private: - - static const char _name[]; unsigned long nextReadTime = 0; unsigned long lastReadTime = 0; float humidity, temperature = 0; @@ -244,14 +242,13 @@ class UsermodDHT : public Usermod { return USERMOD_ID_DHT; } - const char* getName() override { - return FPSTR(_name); + const char* getName() override + { + return FPSTR(_name); } }; -const char UsermodDHT::_name[] PROGMEM = "DHT"; - static UsermodDHT dht; REGISTER_USERMOD(dht); \ No newline at end of file diff --git a/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp b/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp index 591a7a3bea..5d7450d1ac 100644 --- a/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp +++ b/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp @@ -26,9 +26,7 @@ class FixUnreachableNetServices : public Usermod { private: - - static const char _name[]; - //Private class members. You can declare variables and functions only accessible to your usermod here + //Private class members. You can declare variables and functions only accessible to your usermod here unsigned long m_lastTime = 0; // declare required variables @@ -162,13 +160,12 @@ Delay hr) { - return true; - } else { - if (hour(sunrise)==hr && minute(sunrise)mi) { - return true; - } - } - } - return false; -} - -void PIRsensorSwitch::switchStrip(bool switchOn) -{ - if (m_offOnly && bri && (switchOn || (!PIRtriggered && !switchOn))) return; //if lights on and off only, do nothing - if (PIRtriggered && switchOn) return; //if already on and triggered before, do nothing - PIRtriggered = switchOn; - DEBUG_PRINT(F("PIR: strip=")); DEBUG_PRINTLN(switchOn?"on":"off"); - if (switchOn) { - if (m_onPreset) { - if (currentPlaylist>0 && !offMode) { - prevPlaylist = currentPlaylist; - unloadPlaylist(); - } else if (currentPreset>0 && !offMode) { - prevPreset = currentPreset; - } else { - saveTemporaryPreset(); - prevPlaylist = 0; - prevPreset = 255; - } - applyPreset(m_onPreset, CALL_MODE_BUTTON_PRESET); - return; - } - // preset not assigned - if (bri == 0) { - bri = briLast; - stateUpdated(CALL_MODE_BUTTON); - } - } else { - if (m_offPreset) { - applyPreset(m_offPreset, CALL_MODE_BUTTON_PRESET); - return; - } else if (prevPlaylist) { - if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyPreset(prevPlaylist, CALL_MODE_BUTTON_PRESET); - prevPlaylist = 0; - return; - } else if (prevPreset) { - if (prevPreset<255) { if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyPreset(prevPreset, CALL_MODE_BUTTON_PRESET); } - else { if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyTemporaryPreset(); } - prevPreset = 0; - return; - } - // preset not assigned - if (bri != 0) { - briLast = bri; - bri = 0; - stateUpdated(CALL_MODE_BUTTON); - } - } -} - -void PIRsensorSwitch::publishMqtt(bool switchOn) -{ -#ifndef WLED_DISABLE_MQTT - //Check if MQTT Connected, otherwise it will crash the 8266 - if (WLED_MQTT_CONNECTED) { - char buf[128]; - sprintf_P(buf, PSTR("%s/motion"), mqttDeviceTopic); //max length: 33 + 7 = 40 - mqtt->publish(buf, 0, false, switchOn?"on":"off"); - // Domoticz formatted message - if (idx > 0) { - StaticJsonDocument <128> msg; - msg[F("idx")] = idx; - msg[F("RSSI")] = WiFi.RSSI(); - msg[F("command")] = F("switchlight"); - msg[F("switchcmd")] = switchOn ? F("On") : F("Off"); - serializeJson(msg, buf, 128); - mqtt->publish("domoticz/in", 0, false, buf); - } - } -#endif -} - -void PIRsensorSwitch::publishHomeAssistantAutodiscovery() -{ -#ifndef WLED_DISABLE_MQTT - if (WLED_MQTT_CONNECTED) { - StaticJsonDocument<600> doc; - char uid[24], json_str[1024], buf[128]; - - sprintf_P(buf, PSTR("%s Motion"), serverDescription); //max length: 33 + 7 = 40 - doc[F("name")] = buf; - sprintf_P(buf, PSTR("%s/motion"), mqttDeviceTopic); //max length: 33 + 7 = 40 - doc[F("stat_t")] = buf; - doc[F("pl_on")] = "on"; - doc[F("pl_off")] = "off"; - sprintf_P(uid, PSTR("%s_motion"), escapedMac.c_str()); - doc[F("uniq_id")] = uid; - doc[F("dev_cla")] = F("motion"); - doc[F("exp_aft")] = 1800; - - JsonObject device = doc.createNestedObject(F("device")); // attach the sensor to the same device - device[F("name")] = serverDescription; - device[F("ids")] = String(F("wled-sensor-")) + mqttClientID; - device[F("mf")] = F(WLED_BRAND); - device[F("mdl")] = F(WLED_PRODUCT_NAME); - device[F("sw")] = versionString; - - sprintf_P(buf, PSTR("homeassistant/binary_sensor/%s/config"), uid); - DEBUG_PRINTLN(buf); - size_t payload_size = serializeJson(doc, json_str); - DEBUG_PRINTLN(json_str); - - mqtt->publish(buf, 0, true, json_str, payload_size); // do we really need to retain? - } -#endif -} - -bool PIRsensorSwitch::updatePIRsensorState() -{ - bool stateChanged = false; - bool allOff = true; - for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) { - if (PIRsensorPin[i] < 0) continue; - - bool pinState = digitalRead(PIRsensorPin[i]); - if (pinState != sensorPinState[i]) { - sensorPinState[i] = pinState; // change previous state - stateChanged = true; - - if (sensorPinState[i] == HIGH) { - offTimerStart = 0; - allOff = false; - if (!m_mqttOnly && (!m_nightTimeOnly || (m_nightTimeOnly && !isDayTime()))) switchStrip(true); - } - } - } - if (stateChanged) { - publishMqtt(!allOff); - // start switch off timer - if (allOff) offTimerStart = millis(); - } - return stateChanged; -} - -bool PIRsensorSwitch::handleOffTimer() -{ - if (offTimerStart > 0 && millis() - offTimerStart > m_switchOffDelay) { - offTimerStart = 0; - if (!m_mqttOnly && (!m_nightTimeOnly || (m_nightTimeOnly && !isDayTime()) || PIRtriggered)) switchStrip(false); - return true; - } - return false; -} - -//Functions called by WLED - -void PIRsensorSwitch::setup() -{ - for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) { - sensorPinState[i] = LOW; - if (PIRsensorPin[i] < 0) continue; - // pin retrieved from cfg.json (readFromConfig()) prior to running setup() - if (PinManager::allocatePin(PIRsensorPin[i], false, PinOwner::UM_PIR)) { - // PIR Sensor mode INPUT_PULLDOWN - #ifdef ESP8266 - pinMode(PIRsensorPin[i], PIRsensorPin[i]==16 ? INPUT_PULLDOWN_16 : INPUT_PULLUP); // ESP8266 has INPUT_PULLDOWN on GPIO16 only - #else - pinMode(PIRsensorPin[i], INPUT_PULLDOWN); - #endif - sensorPinState[i] = digitalRead(PIRsensorPin[i]); - } else { - DEBUG_PRINT(F("PIRSensorSwitch pin ")); DEBUG_PRINTLN(i); DEBUG_PRINTLN(F(" allocation failed.")); - PIRsensorPin[i] = -1; // allocation failed - } - } - initDone = true; -} - -void PIRsensorSwitch::onMqttConnect(bool sessionPresent) -{ - if (HomeAssistantDiscovery) { - publishHomeAssistantAutodiscovery(); - } -} - -void PIRsensorSwitch::loop() -{ - // only check sensors 5x/s - if (!enabled || millis() - lastLoop < 200) return; - lastLoop = millis(); - - if (!updatePIRsensorState()) { - handleOffTimer(); - } -} - -void PIRsensorSwitch::addToJsonInfo(JsonObject &root) -{ - JsonObject user = root["u"]; - if (user.isNull()) user = root.createNestedObject("u"); - - bool state = LOW; - for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) - if (PIRsensorPin[i] >= 0) state |= sensorPinState[i]; - - JsonArray infoArr = user.createNestedArray(FPSTR(_name)); - - String uiDomString; - if (enabled) { - if (offTimerStart > 0) { - uiDomString = ""; - unsigned int offSeconds = (m_switchOffDelay - (millis() - offTimerStart)) / 1000; - if (offSeconds >= 3600) { - uiDomString += (offSeconds / 3600); - uiDomString += F("h "); - offSeconds %= 3600; - } - if (offSeconds >= 60) { - uiDomString += (offSeconds / 60); - offSeconds %= 60; - } else if (uiDomString.length() > 0) { - uiDomString += 0; - } - if (uiDomString.length() > 0) { - uiDomString += F("min "); - } - uiDomString += (offSeconds); - infoArr.add(uiDomString + F("s")); - } else { - infoArr.add(state ? F("sensor on") : F("inactive")); - } - } else { - infoArr.add(F("disabled")); - } - - uiDomString = F(" "); - infoArr.add(uiDomString); - - if (enabled) { - JsonObject sensor = root[F("sensor")]; - if (sensor.isNull()) sensor = root.createNestedObject(F("sensor")); - sensor[F("motion")] = state || offTimerStart>0 ? true : false; - } -} - -void PIRsensorSwitch::onStateChange(uint8_t mode) { - if (!initDone) return; - DEBUG_PRINT(F("PIR: offTimerStart=")); DEBUG_PRINTLN(offTimerStart); - if (m_override && PIRtriggered && offTimerStart) { // debounce - // checking PIRtriggered and offTimerStart will prevent cancellation upon On trigger - DEBUG_PRINTLN(F("PIR: Canceled.")); - offTimerStart = 0; - PIRtriggered = false; - } -} - -void PIRsensorSwitch::readFromJsonState(JsonObject &root) -{ - if (!initDone) return; // prevent crash on boot applyPreset() - JsonObject usermod = root[FPSTR(_name)]; - if (!usermod.isNull()) { - if (usermod[FPSTR(_enabled)].is()) { - enabled = usermod[FPSTR(_enabled)].as(); - } - } -} - -void PIRsensorSwitch::addToConfig(JsonObject &root) -{ - JsonObject top = root.createNestedObject(FPSTR(_name)); - top[FPSTR(_enabled)] = enabled; - top[FPSTR(_switchOffDelay)] = m_switchOffDelay / 1000; - JsonArray pinArray = top.createNestedArray("pin"); - for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) pinArray.add(PIRsensorPin[i]); - top[FPSTR(_onPreset)] = m_onPreset; - top[FPSTR(_offPreset)] = m_offPreset; - top[FPSTR(_nightTime)] = m_nightTimeOnly; - top[FPSTR(_mqttOnly)] = m_mqttOnly; - top[FPSTR(_offOnly)] = m_offOnly; - top[FPSTR(_override)] = m_override; - top[FPSTR(_haDiscovery)] = HomeAssistantDiscovery; - top[FPSTR(_domoticzIDX)] = idx; - DEBUG_PRINTLN(F("PIR config saved.")); -} - -void PIRsensorSwitch::appendConfigData() -{ - oappend(F("addInfo('PIRsensorSwitch:HA-discovery',1,'HA=Home Assistant');")); // 0 is field type, 1 is actual field - oappend(F("addInfo('PIRsensorSwitch:override',1,'Cancel timer on change');")); // 0 is field type, 1 is actual field - for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) { - char str[128]; - sprintf_P(str, PSTR("addInfo('PIRsensorSwitch:pin[]',%d,'','#%d');"), i, i); - oappend(str); - } -} - -bool PIRsensorSwitch::readFromConfig(JsonObject &root) -{ - int8_t oldPin[PIR_SENSOR_MAX_SENSORS]; - for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) { - oldPin[i] = PIRsensorPin[i]; - PIRsensorPin[i] = -1; - } - - DEBUG_PRINT(FPSTR(_name)); - JsonObject top = root[FPSTR(_name)]; - if (top.isNull()) { - DEBUG_PRINTLN(F(": No config found. (Using defaults.)")); - return false; - } - - JsonArray pins = top["pin"]; - if (!pins.isNull()) { - for (size_t i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) - if (i < pins.size()) PIRsensorPin[i] = pins[i] | PIRsensorPin[i]; - } else { - PIRsensorPin[0] = top["pin"] | oldPin[0]; - } - - enabled = top[FPSTR(_enabled)] | enabled; - - m_switchOffDelay = (top[FPSTR(_switchOffDelay)] | m_switchOffDelay/1000) * 1000; - - m_onPreset = top[FPSTR(_onPreset)] | m_onPreset; - m_onPreset = max(0,min(250,(int)m_onPreset)); - m_offPreset = top[FPSTR(_offPreset)] | m_offPreset; - m_offPreset = max(0,min(250,(int)m_offPreset)); - - m_nightTimeOnly = top[FPSTR(_nightTime)] | m_nightTimeOnly; - m_mqttOnly = top[FPSTR(_mqttOnly)] | m_mqttOnly; - m_offOnly = top[FPSTR(_offOnly)] | m_offOnly; - m_override = top[FPSTR(_override)] | m_override; - HomeAssistantDiscovery = top[FPSTR(_haDiscovery)] | HomeAssistantDiscovery; - idx = top[FPSTR(_domoticzIDX)] | idx; - - if (!initDone) { - // reading config prior to setup() - DEBUG_PRINTLN(F(" config loaded.")); - } else { - for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) - if (oldPin[i] >= 0) PinManager::deallocatePin(oldPin[i], PinOwner::UM_PIR); - setup(); - DEBUG_PRINTLN(F(" config (re)loaded.")); - } - // use "return !top["newestParameter"].isNull();" when updating Usermod with new features - return !(pins.isNull() || pins.size() != PIR_SENSOR_MAX_SENSORS); -} - - -static PIRsensorSwitch pir_sensor_switch; +#include "wled.h" + +#ifndef PIR_SENSOR_PIN + // compatible with QuinLED-Dig-Uno + #ifdef ARDUINO_ARCH_ESP32 + #define PIR_SENSOR_PIN 23 // Q4 + #else //ESP8266 boards + #define PIR_SENSOR_PIN 13 // Q4 (D7 on D1 mini) + #endif +#endif + +#ifndef PIR_SENSOR_OFF_SEC + #define PIR_SENSOR_OFF_SEC 600 +#endif + +#ifndef PIR_SENSOR_MAX_SENSORS + #define PIR_SENSOR_MAX_SENSORS 1 +#endif + +/* + * This usermod handles PIR sensor states. + * The strip will be switched on and the off timer will be resetted when the sensor goes HIGH. + * When the sensor state goes LOW, the off timer is started and when it expires, the strip is switched off. + * Maintained by: @blazoncek + * + * Usermods allow you to add own functionality to WLED more easily + * See: https://github.com/wled-dev/WLED/wiki/Add-own-functionality + * + * v2 usermods are class inheritance based and can (but don't have to) implement more functions, each of them is shown in this example. + * Multiple v2 usermods can be added to one compilation easily. + */ + +class PIRsensorSwitch : public Usermod +{ +public: + // constructor + PIRsensorSwitch() {} + // destructor + ~PIRsensorSwitch() {} + + //Enable/Disable the PIR sensor + inline void EnablePIRsensor(bool en) { enabled = en; } + + // Get PIR sensor enabled/disabled state + inline bool PIRsensorEnabled() { return enabled; } + +private: + + byte prevPreset = 0; + byte prevPlaylist = 0; + + volatile unsigned long offTimerStart = 0; // off timer start time + volatile bool PIRtriggered = false; // did PIR trigger? + bool initDone = false; // status of initialization + unsigned long lastLoop = 0; + bool sensorPinState[PIR_SENSOR_MAX_SENSORS] = {LOW}; // current PIR sensor pin state + + // configurable parameters +#if PIR_SENSOR_PIN < 0 + bool enabled = false; // PIR sensor disabled +#else + bool enabled = true; // PIR sensor enabled +#endif + int8_t PIRsensorPin[PIR_SENSOR_MAX_SENSORS] = {PIR_SENSOR_PIN}; // PIR sensor pin + uint32_t m_switchOffDelay = PIR_SENSOR_OFF_SEC*1000; // delay before switch off after the sensor state goes LOW (10min) + uint8_t m_onPreset = 0; // on preset + uint8_t m_offPreset = 0; // off preset + bool m_nightTimeOnly = false; // flag to indicate that PIR sensor should activate WLED during nighttime only + bool m_mqttOnly = false; // flag to send MQTT message only (assuming it is enabled) + // flag to enable triggering only if WLED is initially off (LEDs are not on, preventing running effect being overwritten by PIR) + bool m_offOnly = false; + bool m_offMode = offMode; + bool m_override = false; + + // Home Assistant + bool HomeAssistantDiscovery = false; // is HA discovery turned on + int16_t idx = -1; // Domoticz virtual switch idx + + // strings to reduce flash memory usage (used more than twice) + static const char _name[]; + static const char _switchOffDelay[]; + static const char _enabled[]; + static const char _onPreset[]; + static const char _offPreset[]; + static const char _nightTime[]; + static const char _mqttOnly[]; + static const char _offOnly[]; + static const char _haDiscovery[]; + static const char _override[]; + static const char _domoticzIDX[]; + + /** + * check if it is daytime + * if sunrise/sunset is not defined (no NTP or lat/lon) default to nighttime + */ + static bool isDayTime(); + + /** + * switch strip on/off + */ + void switchStrip(bool switchOn); + void publishMqtt(bool switchOn); + + // Create an MQTT Binary Sensor for Home Assistant Discovery purposes, this includes a pointer to the topic that is published to in the Loop. + void publishHomeAssistantAutodiscovery(); + + /** + * Read and update PIR sensor state. + * Initialize/reset switch off timer + */ + bool updatePIRsensorState(); + + /** + * switch off the strip if the delay has elapsed + */ + bool handleOffTimer(); + +public: + //Functions called by WLED + + /** + * setup() is called once at boot. WiFi is not yet connected at this point. + * You can use it to initialize variables, sensors or similar. + */ + void setup() override; + + /** + * connected() is called every time the WiFi is (re)connected + * Use it to initialize network interfaces + */ + //void connected(); + + /** + * onMqttConnect() is called when MQTT connection is established + */ + void onMqttConnect(bool sessionPresent) override; + + /** + * loop() is called continuously. Here you can check for events, read sensors, etc. + */ + void loop() override; + + /** + * addToJsonInfo() can be used to add custom entries to the /json/info part of the JSON API. + * + * Add PIR sensor state and switch off timer duration to jsoninfo + */ + void addToJsonInfo(JsonObject &root) override; + + /** + * onStateChanged() is used to detect WLED state change + */ + void onStateChange(uint8_t mode) override; + + /** + * 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); + + /** + * 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) override; + + /** + * provide the changeable values + */ + void addToConfig(JsonObject &root) override; + + /** + * provide UI information and allow extending UI options + */ + void appendConfigData() override; + + /** + * restore the changeable values + * readFromConfig() is called before setup() to populate properties from values stored in cfg.json + * + * The function should return true if configuration was successfully loaded or false if there was no configuration. + */ + bool readFromConfig(JsonObject &root) override; + + /** + * getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!). + * This could be used in the future for the system to determine whether your usermod is installed. + */ + uint16_t getId() override { return USERMOD_ID_PIRSWITCH; } + + const char* getName() override + { + return FPSTR(_name); + } +}; + +// strings to reduce flash memory usage (used more than twice) +const char PIRsensorSwitch::_name[] PROGMEM = "PIRsensorSwitch"; +const char PIRsensorSwitch::_enabled[] PROGMEM = "PIRenabled"; +const char PIRsensorSwitch::_switchOffDelay[] PROGMEM = "PIRoffSec"; +const char PIRsensorSwitch::_onPreset[] PROGMEM = "on-preset"; +const char PIRsensorSwitch::_offPreset[] PROGMEM = "off-preset"; +const char PIRsensorSwitch::_nightTime[] PROGMEM = "nighttime-only"; +const char PIRsensorSwitch::_mqttOnly[] PROGMEM = "mqtt-only"; +const char PIRsensorSwitch::_offOnly[] PROGMEM = "off-only"; +const char PIRsensorSwitch::_haDiscovery[] PROGMEM = "HA-discovery"; +const char PIRsensorSwitch::_override[] PROGMEM = "override"; +const char PIRsensorSwitch::_domoticzIDX[] PROGMEM = "domoticz-idx"; + +bool PIRsensorSwitch::isDayTime() { + updateLocalTime(); + uint8_t hr = hour(localTime); + uint8_t mi = minute(localTime); + + if (sunrise && sunset) { + if (hour(sunrise)
hr) { + return true; + } else { + if (hour(sunrise)==hr && minute(sunrise)mi) { + return true; + } + } + } + return false; +} + +void PIRsensorSwitch::switchStrip(bool switchOn) +{ + if (m_offOnly && bri && (switchOn || (!PIRtriggered && !switchOn))) return; //if lights on and off only, do nothing + if (PIRtriggered && switchOn) return; //if already on and triggered before, do nothing + PIRtriggered = switchOn; + DEBUG_PRINT(F("PIR: strip=")); DEBUG_PRINTLN(switchOn?"on":"off"); + if (switchOn) { + if (m_onPreset) { + if (currentPlaylist>0 && !offMode) { + prevPlaylist = currentPlaylist; + unloadPlaylist(); + } else if (currentPreset>0 && !offMode) { + prevPreset = currentPreset; + } else { + saveTemporaryPreset(); + prevPlaylist = 0; + prevPreset = 255; + } + applyPreset(m_onPreset, CALL_MODE_BUTTON_PRESET); + return; + } + // preset not assigned + if (bri == 0) { + bri = briLast; + stateUpdated(CALL_MODE_BUTTON); + } + } else { + if (m_offPreset) { + applyPreset(m_offPreset, CALL_MODE_BUTTON_PRESET); + return; + } else if (prevPlaylist) { + if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyPreset(prevPlaylist, CALL_MODE_BUTTON_PRESET); + prevPlaylist = 0; + return; + } else if (prevPreset) { + if (prevPreset<255) { if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyPreset(prevPreset, CALL_MODE_BUTTON_PRESET); } + else { if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyTemporaryPreset(); } + prevPreset = 0; + return; + } + // preset not assigned + if (bri != 0) { + briLast = bri; + bri = 0; + stateUpdated(CALL_MODE_BUTTON); + } + } +} + +void PIRsensorSwitch::publishMqtt(bool switchOn) +{ +#ifndef WLED_DISABLE_MQTT + //Check if MQTT Connected, otherwise it will crash the 8266 + if (WLED_MQTT_CONNECTED) { + char buf[128]; + sprintf_P(buf, PSTR("%s/motion"), mqttDeviceTopic); //max length: 33 + 7 = 40 + mqtt->publish(buf, 0, false, switchOn?"on":"off"); + // Domoticz formatted message + if (idx > 0) { + StaticJsonDocument <128> msg; + msg[F("idx")] = idx; + msg[F("RSSI")] = WiFi.RSSI(); + msg[F("command")] = F("switchlight"); + msg[F("switchcmd")] = switchOn ? F("On") : F("Off"); + serializeJson(msg, buf, 128); + mqtt->publish("domoticz/in", 0, false, buf); + } + } +#endif +} + +void PIRsensorSwitch::publishHomeAssistantAutodiscovery() +{ +#ifndef WLED_DISABLE_MQTT + if (WLED_MQTT_CONNECTED) { + StaticJsonDocument<600> doc; + char uid[24], json_str[1024], buf[128]; + + sprintf_P(buf, PSTR("%s Motion"), serverDescription); //max length: 33 + 7 = 40 + doc[F("name")] = buf; + sprintf_P(buf, PSTR("%s/motion"), mqttDeviceTopic); //max length: 33 + 7 = 40 + doc[F("stat_t")] = buf; + doc[F("pl_on")] = "on"; + doc[F("pl_off")] = "off"; + sprintf_P(uid, PSTR("%s_motion"), escapedMac.c_str()); + doc[F("uniq_id")] = uid; + doc[F("dev_cla")] = F("motion"); + doc[F("exp_aft")] = 1800; + + JsonObject device = doc.createNestedObject(F("device")); // attach the sensor to the same device + device[F("name")] = serverDescription; + device[F("ids")] = String(F("wled-sensor-")) + mqttClientID; + device[F("mf")] = F(WLED_BRAND); + device[F("mdl")] = F(WLED_PRODUCT_NAME); + device[F("sw")] = versionString; + + sprintf_P(buf, PSTR("homeassistant/binary_sensor/%s/config"), uid); + DEBUG_PRINTLN(buf); + size_t payload_size = serializeJson(doc, json_str); + DEBUG_PRINTLN(json_str); + + mqtt->publish(buf, 0, true, json_str, payload_size); // do we really need to retain? + } +#endif +} + +bool PIRsensorSwitch::updatePIRsensorState() +{ + bool stateChanged = false; + bool allOff = true; + for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) { + if (PIRsensorPin[i] < 0) continue; + + bool pinState = digitalRead(PIRsensorPin[i]); + if (pinState != sensorPinState[i]) { + sensorPinState[i] = pinState; // change previous state + stateChanged = true; + + if (sensorPinState[i] == HIGH) { + offTimerStart = 0; + allOff = false; + if (!m_mqttOnly && (!m_nightTimeOnly || (m_nightTimeOnly && !isDayTime()))) switchStrip(true); + } + } + } + if (stateChanged) { + publishMqtt(!allOff); + // start switch off timer + if (allOff) offTimerStart = millis(); + } + return stateChanged; +} + +bool PIRsensorSwitch::handleOffTimer() +{ + if (offTimerStart > 0 && millis() - offTimerStart > m_switchOffDelay) { + offTimerStart = 0; + if (!m_mqttOnly && (!m_nightTimeOnly || (m_nightTimeOnly && !isDayTime()) || PIRtriggered)) switchStrip(false); + return true; + } + return false; +} + +//Functions called by WLED + +void PIRsensorSwitch::setup() +{ + for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) { + sensorPinState[i] = LOW; + if (PIRsensorPin[i] < 0) continue; + // pin retrieved from cfg.json (readFromConfig()) prior to running setup() + if (PinManager::allocatePin(PIRsensorPin[i], false, PinOwner::UM_PIR)) { + // PIR Sensor mode INPUT_PULLDOWN + #ifdef ESP8266 + pinMode(PIRsensorPin[i], PIRsensorPin[i]==16 ? INPUT_PULLDOWN_16 : INPUT_PULLUP); // ESP8266 has INPUT_PULLDOWN on GPIO16 only + #else + pinMode(PIRsensorPin[i], INPUT_PULLDOWN); + #endif + sensorPinState[i] = digitalRead(PIRsensorPin[i]); + } else { + DEBUG_PRINT(F("PIRSensorSwitch pin ")); DEBUG_PRINTLN(i); DEBUG_PRINTLN(F(" allocation failed.")); + PIRsensorPin[i] = -1; // allocation failed + } + } + initDone = true; +} + +void PIRsensorSwitch::onMqttConnect(bool sessionPresent) +{ + if (HomeAssistantDiscovery) { + publishHomeAssistantAutodiscovery(); + } +} + +void PIRsensorSwitch::loop() +{ + // only check sensors 5x/s + if (!enabled || millis() - lastLoop < 200) return; + lastLoop = millis(); + + if (!updatePIRsensorState()) { + handleOffTimer(); + } +} + +void PIRsensorSwitch::addToJsonInfo(JsonObject &root) +{ + JsonObject user = root["u"]; + if (user.isNull()) user = root.createNestedObject("u"); + + bool state = LOW; + for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) + if (PIRsensorPin[i] >= 0) state |= sensorPinState[i]; + + JsonArray infoArr = user.createNestedArray(FPSTR(_name)); + + String uiDomString; + if (enabled) { + if (offTimerStart > 0) { + uiDomString = ""; + unsigned int offSeconds = (m_switchOffDelay - (millis() - offTimerStart)) / 1000; + if (offSeconds >= 3600) { + uiDomString += (offSeconds / 3600); + uiDomString += F("h "); + offSeconds %= 3600; + } + if (offSeconds >= 60) { + uiDomString += (offSeconds / 60); + offSeconds %= 60; + } else if (uiDomString.length() > 0) { + uiDomString += 0; + } + if (uiDomString.length() > 0) { + uiDomString += F("min "); + } + uiDomString += (offSeconds); + infoArr.add(uiDomString + F("s")); + } else { + infoArr.add(state ? F("sensor on") : F("inactive")); + } + } else { + infoArr.add(F("disabled")); + } + + uiDomString = F(" "); + infoArr.add(uiDomString); + + if (enabled) { + JsonObject sensor = root[F("sensor")]; + if (sensor.isNull()) sensor = root.createNestedObject(F("sensor")); + sensor[F("motion")] = state || offTimerStart>0 ? true : false; + } +} + +void PIRsensorSwitch::onStateChange(uint8_t mode) { + if (!initDone) return; + DEBUG_PRINT(F("PIR: offTimerStart=")); DEBUG_PRINTLN(offTimerStart); + if (m_override && PIRtriggered && offTimerStart) { // debounce + // checking PIRtriggered and offTimerStart will prevent cancellation upon On trigger + DEBUG_PRINTLN(F("PIR: Canceled.")); + offTimerStart = 0; + PIRtriggered = false; + } +} + +void PIRsensorSwitch::readFromJsonState(JsonObject &root) +{ + if (!initDone) return; // prevent crash on boot applyPreset() + JsonObject usermod = root[FPSTR(_name)]; + if (!usermod.isNull()) { + if (usermod[FPSTR(_enabled)].is()) { + enabled = usermod[FPSTR(_enabled)].as(); + } + } +} + +void PIRsensorSwitch::addToConfig(JsonObject &root) +{ + JsonObject top = root.createNestedObject(FPSTR(_name)); + top[FPSTR(_enabled)] = enabled; + top[FPSTR(_switchOffDelay)] = m_switchOffDelay / 1000; + JsonArray pinArray = top.createNestedArray("pin"); + for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) pinArray.add(PIRsensorPin[i]); + top[FPSTR(_onPreset)] = m_onPreset; + top[FPSTR(_offPreset)] = m_offPreset; + top[FPSTR(_nightTime)] = m_nightTimeOnly; + top[FPSTR(_mqttOnly)] = m_mqttOnly; + top[FPSTR(_offOnly)] = m_offOnly; + top[FPSTR(_override)] = m_override; + top[FPSTR(_haDiscovery)] = HomeAssistantDiscovery; + top[FPSTR(_domoticzIDX)] = idx; + DEBUG_PRINTLN(F("PIR config saved.")); +} + +void PIRsensorSwitch::appendConfigData() +{ + oappend(F("addInfo('PIRsensorSwitch:HA-discovery',1,'HA=Home Assistant');")); // 0 is field type, 1 is actual field + oappend(F("addInfo('PIRsensorSwitch:override',1,'Cancel timer on change');")); // 0 is field type, 1 is actual field + for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) { + char str[128]; + sprintf_P(str, PSTR("addInfo('PIRsensorSwitch:pin[]',%d,'','#%d');"), i, i); + oappend(str); + } +} + +bool PIRsensorSwitch::readFromConfig(JsonObject &root) +{ + int8_t oldPin[PIR_SENSOR_MAX_SENSORS]; + for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) { + oldPin[i] = PIRsensorPin[i]; + PIRsensorPin[i] = -1; + } + + DEBUG_PRINT(FPSTR(_name)); + JsonObject top = root[FPSTR(_name)]; + if (top.isNull()) { + DEBUG_PRINTLN(F(": No config found. (Using defaults.)")); + return false; + } + + JsonArray pins = top["pin"]; + if (!pins.isNull()) { + for (size_t i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) + if (i < pins.size()) PIRsensorPin[i] = pins[i] | PIRsensorPin[i]; + } else { + PIRsensorPin[0] = top["pin"] | oldPin[0]; + } + + enabled = top[FPSTR(_enabled)] | enabled; + + m_switchOffDelay = (top[FPSTR(_switchOffDelay)] | m_switchOffDelay/1000) * 1000; + + m_onPreset = top[FPSTR(_onPreset)] | m_onPreset; + m_onPreset = max(0,min(250,(int)m_onPreset)); + m_offPreset = top[FPSTR(_offPreset)] | m_offPreset; + m_offPreset = max(0,min(250,(int)m_offPreset)); + + m_nightTimeOnly = top[FPSTR(_nightTime)] | m_nightTimeOnly; + m_mqttOnly = top[FPSTR(_mqttOnly)] | m_mqttOnly; + m_offOnly = top[FPSTR(_offOnly)] | m_offOnly; + m_override = top[FPSTR(_override)] | m_override; + HomeAssistantDiscovery = top[FPSTR(_haDiscovery)] | HomeAssistantDiscovery; + idx = top[FPSTR(_domoticzIDX)] | idx; + + if (!initDone) { + // reading config prior to setup() + DEBUG_PRINTLN(F(" config loaded.")); + } else { + for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) + if (oldPin[i] >= 0) PinManager::deallocatePin(oldPin[i], PinOwner::UM_PIR); + setup(); + DEBUG_PRINTLN(F(" config (re)loaded.")); + } + // use "return !top["newestParameter"].isNull();" when updating Usermod with new features + return !(pins.isNull() || pins.size() != PIR_SENSOR_MAX_SENSORS); +} + + +static PIRsensorSwitch pir_sensor_switch; REGISTER_USERMOD(pir_sensor_switch); \ No newline at end of file diff --git a/usermods/RTC/RTC.cpp b/usermods/RTC/RTC.cpp index 4ca2505d15..cbd1a1cda6 100644 --- a/usermods/RTC/RTC.cpp +++ b/usermods/RTC/RTC.cpp @@ -5,8 +5,6 @@ class RTCUsermod : public Usermod { private: - - static const char _name[]; unsigned long lastTime = 0; bool disabled = false; public: @@ -49,12 +47,11 @@ class RTCUsermod : public Usermod { return USERMOD_ID_RTC; } - const char* getName() override { - return FPSTR(_name); + const char* getName() override + { + return FPSTR(_name); } }; -const char RTCUsermod::_name[] PROGMEM = "RTC"; - static RTCUsermod rtc; REGISTER_USERMOD(rtc); \ No newline at end of file diff --git a/usermods/SN_Photoresistor/SN_Photoresistor.h b/usermods/SN_Photoresistor/SN_Photoresistor.h index 8500d35a77..2c21cc9062 100644 --- a/usermods/SN_Photoresistor/SN_Photoresistor.h +++ b/usermods/SN_Photoresistor/SN_Photoresistor.h @@ -1,95 +1,95 @@ -#pragma once -#include "wled.h" - -// the frequency to check photoresistor, 10 seconds -#ifndef USERMOD_SN_PHOTORESISTOR_MEASUREMENT_INTERVAL -#define USERMOD_SN_PHOTORESISTOR_MEASUREMENT_INTERVAL 10000 -#endif - -// how many seconds after boot to take first measurement, 10 seconds -#ifndef USERMOD_SN_PHOTORESISTOR_FIRST_MEASUREMENT_AT -#define USERMOD_SN_PHOTORESISTOR_FIRST_MEASUREMENT_AT 10000 -#endif - -// supplied voltage -#ifndef USERMOD_SN_PHOTORESISTOR_REFERENCE_VOLTAGE -#define USERMOD_SN_PHOTORESISTOR_REFERENCE_VOLTAGE 5 -#endif - -// 10 bits -#ifndef USERMOD_SN_PHOTORESISTOR_ADC_PRECISION -#define USERMOD_SN_PHOTORESISTOR_ADC_PRECISION 1024.0f -#endif - -// resistor size 10K hms -#ifndef USERMOD_SN_PHOTORESISTOR_RESISTOR_VALUE -#define USERMOD_SN_PHOTORESISTOR_RESISTOR_VALUE 10000.0f -#endif - -// only report if difference grater than offset value -#ifndef USERMOD_SN_PHOTORESISTOR_OFFSET_VALUE -#define USERMOD_SN_PHOTORESISTOR_OFFSET_VALUE 5 -#endif - -class Usermod_SN_Photoresistor : public Usermod -{ -private: - float referenceVoltage = USERMOD_SN_PHOTORESISTOR_REFERENCE_VOLTAGE; - float resistorValue = USERMOD_SN_PHOTORESISTOR_RESISTOR_VALUE; - float adcPrecision = USERMOD_SN_PHOTORESISTOR_ADC_PRECISION; - int8_t offset = USERMOD_SN_PHOTORESISTOR_OFFSET_VALUE; - - unsigned long readingInterval = USERMOD_SN_PHOTORESISTOR_MEASUREMENT_INTERVAL; - // set last reading as "40 sec before boot", so first reading is taken after 20 sec - unsigned long lastMeasurement = UINT32_MAX - (USERMOD_SN_PHOTORESISTOR_MEASUREMENT_INTERVAL - USERMOD_SN_PHOTORESISTOR_FIRST_MEASUREMENT_AT); - // flag to indicate we have finished the first getTemperature call - // allows this library to report to the user how long until the first - // measurement - bool getLuminanceComplete = false; - uint16_t lastLDRValue = 65535; - - // flag set at startup - bool disabled = false; - - // strings to reduce flash memory usage (used more than twice) - static const char _name[]; - static const char _enabled[]; - static const char _readInterval[]; - static const char _referenceVoltage[]; - static const char _resistorValue[]; - static const char _adcPrecision[]; - static const char _offset[]; - - uint16_t getLuminance(); - -public: - void setup(); - void loop(); - - uint16_t getLastLDRValue() - { - return lastLDRValue; - } - - void addToJsonInfo(JsonObject &root); - - uint16_t getId() - { - return USERMOD_ID_SN_PHOTORESISTOR; - } - - const char* getName() override - { - return FPSTR(_name); - } - - /** - * addToConfig() (called from set.cpp) stores persistent properties to cfg.json - */ - void addToConfig(JsonObject &root); - - /** - * readFromConfig() is called before setup() to populate properties from values stored in cfg.json - */ - bool readFromConfig(JsonObject &root); -}; +#pragma once +#include "wled.h" + +// the frequency to check photoresistor, 10 seconds +#ifndef USERMOD_SN_PHOTORESISTOR_MEASUREMENT_INTERVAL +#define USERMOD_SN_PHOTORESISTOR_MEASUREMENT_INTERVAL 10000 +#endif + +// how many seconds after boot to take first measurement, 10 seconds +#ifndef USERMOD_SN_PHOTORESISTOR_FIRST_MEASUREMENT_AT +#define USERMOD_SN_PHOTORESISTOR_FIRST_MEASUREMENT_AT 10000 +#endif + +// supplied voltage +#ifndef USERMOD_SN_PHOTORESISTOR_REFERENCE_VOLTAGE +#define USERMOD_SN_PHOTORESISTOR_REFERENCE_VOLTAGE 5 +#endif + +// 10 bits +#ifndef USERMOD_SN_PHOTORESISTOR_ADC_PRECISION +#define USERMOD_SN_PHOTORESISTOR_ADC_PRECISION 1024.0f +#endif + +// resistor size 10K hms +#ifndef USERMOD_SN_PHOTORESISTOR_RESISTOR_VALUE +#define USERMOD_SN_PHOTORESISTOR_RESISTOR_VALUE 10000.0f +#endif + +// only report if difference grater than offset value +#ifndef USERMOD_SN_PHOTORESISTOR_OFFSET_VALUE +#define USERMOD_SN_PHOTORESISTOR_OFFSET_VALUE 5 +#endif + +class Usermod_SN_Photoresistor : public Usermod +{ +private: + float referenceVoltage = USERMOD_SN_PHOTORESISTOR_REFERENCE_VOLTAGE; + float resistorValue = USERMOD_SN_PHOTORESISTOR_RESISTOR_VALUE; + float adcPrecision = USERMOD_SN_PHOTORESISTOR_ADC_PRECISION; + int8_t offset = USERMOD_SN_PHOTORESISTOR_OFFSET_VALUE; + + unsigned long readingInterval = USERMOD_SN_PHOTORESISTOR_MEASUREMENT_INTERVAL; + // set last reading as "40 sec before boot", so first reading is taken after 20 sec + unsigned long lastMeasurement = UINT32_MAX - (USERMOD_SN_PHOTORESISTOR_MEASUREMENT_INTERVAL - USERMOD_SN_PHOTORESISTOR_FIRST_MEASUREMENT_AT); + // flag to indicate we have finished the first getTemperature call + // allows this library to report to the user how long until the first + // measurement + bool getLuminanceComplete = false; + uint16_t lastLDRValue = 65535; + + // flag set at startup + bool disabled = false; + + // strings to reduce flash memory usage (used more than twice) + static const char _name[]; + static const char _enabled[]; + static const char _readInterval[]; + static const char _referenceVoltage[]; + static const char _resistorValue[]; + static const char _adcPrecision[]; + static const char _offset[]; + + uint16_t getLuminance(); + +public: + void setup(); + void loop(); + + uint16_t getLastLDRValue() + { + return lastLDRValue; + } + + void addToJsonInfo(JsonObject &root); + + uint16_t getId() + { + return USERMOD_ID_SN_PHOTORESISTOR; + } + + const char* getName() + { + return FPSTR(_name); + } + + /** + * addToConfig() (called from set.cpp) stores persistent properties to cfg.json + */ + void addToConfig(JsonObject &root); + + /** + * readFromConfig() is called before setup() to populate properties from values stored in cfg.json + */ + bool readFromConfig(JsonObject &root); +}; diff --git a/usermods/ST7789_display/ST7789_display.cpp b/usermods/ST7789_display/ST7789_display.cpp index 05a723bd9d..74e650df05 100644 --- a/usermods/ST7789_display/ST7789_display.cpp +++ b/usermods/ST7789_display/ST7789_display.cpp @@ -48,7 +48,6 @@ extern int getSignalQuality(int rssi); //class name. Use something descriptive and leave the ": public Usermod" part :) class St7789DisplayUsermod : public Usermod { private: - static const char _name[]; //Private class members. You can declare variables and functions only accessible to your usermod here unsigned long lastTime = 0; bool enabled = true; @@ -416,7 +415,5 @@ class St7789DisplayUsermod : public Usermod { //Your usermod will remain compatible as it does not need to implement all methods from the Usermod base class! }; -const char St7789DisplayUsermod::_name[] PROGMEM = "ST7789 Display"; - -static St7789DisplayUsermod st7789_display; +static name. st7789_display; REGISTER_USERMOD(st7789_display); \ No newline at end of file diff --git a/usermods/VL53L0X_gestures/VL53L0X_gestures.cpp b/usermods/VL53L0X_gestures/VL53L0X_gestures.cpp index 958d2d64c0..f575110287 100644 --- a/usermods/VL53L0X_gestures/VL53L0X_gestures.cpp +++ b/usermods/VL53L0X_gestures/VL53L0X_gestures.cpp @@ -36,8 +36,6 @@ class UsermodVL53L0XGestures : public Usermod { private: - - static const char _name[]; //Private class members. You can declare variables and functions only accessible to your usermod here unsigned long lastTime = 0; VL53L0X sensor; @@ -127,12 +125,11 @@ class UsermodVL53L0XGestures : public Usermod { return USERMOD_ID_VL53L0X; } - const char* getName() override { - return FPSTR(_name); + const char* getName() override + { + return FPSTR(_name); } }; -const char UsermodVL53L0XGestures::_name[] PROGMEM = "VL53L0X Gestures"; - static UsermodVL53L0XGestures vl53l0x_gestures; REGISTER_USERMOD(vl53l0x_gestures); \ No newline at end of file diff --git a/usermods/buzzer/buzzer.cpp b/usermods/buzzer/buzzer.cpp index b754ae2423..5bfa403793 100644 --- a/usermods/buzzer/buzzer.cpp +++ b/usermods/buzzer/buzzer.cpp @@ -20,8 +20,6 @@ class BuzzerUsermod : public Usermod { private: - - static const char _name[]; unsigned long lastTime_ = 0; unsigned long delay_ = 0; std::deque> sequence_ {}; @@ -80,12 +78,11 @@ class BuzzerUsermod : public Usermod { return USERMOD_ID_BUZZER; } - const char* getName() override { - return FPSTR(_name); + const char* getName() override + { + return FPSTR(_name); } }; -const char BuzzerUsermod::_name[] PROGMEM = "Buzzer"; - static BuzzerUsermod buzzer; REGISTER_USERMOD(buzzer); \ No newline at end of file diff --git a/usermods/pixels_dice_tray/pixels_dice_tray.cpp b/usermods/pixels_dice_tray/pixels_dice_tray.cpp index bf129d190b..6723f4c333 100644 --- a/usermods/pixels_dice_tray/pixels_dice_tray.cpp +++ b/usermods/pixels_dice_tray/pixels_dice_tray.cpp @@ -39,9 +39,7 @@ class PixelsDiceTrayUsermod : public Usermod { private: - - static const char _name[]; - bool enabled = true; + bool enabled = true; DiceUpdate dice_update; @@ -529,9 +527,10 @@ class PixelsDiceTrayUsermod : public Usermod { */ uint16_t getId() { return USERMOD_ID_PIXELS_DICE_TRAY; } - const char* getName() override { - return FPSTR(_name); - } + const char* getName() override + { + return FPSTR(_name); + } // More methods can be added in the future, this example will then be // extended. Your usermod will remain compatible as it does not need to @@ -539,7 +538,5 @@ class PixelsDiceTrayUsermod : public Usermod { }; -const char PixelsDiceTrayUsermod::_name[] PROGMEM = "Pixels Dice Tray"; - static PixelsDiceTrayUsermod pixels_dice_tray; REGISTER_USERMOD(pixels_dice_tray); \ No newline at end of file diff --git a/usermods/pwm_outputs/pwm_outputs.cpp b/usermods/pwm_outputs/pwm_outputs.cpp index 6024575181..db58f63e70 100644 --- a/usermods/pwm_outputs/pwm_outputs.cpp +++ b/usermods/pwm_outputs/pwm_outputs.cpp @@ -211,13 +211,12 @@ class PwmOutputsUsermod : public Usermod { return USERMOD_ID_PWM_OUTPUTS; } - const char* getName() override { - return FPSTR(_name); + const char* getName() override + { + return FPSTR(_name); } private: - - static const char _name[]; PwmOutput pwms_[USERMOD_PWM_OUTPUT_PINS]; }; @@ -226,7 +225,5 @@ const char PwmOutputsUsermod::USERMOD_NAME[] PROGMEM = "PwmOutputs"; const char PwmOutputsUsermod::PWM_STATE_NAME[] PROGMEM = "pwm"; -const char PwmOutputsUsermod::_name[] PROGMEM = "PWM Outputs"; - static PwmOutputsUsermod pwm_outputs; REGISTER_USERMOD(pwm_outputs); \ No newline at end of file diff --git a/usermods/sensors_to_mqtt/sensors_to_mqtt.cpp b/usermods/sensors_to_mqtt/sensors_to_mqtt.cpp index d9a55b1aec..a48dce5ed9 100644 --- a/usermods/sensors_to_mqtt/sensors_to_mqtt.cpp +++ b/usermods/sensors_to_mqtt/sensors_to_mqtt.cpp @@ -16,9 +16,8 @@ static Adafruit_CCS811 ccs811; class UserMod_SensorsToMQTT : public Usermod { private: - - static const char _name[]; - bool initialized = false; + static const char _name[]; + bool initialized = false; bool mqttInitialized = false; float SensorPressure = 0; float SensorTemperature = 0; @@ -277,12 +276,12 @@ class UserMod_SensorsToMQTT : public Usermod } } - const char* getName() override { - return FPSTR(_name); - } + const char* getName() + { + return FPSTR(_name); + } }; - const char UserMod_SensorsToMQTT::_name[] PROGMEM = "Sensors to MQTT"; static UserMod_SensorsToMQTT sensors_to_mqtt; diff --git a/usermods/seven_segment_display/seven_segment_display.cpp b/usermods/seven_segment_display/seven_segment_display.cpp index c2fcac9422..c60f9df511 100644 --- a/usermods/seven_segment_display/seven_segment_display.cpp +++ b/usermods/seven_segment_display/seven_segment_display.cpp @@ -10,9 +10,7 @@ class SevenSegmentDisplay : public Usermod #define WLED_SS_BUFFLEN 6 #define REFRESHTIME 497 private: - - static const char _name[]; - //Runtime variables. + //Runtime variables. unsigned long lastRefresh = 0; unsigned long lastCharacterStep = 0; String ssDisplayBuffer = ""; @@ -489,9 +487,10 @@ class SevenSegmentDisplay : public Usermod return USERMOD_ID_SEVEN_SEGMENT_DISPLAY; } - const char* getName() override { - return FPSTR(_name); - } + const char* getName() override + { + return FPSTR(_name); + } }; const char SevenSegmentDisplay::_str_perSegment[] PROGMEM = "perSegment"; @@ -504,7 +503,5 @@ const char SevenSegmentDisplay::_str_displayMask[] PROGMEM = "displayMask"; const char SevenSegmentDisplay::_str_displayMsg[] PROGMEM = "displayMsg"; const char SevenSegmentDisplay::_str_sevenSeg[] PROGMEM = "sevenSeg"; -const char SevenSegmentDisplay::_name[] PROGMEM = "Seven Segment Display"; - static SevenSegmentDisplay seven_segment_display; REGISTER_USERMOD(seven_segment_display); \ No newline at end of file diff --git a/usermods/smartnest/smartnest.cpp b/usermods/smartnest/smartnest.cpp index c47723448a..e06c0f2d88 100644 --- a/usermods/smartnest/smartnest.cpp +++ b/usermods/smartnest/smartnest.cpp @@ -7,9 +7,7 @@ class Smartnest : public Usermod { private: - - static const char _name[]; - bool initialized = false; + bool initialized = false; unsigned long lastMqttReport = 0; unsigned long mqttReportInterval = 60000; // Report every minute @@ -173,9 +171,10 @@ class Smartnest : public Usermod return USERMOD_ID_SMARTNEST; } - const char* getName() override { - return FPSTR(_name); - } + const char* getName() override + { + return FPSTR(_name); + } /** * setup() is called once at startup to initialize the usermod. @@ -209,7 +208,5 @@ class Smartnest : public Usermod }; -const char Smartnest::_name[] PROGMEM = "Smartnest"; - static Smartnest smartnest; REGISTER_USERMOD(smartnest); \ No newline at end of file diff --git a/usermods/stairway_wipe_basic/stairway_wipe_basic.cpp b/usermods/stairway_wipe_basic/stairway_wipe_basic.cpp index 56cb236e7c..308ac0b5fc 100644 --- a/usermods/stairway_wipe_basic/stairway_wipe_basic.cpp +++ b/usermods/stairway_wipe_basic/stairway_wipe_basic.cpp @@ -13,8 +13,6 @@ class StairwayWipeUsermod : public Usermod { private: - - static const char _name[]; //Private class members. You can declare variables and functions only accessible to your usermod here unsigned long lastTime = 0; byte wipeState = 0; //0: inactive 1: wiping 2: solid @@ -91,8 +89,9 @@ void setup() { return USERMOD_ID_STAIRWAY_WIPE; } - const char* getName() override { - return FPSTR(_name); + const char* getName() override + { + return FPSTR(_name); } @@ -134,7 +133,5 @@ void setup() { }; -const char StairwayWipeUsermod::_name[] PROGMEM = "Stairway Wipe"; - static StairwayWipeUsermod stairway_wipe_basic; REGISTER_USERMOD(stairway_wipe_basic); \ No newline at end of file diff --git a/usermods/user_fx/user_fx.cpp b/usermods/user_fx/user_fx.cpp index 7487975b72..cf1f8e7b18 100644 --- a/usermods/user_fx/user_fx.cpp +++ b/usermods/user_fx/user_fx.cpp @@ -95,9 +95,6 @@ static const char _data_FX_MODE_DIFFUSIONFIRE[] PROGMEM = "Diffusion Fire@!,Spar class UserFxUsermod : public Usermod { private: - - static const char _name[]; - public: void setup() override { strip.addEffect(255, &mode_diffusionfire, _data_FX_MODE_DIFFUSIONFIRE); @@ -115,12 +112,11 @@ class UserFxUsermod : public Usermod { void loop() override {} // nothing to do in the loop uint16_t getId() override { return USERMOD_ID_USER_FX; } - const char* getName() override { - return FPSTR(_name); - } + const char* getName() override + { + return FPSTR(_name); + } }; -const char UserFxUsermod::_name[] PROGMEM = "User FX"; - static UserFxUsermod user_fx; REGISTER_USERMOD(user_fx); diff --git a/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.cpp b/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.cpp index c1c0d06230..4acdf662ef 100644 --- a/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.cpp +++ b/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.cpp @@ -5,9 +5,8 @@ class RotaryEncoderBrightnessColor : public Usermod { private: - - static const char _name[]; - //Private class members. You can declare variables and functions only accessible to your usermod here + static const char _name[]; + //Private class members. You can declare variables and functions only accessible to your usermod here unsigned long lastTime = 0; unsigned long currentTime; unsigned long loopTime; @@ -187,12 +186,12 @@ class RotaryEncoderBrightnessColor : public Usermod return configComplete; } - const char* getName() override { - return FPSTR(_name); - } + const char* getName() + { + return FPSTR(_name); + } }; - const char RotaryEncoderBrightnessColor::_name[] PROGMEM = "Rotary Brightness Color"; static RotaryEncoderBrightnessColor usermod_rotary_brightness_color; diff --git a/usermods/usermod_v2_RF433/usermod_v2_RF433.cpp b/usermods/usermod_v2_RF433/usermod_v2_RF433.cpp index 881e63f85a..26f4ee569d 100644 --- a/usermods/usermod_v2_RF433/usermod_v2_RF433.cpp +++ b/usermods/usermod_v2_RF433/usermod_v2_RF433.cpp @@ -7,9 +7,7 @@ class RF433Usermod : public Usermod { private: - - static const char _name[]; - RCSwitch mySwitch = RCSwitch(); + RCSwitch mySwitch = RCSwitch(); unsigned long lastCommand = 0; unsigned long lastTime = 0; @@ -120,9 +118,10 @@ class RF433Usermod : public Usermod return USERMOD_ID_RF433; } - const char* getName() override { - return FPSTR(_name); - } + const char* getName() override + { + return FPSTR(_name); + } // this function follows the same principle as decodeIRJson() / remoteJson() bool remoteJson433(int button) @@ -185,7 +184,5 @@ const char RF433Usermod::_modName[] PROGMEM = "RF433 Remote"; const char RF433Usermod::_modEnabled[] PROGMEM = "Enabled"; const char RF433Usermod::_receivePin[] PROGMEM = "RX Pin"; -const char RF433Usermod::_name[] PROGMEM = "RF433"; - static RF433Usermod usermod_v2_RF433; REGISTER_USERMOD(usermod_v2_RF433); diff --git a/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display.h b/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display.h index 93525d9e47..725a9e2baf 100644 --- a/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display.h +++ b/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display.h @@ -1,320 +1,319 @@ -#include "wled.h" -#undef U8X8_NO_HW_I2C // borrowed from WLEDMM: we do want I2C hardware drivers - if possible -#include // from https://github.com/olikraus/u8g2/ - -#pragma once - -#ifndef FLD_ESP32_NO_THREADS - #define FLD_ESP32_USE_THREADS // comment out to use 0.13.x behaviour without parallel update task - slower, but more robust. May delay other tasks like LEDs or audioreactive!! -#endif - -#ifndef FLD_PIN_CS - #define FLD_PIN_CS 15 -#endif - -#ifdef ARDUINO_ARCH_ESP32 - #ifndef FLD_PIN_DC - #define FLD_PIN_DC 19 - #endif - #ifndef FLD_PIN_RESET - #define FLD_PIN_RESET 26 - #endif -#else - #ifndef FLD_PIN_DC - #define FLD_PIN_DC 12 - #endif - #ifndef FLD_PIN_RESET - #define FLD_PIN_RESET 16 - #endif -#endif - -#ifndef FLD_TYPE - #ifndef FLD_SPI_DEFAULT - #define FLD_TYPE SSD1306 - #else - #define FLD_TYPE SSD1306_SPI - #endif -#endif - -// When to time out to the clock or blank the screen -// if SLEEP_MODE_ENABLED. -#define SCREEN_TIMEOUT_MS 60*1000 // 1 min - -// Minimum time between redrawing screen in ms -#define REFRESH_RATE_MS 1000 - -// Extra char (+1) for null -#define LINE_BUFFER_SIZE 16+1 -#define MAX_JSON_CHARS 19+1 -#define MAX_MODE_LINE_SPACE 13+1 - -typedef enum { - NONE = 0, - SSD1306, // U8X8_SSD1306_128X32_UNIVISION_HW_I2C - SH1106, // U8X8_SH1106_128X64_WINSTAR_HW_I2C - SSD1306_64, // U8X8_SSD1306_128X64_NONAME_HW_I2C - SSD1305, // U8X8_SSD1305_128X32_ADAFRUIT_HW_I2C - SSD1305_64, // U8X8_SSD1305_128X64_ADAFRUIT_HW_I2C - SSD1306_SPI, // U8X8_SSD1306_128X32_NONAME_HW_SPI - SSD1306_SPI64, // U8X8_SSD1306_128X64_NONAME_HW_SPI - SSD1309_SPI64, // U8X8_SSD1309_128X64_NONAME0_4W_HW_SPI - SSD1309_64 // U8X8_SSD1309_128X64_NONAME0_HW_I2C -} DisplayType; - -class FourLineDisplayUsermod : public Usermod { - #if defined(ARDUINO_ARCH_ESP32) && defined(FLD_ESP32_USE_THREADS) - public: - FourLineDisplayUsermod() { if (!instance) instance = this; } - static FourLineDisplayUsermod* getInstance(void) { return instance; } - #endif - - private: - - static FourLineDisplayUsermod *instance; - bool initDone = false; - volatile bool drawing = false; - volatile bool lockRedraw = false; - - // HW interface & configuration - U8X8 *u8x8 = nullptr; // pointer to U8X8 display object - - #ifndef FLD_SPI_DEFAULT - int8_t ioPin[3] = {-1, -1, -1}; // I2C pins: SCL, SDA - uint32_t ioFrequency = 400000; // in Hz (minimum is 100000, baseline is 400000 and maximum should be 3400000) - #else - int8_t ioPin[3] = {FLD_PIN_CS, FLD_PIN_DC, FLD_PIN_RESET}; // custom SPI pins: CS, DC, RST - uint32_t ioFrequency = 1000000; // in Hz (minimum is 500kHz, baseline is 1MHz and maximum should be 20MHz) - #endif - - DisplayType type = FLD_TYPE; // display type - bool flip = false; // flip display 180° - uint8_t contrast = 10; // screen contrast - uint8_t lineHeight = 1; // 1 row or 2 rows - uint16_t refreshRate = REFRESH_RATE_MS; // in ms - uint32_t screenTimeout = SCREEN_TIMEOUT_MS; // in ms - bool sleepMode = true; // allow screen sleep? - bool clockMode = false; // display clock - bool showSeconds = true; // display clock with seconds - bool enabled = true; - bool contrastFix = false; - - // Next variables hold the previous known values to determine if redraw is - // required. - String knownSsid = apSSID; - IPAddress knownIp = IPAddress(4, 3, 2, 1); - uint8_t knownBrightness = 0; - uint8_t knownEffectSpeed = 0; - uint8_t knownEffectIntensity = 0; - uint8_t knownMode = 0; - uint8_t knownPalette = 0; - uint8_t knownMinute = 99; - uint8_t knownHour = 99; - byte brightness100; - byte fxspeed100; - byte fxintensity100; - bool knownnightlight = nightlightActive; - bool wificonnected = interfacesInited; - bool powerON = true; - - bool displayTurnedOff = false; - unsigned long nextUpdate = 0; - unsigned long lastRedraw = 0; - unsigned long overlayUntil = 0; - - // Set to 2 or 3 to mark lines 2 or 3. Other values ignored. - byte markLineNum = 255; - byte markColNum = 255; - - // strings to reduce flash memory usage (used more than twice) - static const char _name[]; - static const char _enabled[]; - static const char _contrast[]; - static const char _refreshRate[]; - static const char _screenTimeOut[]; - static const char _flip[]; - static const char _sleepMode[]; - static const char _clockMode[]; - static const char _showSeconds[]; - static const char _busClkFrequency[]; - static const char _contrastFix[]; - - // If display does not work or looks corrupted check the - // constructor reference: - // https://github.com/olikraus/u8g2/wiki/u8x8setupcpp - // or check the gallery: - // https://github.com/olikraus/u8g2/wiki/gallery - - // some displays need this to properly apply contrast - void setVcomh(bool highContrast); - void startDisplay(); - - /** - * Wrappers for screen drawing - */ - void setFlipMode(uint8_t mode); - void setContrast(uint8_t contrast); - void drawString(uint8_t col, uint8_t row, const char *string, bool ignoreLH=false); - void draw2x2String(uint8_t col, uint8_t row, const char *string); - void drawGlyph(uint8_t col, uint8_t row, char glyph, const uint8_t *font, bool ignoreLH=false); - void draw2x2Glyph(uint8_t col, uint8_t row, char glyph, const uint8_t *font); - void draw2x2GlyphIcons(); - uint8_t getCols(); - void clear(); - void setPowerSave(uint8_t save); - void center(String &line, uint8_t width); - - /** - * Display the current date and time in large characters - * on the middle rows. Based 24 or 12 hour depending on - * the useAMPM configuration. - */ - void showTime(); - - /** - * Enable sleep (turn the display off) or clock mode. - */ - void sleepOrClock(bool enabled); - - public: - - // gets called once at boot. Do all initialization that doesn't depend on - // network here - void setup() override; - - // gets called every time WiFi is (re-)connected. Initialize own network - // interfaces here - void connected() override; - - /** - * Da loop. - */ - void loop() override; - - //function to update lastredraw - inline void updateRedrawTime() { lastRedraw = millis(); } - - /** - * Redraw the screen (but only if things have changed - * or if forceRedraw). - */ - void redraw(bool forceRedraw); - - void updateBrightness(); - void updateSpeed(); - void updateIntensity(); - void drawStatusIcons(); - - /** - * marks the position of the arrow showing - * the current setting being changed - * pass line and colum info - */ - void setMarkLine(byte newMarkLineNum, byte newMarkColNum); - - //Draw the arrow for the current setting being changed - void drawArrow(); - - //Display the current effect or palette (desiredEntry) - // on the appropriate line (row). - void showCurrentEffectOrPalette(int inputEffPal, const char *qstring, uint8_t row); - - /** - * If there screen is off or in clock is displayed, - * this will return true. This allows us to throw away - * the first input from the rotary encoder but - * to wake up the screen. - */ - bool wakeDisplay(); - - /** - * Allows you to show one line and a glyph as overlay for a period of time. - * Clears the screen and prints. - * Used in Rotary Encoder usermod. - */ - void overlay(const char* line1, long showHowLong, byte glyphType); - - /** - * Allows you to show Akemi WLED logo overlay for a period of time. - * Clears the screen and prints. - */ - void overlayLogo(long showHowLong); - - /** - * Allows you to show two lines as overlay for a period of time. - * Clears the screen and prints. - * Used in Auto Save usermod - */ - void overlay(const char* line1, const char* line2, long showHowLong); - - void networkOverlay(const char* line1, long showHowLong); - - /** - * handleButton() can be used to override default button behaviour. Returning true - * will prevent button working in a default way. - * Replicating button.cpp - */ - bool handleButton(uint8_t b); - - void onUpdateBegin(bool init) override; - - /* - * 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) override; - - /* - * 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) override; - - /* - * 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) override; - - void appendConfigData() override; - - /* - * 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) override; - - /* - * 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 :) - */ - bool readFromConfig(JsonObject& root) override; - - /* - * getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!). - * This could be used in the future for the system to determine whether your usermod is installed. - */ - uint16_t getId() override { - return USERMOD_ID_FOUR_LINE_DISP; - } - - const char* getName() override - { - return FPSTR(_name); - } - }; +#include "wled.h" +#undef U8X8_NO_HW_I2C // borrowed from WLEDMM: we do want I2C hardware drivers - if possible +#include // from https://github.com/olikraus/u8g2/ + +#pragma once + +#ifndef FLD_ESP32_NO_THREADS + #define FLD_ESP32_USE_THREADS // comment out to use 0.13.x behaviour without parallel update task - slower, but more robust. May delay other tasks like LEDs or audioreactive!! +#endif + +#ifndef FLD_PIN_CS + #define FLD_PIN_CS 15 +#endif + +#ifdef ARDUINO_ARCH_ESP32 + #ifndef FLD_PIN_DC + #define FLD_PIN_DC 19 + #endif + #ifndef FLD_PIN_RESET + #define FLD_PIN_RESET 26 + #endif +#else + #ifndef FLD_PIN_DC + #define FLD_PIN_DC 12 + #endif + #ifndef FLD_PIN_RESET + #define FLD_PIN_RESET 16 + #endif +#endif + +#ifndef FLD_TYPE + #ifndef FLD_SPI_DEFAULT + #define FLD_TYPE SSD1306 + #else + #define FLD_TYPE SSD1306_SPI + #endif +#endif + +// When to time out to the clock or blank the screen +// if SLEEP_MODE_ENABLED. +#define SCREEN_TIMEOUT_MS 60*1000 // 1 min + +// Minimum time between redrawing screen in ms +#define REFRESH_RATE_MS 1000 + +// Extra char (+1) for null +#define LINE_BUFFER_SIZE 16+1 +#define MAX_JSON_CHARS 19+1 +#define MAX_MODE_LINE_SPACE 13+1 + +typedef enum { + NONE = 0, + SSD1306, // U8X8_SSD1306_128X32_UNIVISION_HW_I2C + SH1106, // U8X8_SH1106_128X64_WINSTAR_HW_I2C + SSD1306_64, // U8X8_SSD1306_128X64_NONAME_HW_I2C + SSD1305, // U8X8_SSD1305_128X32_ADAFRUIT_HW_I2C + SSD1305_64, // U8X8_SSD1305_128X64_ADAFRUIT_HW_I2C + SSD1306_SPI, // U8X8_SSD1306_128X32_NONAME_HW_SPI + SSD1306_SPI64, // U8X8_SSD1306_128X64_NONAME_HW_SPI + SSD1309_SPI64, // U8X8_SSD1309_128X64_NONAME0_4W_HW_SPI + SSD1309_64 // U8X8_SSD1309_128X64_NONAME0_HW_I2C +} DisplayType; + +class FourLineDisplayUsermod : public Usermod { + #if defined(ARDUINO_ARCH_ESP32) && defined(FLD_ESP32_USE_THREADS) + public: + FourLineDisplayUsermod() { if (!instance) instance = this; } + static FourLineDisplayUsermod* getInstance(void) { return instance; } + #endif + + private: + + static FourLineDisplayUsermod *instance; + bool initDone = false; + volatile bool drawing = false; + volatile bool lockRedraw = false; + + // HW interface & configuration + U8X8 *u8x8 = nullptr; // pointer to U8X8 display object + + #ifndef FLD_SPI_DEFAULT + int8_t ioPin[3] = {-1, -1, -1}; // I2C pins: SCL, SDA + uint32_t ioFrequency = 400000; // in Hz (minimum is 100000, baseline is 400000 and maximum should be 3400000) + #else + int8_t ioPin[3] = {FLD_PIN_CS, FLD_PIN_DC, FLD_PIN_RESET}; // custom SPI pins: CS, DC, RST + uint32_t ioFrequency = 1000000; // in Hz (minimum is 500kHz, baseline is 1MHz and maximum should be 20MHz) + #endif + + DisplayType type = FLD_TYPE; // display type + bool flip = false; // flip display 180° + uint8_t contrast = 10; // screen contrast + uint8_t lineHeight = 1; // 1 row or 2 rows + uint16_t refreshRate = REFRESH_RATE_MS; // in ms + uint32_t screenTimeout = SCREEN_TIMEOUT_MS; // in ms + bool sleepMode = true; // allow screen sleep? + bool clockMode = false; // display clock + bool showSeconds = true; // display clock with seconds + bool enabled = true; + bool contrastFix = false; + + // Next variables hold the previous known values to determine if redraw is + // required. + String knownSsid = apSSID; + IPAddress knownIp = IPAddress(4, 3, 2, 1); + uint8_t knownBrightness = 0; + uint8_t knownEffectSpeed = 0; + uint8_t knownEffectIntensity = 0; + uint8_t knownMode = 0; + uint8_t knownPalette = 0; + uint8_t knownMinute = 99; + uint8_t knownHour = 99; + byte brightness100; + byte fxspeed100; + byte fxintensity100; + bool knownnightlight = nightlightActive; + bool wificonnected = interfacesInited; + bool powerON = true; + + bool displayTurnedOff = false; + unsigned long nextUpdate = 0; + unsigned long lastRedraw = 0; + unsigned long overlayUntil = 0; + + // Set to 2 or 3 to mark lines 2 or 3. Other values ignored. + byte markLineNum = 255; + byte markColNum = 255; + + // strings to reduce flash memory usage (used more than twice) + static const char _name[]; + static const char _enabled[]; + static const char _contrast[]; + static const char _refreshRate[]; + static const char _screenTimeOut[]; + static const char _flip[]; + static const char _sleepMode[]; + static const char _clockMode[]; + static const char _showSeconds[]; + static const char _busClkFrequency[]; + static const char _contrastFix[]; + + // If display does not work or looks corrupted check the + // constructor reference: + // https://github.com/olikraus/u8g2/wiki/u8x8setupcpp + // or check the gallery: + // https://github.com/olikraus/u8g2/wiki/gallery + + // some displays need this to properly apply contrast + void setVcomh(bool highContrast); + void startDisplay(); + + /** + * Wrappers for screen drawing + */ + void setFlipMode(uint8_t mode); + void setContrast(uint8_t contrast); + void drawString(uint8_t col, uint8_t row, const char *string, bool ignoreLH=false); + void draw2x2String(uint8_t col, uint8_t row, const char *string); + void drawGlyph(uint8_t col, uint8_t row, char glyph, const uint8_t *font, bool ignoreLH=false); + void draw2x2Glyph(uint8_t col, uint8_t row, char glyph, const uint8_t *font); + void draw2x2GlyphIcons(); + uint8_t getCols(); + void clear(); + void setPowerSave(uint8_t save); + void center(String &line, uint8_t width); + + /** + * Display the current date and time in large characters + * on the middle rows. Based 24 or 12 hour depending on + * the useAMPM configuration. + */ + void showTime(); + + /** + * Enable sleep (turn the display off) or clock mode. + */ + void sleepOrClock(bool enabled); + + public: + + // gets called once at boot. Do all initialization that doesn't depend on + // network here + void setup() override; + + // gets called every time WiFi is (re-)connected. Initialize own network + // interfaces here + void connected() override; + + /** + * Da loop. + */ + void loop() override; + + //function to update lastredraw + inline void updateRedrawTime() { lastRedraw = millis(); } + + /** + * Redraw the screen (but only if things have changed + * or if forceRedraw). + */ + void redraw(bool forceRedraw); + + void updateBrightness(); + void updateSpeed(); + void updateIntensity(); + void drawStatusIcons(); + + /** + * marks the position of the arrow showing + * the current setting being changed + * pass line and colum info + */ + void setMarkLine(byte newMarkLineNum, byte newMarkColNum); + + //Draw the arrow for the current setting being changed + void drawArrow(); + + //Display the current effect or palette (desiredEntry) + // on the appropriate line (row). + void showCurrentEffectOrPalette(int inputEffPal, const char *qstring, uint8_t row); + + /** + * If there screen is off or in clock is displayed, + * this will return true. This allows us to throw away + * the first input from the rotary encoder but + * to wake up the screen. + */ + bool wakeDisplay(); + + /** + * Allows you to show one line and a glyph as overlay for a period of time. + * Clears the screen and prints. + * Used in Rotary Encoder usermod. + */ + void overlay(const char* line1, long showHowLong, byte glyphType); + + /** + * Allows you to show Akemi WLED logo overlay for a period of time. + * Clears the screen and prints. + */ + void overlayLogo(long showHowLong); + + /** + * Allows you to show two lines as overlay for a period of time. + * Clears the screen and prints. + * Used in Auto Save usermod + */ + void overlay(const char* line1, const char* line2, long showHowLong); + + void networkOverlay(const char* line1, long showHowLong); + + /** + * handleButton() can be used to override default button behaviour. Returning true + * will prevent button working in a default way. + * Replicating button.cpp + */ + bool handleButton(uint8_t b); + + void onUpdateBegin(bool init) override; + + /* + * 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) override; + + /* + * 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) override; + + /* + * 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) override; + + void appendConfigData() override; + + /* + * 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) override; + + /* + * 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 :) + */ + bool readFromConfig(JsonObject& root) override; + + /* + * getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!). + * This could be used in the future for the system to determine whether your usermod is installed. + */ + uint16_t getId() override { + return USERMOD_ID_FOUR_LINE_DISP; + } + + const char* getName() override { + return FPSTR(_name); + } + }; \ No newline at end of file diff --git a/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.cpp b/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.cpp index 1e6c358994..a4f008872d 100644 --- a/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.cpp +++ b/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.cpp @@ -3,9 +3,7 @@ class PingPongClockUsermod : public Usermod { private: - - static const char _name[]; - // Private class members. You can declare variables and functions only accessible to your usermod here + // Private class members. You can declare variables and functions only accessible to your usermod here unsigned long lastTime = 0; bool colonOn = true; @@ -116,14 +114,13 @@ class PingPongClockUsermod : public Usermod return USERMOD_ID_PING_PONG_CLOCK; } - const char* getName() override { - return FPSTR(_name); - } + const char* getName() override + { + return FPSTR(_name); + } }; -const char PingPongClockUsermod::_name[] PROGMEM = "Ping Pong Clock"; - static PingPongClockUsermod usermod_v2_ping_pong_clock; REGISTER_USERMOD(usermod_v2_ping_pong_clock); \ No newline at end of file diff --git a/usermods/wireguard/wireguard.cpp b/usermods/wireguard/wireguard.cpp index d3b0cab910..9a4f5b9738 100644 --- a/usermods/wireguard/wireguard.cpp +++ b/usermods/wireguard/wireguard.cpp @@ -111,13 +111,12 @@ class WireguardUsermod : public Usermod { uint16_t getId() { return USERMOD_ID_WIREGUARD; } - const char* getName() override { - return FPSTR(_name); + const char* getName() override + { + return FPSTR(_name); } private: - - static const char _name[]; WireGuard wg; char preshared_key[45]; char private_key[45]; @@ -130,7 +129,5 @@ class WireguardUsermod : public Usermod { unsigned long lastTime = 0; }; -const char WireguardUsermod::_name[] PROGMEM = "Wireguard"; - static WireguardUsermod wireguard; REGISTER_USERMOD(wireguard); \ No newline at end of file diff --git a/usermods/wizlights/wizlights.cpp b/usermods/wizlights/wizlights.cpp index 526f2ba7ed..360f972f26 100644 --- a/usermods/wizlights/wizlights.cpp +++ b/usermods/wizlights/wizlights.cpp @@ -12,8 +12,6 @@ WiFiUDP UDP; class WizLightsUsermod : public Usermod { private: - - static const char _name[]; unsigned long lastTime = 0; long updateInterval; long sendDelay; @@ -156,13 +154,12 @@ class WizLightsUsermod : public Usermod { uint16_t getId(){return USERMOD_ID_WIZLIGHTS;} - const char* getName() override { - return FPSTR(_name); + const char* getName() override + { + return FPSTR(_name); } }; -const char WizLightsUsermod::_name[] PROGMEM = "Wiz Lights"; - static WizLightsUsermod wizlights; REGISTER_USERMOD(wizlights); \ No newline at end of file diff --git a/usermods/word-clock-matrix/word-clock-matrix.cpp b/usermods/word-clock-matrix/word-clock-matrix.cpp index a030e914b3..adee87e437 100644 --- a/usermods/word-clock-matrix/word-clock-matrix.cpp +++ b/usermods/word-clock-matrix/word-clock-matrix.cpp @@ -10,9 +10,7 @@ class WordClockMatrix : public Usermod { private: - - static const char _name[]; - unsigned long lastTime = 0; + unsigned long lastTime = 0; uint8_t minuteLast = 99; int dayBrightness = 128; int nightBrightness = 16; @@ -334,15 +332,14 @@ class WordClockMatrix : public Usermod return 500; } - const char* getName() override { - return FPSTR(_name); + const char* getName() override + { + return FPSTR(_name); } }; -const char WordClockMatrix::_name[] PROGMEM = "Word Clock Matrix"; - static WordClockMatrix word_clock_matrix; REGISTER_USERMOD(word_clock_matrix); \ No newline at end of file From 423d319f88242ca789e1ebef79e734e98db10f74 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 28 Dec 2025 06:12:41 +0000 Subject: [PATCH 08/13] Fix FPSTR return type conversion error with reinterpret_cast Co-authored-by: DedeHai <6280424+DedeHai@users.noreply.github.com> --- usermods/ADS1115_v2/ADS1115_v2.cpp | 2 +- usermods/AHT10_v2/AHT10_v2.cpp | 2 +- usermods/Analog_Clock/Analog_Clock.cpp | 2 +- usermods/Animated_Staircase/Animated_Staircase.cpp | 2 +- usermods/BH1750_v2/BH1750_v2.h | 2 +- usermods/BME280_v2/BME280_v2.cpp | 2 +- usermods/BME68X_v2/BME68X_v2.cpp | 2 +- usermods/Battery/Battery.cpp | 2 +- usermods/Cronixie/Cronixie.cpp | 2 +- usermods/DHT/DHT.cpp | 2 +- usermods/EXAMPLE/usermod_v2_example.cpp | 2 +- usermods/EleksTube_IPS/EleksTube_IPS.cpp | 2 +- .../usermod_Fix_unreachable_netservices.cpp | 2 +- usermods/INA226_v2/INA226_v2.cpp | 2 +- usermods/Internal_Temperature_v2/Internal_Temperature_v2.cpp | 2 +- usermods/LD2410_v2/LD2410_v2.cpp | 2 +- usermods/LDR_Dusk_Dawn_v2/LDR_Dusk_Dawn_v2.cpp | 2 +- usermods/MAX17048_v2/MAX17048_v2.cpp | 2 +- usermods/MY9291/MY9291.cpp | 2 +- usermods/PIR_sensor_switch/PIR_sensor_switch.cpp | 2 +- usermods/PWM_fan/PWM_fan.cpp | 2 +- usermods/RTC/RTC.cpp | 2 +- usermods/SN_Photoresistor/SN_Photoresistor.h | 2 +- usermods/ST7789_display/ST7789_display.cpp | 2 +- usermods/Si7021_MQTT_HA/Si7021_MQTT_HA.cpp | 2 +- usermods/Temperature/UsermodTemperature.h | 2 +- usermods/TetrisAI_v2/TetrisAI_v2.cpp | 2 +- usermods/VL53L0X_gestures/VL53L0X_gestures.cpp | 2 +- usermods/boblight/boblight.cpp | 2 +- usermods/buzzer/buzzer.cpp | 2 +- usermods/deep_sleep/deep_sleep.cpp | 2 +- usermods/mpu6050_imu/mpu6050_imu.cpp | 2 +- usermods/mpu6050_imu/usermod_gyro_surge.h | 2 +- usermods/multi_relay/multi_relay.cpp | 2 +- usermods/pixels_dice_tray/pixels_dice_tray.cpp | 2 +- usermods/pwm_outputs/pwm_outputs.cpp | 2 +- usermods/quinled-an-penta/quinled-an-penta.cpp | 2 +- usermods/rgb-rotary-encoder/rgb-rotary-encoder.cpp | 2 +- usermods/sd_card/sd_card.cpp | 2 +- usermods/sensors_to_mqtt/sensors_to_mqtt.cpp | 2 +- usermods/seven_segment_display/seven_segment_display.cpp | 2 +- .../seven_segment_display_reloaded.cpp | 2 +- usermods/sht/ShtUsermod.h | 2 +- usermods/smartnest/smartnest.cpp | 2 +- usermods/stairway_wipe_basic/stairway_wipe_basic.cpp | 2 +- usermods/udp_name_sync/udp_name_sync.cpp | 2 +- usermods/user_fx/user_fx.cpp | 2 +- .../usermod_rotary_brightness_color.cpp | 2 +- .../usermod_v2_HttpPullLightControl.h | 2 +- usermods/usermod_v2_RF433/usermod_v2_RF433.cpp | 2 +- usermods/usermod_v2_auto_save/usermod_v2_auto_save.cpp | 2 +- .../usermod_v2_brightness_follow_sun.cpp | 2 +- .../usermod_v2_four_line_display.h | 2 +- .../usermod_v2_klipper_percentage.cpp | 2 +- .../usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.cpp | 2 +- .../usermod_v2_rotary_encoder_ui_ALT.cpp | 2 +- usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp | 2 +- usermods/wireguard/wireguard.cpp | 2 +- usermods/wizlights/wizlights.cpp | 2 +- usermods/word-clock-matrix/word-clock-matrix.cpp | 2 +- 60 files changed, 60 insertions(+), 60 deletions(-) diff --git a/usermods/ADS1115_v2/ADS1115_v2.cpp b/usermods/ADS1115_v2/ADS1115_v2.cpp index fe06f764be..2261360923 100644 --- a/usermods/ADS1115_v2/ADS1115_v2.cpp +++ b/usermods/ADS1115_v2/ADS1115_v2.cpp @@ -120,7 +120,7 @@ class ADS1115Usermod : public Usermod { const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } private: diff --git a/usermods/AHT10_v2/AHT10_v2.cpp b/usermods/AHT10_v2/AHT10_v2.cpp index c152351357..cc13af1a51 100644 --- a/usermods/AHT10_v2/AHT10_v2.cpp +++ b/usermods/AHT10_v2/AHT10_v2.cpp @@ -184,7 +184,7 @@ class UsermodAHT10 : public Usermod const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } void addToJsonInfo(JsonObject &root) override diff --git a/usermods/Analog_Clock/Analog_Clock.cpp b/usermods/Analog_Clock/Analog_Clock.cpp index c544c0315e..7154ed0aae 100644 --- a/usermods/Analog_Clock/Analog_Clock.cpp +++ b/usermods/Analog_Clock/Analog_Clock.cpp @@ -255,7 +255,7 @@ class AnalogClockUsermod : public Usermod { const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/Animated_Staircase/Animated_Staircase.cpp b/usermods/Animated_Staircase/Animated_Staircase.cpp index 6f9a327449..83ef838887 100644 --- a/usermods/Animated_Staircase/Animated_Staircase.cpp +++ b/usermods/Animated_Staircase/Animated_Staircase.cpp @@ -355,7 +355,7 @@ class Animated_Staircase : public Usermod { const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } #ifndef WLED_DISABLE_MQTT diff --git a/usermods/BH1750_v2/BH1750_v2.h b/usermods/BH1750_v2/BH1750_v2.h index 04c1ed2a52..e77934d720 100644 --- a/usermods/BH1750_v2/BH1750_v2.h +++ b/usermods/BH1750_v2/BH1750_v2.h @@ -91,7 +91,7 @@ class Usermod_BH1750 : public Usermod inline const char* getName() { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/BME280_v2/BME280_v2.cpp b/usermods/BME280_v2/BME280_v2.cpp index 17ffd538bc..a40b54e4a3 100644 --- a/usermods/BME280_v2/BME280_v2.cpp +++ b/usermods/BME280_v2/BME280_v2.cpp @@ -476,7 +476,7 @@ class UsermodBME280 : public Usermod const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/BME68X_v2/BME68X_v2.cpp b/usermods/BME68X_v2/BME68X_v2.cpp index 370a8b67fa..4fe30756dc 100644 --- a/usermods/BME68X_v2/BME68X_v2.cpp +++ b/usermods/BME68X_v2/BME68X_v2.cpp @@ -871,7 +871,7 @@ * @return const char* User module name */ const char* UsermodBME68X::getName() { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } diff --git a/usermods/Battery/Battery.cpp b/usermods/Battery/Battery.cpp index 0a84b2b1d4..c02c652922 100644 --- a/usermods/Battery/Battery.cpp +++ b/usermods/Battery/Battery.cpp @@ -606,7 +606,7 @@ class UsermodBattery : public Usermod const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } /** diff --git a/usermods/Cronixie/Cronixie.cpp b/usermods/Cronixie/Cronixie.cpp index a62f72815a..74fc5e6234 100644 --- a/usermods/Cronixie/Cronixie.cpp +++ b/usermods/Cronixie/Cronixie.cpp @@ -300,7 +300,7 @@ class UsermodCronixie : public Usermod { const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/DHT/DHT.cpp b/usermods/DHT/DHT.cpp index 594e958422..e75bba5b0b 100644 --- a/usermods/DHT/DHT.cpp +++ b/usermods/DHT/DHT.cpp @@ -244,7 +244,7 @@ class UsermodDHT : public Usermod { const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/EXAMPLE/usermod_v2_example.cpp b/usermods/EXAMPLE/usermod_v2_example.cpp index fc6a864271..b77def02ca 100644 --- a/usermods/EXAMPLE/usermod_v2_example.cpp +++ b/usermods/EXAMPLE/usermod_v2_example.cpp @@ -384,7 +384,7 @@ class MyExampleUsermod : public Usermod { */ const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } //More methods can be added in the future, this example will then be extended. diff --git a/usermods/EleksTube_IPS/EleksTube_IPS.cpp b/usermods/EleksTube_IPS/EleksTube_IPS.cpp index 4b6a234957..f4626be1a0 100644 --- a/usermods/EleksTube_IPS/EleksTube_IPS.cpp +++ b/usermods/EleksTube_IPS/EleksTube_IPS.cpp @@ -152,7 +152,7 @@ class ElekstubeIPSUsermod : public Usermod { const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp b/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp index 5d7450d1ac..7aed8db97f 100644 --- a/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp +++ b/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp @@ -162,7 +162,7 @@ Delay (FPSTR(_name)); } }; diff --git a/usermods/INA226_v2/INA226_v2.cpp b/usermods/INA226_v2/INA226_v2.cpp index ca1b20ede6..9434bc26c4 100644 --- a/usermods/INA226_v2/INA226_v2.cpp +++ b/usermods/INA226_v2/INA226_v2.cpp @@ -361,7 +361,7 @@ class UsermodINA226 : public Usermod const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } void addToJsonInfo(JsonObject &root) override diff --git a/usermods/Internal_Temperature_v2/Internal_Temperature_v2.cpp b/usermods/Internal_Temperature_v2/Internal_Temperature_v2.cpp index bc59b10196..8f51947f15 100644 --- a/usermods/Internal_Temperature_v2/Internal_Temperature_v2.cpp +++ b/usermods/Internal_Temperature_v2/Internal_Temperature_v2.cpp @@ -174,7 +174,7 @@ class InternalTemperatureUsermod : public Usermod const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/LD2410_v2/LD2410_v2.cpp b/usermods/LD2410_v2/LD2410_v2.cpp index 27085b11fa..a3c49671b0 100644 --- a/usermods/LD2410_v2/LD2410_v2.cpp +++ b/usermods/LD2410_v2/LD2410_v2.cpp @@ -211,7 +211,7 @@ class LD2410Usermod : public Usermod { const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/LDR_Dusk_Dawn_v2/LDR_Dusk_Dawn_v2.cpp b/usermods/LDR_Dusk_Dawn_v2/LDR_Dusk_Dawn_v2.cpp index 34708bf4b5..c1c5215f90 100644 --- a/usermods/LDR_Dusk_Dawn_v2/LDR_Dusk_Dawn_v2.cpp +++ b/usermods/LDR_Dusk_Dawn_v2/LDR_Dusk_Dawn_v2.cpp @@ -150,7 +150,7 @@ class LDR_Dusk_Dawn_v2 : public Usermod { const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/MAX17048_v2/MAX17048_v2.cpp b/usermods/MAX17048_v2/MAX17048_v2.cpp index 1e6558064f..8061151eec 100644 --- a/usermods/MAX17048_v2/MAX17048_v2.cpp +++ b/usermods/MAX17048_v2/MAX17048_v2.cpp @@ -270,7 +270,7 @@ class Usermod_MAX17048 : public Usermod { const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/MY9291/MY9291.cpp b/usermods/MY9291/MY9291.cpp index 9e89c86285..a81631e9ee 100644 --- a/usermods/MY9291/MY9291.cpp +++ b/usermods/MY9291/MY9291.cpp @@ -43,7 +43,7 @@ class MY9291Usermod : public Usermod { const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/PIR_sensor_switch/PIR_sensor_switch.cpp b/usermods/PIR_sensor_switch/PIR_sensor_switch.cpp index 12684a3b99..3460e28bcb 100644 --- a/usermods/PIR_sensor_switch/PIR_sensor_switch.cpp +++ b/usermods/PIR_sensor_switch/PIR_sensor_switch.cpp @@ -190,7 +190,7 @@ class PIRsensorSwitch : public Usermod const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/PWM_fan/PWM_fan.cpp b/usermods/PWM_fan/PWM_fan.cpp index 4d8d5e4492..ab26f06826 100644 --- a/usermods/PWM_fan/PWM_fan.cpp +++ b/usermods/PWM_fan/PWM_fan.cpp @@ -390,7 +390,7 @@ class PWMFanUsermod : public Usermod { const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/RTC/RTC.cpp b/usermods/RTC/RTC.cpp index cbd1a1cda6..ca7a4cf0f3 100644 --- a/usermods/RTC/RTC.cpp +++ b/usermods/RTC/RTC.cpp @@ -49,7 +49,7 @@ class RTCUsermod : public Usermod { const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/SN_Photoresistor/SN_Photoresistor.h b/usermods/SN_Photoresistor/SN_Photoresistor.h index 2c21cc9062..69e58d2cd6 100644 --- a/usermods/SN_Photoresistor/SN_Photoresistor.h +++ b/usermods/SN_Photoresistor/SN_Photoresistor.h @@ -80,7 +80,7 @@ class Usermod_SN_Photoresistor : public Usermod const char* getName() { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } /** diff --git a/usermods/ST7789_display/ST7789_display.cpp b/usermods/ST7789_display/ST7789_display.cpp index 74e650df05..6d19cc77e4 100644 --- a/usermods/ST7789_display/ST7789_display.cpp +++ b/usermods/ST7789_display/ST7789_display.cpp @@ -408,7 +408,7 @@ class St7789DisplayUsermod : public Usermod { const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } //More methods can be added in the future, this example will then be extended. diff --git a/usermods/Si7021_MQTT_HA/Si7021_MQTT_HA.cpp b/usermods/Si7021_MQTT_HA/Si7021_MQTT_HA.cpp index 8640733272..4b2562545b 100644 --- a/usermods/Si7021_MQTT_HA/Si7021_MQTT_HA.cpp +++ b/usermods/Si7021_MQTT_HA/Si7021_MQTT_HA.cpp @@ -223,7 +223,7 @@ class Si7021_MQTT_HA : public Usermod const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/Temperature/UsermodTemperature.h b/usermods/Temperature/UsermodTemperature.h index 5f9aa20258..034a31cb88 100644 --- a/usermods/Temperature/UsermodTemperature.h +++ b/usermods/Temperature/UsermodTemperature.h @@ -90,7 +90,7 @@ class UsermodTemperature : public Usermod { const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } void setup() override; diff --git a/usermods/TetrisAI_v2/TetrisAI_v2.cpp b/usermods/TetrisAI_v2/TetrisAI_v2.cpp index 3eb82a2326..ed78563d51 100644 --- a/usermods/TetrisAI_v2/TetrisAI_v2.cpp +++ b/usermods/TetrisAI_v2/TetrisAI_v2.cpp @@ -251,7 +251,7 @@ class TetrisAIUsermod : public Usermod const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/VL53L0X_gestures/VL53L0X_gestures.cpp b/usermods/VL53L0X_gestures/VL53L0X_gestures.cpp index f575110287..74ec2a6a8c 100644 --- a/usermods/VL53L0X_gestures/VL53L0X_gestures.cpp +++ b/usermods/VL53L0X_gestures/VL53L0X_gestures.cpp @@ -127,7 +127,7 @@ class UsermodVL53L0XGestures : public Usermod { const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/boblight/boblight.cpp b/usermods/boblight/boblight.cpp index dd64b22792..4c5229d85b 100644 --- a/usermods/boblight/boblight.cpp +++ b/usermods/boblight/boblight.cpp @@ -361,7 +361,7 @@ class BobLightUsermod : public Usermod { const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/buzzer/buzzer.cpp b/usermods/buzzer/buzzer.cpp index 5bfa403793..5ce2ab6980 100644 --- a/usermods/buzzer/buzzer.cpp +++ b/usermods/buzzer/buzzer.cpp @@ -80,7 +80,7 @@ class BuzzerUsermod : public Usermod { const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/deep_sleep/deep_sleep.cpp b/usermods/deep_sleep/deep_sleep.cpp index 25e2de00cc..5e87cdf03b 100644 --- a/usermods/deep_sleep/deep_sleep.cpp +++ b/usermods/deep_sleep/deep_sleep.cpp @@ -220,7 +220,7 @@ void addToConfig(JsonObject& root) override const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/mpu6050_imu/mpu6050_imu.cpp b/usermods/mpu6050_imu/mpu6050_imu.cpp index 224c0538bb..847b1c02f5 100644 --- a/usermods/mpu6050_imu/mpu6050_imu.cpp +++ b/usermods/mpu6050_imu/mpu6050_imu.cpp @@ -434,7 +434,7 @@ class MPU6050Driver : public Usermod { const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/mpu6050_imu/usermod_gyro_surge.h b/usermods/mpu6050_imu/usermod_gyro_surge.h index a0255e149c..873f810e0e 100644 --- a/usermods/mpu6050_imu/usermod_gyro_surge.h +++ b/usermods/mpu6050_imu/usermod_gyro_surge.h @@ -216,7 +216,7 @@ class GyroSurge : public Usermod { } const char* getName() { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/multi_relay/multi_relay.cpp b/usermods/multi_relay/multi_relay.cpp index 3a396b01e7..f8e27dc3c5 100644 --- a/usermods/multi_relay/multi_relay.cpp +++ b/usermods/multi_relay/multi_relay.cpp @@ -148,7 +148,7 @@ class MultiRelay : public Usermod { const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } /** diff --git a/usermods/pixels_dice_tray/pixels_dice_tray.cpp b/usermods/pixels_dice_tray/pixels_dice_tray.cpp index 6723f4c333..a741b898f4 100644 --- a/usermods/pixels_dice_tray/pixels_dice_tray.cpp +++ b/usermods/pixels_dice_tray/pixels_dice_tray.cpp @@ -529,7 +529,7 @@ class PixelsDiceTrayUsermod : public Usermod { const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } // More methods can be added in the future, this example will then be diff --git a/usermods/pwm_outputs/pwm_outputs.cpp b/usermods/pwm_outputs/pwm_outputs.cpp index db58f63e70..40ea69748f 100644 --- a/usermods/pwm_outputs/pwm_outputs.cpp +++ b/usermods/pwm_outputs/pwm_outputs.cpp @@ -213,7 +213,7 @@ class PwmOutputsUsermod : public Usermod { const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } private: diff --git a/usermods/quinled-an-penta/quinled-an-penta.cpp b/usermods/quinled-an-penta/quinled-an-penta.cpp index b99ffbc6eb..1cfc66625f 100644 --- a/usermods/quinled-an-penta/quinled-an-penta.cpp +++ b/usermods/quinled-an-penta/quinled-an-penta.cpp @@ -690,7 +690,7 @@ class QuinLEDAnPentaUsermod : public Usermod const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/rgb-rotary-encoder/rgb-rotary-encoder.cpp b/usermods/rgb-rotary-encoder/rgb-rotary-encoder.cpp index ad41fc520d..50cdaad903 100644 --- a/usermods/rgb-rotary-encoder/rgb-rotary-encoder.cpp +++ b/usermods/rgb-rotary-encoder/rgb-rotary-encoder.cpp @@ -330,7 +330,7 @@ class RgbRotaryEncoderUsermod : public Usermod const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } //More methods can be added in the future, this example will then be extended. diff --git a/usermods/sd_card/sd_card.cpp b/usermods/sd_card/sd_card.cpp index efabd69763..ee90375d2f 100644 --- a/usermods/sd_card/sd_card.cpp +++ b/usermods/sd_card/sd_card.cpp @@ -134,7 +134,7 @@ class UsermodSdCard : public Usermod { const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } void addToConfig(JsonObject& root) diff --git a/usermods/sensors_to_mqtt/sensors_to_mqtt.cpp b/usermods/sensors_to_mqtt/sensors_to_mqtt.cpp index a48dce5ed9..01c43163bf 100644 --- a/usermods/sensors_to_mqtt/sensors_to_mqtt.cpp +++ b/usermods/sensors_to_mqtt/sensors_to_mqtt.cpp @@ -278,7 +278,7 @@ class UserMod_SensorsToMQTT : public Usermod const char* getName() { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/seven_segment_display/seven_segment_display.cpp b/usermods/seven_segment_display/seven_segment_display.cpp index c60f9df511..afa2ecdde8 100644 --- a/usermods/seven_segment_display/seven_segment_display.cpp +++ b/usermods/seven_segment_display/seven_segment_display.cpp @@ -489,7 +489,7 @@ class SevenSegmentDisplay : public Usermod const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/seven_segment_display_reloaded/seven_segment_display_reloaded.cpp b/usermods/seven_segment_display_reloaded/seven_segment_display_reloaded.cpp index dfc8123e3a..5cfe09a909 100644 --- a/usermods/seven_segment_display_reloaded/seven_segment_display_reloaded.cpp +++ b/usermods/seven_segment_display_reloaded/seven_segment_display_reloaded.cpp @@ -582,7 +582,7 @@ class UsermodSSDR : public Usermod { } const char* getName() { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/sht/ShtUsermod.h b/usermods/sht/ShtUsermod.h index bb6770bb86..c045336af2 100644 --- a/usermods/sht/ShtUsermod.h +++ b/usermods/sht/ShtUsermod.h @@ -71,6 +71,6 @@ class ShtUsermod : public Usermod const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/smartnest/smartnest.cpp b/usermods/smartnest/smartnest.cpp index e06c0f2d88..1a6510764c 100644 --- a/usermods/smartnest/smartnest.cpp +++ b/usermods/smartnest/smartnest.cpp @@ -173,7 +173,7 @@ class Smartnest : public Usermod const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } /** diff --git a/usermods/stairway_wipe_basic/stairway_wipe_basic.cpp b/usermods/stairway_wipe_basic/stairway_wipe_basic.cpp index 308ac0b5fc..c5fec0a1c9 100644 --- a/usermods/stairway_wipe_basic/stairway_wipe_basic.cpp +++ b/usermods/stairway_wipe_basic/stairway_wipe_basic.cpp @@ -91,7 +91,7 @@ void setup() { const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } diff --git a/usermods/udp_name_sync/udp_name_sync.cpp b/usermods/udp_name_sync/udp_name_sync.cpp index 1c2d291717..a2ebac2189 100644 --- a/usermods/udp_name_sync/udp_name_sync.cpp +++ b/usermods/udp_name_sync/udp_name_sync.cpp @@ -81,7 +81,7 @@ class UdpNameSync : public Usermod { } const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/user_fx/user_fx.cpp b/usermods/user_fx/user_fx.cpp index cf1f8e7b18..ef63f10599 100644 --- a/usermods/user_fx/user_fx.cpp +++ b/usermods/user_fx/user_fx.cpp @@ -114,7 +114,7 @@ class UserFxUsermod : public Usermod { const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.cpp b/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.cpp index 4acdf662ef..a39df0e566 100644 --- a/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.cpp +++ b/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.cpp @@ -188,7 +188,7 @@ class RotaryEncoderBrightnessColor : public Usermod const char* getName() { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/usermod_v2_HttpPullLightControl/usermod_v2_HttpPullLightControl.h b/usermods/usermod_v2_HttpPullLightControl/usermod_v2_HttpPullLightControl.h index 1071675675..5e49c1086e 100644 --- a/usermods/usermod_v2_HttpPullLightControl/usermod_v2_HttpPullLightControl.h +++ b/usermods/usermod_v2_HttpPullLightControl/usermod_v2_HttpPullLightControl.h @@ -89,7 +89,7 @@ class HttpPullLightControl : public Usermod { const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } inline void enable(bool enable) { enabled = enable; } // Enable or Disable the usermod inline bool isEnabled() { return enabled; } // Get usermod enabled or disabled state diff --git a/usermods/usermod_v2_RF433/usermod_v2_RF433.cpp b/usermods/usermod_v2_RF433/usermod_v2_RF433.cpp index 26f4ee569d..16a4b46bc1 100644 --- a/usermods/usermod_v2_RF433/usermod_v2_RF433.cpp +++ b/usermods/usermod_v2_RF433/usermod_v2_RF433.cpp @@ -120,7 +120,7 @@ class RF433Usermod : public Usermod const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } // this function follows the same principle as decodeIRJson() / remoteJson() diff --git a/usermods/usermod_v2_auto_save/usermod_v2_auto_save.cpp b/usermods/usermod_v2_auto_save/usermod_v2_auto_save.cpp index c16cd43e29..fdb83029a9 100644 --- a/usermods/usermod_v2_auto_save/usermod_v2_auto_save.cpp +++ b/usermods/usermod_v2_auto_save/usermod_v2_auto_save.cpp @@ -268,7 +268,7 @@ class AutoSaveUsermod : public Usermod { const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/usermod_v2_brightness_follow_sun/usermod_v2_brightness_follow_sun.cpp b/usermods/usermod_v2_brightness_follow_sun/usermod_v2_brightness_follow_sun.cpp index d598777553..fd5708bc43 100644 --- a/usermods/usermod_v2_brightness_follow_sun/usermod_v2_brightness_follow_sun.cpp +++ b/usermods/usermod_v2_brightness_follow_sun/usermod_v2_brightness_follow_sun.cpp @@ -41,7 +41,7 @@ class UsermodBrightnessFollowSun : public Usermod const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } void update() diff --git a/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display.h b/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display.h index 725a9e2baf..7f3fe50ffc 100644 --- a/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display.h +++ b/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display.h @@ -313,7 +313,7 @@ class FourLineDisplayUsermod : public Usermod { } const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; \ No newline at end of file diff --git a/usermods/usermod_v2_klipper_percentage/usermod_v2_klipper_percentage.cpp b/usermods/usermod_v2_klipper_percentage/usermod_v2_klipper_percentage.cpp index 3e3b332f4f..0f2aa25789 100644 --- a/usermods/usermod_v2_klipper_percentage/usermod_v2_klipper_percentage.cpp +++ b/usermods/usermod_v2_klipper_percentage/usermod_v2_klipper_percentage.cpp @@ -218,7 +218,7 @@ class klipper_percentage : public Usermod const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; const char klipper_percentage::_name[] PROGMEM = "Klipper_Percentage"; diff --git a/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.cpp b/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.cpp index a4f008872d..1c70b89e4e 100644 --- a/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.cpp +++ b/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.cpp @@ -116,7 +116,7 @@ class PingPongClockUsermod : public Usermod const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.cpp b/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.cpp index 60537bbb87..a544e9f5e5 100644 --- a/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.cpp +++ b/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.cpp @@ -291,7 +291,7 @@ class RotaryEncoderUIUsermod : public Usermod { const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } /** * Enable/Disable the usermod diff --git a/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp b/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp index 89a0e50999..af8c636704 100644 --- a/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp +++ b/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp @@ -503,7 +503,7 @@ class WordClockUsermod : public Usermod } const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } //More methods can be added in the future, this example will then be extended. diff --git a/usermods/wireguard/wireguard.cpp b/usermods/wireguard/wireguard.cpp index 9a4f5b9738..7ca907fb40 100644 --- a/usermods/wireguard/wireguard.cpp +++ b/usermods/wireguard/wireguard.cpp @@ -113,7 +113,7 @@ class WireguardUsermod : public Usermod { const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } private: diff --git a/usermods/wizlights/wizlights.cpp b/usermods/wizlights/wizlights.cpp index 360f972f26..cc770a6673 100644 --- a/usermods/wizlights/wizlights.cpp +++ b/usermods/wizlights/wizlights.cpp @@ -156,7 +156,7 @@ class WizLightsUsermod : public Usermod { const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } }; diff --git a/usermods/word-clock-matrix/word-clock-matrix.cpp b/usermods/word-clock-matrix/word-clock-matrix.cpp index adee87e437..2179fd8a6f 100644 --- a/usermods/word-clock-matrix/word-clock-matrix.cpp +++ b/usermods/word-clock-matrix/word-clock-matrix.cpp @@ -334,7 +334,7 @@ class WordClockMatrix : public Usermod const char* getName() override { - return FPSTR(_name); + return reinterpret_cast(FPSTR(_name)); } From f56c0829729bd6c8ed05ef0966d5061c6a7b07f4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 28 Dec 2025 07:04:57 +0000 Subject: [PATCH 09/13] Fix getName() to return const char* directly without FPSTR casting Co-authored-by: DedeHai <6280424+DedeHai@users.noreply.github.com> --- usermods/ADS1115_v2/ADS1115_v2.cpp | 2 +- usermods/AHT10_v2/AHT10_v2.cpp | 2 +- usermods/Analog_Clock/Analog_Clock.cpp | 11 +++++++---- usermods/Animated_Staircase/Animated_Staircase.cpp | 2 +- usermods/BH1750_v2/BH1750_v2.h | 2 +- usermods/BME280_v2/BME280_v2.cpp | 2 +- usermods/BME68X_v2/BME68X_v2.cpp | 3 ++- usermods/Battery/Battery.cpp | 2 +- usermods/Cronixie/Cronixie.cpp | 11 +++++++---- usermods/DHT/DHT.cpp | 11 +++++++---- usermods/EXAMPLE/usermod_v2_example.cpp | 2 +- usermods/EleksTube_IPS/EleksTube_IPS.cpp | 2 +- .../usermod_Fix_unreachable_netservices.cpp | 13 ++++++++----- usermods/INA226_v2/INA226_v2.cpp | 2 +- .../Internal_Temperature_v2.cpp | 2 +- usermods/LD2410_v2/LD2410_v2.cpp | 2 +- usermods/LDR_Dusk_Dawn_v2/LDR_Dusk_Dawn_v2.cpp | 2 +- usermods/MAX17048_v2/MAX17048_v2.cpp | 2 +- usermods/MY9291/MY9291.cpp | 11 +++++++---- usermods/PIR_sensor_switch/PIR_sensor_switch.cpp | 2 +- usermods/PWM_fan/PWM_fan.cpp | 2 +- usermods/RTC/RTC.cpp | 11 +++++++---- usermods/SN_Photoresistor/SN_Photoresistor.h | 2 +- usermods/ST7789_display/ST7789_display.cpp | 7 +++++-- usermods/Si7021_MQTT_HA/Si7021_MQTT_HA.cpp | 2 +- usermods/Temperature/UsermodTemperature.h | 2 +- usermods/TetrisAI_v2/TetrisAI_v2.cpp | 2 +- usermods/VL53L0X_gestures/VL53L0X_gestures.cpp | 11 +++++++---- usermods/audioreactive/audio_reactive.cpp | 2 +- usermods/boblight/boblight.cpp | 2 +- usermods/buzzer/buzzer.cpp | 11 +++++++---- usermods/deep_sleep/deep_sleep.cpp | 2 +- usermods/mpu6050_imu/mpu6050_imu.cpp | 2 +- usermods/mpu6050_imu/usermod_gyro_surge.h | 2 +- usermods/multi_relay/multi_relay.cpp | 2 +- usermods/pixels_dice_tray/pixels_dice_tray.cpp | 13 ++++++++----- usermods/pwm_outputs/pwm_outputs.cpp | 11 +++++++---- usermods/quinled-an-penta/quinled-an-penta.cpp | 2 +- usermods/rgb-rotary-encoder/rgb-rotary-encoder.cpp | 2 +- usermods/sd_card/sd_card.cpp | 2 +- usermods/sensors_to_mqtt/sensors_to_mqtt.cpp | 7 +++---- .../seven_segment_display/seven_segment_display.cpp | 13 ++++++++----- .../seven_segment_display_reloaded.cpp | 2 +- usermods/sht/ShtUsermod.h | 2 +- usermods/smartnest/smartnest.cpp | 13 ++++++++----- .../stairway_wipe_basic/stairway_wipe_basic.cpp | 11 +++++++---- usermods/udp_name_sync/udp_name_sync.cpp | 4 +++- usermods/user_fx/user_fx.cpp | 13 ++++++++----- .../usermod_rotary_brightness_color.cpp | 13 +++++++------ .../usermod_v2_HttpPullLightControl.h | 2 +- usermods/usermod_v2_RF433/usermod_v2_RF433.cpp | 13 ++++++++----- .../usermod_v2_auto_save/usermod_v2_auto_save.cpp | 2 +- .../usermod_v2_brightness_follow_sun.cpp | 2 +- .../usermod_v2_four_line_display.h | 2 +- .../usermod_v2_klipper_percentage.cpp | 2 +- .../usermod_v2_ping_pong_clock.cpp | 13 ++++++++----- .../usermod_v2_rotary_encoder_ui_ALT.cpp | 2 +- .../usermod_v2_word_clock/usermod_v2_word_clock.cpp | 2 +- usermods/wireguard/wireguard.cpp | 11 +++++++---- usermods/wizlights/wizlights.cpp | 11 +++++++---- usermods/word-clock-matrix/word-clock-matrix.cpp | 11 +++++++---- 61 files changed, 197 insertions(+), 134 deletions(-) diff --git a/usermods/ADS1115_v2/ADS1115_v2.cpp b/usermods/ADS1115_v2/ADS1115_v2.cpp index 2261360923..3d56438d53 100644 --- a/usermods/ADS1115_v2/ADS1115_v2.cpp +++ b/usermods/ADS1115_v2/ADS1115_v2.cpp @@ -120,7 +120,7 @@ class ADS1115Usermod : public Usermod { const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } private: diff --git a/usermods/AHT10_v2/AHT10_v2.cpp b/usermods/AHT10_v2/AHT10_v2.cpp index cc13af1a51..d851c0d78a 100644 --- a/usermods/AHT10_v2/AHT10_v2.cpp +++ b/usermods/AHT10_v2/AHT10_v2.cpp @@ -184,7 +184,7 @@ class UsermodAHT10 : public Usermod const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } void addToJsonInfo(JsonObject &root) override diff --git a/usermods/Analog_Clock/Analog_Clock.cpp b/usermods/Analog_Clock/Analog_Clock.cpp index 7154ed0aae..e5835f0ca6 100644 --- a/usermods/Analog_Clock/Analog_Clock.cpp +++ b/usermods/Analog_Clock/Analog_Clock.cpp @@ -7,7 +7,9 @@ extern Timezone* tz; class AnalogClockUsermod : public Usermod { private: - static constexpr uint32_t refreshRate = 50; // per second + + static const char _name[]; +static constexpr uint32_t refreshRate = 50; // per second static constexpr uint32_t refreshDelay = 1000 / refreshRate; struct Segment { @@ -253,12 +255,13 @@ class AnalogClockUsermod : public Usermod { return USERMOD_ID_ANALOG_CLOCK; } - const char* getName() override - { - return reinterpret_cast(FPSTR(_name)); + const char* getName() override { + return _name; } }; +const char AnalogClockUsermod::_name[] PROGMEM = "Analog Clock"; + static AnalogClockUsermod analog_clock; REGISTER_USERMOD(analog_clock); \ No newline at end of file diff --git a/usermods/Animated_Staircase/Animated_Staircase.cpp b/usermods/Animated_Staircase/Animated_Staircase.cpp index 83ef838887..0d4df05a66 100644 --- a/usermods/Animated_Staircase/Animated_Staircase.cpp +++ b/usermods/Animated_Staircase/Animated_Staircase.cpp @@ -355,7 +355,7 @@ class Animated_Staircase : public Usermod { const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } #ifndef WLED_DISABLE_MQTT diff --git a/usermods/BH1750_v2/BH1750_v2.h b/usermods/BH1750_v2/BH1750_v2.h index e77934d720..fe80c42eb3 100644 --- a/usermods/BH1750_v2/BH1750_v2.h +++ b/usermods/BH1750_v2/BH1750_v2.h @@ -91,7 +91,7 @@ class Usermod_BH1750 : public Usermod inline const char* getName() { - return reinterpret_cast(FPSTR(_name)); + return _name; } }; diff --git a/usermods/BME280_v2/BME280_v2.cpp b/usermods/BME280_v2/BME280_v2.cpp index a40b54e4a3..5fbe571be5 100644 --- a/usermods/BME280_v2/BME280_v2.cpp +++ b/usermods/BME280_v2/BME280_v2.cpp @@ -476,7 +476,7 @@ class UsermodBME280 : public Usermod const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } }; diff --git a/usermods/BME68X_v2/BME68X_v2.cpp b/usermods/BME68X_v2/BME68X_v2.cpp index 4fe30756dc..4c2a055aeb 100644 --- a/usermods/BME68X_v2/BME68X_v2.cpp +++ b/usermods/BME68X_v2/BME68X_v2.cpp @@ -45,6 +45,7 @@ public: /* Public: Functions */ uint16_t getId(); + const char* getName(); void loop(); // Loop of the user module called by wled main in loop void setup(); // Setup of the user module called by wled main void addToConfig(JsonObject& root); // Extends the settings/user module settings page to include the user module requirements. The settings are written from the wled core to the configuration file. @@ -871,7 +872,7 @@ * @return const char* User module name */ const char* UsermodBME68X::getName() { - return reinterpret_cast(FPSTR(_name)); + return _name; } diff --git a/usermods/Battery/Battery.cpp b/usermods/Battery/Battery.cpp index c02c652922..3fbea6c45d 100644 --- a/usermods/Battery/Battery.cpp +++ b/usermods/Battery/Battery.cpp @@ -606,7 +606,7 @@ class UsermodBattery : public Usermod const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } /** diff --git a/usermods/Cronixie/Cronixie.cpp b/usermods/Cronixie/Cronixie.cpp index 74fc5e6234..a111df31b8 100644 --- a/usermods/Cronixie/Cronixie.cpp +++ b/usermods/Cronixie/Cronixie.cpp @@ -2,7 +2,9 @@ class UsermodCronixie : public Usermod { private: - unsigned long lastTime = 0; + + static const char _name[]; +unsigned long lastTime = 0; char cronixieDisplay[7] = "HHMMSS"; byte _digitOut[6] = {10,10,10,10,10,10}; byte dP[6] = {255, 255, 255, 255, 255, 255}; @@ -298,11 +300,12 @@ class UsermodCronixie : public Usermod { return USERMOD_ID_CRONIXIE; } - const char* getName() override - { - return reinterpret_cast(FPSTR(_name)); + const char* getName() override { + return _name; } }; +const char UsermodCronixie::_name[] PROGMEM = "Cronixie"; + static UsermodCronixie cronixie; REGISTER_USERMOD(cronixie); \ No newline at end of file diff --git a/usermods/DHT/DHT.cpp b/usermods/DHT/DHT.cpp index e75bba5b0b..2adda06d48 100644 --- a/usermods/DHT/DHT.cpp +++ b/usermods/DHT/DHT.cpp @@ -59,7 +59,9 @@ DHT_nonblocking dht_sensor(DHTPIN, DHTTYPE); class UsermodDHT : public Usermod { private: - unsigned long nextReadTime = 0; + + static const char _name[]; +unsigned long nextReadTime = 0; unsigned long lastReadTime = 0; float humidity, temperature = 0; bool initializing = true; @@ -242,13 +244,14 @@ class UsermodDHT : public Usermod { return USERMOD_ID_DHT; } - const char* getName() override - { - return reinterpret_cast(FPSTR(_name)); + const char* getName() override { + return _name; } }; +const char UsermodDHT::_name[] PROGMEM = "DHT"; + static UsermodDHT dht; REGISTER_USERMOD(dht); \ No newline at end of file diff --git a/usermods/EXAMPLE/usermod_v2_example.cpp b/usermods/EXAMPLE/usermod_v2_example.cpp index b77def02ca..3c593535c1 100644 --- a/usermods/EXAMPLE/usermod_v2_example.cpp +++ b/usermods/EXAMPLE/usermod_v2_example.cpp @@ -384,7 +384,7 @@ class MyExampleUsermod : public Usermod { */ const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } //More methods can be added in the future, this example will then be extended. diff --git a/usermods/EleksTube_IPS/EleksTube_IPS.cpp b/usermods/EleksTube_IPS/EleksTube_IPS.cpp index f4626be1a0..578ae4f0b1 100644 --- a/usermods/EleksTube_IPS/EleksTube_IPS.cpp +++ b/usermods/EleksTube_IPS/EleksTube_IPS.cpp @@ -152,7 +152,7 @@ class ElekstubeIPSUsermod : public Usermod { const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } }; diff --git a/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp b/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp index 7aed8db97f..229c31d641 100644 --- a/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp +++ b/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp @@ -26,7 +26,9 @@ class FixUnreachableNetServices : public Usermod { private: - //Private class members. You can declare variables and functions only accessible to your usermod here + + static const char _name[]; +//Private class members. You can declare variables and functions only accessible to your usermod here unsigned long m_lastTime = 0; // declare required variables @@ -160,12 +162,13 @@ Delay (FPSTR(_name)); - } + const char* getName() override { + return _name; + } }; +const char FixUnreachableNetServices::_name[] PROGMEM = "Fix Unreachable Netservices"; + static FixUnreachableNetServices fix_unreachable_net_services; REGISTER_USERMOD(fix_unreachable_net_services); diff --git a/usermods/INA226_v2/INA226_v2.cpp b/usermods/INA226_v2/INA226_v2.cpp index 9434bc26c4..ea478608ea 100644 --- a/usermods/INA226_v2/INA226_v2.cpp +++ b/usermods/INA226_v2/INA226_v2.cpp @@ -361,7 +361,7 @@ class UsermodINA226 : public Usermod const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } void addToJsonInfo(JsonObject &root) override diff --git a/usermods/Internal_Temperature_v2/Internal_Temperature_v2.cpp b/usermods/Internal_Temperature_v2/Internal_Temperature_v2.cpp index 8f51947f15..a0ac302e70 100644 --- a/usermods/Internal_Temperature_v2/Internal_Temperature_v2.cpp +++ b/usermods/Internal_Temperature_v2/Internal_Temperature_v2.cpp @@ -174,7 +174,7 @@ class InternalTemperatureUsermod : public Usermod const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } }; diff --git a/usermods/LD2410_v2/LD2410_v2.cpp b/usermods/LD2410_v2/LD2410_v2.cpp index a3c49671b0..0e0b0318a3 100644 --- a/usermods/LD2410_v2/LD2410_v2.cpp +++ b/usermods/LD2410_v2/LD2410_v2.cpp @@ -211,7 +211,7 @@ class LD2410Usermod : public Usermod { const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } }; diff --git a/usermods/LDR_Dusk_Dawn_v2/LDR_Dusk_Dawn_v2.cpp b/usermods/LDR_Dusk_Dawn_v2/LDR_Dusk_Dawn_v2.cpp index c1c5215f90..76da2125a6 100644 --- a/usermods/LDR_Dusk_Dawn_v2/LDR_Dusk_Dawn_v2.cpp +++ b/usermods/LDR_Dusk_Dawn_v2/LDR_Dusk_Dawn_v2.cpp @@ -150,7 +150,7 @@ class LDR_Dusk_Dawn_v2 : public Usermod { const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } }; diff --git a/usermods/MAX17048_v2/MAX17048_v2.cpp b/usermods/MAX17048_v2/MAX17048_v2.cpp index 8061151eec..989cb42783 100644 --- a/usermods/MAX17048_v2/MAX17048_v2.cpp +++ b/usermods/MAX17048_v2/MAX17048_v2.cpp @@ -270,7 +270,7 @@ class Usermod_MAX17048 : public Usermod { const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } }; diff --git a/usermods/MY9291/MY9291.cpp b/usermods/MY9291/MY9291.cpp index a81631e9ee..58fbd51334 100644 --- a/usermods/MY9291/MY9291.cpp +++ b/usermods/MY9291/MY9291.cpp @@ -13,7 +13,9 @@ class MY9291Usermod : public Usermod { private: - my92xx _my92xx = my92xx(MY92XX_MODEL, MY92XX_CHIPS, MY92XX_DI_PIN, MY92XX_DCKI_PIN, MY92XX_COMMAND_DEFAULT); + + static const char _name[]; +my92xx _my92xx = my92xx(MY92XX_MODEL, MY92XX_CHIPS, MY92XX_DI_PIN, MY92XX_DCKI_PIN, MY92XX_COMMAND_DEFAULT); public: @@ -41,11 +43,12 @@ class MY9291Usermod : public Usermod { return USERMOD_ID_MY9291; } - const char* getName() override - { - return reinterpret_cast(FPSTR(_name)); + const char* getName() override { + return _name; } }; +const char MY9291Usermod::_name[] PROGMEM = "MY9291"; + static MY9291Usermod my9291; REGISTER_USERMOD(my9291); \ No newline at end of file diff --git a/usermods/PIR_sensor_switch/PIR_sensor_switch.cpp b/usermods/PIR_sensor_switch/PIR_sensor_switch.cpp index 3460e28bcb..5f4479b79d 100644 --- a/usermods/PIR_sensor_switch/PIR_sensor_switch.cpp +++ b/usermods/PIR_sensor_switch/PIR_sensor_switch.cpp @@ -190,7 +190,7 @@ class PIRsensorSwitch : public Usermod const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } }; diff --git a/usermods/PWM_fan/PWM_fan.cpp b/usermods/PWM_fan/PWM_fan.cpp index ab26f06826..ba63a3bec3 100644 --- a/usermods/PWM_fan/PWM_fan.cpp +++ b/usermods/PWM_fan/PWM_fan.cpp @@ -390,7 +390,7 @@ class PWMFanUsermod : public Usermod { const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } }; diff --git a/usermods/RTC/RTC.cpp b/usermods/RTC/RTC.cpp index ca7a4cf0f3..8d1f4b40cc 100644 --- a/usermods/RTC/RTC.cpp +++ b/usermods/RTC/RTC.cpp @@ -5,7 +5,9 @@ class RTCUsermod : public Usermod { private: - unsigned long lastTime = 0; + + static const char _name[]; +unsigned long lastTime = 0; bool disabled = false; public: @@ -47,11 +49,12 @@ class RTCUsermod : public Usermod { return USERMOD_ID_RTC; } - const char* getName() override - { - return reinterpret_cast(FPSTR(_name)); + const char* getName() override { + return _name; } }; +const char RTCUsermod::_name[] PROGMEM = "RTC"; + static RTCUsermod rtc; REGISTER_USERMOD(rtc); \ No newline at end of file diff --git a/usermods/SN_Photoresistor/SN_Photoresistor.h b/usermods/SN_Photoresistor/SN_Photoresistor.h index 69e58d2cd6..6580f0d063 100644 --- a/usermods/SN_Photoresistor/SN_Photoresistor.h +++ b/usermods/SN_Photoresistor/SN_Photoresistor.h @@ -80,7 +80,7 @@ class Usermod_SN_Photoresistor : public Usermod const char* getName() { - return reinterpret_cast(FPSTR(_name)); + return _name; } /** diff --git a/usermods/ST7789_display/ST7789_display.cpp b/usermods/ST7789_display/ST7789_display.cpp index 6d19cc77e4..3da069c8c0 100644 --- a/usermods/ST7789_display/ST7789_display.cpp +++ b/usermods/ST7789_display/ST7789_display.cpp @@ -48,6 +48,7 @@ extern int getSignalQuality(int rssi); //class name. Use something descriptive and leave the ": public Usermod" part :) class St7789DisplayUsermod : public Usermod { private: + static const char _name[]; //Private class members. You can declare variables and functions only accessible to your usermod here unsigned long lastTime = 0; bool enabled = true; @@ -408,12 +409,14 @@ class St7789DisplayUsermod : public Usermod { const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } //More methods can be added in the future, this example will then be extended. //Your usermod will remain compatible as it does not need to implement all methods from the Usermod base class! }; -static name. st7789_display; +const char St7789DisplayUsermod::_name[] PROGMEM = "ST7789 Display"; + +static St7789DisplayUsermod st7789_display; REGISTER_USERMOD(st7789_display); \ No newline at end of file diff --git a/usermods/Si7021_MQTT_HA/Si7021_MQTT_HA.cpp b/usermods/Si7021_MQTT_HA/Si7021_MQTT_HA.cpp index 4b2562545b..44bea3b2ff 100644 --- a/usermods/Si7021_MQTT_HA/Si7021_MQTT_HA.cpp +++ b/usermods/Si7021_MQTT_HA/Si7021_MQTT_HA.cpp @@ -223,7 +223,7 @@ class Si7021_MQTT_HA : public Usermod const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } }; diff --git a/usermods/Temperature/UsermodTemperature.h b/usermods/Temperature/UsermodTemperature.h index 034a31cb88..7940eda8d4 100644 --- a/usermods/Temperature/UsermodTemperature.h +++ b/usermods/Temperature/UsermodTemperature.h @@ -90,7 +90,7 @@ class UsermodTemperature : public Usermod { const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } void setup() override; diff --git a/usermods/TetrisAI_v2/TetrisAI_v2.cpp b/usermods/TetrisAI_v2/TetrisAI_v2.cpp index ed78563d51..d62df53d85 100644 --- a/usermods/TetrisAI_v2/TetrisAI_v2.cpp +++ b/usermods/TetrisAI_v2/TetrisAI_v2.cpp @@ -251,7 +251,7 @@ class TetrisAIUsermod : public Usermod const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } }; diff --git a/usermods/VL53L0X_gestures/VL53L0X_gestures.cpp b/usermods/VL53L0X_gestures/VL53L0X_gestures.cpp index 74ec2a6a8c..7bad0daa07 100644 --- a/usermods/VL53L0X_gestures/VL53L0X_gestures.cpp +++ b/usermods/VL53L0X_gestures/VL53L0X_gestures.cpp @@ -36,7 +36,9 @@ class UsermodVL53L0XGestures : public Usermod { private: - //Private class members. You can declare variables and functions only accessible to your usermod here + + static const char _name[]; +//Private class members. You can declare variables and functions only accessible to your usermod here unsigned long lastTime = 0; VL53L0X sensor; bool enabled = true; @@ -125,11 +127,12 @@ class UsermodVL53L0XGestures : public Usermod { return USERMOD_ID_VL53L0X; } - const char* getName() override - { - return reinterpret_cast(FPSTR(_name)); + const char* getName() override { + return _name; } }; +const char UsermodVL53L0XGestures::_name[] PROGMEM = "VL53L0X Gestures"; + static UsermodVL53L0XGestures vl53l0x_gestures; REGISTER_USERMOD(vl53l0x_gestures); \ No newline at end of file diff --git a/usermods/audioreactive/audio_reactive.cpp b/usermods/audioreactive/audio_reactive.cpp index a5b65197ea..ffed72dbb3 100644 --- a/usermods/audioreactive/audio_reactive.cpp +++ b/usermods/audioreactive/audio_reactive.cpp @@ -1977,7 +1977,7 @@ class AudioReactive : public Usermod { const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } }; diff --git a/usermods/boblight/boblight.cpp b/usermods/boblight/boblight.cpp index 4c5229d85b..622e1c7f02 100644 --- a/usermods/boblight/boblight.cpp +++ b/usermods/boblight/boblight.cpp @@ -361,7 +361,7 @@ class BobLightUsermod : public Usermod { const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } }; diff --git a/usermods/buzzer/buzzer.cpp b/usermods/buzzer/buzzer.cpp index 5ce2ab6980..2beea3cb01 100644 --- a/usermods/buzzer/buzzer.cpp +++ b/usermods/buzzer/buzzer.cpp @@ -20,7 +20,9 @@ class BuzzerUsermod : public Usermod { private: - unsigned long lastTime_ = 0; + + static const char _name[]; +unsigned long lastTime_ = 0; unsigned long delay_ = 0; std::deque> sequence_ {}; public: @@ -78,11 +80,12 @@ class BuzzerUsermod : public Usermod { return USERMOD_ID_BUZZER; } - const char* getName() override - { - return reinterpret_cast(FPSTR(_name)); + const char* getName() override { + return _name; } }; +const char BuzzerUsermod::_name[] PROGMEM = "Buzzer"; + static BuzzerUsermod buzzer; REGISTER_USERMOD(buzzer); \ No newline at end of file diff --git a/usermods/deep_sleep/deep_sleep.cpp b/usermods/deep_sleep/deep_sleep.cpp index 5e87cdf03b..d484dcfd2e 100644 --- a/usermods/deep_sleep/deep_sleep.cpp +++ b/usermods/deep_sleep/deep_sleep.cpp @@ -220,7 +220,7 @@ void addToConfig(JsonObject& root) override const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } }; diff --git a/usermods/mpu6050_imu/mpu6050_imu.cpp b/usermods/mpu6050_imu/mpu6050_imu.cpp index 847b1c02f5..337dc3080f 100644 --- a/usermods/mpu6050_imu/mpu6050_imu.cpp +++ b/usermods/mpu6050_imu/mpu6050_imu.cpp @@ -434,7 +434,7 @@ class MPU6050Driver : public Usermod { const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } }; diff --git a/usermods/mpu6050_imu/usermod_gyro_surge.h b/usermods/mpu6050_imu/usermod_gyro_surge.h index 873f810e0e..e35d3e3ccb 100644 --- a/usermods/mpu6050_imu/usermod_gyro_surge.h +++ b/usermods/mpu6050_imu/usermod_gyro_surge.h @@ -216,7 +216,7 @@ class GyroSurge : public Usermod { } const char* getName() { - return reinterpret_cast(FPSTR(_name)); + return _name; } }; diff --git a/usermods/multi_relay/multi_relay.cpp b/usermods/multi_relay/multi_relay.cpp index f8e27dc3c5..2ba4c939f8 100644 --- a/usermods/multi_relay/multi_relay.cpp +++ b/usermods/multi_relay/multi_relay.cpp @@ -148,7 +148,7 @@ class MultiRelay : public Usermod { const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } /** diff --git a/usermods/pixels_dice_tray/pixels_dice_tray.cpp b/usermods/pixels_dice_tray/pixels_dice_tray.cpp index a741b898f4..5b96fefb21 100644 --- a/usermods/pixels_dice_tray/pixels_dice_tray.cpp +++ b/usermods/pixels_dice_tray/pixels_dice_tray.cpp @@ -39,7 +39,9 @@ class PixelsDiceTrayUsermod : public Usermod { private: - bool enabled = true; + + static const char _name[]; +bool enabled = true; DiceUpdate dice_update; @@ -527,10 +529,9 @@ class PixelsDiceTrayUsermod : public Usermod { */ uint16_t getId() { return USERMOD_ID_PIXELS_DICE_TRAY; } - const char* getName() override - { - return reinterpret_cast(FPSTR(_name)); - } + const char* getName() override { + return _name; + } // More methods can be added in the future, this example will then be // extended. Your usermod will remain compatible as it does not need to @@ -538,5 +539,7 @@ class PixelsDiceTrayUsermod : public Usermod { }; +const char PixelsDiceTrayUsermod::_name[] PROGMEM = "Pixels Dice Tray"; + static PixelsDiceTrayUsermod pixels_dice_tray; REGISTER_USERMOD(pixels_dice_tray); \ No newline at end of file diff --git a/usermods/pwm_outputs/pwm_outputs.cpp b/usermods/pwm_outputs/pwm_outputs.cpp index 40ea69748f..c3bef17cc0 100644 --- a/usermods/pwm_outputs/pwm_outputs.cpp +++ b/usermods/pwm_outputs/pwm_outputs.cpp @@ -211,13 +211,14 @@ class PwmOutputsUsermod : public Usermod { return USERMOD_ID_PWM_OUTPUTS; } - const char* getName() override - { - return reinterpret_cast(FPSTR(_name)); + const char* getName() override { + return _name; } private: - PwmOutput pwms_[USERMOD_PWM_OUTPUT_PINS]; + + static const char _name[]; +PwmOutput pwms_[USERMOD_PWM_OUTPUT_PINS]; }; @@ -225,5 +226,7 @@ const char PwmOutputsUsermod::USERMOD_NAME[] PROGMEM = "PwmOutputs"; const char PwmOutputsUsermod::PWM_STATE_NAME[] PROGMEM = "pwm"; +const char PwmOutputsUsermod::_name[] PROGMEM = "PWM Outputs"; + static PwmOutputsUsermod pwm_outputs; REGISTER_USERMOD(pwm_outputs); \ No newline at end of file diff --git a/usermods/quinled-an-penta/quinled-an-penta.cpp b/usermods/quinled-an-penta/quinled-an-penta.cpp index 1cfc66625f..4df08bb785 100644 --- a/usermods/quinled-an-penta/quinled-an-penta.cpp +++ b/usermods/quinled-an-penta/quinled-an-penta.cpp @@ -690,7 +690,7 @@ class QuinLEDAnPentaUsermod : public Usermod const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } }; diff --git a/usermods/rgb-rotary-encoder/rgb-rotary-encoder.cpp b/usermods/rgb-rotary-encoder/rgb-rotary-encoder.cpp index 50cdaad903..983e9cb2c9 100644 --- a/usermods/rgb-rotary-encoder/rgb-rotary-encoder.cpp +++ b/usermods/rgb-rotary-encoder/rgb-rotary-encoder.cpp @@ -330,7 +330,7 @@ class RgbRotaryEncoderUsermod : public Usermod const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } //More methods can be added in the future, this example will then be extended. diff --git a/usermods/sd_card/sd_card.cpp b/usermods/sd_card/sd_card.cpp index ee90375d2f..a6ddb36e7a 100644 --- a/usermods/sd_card/sd_card.cpp +++ b/usermods/sd_card/sd_card.cpp @@ -134,7 +134,7 @@ class UsermodSdCard : public Usermod { const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } void addToConfig(JsonObject& root) diff --git a/usermods/sensors_to_mqtt/sensors_to_mqtt.cpp b/usermods/sensors_to_mqtt/sensors_to_mqtt.cpp index 01c43163bf..599be38755 100644 --- a/usermods/sensors_to_mqtt/sensors_to_mqtt.cpp +++ b/usermods/sensors_to_mqtt/sensors_to_mqtt.cpp @@ -276,10 +276,9 @@ class UserMod_SensorsToMQTT : public Usermod } } - const char* getName() - { - return reinterpret_cast(FPSTR(_name)); - } + const char* getName() override { + return _name; + } }; const char UserMod_SensorsToMQTT::_name[] PROGMEM = "Sensors to MQTT"; diff --git a/usermods/seven_segment_display/seven_segment_display.cpp b/usermods/seven_segment_display/seven_segment_display.cpp index afa2ecdde8..d4997d6a47 100644 --- a/usermods/seven_segment_display/seven_segment_display.cpp +++ b/usermods/seven_segment_display/seven_segment_display.cpp @@ -10,7 +10,9 @@ class SevenSegmentDisplay : public Usermod #define WLED_SS_BUFFLEN 6 #define REFRESHTIME 497 private: - //Runtime variables. + + static const char _name[]; +//Runtime variables. unsigned long lastRefresh = 0; unsigned long lastCharacterStep = 0; String ssDisplayBuffer = ""; @@ -487,10 +489,9 @@ class SevenSegmentDisplay : public Usermod return USERMOD_ID_SEVEN_SEGMENT_DISPLAY; } - const char* getName() override - { - return reinterpret_cast(FPSTR(_name)); - } + const char* getName() override { + return _name; + } }; const char SevenSegmentDisplay::_str_perSegment[] PROGMEM = "perSegment"; @@ -503,5 +504,7 @@ const char SevenSegmentDisplay::_str_displayMask[] PROGMEM = "displayMask"; const char SevenSegmentDisplay::_str_displayMsg[] PROGMEM = "displayMsg"; const char SevenSegmentDisplay::_str_sevenSeg[] PROGMEM = "sevenSeg"; +const char SevenSegmentDisplay::_name[] PROGMEM = "Seven Segment Display"; + static SevenSegmentDisplay seven_segment_display; REGISTER_USERMOD(seven_segment_display); \ No newline at end of file diff --git a/usermods/seven_segment_display_reloaded/seven_segment_display_reloaded.cpp b/usermods/seven_segment_display_reloaded/seven_segment_display_reloaded.cpp index 5cfe09a909..748c663492 100644 --- a/usermods/seven_segment_display_reloaded/seven_segment_display_reloaded.cpp +++ b/usermods/seven_segment_display_reloaded/seven_segment_display_reloaded.cpp @@ -582,7 +582,7 @@ class UsermodSSDR : public Usermod { } const char* getName() { - return reinterpret_cast(FPSTR(_name)); + return _name; } }; diff --git a/usermods/sht/ShtUsermod.h b/usermods/sht/ShtUsermod.h index c045336af2..a3922bd083 100644 --- a/usermods/sht/ShtUsermod.h +++ b/usermods/sht/ShtUsermod.h @@ -71,6 +71,6 @@ class ShtUsermod : public Usermod const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } }; diff --git a/usermods/smartnest/smartnest.cpp b/usermods/smartnest/smartnest.cpp index 1a6510764c..eaa465d302 100644 --- a/usermods/smartnest/smartnest.cpp +++ b/usermods/smartnest/smartnest.cpp @@ -7,7 +7,9 @@ class Smartnest : public Usermod { private: - bool initialized = false; + + static const char _name[]; +bool initialized = false; unsigned long lastMqttReport = 0; unsigned long mqttReportInterval = 60000; // Report every minute @@ -171,10 +173,9 @@ class Smartnest : public Usermod return USERMOD_ID_SMARTNEST; } - const char* getName() override - { - return reinterpret_cast(FPSTR(_name)); - } + const char* getName() override { + return _name; + } /** * setup() is called once at startup to initialize the usermod. @@ -208,5 +209,7 @@ class Smartnest : public Usermod }; +const char Smartnest::_name[] PROGMEM = "Smartnest"; + static Smartnest smartnest; REGISTER_USERMOD(smartnest); \ No newline at end of file diff --git a/usermods/stairway_wipe_basic/stairway_wipe_basic.cpp b/usermods/stairway_wipe_basic/stairway_wipe_basic.cpp index c5fec0a1c9..31668084e6 100644 --- a/usermods/stairway_wipe_basic/stairway_wipe_basic.cpp +++ b/usermods/stairway_wipe_basic/stairway_wipe_basic.cpp @@ -13,7 +13,9 @@ class StairwayWipeUsermod : public Usermod { private: - //Private class members. You can declare variables and functions only accessible to your usermod here + + static const char _name[]; +//Private class members. You can declare variables and functions only accessible to your usermod here unsigned long lastTime = 0; byte wipeState = 0; //0: inactive 1: wiping 2: solid unsigned long timeStaticStart = 0; @@ -89,9 +91,8 @@ void setup() { return USERMOD_ID_STAIRWAY_WIPE; } - const char* getName() override - { - return reinterpret_cast(FPSTR(_name)); + const char* getName() override { + return _name; } @@ -133,5 +134,7 @@ void setup() { }; +const char StairwayWipeUsermod::_name[] PROGMEM = "Stairway Wipe"; + static StairwayWipeUsermod stairway_wipe_basic; REGISTER_USERMOD(stairway_wipe_basic); \ No newline at end of file diff --git a/usermods/udp_name_sync/udp_name_sync.cpp b/usermods/udp_name_sync/udp_name_sync.cpp index a2ebac2189..9b571b2991 100644 --- a/usermods/udp_name_sync/udp_name_sync.cpp +++ b/usermods/udp_name_sync/udp_name_sync.cpp @@ -81,9 +81,11 @@ class UdpNameSync : public Usermod { } const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } }; +const char UdpNameSync::_name[] PROGMEM = "UDP Name Sync"; + static UdpNameSync udp_name_sync; REGISTER_USERMOD(udp_name_sync); diff --git a/usermods/user_fx/user_fx.cpp b/usermods/user_fx/user_fx.cpp index ef63f10599..532c6401fd 100644 --- a/usermods/user_fx/user_fx.cpp +++ b/usermods/user_fx/user_fx.cpp @@ -95,7 +95,9 @@ static const char _data_FX_MODE_DIFFUSIONFIRE[] PROGMEM = "Diffusion Fire@!,Spar class UserFxUsermod : public Usermod { private: - public: + + static const char _name[]; +public: void setup() override { strip.addEffect(255, &mode_diffusionfire, _data_FX_MODE_DIFFUSIONFIRE); @@ -112,11 +114,12 @@ class UserFxUsermod : public Usermod { void loop() override {} // nothing to do in the loop uint16_t getId() override { return USERMOD_ID_USER_FX; } - const char* getName() override - { - return reinterpret_cast(FPSTR(_name)); - } + const char* getName() override { + return _name; + } }; +const char UserFxUsermod::_name[] PROGMEM = "User FX"; + static UserFxUsermod user_fx; REGISTER_USERMOD(user_fx); diff --git a/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.cpp b/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.cpp index a39df0e566..90b7737973 100644 --- a/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.cpp +++ b/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.cpp @@ -5,8 +5,9 @@ class RotaryEncoderBrightnessColor : public Usermod { private: - static const char _name[]; - //Private class members. You can declare variables and functions only accessible to your usermod here + + static const char _name[]; +//Private class members. You can declare variables and functions only accessible to your usermod here unsigned long lastTime = 0; unsigned long currentTime; unsigned long loopTime; @@ -186,12 +187,12 @@ class RotaryEncoderBrightnessColor : public Usermod return configComplete; } - const char* getName() - { - return reinterpret_cast(FPSTR(_name)); - } + const char* getName() override { + return _name; + } }; + const char RotaryEncoderBrightnessColor::_name[] PROGMEM = "Rotary Brightness Color"; static RotaryEncoderBrightnessColor usermod_rotary_brightness_color; diff --git a/usermods/usermod_v2_HttpPullLightControl/usermod_v2_HttpPullLightControl.h b/usermods/usermod_v2_HttpPullLightControl/usermod_v2_HttpPullLightControl.h index 5e49c1086e..a5e780c0a5 100644 --- a/usermods/usermod_v2_HttpPullLightControl/usermod_v2_HttpPullLightControl.h +++ b/usermods/usermod_v2_HttpPullLightControl/usermod_v2_HttpPullLightControl.h @@ -89,7 +89,7 @@ class HttpPullLightControl : public Usermod { const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } inline void enable(bool enable) { enabled = enable; } // Enable or Disable the usermod inline bool isEnabled() { return enabled; } // Get usermod enabled or disabled state diff --git a/usermods/usermod_v2_RF433/usermod_v2_RF433.cpp b/usermods/usermod_v2_RF433/usermod_v2_RF433.cpp index 16a4b46bc1..dc26a08b29 100644 --- a/usermods/usermod_v2_RF433/usermod_v2_RF433.cpp +++ b/usermods/usermod_v2_RF433/usermod_v2_RF433.cpp @@ -7,7 +7,9 @@ class RF433Usermod : public Usermod { private: - RCSwitch mySwitch = RCSwitch(); + + static const char _name[]; +RCSwitch mySwitch = RCSwitch(); unsigned long lastCommand = 0; unsigned long lastTime = 0; @@ -118,10 +120,9 @@ class RF433Usermod : public Usermod return USERMOD_ID_RF433; } - const char* getName() override - { - return reinterpret_cast(FPSTR(_name)); - } + const char* getName() override { + return _name; + } // this function follows the same principle as decodeIRJson() / remoteJson() bool remoteJson433(int button) @@ -184,5 +185,7 @@ const char RF433Usermod::_modName[] PROGMEM = "RF433 Remote"; const char RF433Usermod::_modEnabled[] PROGMEM = "Enabled"; const char RF433Usermod::_receivePin[] PROGMEM = "RX Pin"; +const char RF433Usermod::_name[] PROGMEM = "RF433"; + static RF433Usermod usermod_v2_RF433; REGISTER_USERMOD(usermod_v2_RF433); diff --git a/usermods/usermod_v2_auto_save/usermod_v2_auto_save.cpp b/usermods/usermod_v2_auto_save/usermod_v2_auto_save.cpp index fdb83029a9..a98811d650 100644 --- a/usermods/usermod_v2_auto_save/usermod_v2_auto_save.cpp +++ b/usermods/usermod_v2_auto_save/usermod_v2_auto_save.cpp @@ -268,7 +268,7 @@ class AutoSaveUsermod : public Usermod { const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } }; diff --git a/usermods/usermod_v2_brightness_follow_sun/usermod_v2_brightness_follow_sun.cpp b/usermods/usermod_v2_brightness_follow_sun/usermod_v2_brightness_follow_sun.cpp index fd5708bc43..73e7e2d4ec 100644 --- a/usermods/usermod_v2_brightness_follow_sun/usermod_v2_brightness_follow_sun.cpp +++ b/usermods/usermod_v2_brightness_follow_sun/usermod_v2_brightness_follow_sun.cpp @@ -41,7 +41,7 @@ class UsermodBrightnessFollowSun : public Usermod const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } void update() diff --git a/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display.h b/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display.h index 7f3fe50ffc..463449e692 100644 --- a/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display.h +++ b/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display.h @@ -313,7 +313,7 @@ class FourLineDisplayUsermod : public Usermod { } const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } }; \ No newline at end of file diff --git a/usermods/usermod_v2_klipper_percentage/usermod_v2_klipper_percentage.cpp b/usermods/usermod_v2_klipper_percentage/usermod_v2_klipper_percentage.cpp index 0f2aa25789..6587e4b264 100644 --- a/usermods/usermod_v2_klipper_percentage/usermod_v2_klipper_percentage.cpp +++ b/usermods/usermod_v2_klipper_percentage/usermod_v2_klipper_percentage.cpp @@ -218,7 +218,7 @@ class klipper_percentage : public Usermod const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } }; const char klipper_percentage::_name[] PROGMEM = "Klipper_Percentage"; diff --git a/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.cpp b/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.cpp index 1c70b89e4e..80aa4cd33d 100644 --- a/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.cpp +++ b/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.cpp @@ -3,7 +3,9 @@ class PingPongClockUsermod : public Usermod { private: - // Private class members. You can declare variables and functions only accessible to your usermod here + + static const char _name[]; +// Private class members. You can declare variables and functions only accessible to your usermod here unsigned long lastTime = 0; bool colonOn = true; @@ -114,13 +116,14 @@ class PingPongClockUsermod : public Usermod return USERMOD_ID_PING_PONG_CLOCK; } - const char* getName() override - { - return reinterpret_cast(FPSTR(_name)); - } + const char* getName() override { + return _name; + } }; +const char PingPongClockUsermod::_name[] PROGMEM = "Ping Pong Clock"; + static PingPongClockUsermod usermod_v2_ping_pong_clock; REGISTER_USERMOD(usermod_v2_ping_pong_clock); \ No newline at end of file diff --git a/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.cpp b/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.cpp index a544e9f5e5..d110f387b9 100644 --- a/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.cpp +++ b/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.cpp @@ -291,7 +291,7 @@ class RotaryEncoderUIUsermod : public Usermod { const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } /** * Enable/Disable the usermod diff --git a/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp b/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp index af8c636704..07908aa005 100644 --- a/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp +++ b/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp @@ -503,7 +503,7 @@ class WordClockUsermod : public Usermod } const char* getName() override { - return reinterpret_cast(FPSTR(_name)); + return _name; } //More methods can be added in the future, this example will then be extended. diff --git a/usermods/wireguard/wireguard.cpp b/usermods/wireguard/wireguard.cpp index 7ca907fb40..20b6fc22bd 100644 --- a/usermods/wireguard/wireguard.cpp +++ b/usermods/wireguard/wireguard.cpp @@ -111,13 +111,14 @@ class WireguardUsermod : public Usermod { uint16_t getId() { return USERMOD_ID_WIREGUARD; } - const char* getName() override - { - return reinterpret_cast(FPSTR(_name)); + const char* getName() override { + return _name; } private: - WireGuard wg; + + static const char _name[]; +WireGuard wg; char preshared_key[45]; char private_key[45]; IPAddress local_ip; @@ -129,5 +130,7 @@ class WireguardUsermod : public Usermod { unsigned long lastTime = 0; }; +const char WireguardUsermod::_name[] PROGMEM = "Wireguard"; + static WireguardUsermod wireguard; REGISTER_USERMOD(wireguard); \ No newline at end of file diff --git a/usermods/wizlights/wizlights.cpp b/usermods/wizlights/wizlights.cpp index cc770a6673..14dcbe0e40 100644 --- a/usermods/wizlights/wizlights.cpp +++ b/usermods/wizlights/wizlights.cpp @@ -12,7 +12,9 @@ WiFiUDP UDP; class WizLightsUsermod : public Usermod { private: - unsigned long lastTime = 0; + + static const char _name[]; +unsigned long lastTime = 0; long updateInterval; long sendDelay; @@ -154,12 +156,13 @@ class WizLightsUsermod : public Usermod { uint16_t getId(){return USERMOD_ID_WIZLIGHTS;} - const char* getName() override - { - return reinterpret_cast(FPSTR(_name)); + const char* getName() override { + return _name; } }; +const char WizLightsUsermod::_name[] PROGMEM = "Wiz Lights"; + static WizLightsUsermod wizlights; REGISTER_USERMOD(wizlights); \ No newline at end of file diff --git a/usermods/word-clock-matrix/word-clock-matrix.cpp b/usermods/word-clock-matrix/word-clock-matrix.cpp index 2179fd8a6f..a50cf53ce5 100644 --- a/usermods/word-clock-matrix/word-clock-matrix.cpp +++ b/usermods/word-clock-matrix/word-clock-matrix.cpp @@ -10,7 +10,9 @@ class WordClockMatrix : public Usermod { private: - unsigned long lastTime = 0; + + static const char _name[]; +unsigned long lastTime = 0; uint8_t minuteLast = 99; int dayBrightness = 128; int nightBrightness = 16; @@ -332,14 +334,15 @@ class WordClockMatrix : public Usermod return 500; } - const char* getName() override - { - return reinterpret_cast(FPSTR(_name)); + const char* getName() override { + return _name; } }; +const char WordClockMatrix::_name[] PROGMEM = "Word Clock Matrix"; + static WordClockMatrix word_clock_matrix; REGISTER_USERMOD(word_clock_matrix); \ No newline at end of file From b2aedd180a358326a19afceebd75e03480449118 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 28 Dec 2025 08:40:11 +0000 Subject: [PATCH 10/13] Fix indentation and use existing name variables per review feedback Co-authored-by: DedeHai <6280424+DedeHai@users.noreply.github.com> --- usermods/Cronixie/Cronixie.cpp | 1 - usermods/EXAMPLE/usermod_v2_example.cpp | 3 +-- usermods/ST7789_display/ST7789_display.cpp | 4 ++-- usermods/VL53L0X_gestures/VL53L0X_gestures.cpp | 3 +-- usermods/buzzer/buzzer.cpp | 1 - usermods/pwm_outputs/pwm_outputs.cpp | 9 ++------- .../seven_segment_display_reloaded.cpp | 4 +--- usermods/usermod_v2_RF433/usermod_v2_RF433.cpp | 8 ++------ 8 files changed, 9 insertions(+), 24 deletions(-) diff --git a/usermods/Cronixie/Cronixie.cpp b/usermods/Cronixie/Cronixie.cpp index a111df31b8..acc39589e9 100644 --- a/usermods/Cronixie/Cronixie.cpp +++ b/usermods/Cronixie/Cronixie.cpp @@ -2,7 +2,6 @@ class UsermodCronixie : public Usermod { private: - static const char _name[]; unsigned long lastTime = 0; char cronixieDisplay[7] = "HHMMSS"; diff --git a/usermods/EXAMPLE/usermod_v2_example.cpp b/usermods/EXAMPLE/usermod_v2_example.cpp index 3c593535c1..cd893141e8 100644 --- a/usermods/EXAMPLE/usermod_v2_example.cpp +++ b/usermods/EXAMPLE/usermod_v2_example.cpp @@ -379,8 +379,7 @@ class MyExampleUsermod : public Usermod { } /* - * getName() returns the name of the usermod. - * If your usermod has a _name string, return it here. + * getName() must return the _name string of the usermod. */ const char* getName() override { diff --git a/usermods/ST7789_display/ST7789_display.cpp b/usermods/ST7789_display/ST7789_display.cpp index 3da069c8c0..ce597aa807 100644 --- a/usermods/ST7789_display/ST7789_display.cpp +++ b/usermods/ST7789_display/ST7789_display.cpp @@ -365,7 +365,7 @@ class St7789DisplayUsermod : public Usermod { */ void addToConfig(JsonObject& root) override { - JsonObject top = root.createNestedObject("ST7789"); + JsonObject top = root.createNestedObject(FPSTR(_name)); JsonArray pins = top.createNestedArray("pin"); pins.add(TFT_CS); pins.add(TFT_DC); @@ -416,7 +416,7 @@ class St7789DisplayUsermod : public Usermod { //Your usermod will remain compatible as it does not need to implement all methods from the Usermod base class! }; -const char St7789DisplayUsermod::_name[] PROGMEM = "ST7789 Display"; +const char St7789DisplayUsermod::_name[] PROGMEM = "ST7789"; static St7789DisplayUsermod st7789_display; REGISTER_USERMOD(st7789_display); \ No newline at end of file diff --git a/usermods/VL53L0X_gestures/VL53L0X_gestures.cpp b/usermods/VL53L0X_gestures/VL53L0X_gestures.cpp index 7bad0daa07..c50288aa60 100644 --- a/usermods/VL53L0X_gestures/VL53L0X_gestures.cpp +++ b/usermods/VL53L0X_gestures/VL53L0X_gestures.cpp @@ -36,9 +36,8 @@ class UsermodVL53L0XGestures : public Usermod { private: - + //Private class members. You can declare variables and functions only accessible to your usermod here static const char _name[]; -//Private class members. You can declare variables and functions only accessible to your usermod here unsigned long lastTime = 0; VL53L0X sensor; bool enabled = true; diff --git a/usermods/buzzer/buzzer.cpp b/usermods/buzzer/buzzer.cpp index 2beea3cb01..c8eade362b 100644 --- a/usermods/buzzer/buzzer.cpp +++ b/usermods/buzzer/buzzer.cpp @@ -20,7 +20,6 @@ class BuzzerUsermod : public Usermod { private: - static const char _name[]; unsigned long lastTime_ = 0; unsigned long delay_ = 0; diff --git a/usermods/pwm_outputs/pwm_outputs.cpp b/usermods/pwm_outputs/pwm_outputs.cpp index c3bef17cc0..883d58e702 100644 --- a/usermods/pwm_outputs/pwm_outputs.cpp +++ b/usermods/pwm_outputs/pwm_outputs.cpp @@ -212,21 +212,16 @@ class PwmOutputsUsermod : public Usermod { } const char* getName() override { - return _name; + return USERMOD_NAME; } private: - - static const char _name[]; -PwmOutput pwms_[USERMOD_PWM_OUTPUT_PINS]; + PwmOutput pwms_[USERMOD_PWM_OUTPUT_PINS]; }; const char PwmOutputsUsermod::USERMOD_NAME[] PROGMEM = "PwmOutputs"; const char PwmOutputsUsermod::PWM_STATE_NAME[] PROGMEM = "pwm"; - -const char PwmOutputsUsermod::_name[] PROGMEM = "PWM Outputs"; - static PwmOutputsUsermod pwm_outputs; REGISTER_USERMOD(pwm_outputs); \ No newline at end of file diff --git a/usermods/seven_segment_display_reloaded/seven_segment_display_reloaded.cpp b/usermods/seven_segment_display_reloaded/seven_segment_display_reloaded.cpp index 748c663492..ca01dd9fba 100644 --- a/usermods/seven_segment_display_reloaded/seven_segment_display_reloaded.cpp +++ b/usermods/seven_segment_display_reloaded/seven_segment_display_reloaded.cpp @@ -15,7 +15,6 @@ class UsermodSSDR : public Usermod { //#define REFRESHTIME 497 private: - static const char _name[]; //Runtime variables. unsigned long umSSDRLastRefresh = 0; unsigned long umSSDRResfreshTime = 3000; @@ -582,11 +581,10 @@ class UsermodSSDR : public Usermod { } const char* getName() { - return _name; + return _str_name; } }; -const char UsermodSSDR::_name[] PROGMEM = "Seven Segment Display Reloaded"; const char UsermodSSDR::_str_name[] PROGMEM = "UsermodSSDR"; const char UsermodSSDR::_str_timeEnabled[] PROGMEM = "enabled"; const char UsermodSSDR::_str_inverted[] PROGMEM = "inverted"; diff --git a/usermods/usermod_v2_RF433/usermod_v2_RF433.cpp b/usermods/usermod_v2_RF433/usermod_v2_RF433.cpp index dc26a08b29..42cd97c9a7 100644 --- a/usermods/usermod_v2_RF433/usermod_v2_RF433.cpp +++ b/usermods/usermod_v2_RF433/usermod_v2_RF433.cpp @@ -7,9 +7,7 @@ class RF433Usermod : public Usermod { private: - - static const char _name[]; -RCSwitch mySwitch = RCSwitch(); + RCSwitch mySwitch = RCSwitch(); unsigned long lastCommand = 0; unsigned long lastTime = 0; @@ -121,7 +119,7 @@ RCSwitch mySwitch = RCSwitch(); } const char* getName() override { - return _name; + return _modName; } // this function follows the same principle as decodeIRJson() / remoteJson() @@ -185,7 +183,5 @@ const char RF433Usermod::_modName[] PROGMEM = "RF433 Remote"; const char RF433Usermod::_modEnabled[] PROGMEM = "Enabled"; const char RF433Usermod::_receivePin[] PROGMEM = "RX Pin"; -const char RF433Usermod::_name[] PROGMEM = "RF433"; - static RF433Usermod usermod_v2_RF433; REGISTER_USERMOD(usermod_v2_RF433); From f1ea13e553dd430113795ab233bc51f01beb6558 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 28 Dec 2025 09:06:17 +0000 Subject: [PATCH 11/13] Fix remaining indentation issues and use 'mod' pointer name in um_manager Co-authored-by: DedeHai <6280424+DedeHai@users.noreply.github.com> --- usermods/Analog_Clock/Analog_Clock.cpp | 3 +-- usermods/DHT/DHT.cpp | 3 +-- .../usermod_Fix_unreachable_netservices.cpp | 1 - usermods/MY9291/MY9291.cpp | 3 +-- usermods/RTC/RTC.cpp | 3 +-- usermods/pixels_dice_tray/pixels_dice_tray.cpp | 5 ++--- usermods/seven_segment_display/seven_segment_display.cpp | 1 - usermods/smartnest/smartnest.cpp | 5 ++--- usermods/stairway_wipe_basic/stairway_wipe_basic.cpp | 1 - usermods/user_fx/user_fx.cpp | 3 +-- .../usermod_rotary_brightness_color.cpp | 1 - .../usermod_v2_ping_pong_clock.cpp | 1 - usermods/wireguard/wireguard.cpp | 3 +-- usermods/wizlights/wizlights.cpp | 3 +-- usermods/word-clock-matrix/word-clock-matrix.cpp | 3 +-- wled00/um_manager.cpp | 6 +++--- 16 files changed, 15 insertions(+), 30 deletions(-) diff --git a/usermods/Analog_Clock/Analog_Clock.cpp b/usermods/Analog_Clock/Analog_Clock.cpp index e5835f0ca6..9ba75bd257 100644 --- a/usermods/Analog_Clock/Analog_Clock.cpp +++ b/usermods/Analog_Clock/Analog_Clock.cpp @@ -7,9 +7,8 @@ extern Timezone* tz; class AnalogClockUsermod : public Usermod { private: - static const char _name[]; -static constexpr uint32_t refreshRate = 50; // per second + static constexpr uint32_t refreshRate = 50; // per second static constexpr uint32_t refreshDelay = 1000 / refreshRate; struct Segment { diff --git a/usermods/DHT/DHT.cpp b/usermods/DHT/DHT.cpp index 2adda06d48..cf674e59de 100644 --- a/usermods/DHT/DHT.cpp +++ b/usermods/DHT/DHT.cpp @@ -59,9 +59,8 @@ DHT_nonblocking dht_sensor(DHTPIN, DHTTYPE); class UsermodDHT : public Usermod { private: - static const char _name[]; -unsigned long nextReadTime = 0; + unsigned long nextReadTime = 0; unsigned long lastReadTime = 0; float humidity, temperature = 0; bool initializing = true; diff --git a/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp b/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp index 229c31d641..4c670ab891 100644 --- a/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp +++ b/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp @@ -26,7 +26,6 @@ class FixUnreachableNetServices : public Usermod { private: - static const char _name[]; //Private class members. You can declare variables and functions only accessible to your usermod here unsigned long m_lastTime = 0; diff --git a/usermods/MY9291/MY9291.cpp b/usermods/MY9291/MY9291.cpp index 58fbd51334..7adff2e92d 100644 --- a/usermods/MY9291/MY9291.cpp +++ b/usermods/MY9291/MY9291.cpp @@ -13,9 +13,8 @@ class MY9291Usermod : public Usermod { private: - static const char _name[]; -my92xx _my92xx = my92xx(MY92XX_MODEL, MY92XX_CHIPS, MY92XX_DI_PIN, MY92XX_DCKI_PIN, MY92XX_COMMAND_DEFAULT); + my92xx _my92xx = my92xx(MY92XX_MODEL, MY92XX_CHIPS, MY92XX_DI_PIN, MY92XX_DCKI_PIN, MY92XX_COMMAND_DEFAULT); public: diff --git a/usermods/RTC/RTC.cpp b/usermods/RTC/RTC.cpp index 8d1f4b40cc..b4697bceb8 100644 --- a/usermods/RTC/RTC.cpp +++ b/usermods/RTC/RTC.cpp @@ -5,9 +5,8 @@ class RTCUsermod : public Usermod { private: - static const char _name[]; -unsigned long lastTime = 0; + unsigned long lastTime = 0; bool disabled = false; public: diff --git a/usermods/pixels_dice_tray/pixels_dice_tray.cpp b/usermods/pixels_dice_tray/pixels_dice_tray.cpp index 5b96fefb21..944d34160a 100644 --- a/usermods/pixels_dice_tray/pixels_dice_tray.cpp +++ b/usermods/pixels_dice_tray/pixels_dice_tray.cpp @@ -39,9 +39,8 @@ class PixelsDiceTrayUsermod : public Usermod { private: - - static const char _name[]; -bool enabled = true; + static const char _name[]; + bool enabled = true; DiceUpdate dice_update; diff --git a/usermods/seven_segment_display/seven_segment_display.cpp b/usermods/seven_segment_display/seven_segment_display.cpp index d4997d6a47..9cc99d20c6 100644 --- a/usermods/seven_segment_display/seven_segment_display.cpp +++ b/usermods/seven_segment_display/seven_segment_display.cpp @@ -10,7 +10,6 @@ class SevenSegmentDisplay : public Usermod #define WLED_SS_BUFFLEN 6 #define REFRESHTIME 497 private: - static const char _name[]; //Runtime variables. unsigned long lastRefresh = 0; diff --git a/usermods/smartnest/smartnest.cpp b/usermods/smartnest/smartnest.cpp index eaa465d302..e8f8fca883 100644 --- a/usermods/smartnest/smartnest.cpp +++ b/usermods/smartnest/smartnest.cpp @@ -7,9 +7,8 @@ class Smartnest : public Usermod { private: - - static const char _name[]; -bool initialized = false; + static const char _name[]; + bool initialized = false; unsigned long lastMqttReport = 0; unsigned long mqttReportInterval = 60000; // Report every minute diff --git a/usermods/stairway_wipe_basic/stairway_wipe_basic.cpp b/usermods/stairway_wipe_basic/stairway_wipe_basic.cpp index 31668084e6..0b6d460090 100644 --- a/usermods/stairway_wipe_basic/stairway_wipe_basic.cpp +++ b/usermods/stairway_wipe_basic/stairway_wipe_basic.cpp @@ -13,7 +13,6 @@ class StairwayWipeUsermod : public Usermod { private: - static const char _name[]; //Private class members. You can declare variables and functions only accessible to your usermod here unsigned long lastTime = 0; diff --git a/usermods/user_fx/user_fx.cpp b/usermods/user_fx/user_fx.cpp index 532c6401fd..d8a43f2625 100644 --- a/usermods/user_fx/user_fx.cpp +++ b/usermods/user_fx/user_fx.cpp @@ -95,9 +95,8 @@ static const char _data_FX_MODE_DIFFUSIONFIRE[] PROGMEM = "Diffusion Fire@!,Spar class UserFxUsermod : public Usermod { private: - static const char _name[]; -public: + public: void setup() override { strip.addEffect(255, &mode_diffusionfire, _data_FX_MODE_DIFFUSIONFIRE); diff --git a/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.cpp b/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.cpp index 90b7737973..85ff881826 100644 --- a/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.cpp +++ b/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.cpp @@ -5,7 +5,6 @@ class RotaryEncoderBrightnessColor : public Usermod { private: - static const char _name[]; //Private class members. You can declare variables and functions only accessible to your usermod here unsigned long lastTime = 0; diff --git a/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.cpp b/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.cpp index 80aa4cd33d..21072db9b1 100644 --- a/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.cpp +++ b/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.cpp @@ -3,7 +3,6 @@ class PingPongClockUsermod : public Usermod { private: - static const char _name[]; // Private class members. You can declare variables and functions only accessible to your usermod here unsigned long lastTime = 0; diff --git a/usermods/wireguard/wireguard.cpp b/usermods/wireguard/wireguard.cpp index 20b6fc22bd..06c63b1666 100644 --- a/usermods/wireguard/wireguard.cpp +++ b/usermods/wireguard/wireguard.cpp @@ -116,9 +116,8 @@ class WireguardUsermod : public Usermod { } private: - static const char _name[]; -WireGuard wg; + WireGuard wg; char preshared_key[45]; char private_key[45]; IPAddress local_ip; diff --git a/usermods/wizlights/wizlights.cpp b/usermods/wizlights/wizlights.cpp index 14dcbe0e40..e79a5166d2 100644 --- a/usermods/wizlights/wizlights.cpp +++ b/usermods/wizlights/wizlights.cpp @@ -12,9 +12,8 @@ WiFiUDP UDP; class WizLightsUsermod : public Usermod { private: - static const char _name[]; -unsigned long lastTime = 0; + unsigned long lastTime = 0; long updateInterval; long sendDelay; diff --git a/usermods/word-clock-matrix/word-clock-matrix.cpp b/usermods/word-clock-matrix/word-clock-matrix.cpp index a50cf53ce5..70419690b2 100644 --- a/usermods/word-clock-matrix/word-clock-matrix.cpp +++ b/usermods/word-clock-matrix/word-clock-matrix.cpp @@ -10,9 +10,8 @@ class WordClockMatrix : public Usermod { private: - static const char _name[]; -unsigned long lastTime = 0; + unsigned long lastTime = 0; uint8_t minuteLast = 99; int dayBrightness = 128; int nightBrightness = 16; diff --git a/wled00/um_manager.cpp b/wled00/um_manager.cpp index 31329a04c1..ff602ff40c 100644 --- a/wled00/um_manager.cpp +++ b/wled00/um_manager.cpp @@ -91,9 +91,9 @@ Usermod* UsermodManager::lookup(uint16_t mod_id) { * Get usermod name by ID. */ const char* UsermodManager::getName(uint16_t mod_id) { - Usermod* um = lookup(mod_id); - if (um != nullptr) { - return um->getName(); + Usermod* mod = lookup(mod_id); + if (mod != nullptr) { + return mod->getName(); } return nullptr; } From 4ebdb0c0c19253c083d48676ec97f7e3f168aeb6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 28 Dec 2025 09:37:32 +0000 Subject: [PATCH 12/13] Fix getName() indentation to match other functions in each file Co-authored-by: DedeHai <6280424+DedeHai@users.noreply.github.com> --- usermods/ADS1115_v2/ADS1115_v2.cpp | 8 ++++---- usermods/Animated_Staircase/Animated_Staircase.cpp | 8 ++++---- usermods/Battery/Battery.cpp | 8 ++++---- usermods/EleksTube_IPS/EleksTube_IPS.cpp | 8 ++++---- .../usermod_Fix_unreachable_netservices.cpp | 8 ++++---- usermods/INA226_v2/INA226_v2.cpp | 8 ++++---- usermods/LD2410_v2/LD2410_v2.cpp | 8 ++++---- usermods/MAX17048_v2/MAX17048_v2.cpp | 8 ++++---- usermods/PWM_fan/PWM_fan.cpp | 8 ++++---- usermods/Si7021_MQTT_HA/Si7021_MQTT_HA.cpp | 8 ++++---- usermods/Temperature/UsermodTemperature.h | 8 ++++---- usermods/audioreactive/audio_reactive.cpp | 8 ++++---- usermods/boblight/boblight.cpp | 8 ++++---- usermods/deep_sleep/deep_sleep.cpp | 8 ++++---- usermods/mpu6050_imu/mpu6050_imu.cpp | 8 ++++---- usermods/multi_relay/multi_relay.cpp | 8 ++++---- usermods/pixels_dice_tray/pixels_dice_tray.cpp | 6 +++--- usermods/quinled-an-penta/quinled-an-penta.cpp | 8 ++++---- usermods/rgb-rotary-encoder/rgb-rotary-encoder.cpp | 8 ++++---- usermods/sd_card/sd_card.cpp | 8 ++++---- usermods/seven_segment_display/seven_segment_display.cpp | 8 ++++---- usermods/sht/ShtUsermod.h | 8 ++++---- usermods/smartnest/smartnest.cpp | 6 +++--- usermods/user_fx/user_fx.cpp | 8 ++++---- usermods/usermod_v2_RF433/usermod_v2_RF433.cpp | 6 +++--- usermods/usermod_v2_auto_save/usermod_v2_auto_save.cpp | 8 ++++---- .../usermod_v2_ping_pong_clock.cpp | 6 +++--- .../usermod_v2_rotary_encoder_ui_ALT.cpp | 8 ++++---- 28 files changed, 108 insertions(+), 108 deletions(-) diff --git a/usermods/ADS1115_v2/ADS1115_v2.cpp b/usermods/ADS1115_v2/ADS1115_v2.cpp index 3d56438d53..ddbbca5132 100644 --- a/usermods/ADS1115_v2/ADS1115_v2.cpp +++ b/usermods/ADS1115_v2/ADS1115_v2.cpp @@ -118,10 +118,10 @@ class ADS1115Usermod : public Usermod { return USERMOD_ID_ADS1115; } - const char* getName() override - { - return _name; - } + const char* getName() override + { + return _name; + } private: static const char _name[]; diff --git a/usermods/Animated_Staircase/Animated_Staircase.cpp b/usermods/Animated_Staircase/Animated_Staircase.cpp index 0d4df05a66..ded98540e9 100644 --- a/usermods/Animated_Staircase/Animated_Staircase.cpp +++ b/usermods/Animated_Staircase/Animated_Staircase.cpp @@ -353,10 +353,10 @@ class Animated_Staircase : public Usermod { uint16_t getId() { return USERMOD_ID_ANIMATED_STAIRCASE; } - const char* getName() override - { - return _name; - } + const char* getName() override + { + return _name; + } #ifndef WLED_DISABLE_MQTT /** diff --git a/usermods/Battery/Battery.cpp b/usermods/Battery/Battery.cpp index 3fbea6c45d..e27bbd6f15 100644 --- a/usermods/Battery/Battery.cpp +++ b/usermods/Battery/Battery.cpp @@ -604,10 +604,10 @@ class UsermodBattery : public Usermod return USERMOD_ID_BATTERY; } - const char* getName() override - { - return _name; - } + const char* getName() override + { + return _name; + } /** * get currently active battery type diff --git a/usermods/EleksTube_IPS/EleksTube_IPS.cpp b/usermods/EleksTube_IPS/EleksTube_IPS.cpp index 578ae4f0b1..aea6599eef 100644 --- a/usermods/EleksTube_IPS/EleksTube_IPS.cpp +++ b/usermods/EleksTube_IPS/EleksTube_IPS.cpp @@ -150,10 +150,10 @@ class ElekstubeIPSUsermod : public Usermod { return USERMOD_ID_ELEKSTUBE_IPS; } - const char* getName() override - { - return _name; - } + const char* getName() override + { + return _name; + } }; // strings to reduce flash memory usage (used more than twice) diff --git a/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp b/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp index 4c670ab891..f8cd104c3a 100644 --- a/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp +++ b/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp @@ -161,10 +161,10 @@ Delay Date: Sun, 28 Dec 2025 11:58:41 +0100 Subject: [PATCH 13/13] cleanup formating --- usermods/Cronixie/Cronixie.cpp | 2 +- .../usermod_Fix_unreachable_netservices.cpp | 4 ++-- usermods/buzzer/buzzer.cpp | 2 +- .../seven_segment_display/seven_segment_display.cpp | 6 +++--- usermods/stairway_wipe_basic/stairway_wipe_basic.cpp | 2 +- usermods/user_fx/user_fx.cpp | 4 ++-- .../usermod_rotary_brightness_color.cpp | 10 +++++----- usermods/usermod_v2_RF433/usermod_v2_RF433.cpp | 2 +- .../usermod_v2_ping_pong_clock.cpp | 4 ++-- .../usermod_v2_word_clock/usermod_v2_word_clock.cpp | 1 - usermods/word-clock-matrix/word-clock-matrix.cpp | 2 +- 11 files changed, 19 insertions(+), 20 deletions(-) diff --git a/usermods/Cronixie/Cronixie.cpp b/usermods/Cronixie/Cronixie.cpp index acc39589e9..ac4e2061cc 100644 --- a/usermods/Cronixie/Cronixie.cpp +++ b/usermods/Cronixie/Cronixie.cpp @@ -3,7 +3,7 @@ class UsermodCronixie : public Usermod { private: static const char _name[]; -unsigned long lastTime = 0; + unsigned long lastTime = 0; char cronixieDisplay[7] = "HHMMSS"; byte _digitOut[6] = {10,10,10,10,10,10}; byte dP[6] = {255, 255, 255, 255, 255, 255}; diff --git a/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp b/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp index f8cd104c3a..aa63c5c3c1 100644 --- a/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp +++ b/usermods/Fix_unreachable_netservices_v2/usermod_Fix_unreachable_netservices.cpp @@ -26,8 +26,8 @@ class FixUnreachableNetServices : public Usermod { private: - static const char _name[]; -//Private class members. You can declare variables and functions only accessible to your usermod here + //Private class members. You can declare variables and functions only accessible to your usermod here + static const char _name[]; unsigned long m_lastTime = 0; // declare required variables diff --git a/usermods/buzzer/buzzer.cpp b/usermods/buzzer/buzzer.cpp index c8eade362b..2915777eff 100644 --- a/usermods/buzzer/buzzer.cpp +++ b/usermods/buzzer/buzzer.cpp @@ -21,7 +21,7 @@ class BuzzerUsermod : public Usermod { private: static const char _name[]; -unsigned long lastTime_ = 0; + unsigned long lastTime_ = 0; unsigned long delay_ = 0; std::deque> sequence_ {}; public: diff --git a/usermods/seven_segment_display/seven_segment_display.cpp b/usermods/seven_segment_display/seven_segment_display.cpp index f5c2d8204b..2a0c327948 100644 --- a/usermods/seven_segment_display/seven_segment_display.cpp +++ b/usermods/seven_segment_display/seven_segment_display.cpp @@ -10,8 +10,8 @@ class SevenSegmentDisplay : public Usermod #define WLED_SS_BUFFLEN 6 #define REFRESHTIME 497 private: - static const char _name[]; -//Runtime variables. + //Runtime variables. + static const char _name[]; unsigned long lastRefresh = 0; unsigned long lastCharacterStep = 0; String ssDisplayBuffer = ""; @@ -491,7 +491,7 @@ class SevenSegmentDisplay : public Usermod const char* getName() override { return _name; } - }; +}; const char SevenSegmentDisplay::_str_perSegment[] PROGMEM = "perSegment"; const char SevenSegmentDisplay::_str_perPeriod[] PROGMEM = "perPeriod"; diff --git a/usermods/stairway_wipe_basic/stairway_wipe_basic.cpp b/usermods/stairway_wipe_basic/stairway_wipe_basic.cpp index 0b6d460090..e3789fcb48 100644 --- a/usermods/stairway_wipe_basic/stairway_wipe_basic.cpp +++ b/usermods/stairway_wipe_basic/stairway_wipe_basic.cpp @@ -13,8 +13,8 @@ class StairwayWipeUsermod : public Usermod { private: + //Private class members. You can declare variables and functions only accessible to your usermod here static const char _name[]; -//Private class members. You can declare variables and functions only accessible to your usermod here unsigned long lastTime = 0; byte wipeState = 0; //0: inactive 1: wiping 2: solid unsigned long timeStaticStart = 0; diff --git a/usermods/user_fx/user_fx.cpp b/usermods/user_fx/user_fx.cpp index 3c9f05f515..fafef437e4 100644 --- a/usermods/user_fx/user_fx.cpp +++ b/usermods/user_fx/user_fx.cpp @@ -95,7 +95,7 @@ static const char _data_FX_MODE_DIFFUSIONFIRE[] PROGMEM = "Diffusion Fire@!,Spar class UserFxUsermod : public Usermod { private: - static const char _name[]; + static const char _name[]; public: void setup() override { strip.addEffect(255, &mode_diffusionfire, _data_FX_MODE_DIFFUSIONFIRE); @@ -116,7 +116,7 @@ class UserFxUsermod : public Usermod { const char* getName() override { return _name; } - }; +}; const char UserFxUsermod::_name[] PROGMEM = "User FX"; diff --git a/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.cpp b/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.cpp index 85ff881826..90b371a104 100644 --- a/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.cpp +++ b/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.cpp @@ -5,8 +5,8 @@ class RotaryEncoderBrightnessColor : public Usermod { private: - static const char _name[]; -//Private class members. You can declare variables and functions only accessible to your usermod here + //Private class members. You can declare variables and functions only accessible to your usermod here + static const char _name[]; unsigned long lastTime = 0; unsigned long currentTime; unsigned long loopTime; @@ -186,9 +186,9 @@ class RotaryEncoderBrightnessColor : public Usermod return configComplete; } - const char* getName() override { - return _name; - } + const char* getName() override { + return _name; + } }; diff --git a/usermods/usermod_v2_RF433/usermod_v2_RF433.cpp b/usermods/usermod_v2_RF433/usermod_v2_RF433.cpp index 96687c4f42..e437d15add 100644 --- a/usermods/usermod_v2_RF433/usermod_v2_RF433.cpp +++ b/usermods/usermod_v2_RF433/usermod_v2_RF433.cpp @@ -7,7 +7,7 @@ class RF433Usermod : public Usermod { private: - RCSwitch mySwitch = RCSwitch(); + RCSwitch mySwitch = RCSwitch(); unsigned long lastCommand = 0; unsigned long lastTime = 0; diff --git a/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.cpp b/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.cpp index d10e4d7669..c9790927b4 100644 --- a/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.cpp +++ b/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.cpp @@ -3,8 +3,8 @@ class PingPongClockUsermod : public Usermod { private: - static const char _name[]; -// Private class members. You can declare variables and functions only accessible to your usermod here + // Private class members. You can declare variables and functions only accessible to your usermod here + static const char _name[]; unsigned long lastTime = 0; bool colonOn = true; diff --git a/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp b/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp index 07908aa005..1e327b4af6 100644 --- a/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp +++ b/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp @@ -15,7 +15,6 @@ class WordClockUsermod : public Usermod { private: - static const char _name[]; unsigned long lastTime = 0; int lastTimeMinutes = -1; diff --git a/usermods/word-clock-matrix/word-clock-matrix.cpp b/usermods/word-clock-matrix/word-clock-matrix.cpp index 70419690b2..9c5fece385 100644 --- a/usermods/word-clock-matrix/word-clock-matrix.cpp +++ b/usermods/word-clock-matrix/word-clock-matrix.cpp @@ -10,7 +10,7 @@ class WordClockMatrix : public Usermod { private: - static const char _name[]; + static const char _name[]; unsigned long lastTime = 0; uint8_t minuteLast = 99; int dayBrightness = 128;