move commands back to PROGMEM

This commit is contained in:
Paul
2019-07-19 16:12:04 +02:00
parent 80a9c98658
commit a1e7b7f999
4 changed files with 122 additions and 126 deletions

View File

@@ -44,9 +44,6 @@ MyESP::MyESP() {
_web_callback = NULL; _web_callback = NULL;
_helpProjectCmds = NULL;
_helpProjectCmds_count = 0;
_serial = false; _serial = false;
_serial_default = false; _serial_default = false;
@@ -250,23 +247,23 @@ void MyESP::_wifiCallback(justwifi_messages_t code, char * parameter) {
} }
if (code == MESSAGE_SCANNING) { if (code == MESSAGE_SCANNING) {
myDebug_P(PSTR("[WIFI] Scanning\n")); myDebug_P(PSTR("[WIFI] Scanning"));
} }
if (code == MESSAGE_SCAN_FAILED) { if (code == MESSAGE_SCAN_FAILED) {
myDebug_P(PSTR("[WIFI] Scan failed\n")); myDebug_P(PSTR("[WIFI] Scan failed"));
} }
if (code == MESSAGE_NO_NETWORKS) { if (code == MESSAGE_NO_NETWORKS) {
myDebug_P(PSTR("[WIFI] No networks found\n")); myDebug_P(PSTR("[WIFI] No networks found"));
} }
if (code == MESSAGE_NO_KNOWN_NETWORKS) { if (code == MESSAGE_NO_KNOWN_NETWORKS) {
myDebug_P(PSTR("[WIFI] No known networks found\n")); myDebug_P(PSTR("[WIFI] No known networks found"));
} }
if (code == MESSAGE_FOUND_NETWORK) { if (code == MESSAGE_FOUND_NETWORK) {
myDebug_P(PSTR("[WIFI] %s\n"), parameter); myDebug_P(PSTR("[WIFI] %s"), parameter);
} }
if (code == MESSAGE_CONNECT_WAITING) { if (code == MESSAGE_CONNECT_WAITING) {
@@ -274,35 +271,11 @@ void MyESP::_wifiCallback(justwifi_messages_t code, char * parameter) {
} }
if (code == MESSAGE_ACCESSPOINT_CREATING) { if (code == MESSAGE_ACCESSPOINT_CREATING) {
myDebug_P(PSTR("[WIFI] Creating access point\n")); myDebug_P(PSTR("[WIFI] Creating access point"));
} }
if (code == MESSAGE_ACCESSPOINT_FAILED) { if (code == MESSAGE_ACCESSPOINT_FAILED) {
myDebug_P(PSTR("[WIFI] Could not create access point\n")); myDebug_P(PSTR("[WIFI] Could not create access point"));
}
if (code == MESSAGE_WPS_START) {
myDebug_P(PSTR("[WIFI] WPS started\n"));
}
if (code == MESSAGE_WPS_SUCCESS) {
myDebug_P(PSTR("[WIFI] WPS succeeded!\n"));
}
if (code == MESSAGE_WPS_ERROR) {
myDebug_P(PSTR("[WIFI] WPS failed\n"));
}
if (code == MESSAGE_SMARTCONFIG_START) {
myDebug_P(PSTR("[WIFI] Smart Config started\n"));
}
if (code == MESSAGE_SMARTCONFIG_SUCCESS) {
myDebug_P(PSTR("[WIFI] Smart Config succeeded!\n"));
}
if (code == MESSAGE_SMARTCONFIG_ERROR) {
myDebug_P(PSTR("[WIFI] Smart Config failed\n"));
} }
} }
@@ -548,9 +521,7 @@ void MyESP::_eeprom_setup() {
} }
// Set callback of sketch function to process project messages // Set callback of sketch function to process project messages
void MyESP::setTelnet(command_t * cmds, uint8_t count, telnetcommand_callback_f callback_cmd, telnet_callback_f callback) { void MyESP::setTelnet(telnetcommand_callback_f callback_cmd, telnet_callback_f callback) {
_helpProjectCmds = cmds; // command list
_helpProjectCmds_count = count; // number of commands
_telnetcommand_callback = callback_cmd; // external function to handle commands _telnetcommand_callback = callback_cmd; // external function to handle commands
_telnet_callback = callback; _telnet_callback = callback;
} }
@@ -625,27 +596,11 @@ void MyESP::_consoleShowHelp() {
myDebug_P(PSTR("* crash <dump | clear | test [n]>")); myDebug_P(PSTR("* crash <dump | clear | test [n]>"));
#endif #endif
// print custom commands if available. Taken from progmem // call callback function
if (_telnetcommand_callback) { if (_telnet_callback) {
// find the longest key length so we can right align it (_telnet_callback)(TELNET_EVENT_SHOWCMD);
uint8_t max_len = 0;
for (uint8_t i = 0; i < _helpProjectCmds_count; i++) {
if ((strlen(_helpProjectCmds[i].key) > max_len) && (!_helpProjectCmds[i].set)) {
max_len = strlen(_helpProjectCmds[i].key);
}
} }
for (uint8_t i = 0; i < _helpProjectCmds_count; i++) {
if (!_helpProjectCmds[i].set) {
SerialAndTelnet.print("* ");
SerialAndTelnet.print(_helpProjectCmds[i].key);
for (uint8_t j = 0; j < ((max_len + 5) - strlen(_helpProjectCmds[i].key)); j++) { // account for longest string length
SerialAndTelnet.print(" "); // padding
}
SerialAndTelnet.println(_helpProjectCmds[i].description);
}
}
}
myDebug_P(PSTR("")); // newline myDebug_P(PSTR("")); // newline
} }
@@ -654,31 +609,14 @@ void MyESP::_printSetCommands() {
myDebug_P(PSTR("")); // newline myDebug_P(PSTR("")); // newline
myDebug_P(PSTR("The following set commands are available:")); myDebug_P(PSTR("The following set commands are available:"));
myDebug_P(PSTR("")); // newline myDebug_P(PSTR("")); // newline
myDebug_P(PSTR("* set erase")); myDebug_P(PSTR(" set erase"));
myDebug_P(PSTR("* set <wifi_ssid | wifi_password> [value]")); myDebug_P(PSTR(" set <wifi_ssid | wifi_password> [value]"));
myDebug_P(PSTR("* set <mqtt_host | mqtt_username | mqtt_password> [value]")); myDebug_P(PSTR(" set <mqtt_host | mqtt_username | mqtt_password> [value]"));
myDebug_P(PSTR("* set serial <on | off>")); myDebug_P(PSTR(" set serial <on | off>"));
// print custom commands if available. Taken from progmem // call callback function
if (_telnetcommand_callback) { if (_telnet_callback) {
// find the longest key length so we can right align it (_telnet_callback)(TELNET_EVENT_SHOWSET);
uint8_t max_len = 0;
for (uint8_t i = 0; i < _helpProjectCmds_count; i++) {
if ((strlen(_helpProjectCmds[i].key) > max_len) && (_helpProjectCmds[i].set)) {
max_len = strlen(_helpProjectCmds[i].key);
}
}
for (uint8_t i = 0; i < _helpProjectCmds_count; i++) {
if (_helpProjectCmds[i].set) {
SerialAndTelnet.print(FPSTR("* set "));
SerialAndTelnet.print(FPSTR(_helpProjectCmds[i].key));
for (uint8_t j = 0; j < ((max_len + 5) - strlen(_helpProjectCmds[i].key)); j++) { // account for longest string length
SerialAndTelnet.print(FPSTR(" ")); // padding
}
SerialAndTelnet.println(FPSTR(_helpProjectCmds[i].description));
}
}
} }
myDebug_P(PSTR("")); // newline myDebug_P(PSTR("")); // newline
@@ -938,7 +876,9 @@ void MyESP::_telnetCommand(char * commandLine) {
#endif #endif
// call callback function // call callback function
if (_telnetcommand_callback) {
(_telnetcommand_callback)(wc, commandLine); (_telnetcommand_callback)(wc, commandLine);
}
} }
// returns WiFi hostname as a String object // returns WiFi hostname as a String object
@@ -1118,7 +1058,6 @@ void MyESP::_setSystemCheck(bool stable) {
if (stable) { if (stable) {
value = 0; // system is ok value = 0; // system is ok
// myDebug_P(PSTR("[SYSTEM] System OK\n"));
} else { } else {
if (!_getRtcmemStatus()) { if (!_getRtcmemStatus()) {
_setSystemStabilityCounter(1); _setSystemStabilityCounter(1);
@@ -1704,6 +1643,8 @@ void MyESP::_fs_setup() {
_firstInstall = true; // flag as a first install _firstInstall = true; // flag as a first install
} }
myDebug_P(PSTR("[FS] Settings loaded from SPIFFS"));
// _fs_printConfig(); // enable for debugging // _fs_printConfig(); // enable for debugging
} }
@@ -2141,7 +2082,7 @@ void MyESP::_webserver_setup() {
webServer.begin(); webServer.begin();
myDebug_P(PSTR("[WEB] Web server started.")); myDebug_P(PSTR("[WEB] Web server started"));
} }
// bootup sequence // bootup sequence
@@ -2182,6 +2123,9 @@ void MyESP::begin(const char * app_hostname, const char * app_name, const char *
_telnet_setup(); // Telnet setup, called first to set Serial _telnet_setup(); // Telnet setup, called first to set Serial
// print a welcome message
myDebug_P(PSTR("\n\n* %s version %s"), _app_name, _app_version);
// set up onboard LED // set up onboard LED
pinMode(LED_BUILTIN, OUTPUT); pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH); digitalWrite(LED_BUILTIN, HIGH);
@@ -2195,18 +2139,15 @@ void MyESP::begin(const char * app_hostname, const char * app_name, const char *
} }
_eeprom_setup(); // set up EEPROM for storing crash data, if compiled with -DCRASH _eeprom_setup(); // set up EEPROM for storing crash data, if compiled with -DCRASH
_fs_setup(); // SPIFFS setup, do this first to get values _fs_setup(); // SPIFFS setup, do this first to get values
_wifi_setup(); // WIFI setup _wifi_setup(); // WIFI setup
_ota_setup(); // init OTA _ota_setup(); // init OTA
_webserver_setup(); // init web server _webserver_setup(); // init web server
// print a welcome message
myDebug_P(PSTR("\n* %s version %s"), _app_name, _app_version);
SerialAndTelnet.flush();
_setSystemCheck(false); // reset system check _setSystemCheck(false); // reset system check
_heartbeatCheck(true); // force heartbeat _heartbeatCheck(true); // force heartbeat check (not the MQTT one)
SerialAndTelnet.flush();
} }
/* /*

View File

@@ -9,7 +9,7 @@
#ifndef MyEMS_h #ifndef MyEMS_h
#define MyEMS_h #define MyEMS_h
#define MYESP_VERSION "1.1.22" #define MYESP_VERSION "1.1.23"
#include <ArduinoJson.h> #include <ArduinoJson.h>
#include <ArduinoOTA.h> #include <ArduinoOTA.h>
@@ -68,6 +68,8 @@ extern struct rst_info resetInfo;
#define TELNET_MAX_COMMAND_LENGTH 80 // length of a command #define TELNET_MAX_COMMAND_LENGTH 80 // length of a command
#define TELNET_EVENT_CONNECT 1 #define TELNET_EVENT_CONNECT 1
#define TELNET_EVENT_DISCONNECT 0 #define TELNET_EVENT_DISCONNECT 0
#define TELNET_EVENT_SHOWCMD 10
#define TELNET_EVENT_SHOWSET 20
// ANSI Colors // ANSI Colors
#define COLOR_RESET "\x1B[0m" #define COLOR_RESET "\x1B[0m"
@@ -189,6 +191,11 @@ constexpr size_t ArraySize(T (&)[N]) {
return N; return N;
} }
template <typename T>
void PROGMEM_readAnything(const T * sce, T & dest) {
memcpy_P(&dest, sce, sizeof(T));
}
#define UPTIME_OVERFLOW 4294967295 // Uptime overflow value #define UPTIME_OVERFLOW 4294967295 // Uptime overflow value
// web min and max length of wifi ssid and password // web min and max length of wifi ssid and password
@@ -262,7 +269,7 @@ class MyESP {
// debug & telnet // debug & telnet
void myDebug(const char * format, ...); void myDebug(const char * format, ...);
void myDebug_P(PGM_P format_P, ...); void myDebug_P(PGM_P format_P, ...);
void setTelnet(command_t * cmds, uint8_t count, telnetcommand_callback_f callback_cmd, telnet_callback_f callback); void setTelnet(telnetcommand_callback_f callback_cmd, telnet_callback_f callback);
bool getUseSerial(); bool getUseSerial();
void setUseSerial(bool toggle); void setUseSerial(bool toggle);
@@ -346,8 +353,6 @@ class MyESP {
char * _telnet_readWord(bool allow_all_chars); char * _telnet_readWord(bool allow_all_chars);
void _telnet_setup(); void _telnet_setup();
char _command[TELNET_MAX_COMMAND_LENGTH]; // the input command from either Serial or Telnet char _command[TELNET_MAX_COMMAND_LENGTH]; // the input command from either Serial or Telnet
command_t * _helpProjectCmds; // Help of commands setted by project
uint8_t _helpProjectCmds_count; // # available commands
void _consoleShowHelp(); void _consoleShowHelp();
telnetcommand_callback_f _telnetcommand_callback; // Callable for projects commands telnetcommand_callback_f _telnetcommand_callback; // Callable for projects commands
telnet_callback_f _telnet_callback; // callback for connect/disconnect telnet_callback_f _telnet_callback; // callback for connect/disconnect

View File

@@ -93,7 +93,7 @@ typedef struct {
bool doingColdShot; // true if we've just sent a jolt of cold water bool doingColdShot; // true if we've just sent a jolt of cold water
} _EMSESP_Shower; } _EMSESP_Shower;
command_t project_cmds[] = { static const command_t project_cmds[] PROGMEM = {
{true, "led <on | off>", "toggle status LED on/off"}, {true, "led <on | off>", "toggle status LED on/off"},
{true, "led_gpio <gpio>", "set the LED pin. Default is the onboard LED 2. For external D1 use 5"}, {true, "led_gpio <gpio>", "set the LED pin. Default is the onboard LED 2. For external D1 use 5"},
@@ -133,6 +133,7 @@ command_t project_cmds[] = {
{false, "boiler comfort <hot | eco | intelligent>", "set boiler warm water comfort setting"} {false, "boiler comfort <hot | eco | intelligent>", "set boiler warm water comfort setting"}
}; };
uint8_t _project_cmds_count = ArraySize(project_cmds);
// store for overall system status // store for overall system status
_EMSESP_Status EMSESP_Status; _EMSESP_Status EMSESP_Status;
@@ -980,13 +981,13 @@ float _readFloatNumber() {
return atof(numTextPtr); return atof(numTextPtr);
} }
// used to read the next string from an input buffer as a hex value and convert to an 8 bit int // used to read the next string from an input buffer as a hex value and convert to a 16 bit int
uint8_t _readHexNumber() { uint16_t _readHexNumber() {
char * numTextPtr = strtok(NULL, ", \n"); char * numTextPtr = strtok(NULL, ", \n");
if (numTextPtr == nullptr) { if (numTextPtr == nullptr) {
return 0; return 0;
} }
return (uint8_t)strtol(numTextPtr, 0, 16); return (uint16_t)strtol(numTextPtr, 0, 16);
} }
// used to read the next string from an input buffer // used to read the next string from an input buffer
@@ -1338,6 +1339,40 @@ bool SettingsCallback(MYESP_FSACTION action, uint8_t wc, const char * setting, c
return ok; return ok;
} }
// print settings
void _showCommands(uint8_t event) {
bool mode = (event == TELNET_EVENT_SHOWSET); // show set commands or normal commands
command_t cmd;
// find the longest key length so we can right-align the text
uint8_t max_len = 0;
uint8_t i;
for (i = 0; i < _project_cmds_count; i++) {
memcpy_P(&cmd, &project_cmds[i], sizeof(cmd));
if ((strlen(cmd.key) > max_len) && (cmd.set == mode)) {
max_len = strlen(cmd.key);
}
}
char line[200] = {0};
for (i = 0; i < _project_cmds_count; i++) {
memcpy_P(&cmd, &project_cmds[i], sizeof(cmd));
if (cmd.set == mode) {
if (event == TELNET_EVENT_SHOWSET) {
strlcpy(line, " set ", sizeof(line));
} else {
strlcpy(line, "* ", sizeof(line));
}
strlcat(line, cmd.key, sizeof(line));
for (uint8_t j = 0; j < ((max_len + 5) - strlen(cmd.key)); j++) { // account for longest string length
strlcat(line, " ", sizeof(line)); // padding
}
strlcat(line, cmd.description, sizeof(line));
myDebug(line); // print the line
}
}
}
// call back when a telnet client connects or disconnects // call back when a telnet client connects or disconnects
// we set the logging here // we set the logging here
void TelnetCallback(uint8_t event) { void TelnetCallback(uint8_t event) {
@@ -1345,6 +1380,8 @@ void TelnetCallback(uint8_t event) {
ems_setLogging(EMS_SYS_LOGGING_DEFAULT); ems_setLogging(EMS_SYS_LOGGING_DEFAULT);
} else if (event == TELNET_EVENT_DISCONNECT) { } else if (event == TELNET_EVENT_DISCONNECT) {
ems_setLogging(EMS_SYS_LOGGING_NONE); ems_setLogging(EMS_SYS_LOGGING_NONE);
} else if ((event == TELNET_EVENT_SHOWCMD) || (event == TELNET_EVENT_SHOWSET)) {
_showCommands(event);
} }
} }
@@ -1694,7 +1731,9 @@ void WebCallback(char * body) {
void WIFICallback() { void WIFICallback() {
// This is where we enable the UART service to scan the incoming serial Tx/Rx bus signals // This is where we enable the UART service to scan the incoming serial Tx/Rx bus signals
// This is done after we have a WiFi signal to avoid any resource conflicts // This is done after we have a WiFi signal to avoid any resource conflicts
system_uart_swap(); // TODO check
/*
if (myESP.getUseSerial()) { if (myESP.getUseSerial()) {
myDebug_P(PSTR("Warning! EMS bus communication disabled when Serial mode enabled. Use 'set serial off' to start communication.")); myDebug_P(PSTR("Warning! EMS bus communication disabled when Serial mode enabled. Use 'set serial off' to start communication."));
} else { } else {
@@ -1705,6 +1744,7 @@ void WIFICallback() {
ems_discoverModels(); ems_discoverModels();
} }
} }
*/
} }
// Initialize the boiler settings and shower settings // Initialize the boiler settings and shower settings
@@ -1727,6 +1767,9 @@ void initEMSESP() {
EMSESP_Shower.timerPause = 0; EMSESP_Shower.timerPause = 0;
EMSESP_Shower.duration = 0; EMSESP_Shower.duration = 0;
EMSESP_Shower.doingColdShot = false; EMSESP_Shower.doingColdShot = false;
// call ems.cpp's init function to set all the internal params
ems_init();
} }
/* /*
@@ -1799,35 +1842,40 @@ void showerCheck() {
// SETUP // SETUP
// //
void setup() { void setup() {
// init our own parameters initEMSESP(); // init parameters
initEMSESP();
// call ems.cpp's init function to set all the internal params myESP.setTelnet(TelnetCommandCallback, TelnetCallback); // set up Telnet commands
ems_init();
systemCheckTimer.attach(SYSTEMCHECK_TIME, do_systemCheck); // check if EMS is reachable
// set up myESP for Wifi, MQTT, MDNS and Telnet
myESP.setTelnet(project_cmds, ArraySize(project_cmds), TelnetCommandCallback, TelnetCallback); // set up Telnet commands
myESP.setWIFI(NULL, NULL, WIFICallback); // empty ssid and password as we take this from the config file myESP.setWIFI(NULL, NULL, WIFICallback); // empty ssid and password as we take this from the config file
myESP.setMQTT(NULL,
// MQTT host, username and password taken from the SPIFFS settings NULL,
myESP.setMQTT( NULL,
NULL, NULL, NULL, MQTT_BASE, MQTT_KEEPALIVE, MQTT_QOS, MQTT_RETAIN, MQTT_WILL_TOPIC, MQTT_WILL_ONLINE_PAYLOAD, MQTT_WILL_OFFLINE_PAYLOAD, MQTTCallback); MQTT_BASE,
MQTT_KEEPALIVE,
// OTA callback which is called when OTA is starting and stopping MQTT_QOS,
myESP.setOTA(OTACallback_pre, OTACallback_post); MQTT_RETAIN,
MQTT_WILL_TOPIC,
// custom settings in SPIFFS MQTT_WILL_ONLINE_PAYLOAD,
myESP.setSettings(FSCallback, SettingsCallback); MQTT_WILL_OFFLINE_PAYLOAD,
MQTTCallback); // MQTT host, username and password taken from the SPIFFS settings
// web custom settings myESP.setOTA(OTACallback_pre, OTACallback_post); // OTA callback which is called when OTA is starting and stopping
myESP.setWeb(WebCallback); myESP.setSettings(FSCallback, SettingsCallback); // custom settings in SPIFFS
myESP.setWeb(WebCallback); // web custom settings
// start up all the services myESP.begin(APP_HOSTNAME, APP_NAME, APP_VERSION); // start up all the services
myESP.begin(APP_HOSTNAME, APP_NAME, APP_VERSION);
// at this point we have all the settings from our internall SPIFFS config file // at this point we have all the settings from our internall SPIFFS config file
// fire up the UART now
if (myESP.getUseSerial()) {
myDebug_P(PSTR("Warning! EMS bus communication disabled when Serial mode enabled. Use 'set serial off' to start communication."));
} else {
Serial.println("Note: Serial output will now be disabled. Please use Telnet.");
Serial.flush();
emsuart_init();
myDebug_P(PSTR("[UART] Opened Rx/Tx connection"));
if (!EMSESP_Status.listen_mode) {
// go and find the boiler and thermostat types, if not in listen mode
ems_discoverModels();
}
}
// enable regular checks if not in test mode // enable regular checks if not in test mode
if (!EMSESP_Status.listen_mode) { if (!EMSESP_Status.listen_mode) {
@@ -1845,6 +1893,8 @@ void setup() {
// check for Dallas sensors // check for Dallas sensors
EMSESP_Status.dallas_sensors = ds18.setup(EMSESP_Status.dallas_gpio, EMSESP_Status.dallas_parasite); // returns #sensors EMSESP_Status.dallas_sensors = ds18.setup(EMSESP_Status.dallas_gpio, EMSESP_Status.dallas_parasite); // returns #sensors
systemCheckTimer.attach(SYSTEMCHECK_TIME, do_systemCheck); // check if EMS is reachable
} }
// //

View File

@@ -6,5 +6,5 @@
#pragma once #pragma once
#define APP_NAME "EMS-ESP" #define APP_NAME "EMS-ESP"
#define APP_VERSION "1.8.1b19" #define APP_VERSION "1.8.1b20"
#define APP_HOSTNAME "ems-esp" #define APP_HOSTNAME "ems-esp"