From ca858d489b519728fa81e39d1ba6e15c25dc409b Mon Sep 17 00:00:00 2001 From: Stefan de Bruijn Date: Wed, 2 Jun 2021 21:54:06 +0200 Subject: [PATCH] Updated Wifi config to yaml style. Added yaml example of WiFi to config.yaml. Fixed a bug with strings in config. --- Grbl_Esp32/data/config.yaml | 11 ++- Grbl_Esp32/src/Configuration/HandlerBase.h | 9 +- .../src/Configuration/JsonGenerator.cpp | 20 ++-- Grbl_Esp32/src/MachineConfig.cpp | 7 +- Grbl_Esp32/src/MachineConfig.h | 32 ++++--- Grbl_Esp32/src/StringRange.h | 18 ++-- Grbl_Esp32/src/WebUI/BTConfig.cpp | 2 +- Grbl_Esp32/src/WebUI/TelnetServer.cpp | 4 +- Grbl_Esp32/src/WebUI/WebServer.cpp | 5 +- Grbl_Esp32/src/WebUI/WebSettings.cpp | 43 +++++---- Grbl_Esp32/src/WebUI/WifiConfig.cpp | 91 ++++++++++++------- Grbl_Esp32/src/WebUI/WifiServices.cpp | 5 +- 12 files changed, 155 insertions(+), 92 deletions(-) diff --git a/Grbl_Esp32/data/config.yaml b/Grbl_Esp32/data/config.yaml index 41215a85..c12a7ebc 100644 --- a/Grbl_Esp32/data/config.yaml +++ b/Grbl_Esp32/data/config.yaml @@ -68,4 +68,13 @@ coolant: probe: pin: gpio.32:high:pu - \ No newline at end of file + +comms: + wifi_ap: + ssid: ScratchThat + ip_address: "192.168.0.1" + gateway: "192.168.0.1" + netmask: "255.255.255.0" + + wifi_sta: + ssid: StefanMieke diff --git a/Grbl_Esp32/src/Configuration/HandlerBase.h b/Grbl_Esp32/src/Configuration/HandlerBase.h index 8da0af92..2960c7fc 100644 --- a/Grbl_Esp32/src/Configuration/HandlerBase.h +++ b/Grbl_Esp32/src/Configuration/HandlerBase.h @@ -66,10 +66,15 @@ namespace Configuration { virtual void handle(const char* name, Pin& value) = 0; virtual void handle(const char* name, int& value, EnumItem* e) = 0; + virtual void handle(const char* name, String& value) { - StringRange range; + StringRange range(value); + StringRange copy(value); + handle(name, range); - if (range.begin() != nullptr) { + + // Check for changes, and update if the string is changed. + if (range.begin() != copy.begin() || range.end() != copy.end()) { value = range.str(); } } diff --git a/Grbl_Esp32/src/Configuration/JsonGenerator.cpp b/Grbl_Esp32/src/Configuration/JsonGenerator.cpp index 9e58ef74..0be195bb 100644 --- a/Grbl_Esp32/src/Configuration/JsonGenerator.cpp +++ b/Grbl_Esp32/src/Configuration/JsonGenerator.cpp @@ -65,8 +65,16 @@ namespace Configuration { void JsonGenerator::handle(const char* name, bool& value) { enter(name); - const char* val = value ? "true" : "false"; - _encoder.begin_webui(name, _currentPath, "B", val, 0, 10); + const char* val = value ? "Yes" : "No"; + _encoder.begin_webui(name, _currentPath, "B", val); + _encoder.begin_array("O"); + { + _encoder.begin_object(); + _encoder.member("No", 0); + _encoder.member("Yes", 1); + _encoder.end_object(); + } + _encoder.end_array(); _encoder.end_object(); leave(); } @@ -94,15 +102,15 @@ namespace Configuration { } void JsonGenerator::handle(const char* name, Pin& value) { - // Let's for now say these are strings. - - // TODO: Should we comment this out? The code is correct, but I doubt we want all pins in the webui... - + // We commented this out, because pins are very confusing for users. The code is correct, + // but it really gives more support than it's worth. + /* enter(name); auto sv = value.name(); _encoder.begin_webui(name, _currentPath, "S", sv.c_str(), 0, 255); _encoder.end_object(); leave(); + */ } void JsonGenerator::handle(const char* name, int& value, EnumItem* e) { diff --git a/Grbl_Esp32/src/MachineConfig.cpp b/Grbl_Esp32/src/MachineConfig.cpp index aa01b91a..685dd56b 100644 --- a/Grbl_Esp32/src/MachineConfig.cpp +++ b/Grbl_Esp32/src/MachineConfig.cpp @@ -362,17 +362,20 @@ void UserOutputs::handle(Configuration::HandlerBase& handler) { void MachineConfig::validate() const {} void MachineConfig::handle(Configuration::HandlerBase& handler) { + handler.handle("board", _board); + handler.handle("name", _name); + handler.handle("axes", _axes); handler.handle("i2so", _i2so); handler.handle("spi", _spi); handler.handle("control", _control); handler.handle("coolant", _coolant); handler.handle("probe", _probe); + handler.handle("comms", _comms); + handler.handle("pulse_microseconds", _pulseMicroSeconds); handler.handle("dir_delay_microseconds", _directionDelayMicroSeconds); handler.handle("disable_delay_us", _disableDelayMicroSeconds); - handler.handle("board", _board); - handler.handle("name", _name); handler.handle("idle_time", _idleTime); handler.handle("user_outputs", _userOutputs); handler.handle("sdcard", _sdCard); diff --git a/Grbl_Esp32/src/MachineConfig.h b/Grbl_Esp32/src/MachineConfig.h index ff58aabd..7e93f638 100644 --- a/Grbl_Esp32/src/MachineConfig.h +++ b/Grbl_Esp32/src/MachineConfig.h @@ -223,12 +223,14 @@ class WifiConfig : public Configuration::Configurable { public: WifiConfig() = default; - String _ssid = "GRBL_ESP"; - String _password = "12345678"; + String _ssid = "GRBL_ESP"; - uint32_t _ipAddress = 0x0a000001; // 10. 0. 0. 1 - uint32_t _gateway = 0x0a000001; // 10. 0. 0. 1 - uint32_t _netmask = 0xffffff00; // 255.255.255. 0 + // Passwords don't belong in a YAML! + // String _password = "12345678"; + + uint32_t _ipAddress = 0x0100000a; // 10. 0. 0. 1 + uint32_t _gateway = 0x0100000a; // 10. 0. 0. 1 + uint32_t _netmask = 0x00ffffff; // 255.255.255. 0 bool _dhcp = true; @@ -272,7 +274,7 @@ public: void handle(Configuration::HandlerBase& handler) override { handler.handle("ssid", _ssid); - handler.handle("password", _password); + // handler.handle("password", _password); StringRange ip; handler.handle("ip_address", ip); @@ -324,8 +326,10 @@ class Communications : public Configuration::Configurable { public: Communications() = default; - String _userPassword = ""; - String _adminPassword = ""; + // Passwords don't belong in a YAML! + // + // String _userPassword = ""; + // String _adminPassword = ""; bool _telnetEnable = true; int _telnetPort = 23; @@ -340,9 +344,10 @@ public: WifiSTAConfig* _staConfig = nullptr; void validate() const override {} + void handle(Configuration::HandlerBase& handler) override { - handler.handle("user_password", _userPassword); - handler.handle("admin_password", _adminPassword); + // handler.handle("user_password", _userPassword); + // handler.handle("admin_password", _adminPassword); handler.handle("telnet_enable", _telnetEnable); handler.handle("telnet_port", _telnetPort); @@ -412,6 +417,9 @@ public: extern MachineConfig* config; -inline bool hasBluetooth() { - return config && config->_comms && config->_comms->_bluetoothConfig != nullptr; +inline bool hasWiFi() { + return config && config->_comms && (config->_comms->_staConfig != nullptr || config->_comms->_apConfig != nullptr); +} +inline bool hasBluetooth() { + return !hasWiFi() && (config && config->_comms && config->_comms->_bluetoothConfig != nullptr); } diff --git a/Grbl_Esp32/src/StringRange.h b/Grbl_Esp32/src/StringRange.h index 4eefcce0..16bebc85 100644 --- a/Grbl_Esp32/src/StringRange.h +++ b/Grbl_Esp32/src/StringRange.h @@ -83,12 +83,16 @@ public: String str() const { // TODO: Check if we can eliminate this function. I'm pretty sure we can. - auto len = length(); - char* buf = new char[len + 1]; - memcpy(buf, begin(), len); - buf[len] = 0; - String tmp(buf); - delete[] buf; - return tmp; + auto len = length(); + if (len == 0) { + return String(); + } else { + char* buf = new char[len + 1]; + memcpy(buf, begin(), len); + buf[len] = 0; + String tmp(buf); + delete[] buf; + return tmp; + } } }; diff --git a/Grbl_Esp32/src/WebUI/BTConfig.cpp b/Grbl_Esp32/src/WebUI/BTConfig.cpp index 8014c5e3..e6ca8945 100644 --- a/Grbl_Esp32/src/WebUI/BTConfig.cpp +++ b/Grbl_Esp32/src/WebUI/BTConfig.cpp @@ -115,7 +115,7 @@ namespace WebUI { //stop active services end(); - if (wifi_radio_mode->get() == ESP_BT) { + if (hasBluetooth()) { if (!SerialBT.begin(_btname)) { report_status_message(Error::BtFailBegin, CLIENT_ALL); } else { diff --git a/Grbl_Esp32/src/WebUI/TelnetServer.cpp b/Grbl_Esp32/src/WebUI/TelnetServer.cpp index 1b9a7e17..a3bf9e84 100644 --- a/Grbl_Esp32/src/WebUI/TelnetServer.cpp +++ b/Grbl_Esp32/src/WebUI/TelnetServer.cpp @@ -51,10 +51,10 @@ namespace WebUI { _RXbufferSize = 0; _RXbufferpos = 0; - if (telnet_enable->get() == 0) { + if (!hasWiFi() || !config->_comms->_telnetEnable) { return false; } - _port = telnet_port->get(); + _port = config->_comms->_telnetPort; //create instance _telnetserver = new WiFiServer(_port, MAX_TLNT_CLIENTS); diff --git a/Grbl_Esp32/src/WebUI/WebServer.cpp b/Grbl_Esp32/src/WebUI/WebServer.cpp index 325ce903..91e09cf1 100644 --- a/Grbl_Esp32/src/WebUI/WebServer.cpp +++ b/Grbl_Esp32/src/WebUI/WebServer.cpp @@ -105,10 +105,11 @@ namespace WebUI { bool Web_Server::begin() { bool no_error = true; _setupdone = false; - if (http_enable->get() == 0) { + + if (!hasWiFi() || !config->_comms->_httpEnable) { return false; } - _port = http_port->get(); + _port = config->_comms->_httpPort; //create instance _webserver = new WebServer(_port); diff --git a/Grbl_Esp32/src/WebUI/WebSettings.cpp b/Grbl_Esp32/src/WebUI/WebSettings.cpp index c843750b..1c643366 100644 --- a/Grbl_Esp32/src/WebUI/WebSettings.cpp +++ b/Grbl_Esp32/src/WebUI/WebSettings.cpp @@ -945,30 +945,29 @@ namespace WebUI { webPrintln("[MSG: Radio is Off]"); return Error::Ok; } - //On -#ifdef WIFI_OR_BLUETOOTH - switch (wifi_radio_mode->get()) { - case ESP_WIFI_AP: - case ESP_WIFI_STA: -# if !defined(ENABLE_WIFI) - webPrintln("WiFi is not enabled!"); - return Error::WifiFailBegin; -# else - wifi_config.begin(); - return Error::Ok; -# endif - case ESP_BT: - if (hasBluetooth()) { - webPrintln("Bluetooth is not enabled!"); - return Error::BtFailBegin; - } else { - config->_comms->_bluetoothConfig->begin(); - return Error::Ok; - } - default: - webPrintln("[MSG: Radio is Off]"); + //On +#ifdef WIFI_OR_BLUETOOTH + if (hasWiFi()) { +#if !defined(ENABLE_WIFI) + webPrintln("WiFi is not enabled!"); + return Error::WifiFailBegin; + +#else + wifi_config.begin(); + return Error::Ok; +#endif + } else if (hasBluetooth()) { + if (hasBluetooth()) { + webPrintln("Bluetooth is not enabled!"); + return Error::BtFailBegin; + } else { + config->_comms->_bluetoothConfig->begin(); return Error::Ok; + } + } else { + webPrintln("[MSG: Radio is Off]"); + return Error::Ok; } #endif return Error::Ok; diff --git a/Grbl_Esp32/src/WebUI/WifiConfig.cpp b/Grbl_Esp32/src/WebUI/WifiConfig.cpp index 17119059..e43288c3 100644 --- a/Grbl_Esp32/src/WebUI/WifiConfig.cpp +++ b/Grbl_Esp32/src/WebUI/WifiConfig.cpp @@ -276,6 +276,8 @@ namespace WebUI { */ bool WiFiConfig::StartSTA() { + auto commsConfig = config->_comms; + //stop active service wifi_services.end(); //Sanity check @@ -287,25 +289,28 @@ namespace WebUI { } WiFi.enableAP(false); WiFi.mode(WIFI_STA); + + auto comms = config->_comms; // Should be there; startSTA is called with a null check + auto sta = comms->_staConfig; // Should be there; startSTA is called with a null check + //Get parameters for STA - String h = wifi_hostname->get(); - WiFi.setHostname(h.c_str()); + WiFi.setHostname(comms->_hostname.c_str()); + //SSID - String SSID = wifi_sta_ssid->get(); + String& SSID = sta->_ssid; if (SSID.length() == 0) { SSID = DEFAULT_STA_SSID; } //password - String password = wifi_sta_password->get(); - int8_t IP_mode = wifi_sta_mode->get(); - int32_t IP = wifi_sta_ip->get(); - int32_t GW = wifi_sta_gateway->get(); - int32_t MK = wifi_sta_netmask->get(); + String password = wifi_sta_password->get(); + int8_t IP_mode = sta->_dhcp ? DHCP_MODE : STATIC_MODE; + //if not DHCP if (IP_mode != DHCP_MODE) { - IPAddress ip(IP), mask(MK), gateway(GW); + IPAddress ip(sta->_ipAddress), mask(sta->_netmask), gateway(sta->_gateway); WiFi.config(ip, gateway, mask); } + if (WiFi.begin(SSID.c_str(), (password.length() > 0) ? password.c_str() : NULL)) { grbl_send(CLIENT_ALL, "\n[MSG:Client Started]\r\n"); grbl_sendf(CLIENT_ALL, "[MSG:Connecting %s]\r\n", SSID.c_str()); @@ -323,6 +328,7 @@ namespace WebUI { bool WiFiConfig::StartAP() { //stop active services wifi_services.end(); + //Sanity check if ((WiFi.getMode() == WIFI_STA) || (WiFi.getMode() == WIFI_AP_STA)) { WiFi.disconnect(); @@ -330,34 +336,42 @@ namespace WebUI { if ((WiFi.getMode() == WIFI_AP) || (WiFi.getMode() == WIFI_AP_STA)) { WiFi.softAPdisconnect(); } + WiFi.enableSTA(false); WiFi.mode(WIFI_AP); + + auto comms = config->_comms; // Should be there; startSTA is called with a null check + auto ap = comms->_apConfig; // Should be there; startSTA is called with a null check + //Get parameters for AP //SSID - String SSID = wifi_ap_ssid->get(); + String& SSID = ap->_ssid; if (SSID.length() == 0) { SSID = DEFAULT_AP_SSID; } String password = wifi_ap_password->get(); - int8_t channel = wifi_ap_channel->get(); + int8_t channel = int8_t(ap->_channel); if (channel == 0) { channel = DEFAULT_AP_CHANNEL; } - int32_t IP = wifi_ap_ip->get(); - IPAddress ip(IP); + IPAddress ip(ap->_ipAddress); IPAddress mask; mask.fromString(DEFAULT_AP_MK); + + grbl_sendf(CLIENT_ALL, "[MSG: AP IP %s, mask %s]", ip.toString().c_str(), mask.toString().c_str()); + //Set static IP WiFi.softAPConfig(ip, ip, mask); + //Start AP if (WiFi.softAP(SSID.c_str(), (password.length() > 0) ? password.c_str() : NULL, channel)) { grbl_sendf(CLIENT_ALL, "\n[MSG:Local access point %s started, %s]\r\n", SSID.c_str(), WiFi.softAPIP().toString().c_str()); return true; } else { - grbl_send(CLIENT_ALL, "[MSG:Starting AP failed]\r\n"); + grbl_sendf(CLIENT_ALL, "[MSG:Starting AP failed on AP %s, channel %d]\r\n", SSID.c_str(), channel); return false; } } @@ -387,26 +401,37 @@ namespace WebUI { void WiFiConfig::begin() { //stop active services wifi_services.end(); - //setup events - if (!_events_registered) { - //cumulative function and no remove so only do once - WiFi.onEvent(WiFiConfig::WiFiEvent); - _events_registered = true; - } - //Get hostname - _hostname = wifi_hostname->get(); - int8_t wifiMode = wifi_radio_mode->get(); - if (wifiMode == ESP_WIFI_AP) { - StartAP(); - //start services - wifi_services.begin(); - } else if (wifiMode == ESP_WIFI_STA) { - if (!StartSTA()) { - grbl_sendf(CLIENT_ALL, "[MSG:Cannot connect to %s]\r\n", wifi_sta_ssid->get()); - StartAP(); + + if (hasWiFi()) { + //setup events + if (!_events_registered) { + //cumulative function and no remove so only do once + WiFi.onEvent(WiFiConfig::WiFiEvent); + _events_registered = true; + } + + //Get hostname + _hostname = config->_comms->_hostname; + + if (config->_comms->_staConfig != nullptr) { + // WIFI mode is STA; fall back on AP if necessary + if (!StartSTA()) { + grbl_sendf(CLIENT_ALL, "[MSG:Cannot connect to %s]\r\n", config->_comms->_staConfig->_ssid.c_str()); + if (config->_comms->_apConfig != nullptr) { + StartAP(); + } + } + + //start services + wifi_services.begin(); + } else if (config->_comms->_apConfig != nullptr) { + StartAP(); + + //start services + wifi_services.begin(); + } else { + WiFi.mode(WIFI_OFF); } - //start services - wifi_services.begin(); } else { WiFi.mode(WIFI_OFF); } diff --git a/Grbl_Esp32/src/WebUI/WifiServices.cpp b/Grbl_Esp32/src/WebUI/WifiServices.cpp index 88ed9f32..da762cf1 100644 --- a/Grbl_Esp32/src/WebUI/WifiServices.cpp +++ b/Grbl_Esp32/src/WebUI/WifiServices.cpp @@ -53,10 +53,11 @@ namespace WebUI { bool WiFiServices::begin() { bool no_error = true; //Sanity check - if (WiFi.getMode() == WIFI_OFF) { + if (WiFi.getMode() == WIFI_OFF || !hasWiFi()) { return false; } - String h = wifi_hostname->get(); + + String& h = config->_comms->_hostname; //Start SPIFFS SPIFFS.begin(true);