Convert usermods to static libraries

Redesign the usermod system so that usermods are implemented as
PlatformIO libraries instead of headers.  This permits them to call for
dependencies, and eliminates the compiler flags for enabling each one,
allowing the build cache to behave better.

The usermod list is built using some linker magic to construct a static
list in ROM memory.  This eliminates the need for wasting SRAM on
something fixed at build time.
This commit is contained in:
Will Miles 2024-09-14 15:09:47 -04:00
parent c4e697d797
commit b8685f2c39
11 changed files with 100 additions and 562 deletions

View File

@ -0,0 +1,9 @@
Import('env')
usermods = env.GetProjectOption("custom_usermods","")
if usermods:
proj = env.GetProjectConfig()
deps = env.GetProjectOption('lib_deps')
src_dir = proj.get("platformio", "src_dir")
src_dir = src_dir.replace('\\','/')
usermods = [f"{mod} = symlink://{src_dir}/../usermods/{mod}" for mod in usermods.split(" ")]
proj.set("env:" + env['PIOENV'], 'lib_deps', deps + usermods)

View File

@ -114,6 +114,7 @@ extra_scripts =
post:pio-scripts/output_bins.py
post:pio-scripts/strip-floats.py
pre:pio-scripts/user_config_copy.py
pre:pio-scripts/load_usermods.py
pre:pio-scripts/build_ui.py
; post:pio-scripts/obj-dump.py ;; convenience script to create a disassembly dump of the firmware (hardcore debugging)
@ -170,8 +171,6 @@ lib_deps =
;https://github.com/netmindz/animartrix.git#18bf17389e57c69f11bc8d04ebe1d215422c7fb7
# SHT85
;robtillaart/SHT85@~0.3.3
# Audioreactive usermod
;kosme/arduinoFFT @ 2.0.1
extra_scripts = ${scripts_defaults.extra_scripts}
@ -261,11 +260,11 @@ lib_deps =
https://github.com/lorol/LITTLEFS.git
https://github.com/pbolduc/AsyncTCP.git @ 1.2.0
${env.lib_deps}
# additional build flags for audioreactive
AR_build_flags = -D USERMOD_AUDIOREACTIVE
-D sqrt_internal=sqrtf ;; -fsingle-precision-constant ;; forces ArduinoFFT to use float math (2x faster)
AR_lib_deps = kosme/arduinoFFT @ 2.0.1
board_build.partitions = ${esp32.default_partitions} ;; default partioning for 4MB Flash - can be overridden in build envs
# additional build flags for audioreactive - must be applied globally
AR_build_flags = -D sqrt_internal=sqrtf ;; -fsingle-precision-constant ;; forces ArduinoFFT to use float math (2x faster)
AR_lib_deps = kosme/arduinoFFT @ 2.0.1 ;; for pre-usermod-library platformio_override compatibility
[esp32_idf_V4]
;; experimental build environment for ESP32 using ESP-IDF 4.4.x / arduino-esp32 v2.0.5
@ -424,11 +423,11 @@ build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=
board = esp32dev
platform = ${esp32.platform}
platform_packages = ${esp32.platform_packages}
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32.build_flags} -D WLED_RELEASE_NAME=\"ESP32\" #-D WLED_DISABLE_BROWNOUT_DET
${esp32.AR_build_flags}
lib_deps = ${esp32.lib_deps}
${esp32.AR_lib_deps}
monitor_filters = esp32_exception_decoder
board_build.partitions = ${esp32.default_partitions}
@ -436,11 +435,11 @@ board_build.partitions = ${esp32.default_partitions}
board = esp32dev
platform = ${esp32_idf_V4.platform}
platform_packages = ${esp32_idf_V4.platform_packages}
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=\"ESP32_8M\" #-D WLED_DISABLE_BROWNOUT_DET
${esp32.AR_build_flags}
lib_deps = ${esp32_idf_V4.lib_deps}
${esp32.AR_lib_deps}
monitor_filters = esp32_exception_decoder
board_build.partitions = ${esp32.large_partitions}
board_upload.flash_size = 8MB
@ -452,11 +451,11 @@ board_upload.maximum_size = 8388608
board = esp32dev
platform = ${esp32_idf_V4.platform}
platform_packages = ${esp32_idf_V4.platform_packages}
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=\"ESP32_16M\" #-D WLED_DISABLE_BROWNOUT_DET
${esp32.AR_build_flags}
lib_deps = ${esp32_idf_V4.lib_deps}
${esp32.AR_lib_deps}
monitor_filters = esp32_exception_decoder
board_build.partitions = ${esp32.extreme_partitions}
board_upload.flash_size = 16MB
@ -468,11 +467,11 @@ board_build.flash_mode = dio
;board = esp32dev
;platform = ${esp32.platform}
;platform_packages = ${esp32.platform_packages}
;custom_usermods = audioreactive
;build_unflags = ${common.build_unflags}
;build_flags = ${common.build_flags} ${esp32.build_flags} -D WLED_RELEASE_NAME=\"ESP32_audioreactive\" #-D WLED_DISABLE_BROWNOUT_DET
; ${esp32.AR_build_flags}
;lib_deps = ${esp32.lib_deps}
; ${esp32.AR_lib_deps}
;monitor_filters = esp32_exception_decoder
;board_build.partitions = ${esp32.default_partitions}
;; board_build.f_flash = 80000000L
@ -483,12 +482,12 @@ board = esp32-poe
platform = ${esp32.platform}
platform_packages = ${esp32.platform_packages}
upload_speed = 921600
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32.build_flags} -D WLED_RELEASE_NAME=\"ESP32_Ethernet\" -D RLYPIN=-1 -D WLED_USE_ETHERNET -D BTNPIN=-1
; -D WLED_DISABLE_ESPNOW ;; ESP-NOW requires wifi, may crash with ethernet only
${esp32.AR_build_flags}
lib_deps = ${esp32.lib_deps}
${esp32.AR_lib_deps}
board_build.partitions = ${esp32.default_partitions}
[env:esp32_wrover]
@ -499,14 +498,14 @@ board = ttgo-t7-v14-mini32
board_build.f_flash = 80000000L
board_build.flash_mode = qio
board_build.partitions = ${esp32.extended_partitions}
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=\"ESP32_WROVER\"
-DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue ;; Older ESP32 (rev.<3) need a PSRAM fix (increases static RAM used) https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-guides/external-ram.html
-D DATA_PINS=25
${esp32.AR_build_flags}
lib_deps = ${esp32_idf_V4.lib_deps}
${esp32.AR_lib_deps}
[env:esp32c3dev]
extends = esp32c3
platform = ${esp32c3.platform}
@ -530,6 +529,7 @@ board_build.arduino.memory_type = qio_opi ;; use with PSRAM: 8MB or 16MB
platform = ${esp32s3.platform}
platform_packages = ${esp32s3.platform_packages}
upload_speed = 921600
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=\"ESP32-S3_16MB_opi\"
-D CONFIG_LITTLEFS_FOR_IDF_3_2 -D WLED_WATCHDOG_TIMEOUT=0
@ -538,7 +538,6 @@ build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=
-DBOARD_HAS_PSRAM
${esp32.AR_build_flags}
lib_deps = ${esp32s3.lib_deps}
${esp32.AR_lib_deps}
board_build.partitions = ${esp32.extreme_partitions}
board_upload.flash_size = 16MB
board_upload.maximum_size = 16777216
@ -553,6 +552,7 @@ board_build.arduino.memory_type = qio_opi ;; use with PSRAM: 8MB or 16MB
platform = ${esp32s3.platform}
platform_packages = ${esp32s3.platform_packages}
upload_speed = 921600
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=\"ESP32-S3_8MB_opi\"
-D CONFIG_LITTLEFS_FOR_IDF_3_2 -D WLED_WATCHDOG_TIMEOUT=0
@ -561,7 +561,6 @@ build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=
-DBOARD_HAS_PSRAM
${esp32.AR_build_flags}
lib_deps = ${esp32s3.lib_deps}
${esp32.AR_lib_deps}
board_build.partitions = ${esp32.large_partitions}
board_build.f_flash = 80000000L
board_build.flash_mode = qio
@ -575,6 +574,7 @@ platform_packages = ${esp32s3.platform_packages}
board = esp32s3camlcd ;; this is the only standard board with "opi_opi"
board_build.arduino.memory_type = opi_opi
upload_speed = 921600
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=\"ESP32-S3_WROOM-2\"
-D CONFIG_LITTLEFS_FOR_IDF_3_2 -D WLED_WATCHDOG_TIMEOUT=0
@ -587,7 +587,6 @@ build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=
${esp32.AR_build_flags}
-D SR_DMTYPE=1 -D I2S_SDPIN=13 -D I2S_CKPIN=14 -D I2S_WSPIN=15 -D MCLK_PIN=4 ;; I2S mic
lib_deps = ${esp32s3.lib_deps}
${esp32.AR_lib_deps}
board_build.partitions = ${esp32.extreme_partitions}
board_upload.flash_size = 16MB
@ -600,6 +599,7 @@ board = lolin_s3_mini ;; -S3 mini, 4MB flash 2MB PSRAM
platform = ${esp32s3.platform}
platform_packages = ${esp32s3.platform_packages}
upload_speed = 921600
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=\"ESP32-S3_4M_qspi\"
-DARDUINO_USB_CDC_ON_BOOT=1 -DARDUINO_USB_MODE=1 ;; for boards with USB-OTG connector only (USBCDC or "TinyUSB")
@ -608,7 +608,6 @@ build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=
-D WLED_WATCHDOG_TIMEOUT=0
${esp32.AR_build_flags}
lib_deps = ${esp32s3.lib_deps}
${esp32.AR_lib_deps}
board_build.partitions = ${esp32.default_partitions}
board_build.f_flash = 80000000L
board_build.flash_mode = qio
@ -621,6 +620,7 @@ board = lolin_s2_mini
board_build.partitions = ${esp32.default_partitions}
board_build.flash_mode = qio
board_build.f_flash = 80000000L
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32s2.build_flags} -D WLED_RELEASE_NAME=\"ESP32-S2\"
-DARDUINO_USB_CDC_ON_BOOT=1
@ -639,4 +639,3 @@ build_flags = ${common.build_flags} ${esp32s2.build_flags} -D WLED_RELEASE_NAME=
; -D STATUSLED=15
${esp32.AR_build_flags}
lib_deps = ${esp32s2.lib_deps}
${esp32.AR_lib_deps}

