diff --git a/CHANGELOG.md b/CHANGELOG.md index 83db7685f..b5fbf823e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [1.5.7 dev] 2019-03- +## [1.6.0 dev] 2019-03-19 ### Added @@ -27,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - included various fixes and suggestions from @nomis - upgraded MyESP library - test_mode renamed to silent_mode +- 'set wifi' replaced with 'set wifi_ssid and set wifi_password' to allow values with spaces ## [1.5.6] 2019-03-09 diff --git a/README.md b/README.md index bc00771bf..586fa3e8b 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ EMS-ESP is a project to build an electronic controller circuit using an Espressi There are 3 parts to this project, first the design of the circuit, secondly the code for the ESP8266 microcontroller firmware with telnet and MQTT support, and lastly an example configuration for Home Assistant to monitor the data and issue direct commands via a MQTT broker. [![Codacy Badge](https://api.codacy.com/project/badge/Grade/b8880625bdf841d4adb2829732030887)](https://app.codacy.com/app/proddy/EMS-ESP?utm_source=github.com&utm_medium=referral&utm_content=proddy/EMS-ESP&utm_campaign=Badge_Grade_Settings) -[![version](https://img.shields.io/badge/version-1.5.5-brightgreen.svg)](CHANGELOG.md) +[![version](https://img.shields.io/badge/version-1.6.0-brightgreen.svg)](CHANGELOG.md) - [EMS-ESP](#ems-esp) - [Introduction](#introduction) @@ -69,7 +69,7 @@ The code and circuit has been tested with a few ESP8266 development boards such 5. Connect an external USB 5v power adapter to the ESP8266 board. 7. When the ESP8266 starts up for the first time the onboard LED will be flashing. This is because the EMS bus is not yet connected and receiving data. 8. If you haven't hardcoded the WiFi credentials in step 4, the ESP8266 will boot up in a WiFi Access Point (AP) mode with the ssid name `ems-esp`. Now you can either use a laptop and connect to this AP using Telnet to `192.168.1.4` or if its powered from a computers USB use a Serial monitor tool to the ESP's COM port. Tip: to enable Telnet on Windows 10 run `dism /online /Enable-Feature /FeatureName:TelnetClient` or install something like [putty](https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html). -9. Next is to customize some of the onboard settings. Type `set` to list the current stored settings and `?` to see the syntax. Use `set wifi` to add your wifi credentials and if you're using MQTT set the host, username and password. There is no need to reboot the ESP. +9. Next is to customize some of the onboard settings. Type `set` to list the current stored settings and `?` to see the syntax. Use `set wifi_ssid` and `set wifi_password` to add your WiFi credentials and if you're using MQTT set the host, username and password. There is no need to reboot the ESP. 10. The `led_gpio` will default to the onboard LED (which is probably blinking now). Ignore `thermostat_type` and `boiler_type` as these will be auto-detected hopefully later on. 11. **Important**: By default the serial port is enabled and the EMS bus disabled. This is to allow users to configure their ESP via the serial monitor when pluged into a PC/laptop. You must disable serial with `set serial off` to get the EMS transmission working. 12. Hook up the ESP to the EMS board as follows: @@ -330,7 +330,7 @@ pre-baked firmware for the Wemos D1 mini is available in the GitHub [releases](h 1. Check if you have **python 2.7** installed. If not [download it](https://www.python.org/downloads/) and make sure you select the option to add Python to the windows PATH 2. Then install the ESPTool by running `pip install esptool` from a command prompt -The ESP8266 will start in Access Point (AP) mode. Connect via WiFi to the SSID **EMS-ESP** and telnet to **192.168.4.1**. Then use the `set wifi` command to configure your own network settings like `set wifi your_ssid your_password`. Alternatively connect the ESP8266 to your PC and open a Serial monitor (with baud 115200) to configure the settings. Make sure you disable Serial support before connecting the EMS lines using `set serial off`. +The ESP8266 will start in Access Point (AP) mode. Connect via WiFi to the SSID **EMS-ESP** and telnet to **192.168.4.1**. Then use the `set wifi_ssid/set wifi_password` command to configure your own network settings. Alternatively connect the ESP8266 to your PC and open a Serial monitor (with baud 115200) to configure the settings. Make sure you disable Serial support before connecting the EMS lines using `set serial off`. `set` wil list all currently stored settings. diff --git a/lib/MyESP/MyESP.cpp b/lib/MyESP/MyESP.cpp index 9a1ff6d76..a42996251 100644 --- a/lib/MyESP/MyESP.cpp +++ b/lib/MyESP/MyESP.cpp @@ -503,7 +503,7 @@ void MyESP::_printSetCommands() { myDebug_P(PSTR("The following set commands are available:")); myDebug_P(PSTR("")); // newline myDebug_P(PSTR("* set erase")); - myDebug_P(PSTR("* set wifi [ssid] [password]")); + myDebug_P(PSTR("* set [value]")); myDebug_P(PSTR("* set [value]")); myDebug_P(PSTR("* set serial ")); @@ -532,12 +532,14 @@ void MyESP::_printSetCommands() { myDebug_P(PSTR("")); // newline myDebug_P(PSTR("Stored settings:")); myDebug_P(PSTR("")); // newline - SerialAndTelnet.printf(PSTR(" wifi=%s "), (!_wifi_ssid) ? "" : _wifi_ssid); + myDebug_P(PSTR(" wifi_ssid=%s "), (!_wifi_ssid) ? "" : _wifi_ssid); + SerialAndTelnet.print(FPSTR(" wifi_password=")); if (!_wifi_password) { SerialAndTelnet.print(FPSTR("")); } else { - for (uint8_t i = 0; i < strlen(_wifi_password); i++) + for (uint8_t i = 0; i < strlen(_wifi_password); i++) { SerialAndTelnet.print(FPSTR("*")); + } } myDebug_P(PSTR("")); // newline myDebug_P(PSTR(" mqtt_host=%s"), (!_mqtt_host) ? "" : _mqtt_host); @@ -546,8 +548,9 @@ void MyESP::_printSetCommands() { if (!_mqtt_password) { SerialAndTelnet.print(FPSTR("")); } else { - for (uint8_t i = 0; i < strlen(_mqtt_password); i++) + for (uint8_t i = 0; i < strlen(_mqtt_password); i++) { SerialAndTelnet.print(FPSTR("*")); + } } myDebug_P(PSTR("")); // newline @@ -571,54 +574,47 @@ void MyESP::resetESP() { } // read next word from string buffer -char * MyESP::_telnet_readWord() { - return (strtok(NULL, ", \n")); -} - -// change setting for 2 params (set ) -void MyESP::_changeSetting2(const char * setting, const char * value1, const char * value2) { - if (strcmp(setting, "wifi") == 0) { - if (_wifi_ssid) - free(_wifi_ssid); - if (_wifi_password) - free(_wifi_password); - _wifi_ssid = NULL; - _wifi_password = NULL; - - if (value1) { - _wifi_ssid = strdup(value1); - } - - if (value2) { - _wifi_password = strdup(value2); - } - - (void)fs_saveConfig(); - myDebug_P(PSTR("WiFi settings changed. Reboot ESP.")); - //jw.disconnect(); - //jw.cleanNetworks(); - //jw.addNetwork(_wifi_ssid, _wifi_password); +// if parameter true then a word is only terminated by a newline +char * MyESP::_telnet_readWord(bool allow_all_chars) { + if (allow_all_chars) { + return (strtok(NULL, "\n")); // allow only newline + } else { + return (strtok(NULL, ", \n")); // allow space and comma } } // change settings - always as strings // messy code but effective since we don't have too many settings // wc is word count, number of parameters after the 'set' command -void MyESP::_changeSetting(uint8_t wc, const char * setting, const char * value) { +bool MyESP::_changeSetting(uint8_t wc, const char * setting, const char * value) { bool ok = false; // check for our internal commands first if (strcmp(setting, "erase") == 0) { _fs_eraseConfig(); - return; - } else if ((strcmp(setting, "wifi") == 0) && (wc == 1)) { // erase wifi settings + return true; + + } else if (strcmp(setting, "wifi_ssid") == 0) { if (_wifi_ssid) free(_wifi_ssid); + _wifi_ssid = NULL; // just to be sure + if (value) { + _wifi_ssid = strdup(value); + } + ok = true; + jw.enableSTA(false); + myDebug_P(PSTR("Note: please reboot to apply new WiFi settings")); + } else if (strcmp(setting, "wifi_password") == 0) { if (_wifi_password) free(_wifi_password); - _wifi_ssid = NULL; - _wifi_password = NULL; - ok = true; + _wifi_password = NULL; // just to be sure + if (value) { + _wifi_password = strdup(value); + } + ok = true; + jw.enableSTA(false); + myDebug_P(PSTR("Note: please reboot to apply new WiFi settings")); + } else if (strcmp(setting, "mqtt_host") == 0) { if (_mqtt_host) free(_mqtt_host); @@ -643,6 +639,7 @@ void MyESP::_changeSetting(uint8_t wc, const char * setting, const char * value) _mqtt_password = strdup(value); } ok = true; + } else if (strcmp(setting, "serial") == 0) { ok = true; _use_serial = false; @@ -664,29 +661,30 @@ void MyESP::_changeSetting(uint8_t wc, const char * setting, const char * value) ok = (_fs_settings_callback)(MYESP_FSACTION_SET, wc, setting, value); } - if (!ok) { - myDebug_P(PSTR("\nInvalid parameter for set command.")); - return; + // if we were able to recognize the set command, continue + if (ok) { + // check for 2 params + if (value == nullptr) { + myDebug_P(PSTR("%s setting reset to its default value."), setting); + } else { + // must be 3 params + myDebug_P(PSTR("%s changed."), setting); + } + + myDebug_P(PSTR("")); // newline + + (void)fs_saveConfig(); // always save the values } - // check for 2 params - if (value == nullptr) { - myDebug_P(PSTR("%s setting reset to its default value."), setting); - } else { - // must be 3 params - myDebug_P(PSTR("%s changed."), setting); - } - - myDebug_P(PSTR("")); // newline - - (void)fs_saveConfig(); // always save the values + return ok; } void MyESP::_telnetCommand(char * commandLine) { + char * str = commandLine; + bool state = false; + // count the number of arguments - char * str = commandLine; - bool state = false; - unsigned wc = 0; + unsigned wc = 0; while (*str) { if (*str == ' ' || *str == '\n' || *str == '\t') { state = false; @@ -698,26 +696,28 @@ void MyESP::_telnetCommand(char * commandLine) { } // check first for reserved commands - char * temp = strdup(commandLine); // because strotok kills original string buffer - char * ptrToCommandName = strtok((char *)temp, ", \n"); + char * temp = strdup(commandLine); // because strotok kills original string buffer + char * ptrToCommandName = strtok((char *)temp, " \n"); // space and newline // set command if (strcmp(ptrToCommandName, "set") == 0) { + bool ok = false; if (wc == 1) { _printSetCommands(); - } else if (wc == 2) { - char * setting = _telnet_readWord(); - _changeSetting(1, setting, NULL); - } else if (wc == 3) { - char * setting = _telnet_readWord(); - char * value = _telnet_readWord(); - _changeSetting(2, setting, value); - } else if (wc == 4) { - char * setting = _telnet_readWord(); - char * value1 = _telnet_readWord(); - char * value2 = _telnet_readWord(); - _changeSetting2(setting, value1, value2); + ok = true; + } else if (wc == 2) { // set + char * setting = _telnet_readWord(false); + ok = _changeSetting(wc - 1, setting, NULL); + } else { // set + char * setting = _telnet_readWord(false); + char * value = _telnet_readWord(true); // allow strange characters + ok = _changeSetting(wc - 1, setting, value); } + + if (!ok) { + myDebug_P(PSTR("\nInvalid parameter for set command.")); + } + return; } @@ -735,13 +735,13 @@ void MyESP::_telnetCommand(char * commandLine) { // crash command #ifdef CRASH if ((strcmp(ptrToCommandName, "crash") == 0) && (wc >= 2)) { - char * cmd = _telnet_readWord(); + char * cmd = _telnet_readWord(false); if (strcmp(cmd, "dump") == 0) { crashDump(); } else if (strcmp(cmd, "clear") == 0) { crashClear(); } else if ((strcmp(cmd, "test") == 0) && (wc == 3)) { - char * value = _telnet_readWord(); + char * value = _telnet_readWord(false); crashTest(atoi(value)); } return; // don't call custom command line callback @@ -1253,7 +1253,7 @@ void MyESP::_fs_setup() { // load the config file. if it doesn't exist (function returns false) create it if (!_fs_loadConfig()) { - myDebug_P(PSTR("[FS] Re-creating config file")); + //myDebug_P(PSTR("[FS] Re-creating config file")); fs_saveConfig(); } diff --git a/lib/MyESP/MyESP.h b/lib/MyESP/MyESP.h index 70dd253ef..23f1cc455 100644 --- a/lib/MyESP/MyESP.h +++ b/lib/MyESP/MyESP.h @@ -9,7 +9,7 @@ #ifndef MyEMS_h #define MyEMS_h -#define MYESP_VERSION "1.1.6b2" +#define MYESP_VERSION "1.1.6b3" #include #include @@ -242,7 +242,7 @@ class MyESP { void _telnetDisconnected(); void _telnetHandle(); void _telnetCommand(char * commandLine); - char * _telnet_readWord(); + char * _telnet_readWord(bool allow_all_chars); void _telnet_setup(); char _command[TELNET_MAX_COMMAND_LENGTH]; // the input command from either Serial or Telnet command_t * _helpProjectCmds; // Help of commands setted by project @@ -250,8 +250,7 @@ class MyESP { void _consoleShowHelp(); telnetcommand_callback_f _telnetcommand_callback; // Callable for projects commands telnet_callback_f _telnet_callback; // callback for connect/disconnect - void _changeSetting(uint8_t wc, const char * setting, const char * value); - void _changeSetting2(const char * setting, const char * value1, const char * value2); + bool _changeSetting(uint8_t wc, const char * setting, const char * value); // fs void _fs_setup();