mirror of
https://github.com/rstrouse/ESPSomfy-RTS.git
synced 2026-03-30 08:52:11 +02:00
backup with RAM
This commit is contained in:
parent
9113e58ec4
commit
2509030c49
9 changed files with 121 additions and 19 deletions
|
|
@ -82,3 +82,8 @@ Configuration of the Transceiver is done with the ELECHOUSE_CC1101 library which
|
|||
|
||||
|
||||
|
||||
pio pkg exec -p tool-esptoolpy -- esptool.py --port COM9 read_flash 0x3F0000 0x10000 coredump.bin
|
||||
|
||||
|
||||
|
||||
esp-coredump info_corefile --core coredump.bin --core-format=raw --gdb C:\Users\oem\.platformio\packages\toolchain-xtensa-esp32\bin\xtensa-esp32-elf-gdb.exe .pio\build\esp32dev\firmware.elf > coredump_report.txt
|
||||
|
|
@ -133,12 +133,12 @@ def minify_svg(text: str) -> str:
|
|||
|
||||
|
||||
MINIFIERS = {
|
||||
# ".html": minify_html,
|
||||
# ".htm": minify_html,
|
||||
# ".css": minify_css,
|
||||
".html": minify_html,
|
||||
".htm": minify_html,
|
||||
".css": minify_css,
|
||||
# ".js": minify_js,
|
||||
# ".json": minify_json,
|
||||
# ".svg": minify_svg,
|
||||
".svg": minify_svg,
|
||||
# ".xml": minify_svg, # same approach works for generic XML
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,9 +11,11 @@
|
|||
[platformio]
|
||||
default_envs = esp32dev
|
||||
|
||||
|
||||
|
||||
[env:esp32dev]
|
||||
platform = espressif32
|
||||
board = esp32-c3-devkitm-1
|
||||
board = esp32dev
|
||||
framework = arduino
|
||||
lib_deps =
|
||||
bblanchon/ArduinoJson@^7.2.2
|
||||
|
|
@ -23,7 +25,11 @@ lib_deps =
|
|||
extra_scripts = pre:minify.py
|
||||
board_build.partitions = min_spiffs.csv
|
||||
board_build.filesystem = littlefs
|
||||
|
||||
build_flags =
|
||||
-DCONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=1
|
||||
-DCONFIG_ESP_COREDUMP_DATA_FORMAT_ELF=1
|
||||
-DCONFIG_ESP_COREDUMP_CHECKSUM_CRC32=1
|
||||
|
||||
[env:esp32devdbg]
|
||||
build_type = debug
|
||||
platform = espressif32
|
||||
|
|
@ -36,4 +42,17 @@ lib_deps =
|
|||
knolleary/PubSubClient@^2.8
|
||||
extra_scripts = pre:minify.py
|
||||
board_build.partitions = min_spiffs.csv
|
||||
board_build.filesystem = littlefs
|
||||
|
||||
[env:esp32c3dev]
|
||||
platform = espressif32
|
||||
board = esp32-c3-devkitm-1
|
||||
framework = arduino
|
||||
lib_deps =
|
||||
bblanchon/ArduinoJson@^7.2.2
|
||||
links2004/WebSockets@^2.7.3
|
||||
lsatan/SmartRC-CC1101-Driver-Lib@^2.5.7
|
||||
knolleary/PubSubClient@^2.8
|
||||
extra_scripts = pre:minify.py
|
||||
board_build.partitions = min_spiffs.csv
|
||||
board_build.filesystem = littlefs
|
||||
|
|
@ -22,10 +22,15 @@ bool ConfigFile::begin(const char* filename, bool readOnly) {
|
|||
this->_opened = true;
|
||||
return true;
|
||||
}
|
||||
bool ConfigFile::beginRAM(String *buf) {
|
||||
_ramBuf = buf;
|
||||
_opened = true;
|
||||
return true;
|
||||
}
|
||||
void ConfigFile::end() {
|
||||
if(this->isOpen()) {
|
||||
if(!this->readOnly) this->file.flush();
|
||||
this->file.close();
|
||||
if(_ramBuf) { _ramBuf = nullptr; }
|
||||
else { if(!this->readOnly) this->file.flush(); this->file.close(); }
|
||||
}
|
||||
this->_opened = false;
|
||||
}
|
||||
|
|
@ -187,10 +192,16 @@ bool ConfigFile::readVarString(char *buff, size_t len) {
|
|||
bool ConfigFile::writeString(const char *val, size_t len, const char tok) {
|
||||
if(!this->isOpen()) return false;
|
||||
int slen = strlen(val);
|
||||
if(_ramBuf) {
|
||||
if(slen > 0) _ramBuf->concat(val);
|
||||
while(slen < (int)len - 1) { _ramBuf->concat(' '); slen++; }
|
||||
if(tok != CFG_TOK_NONE) _ramBuf->concat(tok);
|
||||
return true;
|
||||
}
|
||||
if(slen > 0)
|
||||
if(this->file.write((uint8_t *)val, slen) != slen) return false;
|
||||
// Now we need to pad the end of the string so that it is of a fixed length.
|
||||
while(slen < len - 1) {
|
||||
while(slen < (int)len - 1) {
|
||||
this->file.write(' ');
|
||||
slen++;
|
||||
}
|
||||
|
|
@ -202,6 +213,13 @@ bool ConfigFile::writeString(const char *val, size_t len, const char tok) {
|
|||
bool ConfigFile::writeVarString(const char *val, const char tok) {
|
||||
if(!this->isOpen()) return false;
|
||||
int slen = strlen(val);
|
||||
if(_ramBuf) {
|
||||
_ramBuf->concat((char)CFG_TOK_QUOTE);
|
||||
if(slen > 0) _ramBuf->concat(val);
|
||||
_ramBuf->concat((char)CFG_TOK_QUOTE);
|
||||
if(tok != CFG_TOK_NONE) _ramBuf->concat(tok);
|
||||
return true;
|
||||
}
|
||||
this->writeChar(CFG_TOK_QUOTE);
|
||||
if(slen > 0) if(this->file.write((uint8_t *)val, slen) != slen) return false;
|
||||
this->writeChar(CFG_TOK_QUOTE);
|
||||
|
|
@ -210,6 +228,7 @@ bool ConfigFile::writeVarString(const char *val, const char tok) {
|
|||
}
|
||||
bool ConfigFile::writeChar(const char val) {
|
||||
if(!this->isOpen()) return false;
|
||||
if(_ramBuf) { _ramBuf->concat(val); return true; }
|
||||
if(this->file.write(static_cast<uint8_t>(val)) == 1) return true;
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,12 +31,14 @@ struct config_header_t {
|
|||
class ConfigFile {
|
||||
protected:
|
||||
File file;
|
||||
String *_ramBuf = nullptr;
|
||||
bool readOnly = false;
|
||||
bool begin(const char *filename, bool readOnly = false);
|
||||
uint32_t startRecPos = 0;
|
||||
bool _opened = false;
|
||||
public:
|
||||
config_header_t header;
|
||||
bool beginRAM(String *buf);
|
||||
void end();
|
||||
bool isOpen();
|
||||
bool seekRecordByIndex(uint16_t ndx);
|
||||
|
|
|
|||
|
|
@ -633,8 +633,10 @@ void SomfyShadeController::commit() {
|
|||
void SomfyShadeController::writeBackup() {
|
||||
if(git.lockFS) return;
|
||||
esp_task_wdt_reset(); // Make sure we don't reset inadvertently.
|
||||
this->backupData = "";
|
||||
this->backupData.reserve(16384);
|
||||
ShadeConfigFile file;
|
||||
file.begin("/controller.backup", false);
|
||||
file.beginRAM(&this->backupData);
|
||||
file.backup(this);
|
||||
file.end();
|
||||
}
|
||||
|
|
@ -2888,6 +2890,7 @@ void SomfyShade::moveToMyPosition() {
|
|||
}
|
||||
void SomfyShade::sendCommand(somfy_commands cmd) { this->sendCommand(cmd, this->repeats); }
|
||||
void SomfyShade::sendCommand(somfy_commands cmd, uint8_t repeat, uint8_t stepSize) {
|
||||
Serial.print("Send command start\n");
|
||||
// This sendCommand function will always be called externally. sendCommand at the remote level
|
||||
// is expected to be called internally when the motor needs commanded.
|
||||
if(this->bitLength == 0) this->bitLength = somfy.transceiver.config.type;
|
||||
|
|
@ -2930,9 +2933,13 @@ void SomfyShade::sendCommand(somfy_commands cmd, uint8_t repeat, uint8_t stepSiz
|
|||
else if(cmd == somfy_commands::My) {
|
||||
if(this->isToggle() || this->shadeType == shade_types::drycontact)
|
||||
SomfyRemote::sendCommand(cmd, repeat);
|
||||
else if(this->shadeType == shade_types::drycontact2) return;
|
||||
else if(this->shadeType == shade_types::drycontact2){
|
||||
Serial.print("Send command start 1\n");
|
||||
return;
|
||||
}
|
||||
else if(this->isIdle()) {
|
||||
this->moveToMyPosition();
|
||||
this->moveToMyPosition();
|
||||
Serial.print("Send command end 2\n");
|
||||
return;
|
||||
}
|
||||
else {
|
||||
|
|
@ -2951,6 +2958,7 @@ void SomfyShade::sendCommand(somfy_commands cmd, uint8_t repeat, uint8_t stepSiz
|
|||
else {
|
||||
SomfyRemote::sendCommand(cmd, repeat, stepSize);
|
||||
}
|
||||
Serial.print("Send command end\n");
|
||||
}
|
||||
void SomfyGroup::sendCommand(somfy_commands cmd) { this->sendCommand(cmd, this->repeats); }
|
||||
void SomfyGroup::sendCommand(somfy_commands cmd, uint8_t repeat, uint8_t stepSize) {
|
||||
|
|
|
|||
|
|
@ -578,6 +578,7 @@ class SomfyShadeController {
|
|||
void processWaitingFrame();
|
||||
void commit();
|
||||
void writeBackup();
|
||||
String backupData;
|
||||
bool loadShadesFile(const char *filename);
|
||||
#ifdef USE_NVS
|
||||
bool loadLegacy();
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include "Somfy.h"
|
||||
#include "MQTT.h"
|
||||
#include "GitOTA.h"
|
||||
#include "esp_core_dump.h"
|
||||
|
||||
ConfigSettings settings;
|
||||
Web webServer;
|
||||
|
|
@ -20,11 +21,61 @@ MQTTClass mqtt;
|
|||
GitUpdater git;
|
||||
|
||||
uint32_t oldheap = 0;
|
||||
void setup() {
|
||||
|
||||
void inline checkCoreDumpPartition() {
|
||||
esp_core_dump_init();
|
||||
esp_core_dump_summary_t *summary =
|
||||
static_cast<esp_core_dump_summary_t *>(malloc(sizeof(esp_core_dump_summary_t)));
|
||||
if (summary) {
|
||||
esp_err_t err = esp_core_dump_get_summary(summary);
|
||||
if (err == ESP_OK) {
|
||||
log_i("Getting core dump summary ok.");
|
||||
|
||||
} else {
|
||||
log_e("Getting core dump summary not ok. Error: %d", (int)err);
|
||||
log_e("Probably no coredump present yet.");
|
||||
log_e("esp_core_dump_image_check() = %d", esp_core_dump_image_check());
|
||||
}
|
||||
free(summary);
|
||||
}
|
||||
}
|
||||
|
||||
void listDir(const char *dirname, uint8_t levels) {
|
||||
Serial.printf("Listing: %s\n", dirname);
|
||||
File root = LittleFS.open(dirname);
|
||||
if (!root || !root.isDirectory()) {
|
||||
Serial.println("Failed to open directory");
|
||||
return;
|
||||
}
|
||||
File file = root.openNextFile();
|
||||
while (file) {
|
||||
if (file.isDirectory()) {
|
||||
Serial.printf(" DIR : %s\n", file.name());
|
||||
if (levels) listDir(file.path(), levels - 1);
|
||||
} else {
|
||||
Serial.printf(" FILE: %-30s %d bytes\n", file.name(), file.size());
|
||||
}
|
||||
file = root.openNextFile();
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Serial.println();
|
||||
Serial.println("Startup/Boot....");
|
||||
Serial.println("Mounting File System...");
|
||||
checkCoreDumpPartition();
|
||||
|
||||
if (LittleFS.begin()) {
|
||||
Serial.printf("\nTotal: %d bytes\n", LittleFS.totalBytes());
|
||||
Serial.printf("Used: %d bytes\n", LittleFS.usedBytes());
|
||||
Serial.printf("Free: %d bytes\n", LittleFS.totalBytes() - LittleFS.usedBytes());
|
||||
Serial.println();
|
||||
listDir("/", 3);
|
||||
} else {
|
||||
Serial.println("LittleFS mount failed!");
|
||||
}
|
||||
|
||||
if(LittleFS.begin()) Serial.println("File system mounted successfully");
|
||||
else Serial.println("Error mounting file system");
|
||||
settings.begin();
|
||||
|
|
|
|||
|
|
@ -858,14 +858,11 @@ void Web::handleBackup(WebServer &server, bool attach) {
|
|||
}
|
||||
Serial.println("Saving current shade information");
|
||||
somfy.writeBackup();
|
||||
File file = LittleFS.open("/controller.backup", "r");
|
||||
if (!file) {
|
||||
Serial.println("Error opening shades.cfg");
|
||||
server.send(500, _encoding_text, "shades.cfg");
|
||||
if(somfy.backupData.length() == 0) {
|
||||
server.send(500, _encoding_text, "backup failed");
|
||||
return;
|
||||
}
|
||||
server.streamFile(file, _encoding_text);
|
||||
file.close();
|
||||
server.send(200, _encoding_text, somfy.backupData);
|
||||
}
|
||||
void Web::handleSetPositions(WebServer &server) {
|
||||
webServer.sendCORSHeaders(server);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue