Rework dispatcher commands

This commit is contained in:
fvanroie 2020-11-29 19:37:59 +01:00
parent 6eaa62458a
commit 5e1cce9b6a
12 changed files with 194 additions and 179 deletions

View File

@ -571,7 +571,7 @@ void haspLoadPage(const char * pages)
Log.notice(TAG_HASP, F("Loading file %s"), pages); Log.notice(TAG_HASP, F("Loading file %s"), pages);
File file = HASP_FS.open(pages, "r"); File file = HASP_FS.open(pages, "r");
dispatchParseJsonl(file); dispatch_parse_jsonl(file);
file.close(); file.close();
Log.trace(TAG_HASP, F("File %s loaded"), pages); Log.trace(TAG_HASP, F("File %s loaded"), pages);

View File

@ -153,7 +153,7 @@ void debugSetup()
// memset(serialInputBuffer, 0, sizeof(serialInputBuffer)); // memset(serialInputBuffer, 0, sizeof(serialInputBuffer));
// serialInputIndex = 0; // serialInputIndex = 0;
Log.notice(TAG_DEBG, F("Setting the console parser")); Log.notice(TAG_DEBG, F("Setting the console parser"));
debugConsole.setLineCallback(dispatchTextLine); debugConsole.setLineCallback(dispatch_text_line);
} }
void debugStartSyslog() void debugStartSyslog()
@ -673,11 +673,11 @@ void IRAM_ATTR debugLoop(void)
switch(keypress) { switch(keypress) {
case ConsoleInput::KEY_PAGE_UP: case ConsoleInput::KEY_PAGE_UP:
dispatchPageNext(); dispatch_page_next();
break; break;
case ConsoleInput::KEY_PAGE_DOWN: case ConsoleInput::KEY_PAGE_DOWN:
dispatchPagePrev(); dispatch_page_prev();
break; break;
case(ConsoleInput::KEY_FN)...(ConsoleInput::KEY_FN + 12): case(ConsoleInput::KEY_FN)...(ConsoleInput::KEY_FN + 12):

View File

@ -18,7 +18,9 @@
#include "hasp.h" #include "hasp.h"
uint8_t nCommands = 0; uint8_t nCommands = 0;
haspCommand_t commands[15]; haspCommand_t commands[16];
static void dispatch_config(const char * topic, const char * payload);
bool is_true(const char * s) bool is_true(const char * s)
{ {
@ -26,6 +28,19 @@ bool is_true(const char * s)
!strcmp_P(s, PSTR("1"))); !strcmp_P(s, PSTR("1")));
} }
void dispatch_screenshot(const char *, const char * filename)
{
if(strlen(filename) == 0) { // no filename given
char tempfile[32];
memcpy_P(tempfile, PSTR("/screenshot.bmp"), sizeof(tempfile));
guiTakeScreenshot(tempfile);
} else if(strlen(filename) > 31 || filename[0] != '/') { // Invalid filename
Log.warning(TAG_MSGR, "Invalid filename %s", filename);
} else { // Valid filename
guiTakeScreenshot(filename);
}
}
// Format filesystem and erase EEPROM // Format filesystem and erase EEPROM
bool dispatch_factory_reset() bool dispatch_factory_reset()
{ {
@ -68,7 +83,7 @@ void dispatchGpioOutput(String strTopic, const char * payload)
dispatchGpioOutput(strTemp.toInt(), is_true(payload)); dispatchGpioOutput(strTemp.toInt(), is_true(payload));
} }
// p[x].b[y]=value // p[x].b[y].attr=value
inline void dispatch_process_button_attribute(String strTopic, const char * payload) inline void dispatch_process_button_attribute(String strTopic, const char * payload)
{ {
// Log.verbose(TAG_MSGR,F("BTN ATTR: %s = %s"), strTopic.c_str(), payload); // Log.verbose(TAG_MSGR,F("BTN ATTR: %s = %s"), strTopic.c_str(), payload);
@ -97,7 +112,7 @@ inline void dispatch_process_button_attribute(String strTopic, const char * payl
} }
// objectattribute=value // objectattribute=value
void dispatchCommand(const char * topic, const char * payload) void dispatch_command(const char * topic, const char * payload)
{ {
/* ================================= Standard payload commands ======================================= */ /* ================================= Standard payload commands ======================================= */
@ -105,7 +120,7 @@ void dispatchCommand(const char * topic, const char * payload)
for(int i = 0; i < nCommands; i++) { for(int i = 0; i < nCommands; i++) {
if(!strcasecmp_P(topic, commands[i].p_cmdstr)) { if(!strcasecmp_P(topic, commands[i].p_cmdstr)) {
// Log.warning(TAG_MSGR, F("Command %d found in array !!!"), i); // Log.warning(TAG_MSGR, F("Command %d found in array !!!"), i);
commands[i].func((char *)payload); /* execute command */ commands[i].func(topic, payload); /* execute command */
return; return;
} }
} }
@ -115,8 +130,8 @@ void dispatchCommand(const char * topic, const char * payload)
if(strlen(topic) == 7 && topic == strstr_P(topic, PSTR("output"))) { if(strlen(topic) == 7 && topic == strstr_P(topic, PSTR("output"))) {
dispatchGpioOutput(topic, payload); dispatchGpioOutput(topic, payload);
} else if(strcasecmp_P(topic, PSTR("screenshot")) == 0) { // } else if(strcasecmp_P(topic, PSTR("screenshot")) == 0) {
guiTakeScreenshot("/screenshot.bmp"); // Literal String // guiTakeScreenshot("/screenshot.bmp"); // Literal String
} else if(topic == strstr_P(topic, PSTR("p["))) { } else if(topic == strstr_P(topic, PSTR("p["))) {
dispatch_process_button_attribute(topic, payload); dispatch_process_button_attribute(topic, payload);
@ -140,19 +155,19 @@ void dispatchCommand(const char * topic, const char * payload)
} else { } else {
if(strlen(payload) == 0) { if(strlen(payload) == 0) {
// dispatchTextLine(topic); // Could cause an infinite loop! // dispatch_text_line(topic); // Could cause an infinite loop!
} }
Log.warning(TAG_MSGR, F("Command '%s' not found => %s"), topic, payload); Log.warning(TAG_MSGR, F("Command '%s' not found => %s"), topic, payload);
} }
} }
// Strip command/config prefix from the topic and process the payload // Strip command/config prefix from the topic and process the payload
void dispatchTopicPayload(const char * topic, const char * payload) void dispatch_topic_payload(const char * topic, const char * payload)
{ {
// Log.verbose(TAG_MSGR,F("TOPIC: short topic: %s"), topic); // Log.verbose(TAG_MSGR,F("TOPIC: short topic: %s"), topic);
if(!strcmp_P(topic, PSTR("command"))) { if(!strcmp_P(topic, PSTR("command"))) {
dispatchTextLine((char *)payload); dispatch_text_line((char *)payload);
return; return;
} }
@ -162,63 +177,54 @@ void dispatchTopicPayload(const char * topic, const char * payload)
// '[...]/device/command/p[1].b[4].txt' -m '"Lights On"' == // '[...]/device/command/p[1].b[4].txt' -m '"Lights On"' ==
// nextionSetAttr("p[1].b[4].txt", "\"Lights On\"") // nextionSetAttr("p[1].b[4].txt", "\"Lights On\"")
dispatchCommand(topic, (char *)payload); dispatch_command(topic, (char *)payload);
return; return;
} }
if(topic == strstr_P(topic, PSTR("config/"))) { // startsWith command/ if(topic == strstr_P(topic, PSTR("config/"))) { // startsWith command/
topic += 7u; topic += 7u;
dispatchConfig(topic, (char *)payload); dispatch_config(topic, (char *)payload);
return; return;
} }
dispatchCommand(topic, (char *)payload); // dispatch as is dispatch_command(topic, (char *)payload); // dispatch as is
} }
// Parse one line of text and execute the command(s) // Parse one line of text and execute the command
void dispatchTextLine(const char * cmnd) void dispatch_text_line(const char * cmnd)
{ {
// dispatchPrintln(F("CMND"), cmnd); size_t pos1 = std::string(cmnd).find("=");
size_t pos2 = std::string(cmnd).find(" ");
size_t pos = 0;
if(cmnd == strstr_P(cmnd, PSTR("page "))) { // startsWith command/ // Find what comes first, ' ' or '='
dispatchPage(cmnd + 5); if(pos1 != std::string::npos) {
if(pos2 != std::string::npos) {
pos = (pos1 < pos2 ? pos1 : pos2);
} else {
pos = pos1;
}
} else { } else {
size_t pos1 = std::string(cmnd).find("="); pos = (pos2 != std::string::npos) ? pos2 : 0;
size_t pos2 = std::string(cmnd).find(" "); }
int pos = 0;
if(pos1 != std::string::npos) { if(pos > 0) { // ' ' or '=' found
if(pos2 != std::string::npos) { char topic[64];
pos = (pos1 < pos2 ? pos1 : pos2); memset(topic, 0, sizeof(topic));
} else { if(pos < sizeof(topic))
pos = pos1; memcpy(topic, cmnd, pos);
} else
memcpy(topic, cmnd, sizeof(topic) - 1);
} else if(pos2 != std::string::npos) { // topic is before '=', payload is after '=' position
pos = pos2; Log.notice(TAG_MSGR, F("%s = %s"), topic, cmnd + pos + 1);
} else { dispatch_topic_payload(topic, cmnd + pos + 1);
pos = 0; } else {
} char empty_payload[1] = {0};
Log.notice(TAG_MSGR, F("%s = %s"), cmnd, empty_payload);
if(pos > 0) { dispatch_topic_payload(cmnd, empty_payload);
String strTopic((char *)0);
// String strPayload((char *)0);
strTopic.reserve(pos + 1);
// strPayload.reserve(128);
strTopic = String(cmnd).substring(0, pos);
// strPayload = cmnd.substring(pos + 1, cmnd.length());
// cmnd[pos] = 0; // change '=' character into '\0'
dispatchTopicPayload(strTopic.c_str(),
cmnd + pos + 1); // topic is before '=', payload is after '=' position
} else {
char buf[1] = {0};
dispatchTopicPayload(cmnd, buf);
}
} }
} }
@ -240,23 +246,6 @@ void dispatch_output_idle_state(const char * state)
#endif #endif
} }
// restart the device
void dispatchReboot(bool saveConfig)
{
if(saveConfig) configWriteConfig();
#if HASP_USE_MQTT > 0
mqttStop(); // Stop the MQTT Client first
#endif
debugStop();
#if HASP_USE_WIFI > 0
wifiStop();
#endif
Log.verbose(TAG_MSGR, F("-------------------------------------"));
Log.notice(TAG_MSGR, F("HALT: Properly Rebooting the MCU now!"));
Serial.flush();
halRestartMcu();
}
void dispatch_button(uint8_t id, const char * event) void dispatch_button(uint8_t id, const char * event)
{ {
#if !defined(HASP_USE_MQTT) && !defined(HASP_USE_TASMOTA_SLAVE) #if !defined(HASP_USE_MQTT) && !defined(HASP_USE_TASMOTA_SLAVE)
@ -388,7 +377,7 @@ void IRAM_ATTR dispatch_obj_attribute_str(uint8_t pageid, uint8_t btnid, const c
} }
// Get or Set a part of the config.json file // Get or Set a part of the config.json file
void dispatchConfig(const char * topic, const char * payload) static void dispatch_config(const char * topic, const char * payload)
{ {
DynamicJsonDocument doc(128 * 2); DynamicJsonDocument doc(128 * 2);
char buffer[128 * 2]; char buffer[128 * 2];
@ -487,7 +476,7 @@ void dispatchConfig(const char * topic, const char * payload)
/********************************************** Native Commands ****************************************/ /********************************************** Native Commands ****************************************/
void dispatchParseJson(const char * payload) void dispatch_parse_json(const char *, const char * payload)
{ // Parse an incoming JSON array into individual commands { // Parse an incoming JSON array into individual commands
/* if(strPayload.endsWith(",]")) { /* if(strPayload.endsWith(",]")) {
// Trailing null array elements are an artifact of older Home Assistant automations // Trailing null array elements are an artifact of older Home Assistant automations
@ -502,54 +491,68 @@ void dispatchParseJson(const char * payload)
if(jsonError) { // Couldn't parse incoming JSON command if(jsonError) { // Couldn't parse incoming JSON command
Log.warning(TAG_MSGR, F("Failed to parse incoming JSON command with error: %s"), jsonError.c_str()); Log.warning(TAG_MSGR, F("Failed to parse incoming JSON command with error: %s"), jsonError.c_str());
} else {
if(json.is<JsonArray>()) { } else if(json.is<JsonArray>()) { // handle json as an array of commands
// handle json as an array of commands JsonArray arr = json.as<JsonArray>();
JsonArray arr = json.as<JsonArray>(); for(JsonVariant command : arr) {
for(JsonVariant command : arr) { dispatch_text_line(command.as<String>().c_str());
dispatchTextLine(command.as<String>().c_str());
}
} else if(json.is<JsonObject>()) {
// handle json as a jsonl
uint8_t savedPage = haspGetPage();
hasp_new_object(json.as<JsonObject>(), savedPage);
} else if(json.is<const char *>()) {
// handle json as a single command
dispatchTextLine(json.as<const char *>());
} else if(json.is<char *>()) {
// handle json as a single command
dispatchTextLine(json.as<char *>());
} else if(json.is<String>()) {
// handle json as a single command
dispatchTextLine(json.as<String>().c_str());
} else {
Log.warning(TAG_MSGR, F("Failed to parse incoming JSON command"));
} }
} else if(json.is<JsonObject>()) { // handle json as a jsonl
uint8_t savedPage = haspGetPage();
hasp_new_object(json.as<JsonObject>(), savedPage);
} else if(json.is<const char *>()) { // handle json as a single command
dispatch_text_line(json.as<const char *>());
} else if(json.is<char *>()) { // handle json as a single command
dispatch_text_line(json.as<char *>());
} else if(json.is<String>()) { // handle json as a single command
dispatch_text_line(json.as<String>().c_str());
} else {
Log.warning(TAG_MSGR, F("Failed to parse incoming JSON command"));
} }
} }
void dispatchParseJsonl(Stream & stream) void dispatch_parse_jsonl(Stream & stream)
{ {
DynamicJsonDocument jsonl(4 * 128u);
uint8_t savedPage = haspGetPage(); uint8_t savedPage = haspGetPage();
size_t line = 1;
DynamicJsonDocument jsonl(4 * 128u); // max ~256 characters per line
DeserializationError err = deserializeJson(jsonl, stream);
// Log.notice(TAG_MSGR,F("DISPATCH: jsonl")); while(err == DeserializationError::Ok) {
while(deserializeJson(jsonl, stream) == DeserializationError::Ok) {
// serializeJson(jsonl, Serial);
// Serial.println();
hasp_new_object(jsonl.as<JsonObject>(), savedPage); hasp_new_object(jsonl.as<JsonObject>(), savedPage);
err = deserializeJson(jsonl, stream);
line++;
}
/* For debugging pourposes */
if(err == DeserializationError::EmptyInput) {
Log.trace(TAG_MSGR, F("Jsonl parsed successfully"));
} else if(err == DeserializationError::InvalidInput || err == DeserializationError::IncompleteInput) {
Log.error(TAG_MSGR, F("Jsonl: Invalid Input at object %d"), line);
} else if(err == DeserializationError::NoMemory) {
Log.error(TAG_MSGR, F("Jsonl: No Memory at object %d"), line);
} else if(err == DeserializationError::NotSupported) {
Log.error(TAG_MSGR, F("Jsonl: Not Supported at object %d"), line);
} else if(err == DeserializationError::TooDeep) {
Log.error(TAG_MSGR, F("Jsonl: Too Deep at object %d"), line);
} }
} }
void dispatchParseJsonl(const char * payload) void dispatch_parse_jsonl(const char *, const char * payload)
{ {
CharStream stream((char *)payload); CharStream stream((char *)payload);
dispatchParseJsonl(stream); dispatch_parse_jsonl(stream);
} }
void dispatchCurrentPage() void dispatch_output_current_page()
{ {
// Log result // Log result
char buffer[4]; char buffer[4];
@ -565,16 +568,16 @@ void dispatchCurrentPage()
} }
// Get or Set a page // Get or Set a page
void dispatchPage(const char * page) void dispatch_page(const char *, const char * page)
{ {
if(strlen(page) > 0 && atoi(page) < HASP_NUM_PAGES) { if(strlen(page) > 0 && atoi(page) < HASP_NUM_PAGES) {
haspSetPage(atoi(page)); haspSetPage(atoi(page));
} }
dispatchCurrentPage(); dispatch_output_current_page();
} }
void dispatchPageNext() void dispatch_page_next()
{ {
uint8_t page = haspGetPage(); uint8_t page = haspGetPage();
if(page + 1 >= HASP_NUM_PAGES) { if(page + 1 >= HASP_NUM_PAGES) {
@ -583,10 +586,10 @@ void dispatchPageNext()
page++; page++;
} }
haspSetPage(page); haspSetPage(page);
dispatchCurrentPage(); dispatch_output_current_page();
} }
void dispatchPagePrev() void dispatch_page_prev()
{ {
uint8_t page = haspGetPage(); uint8_t page = haspGetPage();
if(page == 0) { if(page == 0) {
@ -595,11 +598,11 @@ void dispatchPagePrev()
page--; page--;
} }
haspSetPage(page); haspSetPage(page);
dispatchCurrentPage(); dispatch_output_current_page();
} }
// Clears a page id or the current page if empty // Clears a page id or the current page if empty
void dispatchClearPage(const char * page) void dispatch_clear_page(const char *, const char * page)
{ {
if(strlen(page) == 0) { if(strlen(page) == 0) {
haspClearPage(haspGetPage()); haspClearPage(haspGetPage());
@ -608,14 +611,13 @@ void dispatchClearPage(const char * page)
} }
} }
void dispatchDim(const char * level) void dispatch_dim(const char *, const char * level)
{ {
// Set the current state // Set the current state
if(strlen(level) != 0) guiSetDim(atoi(level)); if(strlen(level) != 0) guiSetDim(atoi(level));
// dispatchPrintln(F("DIM"), strDimLevel);
char buffer[4];
#if defined(HASP_USE_MQTT) || defined(HASP_USE_TASMOTA_SLAVE) #if defined(HASP_USE_MQTT) || defined(HASP_USE_TASMOTA_SLAVE)
char buffer[4];
itoa(guiGetDim(), buffer, DEC); itoa(guiGetDim(), buffer, DEC);
#if HASP_USE_MQTT > 0 #if HASP_USE_MQTT > 0
@ -629,11 +631,8 @@ void dispatchDim(const char * level)
#endif #endif
} }
void dispatchBacklight(const char * payload) void dispatch_backlight(const char *, const char * payload)
{ {
// strPayload.toUpperCase();
// dispatchPrintln(F("LIGHT"), strPayload);
// Set the current state // Set the current state
if(strlen(payload) != 0) guiSetBacklight(is_true(payload)); if(strlen(payload) != 0) guiSetBacklight(is_true(payload));
@ -658,7 +657,7 @@ void dispatch_output_statusupdate()
#endif #endif
} }
void dispatchWebUpdate(const char * espOtaUrl) void dispatch_web_update(const char *, const char * espOtaUrl)
{ {
#if HASP_USE_OTA > 0 #if HASP_USE_OTA > 0
Log.notice(TAG_MSGR, F("Checking for updates at URL: %s"), espOtaUrl); Log.notice(TAG_MSGR, F("Checking for updates at URL: %s"), espOtaUrl);
@ -666,38 +665,55 @@ void dispatchWebUpdate(const char * espOtaUrl)
#endif #endif
} }
// restart the device
void dispatch_reboot(bool saveConfig)
{
if(saveConfig) configWriteConfig();
#if HASP_USE_MQTT > 0
mqttStop(); // Stop the MQTT Client first
#endif
debugStop();
#if HASP_USE_WIFI > 0
wifiStop();
#endif
Log.verbose(TAG_MSGR, F("-------------------------------------"));
Log.notice(TAG_MSGR, F("HALT: Properly Rebooting the MCU now!"));
Serial.flush();
halRestartMcu();
}
/******************************************* Command Wrapper Functions *********************************/ /******************************************* Command Wrapper Functions *********************************/
void dispatch_output_statusupdate(const char *) void dispatch_output_statusupdate(const char *, const char *)
{ {
dispatch_output_statusupdate(); dispatch_output_statusupdate();
} }
void dispatchCalibrate(const char *) void dispatch_calibrate(const char *, const char *)
{ {
guiCalibrate(); guiCalibrate();
} }
void dispatchWakeup(const char *) void dispatch_wakeup(const char *, const char *)
{ {
haspWakeUp(); haspWakeUp();
} }
void dispatchReboot(const char *) void dispatch_reboot(const char *, const char *)
{ {
dispatchReboot(true); dispatch_reboot(true);
} }
void dispatch_factory_reset(const char *) void dispatch_factory_reset(const char *, const char *)
{ {
dispatch_factory_reset(); dispatch_factory_reset();
delay(250); delay(500);
dispatchReboot(false); // don't save config dispatch_reboot(false); // don't save config
} }
/******************************************* Commands builder *******************************************/ /******************************************* Commands builder *******************************************/
static void dispatch_add_command(const char * p_cmdstr, void (*func)(const char *)) static void dispatch_add_command(const char * p_cmdstr, void (*func)(const char *, const char *))
{ {
if(nCommands >= sizeof(commands) / sizeof(haspCommand_t)) { if(nCommands >= sizeof(commands) / sizeof(haspCommand_t)) {
Log.fatal(TAG_MSGR, F("Dispatchcer command array overflow: %d"), nCommands); Log.fatal(TAG_MSGR, F("Dispatchcer command array overflow: %d"), nCommands);
@ -716,22 +732,23 @@ void dispatchSetup()
// The command.func() call will receive the full payload as ONLY parameter! // The command.func() call will receive the full payload as ONLY parameter!
/* WARNING: remember to expand the commands array when adding new commands */ /* WARNING: remember to expand the commands array when adding new commands */
dispatch_add_command(PSTR("json"), dispatch_parse_json);
dispatch_add_command(PSTR("json"), dispatchParseJson); dispatch_add_command(PSTR("page"), dispatch_page);
dispatch_add_command(PSTR("page"), dispatchPage); dispatch_add_command(PSTR("wakeup"), dispatch_wakeup);
dispatch_add_command(PSTR("wakeup"), dispatchWakeup);
dispatch_add_command(PSTR("statusupdate"), dispatch_output_statusupdate); dispatch_add_command(PSTR("statusupdate"), dispatch_output_statusupdate);
dispatch_add_command(PSTR("clearpage"), dispatchClearPage); dispatch_add_command(PSTR("clearpage"), dispatch_clear_page);
dispatch_add_command(PSTR("jsonl"), dispatchParseJsonl); dispatch_add_command(PSTR("jsonl"), dispatch_parse_jsonl);
dispatch_add_command(PSTR("dim"), dispatchDim); dispatch_add_command(PSTR("dim"), dispatch_dim);
dispatch_add_command(PSTR("brightness"), dispatchDim); dispatch_add_command(PSTR("brightness"), dispatch_dim);
dispatch_add_command(PSTR("light"), dispatchBacklight); dispatch_add_command(PSTR("light"), dispatch_backlight);
dispatch_add_command(PSTR("calibrate"), dispatchCalibrate); dispatch_add_command(PSTR("calibrate"), dispatch_calibrate);
dispatch_add_command(PSTR("update"), dispatchWebUpdate); dispatch_add_command(PSTR("update"), dispatch_web_update);
dispatch_add_command(PSTR("reboot"), dispatchReboot); dispatch_add_command(PSTR("reboot"), dispatch_reboot);
dispatch_add_command(PSTR("restart"), dispatchReboot); dispatch_add_command(PSTR("restart"), dispatch_reboot);
dispatch_add_command(PSTR("screenshot"), dispatch_screenshot);
dispatch_add_command(PSTR("factoryreset"), dispatch_factory_reset); dispatch_add_command(PSTR("factoryreset"), dispatch_factory_reset);
dispatch_add_command(PSTR("setupap"), oobeFakeSetup); dispatch_add_command(PSTR("setupap"), oobeFakeSetup);
/* WARNING: remember to expand the commands array when adding new commands */
} }
void IRAM_ATTR dispatchLoop() void IRAM_ATTR dispatchLoop()

View File

@ -16,24 +16,24 @@ void dispatchStart(void);
void dispatchStop(void); void dispatchStop(void);
/* ===== Special Event Processors ===== */ /* ===== Special Event Processors ===== */
void dispatchConfig(const char * topic, const char * payload); void dispatch_topic_payload(const char * topic, const char * payload);
void dispatchTopicPayload(const char * topic, const char * payload); void dispatch_text_line(const char * cmnd);
void dispatchTextLine(const char * cmnd); void dispatch_parse_jsonl(Stream & stream);
void dispatchParseJsonl(Stream & stream); void dispatch_clear_page(const char * page);
void dispatchClearPage(const char * page);
void dispatchPage(const char * page); // void dispatchPage(uint8_t page);
void dispatchPageNext(); void dispatch_page_next();
void dispatchPagePrev(); void dispatch_page_prev();
void dispatchDim(const char * level); void dispatch_dim(const char * level);
void dispatchBacklight(const char * payload); void dispatch_backlight(const char * payload);
void dispatchWebUpdate(const char * espOtaUrl); void dispatch_web_update(const char * espOtaUrl);
void dispatchReboot(bool saveConfig); void dispatch_reboot(bool saveConfig);
void dispatch_output_idle_state(const char * state); void dispatch_output_idle_state(const char * state);
void dispatch_output_statusupdate(void); void dispatch_output_statusupdate(void);
void dispatch_output_current_page();
void dispatch_button(uint8_t id, const char * event); void dispatch_button(uint8_t id, const char * event);
@ -52,7 +52,7 @@ void IRAM_ATTR dispatch_send_obj_attribute_str(uint8_t pageid, uint8_t btnid, co
/* ===== Structs and Constants ===== */ /* ===== Structs and Constants ===== */
struct haspCommand_t struct haspCommand_t
{ {
void (*func)(const char *); void (*func)(const char *, const char *);
const char * p_cmdstr; const char * p_cmdstr;
}; };

View File

@ -95,6 +95,8 @@ void halRestartMcu(void)
#else #else
NVIC_SystemReset(); NVIC_SystemReset();
#endif #endif
for(;;) {
} // halt
} }
String halGetResetInfo() String halGetResetInfo()

View File

@ -275,7 +275,7 @@ void httpHandleReboot()
webSendFooter(); webSendFooter();
delay(200); delay(200);
dispatchReboot(true); dispatch_reboot(true);
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
@ -285,9 +285,9 @@ void webHandleScreenshot()
if(webServer.hasArg(F("a"))) { if(webServer.hasArg(F("a"))) {
if(webServer.arg(F("a")) == F("next")) { if(webServer.arg(F("a")) == F("next")) {
dispatchPageNext(); dispatch_page_next();
} else if(webServer.arg(F("a")) == F("prev")) { } else if(webServer.arg(F("a")) == F("prev")) {
dispatchPagePrev(); dispatch_page_prev();
} }
} }
@ -680,8 +680,7 @@ void webUpdateReboot()
webSendFooter(); webSendFooter();
delay(250); delay(250);
dispatchReboot(true); // Save the current config dispatch_reboot(true); // Save the current config
delay(5000);
} }
void webHandleFirmwareUpdate() void webHandleFirmwareUpdate()
@ -1120,7 +1119,7 @@ void webHandleGuiConfig()
} }
webSendFooter(); webSendFooter();
if(webServer.hasArg(F("action"))) dispatchTextLine(webServer.arg(F("action")).c_str()); if(webServer.hasArg(F("action"))) dispatch_text_line(webServer.arg(F("action")).c_str());
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
@ -1381,7 +1380,7 @@ void webHandleGpioOptions()
} }
webSendFooter(); webSendFooter();
if(webServer.hasArg(F("action"))) dispatchTextLine(webServer.arg(F("action")).c_str()); if(webServer.hasArg(F("action"))) dispatch_text_line(webServer.arg(F("action")).c_str()); // Security check
} }
#endif // HASP_USE_GPIO #endif // HASP_USE_GPIO
@ -1698,7 +1697,7 @@ void httpHandleResetConfig()
if(resetConfirmed) { if(resetConfirmed) {
delay(250); delay(250);
// configClearSaved(); // configClearSaved();
dispatchReboot(false); // Do not save the current config dispatch_reboot(false); // Do not save the current config
} }
} }