View File

@ -1,4 +1,3 @@
#pragma once
#include "wled.h"
@ -2064,3 +2063,6 @@ const char AudioReactive::_digitalmic[] PROGMEM = "digitalmic";
const char AudioReactive::_addPalettes[] PROGMEM = "add-palettes";
const char AudioReactive::UDP_SYNC_HEADER[] PROGMEM = "00002"; // new sync header version, as format no longer compatible with previous structure
const char AudioReactive::UDP_SYNC_HEADER_v1[] PROGMEM = "00001"; // old sync header version - need to add backwards-compatibility feature
static AudioReactive ar_module;
REGISTER_USERMOD(ar_module);

View File

@ -0,0 +1,17 @@
{
"name": "audioreactive",
"build": {
"srcDir": ".",
"includeDir": "../../wled00",
"libLDFMode": "chain+",
"libArchive": false
},
"dependencies": [
{
"owner": "kosme",
"name": "arduinoFFT",
"version": "2.0.1",
"platforms": "espressif32"
}
]
}

View File

@ -0,0 +1,8 @@
{
"name": "auto_save",
"build": {
"srcDir": ".",
"includeDir": "../../wled00",
"libLDFMode": "chain+"
}
}

View File

@ -275,3 +275,6 @@ const char AutoSaveUsermod::_autoSaveEnabled[] PROGMEM = "enabled";
const char AutoSaveUsermod::_autoSaveAfterSec[] PROGMEM = "autoSaveAfterSec";
const char AutoSaveUsermod::_autoSavePreset[] PROGMEM = "autoSavePreset";
const char AutoSaveUsermod::_autoSaveApplyOnBoot[] PROGMEM = "autoSaveApplyOnBoot";
static AutoSaveUsermod autosave;
REGISTER_USERMOD(autosave);

