mirror of
https://github.com/HASwitchPlate/openHASP.git
synced 2025-07-28 05:36:37 +00:00
Rework dispatcher commands
This commit is contained in:
parent
6eaa62458a
commit
5e1cce9b6a
@ -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);
|
||||||
|
@ -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):
|
||||||
|
@ -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,33 +177,28 @@ 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);
|
|
||||||
|
|
||||||
if(cmnd == strstr_P(cmnd, PSTR("page "))) { // startsWith command/
|
|
||||||
dispatchPage(cmnd + 5);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
size_t pos1 = std::string(cmnd).find("=");
|
size_t pos1 = std::string(cmnd).find("=");
|
||||||
size_t pos2 = std::string(cmnd).find(" ");
|
size_t pos2 = std::string(cmnd).find(" ");
|
||||||
int pos = 0;
|
size_t pos = 0;
|
||||||
|
|
||||||
|
// Find what comes first, ' ' or '='
|
||||||
if(pos1 != std::string::npos) {
|
if(pos1 != std::string::npos) {
|
||||||
if(pos2 != std::string::npos) {
|
if(pos2 != std::string::npos) {
|
||||||
pos = (pos1 < pos2 ? pos1 : pos2);
|
pos = (pos1 < pos2 ? pos1 : pos2);
|
||||||
@ -196,29 +206,25 @@ void dispatchTextLine(const char * cmnd)
|
|||||||
pos = pos1;
|
pos = pos1;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if(pos2 != std::string::npos) {
|
|
||||||
pos = pos2;
|
|
||||||
} else {
|
} else {
|
||||||
pos = 0;
|
pos = (pos2 != std::string::npos) ? pos2 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pos > 0) {
|
if(pos > 0) { // ' ' or '=' found
|
||||||
String strTopic((char *)0);
|
char topic[64];
|
||||||
// String strPayload((char *)0);
|
memset(topic, 0, sizeof(topic));
|
||||||
|
if(pos < sizeof(topic))
|
||||||
|
memcpy(topic, cmnd, pos);
|
||||||
|
else
|
||||||
|
memcpy(topic, cmnd, sizeof(topic) - 1);
|
||||||
|
|
||||||
strTopic.reserve(pos + 1);
|
// topic is before '=', payload is after '=' position
|
||||||
// strPayload.reserve(128);
|
Log.notice(TAG_MSGR, F("%s = %s"), topic, cmnd + pos + 1);
|
||||||
|
dispatch_topic_payload(topic, cmnd + pos + 1);
|
||||||
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 {
|
} else {
|
||||||
char buf[1] = {0};
|
char empty_payload[1] = {0};
|
||||||
dispatchTopicPayload(cmnd, buf);
|
Log.notice(TAG_MSGR, F("%s = %s"), cmnd, empty_payload);
|
||||||
}
|
dispatch_topic_payload(cmnd, empty_payload);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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) {
|
||||||
dispatchTextLine(command.as<String>().c_str());
|
dispatch_text_line(command.as<String>().c_str());
|
||||||
}
|
}
|
||||||
} else if(json.is<JsonObject>()) {
|
} else if(json.is<JsonObject>()) { // handle json as a jsonl
|
||||||
// handle json as a jsonl
|
|
||||||
uint8_t savedPage = haspGetPage();
|
uint8_t savedPage = haspGetPage();
|
||||||
hasp_new_object(json.as<JsonObject>(), savedPage);
|
hasp_new_object(json.as<JsonObject>(), savedPage);
|
||||||
} else if(json.is<const char *>()) {
|
|
||||||
// handle json as a single command
|
} else if(json.is<const char *>()) { // handle json as a single command
|
||||||
dispatchTextLine(json.as<const char *>());
|
dispatch_text_line(json.as<const char *>());
|
||||||
} else if(json.is<char *>()) {
|
|
||||||
// handle json as a single command
|
} else if(json.is<char *>()) { // handle json as a single command
|
||||||
dispatchTextLine(json.as<char *>());
|
dispatch_text_line(json.as<char *>());
|
||||||
} else if(json.is<String>()) {
|
|
||||||
// handle json as a single command
|
} else if(json.is<String>()) { // handle json as a single command
|
||||||
dispatchTextLine(json.as<String>().c_str());
|
dispatch_text_line(json.as<String>().c_str());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Log.warning(TAG_MSGR, F("Failed to parse incoming JSON command"));
|
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()
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -95,6 +95,8 @@ void halRestartMcu(void)
|
|||||||
#else
|
#else
|
||||||
NVIC_SystemReset();
|
NVIC_SystemReset();
|
||||||
#endif
|
#endif
|
||||||
|
for(;;) {
|
||||||
|
} // halt
|
||||||
}
|
}
|
||||||
|
|
||||||
String halGetResetInfo()
|
String halGetResetInfo()
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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()
|
||||||
|
@ -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";
|
||||||
|
@ -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
|
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ static void wifiDisconnected(const char * ssid, uint8_t reason)
|
|||||||
|
|
||||||
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) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user