View File

@ -285,7 +285,7 @@ static void mqtt_message_cb(char * topic, byte * payload, unsigned int length)
// Group topic // Group topic
topic += strlen(mqttGroupTopic); // shorten topic topic += strlen(mqttGroupTopic); // shorten topic
dispatchTopicPayload(topic, (char *)payload); dispatch_topic_payload(topic, (const char *)payload);
return; return;
} else { } else {
@ -310,7 +310,7 @@ static void mqtt_message_cb(char * topic, byte * payload, unsigned int length)
// Log.notice(TAG_MQTT, F("ignoring status = ON")); // Log.notice(TAG_MQTT, F("ignoring status = ON"));
} }
} else { } else {
dispatchTopicPayload(topic, (char *)payload); dispatch_topic_payload(topic, (const char *)payload);
} }
} }
@ -390,7 +390,7 @@ void mqttStart()
if(mqttReconnectCount > 50) { if(mqttReconnectCount > 50) {
Log.error(TAG_MQTT, F("Retry count exceeded, rebooting...")); Log.error(TAG_MQTT, F("Retry count exceeded, rebooting..."));
dispatchReboot(false); dispatch_reboot(false);
} }
return; return;
} }
@ -435,10 +435,8 @@ void mqttStart()
mqttReconnectCount = 0; mqttReconnectCount = 0;
haspReconnect(); haspReconnect();
char page[4] = "999"; dispatch_output_current_page();
itoa(haspGetPage(), page, DEC); dispatch_output_statusupdate();
dispatchPage(page);
mqtt_send_statusupdate();
} }
void mqttSetup() void mqttSetup()