View File

@ -381,7 +381,7 @@ class Usermod {
protected:
um_data_t *um_data; // um_data should be allocated using new in (derived) Usermod's setup() or constructor
public:
Usermod() { um_data = nullptr; }
Usermod() : um_data(nullptr) {};
virtual ~Usermod() { if (um_data) delete um_data; }
virtual void setup() = 0; // pure virtual, has to be overriden
virtual void loop() = 0; // pure virtual, has to be overriden
@ -418,8 +418,6 @@ class Usermod {
};
namespace UsermodManager {
extern byte numMods;
void loop();
void handleOverlayDraw();
bool handleButton(uint8_t b);
@ -441,13 +439,12 @@ namespace UsermodManager {
#endif
void onUpdateBegin(bool);
void onStateChange(uint8_t);
bool add(Usermod* um);
Usermod* lookup(uint16_t mod_id);
inline byte getModCount() {return numMods;};
size_t getModCount();
};
//usermods_list.cpp
void registerUsermods();
// Register usermods by building a static list via a linker section
#define REGISTER_USERMOD(x) Usermod* const um_##x __attribute__((__section__(".dtors.tbl.usermods.1"), used)) = &x
//usermod.cpp
void userSetup();

View File

@ -3,75 +3,81 @@
* Registration and management utility for v2 usermods
*/
static Usermod* ums[WLED_MAX_USERMODS] = {nullptr};
byte UsermodManager::numMods = 0;
// Global usermod instance list
// Table begin and end references
// Zero-length arrays -- so they'll get assigned addresses, but consume no flash
// The numeric suffix ensures they're put in the right place; the linker script will sort them
// We stick them in the '.dtors' segment because it's always included by the linker scripts
// even though it never gets called. Who calls exit() in an embedded program anyways?
// If someone ever does, though, it'll explode as these aren't function pointers.
static Usermod * const _usermod_table_begin[0] __attribute__((__section__(".dtors.tbl.usermods.0"), unused)) = {};
static Usermod * const _usermod_table_end[0] __attribute__((__section__(".dtors.tbl.usermods.99"), unused)) = {};
static size_t getCount() {
return &_usermod_table_end[0] - &_usermod_table_begin[0];
}
//Usermod Manager internals
void UsermodManager::setup() { for (unsigned i = 0; i < numMods; i++) ums[i]->setup(); }
void UsermodManager::connected() { for (unsigned i = 0; i < numMods; i++) ums[i]->connected(); }
void UsermodManager::loop() { for (unsigned i = 0; i < numMods; i++) ums[i]->loop(); }
void UsermodManager::handleOverlayDraw() { for (unsigned i = 0; i < numMods; i++) ums[i]->handleOverlayDraw(); }
void UsermodManager::appendConfigData(Print& dest) { for (unsigned i = 0; i < numMods; i++) ums[i]->appendConfigData(dest); }
void UsermodManager::setup() { for (auto mod = _usermod_table_begin; mod < _usermod_table_end; ++mod) (*mod)->setup(); }
void UsermodManager::connected() { for (auto mod = _usermod_table_begin; mod < _usermod_table_end; ++mod) (*mod)->connected(); }
void UsermodManager::loop() { for (auto mod = _usermod_table_begin; mod < _usermod_table_end; ++mod) (*mod)->loop(); }
void UsermodManager::handleOverlayDraw() { for (auto mod = _usermod_table_begin; mod < _usermod_table_end; ++mod) (*mod)->handleOverlayDraw(); }
void UsermodManager::appendConfigData(Print& dest) { for (auto mod = _usermod_table_begin; mod < _usermod_table_end; ++mod) (*mod)->appendConfigData(dest); }
bool UsermodManager::handleButton(uint8_t b) {
bool overrideIO = false;
for (unsigned i = 0; i < numMods; i++) {
if (ums[i]->handleButton(b)) overrideIO = true;
for (auto mod = _usermod_table_begin; mod < _usermod_table_end; ++mod) {
if ((*mod)->handleButton(b)) overrideIO = true;
}
return overrideIO;
}
bool UsermodManager::getUMData(um_data_t **data, uint8_t mod_id) {
for (unsigned i = 0; i < numMods; i++) {
if (mod_id > 0 && ums[i]->getId() != mod_id) continue; // only get data form requested usermod if provided
if (ums[i]->getUMData(data)) return true; // if usermod does provide data return immediately (only one usermod can provide data at one time)
for (auto mod = _usermod_table_begin; mod < _usermod_table_end; ++mod) {
if (mod_id > 0 && (*mod)->getId() != mod_id) continue; // only get data form requested usermod if provided
if ((*mod)->getUMData(data)) return true; // if usermod does provide data return immediately (only one usermod can provide data at one time)
}
return false;
}
void UsermodManager::addToJsonState(JsonObject& obj) { for (unsigned i = 0; i < numMods; i++) ums[i]->addToJsonState(obj); }
void UsermodManager::addToJsonInfo(JsonObject& obj) { for (unsigned i = 0; i < numMods; i++) ums[i]->addToJsonInfo(obj); }
void UsermodManager::readFromJsonState(JsonObject& obj) { for (unsigned i = 0; i < numMods; i++) ums[i]->readFromJsonState(obj); }
void UsermodManager::addToConfig(JsonObject& obj) { for (unsigned i = 0; i < numMods; i++) ums[i]->addToConfig(obj); }
void UsermodManager::addToJsonState(JsonObject& obj) { for (auto mod = _usermod_table_begin; mod < _usermod_table_end; ++mod) (*mod)->addToJsonState(obj); }
void UsermodManager::addToJsonInfo(JsonObject& obj) { for (auto mod = _usermod_table_begin; mod < _usermod_table_end; ++mod) (*mod)->addToJsonInfo(obj); }
void UsermodManager::readFromJsonState(JsonObject& obj) { for (auto mod = _usermod_table_begin; mod < _usermod_table_end; ++mod) (*mod)->readFromJsonState(obj); }
void UsermodManager::addToConfig(JsonObject& obj) { for (auto mod = _usermod_table_begin; mod < _usermod_table_end; ++mod) (*mod)->addToConfig(obj); }
bool UsermodManager::readFromConfig(JsonObject& obj) {
bool allComplete = true;
for (unsigned i = 0; i < numMods; i++) {
if (!ums[i]->readFromConfig(obj)) allComplete = false;
for (auto mod = _usermod_table_begin; mod < _usermod_table_end; ++mod) {
if (!(*mod)->readFromConfig(obj)) allComplete = false;
}
return allComplete;
}
#ifndef WLED_DISABLE_MQTT
void UsermodManager::onMqttConnect(bool sessionPresent) { for (unsigned i = 0; i < numMods; i++) ums[i]->onMqttConnect(sessionPresent); }
void UsermodManager::onMqttConnect(bool sessionPresent) { for (auto mod = _usermod_table_begin; mod < _usermod_table_end; ++mod) (*mod)->onMqttConnect(sessionPresent); }
bool UsermodManager::onMqttMessage(char* topic, char* payload) {
for (unsigned i = 0; i < numMods; i++) if (ums[i]->onMqttMessage(topic, payload)) return true;
for (auto mod = _usermod_table_begin; mod < _usermod_table_end; ++mod) if ((*mod)->onMqttMessage(topic, payload)) return true;
return false;
}
#endif
#ifndef WLED_DISABLE_ESPNOW
bool UsermodManager::onEspNowMessage(uint8_t* sender, uint8_t* payload, uint8_t len) {
for (unsigned i = 0; i < numMods; i++) if (ums[i]->onEspNowMessage(sender, payload, len)) return true;
for (auto mod = _usermod_table_begin; mod < _usermod_table_end; ++mod) if ((*mod)->onEspNowMessage(sender, payload, len)) return true;
return false;
}
#endif
void UsermodManager::onUpdateBegin(bool init) { for (unsigned i = 0; i < numMods; i++) ums[i]->onUpdateBegin(init); } // notify usermods that update is to begin
void UsermodManager::onStateChange(uint8_t mode) { for (unsigned i = 0; i < numMods; i++) ums[i]->onStateChange(mode); } // notify usermods that WLED state changed
void UsermodManager::onUpdateBegin(bool init) { for (auto mod = _usermod_table_begin; mod < _usermod_table_end; ++mod) (*mod)->onUpdateBegin(init); } // notify usermods that update is to begin
void UsermodManager::onStateChange(uint8_t mode) { for (auto mod = _usermod_table_begin; mod < _usermod_table_end; ++mod) (*mod)->onStateChange(mode); } // notify usermods that WLED state changed
/*
* Enables usermods to lookup another Usermod.
*/
Usermod* UsermodManager::lookup(uint16_t mod_id) {
for (unsigned i = 0; i < numMods; i++) {
if (ums[i]->getId() == mod_id) {
return ums[i];
for (auto mod = _usermod_table_begin; mod < _usermod_table_end; ++mod) {
if ((*mod)->getId() == mod_id) {
return *mod;
}
}
return nullptr;
}
bool UsermodManager::add(Usermod* um)
{
if (numMods >= WLED_MAX_USERMODS || um == nullptr) return false;
ums[numMods++] = um;
return true;
}
size_t UsermodManager::getModCount() { return getCount(); };
/* Usermod v2 interface shim for oappend */
Print* Usermod::oappend_shim = nullptr;

View File

@ -1,18 +0,0 @@
#pragma once
#include "wled.h"
//This is an empty v2 usermod template. Please see the file usermod_v2_example.h in the EXAMPLE_v2 usermod folder for documentation on the functions you can use!
class UsermodRenameMe : public Usermod {
private:
public:
void setup() {
}
void loop() {
}
};

View File

@ -1,482 +0,0 @@
#include "wled.h"
/*
* Register your v2 usermods here!
* (for v1 usermods using just usermod.cpp, you can ignore this file)
*/
/*
* Add/uncomment your usermod filename here (and once more below)
* || || ||
* \/ \/ \/
*/
//#include "../usermods/EXAMPLE_v2/usermod_v2_example.h"
#ifdef USERMOD_BATTERY
#include "../usermods/Battery/usermod_v2_Battery.h"
#endif
#ifdef USERMOD_DALLASTEMPERATURE
#include "../usermods/Temperature/usermod_temperature.h"
#endif
#ifdef USERMOD_SHT
#include "../usermods/sht/usermod_sht.h"
#endif
#ifdef USERMOD_SN_PHOTORESISTOR
#include "../usermods/SN_Photoresistor/usermod_sn_photoresistor.h"
#endif
#ifdef USERMOD_PWM_FAN
// requires DALLASTEMPERATURE or SHT included before it
#include "../usermods/PWM_fan/usermod_PWM_fan.h"
#endif
#ifdef USERMOD_BUZZER
#include "../usermods/buzzer/usermod_v2_buzzer.h"
#endif
#ifdef USERMOD_SENSORSTOMQTT
#include "../usermods/sensors_to_mqtt/usermod_v2_SensorsToMqtt.h"
#endif
#ifdef USERMOD_PIRSWITCH
#include "../usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h"
#endif
#ifdef USERMOD_BH1750
#include "../usermods/BH1750_v2/usermod_bh1750.h"
#endif
// BME280 v2 usermod. Define "USERMOD_BME280" in my_config.h
#ifdef USERMOD_BME280
#include "../usermods/BME280_v2/usermod_bme280.h"
#endif
#ifdef USERMOD_BME68X
#include "../usermods/BME68X_v2/usermod_bme68x.h"
#endif
#ifdef USERMOD_FOUR_LINE_DISPLAY
#include "../usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display_ALT.h"
#endif
#ifdef USERMOD_ROTARY_ENCODER_UI
#include "../usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h"
#endif
#ifdef USERMOD_AUTO_SAVE
#include "../usermods/usermod_v2_auto_save/usermod_v2_auto_save.h"
#endif
#ifdef USERMOD_DHT
#include "../usermods/DHT/usermod_dht.h"
#endif
#ifdef USERMOD_VL53L0X_GESTURES
#include "../usermods/VL53L0X_gestures/usermod_vl53l0x_gestures.h"
#endif
#ifdef USERMOD_ANIMATED_STAIRCASE
#include "../usermods/Animated_Staircase/Animated_Staircase.h"
#endif
#ifdef USERMOD_MULTI_RELAY
#include "../usermods/multi_relay/usermod_multi_relay.h"
#endif
#ifdef USERMOD_RTC
#include "../usermods/RTC/usermod_rtc.h"
#endif
#ifdef USERMOD_ELEKSTUBE_IPS
#include "../usermods/EleksTube_IPS/usermod_elekstube_ips.h"
#endif
#ifdef USERMOD_ROTARY_ENCODER_BRIGHTNESS_COLOR
#include "../usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.h"
#endif
#ifdef RGB_ROTARY_ENCODER
#include "../usermods/rgb-rotary-encoder/rgb-rotary-encoder.h"
#endif
#ifdef USERMOD_ST7789_DISPLAY
#include "../usermods/ST7789_display/ST7789_Display.h"
#endif
#ifdef USERMOD_PIXELS_DICE_TRAY
#include "../usermods/pixels_dice_tray/pixels_dice_tray.h"
#endif
#ifdef USERMOD_SEVEN_SEGMENT
#include "../usermods/seven_segment_display/usermod_v2_seven_segment_display.h"
#endif
#ifdef USERMOD_SSDR
#include "../usermods/seven_segment_display_reloaded/usermod_seven_segment_reloaded.h"
#endif
#ifdef USERMOD_CRONIXIE
#include "../usermods/Cronixie/usermod_cronixie.h"
#endif
#ifdef QUINLED_AN_PENTA
#include "../usermods/quinled-an-penta/quinled-an-penta.h"
#endif
#ifdef USERMOD_WIZLIGHTS
#include "../usermods/wizlights/wizlights.h"
#endif
#ifdef USERMOD_WIREGUARD
#include "../usermods/wireguard/wireguard.h"
#endif
#ifdef USERMOD_WORDCLOCK
#include "../usermods/usermod_v2_word_clock/usermod_v2_word_clock.h"
#endif
#ifdef USERMOD_MY9291
#include "../usermods/MY9291/usermode_MY9291.h"
#endif
#ifdef USERMOD_SI7021_MQTT_HA
#include "../usermods/Si7021_MQTT_HA/usermod_si7021_mqtt_ha.h"
#endif
#ifdef USERMOD_SMARTNEST
#include "../usermods/smartnest/usermod_smartnest.h"
#endif
#ifdef USERMOD_AUDIOREACTIVE
#include "../usermods/audioreactive/audio_reactive.h"
#endif
#ifdef USERMOD_ANALOG_CLOCK
#include "../usermods/Analog_Clock/Analog_Clock.h"
#endif
#ifdef USERMOD_PING_PONG_CLOCK
#include "../usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.h"
#endif
#ifdef USERMOD_ADS1115
#include "../usermods/ADS1115_v2/usermod_ads1115.h"
#endif
#ifdef USERMOD_KLIPPER_PERCENTAGE
#include "../usermods/usermod_v2_klipper_percentage/usermod_v2_klipper_percentage.h"
#endif
#ifdef USERMOD_BOBLIGHT
#include "../usermods/boblight/boblight.h"
#endif
#ifdef USERMOD_ANIMARTRIX
#include "../usermods/usermod_v2_animartrix/usermod_v2_animartrix.h"
#endif
#ifdef USERMOD_INTERNAL_TEMPERATURE
#include "../usermods/Internal_Temperature_v2/usermod_internal_temperature.h"
#endif
#if defined(WLED_USE_SD_MMC) || defined(WLED_USE_SD_SPI)
// This include of SD.h and SD_MMC.h must happen here, else they won't be
// resolved correctly (when included in mod's header only)
#ifdef WLED_USE_SD_MMC
#include "SD_MMC.h"
#elif defined(WLED_USE_SD_SPI)
#include "SD.h"
#include "SPI.h"
#endif
#include "../usermods/sd_card/usermod_sd_card.h"
#endif
#ifdef USERMOD_PWM_OUTPUTS
#include "../usermods/pwm_outputs/usermod_pwm_outputs.h"
#endif
#ifdef USERMOD_HTTP_PULL_LIGHT_CONTROL
#include "../usermods/usermod_v2_HttpPullLightControl/usermod_v2_HttpPullLightControl.h"
#endif
#ifdef USERMOD_MPU6050_IMU
#include "../usermods/mpu6050_imu/usermod_mpu6050_imu.h"
#endif
#ifdef USERMOD_MPU6050_IMU
#include "../usermods/mpu6050_imu/usermod_gyro_surge.h"
#endif
#ifdef USERMOD_LDR_DUSK_DAWN
#include "../usermods/LDR_Dusk_Dawn_v2/usermod_LDR_Dusk_Dawn_v2.h"
#endif
#ifdef USERMOD_POV_DISPLAY
#include "../usermods/pov_display/usermod_pov_display.h"
#endif
#ifdef USERMOD_STAIRCASE_WIPE
#include "../usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h"
#endif
#ifdef USERMOD_MAX17048
#include "../usermods/MAX17048_v2/usermod_max17048.h"
#endif
#ifdef USERMOD_TETRISAI
#include "../usermods/TetrisAI_v2/usermod_v2_tetrisai.h"
#endif
#ifdef USERMOD_AHT10
#include "../usermods/AHT10_v2/usermod_aht10.h"
#endif
#ifdef USERMOD_INA226
#include "../usermods/INA226_v2/usermod_ina226.h"
#endif
#ifdef USERMOD_LD2410
#include "../usermods/LD2410_v2/usermod_ld2410.h"
#endif
#ifdef USERMOD_DEEP_SLEEP
#include "../usermods/deep_sleep/usermod_deep_sleep.h"
#endif
void registerUsermods()
{
/*
* Add your usermod class name here
* || || ||
* \/ \/ \/
*/
//UsermodManager::add(new MyExampleUsermod());
#ifdef USERMOD_BATTERY
UsermodManager::add(new UsermodBattery());
#endif
#ifdef USERMOD_DALLASTEMPERATURE
UsermodManager::add(new UsermodTemperature());
#endif
#ifdef USERMOD_SN_PHOTORESISTOR
UsermodManager::add(new Usermod_SN_Photoresistor());
#endif
#ifdef USERMOD_PWM_FAN
UsermodManager::add(new PWMFanUsermod());
#endif
#ifdef USERMOD_BUZZER
UsermodManager::add(new BuzzerUsermod());
#endif
#ifdef USERMOD_BH1750
UsermodManager::add(new Usermod_BH1750());
#endif
#ifdef USERMOD_BME280
UsermodManager::add(new UsermodBME280());
#endif
#ifdef USERMOD_BME68X
UsermodManager::add(new UsermodBME68X());
#endif
#ifdef USERMOD_SENSORSTOMQTT
UsermodManager::add(new UserMod_SensorsToMQTT());
#endif
#ifdef USERMOD_PIRSWITCH
UsermodManager::add(new PIRsensorSwitch());
#endif
#ifdef USERMOD_FOUR_LINE_DISPLAY
UsermodManager::add(new FourLineDisplayUsermod());
#endif
#ifdef USERMOD_ROTARY_ENCODER_UI
UsermodManager::add(new RotaryEncoderUIUsermod()); // can use USERMOD_FOUR_LINE_DISPLAY
#endif
#ifdef USERMOD_AUTO_SAVE
UsermodManager::add(new AutoSaveUsermod()); // can use USERMOD_FOUR_LINE_DISPLAY
#endif
#ifdef USERMOD_DHT
UsermodManager::add(new UsermodDHT());
#endif
#ifdef USERMOD_VL53L0X_GESTURES
UsermodManager::add(new UsermodVL53L0XGestures());
#endif
#ifdef USERMOD_ANIMATED_STAIRCASE
UsermodManager::add(new Animated_Staircase());
#endif
#ifdef USERMOD_MULTI_RELAY
UsermodManager::add(new MultiRelay());
#endif
#ifdef USERMOD_RTC
UsermodManager::add(new RTCUsermod());
#endif
#ifdef USERMOD_ELEKSTUBE_IPS
UsermodManager::add(new ElekstubeIPSUsermod());
#endif
#ifdef USERMOD_ROTARY_ENCODER_BRIGHTNESS_COLOR
UsermodManager::add(new RotaryEncoderBrightnessColor());
#endif
#ifdef RGB_ROTARY_ENCODER
UsermodManager::add(new RgbRotaryEncoderUsermod());
#endif
#ifdef USERMOD_ST7789_DISPLAY
UsermodManager::add(new St7789DisplayUsermod());
#endif
#ifdef USERMOD_PIXELS_DICE_TRAY
UsermodManager::add(new PixelsDiceTrayUsermod());
#endif
#ifdef USERMOD_SEVEN_SEGMENT
UsermodManager::add(new SevenSegmentDisplay());
#endif
#ifdef USERMOD_SSDR
UsermodManager::add(new UsermodSSDR());
#endif
#ifdef USERMOD_CRONIXIE
UsermodManager::add(new UsermodCronixie());
#endif
#ifdef QUINLED_AN_PENTA
UsermodManager::add(new QuinLEDAnPentaUsermod());
#endif
#ifdef USERMOD_WIZLIGHTS
UsermodManager::add(new WizLightsUsermod());
#endif
#ifdef USERMOD_WIREGUARD
UsermodManager::add(new WireguardUsermod());
#endif
#ifdef USERMOD_WORDCLOCK
UsermodManager::add(new WordClockUsermod());
#endif
#ifdef USERMOD_MY9291
UsermodManager::add(new MY9291Usermod());
#endif
#ifdef USERMOD_SI7021_MQTT_HA
UsermodManager::add(new Si7021_MQTT_HA());
#endif
#ifdef USERMOD_SMARTNEST
UsermodManager::add(new Smartnest());
#endif
#ifdef USERMOD_AUDIOREACTIVE
UsermodManager::add(new AudioReactive());
#endif
#ifdef USERMOD_ANALOG_CLOCK
UsermodManager::add(new AnalogClockUsermod());
#endif
#ifdef USERMOD_PING_PONG_CLOCK
UsermodManager::add(new PingPongClockUsermod());
#endif
#ifdef USERMOD_ADS1115
UsermodManager::add(new ADS1115Usermod());
#endif
#ifdef USERMOD_KLIPPER_PERCENTAGE
UsermodManager::add(new klipper_percentage());
#endif
#ifdef USERMOD_BOBLIGHT
UsermodManager::add(new BobLightUsermod());
#endif
#ifdef SD_ADAPTER
UsermodManager::add(new UsermodSdCard());
#endif
#ifdef USERMOD_PWM_OUTPUTS
UsermodManager::add(new PwmOutputsUsermod());
#endif
#ifdef USERMOD_SHT
UsermodManager::add(new ShtUsermod());
#endif
#ifdef USERMOD_ANIMARTRIX
UsermodManager::add(new AnimartrixUsermod("Animartrix", false));
#endif
#ifdef USERMOD_INTERNAL_TEMPERATURE
UsermodManager::add(new InternalTemperatureUsermod());
#endif
#ifdef USERMOD_HTTP_PULL_LIGHT_CONTROL
UsermodManager::add(new HttpPullLightControl());
#endif
#ifdef USERMOD_MPU6050_IMU
static MPU6050Driver mpu6050; UsermodManager::add(&mpu6050);
#endif
#ifdef USERMOD_GYRO_SURGE
static GyroSurge gyro_surge; UsermodManager::add(&gyro_surge);
#endif
#ifdef USERMOD_LDR_DUSK_DAWN
UsermodManager::add(new LDR_Dusk_Dawn_v2());
#endif
#ifdef USERMOD_STAIRCASE_WIPE
UsermodManager::add(new StairwayWipeUsermod());
#endif
#ifdef USERMOD_MAX17048
UsermodManager::add(new Usermod_MAX17048());
#endif
#ifdef USERMOD_TETRISAI
UsermodManager::add(new TetrisAIUsermod());
#endif
#ifdef USERMOD_AHT10
UsermodManager::add(new UsermodAHT10());
#endif
#ifdef USERMOD_INA226
UsermodManager::add(new UsermodINA226());
#endif
#ifdef USERMOD_LD2410
UsermodManager::add(new LD2410Usermod());
#endif
#ifdef USERMOD_POV_DISPLAY
UsermodManager::add(new PovDisplayUsermod());
#endif
#ifdef USERMOD_DEEP_SLEEP
usermods.add(new DeepSleepUsermod());
#endif
}

View File

@ -424,9 +424,6 @@ void WLED::setup()
PinManager::allocatePin(2, true, PinOwner::DMX);
#endif
DEBUG_PRINTLN(F("Registering usermods ..."));
registerUsermods();
DEBUG_PRINTF_P(PSTR("heap %u\n"), ESP.getFreeHeap());
bool fsinit = false;