2020-11-06 21:12:48 +00:00
# include "wled.h"
/*
* Methods to handle saving and loading presets to / from the filesystem
*/
2022-01-01 11:52:50 +00:00
# ifdef ARDUINO_ARCH_ESP32
static char * tmpRAMbuffer = nullptr ;
# endif
static volatile byte presetToApply = 0 ;
static volatile byte callModeToApply = 0 ;
2022-02-02 19:53:16 +00:00
static volatile bool checkPlaylist = false ;
2022-01-01 11:52:50 +00:00
2022-02-02 19:53:16 +00:00
bool applyPreset ( byte index , byte callMode , bool fromJson )
2020-11-06 21:12:48 +00:00
{
2022-01-01 11:52:50 +00:00
presetToApply = index ;
callModeToApply = callMode ;
2022-02-02 19:53:16 +00:00
checkPlaylist = fromJson ;
2022-01-01 11:52:50 +00:00
return true ;
}
void handlePresets ( )
{
if ( presetToApply = = 0 | | fileDoc ) return ; //JSON buffer allocated (apply preset in next cycle) or no preset waiting
JsonObject fdo ;
2022-02-02 21:00:31 +00:00
const char * filename = presetToApply < 255 ? " /presets.json " : " /tmp.json " ;
2022-01-01 11:52:50 +00:00
// allocate buffer
DEBUG_PRINTLN ( F ( " Apply preset JSON buffer requested. " ) ) ;
if ( ! requestJSONBufferLock ( 9 ) ) return ; // will also assign fileDoc
# ifdef ARDUINO_ARCH_ESP32
if ( presetToApply = = 255 & & tmpRAMbuffer ! = nullptr ) {
deserializeJson ( * fileDoc , tmpRAMbuffer ) ;
errorFlag = ERR_NONE ;
} else
# endif
{
errorFlag = readObjectFromFileUsingId ( filename , presetToApply , fileDoc ) ? ERR_NONE : ERR_FS_PLOAD ;
2020-11-06 21:12:48 +00:00
}
2022-01-01 11:52:50 +00:00
fdo = fileDoc - > as < JsonObject > ( ) ;
2022-01-03 21:23:03 +00:00
//HTTP API commands
const char * httpwin = fdo [ " win " ] ;
if ( httpwin ) {
2022-02-19 19:34:37 +00:00
String apireq = " win " ; apireq + = ' & ' ; // reduce flash string usage
2022-01-03 21:23:03 +00:00
apireq + = httpwin ;
handleSet ( nullptr , apireq , false ) ;
} else {
fdo . remove ( " ps " ) ; //remove load request for presets to prevent recursive crash
2022-02-02 19:53:16 +00:00
// if we applyPreset from JSON and preset contains "seg" we must unload playlist
if ( checkPlaylist & & ! fdo [ " seg " ] . isNull ( ) ) unloadPlaylist ( ) ;
2022-01-03 21:23:03 +00:00
deserializeState ( fdo , CALL_MODE_NO_NOTIFY , presetToApply ) ;
}
2020-11-06 21:12:48 +00:00
2022-01-01 11:52:50 +00:00
# if defined(ARDUINO_ARCH_ESP32)
//Aircoookie recommended not to delete buffer
if ( presetToApply = = 255 & & tmpRAMbuffer ! = nullptr ) {
free ( tmpRAMbuffer ) ;
tmpRAMbuffer = nullptr ;
2020-11-06 21:12:48 +00:00
}
2022-01-01 11:52:50 +00:00
# endif
releaseJSONBufferLock ( ) ; // will also clear fileDoc
if ( ! errorFlag & & presetToApply < 255 ) currentPreset = presetToApply ;
2022-01-03 21:23:03 +00:00
colorUpdated ( callModeToApply ) ;
updateInterfaces ( callModeToApply ) ;
2022-01-01 11:52:50 +00:00
presetToApply = 0 ; //clear request for preset
callModeToApply = 0 ;
2022-02-02 19:53:16 +00:00
checkPlaylist = false ;
2020-11-06 21:12:48 +00:00
}
2022-01-01 11:52:50 +00:00
//called from handleSet(PS=) [network callback (fileDoc==nullptr), IR (irrational), deserializeState, UDP] and deserializeState() [network callback (filedoc!=nullptr)]
2022-03-15 08:55:23 +00:00
void savePreset ( byte index , const char * pname , JsonObject saveobj )
2020-11-06 21:12:48 +00:00
{
2022-03-15 08:55:23 +00:00
if ( index = = 0 | | ( index > 250 & & index < 255 ) ) return ;
2022-02-19 10:37:48 +00:00
char tmp [ 12 ] ;
2020-11-06 21:12:48 +00:00
JsonObject sObj = saveobj ;
2022-01-01 11:52:50 +00:00
bool bufferAllocated = false ;
2020-11-06 21:12:48 +00:00
2022-03-15 08:55:23 +00:00
bool persist = ( index ! = 255 ) ;
2022-02-02 21:00:31 +00:00
const char * filename = persist ? " /presets.json " : " /tmp.json " ;
2021-10-04 18:22:04 +00:00
2021-11-03 13:52:22 +00:00
if ( ! fileDoc ) {
2022-01-01 11:52:50 +00:00
// called from handleSet() HTTP API
2021-11-12 22:33:10 +00:00
DEBUG_PRINTLN ( F ( " Save preset JSON buffer requested. " ) ) ;
2021-11-14 15:56:34 +00:00
if ( ! requestJSONBufferLock ( 10 ) ) return ;
2022-01-01 11:52:50 +00:00
sObj = fileDoc - > to < JsonObject > ( ) ;
bufferAllocated = true ;
}
2022-02-19 10:37:48 +00:00
if ( sObj [ " n " ] . isNull ( ) & & pname = = nullptr ) {
sprintf_P ( tmp , PSTR ( " Preset %d " ) , index ) ;
sObj [ " n " ] = tmp ;
} else if ( pname ) sObj [ " n " ] = pname ;
2020-11-29 21:07:12 +00:00
2022-01-01 11:52:50 +00:00
sObj . remove ( F ( " psave " ) ) ;
sObj . remove ( F ( " v " ) ) ;
2021-11-03 13:52:22 +00:00
2022-01-01 11:52:50 +00:00
if ( ! sObj [ " o " ] ) {
DEBUGFS_PRINTLN ( F ( " Serialize current state " ) ) ;
if ( sObj [ " ib " ] . isNull ( ) & & sObj [ " sb " ] . isNull ( ) ) serializeState ( sObj , true ) ;
else serializeState ( sObj , true , sObj [ " ib " ] , sObj [ " sb " ] ) ;
if ( persist ) currentPreset = index ;
}
sObj . remove ( " o " ) ;
sObj . remove ( " ib " ) ;
sObj . remove ( " sb " ) ;
2022-01-14 13:27:11 +00:00
sObj . remove ( F ( " sc " ) ) ;
2022-01-01 11:52:50 +00:00
sObj . remove ( F ( " error " ) ) ;
sObj . remove ( F ( " time " ) ) ;
2020-11-06 21:12:48 +00:00
2022-01-01 11:52:50 +00:00
# if defined(ARDUINO_ARCH_ESP32)
if ( index = = 255 ) {
if ( tmpRAMbuffer ! = nullptr ) free ( tmpRAMbuffer ) ;
size_t len = measureJson ( * fileDoc ) + 1 ;
DEBUG_PRINTLN ( len ) ;
// if possible use SPI RAM on ESP32
# ifdef WLED_USE_PSRAM
if ( psramFound ( ) )
tmpRAMbuffer = ( char * ) ps_malloc ( len ) ;
else
# endif
tmpRAMbuffer = ( char * ) malloc ( len ) ;
if ( tmpRAMbuffer ! = nullptr ) {
serializeJson ( * fileDoc , tmpRAMbuffer , len ) ;
} else {
writeObjectToFileUsingId ( filename , index , fileDoc ) ;
2020-11-29 21:07:12 +00:00
}
2022-01-01 11:52:50 +00:00
} else
# endif
writeObjectToFileUsingId ( filename , index , fileDoc ) ;
2020-11-06 21:12:48 +00:00
2021-10-04 18:22:04 +00:00
if ( persist ) presetsModifiedTime = toki . second ( ) ; //unix time
2022-01-01 11:52:50 +00:00
if ( bufferAllocated ) releaseJSONBufferLock ( ) ;
2020-11-06 21:12:48 +00:00
updateFSInfo ( ) ;
}
void deletePreset ( byte index ) {
StaticJsonDocument < 24 > empty ;
writeObjectToFileUsingId ( " /presets.json " , index , & empty ) ;
2021-05-25 07:59:19 +00:00
presetsModifiedTime = toki . second ( ) ; //unix time
2020-11-06 21:12:48 +00:00
updateFSInfo ( ) ;
}