View File

@ -76,7 +76,7 @@ static void kb_event_cb(lv_obj_t * event_kb, lv_event_t event)
if(wifiValidateSsid(ssid, pass)) { if(wifiValidateSsid(ssid, pass)) {
wifiSetConfig(settings.as<JsonObject>()); wifiSetConfig(settings.as<JsonObject>());
Log.notice(TAG_OOBE, F("SSID validated, rebooting...")); Log.notice(TAG_OOBE, F("SSID validated, rebooting..."));
dispatchReboot(true); dispatch_reboot(true);
} }
} }
@ -336,7 +336,7 @@ bool oobeSetup()
} }
// Thist is used for testing only !! // Thist is used for testing only !!
void oobeFakeSetup(const char *) void oobeFakeSetup(const char *, const char *)
{ {
#if HASP_USE_WIFI > 0 #if HASP_USE_WIFI > 0
char ssid[32] = "HASP-ABCDEF"; char ssid[32] = "HASP-ABCDEF";

View File

@ -3,4 +3,4 @@
void oobeSetAutoCalibrate(bool cal); void oobeSetAutoCalibrate(bool cal);
bool oobeSetup(); bool oobeSetup();
void oobeFakeSetup(const char *); void oobeFakeSetup(const char *, const char *); // for testing purposes only

View File

@ -69,7 +69,7 @@ void otaSetup(void)
otaProgress(); otaProgress();
otaPrecentageComplete = -1; otaPrecentageComplete = -1;
// setup(); // setup();
dispatchReboot(true); dispatch_reboot(true);
}); });
ArduinoOTA.onProgress(otaOnProgress); ArduinoOTA.onProgress(otaOnProgress);
ArduinoOTA.onError([](ota_error_t error) { ArduinoOTA.onError([](ota_error_t error) {
@ -172,8 +172,7 @@ void otaHttpUpdate(const char * espOtaUrl)
case HTTP_UPDATE_OK: case HTTP_UPDATE_OK:
Log.notice(TAG_FWUP, F("HTTP_UPDATE_OK")); Log.notice(TAG_FWUP, F("HTTP_UPDATE_OK"));
// nextionSetAttr("p[0].b[1].txt", "\"HTTP Update\\rcomplete!\\r\\rRestarting.\""); // nextionSetAttr("p[0].b[1].txt", "\"HTTP Update\\rcomplete!\\r\\rRestarting.\"");
dispatchReboot(true); dispatch_reboot(true);
delay(5000);
} }
#if HASP_USE_MDNS > 0 #if HASP_USE_MDNS > 0

View File

@ -221,7 +221,7 @@ static inline void telnetProcessLine(const char * input)
telnetClient.println(F("\r\nUsername: ")); telnetClient.println(F("\r\nUsername: "));
telnetLoginState = TELNET_UNAUTHENTICATED; telnetLoginState = TELNET_UNAUTHENTICATED;
} else { } else {
dispatchTextLine(input); dispatch_text_line(input);
} }
} }
} }

