Ethernet Support (#1316)

Ethernet Support
This commit is contained in:
tbnobody 2020-11-13 18:25:13 +01:00 committed by GitHub
parent 560f72a320
commit c365fd9d74
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 191 additions and 41 deletions

View File

@ -39,6 +39,7 @@ default_envs = travis_esp8266, travis_esp32
; default_envs = d1_mini_5CH_Shojo_PCB
; default_envs = wemos_shield_esp32
; default_envs = m5atom
; default_envs = esp32_poe
[common]
# ------------------------------------------------------------------------------
@ -248,6 +249,15 @@ lib_ignore =
ESPAsyncTCP
ESPAsyncUDP
[env:esp32_poe]
board = esp32-poe
platform = espressif32@1.12.4
upload_speed = 921600
build_flags = ${common.build_flags_esp32} ${common.debug_flags} -D RLYPIN=-1 -D WLED_USE_ETHERNET
lib_ignore =
ESPAsyncTCP
ESPAsyncUDP
[env:esp8285_4CH_MagicHome]
board = esp8285
platform = ${common.platform_latest}

59
wled00/Network.cpp Normal file
View File

@ -0,0 +1,59 @@
#include "Network.h"
IPAddress NetworkClass::localIP()
{
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
if (ETH.localIP()[0] != 0) {
return ETH.localIP();
}
#endif
if (WiFi.localIP()[0] != 0) {
return WiFi.localIP();
}
return INADDR_NONE;
}
IPAddress NetworkClass::subnetMask()
{
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
if (ETH.localIP()[0] != 0) {
return ETH.subnetMask();
}
#endif
if (WiFi.localIP()[0] != 0) {
return WiFi.subnetMask();
}
return IPAddress(255, 255, 255, 0);
}
IPAddress NetworkClass::gatewayIP()
{
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
if (ETH.localIP()[0] != 0) {
return ETH.gatewayIP();
}
#endif
if (WiFi.localIP()[0] != 0) {
return WiFi.gatewayIP();
}
return INADDR_NONE;
}
bool NetworkClass::isConnected()
{
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
return (WiFi.localIP()[0] != 0 && WiFi.status() == WL_CONNECTED) || ETH.localIP()[0] != 0;
#else
return (WiFi.localIP()[0] != 0 && WiFi.status() == WL_CONNECTED);
#endif
}
bool NetworkClass::isEthernet()
{
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
return (ETH.localIP()[0] != 0);
#endif
return false;
}
NetworkClass Network;

23
wled00/Network.h Normal file
View File

@ -0,0 +1,23 @@
#ifdef ESP8266
#include <ESP8266WiFi.h>
#else // ESP32
#include <WiFi.h>
#include <ETH.h>
#endif
#ifndef Network_h
#define Network_h
class NetworkClass
{
public:
IPAddress localIP();
IPAddress subnetMask();
IPAddress gatewayIP();
bool isConnected();
bool isEthernet();
};
extern NetworkClass Network;
#endif

View File

@ -18,6 +18,7 @@
*/
#include "ESPAsyncE131.h"
#include "Network.h"
#include <string.h>
// E1.17 ACN Packet Identifier
@ -75,7 +76,7 @@ bool ESPAsyncE131::initMulticast(uint16_t port, uint16_t universe, uint8_t n) {
ip4_addr_t ifaddr;
ip4_addr_t multicast_addr;
ifaddr.addr = static_cast<uint32_t>(WiFi.localIP());
ifaddr.addr = static_cast<uint32_t>(Network.localIP());
for (uint8_t i = 1; i < n; i++) {
multicast_addr.addr = static_cast<uint32_t>(IPAddress(239, 255,
(((universe + i) >> 8) & 0xff), (((universe + i) >> 0)

View File

@ -47,6 +47,7 @@
#endif
#endif
#include <WiFiUdp.h>
#include "Network.h"
#ifdef ESPALEXA_DEBUG
#pragma message "Espalexa 2.4.6 debug mode"
@ -207,7 +208,7 @@ private:
void serveDescription()
{
EA_DEBUGLN("# Responding to description.xml ... #\n");
IPAddress localIP = WiFi.localIP();
IPAddress localIP = Network.localIP();
char s[16];
sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
char buf[1024];
@ -281,7 +282,7 @@ private:
//respond to UDP SSDP M-SEARCH
void respondToSearch()
{
IPAddress localIP = WiFi.localIP();
IPAddress localIP = Network.localIP();
char s[16];
sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
@ -333,7 +334,7 @@ public:
#ifdef ARDUINO_ARCH_ESP32
udpConnected = espalexaUdp.beginMulticast(IPAddress(239, 255, 255, 250), 1900);
#else
udpConnected = espalexaUdp.beginMulticast(WiFi.localIP(), IPAddress(239, 255, 255, 250), 1900);
udpConnected = espalexaUdp.beginMulticast(Network.localIP(), IPAddress(239, 255, 255, 250), 1900);
#endif
if (udpConnected){

View File

@ -61,7 +61,7 @@ void notify(byte callMode, bool followUp)
udpOut[28] = (t >> 0) & 0xFF;
IPAddress broadcastIp;
broadcastIp = ~uint32_t(WiFi.subnetMask()) | uint32_t(WiFi.gatewayIP());
broadcastIp = ~uint32_t(Network.subnetMask()) | uint32_t(Network.gatewayIP());
notifierUdp.beginPacket(broadcastIp, udpPort);
notifierUdp.write(udpOut, WLEDPACKETSIZE);
@ -157,7 +157,7 @@ void handleNotifications()
//notifier and UDP realtime
if (!packetSize || packetSize > UDP_IN_MAXSIZE) return;
if (!isSupp && notifierUdp.remoteIP() == WiFi.localIP()) return; //don't process broadcasts we send ourselves
if (!isSupp && notifierUdp.remoteIP() == Network.localIP()) return; //don't process broadcasts we send ourselves
uint8_t udpIn[packetSize +1];
if (isSupp) notifier2Udp.read(udpIn, packetSize);

View File

@ -43,6 +43,68 @@ bool oappend(const char* txt)
return true;
}
void prepareHostname(char* hostname)
{
const char *pC = serverDescription;
uint8_t pos = 5;
while (*pC && pos < 24) { // while !null and not over length
if (isalnum(*pC)) { // if the current char is alpha-numeric append it to the hostname
hostname[pos] = *pC;
pos++;
} else if (*pC == ' ' || *pC == '_' || *pC == '-' || *pC == '+' || *pC == '!' || *pC == '?' || *pC == '*') {
hostname[pos] = '-';
pos++;
}
// else do nothing - no leading hyphens and do not include hyphens for all other characters.
pC++;
}
// if the hostname is left blank, use the mac address/default mdns name
if (pos < 6) {
sprintf(hostname + 5, "%*s", 6, escapedMac.c_str() + 6);
} else { //last character must not be hyphen
while (pos > 0 && hostname[pos -1] == '-') {
hostname[pos -1] = 0;
pos--;
}
}
}
//handle Ethernet connection event
void WiFiEvent(WiFiEvent_t event)
{
char hostname[25] = "wled-";
switch (event) {
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
case SYSTEM_EVENT_ETH_START:
DEBUG_PRINT("ETH Started");
break;
case SYSTEM_EVENT_ETH_CONNECTED:
DEBUG_PRINT("ETH Connected");
if (!apActive) {
WiFi.disconnect(true);
}
if (staticIP != (uint32_t)0x00000000 && staticGateway != (uint32_t)0x00000000) {
ETH.config(staticIP, staticGateway, staticSubnet, IPAddress(8, 8, 8, 8));
} else {
ETH.config(INADDR_NONE, INADDR_NONE, INADDR_NONE);
}
// convert the "serverDescription" into a valid DNS hostname (alphanumeric)
prepareHostname(hostname);
ETH.setHostname(hostname);
showWelcomePage = false;
break;
case SYSTEM_EVENT_ETH_DISCONNECTED:
DEBUG_PRINT("ETH Disconnected");
forceReconnect = true;
break;
#endif
default:
break;
}
}
void WLED::loop()
{
handleIR(); // 2nd call to function needed for ESP32 to return valid results -- should be good for ESP8266, too
@ -120,7 +182,7 @@ void WLED::loop()
lastWifiState = WiFi.status();
DEBUG_PRINT("State time: "); DEBUG_PRINTLN(wifiStateChangedTime);
DEBUG_PRINT("NTP last sync: "); DEBUG_PRINTLN(ntpLastSyncTime);
DEBUG_PRINT("Client IP: "); DEBUG_PRINTLN(WiFi.localIP());
DEBUG_PRINT("Client IP: "); DEBUG_PRINTLN(Network.localIP());
DEBUG_PRINT("Loops/sec: "); DEBUG_PRINTLN(loops / 10);
loops = 0;
debugTime = millis();
@ -187,6 +249,7 @@ void WLED::setup()
if (strcmp(clientSSID, DEFAULT_CLIENT_SSID) == 0)
showWelcomePage = true;
WiFi.persistent(false);
WiFi.onEvent(WiFiEvent);
if (macroBoot > 0)
applyMacro(macroBoot);
@ -303,6 +366,10 @@ void WLED::initConnection()
ws.onEvent(wsEvent);
#endif
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
ETH.begin();
#endif
WiFi.disconnect(true); // close old connections
#ifdef ESP8266
WiFi.setPhyMode(WIFI_PHY_MODE_11N);
@ -338,29 +405,7 @@ void WLED::initConnection()
// convert the "serverDescription" into a valid DNS hostname (alphanumeric)
char hostname[25] = "wled-";
const char *pC = serverDescription;
uint8_t pos = 5;
while (*pC && pos < 24) { // while !null and not over length
if (isalnum(*pC)) { // if the current char is alpha-numeric append it to the hostname
hostname[pos] = *pC;
pos++;
} else if (*pC == ' ' || *pC == '_' || *pC == '-' || *pC == '+' || *pC == '!' || *pC == '?' || *pC == '*') {
hostname[pos] = '-';
pos++;
}
// else do nothing - no leading hyphens and do not include hyphens for all other characters.
pC++;
}
// if the hostname is left blank, use the mac address/default mdns name
if (pos < 6) {
sprintf(hostname + 5, "%*s", 6, escapedMac.c_str() + 6);
} else { //last character must not be hyphen
while (pos > 0 && hostname[pos -1] == '-') {
hostname[pos -1] = 0;
pos--;
}
}
prepareHostname(hostname);
#ifdef ESP8266
WiFi.hostname(hostname);
@ -381,9 +426,9 @@ void WLED::initInterfaces()
DEBUG_PRINTLN(F("Init STA interfaces"));
if (hueIP[0] == 0) {
hueIP[0] = WiFi.localIP()[0];
hueIP[1] = WiFi.localIP()[1];
hueIP[2] = WiFi.localIP()[2];
hueIP[0] = Network.localIP()[0];
hueIP[1] = Network.localIP()[1];
hueIP[2] = Network.localIP()[2];
}
// init Alexa hue emulation
@ -482,7 +527,7 @@ void WLED::handleConnection()
wasConnected = false;
return;
}
if (!WLED_CONNECTED) {
if (!Network.isConnected()) {
if (interfacesInited) {
DEBUG_PRINTLN(F("Disconnected!"));
interfacesInited = false;
@ -495,7 +540,7 @@ void WLED::handleConnection()
} else if (!interfacesInited) { // newly connected
DEBUG_PRINTLN("");
DEBUG_PRINT(F("Connected! IP address: "));
DEBUG_PRINTLN(WiFi.localIP());
DEBUG_PRINTLN(Network.localIP());
initInterfaces();
userConnected();
usermods.connected();

View File

@ -54,12 +54,15 @@
}
#else // ESP32
#include <WiFi.h>
#include <ETH.h>
#include "esp_wifi.h"
#include <ESPmDNS.h>
#include <AsyncTCP.h>
#include "SPIFFS.h"
#endif
#include "Network.h"
#include <ESPAsyncWebServer.h>
#include <EEPROM.h>
#include <WiFiUdp.h>
@ -521,8 +524,11 @@ WLED_GLOBAL UsermodManager usermods _INIT(UsermodManager());
WLED_GLOBAL int loops _INIT(0);
#endif
#ifdef ARDUINO_ARCH_ESP32
#define WLED_CONNECTED (WiFi.status() == WL_CONNECTED || ETH.localIP()[0] != 0)
#else
#define WLED_CONNECTED (WiFi.status() == WL_CONNECTED)
#endif
#define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID, DEFAULT_CLIENT_SSID) != 0)
#define WLED_MQTT_CONNECTED (mqtt != nullptr && mqtt->connected())

View File

@ -83,9 +83,10 @@ void URL_response(AsyncWebServerRequest *request)
char s[16];
oappend(SET_F("http://"));
IPAddress localIP = WiFi.localIP();
IPAddress localIP = Network.localIP();
sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
oappend(s);
oappend(SET_F("/win&A="));
oappendi(bri);
oappend(SET_F("&CL=h"));
@ -219,11 +220,15 @@ void getSettingsJS(byte subPage, char* dest)
sappend('c',SET_F("WS"),noWifiSleep);
if (WiFi.localIP()[0] != 0) //is connected
if (Network.isConnected()) //is connected
{
char s[16];
IPAddress localIP = WiFi.localIP();
char s[32];
IPAddress localIP = Network.localIP();
sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
if (Network.isEthernet()) strcat_P(s ,SET_F(" (Ethernet)"));
#endif
sappends('m',SET_F("(\"sip\")[0]"),s);
} else
{