diff --git a/ConfigSettings.cpp b/ConfigSettings.cpp index fce16ba..00bb781 100644 --- a/ConfigSettings.cpp +++ b/ConfigSettings.cpp @@ -39,6 +39,16 @@ bool BaseSettings::parseValueString(JsonObject &obj, const char *prop, char *pde if(obj.containsKey(prop)) strlcpy(pdest, obj[prop], size); return true; } +bool BaseSettings::parseIPAddress(JsonObject &obj, const char *prop, IPAddress *pdest) { + if(obj.containsKey(prop)) { + char buff[16]; + strlcpy(buff, obj[prop], sizeof(buff)); + pdest->fromString(buff); + } + return true; +} + + int BaseSettings::parseValueInt(JsonObject &obj, const char *prop, int defVal) { if(obj.containsKey(prop)) return obj[prop]; return defVal; @@ -48,12 +58,60 @@ double BaseSettings::parseValueDouble(JsonObject &obj, const char *prop, double return defVal; } bool ConfigSettings::begin() { + uint32_t chipId = 0; + uint64_t mac = ESP.getEfuseMac(); + for(int i=0; i<17; i=i+8) { + chipId |= ((mac >> (40 - i)) & 0xff) << i; + } + snprintf_P(this->serverId, sizeof(this->serverId), "%02X%02X%02X", + (uint16_t)((chipId >> 16) & 0xff), + (uint16_t)((chipId >> 8) & 0xff), + (uint16_t)chipId & 0xff); this->WIFI.begin(); + this->Ethernet.begin(); this->NTP.begin(); this->MQTT.begin(); this->print(); return true; } +bool ConfigSettings::load() { + pref.begin("CFG"); + pref.getString("hostname", this->hostname, sizeof(this->hostname)); + this->ssdpBroadcast = pref.getBool("ssdpBroadcast", true); + this->connType = static_cast(pref.getChar("connType", 0x00)); + pref.end(); + if(this->connType == conn_types::unset) { + // We are doing this to convert the data from previous versions. + this->connType == conn_types::wifi; + pref.begin("WIFI"); + pref.getString("hostname", this->hostname, sizeof(this->hostname)); + this->ssdpBroadcast = pref.getBool("ssdpBroadcast", true); + pref.remove("hostname"); + pref.remove("ssdpBroadcast"); + pref.end(); + this->save(); + } + return true; +} +bool ConfigSettings::save() { + pref.begin("CFG"); + pref.putString("hostname", this->hostname); + pref.putBool("ssdpBroadcast", this->ssdpBroadcast); + pref.putChar("connType", static_cast(this->connType)); + pref.end(); + return true; +} +bool ConfigSettings::toJSON(JsonObject &obj) { + obj["ssdpBroadcast"] = this->ssdpBroadcast; + obj["hostname"] = this->hostname; + obj["connType"] = static_cast(this->connType); + return true; +} +bool ConfigSettings::fromJSON(JsonObject &obj) { + if(obj.containsKey("ssdpBroadcast")) this->ssdpBroadcast = obj["ssdpBroadcast"]; + if(obj.containsKey("hostname")) this->parseValueString(obj, "hostname", this->hostname, sizeof(this->hostname)); + return true; +} void ConfigSettings::print() { this->NTP.print(); this->WIFI.print(); @@ -165,56 +223,36 @@ bool NTPSettings::apply() { setenv("TZ", this->posixZone, 1); return true; } -WifiSettings::WifiSettings() { - uint32_t chipId = 0; - uint64_t mac = ESP.getEfuseMac(); - for(int i=0; i<17; i=i+8) { - chipId |= ((mac >> (40 - i)) & 0xff) << i; - } - snprintf_P(this->serverId, sizeof(this->serverId), "%02X%02X%02X", - (uint16_t)((chipId >> 16) & 0xff), - (uint16_t)((chipId >> 8) & 0xff), - (uint16_t)chipId & 0xff); -} +WifiSettings::WifiSettings() {} bool WifiSettings::begin() { this->load(); return true; } bool WifiSettings::fromJSON(JsonObject &obj) { - this->parseValueString(obj, "hostname", this->hostname, sizeof(this->hostname)); this->parseValueString(obj, "ssid", this->ssid, sizeof(this->ssid)); this->parseValueString(obj, "passphrase", this->passphrase, sizeof(this->passphrase)); - if(obj.containsKey("ssdpBroadcast")) this->ssdpBroadcast = obj["ssdpBroadcast"]; return true; } bool WifiSettings::toJSON(JsonObject &obj) { - obj["hostname"] = this->hostname; obj["ssid"] = this->ssid; obj["passphrase"] = this->passphrase; - obj["ssdpBroadcast"] = this->ssdpBroadcast; return true; } bool WifiSettings::save() { pref.begin("WIFI"); pref.clear(); - pref.putString("hostname", this->hostname); pref.putString("ssid", this->ssid); pref.putString("passphrase", this->passphrase); - pref.putBool("ssdpBroadcast", this->ssdpBroadcast); pref.end(); return true; } bool WifiSettings::load() { pref.begin("WIFI"); - pref.getString("hostname", this->hostname, sizeof(this->hostname)); pref.getString("ssid", this->ssid, sizeof(this->ssid)); pref.getString("passphrase", this->passphrase, sizeof(this->passphrase)); - this->hostname[sizeof(this->hostname) - 1] = '\0'; this->ssid[sizeof(this->ssid) - 1] = '\0'; this->passphrase[sizeof(this->passphrase) - 1] = '\0'; - if(strlen(this->hostname) == 0) strlcpy(this->hostname, "ESPSomfyRTS", sizeof(this->hostname)); - this->ssdpBroadcast = pref.getBool("ssdpBroadcast", true); pref.end(); return true; } @@ -237,8 +275,6 @@ String WifiSettings::mapEncryptionType(int type) { } void WifiSettings::print() { Serial.println("WIFI Settings"); - Serial.print("HOST: "); - Serial.print(this->hostname); Serial.print(" SSID: ["); Serial.print(this->ssid); Serial.print("] PassPhrase: ["); @@ -279,3 +315,57 @@ bool WifiSettings::ssidExists(const char *ssid) { } return false; } +EthernetSettings::EthernetSettings() {} +bool EthernetSettings::begin() { + this->load(); + return true; +} +bool EthernetSettings::fromJSON(JsonObject &obj) { + this->parseIPAddress(obj, "gateway", &this->gateway); + this->parseIPAddress(obj, "subnet", &this->subnet); + this->parseIPAddress(obj, "dns1", &this->dns1); + this->parseIPAddress(obj, "dns2", &this->dns2); + return true; +} +bool EthernetSettings::toJSON(JsonObject &obj) { + obj["gateway"] = this->gateway.toString(); + obj["subnet"] = this->subnet.toString(); + obj["dns1"] = this->dns1.toString(); + obj["dns2"] = this->dns2.toString(); + return true; +} +bool EthernetSettings::save() { + pref.begin("ETH"); + pref.clear(); + pref.putString("gateway", this->gateway.toString()); + pref.putString("subnet", this->subnet.toString()); + pref.putString("dns1", this->dns1.toString()); + pref.putString("dns2", this->dns2.toString()); + pref.end(); + return true; +} +bool EthernetSettings::load() { + pref.begin("ETH"); + char buff[16]; + pref.getString("gateway", buff, sizeof(buff)); + this->gateway.fromString(buff); + pref.getString("subnet", buff, sizeof(buff)); + this->subnet.fromString(buff); + pref.getString("dns1", buff, sizeof(buff)); + this->dns1.fromString(buff); + pref.getString("dns2", buff, sizeof(buff)); + this->dns2.fromString(buff); + pref.end(); + return true; +} +void EthernetSettings::print() { + Serial.println("Ethernet Settings"); + Serial.print(" GATEWAY: "); + Serial.println(this->gateway); + Serial.print(" SUBNET: "); + Serial.println(this->subnet); + Serial.print(" DNS1: "); + Serial.println(this->dns1); + Serial.print(" DNS2: "); + Serial.println(this->dns2); +} diff --git a/ConfigSettings.h b/ConfigSettings.h index 0db2f4d..726c2eb 100644 --- a/ConfigSettings.h +++ b/ConfigSettings.h @@ -2,7 +2,7 @@ #ifndef configsettings_h #define configsettings_h -#define FW_VERSION "v1.2.2" +#define FW_VERSION "v1.2.3" enum DeviceStatus { DS_OK = 0, DS_ERROR = 1, @@ -14,6 +14,7 @@ class BaseSettings { bool loadFile(const char* filename); bool fromJSON(JsonObject &obj); bool toJSON(JsonObject &obj); + bool parseIPAddress(JsonObject &obj, const char *prop, IPAddress *); bool parseValueString(JsonObject &obj, const char *prop, char *dest, size_t size); int parseValueInt(JsonObject &obj, const char *prop, int defVal); double parseValueDouble(JsonObject &obj, const char *prop, double defVal); @@ -36,11 +37,10 @@ class NTPSettings: BaseSettings { class WifiSettings: BaseSettings { public: WifiSettings(); - char serverId[10] = ""; - char hostname[32] = "ESPSomfyRTS"; +// char hostname[32] = "ESPSomfyRTS"; char ssid[64] = ""; char passphrase[32] = ""; - bool ssdpBroadcast = true; + //bool ssdpBroadcast = true; bool begin(); bool fromJSON(JsonObject &obj); bool toJSON(JsonObject &obj); @@ -51,6 +51,21 @@ class WifiSettings: BaseSettings { bool load(); void print(); }; +class EthernetSettings: BaseSettings { + public: + EthernetSettings(); + IPAddress subnet = IPAddress(255,255,255,0); + IPAddress gateway; + IPAddress dns1; + IPAddress dns2; + bool begin(); + bool fromJSON(JsonObject &obj); + bool toJSON(JsonObject &obj); + bool load(); + bool save(); + void print(); + +}; class MQTTSettings: BaseSettings { public: bool enabled = false; @@ -66,13 +81,26 @@ class MQTTSettings: BaseSettings { bool toJSON(JsonObject &obj); bool fromJSON(JsonObject &obj); }; +enum class conn_types : byte { + unset = 0x00, + wifi = 0x1, + ethernet = 0x2 +}; + class ConfigSettings: BaseSettings { public: + char serverId[10] = ""; + char hostname[32] = "ESPSomfyRTS"; + conn_types connType = conn_types::wifi; const char* fwVersion = FW_VERSION; + bool ssdpBroadcast = true; uint8_t status; WifiSettings WIFI; + EthernetSettings Ethernet; NTPSettings NTP; MQTTSettings MQTT; + bool fromJSON(JsonObject &obj); + bool toJSON(JsonObject &obj); bool begin(); bool save(); bool load(); diff --git a/Network.cpp b/Network.cpp index bd97424..15c320f 100644 --- a/Network.cpp +++ b/Network.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include "ConfigSettings.h" @@ -50,11 +51,11 @@ void Network::loop() { if(WiFi.status() != WL_CONNECTED) return; } sockEmit.loop(); - if(settings.WIFI.ssdpBroadcast) { + if(settings.ssdpBroadcast) { if(!SSDP.isStarted) SSDP.begin(); SSDP.loop(); } - else if(!settings.WIFI.ssdpBroadcast && SSDP.isStarted) SSDP.end(); + else if(!settings.ssdpBroadcast && SSDP.isStarted) SSDP.end(); mqtt.loop(); } void Network::emitSockets() { @@ -82,7 +83,7 @@ void Network::emitSockets(uint8_t num) { sockEmit.sendToClient(num, "wifiStrength", "{\"ssid\":\"\", \"strength\":-100,\"channel\":-1}"); } void Network::setConnected() { - WiFi.hostname(settings.WIFI.hostname); + WiFi.hostname(settings.hostname); this->ssid = WiFi.SSID(); this->mac = WiFi.BSSIDstr(); this->strength = WiFi.RSSI(); @@ -117,7 +118,7 @@ void Network::setConnected() { SSDP.setSchemaURL(0, "upnp.xml"); SSDP.setChipId(0, this->getChipId()); SSDP.setDeviceType(0, "urn:schemas-rstrouse-org:device:ESPSomfyRTS:1"); - SSDP.setName(0, settings.WIFI.hostname); + SSDP.setName(0, settings.hostname); //SSDP.setSerialNumber(0, "C2496952-5610-47E6-A968-2FC19737A0DB"); //SSDP.setUUID(0, settings.uuid); @@ -127,25 +128,25 @@ void Network::setConnected() { SSDP.setManufacturer(0, "rstrouse"); SSDP.setManufacturerURL(0, "https://github.com/rstrouse"); SSDP.setURL(0, "/"); - if(MDNS.begin(settings.WIFI.hostname)) { - Serial.printf("MDNS Responder Started: serverId=%s\n", settings.WIFI.serverId); + if(MDNS.begin(settings.hostname)) { + Serial.printf("MDNS Responder Started: serverId=%s\n", settings.serverId); MDNS.addService("http", "tcp", 80); MDNS.addServiceTxt("http", "tcp", "board", "ESP32"); MDNS.addServiceTxt("http", "tcp", "model", "ESPSomfyRTS"); MDNS.addService("espsomfy_rts", "tcp", 8080); - MDNS.addServiceTxt("espsomfy_rts", "tcp", "serverId", String(settings.WIFI.serverId)); + MDNS.addServiceTxt("espsomfy_rts", "tcp", "serverId", String(settings.serverId)); MDNS.addServiceTxt("espsomfy_rts", "tcp", "model", "ESPSomfyRTS"); MDNS.addServiceTxt("espsomfy_rts", "tcp", "version", String(settings.fwVersion)); } - if(settings.WIFI.ssdpBroadcast) { + if(settings.ssdpBroadcast) { if(SSDP.begin()) Serial.println("SSDP Client Started..."); } else if(SSDP.isStarted) SSDP.end(); this->emitSockets(); } bool Network::connect() { - if(settings.WIFI.hostname[0] != '\0') WiFi.hostname(settings.WIFI.hostname); + if(settings.hostname[0] != '\0') WiFi.hostname(settings.hostname); if(settings.WIFI.ssid[0] != '\0') { if(WiFi.status() == WL_CONNECTED && WiFi.SSID().compareTo(settings.WIFI.ssid) == 0) { this->disconnected = 0; diff --git a/Somfy.cpp b/Somfy.cpp index 9f32e4c..01aab4d 100644 --- a/Somfy.cpp +++ b/Somfy.cpp @@ -1299,8 +1299,13 @@ bool Transceiver::end() { } void transceiver_config_t::fromJSON(JsonObject& obj) { Serial.print("Deserialize Radio JSON "); - Serial.printf("SCK:%u MISO:%u MOSI:%u CSN:%u RX:%u TX:%u\n", this->SCKPin, this->MISOPin, this->MOSIPin, this->CSNPin, this->RXPin, this->TXPin); if(obj.containsKey("type")) this->type = obj["type"]; + if(obj.containsKey("CSNPin")) this->CSNPin = obj["CSNPin"]; + if(obj.containsKey("MISOPin")) this->MISOPin = obj["MISOPin"]; + if(obj.containsKey("MOSIPin")) this->MOSIPin = obj["MOSIPin"]; + if(obj.containsKey("RXPin")) this->RXPin = obj["RXPin"]; + if(obj.containsKey("SCKPin")) this->SCKPin = obj["SCKPin"]; + if(obj.containsKey("TXPin")) this->TXPin = obj["TXPin"]; if (obj.containsKey("internalCCMode")) this->internalCCMode = obj["internalCCMode"]; if (obj.containsKey("modulationMode")) this->modulationMode = obj["modulationMode"]; if (obj.containsKey("frequency")) this->frequency = obj["frequency"]; // float @@ -1329,6 +1334,7 @@ void transceiver_config_t::fromJSON(JsonObject& obj) { if (obj.containsKey("appendStatus")) this->appendStatus = obj["appendStatus"]; if (obj.containsKey("printBuffer")) this->printBuffer = obj["printBuffer"]; if(obj.containsKey("enabled")) this->enabled = obj["enabled"]; + Serial.printf("SCK:%u MISO:%u MOSI:%u CSN:%u RX:%u TX:%u\n", this->SCKPin, this->MISOPin, this->MOSIPin, this->CSNPin, this->RXPin, this->TXPin); } void transceiver_config_t::toJSON(JsonObject& obj) { obj["type"] = this->type; @@ -1366,6 +1372,7 @@ void transceiver_config_t::toJSON(JsonObject& obj) { obj["appendStatus"] = this->appendStatus; obj["printBuffer"] = somfy.transceiver.printBuffer; obj["enabled"] = this->enabled; + obj["radioInit"] = this->radioInit; Serial.print("Serialize Radio JSON "); Serial.printf("SCK:%u MISO:%u MOSI:%u CSN:%u RX:%u TX:%u\n", this->SCKPin, this->MISOPin, this->MOSIPin, this->CSNPin, this->RXPin, this->TXPin); } @@ -1405,7 +1412,9 @@ void transceiver_config_t::save() { pref.putUChar("pqtThreshold", this->pqtThreshold); pref.putBool("appendStatus", this->appendStatus); pref.putBool("enabled", this->enabled); + pref.putBool("radioInit", true); pref.end(); + Serial.print("Save Radio Settings "); Serial.printf("SCK:%u MISO:%u MOSI:%u CSN:%u RX:%u TX:%u\n", this->SCKPin, this->MISOPin, this->MOSIPin, this->CSNPin, this->RXPin, this->TXPin); } @@ -1452,11 +1461,21 @@ void transceiver_config_t::apply() { somfy.transceiver.disableReceive(); bit_length = this->type; if(this->enabled) { - Serial.print("Applying radio settings "); - Serial.printf("SCK:%u MISO:%u MOSI:%u CSN:%u RX:%u TX:%u\n", this->SCKPin, this->MISOPin, this->MOSIPin, this->CSNPin, this->RXPin, this->TXPin); - ELECHOUSE_cc1101.Init(); - ELECHOUSE_cc1101.setGDO(this->RXPin, this->TXPin); + bool radioInit = true; + pref.begin("CC1101"); + radioInit = pref.getBool("radioInit", true); + // If the radio locks up then we can simply reboot and re-enable the radio. + pref.putBool("radioInit", false); + this->radioInit = false; + pref.end(); + if(!radioInit) return; + Serial.print("Applying Initializing radio settings "); + Serial.printf("Setting Data Pins RX:%u TX:%u\n", this->RXPin, this->TXPin); + ELECHOUSE_cc1101.setGDO(this->TXPin, this->RXPin); + Serial.printf("Setting SPI Pins SCK:%u MISO:%u MOSI:%u CSN:%u\n", this->SCKPin, this->MISOPin, this->MOSIPin, this->CSNPin); ELECHOUSE_cc1101.setSpiPin(this->SCKPin, this->MISOPin, this->MOSIPin, this->CSNPin); + Serial.println("Radio Pins Configured!"); + ELECHOUSE_cc1101.Init(); ELECHOUSE_cc1101.setMHZ(this->frequency); // Here you can set your basic frequency. The lib calculates the frequency automatically (default = 433.92).The cc1101 can: 300-348 MHZ, 387-464MHZ and 779-928MHZ. Read More info from datasheet. ELECHOUSE_cc1101.setRxBW(this->rxBandwidth); // Set the Receive Bandwidth in kHz. Value from 58.03 to 812.50. Default is 812.50 kHz. ELECHOUSE_cc1101.setPA(this->txPower); // Set TxPower. The following settings are possible depending on the frequency band. (-30 -20 -15 -10 -6 0 5 7 10 11 12) Default is max! @@ -1464,15 +1483,22 @@ void transceiver_config_t::apply() { //ELECHOUSE_cc1101.setModulation(this->modulationMode); // set modulation mode. 0 = 2-FSK, 1 = GFSK, 2 = ASK/OOK, 3 = 4-FSK, 4 = MSK. if (!ELECHOUSE_cc1101.getCC1101()) { Serial.println("Error setting up the radio"); + this->radioInit = false; } else { Serial.println("Successfully set up the radio"); somfy.transceiver.enableReceive(); + this->radioInit = true; } + pref.begin("CC1101"); + pref.putBool("radioInit", true); + pref.end(); + } else { ELECHOUSE_cc1101.setSidle(); somfy.transceiver.disableReceive(); + this->radioInit = false; } /* ELECHOUSE_cc1101.setDeviation(this->deviation); // Set the Frequency deviation in kHz. Value from 1.58 to 380.85. Default is 47.60 kHz. diff --git a/Somfy.h b/Somfy.h index 03ef923..4a799d3 100644 --- a/Somfy.h +++ b/Somfy.h @@ -106,7 +106,7 @@ class SomfyShade : public SomfyRemote { typedef struct transceiver_config_t { bool printBuffer = false; - bool enabled = true; + bool enabled = false; uint8_t type = 56; // 56 or 80 bit protocol. uint8_t SCKPin = 18; uint8_t TXPin = 12; @@ -114,6 +114,7 @@ typedef struct transceiver_config_t { uint8_t MOSIPin = 23; uint8_t MISOPin = 19; uint8_t CSNPin = 5; + bool radioInit = false; bool internalCCMode = false; // Use internal transmission mode FIFO buffers. byte modulationMode = 2; // Modulation mode. 0 = 2-FSK, 1 = GFSK, 2 = ASK/OOK, 3 = 4-FSK, 4 = MSK. float frequency = 433.42; // Basic frequency diff --git a/SomfyController.ino.esp32.bin b/SomfyController.ino.esp32.bin index e597c98..1e5f7a4 100644 Binary files a/SomfyController.ino.esp32.bin and b/SomfyController.ino.esp32.bin differ diff --git a/SomfyController.littlefs.bin b/SomfyController.littlefs.bin index 3bbc28e..0082362 100644 Binary files a/SomfyController.littlefs.bin and b/SomfyController.littlefs.bin differ diff --git a/Web.cpp b/Web.cpp index 467bee3..bbd4dbf 100644 --- a/Web.cpp +++ b/Web.cpp @@ -57,7 +57,7 @@ void Web::begin() { Serial.println("Discovery Requested"); DynamicJsonDocument doc(16384); JsonObject obj = doc.to(); - obj["serverId"] = settings.WIFI.serverId; + obj["serverId"] = settings.serverId; obj["version"] = settings.fwVersion; obj["model"] = "ESPSomfyRTS"; JsonArray arr = obj.createNestedArray("shades"); @@ -991,7 +991,7 @@ void Web::begin() { if (method == HTTP_POST || method == HTTP_PUT) { somfy.transceiver.fromJSON(obj); somfy.transceiver.save(); - DynamicJsonDocument sdoc(512); + DynamicJsonDocument sdoc(1024); JsonObject sobj = sdoc.to(); somfy.transceiver.toJSON(sobj); serializeJson(sdoc, g_content); @@ -1076,9 +1076,9 @@ void Web::begin() { HTTPMethod method = server.method(); if (method == HTTP_POST || method == HTTP_PUT) { // Parse out all the inputs. - if (obj.containsKey("hostname")) { - settings.WIFI.fromJSON(obj); - settings.WIFI.save(); + if (obj.containsKey("hostname") || obj.containsKey("ssdpBroadcast")) { + settings.fromJSON(obj); + settings.save(); } if (obj.containsKey("ntpServer") || obj.containsKey("ntpServer")) { settings.NTP.fromJSON(obj); @@ -1122,7 +1122,6 @@ void Web::begin() { else { SETCHARPROP(settings.WIFI.ssid, ssid.c_str(), sizeof(settings.WIFI.ssid)); SETCHARPROP(settings.WIFI.passphrase, passphrase.c_str(), sizeof(settings.WIFI.passphrase)); - if (obj.containsKey("ssdpBroadcast")) settings.WIFI.ssdpBroadcast = obj["ssdpBroadcast"].as(); settings.WIFI.save(); settings.WIFI.print(); server.send(201, _encoding_json, "{\"status\":\"OK\",\"desc\":\"Successfully set server connection\"}"); @@ -1143,11 +1142,27 @@ void Web::begin() { DynamicJsonDocument doc(512); JsonObject obj = doc.to(); doc["fwVersion"] = settings.fwVersion; - settings.WIFI.toJSON(obj); + settings.toJSON(obj); + //settings.Ethernet.toJSON(obj); + //settings.WIFI.toJSON(obj); settings.NTP.toJSON(obj); serializeJson(doc, g_content); server.send(200, _encoding_json, g_content); }); + server.on("/networksettings", []() { + webServer.sendCORSHeaders(); + DynamicJsonDocument doc(1024); + JsonObject obj = doc.to(); + doc["fwVersion"] = settings.fwVersion; + settings.toJSON(obj); + JsonObject eth = obj.createNestedObject("ethernet"); + settings.Ethernet.toJSON(eth); + JsonObject wifi = obj.createNestedObject("wifi"); + settings.WIFI.toJSON(wifi); + serializeJson(doc, g_content); + server.send(200, _encoding_json, g_content); + }); + server.on("/connectmqtt", []() { DynamicJsonDocument doc(512); DeserializationError err = deserializeJson(doc, server.arg("plain")); diff --git a/data/index.html b/data/index.html index 4ba37c1..664d161 100644 --- a/data/index.html +++ b/data/index.html @@ -3,13 +3,14 @@ - - + + - +
+
Radio Not Initialized

ESPSomfy RTS