View File

@ -73,11 +73,11 @@ static void wifiDisconnected(const char * ssid, uint8_t reason)
wifiReconnectCounter++; wifiReconnectCounter++;
haspProgressVal(wifiReconnectCounter * 3); haspProgressVal(wifiReconnectCounter * 3);
// networkStop(); // networkStop();
if(wifiReconnectCounter > 33) { if(wifiReconnectCounter > 33) {
Log.error(TAG_WIFI, F("Retries exceed %u: Rebooting..."), wifiReconnectCounter); Log.error(TAG_WIFI, F("Retries exceed %u: Rebooting..."), wifiReconnectCounter);
dispatchReboot(false); dispatch_reboot(false);
} }
char buffer[64]; char buffer[64];
@ -440,7 +440,7 @@ bool wifiEvery5Seconds()
wifiReconnectCounter++; wifiReconnectCounter++;
if(wifiReconnectCounter > 45) { if(wifiReconnectCounter > 45) {
Log.error(TAG_WIFI, F("Retries exceed %u: Rebooting..."), wifiReconnectCounter); Log.error(TAG_WIFI, F("Retries exceed %u: Rebooting..."), wifiReconnectCounter);
dispatchReboot(false); dispatch_reboot(false);
} }
Log.warning(TAG_WIFI, F("No Connection... retry %u"), wifiReconnectCounter); Log.warning(TAG_WIFI, F("No Connection... retry %u"), wifiReconnectCounter);
if(wifiReconnectCounter % 6 == 0) { if(wifiReconnectCounter % 6 == 0) {