2020-05-28 00:20:02 +00:00
# include "wled.h"
/*
* Registration and management utility for v2 usermods
*/
2024-09-14 19:09:47 +00:00
// 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 ] ;
}
2024-10-20 14:42:02 +00:00
2020-05-28 00:20:02 +00:00
//Usermod Manager internals
2024-09-14 19:09:47 +00:00
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 ) ; }
2023-01-06 08:24:29 +00:00
bool UsermodManager : : handleButton ( uint8_t b ) {
2021-10-17 15:14:55 +00:00
bool overrideIO = false ;
2024-09-14 19:09:47 +00:00
for ( auto mod = _usermod_table_begin ; mod < _usermod_table_end ; + + mod ) {
if ( ( * mod ) - > handleButton ( b ) ) overrideIO = true ;
2021-10-17 15:14:55 +00:00
}
return overrideIO ;
}
2023-01-06 08:24:29 +00:00
bool UsermodManager : : getUMData ( um_data_t * * data , uint8_t mod_id ) {
2024-09-14 19:09:47 +00:00
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)
2022-06-08 19:14:01 +00:00
}
return false ;
}
2024-09-14 19:09:47 +00:00
void UsermodManager : : addToJsonState ( JsonObject & obj ) { for ( auto mod = _usermod_table_begin ; mod < _usermod_table_end ; + + mod ) ( * mod ) - > addToJsonState ( obj ) ; }
2025-05-19 20:53:08 +00:00
void UsermodManager : : addToJsonInfo ( JsonObject & obj ) {
auto um_id_list = obj . createNestedArray ( " um " ) ;
for ( auto mod = _usermod_table_begin ; mod < _usermod_table_end ; + + mod ) {
um_id_list . add ( ( * mod ) - > getId ( ) ) ;
( * mod ) - > addToJsonInfo ( obj ) ;
}
}
2024-09-14 19:09:47 +00:00
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 ) ; }
2023-01-06 08:24:29 +00:00
bool UsermodManager : : readFromConfig ( JsonObject & obj ) {
2021-06-24 23:26:15 +00:00
bool allComplete = true ;
2024-09-14 19:09:47 +00:00
for ( auto mod = _usermod_table_begin ; mod < _usermod_table_end ; + + mod ) {
if ( ! ( * mod ) - > readFromConfig ( obj ) ) allComplete = false ;
2021-06-24 23:26:15 +00:00
}
return allComplete ;
}
2024-05-25 18:01:38 +00:00
# ifndef WLED_DISABLE_MQTT
2024-09-14 19:09:47 +00:00
void UsermodManager : : onMqttConnect ( bool sessionPresent ) { for ( auto mod = _usermod_table_begin ; mod < _usermod_table_end ; + + mod ) ( * mod ) - > onMqttConnect ( sessionPresent ) ; }
2021-05-07 10:41:39 +00:00
bool UsermodManager : : onMqttMessage ( char * topic , char * payload ) {
2024-09-14 19:09:47 +00:00
for ( auto mod = _usermod_table_begin ; mod < _usermod_table_end ; + + mod ) if ( ( * mod ) - > onMqttMessage ( topic , payload ) ) return true ;
2021-05-07 10:41:39 +00:00
return false ;
}
2024-05-25 18:01:38 +00:00
# endif
# ifndef WLED_DISABLE_ESPNOW
bool UsermodManager : : onEspNowMessage ( uint8_t * sender , uint8_t * payload , uint8_t len ) {
2024-09-14 19:09:47 +00:00
for ( auto mod = _usermod_table_begin ; mod < _usermod_table_end ; + + mod ) if ( ( * mod ) - > onEspNowMessage ( sender , payload , len ) ) return true ;
2024-05-25 18:01:38 +00:00
return false ;
}
# endif
2024-09-14 19:09:47 +00:00
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
2020-05-28 00:20:02 +00:00
2021-02-09 16:15:43 +00:00
/*
* Enables usermods to lookup another Usermod .
*/
Usermod * UsermodManager : : lookup ( uint16_t mod_id ) {
2024-09-14 19:09:47 +00:00
for ( auto mod = _usermod_table_begin ; mod < _usermod_table_end ; + + mod ) {
if ( ( * mod ) - > getId ( ) = = mod_id ) {
return * mod ;
2021-02-09 16:15:43 +00:00
}
}
return nullptr ;
}
2024-09-14 19:09:47 +00:00
size_t UsermodManager : : getModCount ( ) { return getCount ( ) ; } ;
2024-09-17 22:26:46 +00:00
/* Usermod v2 interface shim for oappend */
Print * Usermod : : oappend_shim = nullptr ;
2024-09-18 23:19:40 +00:00
void Usermod : : appendConfigData ( Print & settingsScript ) {
2024-09-17 22:26:46 +00:00
assert ( ! oappend_shim ) ;
2024-09-18 23:19:40 +00:00
oappend_shim = & settingsScript ;
2024-09-17 22:26:46 +00:00
this - > appendConfigData ( ) ;
oappend_shim = nullptr ;
}