Wired Ethernet Support!

Added ESP32 wired ethernet support.
This commit is contained in:
Robert Strouse 2023-02-26 11:50:57 -08:00
parent 7f5463250f
commit 0f2f30bf4d
12 changed files with 605 additions and 78 deletions

View file

@ -67,6 +67,7 @@ bool ConfigSettings::begin() {
(uint16_t)((chipId >> 16) & 0xff), (uint16_t)((chipId >> 16) & 0xff),
(uint16_t)((chipId >> 8) & 0xff), (uint16_t)((chipId >> 8) & 0xff),
(uint16_t)chipId & 0xff); (uint16_t)chipId & 0xff);
this->load();
this->WIFI.begin(); this->WIFI.begin();
this->Ethernet.begin(); this->Ethernet.begin();
this->NTP.begin(); this->NTP.begin();
@ -110,11 +111,14 @@ bool ConfigSettings::toJSON(JsonObject &obj) {
bool ConfigSettings::fromJSON(JsonObject &obj) { bool ConfigSettings::fromJSON(JsonObject &obj) {
if(obj.containsKey("ssdpBroadcast")) this->ssdpBroadcast = obj["ssdpBroadcast"]; if(obj.containsKey("ssdpBroadcast")) this->ssdpBroadcast = obj["ssdpBroadcast"];
if(obj.containsKey("hostname")) this->parseValueString(obj, "hostname", this->hostname, sizeof(this->hostname)); if(obj.containsKey("hostname")) this->parseValueString(obj, "hostname", this->hostname, sizeof(this->hostname));
if(obj.containsKey("connType")) this->connType = static_cast<conn_types>(obj["connType"].as<uint8_t>());
return true; return true;
} }
void ConfigSettings::print() { void ConfigSettings::print() {
Serial.printf("Connection Type: %d\n", this->connType);
this->NTP.print(); this->NTP.print();
this->WIFI.print(); if(this->connType == conn_types::wifi || this->connType == conn_types::unset) this->WIFI.print();
if(this->connType == conn_types::ethernet || this->connType == conn_types::ethernetpref) this->Ethernet.print();
} }
void ConfigSettings::emitSockets() {} void ConfigSettings::emitSockets() {}
void ConfigSettings::emitSockets(uint8_t num) {} void ConfigSettings::emitSockets(uint8_t num) {}
@ -321,6 +325,15 @@ bool EthernetSettings::begin() {
return true; return true;
} }
bool EthernetSettings::fromJSON(JsonObject &obj) { bool EthernetSettings::fromJSON(JsonObject &obj) {
if(obj.containsKey("dhcp")) this->dhcp = obj["dhcp"];
if(obj.containsKey("boardType")) this->boardType = obj["boardType"];
if(obj.containsKey("phyAddress")) this->phyAddress = obj["phyAddress"];
if(obj.containsKey("CLKMode")) this->CLKMode = static_cast<eth_clock_mode_t>(obj["CLKMode"]);
if(obj.containsKey("phyType")) this->phyType = static_cast<eth_phy_type_t>(obj["phyType"]);
if(obj.containsKey("PWRPin")) this->PWRPin = obj["PWRPin"];
if(obj.containsKey("MDCPin")) this->MDCPin = obj["MDCPin"];
if(obj.containsKey("MDIOPin")) this->MDIOPin = obj["MDIOPin"];
this->parseIPAddress(obj, "ip", &this->ip);
this->parseIPAddress(obj, "gateway", &this->gateway); this->parseIPAddress(obj, "gateway", &this->gateway);
this->parseIPAddress(obj, "subnet", &this->subnet); this->parseIPAddress(obj, "subnet", &this->subnet);
this->parseIPAddress(obj, "dns1", &this->dns1); this->parseIPAddress(obj, "dns1", &this->dns1);
@ -328,6 +341,15 @@ bool EthernetSettings::fromJSON(JsonObject &obj) {
return true; return true;
} }
bool EthernetSettings::toJSON(JsonObject &obj) { bool EthernetSettings::toJSON(JsonObject &obj) {
obj["boardType"] = this->boardType;
obj["phyAddress"] = this->phyAddress;
obj["dhcp"] = this->dhcp;
obj["CLKMode"] = static_cast<uint8_t>(this->CLKMode);
obj["phyType"] = static_cast<uint8_t>(this->phyType);
obj["PWRPin"] = this->PWRPin;
obj["MDCPin"] = this->MDCPin;
obj["MDIOPin"] = this->MDIOPin;
obj["ip"] = this->ip.toString();
obj["gateway"] = this->gateway.toString(); obj["gateway"] = this->gateway.toString();
obj["subnet"] = this->subnet.toString(); obj["subnet"] = this->subnet.toString();
obj["dns1"] = this->dns1.toString(); obj["dns1"] = this->dns1.toString();
@ -337,6 +359,15 @@ bool EthernetSettings::toJSON(JsonObject &obj) {
bool EthernetSettings::save() { bool EthernetSettings::save() {
pref.begin("ETH"); pref.begin("ETH");
pref.clear(); pref.clear();
pref.putBool("dhcp", this->dhcp);
pref.putChar("boardType", this->boardType);
pref.putChar("phyAddress", this->phyAddress);
pref.putChar("phyType", static_cast<uint8_t>(this->phyType));
pref.putChar("CLKMode", static_cast<uint8_t>(this->CLKMode));
pref.putChar("PWRPin", this->PWRPin);
pref.putChar("MDCPin", this->MDCPin);
pref.putChar("MDIOPin", this->MDIOPin);
pref.putString("ip", this->ip.toString());
pref.putString("gateway", this->gateway.toString()); pref.putString("gateway", this->gateway.toString());
pref.putString("subnet", this->subnet.toString()); pref.putString("subnet", this->subnet.toString());
pref.putString("dns1", this->dns1.toString()); pref.putString("dns1", this->dns1.toString());
@ -346,7 +377,18 @@ bool EthernetSettings::save() {
} }
bool EthernetSettings::load() { bool EthernetSettings::load() {
pref.begin("ETH"); pref.begin("ETH");
this->dhcp = pref.getBool("dhcp", true);
this->boardType = pref.getChar("boardType", this->boardType);
this->phyType = static_cast<eth_phy_type_t>(pref.getChar("phyType", ETH_PHY_LAN8720));
this->CLKMode = static_cast<eth_clock_mode_t>(pref.getChar("CLKMode", ETH_CLOCK_GPIO0_IN));
this->phyAddress = pref.getChar("phyAddress", this->phyAddress);
this->PWRPin = pref.getChar("PWRPin", this->PWRPin);
this->MDCPin = pref.getChar("MDCPin", this->MDCPin);
this->MDIOPin = pref.getChar("MDIOPin", this->MDIOPin);
char buff[16]; char buff[16];
pref.getString("ip", buff, sizeof(buff));
this->ip.fromString(buff);
pref.getString("gateway", buff, sizeof(buff)); pref.getString("gateway", buff, sizeof(buff));
this->gateway.fromString(buff); this->gateway.fromString(buff);
pref.getString("subnet", buff, sizeof(buff)); pref.getString("subnet", buff, sizeof(buff));
@ -360,12 +402,13 @@ bool EthernetSettings::load() {
} }
void EthernetSettings::print() { void EthernetSettings::print() {
Serial.println("Ethernet Settings"); Serial.println("Ethernet Settings");
Serial.printf("Board:%d PHYType:%d CLK:%d ADDR:%d PWR:%d MDC:%d MDIO:%d\n", this->boardType, this->phyType, this->CLKMode, this->phyAddress, this->PWRPin, this->MDCPin, this->MDIOPin);
Serial.print(" GATEWAY: "); Serial.print(" GATEWAY: ");
Serial.println(this->gateway); Serial.println(this->gateway);
Serial.print(" SUBNET: "); Serial.print(" SUBNET: ");
Serial.println(this->subnet); Serial.println(this->subnet);
Serial.print(" DNS1: "); Serial.print(" DNS1: ");
Serial.println(this->dns1); Serial.println(this->dns1);
Serial.print(" DNS2: "); Serial.print(" DNS2: ");
Serial.println(this->dns2); Serial.println(this->dns2);
} }

View file

@ -1,8 +1,9 @@
#include <ArduinoJson.h> #include <ArduinoJson.h>
#include <ETH.h>
#ifndef configsettings_h #ifndef configsettings_h
#define configsettings_h #define configsettings_h
#define FW_VERSION "v1.2.3" #define FW_VERSION "v1.3.0"
enum DeviceStatus { enum DeviceStatus {
DS_OK = 0, DS_OK = 0,
DS_ERROR = 1, DS_ERROR = 1,
@ -54,10 +55,20 @@ class WifiSettings: BaseSettings {
class EthernetSettings: BaseSettings { class EthernetSettings: BaseSettings {
public: public:
EthernetSettings(); EthernetSettings();
uint8_t boardType = 0; // These board types are enumerated in the ui and used to set the chip settings.
bool dhcp = true;
IPAddress ip;
IPAddress subnet = IPAddress(255,255,255,0); IPAddress subnet = IPAddress(255,255,255,0);
IPAddress gateway; IPAddress gateway;
IPAddress dns1; IPAddress dns1;
IPAddress dns2; IPAddress dns2;
eth_phy_type_t phyType = ETH_PHY_LAN8720;
eth_clock_mode_t CLKMode = ETH_CLOCK_GPIO0_IN;
int8_t phyAddress = ETH_PHY_ADDR;
int8_t PWRPin = ETH_PHY_POWER;
int8_t MDCPin = ETH_PHY_MDC;
int8_t MDIOPin = ETH_PHY_MDIO;
bool begin(); bool begin();
bool fromJSON(JsonObject &obj); bool fromJSON(JsonObject &obj);
bool toJSON(JsonObject &obj); bool toJSON(JsonObject &obj);
@ -83,15 +94,16 @@ class MQTTSettings: BaseSettings {
}; };
enum class conn_types : byte { enum class conn_types : byte {
unset = 0x00, unset = 0x00,
wifi = 0x1, wifi = 0x01,
ethernet = 0x2 ethernet = 0x02,
ethernetpref = 0x03
}; };
class ConfigSettings: BaseSettings { class ConfigSettings: BaseSettings {
public: public:
char serverId[10] = ""; char serverId[10] = "";
char hostname[32] = "ESPSomfyRTS"; char hostname[32] = "ESPSomfyRTS";
conn_types connType = conn_types::wifi; conn_types connType = conn_types::unset;
const char* fwVersion = FW_VERSION; const char* fwVersion = FW_VERSION;
bool ssdpBroadcast = true; bool ssdpBroadcast = true;
uint8_t status; uint8_t status;

View file

@ -15,6 +15,7 @@ extern Web webServer;
extern SocketEmitter sockEmit; extern SocketEmitter sockEmit;
extern MQTTClass mqtt; extern MQTTClass mqtt;
extern rebootDelay_t rebootDelay; extern rebootDelay_t rebootDelay;
extern Network net;
int connectRetries = 0; int connectRetries = 0;
void Network::end() { void Network::end() {
@ -25,11 +26,14 @@ void Network::end() {
} }
bool Network::setup() { bool Network::setup() {
WiFi.persistent(false); WiFi.persistent(false);
//Serial.print("WiFi Mode: ");
//Serial.println(WiFi.getMode());
if(WiFi.status() == WL_CONNECTED) WiFi.disconnect(true); if(WiFi.status() == WL_CONNECTED) WiFi.disconnect(true);
WiFi.mode(WIFI_STA); if(settings.connType == conn_types::wifi || settings.connType == conn_types::unset) {
settings.WIFI.printNetworks(); WiFi.persistent(false);
Serial.print("WiFi Mode: ");
Serial.println(WiFi.getMode());
WiFi.mode(WIFI_STA);
settings.WIFI.printNetworks();
}
sockEmit.begin(); sockEmit.begin();
if(!this->connect()) this->openSoftAP(); if(!this->connect()) this->openSoftAP();
return true; return true;
@ -48,7 +52,7 @@ void Network::loop() {
connectRetries = 0; connectRetries = 0;
this->lastEmit = millis(); this->lastEmit = millis();
this->emitSockets(); this->emitSockets();
if(WiFi.status() != WL_CONNECTED) return; if(!this->connected()) return;
} }
sockEmit.loop(); sockEmit.loop();
if(settings.ssdpBroadcast) { if(settings.ssdpBroadcast) {
@ -68,48 +72,86 @@ void Network::emitSockets() {
this->lastChannel = WiFi.channel(); this->lastChannel = WiFi.channel();
} }
} }
else else {
sockEmit.sendToClients("wifiStrength", "{\"ssid\":\"\", \"strength\":-100,\"channel\":-1}"); if(this->connType == conn_types::ethernet && this->lastRSSI != -100 && this->lastChannel != -1) {
sockEmit.sendToClients("wifiStrength", "{\"ssid\":\"\", \"strength\":-100,\"channel\":-1}");
this->lastRSSI = -100;
this->lastChannel = -1;
}
}
} }
void Network::emitSockets(uint8_t num) { void Network::emitSockets(uint8_t num) {
char buf[128];
if(WiFi.status() == WL_CONNECTED) { if(WiFi.status() == WL_CONNECTED) {
char buf[128];
snprintf(buf, sizeof(buf), "{\"ssid\":\"%s\",\"strength\":%d,\"channel\":%d}", WiFi.SSID().c_str(), WiFi.RSSI(), WiFi.channel()); snprintf(buf, sizeof(buf), "{\"ssid\":\"%s\",\"strength\":%d,\"channel\":%d}", WiFi.SSID().c_str(), WiFi.RSSI(), WiFi.channel());
sockEmit.sendToClient(num, "wifiStrength", buf); sockEmit.sendToClient(num, "wifiStrength", buf);
this->lastRSSI = WiFi.RSSI(); this->lastRSSI = WiFi.RSSI();
this->lastChannel = WiFi.channel(); this->lastChannel = WiFi.channel();
} }
else {
if(this->connType == conn_types::ethernet && this->lastRSSI != -100 && this->lastChannel != -1)
sockEmit.sendToClient(num, "wifiStrength", "{\"ssid\":\"\", \"strength\":-100,\"channel\":-1}");
this->lastRSSI = -100;
this->lastChannel = -1;
}
if(this->connType == conn_types::ethernet) {
snprintf(buf, sizeof(buf), "{\"connected\":true,\"speed\":%d,\"fullduplex\":%s}", ETH.linkSpeed(), ETH.fullDuplex() ? "true" : "false");
sockEmit.sendToClient(num, "ethernet", buf);
}
else else
sockEmit.sendToClient(num, "wifiStrength", "{\"ssid\":\"\", \"strength\":-100,\"channel\":-1}"); sockEmit.sendToClient(num, "ethernet", "{\"connected\":false, \"speed\":0,\"fullduplex\":false}");
} }
void Network::setConnected() { void Network::setConnected(conn_types connType) {
WiFi.hostname(settings.hostname); this->connType = connType;
this->ssid = WiFi.SSID();
this->mac = WiFi.BSSIDstr();
this->strength = WiFi.RSSI();
this->channel = WiFi.channel();
this->connectTime = millis(); this->connectTime = millis();
if(this->connectAttempts == 1) { if(this->connectAttempts == 1) {
Serial.println(); Serial.println();
Serial.print("Successfully Connected to WiFi!!!!"); if(this->connType == conn_types::wifi) {
Serial.print(WiFi.localIP()); Serial.print("Successfully Connected to WiFi!!!!");
Serial.print(" ("); Serial.print(WiFi.localIP());
Serial.print(this->strength); Serial.print(" (");
Serial.println("dbm)"); Serial.print(this->strength);
Serial.println("dbm)");
}
else {
Serial.print("Successfully Connected to Ethernet!!! ");
Serial.print(ETH.localIP());
if(ETH.fullDuplex()) {
Serial.print(" FULL DUPLEX");
}
Serial.print(" ");
Serial.print(ETH.linkSpeed());
Serial.println("Mbps");
}
char buf[128];
snprintf(buf, sizeof(buf), "{\"connected\":true,\"speed\":%d,\"fullduplex\":%s}", ETH.linkSpeed(), ETH.fullDuplex() ? "true" : "false");
sockEmit.sendToClients("ethernet", buf);
} }
else { else {
Serial.println(); Serial.println();
Serial.print("Reconnected after "); Serial.print("Reconnected after ");
Serial.print(1.0 * (millis() - this->connectStart)/1000); Serial.print(1.0 * (millis() - this->connectStart)/1000);
Serial.print("sec IP: "); Serial.print("sec IP: ");
Serial.print(WiFi.localIP()); if(this->connType == conn_types::wifi) {
Serial.print(" "); Serial.print(WiFi.localIP());
Serial.print(this->mac); Serial.print(" ");
Serial.print(" CH:"); Serial.print(this->mac);
Serial.print(this->channel); Serial.print(" CH:");
Serial.print(" ("); Serial.print(this->channel);
Serial.print(this->strength); Serial.print(" (");
Serial.print(" dBm)"); Serial.print(this->strength);
Serial.print(" dBm)");
}
else {
Serial.print(ETH.localIP());
if(ETH.fullDuplex()) {
Serial.print(" FULL DUPLEX");
}
Serial.print(" ");
Serial.print(ETH.linkSpeed());
Serial.print("Mbps");
}
Serial.print(" Disconnected "); Serial.print(" Disconnected ");
Serial.print(this->connectAttempts - 1); Serial.print(this->connectAttempts - 1);
Serial.println(" times"); Serial.println(" times");
@ -145,7 +187,52 @@ void Network::setConnected() {
else if(SSDP.isStarted) SSDP.end(); else if(SSDP.isStarted) SSDP.end();
this->emitSockets(); this->emitSockets();
} }
bool Network::connect() { bool Network::connectWired() {
if(this->connType == conn_types::ethernet) {
this->disconnected = 0;
return true;
}
if(this->connectAttempts > 0) {
Serial.printf("Ethernet Connection Lost... %d Reconnecting ", this->connectAttempts);
Serial.println(this->mac);
}
else
Serial.println("Connecting to Wired Ethernet");
this->connectAttempts++;
if(!this->ethStarted) {
this->ethStarted = true;
WiFi.mode(WIFI_OFF);
WiFi.onEvent(this->networkEvent);
if(!ETH.begin(settings.Ethernet.phyAddress, settings.Ethernet.PWRPin, settings.Ethernet.MDCPin, settings.Ethernet.MDIOPin, settings.Ethernet.phyType, settings.Ethernet.CLKMode)) {
Serial.println("Ethernet Begin failed");
if(settings.connType == conn_types::ethernetpref) {
this->wifiFallback = true;
return connectWiFi();
}
return false;
}
else {
uint32_t wait = millis();
while(millis() - wait < 7000) {
if(this->connected()) return true;
delay(500);
}
if(settings.connType == conn_types::ethernetpref) {
this->wifiFallback = true;
return connectWiFi();
}
}
}
int retries = 0;
while(retries++ < 100) {
delay(100);
if(this->connected()) return true;
}
if(this->connectAttempts > 10) this->wifiFallback = true;
return false;
}
bool Network::connectWiFi() {
if(settings.hostname[0] != '\0') WiFi.hostname(settings.hostname); if(settings.hostname[0] != '\0') WiFi.hostname(settings.hostname);
if(settings.WIFI.ssid[0] != '\0') { if(settings.WIFI.ssid[0] != '\0') {
if(WiFi.status() == WL_CONNECTED && WiFi.SSID().compareTo(settings.WIFI.ssid) == 0) { if(WiFi.status() == WL_CONNECTED && WiFi.SSID().compareTo(settings.WIFI.ssid) == 0) {
@ -173,7 +260,6 @@ bool Network::connect() {
delay(100); delay(100);
int retries = 0; int retries = 0;
while(retries < 100) { while(retries < 100) {
//digitalWrite(LED_BUILTIN, retries % 2 ? HIGH : LOW); // Flash the LED while connecting
switch(WiFi.status()) { switch(WiFi.status()) {
case WL_SCAN_COMPLETED: case WL_SCAN_COMPLETED:
Serial.println("Status: Scan Completed"); Serial.println("Status: Scan Completed");
@ -188,7 +274,12 @@ bool Network::connect() {
Serial.print("*"); Serial.print("*");
break; break;
case WL_CONNECTED: case WL_CONNECTED:
this->setConnected(); WiFi.hostname(settings.hostname);
this->ssid = WiFi.SSID();
this->mac = WiFi.BSSIDstr();
this->strength = WiFi.RSSI();
this->channel = WiFi.channel();
this->setConnected(conn_types::wifi);
WiFi.setSleep(false); WiFi.setSleep(false);
return true; return true;
case WL_NO_SHIELD: case WL_NO_SHIELD:
@ -213,11 +304,14 @@ bool Network::connect() {
//if(disconnected > 0 && st == -100) settings.WIFI.PrintNetworks(); //if(disconnected > 0 && st == -100) settings.WIFI.PrintNetworks();
disconnected++; disconnected++;
} }
} }
//digitalWrite(LED_BUILTIN, HIGH); // Turn off the LED.
return false; return false;
} }
bool Network::connect() {
if(settings.connType != conn_types::wifi && !this->wifiFallback)
return this->connectWired();
return this->connectWiFi();
}
int Network::getStrengthByMac(const char *macAddr) { int Network::getStrengthByMac(const char *macAddr) {
int strength = -100; int strength = -100;
int n = WiFi.scanNetworks(true); int n = WiFi.scanNetworks(true);
@ -314,12 +408,6 @@ bool Network::openSoftAP() {
WiFi.softAPdisconnect(true); WiFi.softAPdisconnect(true);
return false; return false;
} }
if(digitalRead(D0) == LOW) {
Serial.println();
Serial.println("Button Pressed...Stopping AP Mode");
WiFi.softAPdisconnect(true);
return false;
}
if(c == 100) { if(c == 100) {
Serial.println(); Serial.println();
c = 0; c = 0;
@ -327,3 +415,58 @@ bool Network::openSoftAP() {
yield(); yield();
} }
} }
bool Network::connected() {
if(this->connType == conn_types::unset) return false;
else if(this->connType == conn_types::wifi) return WiFi.status() == WL_CONNECTED;
else return this->connType != conn_types::unset;
return false;
}
void Network::networkEvent(WiFiEvent_t event) {
switch(event) {
case ARDUINO_EVENT_ETH_START:
Serial.println("Ethernet Started");
if(settings.hostname[0] != '\0')
ETH.setHostname(settings.hostname);
else
ETH.setHostname("ESPSomfy-RTS");
break;
case ARDUINO_EVENT_ETH_GOT_IP:
// If the Wifi is connected then drop that connection
if(WiFi.status() == WL_CONNECTED) WiFi.disconnect(true);
Serial.print("Got Ethernet IP ");
Serial.println(ETH.localIP());
net.mac = ETH.macAddress();
net.setConnected(conn_types::ethernet);
break;
case ARDUINO_EVENT_ETH_CONNECTED:
Serial.print("Ethernet Connected ");
// We don't want to call setConnected if we do not have an IP address yet
if(ETH.localIP() != INADDR_NONE)
net.setConnected(conn_types::ethernet);
break;
case ARDUINO_EVENT_ETH_DISCONNECTED:
Serial.println("Ethernet Disconnected");
sockEmit.sendToClients("ethernet", "{\"connected\":false, \"speed\":0,\"fullduplex\":false}");
net.connType = conn_types::unset;
break;
case ARDUINO_EVENT_ETH_STOP:
Serial.println("Ethernet Stopped");
net.connType = conn_types::unset;
break;
case ARDUINO_EVENT_WIFI_AP_STOP:
Serial.println("WiFi AP Stopped");
break;
case ARDUINO_EVENT_WIFI_AP_START:
Serial.println("WiFi AP Started");
break;
case ARDUINO_EVENT_WIFI_STA_START:
Serial.println("WiFi STA Started");
break;
case ARDUINO_EVENT_WIFI_STA_CONNECTED:
break;
default:
if(event > ARDUINO_EVENT_ETH_START)
Serial.printf("Unknown Ethernet Event %d\n", event);
break;
}
}

View file

@ -7,7 +7,12 @@ class Network {
unsigned long lastEmit = 0; unsigned long lastEmit = 0;
int lastRSSI = 0; int lastRSSI = 0;
int lastChannel = 0; int lastChannel = 0;
int linkSpeed = 0;
bool ethStarted = false;
public: public:
bool wifiFallback = false;
conn_types connType = conn_types::unset;
bool connected();
String ssid; String ssid;
String mac; String mac;
int channel; int channel;
@ -18,7 +23,9 @@ class Network {
long connectTime = 0; long connectTime = 0;
bool openSoftAP(); bool openSoftAP();
bool connect(); bool connect();
void setConnected(); bool connectWiFi();
bool connectWired();
void setConnected(conn_types connType);
int getStrengthByMac(const char *mac); int getStrengthByMac(const char *mac);
int getStrengthBySSID(const char *ssid); int getStrengthBySSID(const char *ssid);
bool setup(); bool setup();
@ -27,5 +34,6 @@ class Network {
void emitSockets(); void emitSockets();
void emitSockets(uint8_t num); void emitSockets(uint8_t num);
uint32_t getChipId(); uint32_t getChipId();
static void networkEvent(WiFiEvent_t event);
}; };
#endif #endif

View file

@ -761,7 +761,7 @@ void SSDPClass::loop() {
this->_sendQueuedResponses(); this->_sendQueuedResponses();
} }
void SSDPClass::schema(Print &client) { void SSDPClass::schema(Print &client) {
IPAddress ip = WiFi.localIP(); IPAddress ip = this->localIP();
uint8_t devCount = 0; uint8_t devCount = 0;
for(uint8_t i = 0; i < this->m_cdeviceTypes; i++) { for(uint8_t i = 0; i < this->m_cdeviceTypes; i++) {
if(this->deviceTypes[i].deviceType && strlen(this->deviceTypes[i].deviceType) > 0) devCount++; if(this->deviceTypes[i].deviceType && strlen(this->deviceTypes[i].deviceType) > 0) devCount++;

View file

@ -21,14 +21,10 @@ void setup() {
Serial.println(); Serial.println();
Serial.println("Startup/Boot...."); Serial.println("Startup/Boot....");
settings.begin(); settings.begin();
WiFi.persistent(false);
Serial.print("WiFi Mode: ");
Serial.println(WiFi.getMode());
Serial.println("Mounting File System..."); Serial.println("Mounting File System...");
if(LittleFS.begin()) Serial.println("File system mounted successfully"); if(LittleFS.begin()) Serial.println("File system mounted successfully");
else Serial.println("Error mounting file system"); else Serial.println("Error mounting file system");
if(WiFi.status() == WL_CONNECTED) WiFi.disconnect(true); if(WiFi.status() == WL_CONNECTED) WiFi.disconnect(true);
WiFi.mode(WIFI_AP_STA);
delay(10); delay(10);
Serial.println(); Serial.println();
webServer.startup(); webServer.startup();
@ -43,7 +39,7 @@ void loop() {
if(rebootDelay.reboot && millis() > rebootDelay.rebootTime) ESP.restart(); if(rebootDelay.reboot && millis() > rebootDelay.rebootTime) ESP.restart();
net.loop(); net.loop();
somfy.loop(); somfy.loop();
if(WiFi.status() == WL_CONNECTED) { if(net.connected()) {
webServer.loop(); webServer.loop();
sockEmit.loop(); sockEmit.loop();
} }

Binary file not shown.

Binary file not shown.

48
Web.cpp
View file

@ -1091,6 +1091,54 @@ void Web::begin() {
} }
} }
}); });
server.on("/setNetwork", []() {
webServer.sendCORSHeaders();
DynamicJsonDocument doc(1024);
DeserializationError err = deserializeJson(doc, server.arg("plain"));
if (err) {
Serial.print("Error parsing JSON ");
Serial.println(err.c_str());
String msg = err.c_str();
server.send(400, _encoding_html, "Error parsing JSON body<br>" + msg);
}
else {
JsonObject obj = doc.as<JsonObject>();
HTTPMethod method = server.method();
if (method == HTTP_POST || method == HTTP_PUT) {
// Parse out all the inputs.
bool reboot = false;
if(obj.containsKey("connType") && obj["connType"].as<uint8_t>() != static_cast<uint8_t>(settings.connType)) {
settings.connType = static_cast<conn_types>(obj["connType"].as<uint8_t>());
settings.save();
reboot = true;
}
if(settings.connType == conn_types::wifi) {
if(obj.containsKey("ssid") && obj["ssid"].as<String>().compareTo(settings.WIFI.ssid) != 0) reboot = true;
if(obj.containsKey("passphrase") && obj["passphrase"].as<String>().compareTo(settings.WIFI.passphrase) != 0) reboot = true;
}
else {
// This is an ethernet connection so if anything changes we need to reboot.
reboot = true;
}
JsonObject objWifi = obj["wifi"];
JsonObject objEth = obj["ethernet"];
settings.WIFI.fromJSON(objWifi);
settings.Ethernet.fromJSON(objEth);
settings.WIFI.save();
settings.Ethernet.save();
if (reboot) {
Serial.println("Rebooting ESP for new Network settings...");
rebootDelay.reboot = true;
rebootDelay.rebootTime = millis() + 1000;
}
server.send(200, "application/json", "{\"status\":\"OK\",\"desc\":\"Successfully set Network Settings\"}");
}
else {
server.send(201, "application/json", "{\"status\":\"ERROR\",\"desc\":\"Invalid HTTP Method: \"}");
}
}
});
server.on("/connectwifi", []() { server.on("/connectwifi", []() {
webServer.sendCORSHeaders(); webServer.sendCORSHeaders();
int statusCode = 200; int statusCode = 200;

View file

@ -3,17 +3,17 @@
<head> <head>
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="UTF-8"> <meta charset="UTF-8">
<link rel="stylesheet" href="main.css?v=1.2.3" type="text/css" /> <link rel="stylesheet" href="main.css?v=1.3.0" type="text/css" />
<link rel="stylesheet" href="icons.css?v=1.2.3" type="text/css" /> <link rel="stylesheet" href="icons.css?v=1.3.0" type="text/css" />
<link rel="icon" type="image/png" href="favicon.png" /> <link rel="icon" type="image/png" href="favicon.png" />
<script type="text/javascript" src="index.js?v=1.2.3"></script> <script type="text/javascript" src="index.js?v=1.3.0"></script>
</head> </head>
<body> <body>
<div id="divContainer" class="container" style="user-select:none;position:relative;"> <div id="divContainer" class="container" style="user-select:none;position:relative;">
<div id="divRadioError" style="text-align:center;background:gainsboro;color:gray;margin-bottom:7px;text-transform:uppercase;font-weight:bold;padding:4px;border-radius:5px;">Radio Not Initialized</div> <div id="divRadioError" style="text-align:center;background:gainsboro;color:gray;margin-bottom:7px;text-transform:uppercase;font-weight:bold;padding:4px;border-radius:5px;">Radio Not Initialized</div>
<h1 style="text-align: center;"><span>ESPSomfy RTS</span><span class="button-outline" onclick="general.toggleConfig();" style="float:right;font-size:1.25rem;display:inline-block;vertical-align:middle;width:38px;height:38px;position:relative;padding-top:4px;"><span style="vertical-align:middle;clear:both;text-align:center;display:inline-block;"><i id="icoConfig" class="icss-gear" style=""></i></span></span></h1> <h1 style="text-align: center;"><span>ESPSomfy RTS</span><span class="button-outline" onclick="general.toggleConfig();" style="float:right;font-size:1.25rem;display:inline-block;vertical-align:middle;width:38px;height:38px;position:relative;padding-top:4px;"><span style="vertical-align:middle;clear:both;text-align:center;display:inline-block;"><i id="icoConfig" class="icss-gear" style=""></i></span></span></h1>
<div id="divConfigPnl" style="display:none;"> <div id="divConfigPnl" style="display:none;">
<div style="margin-top:-10px;text-align:center;font-size:12px;"> <div id="divWiFiStrength" style="margin-top:-10px;text-align:center;font-size:12px;">
<div style="display:inline-block;vertical-align:middle;"> <div style="display:inline-block;vertical-align:middle;">
<div><span style="text-align:right;display:inline-block;width:57px;color:#00bcd4">Network:</span><span id="spanNetworkSSID" style="padding-left:4px;display:inline-block;text-align:left;width:120px;">-------------</span></div> <div><span style="text-align:right;display:inline-block;width:57px;color:#00bcd4">Network:</span><span id="spanNetworkSSID" style="padding-left:4px;display:inline-block;text-align:left;width:120px;">-------------</span></div>
<div><span style="text-align:right;display:inline-block;width:57px;color:#00bcd4">Channel:</span><span id="spanNetworkChannel" style="padding-left:4px;display:inline-block;text-align:left;width:120px;">--</span></div> <div><span style="text-align:right;display:inline-block;width:57px;color:#00bcd4">Channel:</span><span id="spanNetworkChannel" style="padding-left:4px;display:inline-block;text-align:left;width:120px;">--</span></div>
@ -24,6 +24,12 @@
<div style="position:relative;border:solid 1px silver;background-color:cornsilk;padding:2px;font-size:12px;box-shadow: 0 3px 5px rgba(0,0,0,0.19), 0 2px 2px rgba(0,0,0,0.23);float:right;border-radius:4px;margin-left:-4px;"><span id="spanNetworkStrength">---</span><span>dBm</span></div> <div style="position:relative;border:solid 1px silver;background-color:cornsilk;padding:2px;font-size:12px;box-shadow: 0 3px 5px rgba(0,0,0,0.19), 0 2px 2px rgba(0,0,0,0.23);float:right;border-radius:4px;margin-left:-4px;"><span id="spanNetworkStrength">---</span><span>dBm</span></div>
</div> </div>
</div> </div>
<div id="divEthernetStatus" style="margin-top:-10px;text-align:center;font-size:12px;display:none;">
<div style="display:inline-block;vertical-align:middle;">
<div><span style="text-align:right;display:inline-block;width:57px;color:#00bcd4">Status:</span><span id="spanEthernetStatus" style="padding-left:4px;display:inline-block;text-align:left;width:120px;">-------------</span></div>
<div><span style="text-align:right;display:inline-block;width:57px;color:#00bcd4">Speed:</span><span id="spanEthernetSpeed" style="padding-left:4px;display:inline-block;text-align:left;width:120px;">--</span></div>
</div>
</div>
<div class="tab-container"><span class="selected" data-grpid="fsGeneralSettings">General</span><span data-grpid="fsWiFiSettings">WiFi</span><span data-grpid="fsMQTTSettings">MQTT</span><span data-grpid="fsSomfySettings">Somfy</span><span data-grpid="fsUpdates">Updates</span></div> <div class="tab-container"><span class="selected" data-grpid="fsGeneralSettings">General</span><span data-grpid="fsWiFiSettings">WiFi</span><span data-grpid="fsMQTTSettings">MQTT</span><span data-grpid="fsSomfySettings">Somfy</span><span data-grpid="fsUpdates">Updates</span></div>
<fieldset id="fsGeneralSettings"> <fieldset id="fsGeneralSettings">
<legend>General Settings</legend> <legend>General Settings</legend>
@ -33,7 +39,7 @@
<label for="fldHostname">Host Name</label> <label for="fldHostname">Host Name</label>
</div> </div>
<div class="field-group"> <div class="field-group">
<select id="selTimeZone" name="timeZone" type="password" length=32 placeholder="Time Zone" style="width:100%;"></select> <select id="selTimeZone" name="timeZone" placeholder="Time Zone" style="width:100%;"></select>
<label for="selTimeZone">Time Zone</label> <label for="selTimeZone">Time Zone</label>
</div> </div>
<div class="field-group"> <div class="field-group">
@ -57,26 +63,101 @@
</form> </form>
</fieldset> </fieldset>
<fieldset id="fsWiFiSettings" style="display:none;"> <fieldset id="fsWiFiSettings" style="display:none;">
<legend>WiFi Settings</legend> <legend>WiFi/LAN Settings</legend>
<form method="post" action="/scan"> <div class="field-group" style="vertical-align:middle;color:#00bcd4;margin-top:-30px;margin-bottom:18px;">
<div id="divAps" data-lastloaded="0"></div> <input id="cbHardwired" name="hardwired" type="checkbox" style="display:inline-block;" onclick="wifi.useEthernetClicked();" />
<div class="button-container"><button id="btnScanAPs" type="button" onclick="wifi.loadAPs();">Scan</button></div> <label for="cbHardwired" style="display:inline-block;cursor:pointer;">Use Ethernet</label>
</form> <div id="divFallbackWireless" style="display:inline-block;padding-left:7px;">
<input id="cbFallbackWireless" name="fallbackwireless" type="checkbox" style="display:inline-block;" />
<label for="cbFallbackWireless" style="display:inline-block;cursor:pointer;">Fallback to Wireless</label>
</div>
</div>
<div id="divWiFiMode">
<form method="post" action="/scan">
<div id="divAps" data-lastloaded="0" style="border-radius:5px;border:solid 1px #00bcd4;margin-bottom:-10px;"></div>
<div class="button-container"><button id="btnScanAPs" type="button" onclick="wifi.loadAPs();">Scan</button></div>
<div class="field-group">
<input id="fldSsid" name="ssid" type="text" length=32 placeholder="SSID">
<label for="fldSsid">Network SSID</label>
</div>
<div class="field-group">
<input id="fldPassphrase" name="passphrase" type="password" length=32 placeholder="Passphrase">
<label for="fldPassphrase">Passphrase</label>
</div>
</form>
</div>
<div id="divEthernetMode" style="display:none;">
<form method="post" action="/ethernet">
<div class="field-group">
<select id="selETHBoardType" name="ethBoardType" placeholder="Board Type" style="width:100%;" onchange="wifi.onETHBoardTypeChanged(this);"></select>
<label for="selETHBoardType">Board Type</label>
</div>
<div id="divETHSettings">
<div class="field-group" style="width:30%;margin-right:7px;display:inline-block;">
<select id="selETHPhyType" name="ethphytype" placeholder="PHY Type" style="width:100%;"></select>
<label for="selETHPhyType">PHY Chip Type</label>
</div>
<div class="field-group" style="width:20%;display:inline-block;margin-right:7px;">
<select id="selETHAddress" name="address" placeholder="Address" style="width:100%;"></select>
<label for="selETHAddress">Address</label>
</div>
<div class="field-group" style="width:30%;display:inline-block;margin-right:7px;">
<select id="selETHClkMode" name="clkmode" placeholder="Clock Mode" style="width:100%;"></select>
<label for="selETHClkMode">Clock Mode</label>
</div>
<div class="field-group" style="width:20%;display:inline-block;margin-right:7px;">
<select id="selETHPWRPin" name="pwr" placeholder="Power Pin" style="width:100%;"></select>
<label for="selETHPWRPin">Power Pin</label>
</div>
<div class="field-group" style="width:20%;display:inline-block;margin-right:7px;">
<select id="selETHMDCPin" name="mdc" placeholder="MDC Pin" style="width:100%;"></select>
<label for="selETHPMDCPin">MDC Pin</label>
</div>
<div class="field-group" style="width:20%;display:inline-block;margin-right:7px;">
<select id="selETHMDIOPin" name="mdc" placeholder="MDIO Pin" style="width:100%;"></select>
<label for="selETHMDIOPin">MDIO Pin</label>
</div>
<hr />
</div>
<div class="field-group">
<input id="cbUseDHCP" name="dhcp" type="checkbox" style="display:inline-block;" onclick="wifi.onDHCPClicked(this);" checked="checked" />
<label for="cbUseDHCP" style="display:inline-block;cursor:pointer;">Acquire IP Address automatically (DHCP)</label>
</div>
<div id="divStaticIP" style="display:none;">
<div class="field-group">
<input id="fldIPAddress" name="staticIP" type="text" length=32 placeholder="0.0.0.0">
<label for="fldIPAddress">Static IP Address</label>
</div>
<div class="field-group">
<input id="fldSubnetMask" name="subnet" type="text" length=32 placeholder="0.0.0.0">
<label for="fldSubnetMask">Subnet Mask</label>
</div>
<div class="field-group">
<input id="fldGateway" name="gateway" type="text" length=32 placeholder="0.0.0.0">
<label for="fldGateway">Gateway</label>
</div>
<div class="field-group">
<input id="fldDNS1" name="dns1" type="text" length=32 placeholder="0.0.0.0">
<label for="fldDNS1">Domain Name Server 1</label>
</div>
<div class="field-group">
<input id="fldDNS2" name="dns2" type="text" length=32 placeholder="0.0.0.0">
<label for="fldDNS2">Domain Name Server 2</label>
</div>
</div>
</form>
</div>
<form method="post" action="/wifi" style="margin-top:8px;"> <form method="post" action="/wifi" style="margin-top:8px;">
<div class="field-group">
<input id="fldSsid" name="ssid" type="text" length=32 placeholder="SSID">
<label for="fldSsid">Network SSID</label>
</div>
<div class="field-group">
<input id="fldPassphrase" name="passphrase" type="password" length=32 placeholder="Passphrase">
<label for="fldPassphrase">Passphrase</label>
</div>
<div class="button-container"> <div class="button-container">
<button id="btnConnectWiFi" type="button" onclick="wifi.connectWiFi();"> <button id="btnSaveNetwork" type="button" onclick="wifi.saveNetwork();">
Save Save
</button> </button>
</div> </div>
</form> </form>
</fieldset> </fieldset>
<fieldset id="fsMQTTSettings" style="display:none;"> <fieldset id="fsMQTTSettings" style="display:none;">
<legend>MQTT Settings</legend> <legend>MQTT Settings</legend>

View file

@ -227,9 +227,6 @@ async function initSockets() {
return value; return value;
}); });
switch (eventName) { switch (eventName) {
case 'wifiStrength':
wifi.procWifiStrength(msg);
break;
case 'remoteFrame': case 'remoteFrame':
somfy.procRemoteFrame(msg); somfy.procRemoteFrame(msg);
break; break;
@ -240,6 +237,13 @@ async function initSockets() {
break; break;
case 'shadeAdded': case 'shadeAdded':
break; break;
case 'ethernet':
wifi.procEthernet(msg);
break;
case 'wifiStrength':
wifi.procWifiStrength(msg);
break;
} }
} catch (err) { } catch (err) {
console.log({ eventName: eventName, data: data, err: err }); console.log({ eventName: eventName, data: data, err: err });
@ -274,6 +278,8 @@ async function initSockets() {
} }
}; };
socket.onclose = (evt) => { socket.onclose = (evt) => {
procWifiStrength({ ssid: '', channel: -1, strength: -100 });
procEthernet({ connected: '', speed: 0, fullduplex: false });
if (document.getElementsByClassName('socket-wait') === 0) if (document.getElementsByClassName('socket-wait') === 0)
waitMessage(document.getElementById('divContainer')).classList.add('socket-wait'); waitMessage(document.getElementById('divContainer')).classList.add('socket-wait');
if (evt.wasClean) { if (evt.wasClean) {
@ -328,7 +334,7 @@ async function reopenSocket() {
await initSockets(); await initSockets();
} }
class General { class General {
appVersion = 'v1.2.3'; appVersion = 'v1.3.0';
reloadApp = false; reloadApp = false;
async init() { async init() {
this.setAppVersion(); this.setAppVersion();
@ -552,9 +558,64 @@ class General {
}; };
var general = new General(); var general = new General();
class Wifi { class Wifi {
ethBoardTypes = [{ val: 0, label: 'Custom Config' },
{ val: 1, label: 'WT32-ETH01', clk: 0, ct: 0, addr: 1, pwr: 16, mdc: 23, mdio: 18 },
{ val: 2, label: 'Olimex ESP32-POE', clk: 3, ct: 0, addr: 0, pwr: 12, mdc: 23, mdio: 18 },
{ val: 3, label: 'Olimex ESP32-EVB', clk: 0, ct: 0, addr: 0, pwr: -1, mdc: 23, mdio: 18 },
{ val: 4, label: 'LILYGO T-Internet POE', clk: 3, ct: 0, addr: 0, pwr: 16, mdc: 23, mdio: 18 },
{ val: 5, label: 'wESP32 v7+', clk: 0, ct: 3, addr: 0, pwr: -1, mdc: 16, mdio: 17 },
{ val: 6, label: 'wESP32 < v7', clk: 0, ct: 0, addr: 0, pwr: -1, mdc: 16, mdio: 17 }
];
ethClockModes = [{ val: 0, label: 'GPIO0 IN' }, { val: 1, label: 'GPIO0 OUT' }, { val: 2, label: 'GPIO16 OUT' }, { val: 3, label: 'GPIO17 OUT' }];
ethPhyTypes = [{ val: 0, label: 'LAN8720' }, { val: 1, label: 'TLK110' }, { val: 2, label: 'RTL8201' }, { val: 3, label: 'DP83848' }, { val: 4, label: 'DM9051' }, { val: 5, label: 'KZ8081' }];
init() { init() {
document.getElementById("divNetworkStrength").innerHTML = this.displaySignal(-100); document.getElementById("divNetworkStrength").innerHTML = this.displaySignal(-100);
let addr = [];
this.loadETHDropdown(document.getElementById('selETHClkMode'), this.ethClockModes);
this.loadETHDropdown(document.getElementById('selETHPhyType'), this.ethPhyTypes);
this.loadETHDropdown(document.getElementById('selETHBoardType'), this.ethBoardTypes);
for (let i = 0; i < 32; i++) addr.push({ val: i, label: `PHY ${i}` });
this.loadETHDropdown(document.getElementById('selETHAddress'), addr);
this.loadETHPins(document.getElementById('selETHPWRPin'), 'power');
this.loadETHPins(document.getElementById('selETHMDCPin'), 'mdc', 23);
this.loadETHPins(document.getElementById('selETHMDIOPin'), 'mdio', 18);
if (typeof document.querySelector('div.tab-container > span.selected[data-grpid="fsWiFiSettings"]') !== 'undefined') {
this.loadNetwork();
}
}; };
loadETHPins(sel, type, selected) {
let arr = [];
switch (type) {
case 'power':
arr.push({ val: -1, label: 'None' });
break;
}
for (let i = 0; i < 36; i++) {
arr.push({ val: i, label: `GPIO ${i}` });
}
this.loadETHDropdown(sel, arr, selected);
};
loadETHDropdown(sel, arr, selected) {
while (sel.firstChild) sel.removeChild(sel.firstChild);
for (let i = 0; i < arr.length; i++) {
let elem = arr[i];
sel.options[sel.options.length] = new Option(elem.label, elem.val, elem.val === selected, elem.val === selected);
}
};
onETHBoardTypeChanged(sel) {
let type = this.ethBoardTypes.find(elem => parseInt(sel.value, 10) === elem.val);
if (typeof type !== 'undefined') {
// Change the values to represent what the board type says.
if(typeof type.ct !== 'undefined') document.getElementById('selETHPhyType').value = type.ct;
if (typeof type.clk !== 'undefined') document.getElementById('selETHClkMode').value = type.clk;
if (typeof type.addr !== 'undefined') document.getElementById('selETHAddress').value = type.addr;
if (typeof type.pwr !== 'undefined') document.getElementById('selETHPWRPin').value = type.pwr;
if (typeof type.mdc !== 'undefined') document.getElementById('selETHMDCPin').value = type.mdc;
if (typeof type.mdio !== 'undefined') document.getElementById('selETHMDIOPin').value = type.mdio;
document.getElementById('divETHSettings').style.display = type.val === 0 ? '' : 'none';
}
};
onDHCPClicked(cb) { document.getElementById('divStaticIP').style.display = cb.checked ? 'none' : ''; };
loadNetwork() { loadNetwork() {
let overlay = waitMessage(document.getElementById('fsWiFiSettings')); let overlay = waitMessage(document.getElementById('fsWiFiSettings'));
getJSON('/networksettings', (err, settings) => { getJSON('/networksettings', (err, settings) => {
@ -566,10 +627,47 @@ class Wifi {
else { else {
document.getElementById('fldSsid').value = settings.wifi.ssid; document.getElementById('fldSsid').value = settings.wifi.ssid;
document.getElementById('fldPassphrase').value = settings.wifi.passphrase; document.getElementById('fldPassphrase').value = settings.wifi.passphrase;
document.getElementById('selETHBoardType').value = settings.ethernet.boardType;
document.getElementById('cbUseDHCP').checked = settings.ethernet.dhcp;
document.getElementById('cbHardwired').checked = settings.connType >= 2;
document.getElementById('cbFallbackWireless').checked = settings.connType === 3;
document.getElementById('selETHPhyType').value = settings.ethernet.phyType;
document.getElementById('selETHAddress').value = settings.ethernet.phyAddress;
document.getElementById('selETHClkMode').value = settings.ethernet.CLKMode;
document.getElementById('selETHPWRPin').value = settings.ethernet.PWRPin;
document.getElementById('selETHMDCPin').value = settings.ethernet.MDCPin;
document.getElementById('selETHMDIOPin').value = settings.ethernet.MDIOPin;
document.getElementById('fldIPAddress').value = settings.ethernet.ip;
document.getElementById('fldSubnetMask').value = settings.ethernet.subnet;
document.getElementById('fldGateway').value = settings.ethernet.gateway;
document.getElementById('fldDNS1').value = settings.ethernet.dns1;
document.getElementById('fldDNS2').value = settings.ethernet.dns2;
if (settings.connType >= 2) {
document.getElementById('divWiFiMode').style.display = 'none';
document.getElementById('divEthernetMode').style.display = '';
document.getElementById('divFallbackWireless').style.display = 'inline-block';
}
else {
document.getElementById('divWiFiMode').style.display = '';
document.getElementById('divEthernetMode').style.display = 'none';
document.getElementById('divFallbackWireless').style.display = 'none';
}
if (settings.ethernet.boardType === 0) {
document.getElementById('divETHSettings').style.display = '';
}
else {
document.getElementById('divETHSettings').style.display = 'none';
}
} }
}); });
}; };
useEthernetClicked() {
let useEthernet = document.getElementById('cbHardwired').checked;
document.getElementById('divWiFiMode').style.display = useEthernet ? 'none' : '';
document.getElementById('divEthernetMode').style.display = useEthernet ? '' : 'none';
document.getElementById('divFallbackWireless').style.display = useEthernet ? 'inline-block' : 'none';
}
async loadAPs() { async loadAPs() {
if (document.getElementById('btnScanAPs').classList.contains('disabled')) return; if (document.getElementById('btnScanAPs').classList.contains('disabled')) return;
document.getElementById('divAps').innerHTML = '<div style="display:flex;justify-content:center;align-items:center;"><div class="lds-roller"><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div></div></div>'; document.getElementById('divAps').innerHTML = '<div style="display:flex;justify-content:center;align-items:center;"><div class="lds-roller"><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div></div></div>';
@ -636,6 +734,81 @@ class Wifi {
displaySignal(sig) { displaySignal(sig) {
return `<div class="signal waveStrength-${this.calcWaveStrength(sig)}"><div class="wv4 wave"><div class="wv3 wave"><div class="wv2 wave"><div class="wv1 wave"><div class="wv0 wave"></div></div></div></div></div></div>`; return `<div class="signal waveStrength-${this.calcWaveStrength(sig)}"><div class="wv4 wave"><div class="wv3 wave"><div class="wv2 wave"><div class="wv1 wave"><div class="wv0 wave"></div></div></div></div></div></div>`;
}; };
saveNetwork() {
let obj = {
connType: document.getElementById('cbHardwired').checked ? document.getElementById('cbFallbackWireless').checked ? 3 : 2 : 1,
wifi: {},
ethernet: {}
};
if (obj.connType >= 2) {
// We are connecting to a LAN but we need the user to be sure about this since
// the information needs to be correct. Incorrect settings can destroy the board.
obj.ethernet = {
boardType: parseInt(document.getElementById('selETHBoardType').value, 10),
phyType: parseInt(document.getElementById('selETHPhyType').value, 10),
phyAddress: parseInt(document.getElementById('selETHAddress').value, 10),
dhcp: document.getElementById('cbUseDHCP').checked,
CLKMode: parseInt(document.getElementById('selETHClkMode').value, 10),
PWRPin: parseInt(document.getElementById('selETHPWRPin').value, 10),
MDCPin: parseInt(document.getElementById('selETHMDCPin').value, 10),
MDIOPin: parseInt(document.getElementById('selETHMDIOPin').value, 10),
ip: document.getElementById('fldIPAddress').value,
subnet: document.getElementById('fldSubnetMask').value,
gateway: document.getElementById('fldGateway').value,
dns1: document.getElementById('fldDNS1').value,
dns2: document.getElementById('fldDNS2').value
}
let boardType = this.ethBoardTypes.find(elem => obj.ethernet.boardType === elem.val);
let phyType = this.ethPhyTypes.find(elem => obj.ethernet.phyType === elem.val);
let clkMode = this.ethClockModes.find(elem => obj.ethernet.CLKMode === elem.val);
let div = document.createElement('div');
let html = `<form id="frmSetLAN"><div id="divLanSettings" class="instructions" style="display:block;height:auto;min-height:100%">`;
html += '<div style="width:100%;color:red;text-align:center;font-weight:bold;"><span style="background:yellow;padding:10px;display:inline-block;border-radius:5px;background:white;">BEWARE ... WARNING ... DANGER<span></div>';
html += '<hr style="width:100%;margin:0px;"></hr>';
html += '<p style="font-size:14px;">Incorrect Ethernet settings can damage your ESP32. Please verify the settings below and ensure they match the manufacturer spec sheet.</p>';
html += '<p style="font-size:14px;">If you are unsure do not press the Red button and press the Green button. If any of the settings are incorrect please use the Custom Board type and set them to the correct values.';
html += '<hr/><div>';
html += `<div class="eth-setting-line"><label>Board Type</label><span>${boardType.label} [${boardType.val}]</span></div>`;
html += `<div class="eth-setting-line"><label>PHY Chip Type</label><span>${phyType.label} [${phyType.val}]</span></div>`;
html += `<div class="eth-setting-line"><label>PHY Address</label><span>${obj.ethernet.phyAddress}</span ></div >`;
html += `<div class="eth-setting-line"><label>Clock Mode</label><span>${clkMode.label} [${clkMode.val}]</span></div >`;
html += `<div class="eth-setting-line"><label>Power Pin</label><span>${obj.ethernet.PWRPin === -1 ? 'None' : obj.ethernet.PWRPin}</span></div>`;
html += `<div class="eth-setting-line"><label>MDC Pin</label><span>${obj.ethernet.MDCPin}</span></div>`;
html += `<div class="eth-setting-line"><label>MDIO Pin</label><span>${obj.ethernet.MDIOPin}</span></div>`;
html += '</div>'
html += `<div class="button-container">`
html += `<button id="btnSaveEthernet" type="button" style="padding-left:20px;padding-right:20px;display:inline-block;background:orangered;">Save Ethernet Settings</button>`
html += `<button id="btnCancel" type="button" style="padding-left:20px;padding-right:20px;display:inline-block;background:lawngreen;color:gray" onclick="document.getElementById('frmSetLAN').remove();">Cancel</button>`
html += `</div><form>`;
div.innerHTML = html;
document.getElementById('divContainer').appendChild(div);
div.querySelector('#btnSaveEthernet').addEventListener('click', (el, event) => {
console.log(obj);
document.getElementById('frmSetLAN').remove();
this.sendNetworkSettings(obj);
});
}
else {
obj.wifi = {
ssid: document.getElementsByName('ssid')[0].value,
passphrase: document.getElementsByName('passphrase')[0].value
};
this.sendNetworkSettings(obj);
}
}
sendNetworkSettings(obj) {
if (document.getElementById('btnSaveNetwork').classList.contains('disabled')) return;
document.getElementById('btnSaveNetwork').classList.add('disabled');
let overlay = waitMessage(document.getElementById('divContainer'));
putJSON('/setNetwork', obj, (err, response) => {
overlay.remove();
document.getElementById('btnSaveNetwork').classList.remove('disabled');
console.log(response);
});
}
connectWiFi() { connectWiFi() {
if (document.getElementById('btnConnectWiFi').classList.contains('disabled')) return; if (document.getElementById('btnConnectWiFi').classList.contains('disabled')) return;
document.getElementById('btnConnectWiFi').classList.add('disabled'); document.getElementById('btnConnectWiFi').classList.add('disabled');
@ -663,6 +836,13 @@ class Wifi {
} }
document.getElementById('spanNetworkStrength').innerHTML = (isNaN(strength.strength) || strength.strength <= -100) ? '----' : strength.strength; document.getElementById('spanNetworkStrength').innerHTML = (isNaN(strength.strength) || strength.strength <= -100) ? '----' : strength.strength;
} }
procEthernet(ethernet) {
console.log(ethernet);
document.getElementById('divEthernetStatus').style.display = ethernet.connected ? '' : 'none';
document.getElementById('divWiFiStrength').style.display = ethernet.connected ? 'none' : '';
document.getElementById('spanEthernetStatus').innerHTML = ethernet.connected ? 'Connected' : 'Disconnected';
document.getElementById('spanEthernetSpeed').innerHTML = !ethernet.connected ? '--------' : `${ethernet.speed}Mbps ${ethernet.fullduplex ? 'Full-duplex' : 'Half-duplex'}`;
}
}; };
var wifi = new Wifi(); var wifi = new Wifi();
class Somfy { class Somfy {
@ -1569,7 +1749,7 @@ class Firmware {
} }
break; break;
case '/updateFirmware': case '/updateFirmware':
if (filename.indexOf('.ino.esp') === -1 || !filename.endsWith('.bin')) { if (filename.indexOf('.ino.') === -1 || !filename.endsWith('.bin')) {
errorMessage(el, 'This file is not a valid firmware binary file.'); errorMessage(el, 'This file is not a valid firmware binary file.');
return; return;
} }

View file

@ -630,4 +630,20 @@ div.waitoverlay > .lds-roller {
} }
.shade-positioner label .shade-target { .shade-positioner label .shade-target {
display:inline-block; display:inline-block;
}
div.eth-setting-line {
font-size:12px;
padding-top:0px;
padding-bottom:0px;
}
div.eth-setting-line span {
margin-left:7px;
}
div.eth-setting-line label {
margin-left: 40px;
display:inline-block;
width: 90px;
text-align:right;
color:mediumspringgreen;
} }