diff --git a/.travis.yml b/.travis.yml index 393fdeefd..c33d680d2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -73,7 +73,7 @@ script: - PLATFORMIO_BUILD_FLAGS="-D CONTINUOUS_INTEGRATION" platformio run -e test_ESP8266_4M1M_VCC #- PLATFORMIO_BUILD_FLAGS="-D CONTINUOUS_INTEGRATION" platformio run -e test_ESP8266_4M1M_VCC_MDNS_SD #- PLATFORMIO_BUILD_FLAGS="-D CONTINUOUS_INTEGRATION" platformio run -e test_beta_ESP8266_16M_LittleFS - - PLATFORMIO_BUILD_FLAGS="-D CONTINUOUS_INTEGRATION" platformio run -e test_beta_ESP8266_4M1M + #- PLATFORMIO_BUILD_FLAGS="-D CONTINUOUS_INTEGRATION" platformio run -e test_beta_ESP8266_4M1M before_deploy: - ./before_deploy diff --git a/docs/source/Rules/Rules.rst b/docs/source/Rules/Rules.rst index 50a74ee43..71a40dfc8 100644 --- a/docs/source/Rules/Rules.rst +++ b/docs/source/Rules/Rules.rst @@ -388,6 +388,7 @@ Transformation * A "binary" transformation can be "inverted" by adding a leading ``!``. * A "binary" value is considered 0 when its string value is "0" or empty, otherwise it is an 1. (float values are rounded) * A "binary" value can also be used to detect presence of a string, as it is 0 on an empty string or 1 otherwise. +* If the transformation contains ``R``, under certain circumstances, the value will be right-aligned. Binary transformations: @@ -417,9 +418,16 @@ Floating point transformations: * ``F``: Floor (round down) * ``E``: cEiling (round up) +Other transformations: + +* ``p``: Password display, replacing all value characters by asterisks ``*``. If the value is "0", nothing will be displayed. +* ``Pc``: Password display with custom character ``c``. For example P- will display value "123" as "---". If the value is "0", nothing will be displayed. + Justification ^^^^^^^^^^^^^ +To apply a justification, a transformation must also be used. If no transformation is needed, use the ``V`` (value) transformation. + * ``Pn``: Prefix Fill with n spaces. * ``Sn``: Suffix Fill with n spaces. * ``Ln``: Left part of the string, n characters. diff --git a/platformio_esp32_envs.ini b/platformio_esp32_envs.ini index 0e1dc2ffe..f14bccc17 100644 --- a/platformio_esp32_envs.ini +++ b/platformio_esp32_envs.ini @@ -27,7 +27,6 @@ monitor_filters = esp32_exception_decoder - ; Custom: 4096k version -------------------------- [env:custom_ESP32_4M316k] extends = esp32_common @@ -40,7 +39,9 @@ extra_scripts = ${esp32_common.extra_scripts} [env:test_ESP32_4M316k] extends = esp32_common platform = ${esp32_common.platform} -build_flags = ${esp32_common.build_flags} -DPLUGIN_SET_TEST_ESP32 +build_flags = ${esp32_common.build_flags} + -DFEATURE_ARDUINO_OTA + -DPLUGIN_SET_TEST_ESP32 board = esp32dev extra_scripts = ${esp32_common.extra_scripts} @@ -48,11 +49,30 @@ extra_scripts = ${esp32_common.extra_scripts} [env:test_ESP32-wrover-kit_4M316k] extends = esp32_common platform = ${esp32_common.platform} -build_flags = ${esp32_common.build_flags} -DPLUGIN_SET_TEST_ESP32 +build_flags = ${esp32_common.build_flags} + -DFEATURE_ARDUINO_OTA + -DPLUGIN_SET_TEST_ESP32 board = esp-wrover-kit upload_protocol = ftdi debug_tool = ftdi debug_extra_cmds = break Misc.ino:3011 extra_scripts = ${esp32_common.extra_scripts} +; Custom: 4096k version -------------------------- +[env:custom_ESP32_4M316k_ETH] +extends = env:custom_ESP32_4M316k +platform = ${env:custom_ESP32_4M316k.platform} +build_flags = ${env:custom_ESP32_4M316k.build_flags} -DHAS_ETHERNET + +[env:test_ESP32_4M316k_ETH] +extends = env:test_ESP32_4M316k +platform = ${env:test_ESP32_4M316k.platform} +build_flags = ${env:test_ESP32_4M316k.build_flags} -DHAS_ETHERNET + + +[env:test_ESP32-wrover-kit_4M316k_ETH] +extends = env:test_ESP32-wrover-kit_4M316k +platform = ${env:test_ESP32-wrover-kit_4M316k.platform} +build_flags = ${env:test_ESP32-wrover-kit_4M316k.build_flags} -DHAS_ETHERNET + diff --git a/src/Controller.ino b/src/Controller.ino index 3e854aab1..ebc0f0f18 100644 --- a/src/Controller.ino +++ b/src/Controller.ino @@ -273,7 +273,7 @@ String getMQTTclientID(const ControllerSettingsStruct& ControllerSettings) { \*********************************************************************************************/ bool MQTTCheck(controllerIndex_t controller_idx) { - if (!WiFiConnected(10)) { + if (!NetworkConnected(10)) { return false; } protocolIndex_t ProtocolIndex = getProtocolIndex_from_ControllerIndex(controller_idx); diff --git a/src/ESPEasy-Globals.cpp b/src/ESPEasy-Globals.cpp index e255ccfed..212aed707 100644 --- a/src/ESPEasy-Globals.cpp +++ b/src/ESPEasy-Globals.cpp @@ -2,6 +2,7 @@ #include "ESPEasy-Globals.h" #include "ESPEasy_plugindefs.h" +#include "ESPEasyEthWifi.h" #if defined(ESP32) @@ -23,6 +24,14 @@ bool dnsServerActive = false; //NTP status bool statusNTPInitialized = false; +// Ethernet Connectiopn status +#ifdef HAS_ETHERNET +uint8_t eth_wifi_mode = ETHERNET; + // WIFI = 0 + // ETHERNET = 1 +bool eth_connected = false; +#endif + // udp protocol stuff (syslog, global sync, node info list, ntp time) WiFiUDP portUDP; diff --git a/src/ESPEasy-Globals.h b/src/ESPEasy-Globals.h index 9639e3679..d726c4f6d 100644 --- a/src/ESPEasy-Globals.h +++ b/src/ESPEasy-Globals.h @@ -230,6 +230,11 @@ extern bool statusNTPInitialized; // udp protocol stuff (syslog, global sync, node info list, ntp time) extern WiFiUDP portUDP; +// Ethernet Connectiopn status +#ifdef HAS_ETHERNET +extern uint8_t eth_wifi_mode; +extern bool eth_connected; +#endif @@ -438,6 +443,16 @@ struct GpioFactorySettingsStruct { i2c_sda = -1; // GPIO4 conflicts with relay control. i2c_scl = -1; // GPIO5 conflicts with SW input break; + case DeviceMode_Olimex_ESP32_PoE: + button[0] = 34; // DUT1 Button + relais[0] = -1; // No LED's or relays on board + status_led = -1; + i2c_sda = 4; + i2c_scl = 5; + eth_power = 12; + eth_clock_mode = 3; + eth_wifi_mode = 1; + break; // case DeviceModel_default: break; default: break; @@ -449,6 +464,13 @@ struct GpioFactorySettingsStruct { int8_t status_led = DEFAULT_PIN_STATUS_LED; int8_t i2c_sda = DEFAULT_PIN_I2C_SDA; int8_t i2c_scl = DEFAULT_PIN_I2C_SCL; + int8_t eth_phyaddr = DEFAULT_ETH_PHY_ADDR; + int8_t eth_phytype = DEFAULT_ETH_PHY_TYPE; + int8_t eth_mdc = DEFAULT_ETH_PIN_MDC; + int8_t eth_mdio = DEFAULT_ETH_PIN_MDIO; + int8_t eth_power = DEFAULT_ETH_PIN_POWER; + int8_t eth_clock_mode = DEFAULT_ETH_CLOCK_MODE; + int8_t eth_wifi_mode = DEFAULT_ETH_WIFI_MODE; }; void addPredefinedPlugins(const GpioFactorySettingsStruct& gpio_settings); diff --git a/src/ESPEasy.ino b/src/ESPEasy.ino index 5ca0e373d..0d2da7869 100644 --- a/src/ESPEasy.ino +++ b/src/ESPEasy.ino @@ -118,6 +118,8 @@ #include "src/Globals/Services.h" #include "src/Globals/Settings.h" #include "src/Globals/Statistics.h" +#include "ESPEasyWiFi_credentials.h" +#include "ESPEasyWifi_ProcessEvent.h" #if FEATURE_ADC_VCC ADC_MODE(ADC_VCC); @@ -236,7 +238,6 @@ void setup() log += FreeMem(); addLog(LOG_LEVEL_INFO, log); - //warm boot if (readFromRTC()) { @@ -283,6 +284,18 @@ void setup() progMemMD5check(); LoadSettings(); + #ifdef HAS_ETHERNET + // This ensures, that changing WIFI OR ETHERNET MODE happens properly only after reboot. Changing without reboot would not be a good idea. + // This only works after LoadSettings(); + eth_wifi_mode = Settings.ETH_Wifi_Mode; + log = F("INIT : ETH_WIFI_MODE:"); + log += String(eth_wifi_mode); + log += F(" ("); + log += (eth_wifi_mode == WIFI ? F("WIFI") : F("ETHERNET")); + log += F(")"); + addLog(LOG_LEVEL_INFO, log); + #endif + Settings.UseRTOSMultitasking = false; // For now, disable it, we experience heap corruption. if (RTC.bootFailedCount > 10 && RTC.bootCounter > 10) { byte toDisable = RTC.bootFailedCount - 10; @@ -374,7 +387,7 @@ void setup() rulesProcessing(event); // TD-er: Process events in the setup() now. } - WiFiConnectRelaxed(); + NetworkConnectRelaxed(); setWebserverRunning(true); @@ -546,9 +559,16 @@ void loop() updateLoopStats(); + #ifdef HAS_ETHERNET + // Handle WiFiEvents when compiled with HAS_ETHERNET but in WiFi Mode eth_wifi_mode (WIFI = 0, ETHERNET = 1) + if(eth_wifi_mode == WIFI) { + handle_unprocessedWiFiEvents(); + } + #else handle_unprocessedWiFiEvents(); + #endif - bool firstLoopConnectionsEstablished = WiFiConnected() && firstLoop; + bool firstLoopConnectionsEstablished = NetworkConnected() && firstLoop; if (firstLoopConnectionsEstablished) { addLog(LOG_LEVEL_INFO, F("firstLoopConnectionsEstablished")); firstLoop = false; @@ -666,7 +686,7 @@ void updateMQTTclient_connected() { void runPeriodicalMQTT() { // MQTT_KEEPALIVE = 15 seconds. - if (!WiFiConnected(10)) { + if (!NetworkConnected(10)) { updateMQTTclient_connected(); return; } @@ -744,7 +764,7 @@ void run10TimesPerSecond() { processNextEvent(); #ifdef USES_C015 - if (WiFiConnected()) + if (NetworkConnected()) Blynk_Run_c015(); #endif #ifndef USE_RTOS_MULTITASKING @@ -875,8 +895,18 @@ void runEach30Seconds() log += connectionFailures; log += F(" FreeMem "); log += FreeMem(); + #ifdef HAS_ETHERNET + if(eth_wifi_mode == ETHERNET) { + log += F( " EthSpeedState "); + log += getValue(LabelType::ETH_SPEED_STATE); + } else { + log += F(" WiFiStatus "); + log += WiFi.status(); + } + #else log += F(" WiFiStatus "); log += WiFi.status(); + #endif // log += F(" ListenInterval "); // log += WiFi.getListenInterval(); addLog(LOG_LEVEL_INFO, log); @@ -935,10 +965,10 @@ void backgroundtasks() return; } START_TIMER - const bool wifiConnected = WiFiConnected(); + const bool networkConnected = NetworkConnected(); runningBackgroundTasks=true; - if (wifiConnected) { + if (networkConnected) { #if defined(ESP8266) tcpCleanup(); #endif @@ -954,7 +984,12 @@ void backgroundtasks() if (webserverRunning) { web_server.handleClient(); } - if (WiFi.getMode() != WIFI_OFF) { + if (WiFi.getMode() != WIFI_OFF + // This makes UDP working for ETHERNET + #ifdef HAS_ETHERNET + || eth_connected + #endif + ) { checkUDP(); } } @@ -964,14 +999,14 @@ void backgroundtasks() dnsServer.processNextRequest(); #ifdef FEATURE_ARDUINO_OTA - if(Settings.ArduinoOTAEnable && wifiConnected) + if(Settings.ArduinoOTAEnable && networkConnected) ArduinoOTA.handle(); //once OTA is triggered, only handle that and dont do other stuff. (otherwise it fails) while (ArduinoOTAtriggered) { delay(0); - if (WiFiConnected()) { + if (NetworkConnected()) { ArduinoOTA.handle(); } } @@ -980,7 +1015,7 @@ void backgroundtasks() #ifdef FEATURE_MDNS // Allow MDNS processing - if (wifiConnected) { + if (networkConnected) { MDNS.update(); } #endif @@ -991,4 +1026,4 @@ void backgroundtasks() runningBackgroundTasks=false; STOP_TIMER(BACKGROUND_TASKS); -} +} \ No newline at end of file diff --git a/src/ESPEasyEth.cpp b/src/ESPEasyEth.cpp new file mode 100644 index 000000000..5d7ce21bd --- /dev/null +++ b/src/ESPEasyEth.cpp @@ -0,0 +1,130 @@ +#ifdef HAS_ETHERNET + +#include "ESPEasyEth.h" +#include "ESPEasyNetwork.h" +#include "ETH.h" +#include "ESPEasy-Globals.h" +#include "eth_phy/phy.h" + +bool ethUseStaticIP() { + return Settings.ETH_IP[0] != 0 && Settings.ETH_IP[0] != 255; +} + +void ethSetupStaticIPconfig() { + if (!ethUseStaticIP()) { return; } + const IPAddress ip = Settings.ETH_IP; + const IPAddress gw = Settings.ETH_Gateway; + const IPAddress subnet = Settings.ETH_Subnet; + const IPAddress dns = Settings.ETH_DNS; + + if (loglevelActiveFor(LOG_LEVEL_INFO)) { + String log = F("ETH IP : Static IP : "); + log += formatIP(ip); + log += F(" GW: "); + log += formatIP(gw); + log += F(" SN: "); + log += formatIP(subnet); + log += F(" DNS: "); + log += formatIP(dns); + addLog(LOG_LEVEL_INFO, log); + } + ETH.config(ip, gw, subnet, dns); +} + +bool ethCheckSettings() { + bool result = true; + if (Settings.ETH_Phy_Type != 0 && Settings.ETH_Phy_Type != 1) + result = false; + if (Settings.ETH_Clock_Mode > 3) + result = false; + if (Settings.ETH_Wifi_Mode > 1) + result = false; + if (Settings.ETH_Pin_mdc > MAX_GPIO) + result = false; + if (Settings.ETH_Pin_mdio > MAX_GPIO) + result = false; + if (Settings.ETH_Pin_power > MAX_GPIO) + result = false; + return result; +} + +bool ethPrepare() { + if (!ethCheckSettings()) + { + addLog(LOG_LEVEL_ERROR, F("ETH: Settings not correct!!!")); + return false; + } + char hostname[40]; + safe_strncpy(hostname, NetworkCreateRFCCompliantHostname().c_str(), sizeof(hostname)); + ETH.setHostname(hostname); + ETH.config(INADDR_NONE, INADDR_NONE, INADDR_NONE); + ethSetupStaticIPconfig(); + return true; +} + +String ethGetDebugClockModeStr() { + switch (Settings.ETH_Clock_Mode) + { + case 0: return F("ETH_CLOCK_GPIO0_IN"); + case 1: return F("ETH_CLOCK_GPIO0_OUT"); + case 2: return F("ETH_CLOCK_GPIO16_OUT"); + case 3: return F("ETH_CLOCK_GPIO17_OUT"); + default: return F("ETH_CLOCK_ERR"); + } +} + +String ethGetDebugEthWifiModeStr() { + switch (eth_wifi_mode) + { + case 0: return F("WIFI"); + case 1: return F("ETHERNET"); + default: return F("ETH_WIFI_ERR"); + } +} + +void ethPrintSettings() { + String settingsDebugLog; + settingsDebugLog.reserve(115); + settingsDebugLog += F("Eth Wifi mode: "); + settingsDebugLog += ethGetDebugEthWifiModeStr(); + settingsDebugLog += F(" ETH: PHY Type: "); + settingsDebugLog += Settings.ETH_Phy_Type == 0 ? F("ETH_PHY_LAN8720") : F("ETH_PHY_TLK110"); + settingsDebugLog += F(" PHY Addr: "); + settingsDebugLog += Settings.ETH_Phy_Addr; + settingsDebugLog += F(" Eth Clock mode: "); + settingsDebugLog += ethGetDebugClockModeStr(); + settingsDebugLog += F(" MDC Pin: "); + settingsDebugLog += String(Settings.ETH_Pin_mdc); + settingsDebugLog += F(" MIO Pin: "); + settingsDebugLog += String(Settings.ETH_Pin_mdio); + settingsDebugLog += F(" Power Pin: "); + settingsDebugLog += String(Settings.ETH_Pin_power); + addLog(LOG_LEVEL_INFO, settingsDebugLog); +} + +uint8_t * ETHMacAddress(uint8_t* mac) { + esp_eth_get_mac(mac); + return mac; +} + +void ETHConnectRelaxed() { + ethPrintSettings(); + ETH.begin(Settings.ETH_Phy_Addr, + Settings.ETH_Pin_power, + Settings.ETH_Pin_mdc, + Settings.ETH_Pin_mdio, + (eth_phy_type_t)Settings.ETH_Phy_Type, + (eth_clock_mode_t)Settings.ETH_Clock_Mode); + addLog(LOG_LEVEL_INFO, F("After ETH.begin")); + if (!ethPrepare()) { + // Dead code for now... + addLog(LOG_LEVEL_ERROR, F("ETH : Could not prepare ETH!")); + return; + } +} + +bool ETHConnected() { + return eth_connected; +} + +#endif \ No newline at end of file diff --git a/src/ESPEasyEth.h b/src/ESPEasyEth.h new file mode 100644 index 000000000..b130144e9 --- /dev/null +++ b/src/ESPEasyEth.h @@ -0,0 +1,19 @@ +#ifdef HAS_ETHERNET +#ifndef ESPEASY_ETH_H +#define ESPEASY_ETH_H + +#include "ESPEasy_common.h" + +bool ethUseStaticIP(); +void ethSetupStaticIPconfig(); +bool ethCheckSettings(); +bool ethPrepare(); +String ethGetDebugClockModeStr(); +String ethGetDebugEthWifiModeStr(); +void ethPrintSettings(); +void ETHConnectRelaxed(); +bool ETHConnected(); +uint8_t * ETHMacAddress(uint8_t* mac); + +#endif // ESPEASY_ETH_H +#endif \ No newline at end of file diff --git a/src/ESPEasyEthWifi.h b/src/ESPEasyEthWifi.h new file mode 100644 index 000000000..a7fec2e5d --- /dev/null +++ b/src/ESPEasyEthWifi.h @@ -0,0 +1,14 @@ +#ifdef HAS_ETHERNET +#ifndef ESPEASY_WTH_WIFI_H_ +#define ESPEASY_WTH_WIFI_H_ + +#ifndef WIFI +#define WIFI 0 +#endif + +#ifndef ETHERNET +#define ETHERNET 1 +#endif + +#endif // ESPEASY_WTH_WIFI_H_ +#endif // HAS_ETHERNET \ No newline at end of file diff --git a/src/ESPEasyNetwork.cpp b/src/ESPEasyNetwork.cpp new file mode 100644 index 000000000..67e3e03c6 --- /dev/null +++ b/src/ESPEasyNetwork.cpp @@ -0,0 +1,181 @@ +#include "ESPEasyNetwork.h" +#include "ESPEasy_fdwdecl.h" +#include "ESPEasy-Globals.h" +#include "ESPEasy_Log.h" +#include "ESPEasyEth.h" + +#ifdef HAS_ETHERNET +#include "ETH.h" +#endif + +/*********************************************************************************************\ + Ethernet or Wifi Support for ESP32 Build flag HAS_ETHERNET +\*********************************************************************************************/ +void NetworkConnectRelaxed() { +#ifdef HAS_ETHERNET + addLog(LOG_LEVEL_INFO, F("Connect to: ")); + addLog(LOG_LEVEL_INFO, ethGetDebugEthWifiModeStr()); + if(eth_wifi_mode == ETHERNET) { + ETHConnectRelaxed(); + } else { + WiFiConnectRelaxed(); + } +#else + WiFiConnectRelaxed(); +#endif +} + +bool NetworkConnected() { + #ifdef HAS_ETHERNET + if(eth_wifi_mode == ETHERNET) { + return ETHConnected(); + } else { + return WiFiConnected(); + } + #else + return WiFiConnected(); + #endif +} + +IPAddress NetworkLocalIP() { + #ifdef HAS_ETHERNET + if(eth_wifi_mode == ETHERNET) { + if(eth_connected) { + return ETH.localIP(); + } else { + addLog(LOG_LEVEL_ERROR, F("Call NetworkLocalIP() only on connected Ethernet!")); + return IPAddress(); + } + } else { + return WiFi.localIP(); + } + #else + return WiFi.localIP(); + #endif +} + +IPAddress NetworkSubnetMask() { + #ifdef HAS_ETHERNET + if(eth_wifi_mode == ETHERNET) { + if(eth_connected) { + return ETH.subnetMask(); + } else { + addLog(LOG_LEVEL_ERROR, F("Call NetworkSubnetMask() only on connected Ethernet!")); + return IPAddress(); + } + } else { + return WiFi.subnetMask(); + } + #else + return WiFi.subnetMask(); + #endif +} + +IPAddress NetworkGatewayIP() { + #ifdef HAS_ETHERNET + if(eth_wifi_mode == ETHERNET) { + if(eth_connected) { + return ETH.gatewayIP(); + } else { + addLog(LOG_LEVEL_ERROR, F("Call NetworkGatewayIP() only on connected Ethernet!")); + return IPAddress(); + } + } else { + return WiFi.gatewayIP(); + } + #else + return WiFi.gatewayIP(); + #endif +} + +IPAddress NetworkDnsIP (uint8_t dns_no) { + #ifdef HAS_ETHERNET + if(eth_wifi_mode == ETHERNET) { + if(eth_connected) { + return ETH.dnsIP(); + } else { + addLog(LOG_LEVEL_ERROR, F("Call NetworkDnsIP(uint8_t dns_no) only on connected Ethernet!")); + return IPAddress(); + } + } else { + return WiFi.dnsIP(dns_no); + } + #else + return WiFi.dnsIP(dns_no); + #endif +} + +String NetworkMacAddress() { + #ifdef HAS_ETHERNET + if(eth_wifi_mode == ETHERNET) { + if(!eth_connected) { + addLog(LOG_LEVEL_ERROR, F("Call NetworkMacAddress() only on connected Ethernet!")); + } else { + return ETH.macAddress(); + } + } + #endif + + uint8_t mac[] = { 0, 0, 0, 0, 0, 0 }; + uint8_t *macread = NetworkMacAddressAsBytes(mac); + char macaddress[20]; + formatMAC(macread, macaddress); + + return String(macaddress); +} + +uint8_t * NetworkMacAddressAsBytes(uint8_t* mac) { + #ifdef HAS_ETHERNET + if(eth_wifi_mode == ETHERNET) { + return ETHMacAddress(mac); + } else { + return WiFi.macAddress(mac); + } + #else + return WiFi.macAddress(mac); + #endif +} + +String NetworkGetHostname() { + #ifdef ESP32 + #ifdef HAS_ETHERNET + if(Settings.ETH_Wifi_Mode == ETHERNET) { + return String(ETH.getHostname()); + } + return String(WiFi.getHostname()); + #else + return String(WiFi.getHostname()); + #endif + #else + return String(WiFi.hostname()); + #endif +} + +// ******************************************************************************** +// Determine Wifi AP name to set. (also used for mDNS) +// ******************************************************************************** +String NetworkGetHostNameFromSettings() +{ + return Settings.getHostname(); +} + +String NetworkCreateRFCCompliantHostname() { + return createRFCCompliantHostname(NetworkGetHostNameFromSettings()); +} + +// Create hostname with - instead of spaces +String createRFCCompliantHostname(String oldString) { + String result(oldString); + + result.replace(" ", "-"); + result.replace("_", "-"); // See RFC952 + return result; +} + +String WifiSoftAPmacAddress() { + uint8_t mac[] = { 0, 0, 0, 0, 0, 0 }; + uint8_t *macread = WiFi.softAPmacAddress(mac); + char macaddress[20]; + formatMAC(macread, macaddress); + return String(macaddress); +} \ No newline at end of file diff --git a/src/ESPEasyNetwork.h b/src/ESPEasyNetwork.h new file mode 100644 index 000000000..cdb774e85 --- /dev/null +++ b/src/ESPEasyNetwork.h @@ -0,0 +1,21 @@ +#ifndef NETWORK_H +#define NETWORK_H + +#include "ESPEasy-Globals.h" + +void NetworkConnectRelaxed(); +bool NetworkConnected(); +IPAddress NetworkLocalIP(); +IPAddress NetworkSubnetMask(); +IPAddress NetworkGatewayIP(); +IPAddress NetworkDnsIP (uint8_t dns_no); +uint8_t * NetworkMacAddressAsBytes(uint8_t* mac); +String NetworkMacAddress(); +String NetworkGetHostNameFromSettings(); +String NetworkGetHostname(); +String NetworkCreateRFCCompliantHostname(); +String createRFCCompliantHostname(String oldString); +String WifiSoftAPmacAddress(); + + +#endif // NETWORK_H \ No newline at end of file diff --git a/src/ESPEasyStorage.ino b/src/ESPEasyStorage.ino index 2ce5fd626..8914e929f 100644 --- a/src/ESPEasyStorage.ino +++ b/src/ESPEasyStorage.ino @@ -1,3 +1,4 @@ +#include "ESPEasyWifi.h" #include "src/Globals/Cache.h" #include "src/Globals/CRCValues.h" #include "src/Globals/ResetFactoryDefaultPref.h" @@ -186,6 +187,15 @@ String BuildFixes() if (Settings.Build < 20107) { Settings.WebserverPort = 80; } + if (Settings.Build < 20108) { + Settings.ETH_Phy_Addr = DEFAULT_ETH_PHY_ADDR; + Settings.ETH_Pin_mdc = DEFAULT_ETH_PIN_MDC; + Settings.ETH_Pin_mdio = DEFAULT_ETH_PIN_MDIO; + Settings.ETH_Pin_power = DEFAULT_ETH_PIN_POWER; + Settings.ETH_Phy_Type = DEFAULT_ETH_PHY_TYPE; + Settings.ETH_Clock_Mode = DEFAULT_ETH_CLOCK_MODE; + Settings.ETH_Wifi_Mode = DEFAULT_ETH_WIFI_MODE; + } Settings.Build = BUILD; return SaveSettings(); diff --git a/src/ESPEasyWiFiEvent.cpp b/src/ESPEasyWiFiEvent.cpp index e8ac039e3..939b1e884 100644 --- a/src/ESPEasyWiFiEvent.cpp +++ b/src/ESPEasyWiFiEvent.cpp @@ -1,12 +1,22 @@ +#ifdef HAS_ETHERNET +#include "ETH.h" +#endif #include "ESPEasyWiFiEvent.h" +#include "ESPEasyWifi_ProcessEvent.h" #include "src/Globals/ESPEasyWiFiEvent.h" #include "src/Globals/RTC.h" #include "ESPEasyTimeTypes.h" +#include "ESPEasy_Log.h" +#include "ESPEasy_fdwdecl.h" #include "src/DataStructs/RTCStruct.h" #include "src/Helpers/ESPEasy_time_calc.h" +#ifdef HAS_ETHERNET +extern bool eth_connected; +#endif + #ifdef ESP32 void WiFi_Access_Static_IP::set_use_static_ip(bool enabled) { _useStaticIp = enabled; @@ -99,6 +109,50 @@ void WiFiEvent(system_event_id_t event, system_event_info_t info) { case SYSTEM_EVENT_SCAN_DONE: processedScanDone = false; break; +#ifdef HAS_ETHERNET + case SYSTEM_EVENT_ETH_START: + addLog(LOG_LEVEL_INFO, F("ETH Started")); + break; + case SYSTEM_EVENT_ETH_CONNECTED: + addLog(LOG_LEVEL_INFO, F("ETH Connected")); + eth_connected = true; + processEthernetConnected(); + break; + case SYSTEM_EVENT_ETH_GOT_IP: + { + String log = F("ETH MAC: "); + log += NetworkMacAddress(); + log += F(" IPv4: "); + log += NetworkLocalIP().toString(); + log += " ("; + log += NetworkGetHostname(); + log += F(") GW: "); + log += NetworkGatewayIP().toString(); + log += F(" SN: "); + log += NetworkSubnetMask().toString(); + if (ETH.fullDuplex()) { + log += F(" FULL_DUPLEX"); + } + log += F(" "); + log += ETH.linkSpeed(); + log += F("Mbps"); + addLog(LOG_LEVEL_INFO, log); + } + eth_connected = true; + break; + case SYSTEM_EVENT_ETH_DISCONNECTED: + addLog(LOG_LEVEL_ERROR, F("ETH Disconnected")); + eth_connected = false; + processEthernetDisconnected(); + break; + case SYSTEM_EVENT_ETH_STOP: + addLog(LOG_LEVEL_INFO, F("ETH Stopped")); + eth_connected = false; + break; + case SYSTEM_EVENT_GOT_IP6: + addLog(LOG_LEVEL_INFO, F("ETH Got IP6")); + break; +#endif //HAS_ETHERNET default: break; } diff --git a/src/ESPEasyWiFi_credentials.ino b/src/ESPEasyWiFi_credentials.cpp similarity index 92% rename from src/ESPEasyWiFi_credentials.ino rename to src/ESPEasyWiFi_credentials.cpp index 3289fa2fb..aea8a2c5a 100644 --- a/src/ESPEasyWiFi_credentials.ino +++ b/src/ESPEasyWiFi_credentials.cpp @@ -1,3 +1,7 @@ +#include "ESPEasyWiFi_credentials.h" +#include "src/Globals/RTC.h" +#include "src/Globals/SecuritySettings.h" + // ******************************************************************************** // Manage WiFi credentials // ******************************************************************************** diff --git a/src/ESPEasyWiFi_credentials.h b/src/ESPEasyWiFi_credentials.h new file mode 100644 index 000000000..f608100d9 --- /dev/null +++ b/src/ESPEasyWiFi_credentials.h @@ -0,0 +1,11 @@ +#ifndef ESPEASYWIFI_CREDENTIALS_H +#define ESPEASYWIFI_CREDENTIALS_H + +const char* getLastWiFiSettingsSSID(); +const char* getLastWiFiSettingsPassphrase(); +bool selectNextWiFiSettings(); +bool selectValidWiFiSettings(); +bool wifiSettingsValid(const char *ssid, const char *pass); + + +#endif // ESPEASYWIFI_CREDENTIALS_H \ No newline at end of file diff --git a/src/ESPEasyWifi.ino b/src/ESPEasyWifi.cpp similarity index 96% rename from src/ESPEasyWifi.ino rename to src/ESPEasyWifi.cpp index 9eec41d8d..f4d55eb66 100644 --- a/src/ESPEasyWifi.ino +++ b/src/ESPEasyWifi.cpp @@ -1,10 +1,13 @@ -#define WIFI_RECONNECT_WAIT 20000 // in milliSeconds -#define WIFI_AP_OFF_TIMER_DURATION 60000 // in milliSeconds -#define WIFI_CONNECTION_CONSIDERED_STABLE 300000 // in milliSeconds -#define WIFI_ALLOW_AP_AFTERBOOT_PERIOD 5 // in minutes - +#include "ESPEasyWifi.h" +#include "ESPEasyNetwork.h" +#include "ESPEasyWifi_ProcessEvent.h" #include "src/Globals/ESPEasyWiFiEvent.h" #include "ESPEasy-Globals.h" +#include "ESPEasyWiFi_credentials.h" +#include "src/DataStructs/TimingStats.h" +#include "src/Globals/RTC.h" +#include "src/Globals/SecuritySettings.h" +#include "src/Helpers/ESPEasy_time_calc.h" // ******************************************************************************** // WiFi state @@ -203,7 +206,7 @@ bool prepareWiFi() { } setSTA(true); char hostname[40]; - safe_strncpy(hostname, WifiGetHostname().c_str(), sizeof(hostname)); + safe_strncpy(hostname, NetworkCreateRFCCompliantHostname().c_str(), sizeof(hostname)); #if defined(ESP8266) wifi_station_set_hostname(hostname); @@ -381,7 +384,7 @@ void setAPinternal(bool enable) if (enable) { // create and store unique AP SSID/PW to prevent ESP from starting AP mode with default SSID and No password! // setup ssid for AP Mode when needed - String softAPSSID = WifiGetAPssid(); + String softAPSSID = NetworkCreateRFCCompliantHostname(); String pwd = SecuritySettings.WifiAPKey; IPAddress subnet(DEFAULT_AP_SUBNET); @@ -506,26 +509,6 @@ bool WifiIsSTA(WiFiMode_t wifimode) #endif // if defined(ESP32) } -// ******************************************************************************** -// Determine Wifi AP name to set. (also used for mDNS) -// ******************************************************************************** -String WifiGetAPssid() -{ - return Settings.getHostname(); -} - -// ******************************************************************************** -// Determine hostname: basically WifiGetAPssid with spaces changed to - -// ******************************************************************************** -String WifiGetHostname() -{ - String hostname(WifiGetAPssid()); - - hostname.replace(" ", "-"); - hostname.replace("_", "-"); // See RFC952 - return hostname; -} - bool useStaticIP() { return Settings.IP[0] != 0 && Settings.IP[0] != 255; } diff --git a/src/ESPEasyWifi.h b/src/ESPEasyWifi.h new file mode 100644 index 000000000..34c294237 --- /dev/null +++ b/src/ESPEasyWifi.h @@ -0,0 +1,43 @@ +#ifndef ESPEASY_ETH_H +#define ESPEASY_ETH_H + +#include "ESPEasy_common.h" + +#if defined(ESP8266) + # include + # include +#endif // if defined(ESP8266) +#if defined(ESP32) + # include + # include +#endif // if defined(ESP32) + + +#define WIFI_RECONNECT_WAIT 20000 // in milliSeconds +#define WIFI_AP_OFF_TIMER_DURATION 60000 // in milliSeconds +#define WIFI_CONNECTION_CONSIDERED_STABLE 300000 // in milliSeconds +#define WIFI_ALLOW_AP_AFTERBOOT_PERIOD 5 // in minutes + +bool WiFiConnected(); +void WiFiConnectRelaxed(); +bool prepareWiFi(); +void resetWiFi(); +void WifiDisconnect(); +void WifiScan(bool async, bool quick); +void WifiScan(); +void setSTA(bool enable); +void setAP(bool enable); +String getWifiModeString(WiFiMode_t wifimode); +void setWifiMode(WiFiMode_t wifimode); +bool WifiIsAP(WiFiMode_t wifimode); +bool useStaticIP(); +bool wifiConnectTimeoutReached(); +bool wifiAPmodeActivelyUsed(); +void setConnectionSpeed(); +void setupStaticIPconfig(); +String formatScanResult(int i, const String& separator); +String formatScanResult(int i, const String& separator, int32_t& rssi); +void logConnectionStatus(); +String getLastDisconnectReason(); + +#endif // ESPEASY_ETH_H \ No newline at end of file diff --git a/src/ESPEasyWifi_ProcessEvent.ino b/src/ESPEasyWifi_ProcessEvent.cpp similarity index 93% rename from src/ESPEasyWifi_ProcessEvent.ino rename to src/ESPEasyWifi_ProcessEvent.cpp index 288f50875..b7181703e 100644 --- a/src/ESPEasyWifi_ProcessEvent.ino +++ b/src/ESPEasyWifi_ProcessEvent.cpp @@ -1,4 +1,14 @@ +#include "ESPEasyWifi_ProcessEvent.h" +#include "ESPEasy-Globals.h" +#include "ESPEasyNetwork.h" +#include "ESPEasyWifi.h" +#include "ESPEasyWiFi_credentials.h" +#include "ESPEasy_fdwdecl.h" #include "src/Globals/ESPEasyWiFiEvent.h" +#include "src/Globals/RTC.h" +#include "src/Globals/MQTT.h" +#include "src/Helpers/ESPEasy_time_calc.h" +#include "src/DataStructs/SchedulerTimers.h" bool unprocessedWifiEvents() { if (processedConnect && processedDisconnect && processedGotIP && processedDHCPTimeout) @@ -24,7 +34,7 @@ void handle_unprocessedWiFiEvents() delay(1); if (wifiConnectAttemptNeeded) { - WiFiConnectRelaxed(); + NetworkConnectRelaxed(); } // Process disconnect events before connect events. @@ -82,7 +92,7 @@ void handle_unprocessedWiFiEvents() markWiFi_services_initialized(); } } - } else if (!WiFiConnected()) { + } else if (!NetworkConnected()) { // Somehow the WiFi has entered a limbo state. // FIXME TD-er: This may happen on WiFi config with AP_STA mode active. // addLog(LOG_LEVEL_ERROR, F("Wifi status out sync")); @@ -231,7 +241,7 @@ void processGotIP() { // Only process GotIP events if we are connected. return; } - IPAddress ip = WiFi.localIP(); + IPAddress ip = NetworkLocalIP(); if (!useStaticIP()) { if ((ip[0] == 0) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 0)) { @@ -240,8 +250,8 @@ void processGotIP() { } processedGotIP = true; wifiStatus |= ESPEASY_WIFI_GOT_IP; - const IPAddress gw = WiFi.gatewayIP(); - const IPAddress subnet = WiFi.subnetMask(); + const IPAddress gw = NetworkGatewayIP(); + const IPAddress subnet = NetworkSubnetMask(); const long dhcp_duration = timeDiff(lastConnectMoment, lastGetIPmoment); if (loglevelActiveFor(LOG_LEVEL_INFO)) { @@ -254,7 +264,7 @@ void processGotIP() { } log += formatIP(ip); log += " ("; - log += WifiGetHostname(); + log += NetworkGetHostname(); log += F(") GW: "); log += formatIP(gw); log += F(" SN: "); @@ -450,4 +460,23 @@ void markWiFi_services_initialized() { wifiConnectInProgress = false; processedDHCPTimeout = true; // FIXME TD-er: Is this ever happening? -} \ No newline at end of file +} + +#ifdef HAS_ETHERNET + +void processEthernetConnected() { + if (Settings.UseRules) + { + eventQueue.add(F("ETHERNET#Connected")); + } + statusLED(true); +} + +void processEthernetDisconnected() { + if (Settings.UseRules) + { + eventQueue.add(F("ETHERNET#Disconnected")); + } +} + +#endif \ No newline at end of file diff --git a/src/ESPEasyWifi_ProcessEvent.h b/src/ESPEasyWifi_ProcessEvent.h new file mode 100644 index 000000000..78c4a1161 --- /dev/null +++ b/src/ESPEasyWifi_ProcessEvent.h @@ -0,0 +1,20 @@ +#ifndef ESPEASYWIFI_PROCESSEVENT_H +#define ESPEASYWIFI_PROCESSEVENT_H + +bool unprocessedWifiEvents(); +void handle_unprocessedWiFiEvents(); +void processDisconnect(); +void processConnect(); +void processGotIP(); +void processDisconnectAPmode(); +void processConnectAPmode(); +void processDisableAPmode(); +void processScanDone(); +void markWiFi_services_initialized(); + +#ifdef HAS_ETHERNET +void processEthernetConnected(); +void processEthernetDisconnected(); +#endif + +#endif //ESPEASYWIFI_PROCESSEVENT_H \ No newline at end of file diff --git a/src/ESPEasy_buildinfo.h b/src/ESPEasy_buildinfo.h index b6647320a..ccdc2b084 100644 --- a/src/ESPEasy_buildinfo.h +++ b/src/ESPEasy_buildinfo.h @@ -20,7 +20,7 @@ #endif // if defined(ESP32) -#define BUILD 20107 // git version e.g. "20103" can be read as "2.1.03" (stored in int16_t) +#define BUILD 20108 // git version e.g. "20103" can be read as "2.1.03" (stored in int16_t) #if defined(ESP8266) # define BUILD_NOTES " - Mega" #endif // if defined(ESP8266) diff --git a/src/ESPEasy_checks.ino b/src/ESPEasy_checks.ino index db97b1873..feb5d883a 100644 --- a/src/ESPEasy_checks.ino +++ b/src/ESPEasy_checks.ino @@ -36,7 +36,7 @@ template constexpr size_t offsetOf(U T::*member) void run_compiletime_checks() { check_size(); check_size(); - const unsigned int SettingsStructSize = (252 + 82 * TASKS_MAX); + const unsigned int SettingsStructSize = (276 + 82 * TASKS_MAX); check_size(); check_size(); #ifdef USES_NOTIFIER @@ -60,7 +60,7 @@ void run_compiletime_checks() { check_size(); check_size(); check_size(); - check_size(); + check_size(); #if defined(USE_NON_STANDARD_24_TASKS) && defined(ESP8266) static_assert(TASKS_MAX == 24, "TASKS_MAX invalid size"); #endif diff --git a/src/ESPEasy_common.h b/src/ESPEasy_common.h index dce51298f..d1845bf12 100644 --- a/src/ESPEasy_common.h +++ b/src/ESPEasy_common.h @@ -112,7 +112,7 @@ String getUnknownString(); // #define FEATURE_MDNS #endif #if defined(ESP32) - #define FEATURE_ARDUINO_OTA + //#define FEATURE_ARDUINO_OTA //#define FEATURE_MDNS #endif diff --git a/src/ESPEasy_fdwdecl.h b/src/ESPEasy_fdwdecl.h index 72d7262b8..5f149502e 100644 --- a/src/ESPEasy_fdwdecl.h +++ b/src/ESPEasy_fdwdecl.h @@ -66,14 +66,17 @@ bool connectClient(WiFiClient& client, String getWifiModeString(WiFiMode_t wifimode); -bool WiFiConnected(uint32_t timeout_ms); -bool WiFiConnected(); +bool NetworkConnected(uint32_t timeout_ms); +bool NetworkConnected(); bool useStaticIP(); bool hostReachable(const IPAddress& ip); bool hostReachable(const String& hostname); void formatMAC(const uint8_t * mac, char (& strMAC)[20]); +String formatMAC(const uint8_t *mac); String to_json_object_value(const String& object, const String& value); +void htmlEscape(String& html, char c); +void htmlEscape(String& html); bool I2C_read_bytes(uint8_t i2caddr, @@ -142,6 +145,7 @@ String formatToHex(unsigned long value, const String& prefix); String formatToHex(unsigned long value); String formatToHex_decimal(unsigned long value); String getNumerical(const String& tBuf, bool mustBeInteger); +String format_msec_duration(long duration); float getCPUload(); int getLoopCountPerSec(); @@ -150,6 +154,7 @@ void setLogLevelFor(byte destination, byte logLevel); uint16_t getPortFromKey(uint32_t key); void initRTC(); +boolean saveToRTC(); void deepSleepStart(int dsdelay); bool setControllerEnableStatus(controllerIndex_t controllerIndex, bool enabled); bool setTaskEnableStatus(taskIndex_t taskIndex, bool enabled); @@ -195,11 +200,16 @@ bool ExecuteCommand(taskIndex_t taskIndex, EventValueSource::Enum source, const void WifiScan(bool async, bool quick = false); void WifiScan(); -void WiFiConnectRelaxed(); void WifiDisconnect(); void setAP(bool enable); void setSTA(bool enable); +// Used for Networking with Wifi or Ethernet +#include "ESPEasyEthWifi.h" +#include "ESPEasyNetwork.h" +void WiFiConnectRelaxed(); +bool WiFiConnected(); + #include "src/Globals/ESPEasyWiFiEvent.h" void setWifiMode(WiFiMode_t wifimode); @@ -211,13 +221,16 @@ unsigned long FreeMem(void); void ResetFactory(); void reboot(); void SendUDPCommand(byte destUnit, const char *data, byte dataLength); +bool hasIPaddr(); #include void printDirectory(File dir, int numTabs); void delayBackground(unsigned long dsdelay); -void setIntervalTimerOverride(unsigned long id, unsigned long msecFromNow); //implemented in Scheduler.ino +//implemented in Scheduler.ino +void setIntervalTimerOverride(unsigned long id, unsigned long msecFromNow); +void sendGratuitousARP_now(); byte PluginCall(byte Function, struct EventStruct *event, String& str); diff --git a/src/Hardware.ino b/src/Hardware.ino index 98f14bb1a..965cd9fad 100644 --- a/src/Hardware.ino +++ b/src/Hardware.ino @@ -232,6 +232,7 @@ String getDeviceModelBrandString(DeviceModel model) { case DeviceModel_Sonoff_POWr2: return F("Sonoff"); case DeviceModel_Shelly1: case DeviceModel_ShellyPLUG_S: return F("Shelly"); + case DeviceMode_Olimex_ESP32_PoE: return F("Olimex"); // case DeviceModel_default: default: return ""; @@ -256,6 +257,7 @@ String getDeviceModelString(DeviceModel model) { case DeviceModel_Sonoff_POWr2: result += F(" POW-r2"); break; case DeviceModel_Shelly1: result += '1'; break; case DeviceModel_ShellyPLUG_S: result += F(" PLUG S"); break; + case DeviceMode_Olimex_ESP32_PoE: result += F(" ESP32-PoE"); break; // case DeviceModel_default: default: result += F("default"); @@ -279,6 +281,7 @@ bool modelMatchingFlashSize(DeviceModel model) { case DeviceModel_Sonoff_POWr2: return size_MB == 4; case DeviceModel_Shelly1: case DeviceModel_ShellyPLUG_S: return size_MB == 2; + case DeviceMode_Olimex_ESP32_PoE:return size_MB == 4; // case DeviceModel_default: default: return true; diff --git a/src/Misc.ino b/src/Misc.ino index b033c4f5b..8700c0109 100644 --- a/src/Misc.ino +++ b/src/Misc.ino @@ -384,7 +384,7 @@ bool readyForSleep() return false; } - if (!WiFiConnected()) { + if (!NetworkConnected()) { // Allow 12 seconds to establish connections return timeOutReached(timerAwakeFromDeepSleep + 12000); } @@ -795,7 +795,7 @@ void statusLED(bool traffic) else { - if (WiFiConnected()) + if (NetworkConnected()) { long int delta = timePassedSince(gnLastUpdate); if (delta>0 || delta<0 ) @@ -1303,6 +1303,14 @@ void ResetFactory() Settings.UseSerial = DEFAULT_USE_SERIAL; Settings.BaudRate = DEFAULT_SERIAL_BAUD; + Settings.ETH_Phy_Addr = gpio_settings.eth_phyaddr; + Settings.ETH_Pin_mdc = gpio_settings.eth_mdc; + Settings.ETH_Pin_mdio = gpio_settings.eth_mdio; + Settings.ETH_Pin_power = gpio_settings.eth_power; + Settings.ETH_Phy_Type = gpio_settings.eth_phytype; + Settings.ETH_Clock_Mode = gpio_settings.eth_clock_mode; + Settings.ETH_Wifi_Mode = gpio_settings.eth_wifi_mode; + /* Settings.GlobalSync = DEFAULT_USE_GLOBAL_SYNC; @@ -1980,6 +1988,33 @@ void transformValue( { case 'V': //value = value without transformations break; + case 'P': // Password hide using a custom password character: Pc + if (tempValueFormatLength > 1) + { + if (value == F("0")) { + value = ""; + } else { + const int valueLength = value.length(); + for (int i = 0; i < valueLength; i++) { + value[i] = tempValueFormat[1]; + } + } + } else { + value = F("ERR"); + } + break; + case 'p': // Password hide using asterisks + { + if (value == F("0")) { + value = ""; + } else { + const int valueLength = value.length(); + for (int i = 0; i < valueLength; i++) { + value[i] = '*'; + } + } + } + break; case 'O': value = logicVal == 0 ? F("OFF") : F(" ON"); //(equivalent to XOR operator) break; diff --git a/src/Networking.ino b/src/Networking.ino index 838bf0d05..dcf92e43c 100644 --- a/src/Networking.ino +++ b/src/Networking.ino @@ -60,7 +60,7 @@ void etharp_gratuitous_r(struct netif *netif) { \*********************************************************************************************/ void syslog(byte logLevel, const char *message) { - if ((Settings.Syslog_IP[0] != 0) && WiFiConnected()) + if ((Settings.Syslog_IP[0] != 0) && NetworkConnected()) { IPAddress broadcastIP(Settings.Syslog_IP[0], Settings.Syslog_IP[1], Settings.Syslog_IP[2], Settings.Syslog_IP[3]); portUDP.beginPacket(broadcastIP, 514); @@ -230,7 +230,7 @@ void checkUDP() \*********************************************************************************************/ void SendUDPCommand(byte destUnit, const char *data, byte dataLength) { - if (!WiFiConnected(10)) { + if (!NetworkConnected(10)) { return; } @@ -254,7 +254,7 @@ void SendUDPCommand(byte destUnit, const char *data, byte dataLength) \*********************************************************************************************/ void sendUDP(byte unit, const byte *data, byte size) { - if (!WiFiConnected(10)) { + if (!NetworkConnected(10)) { return; } @@ -329,7 +329,7 @@ void refreshNodeList() \*********************************************************************************************/ void sendSysInfoUDP(byte repeats) { - if ((Settings.UDPPort == 0) || !WiFiConnected(10)) { + if ((Settings.UDPPort == 0) || !NetworkConnected(10)) { return; } @@ -351,7 +351,8 @@ void sendSysInfoUDP(byte repeats) for (byte counter = 0; counter < repeats; counter++) { uint8_t mac[] = { 0, 0, 0, 0, 0, 0 }; - uint8_t *macread = WiFi.macAddress(mac); + uint8_t *macread = NetworkMacAddressAsBytes(mac); + byte data[80]; data[0] = 255; data[1] = 1; @@ -359,8 +360,9 @@ void sendSysInfoUDP(byte repeats) for (byte x = 0; x < 6; x++) { data[x + 2] = macread[x]; } - IPAddress ip = WiFi.localIP(); - + + IPAddress ip = NetworkLocalIP(); + for (byte x = 0; x < 4; x++) { data[x + 8] = ip[x]; } @@ -389,7 +391,7 @@ void sendSysInfoUDP(byte repeats) if (it != Nodes.end()) { - IPAddress ip = WiFi.localIP(); + IPAddress ip = NetworkLocalIP(); for (byte x = 0; x < 4; x++) { it->second.ip[x] = ip[x]; @@ -408,11 +410,11 @@ void sendSysInfoUDP(byte repeats) Respond to HTTP XML requests for SSDP information \*********************************************************************************************/ void SSDP_schema(WiFiClient& client) { - if (!WiFiConnected(10)) { + if (!NetworkConnected(10)) { return; } - const IPAddress ip = WiFi.localIP(); + const IPAddress ip = NetworkLocalIP(); const uint32_t chipId = ESP.getChipId(); char uuid[64]; sprintf_P(uuid, PSTR("38323636-4558-4dda-9188-cda0e6%02x%02x%02x"), @@ -504,7 +506,7 @@ bool SSDP_begin() { _server->ref(); ip_addr_t ifaddr; - ifaddr.addr = WiFi.localIP(); + ifaddr.addr = NetworkLocalIP(); ip_addr_t multicast_addr; multicast_addr.addr = (uint32_t)SSDP_MULTICAST_ADDR; @@ -550,7 +552,7 @@ bool SSDP_begin() { Send SSDP messages (notify & responses) \*********************************************************************************************/ void SSDP_send(byte method) { - uint32_t ip = WiFi.localIP(); + uint32_t ip = NetworkLocalIP(); // FIXME TD-er: Why create String objects of these flashstrings? String _ssdp_response_template = F( @@ -569,7 +571,7 @@ void SSDP_send(byte method) { "CACHE-CONTROL: max-age=%u\r\n" // SSDP_INTERVAL "SERVER: Arduino/1.0 UPNP/1.1 ESPEasy/%u\r\n" // _modelNumber "USN: uuid:%s\r\n" // _uuid - "LOCATION: http://%u.%u.%u.%u:80/ssdp.xml\r\n" // WiFi.localIP(), + "LOCATION: http://%u.%u.%u.%u:80/ssdp.xml\r\n" // NetworkLocalIP(), "\r\n"); { char uuid[64] = { 0 }; @@ -759,8 +761,10 @@ bool getSubnetRange(IPAddress& low, IPAddress& high) if (wifiStatus < ESPEASY_WIFI_GOT_IP) { return false; } - const IPAddress ip = WiFi.localIP(); - const IPAddress subnet = WiFi.subnetMask(); + + const IPAddress ip = NetworkLocalIP(); + const IPAddress subnet = NetworkSubnetMask(); + low = ip; high = ip; @@ -804,8 +808,8 @@ bool hasIPaddr() { #endif // ifdef CORE_POST_2_5_0 } -// Check WiFi connection. Maximum timeout 500 msec. -bool WiFiConnected(uint32_t timeout_ms) { +// Check connection. Maximum timeout 500 msec. +bool NetworkConnected(uint32_t timeout_ms) { uint32_t timer = millis() + (timeout_ms > 500 ? 500 : timeout_ms); uint32_t min_delay = timeout_ms / 20; @@ -815,7 +819,7 @@ bool WiFiConnected(uint32_t timeout_ms) { } // Apparently something needs network, perform check to see if it is ready now. - while (!WiFiConnected()) { + while (!NetworkConnected()) { if (timeOutReached(timer)) { return false; } @@ -825,7 +829,7 @@ bool WiFiConnected(uint32_t timeout_ms) { } bool hostReachable(const IPAddress& ip) { - if (!WiFiConnected()) { return false; } + if (!NetworkConnected()) { return false; } return true; // Disabled ping as requested here: // https://github.com/letscontrolit/ESPEasy/issues/1494#issuecomment-397872538 @@ -871,7 +875,7 @@ bool connectClient(WiFiClient& client, IPAddress ip, uint16_t port) { START_TIMER; - if (!WiFiConnected()) { + if (!NetworkConnected()) { return false; } bool connected = (client.connect(ip, port) == 1); @@ -894,7 +898,7 @@ bool connectClient(WiFiClient& client, IPAddress ip, uint16_t port) bool resolveHostByName(const char *aHostname, IPAddress& aResult) { START_TIMER; - if (!WiFiConnected()) { + if (!NetworkConnected()) { return false; } #if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ESP32) @@ -926,7 +930,7 @@ bool hostReachable(const String& hostname) { // Create a random port for the UDP connection. // Return true when successful. bool beginWiFiUDP_randomPort(WiFiUDP& udp) { - if (!WiFiConnected()) { + if (!NetworkConnected()) { return false; } unsigned int attempts = 3; @@ -943,7 +947,7 @@ bool beginWiFiUDP_randomPort(WiFiUDP& udp) { } void sendGratuitousARP() { - if (!WiFiConnected()) { + if (!NetworkConnected()) { return; } #ifdef SUPPORT_ARP diff --git a/src/StringProvider.ino b/src/StringProvider.ino index 1e61c7cdc..11182c80d 100644 --- a/src/StringProvider.ino +++ b/src/StringProvider.ino @@ -1,4 +1,8 @@ #include "StringProviderTypes.h" +#include "ESPEasyNetwork.h" +#ifdef HAS_ETHERNET +#include "ETH.h" +#endif #include "src/Helpers/CompiletimeDefines.h" @@ -106,6 +110,20 @@ String getLabel(LabelType::Enum label) { case LabelType::MAX_OTA_SKETCH_SIZE: return F("Max. OTA Sketch Size"); case LabelType::OTA_2STEP: return F("OTA 2-step Needed"); case LabelType::OTA_POSSIBLE: return F("OTA possible"); +#ifdef HAS_ETHERNET + case LabelType::ETH_IP_ADDRESS: return F("Eth IP Address"); + case LabelType::ETH_IP_SUBNET: return F("Eth IP Subnet"); + case LabelType::ETH_IP_ADDRESS_SUBNET: return F("Eth IP / Subnet"); + case LabelType::ETH_IP_GATEWAY: return F("Eth Gateway"); + case LabelType::ETH_IP_DNS: return F("Eth DNS"); + case LabelType::ETH_MAC: return F("Eth MAC"); + case LabelType::ETH_DUPLEX: return F("Eth Mode"); + case LabelType::ETH_SPEED: return F("Eth Speed"); + case LabelType::ETH_STATE: return F("Eth State"); + case LabelType::ETH_SPEED_STATE: return F("Eth Speed State"); + case LabelType::ETH_WIFI_MODE: return F("Eth Wifi Mode"); + case LabelType::ETH_CONNECTED: return F("Eth connected"); +#endif } return F("MissingString"); @@ -118,12 +136,8 @@ String getValue(LabelType::Enum label) { { case LabelType::UNIT_NR: return String(Settings.Unit); case LabelType::UNIT_NAME: return String(Settings.Name); // Only return the set name, no appended unit. - case LabelType::HOST_NAME: - #ifdef ESP32 - return WiFi.getHostname(); - #else - return WiFi.hostname(); - #endif + case LabelType::HOST_NAME: return NetworkGetHostname(); + case LabelType::LOCAL_TIME: return node_time.getDateTimeString('-',':',' '); case LabelType::UPTIME: return String(wdcounter / 2); @@ -149,20 +163,21 @@ String getValue(LabelType::Enum label) { case LabelType::IP_CONFIG: return useStaticIP() ? getLabel(LabelType::IP_CONFIG_STATIC) : getLabel(LabelType::IP_CONFIG_DYNAMIC); case LabelType::IP_CONFIG_STATIC: break; case LabelType::IP_CONFIG_DYNAMIC: break; - case LabelType::IP_ADDRESS: return WiFi.localIP().toString(); - case LabelType::IP_SUBNET: return WiFi.subnetMask().toString(); + case LabelType::IP_ADDRESS: return NetworkLocalIP().toString(); + case LabelType::IP_SUBNET: return NetworkSubnetMask().toString(); case LabelType::IP_ADDRESS_SUBNET: return String(getValue(LabelType::IP_ADDRESS) + F(" / ") + getValue(LabelType::IP_SUBNET)); - case LabelType::GATEWAY: return WiFi.gatewayIP().toString(); + case LabelType::GATEWAY: return NetworkGatewayIP().toString(); case LabelType::CLIENT_IP: return formatIP(web_server.client().remoteIP()); + #ifdef FEATURE_MDNS - case LabelType::M_DNS: return String(WifiGetHostname()) + F(".local"); + case LabelType::M_DNS: return String(NetworkGetHostname()) + F(".local"); #endif case LabelType::DNS: return String(getValue(LabelType::DNS_1) + F(" / ") + getValue(LabelType::DNS_2)); - case LabelType::DNS_1: return WiFi.dnsIP(0).toString(); - case LabelType::DNS_2: return WiFi.dnsIP(1).toString(); + case LabelType::DNS_1: return NetworkDnsIP(0).toString(); + case LabelType::DNS_2: return NetworkDnsIP(1).toString(); case LabelType::ALLOWED_IP_RANGE: return describeAllowedIPrange(); - case LabelType::STA_MAC: return WiFi.macAddress(); - case LabelType::AP_MAC: break; + case LabelType::STA_MAC: return NetworkMacAddress(); + case LabelType::AP_MAC: return WifiSoftAPmacAddress(); case LabelType::SSID: return WiFi.SSID(); case LabelType::BSSID: return WiFi.BSSIDstr(); case LabelType::CHANNEL: return String(WiFi.channel()); @@ -211,11 +226,50 @@ String getValue(LabelType::Enum label) { case LabelType::MAX_OTA_SKETCH_SIZE: break; case LabelType::OTA_2STEP: break; case LabelType::OTA_POSSIBLE: break; +#ifdef HAS_ETHERNET + case LabelType::ETH_IP_ADDRESS: return NetworkLocalIP().toString(); + case LabelType::ETH_IP_SUBNET: return NetworkSubnetMask().toString(); + case LabelType::ETH_IP_ADDRESS_SUBNET: return String(getValue(LabelType::ETH_IP_ADDRESS) + F(" / ") + getValue(LabelType::ETH_IP_SUBNET)); + case LabelType::ETH_IP_GATEWAY: return NetworkGatewayIP().toString(); + case LabelType::ETH_IP_DNS: return NetworkDnsIP(0).toString(); + case LabelType::ETH_MAC: return NetworkMacAddress(); + case LabelType::ETH_DUPLEX: return eth_connected ? (ETH.fullDuplex() ? F("Full Duplex") : F("Half Duplex")) : F("No Ethernet"); + case LabelType::ETH_SPEED: return eth_connected ? getEthSpeed() : F("No Ethernet"); + case LabelType::ETH_STATE: return eth_connected ? (ETH.linkUp() ? F("Link Up") : F("Link Down")) : F("No Ethernet"); + case LabelType::ETH_SPEED_STATE: return eth_connected ? getEthLinkSpeedState() : F("No Ethernet"); + case LabelType::ETH_WIFI_MODE: return (eth_wifi_mode == WIFI ? F("WIFI") : F("ETHERNET")); + case LabelType::ETH_CONNECTED: return (eth_connected ? F("CONNECTED") : F("DISCONNECTED")); // 0=disconnected, 1=connected +#endif } return F("MissingString"); } +#ifdef HAS_ETHERNET +String getEthSpeed() { + String result; + result.reserve(7); + result += ETH.linkSpeed(); + result += F("Mbps"); + return result; +} + +String getEthLinkSpeedState() { + String result; + result.reserve(29); + if (ETH.linkUp()) { + result += getValue(LabelType::ETH_STATE); + result += ' '; + result += getValue(LabelType::ETH_DUPLEX); + result += ' '; + result += getEthSpeed(); + } else { + result = getValue(LabelType::ETH_STATE); + } + return result; +} +#endif + String getExtendedValue(LabelType::Enum label) { switch (label) { diff --git a/src/StringProviderTypes.h b/src/StringProviderTypes.h index 82d976d27..efca0d940 100644 --- a/src/StringProviderTypes.h +++ b/src/StringProviderTypes.h @@ -100,7 +100,20 @@ enum Enum : short { MAX_OTA_SKETCH_SIZE, OTA_2STEP, OTA_POSSIBLE, - +#ifdef HAS_ETHERNET + ETH_IP_ADDRESS, + ETH_IP_SUBNET, + ETH_IP_ADDRESS_SUBNET, + ETH_IP_GATEWAY, + ETH_IP_DNS, + ETH_MAC, + ETH_DUPLEX, + ETH_SPEED, + ETH_STATE, + ETH_SPEED_STATE, + ETH_WIFI_MODE, + ETH_CONNECTED, +#endif }; }; diff --git a/src/WebServer.ino b/src/WebServer.ino index 056b83a00..d9da1b73c 100644 --- a/src/WebServer.ino +++ b/src/WebServer.ino @@ -4,6 +4,7 @@ #include +#include "ESPEasyNetwork.h" #include "ESPEasy_common.h" #include "src/Globals/CPlugins.h" #include "src/Globals/Device.h" @@ -316,8 +317,8 @@ void set_mDNS() { if (webserverRunning) { addLog(LOG_LEVEL_INFO, F("WIFI : Starting mDNS...")); - bool mdns_started = MDNS.begin(WifiGetHostname().c_str()); - MDNS.setInstanceName(WifiGetHostname()); // Needed for when the hostname has changed. + bool mdns_started = MDNS.begin(NetworkGetHostname().c_str()); + MDNS.setInstanceName(NetworkGetHostname()); // Needed for when the hostname has changed. if (loglevelActiveFor(LOG_LEVEL_INFO)) { String log = F("WIFI : "); diff --git a/src/WebServer_ConfigPage.ino b/src/WebServer_ConfigPage.ino index 66a380430..aea5bfe9f 100644 --- a/src/WebServer_ConfigPage.ino +++ b/src/WebServer_ConfigPage.ino @@ -28,6 +28,12 @@ void handle_config() { String espgateway = web_server.arg(F("espgateway")); String espsubnet = web_server.arg(F("espsubnet")); String espdns = web_server.arg(F("espdns")); +#ifdef HAS_ETHERNET + String espethip = web_server.arg(F("espethip")); + String espethgateway = web_server.arg(F("espethgateway")); + String espethsubnet = web_server.arg(F("espethsubnet")); + String espethdns = web_server.arg(F("espethdns")); +#endif Settings.Unit = getFormItemInt(F("unit"), Settings.Unit); // String apkey = web_server.arg(F("apkey")); @@ -96,6 +102,12 @@ void handle_config() { str2ip(espgateway, Settings.Gateway); str2ip(espsubnet, Settings.Subnet); str2ip(espdns, Settings.DNS); +#ifdef HAS_ETHERNET + str2ip(espethip, Settings.ETH_IP); + str2ip(espethgateway, Settings.ETH_Gateway); + str2ip(espethsubnet, Settings.ETH_Subnet); + str2ip(espethdns, Settings.ETH_DNS); +#endif addHtmlError(SaveSettings()); } @@ -137,14 +149,24 @@ void handle_config() { addFormIPBox(F("Access IP upper range"), F("iprangehigh"), iphigh); } - addFormSubHeader(F("IP Settings")); + addFormSubHeader(F("WiFi IP Settings")); - addFormIPBox(F("ESP IP"), F("espip"), Settings.IP); - addFormIPBox(F("ESP GW"), F("espgateway"), Settings.Gateway); - addFormIPBox(F("ESP Subnetmask"), F("espsubnet"), Settings.Subnet); - addFormIPBox(F("ESP DNS"), F("espdns"), Settings.DNS); + addFormIPBox(F("ESP WiFi IP"), F("espip"), Settings.IP); + addFormIPBox(F("ESP WiFi GW"), F("espgateway"), Settings.Gateway); + addFormIPBox(F("ESP WiFi Subnetmask"), F("espsubnet"), Settings.Subnet); + addFormIPBox(F("ESP WiFi DNS"), F("espdns"), Settings.DNS); addFormNote(F("Leave empty for DHCP")); +#ifdef HAS_ETHERNET + addFormSubHeader(F("Ethernet IP Settings")); + + addFormIPBox(F("ESP Ethernet IP"), F("espethip"), Settings.ETH_IP); + addFormIPBox(F("ESP Ethernet GW"), F("espethgateway"), Settings.ETH_Gateway); + addFormIPBox(F("ESP Ethernet Subnetmask"), F("espethsubnet"), Settings.ETH_Subnet); + addFormIPBox(F("ESP Ethernet DNS"), F("espethdns"), Settings.ETH_DNS); + addFormNote(F("Leave empty for DHCP")); +#endif + addFormSubHeader(F("Sleep Mode")); diff --git a/src/WebServer_HardwarePage.ino b/src/WebServer_HardwarePage.ino index 653c15708..9fc4170f2 100644 --- a/src/WebServer_HardwarePage.ino +++ b/src/WebServer_HardwarePage.ino @@ -25,6 +25,15 @@ void handle_hardware() { Settings.InitSPI = isFormItemChecked(F("initspi")); // SPI Init #endif Settings.Pin_sd_cs = getFormItemInt(F("sd")); +#ifdef HAS_ETHERNET + Settings.ETH_Phy_Addr = getFormItemInt(F("ethphy")); + Settings.ETH_Pin_mdc = getFormItemInt(F("ethmdc")); + Settings.ETH_Pin_mdio = getFormItemInt(F("ethmdio")); + Settings.ETH_Pin_power = getFormItemInt(F("ethpower")); + Settings.ETH_Phy_Type = getFormItemInt(F("ethtype")); + Settings.ETH_Clock_Mode = getFormItemInt(F("ethclock")); + Settings.ETH_Wifi_Mode = getFormItemInt(F("ethwifi")); +#endif int gpio = 0; // FIXME TD-er: Max of 17 is a limit in the Settings.PinBootStates array @@ -83,9 +92,31 @@ void handle_hardware() { #endif addFormNote(F("Chip Select (CS) config must be done in the plugin")); - #ifdef FEATURE_SD - addFormPinSelect(formatGpioName_output("SD Card CS"), "sd", Settings.Pin_sd_cs); - #endif // ifdef FEATURE_SD +#ifdef FEATURE_SD + addFormPinSelect(formatGpioName_output("SD Card CS"), "sd", Settings.Pin_sd_cs); +#endif // ifdef FEATURE_SD + +#ifdef HAS_ETHERNET + addFormSubHeader(F("Ethernet")); + addRowLabel_tr_id(F("Ethernet or WIFI?"), "ethwifi"); + String ethWifiOptions[2] = { F("WIFI"), F("ETHERNET") }; + addSelector("ethwifi", 2, ethWifiOptions, NULL, NULL, Settings.ETH_Wifi_Mode, false, true); + addFormNote(F("Change Switch between WIFI and ETHERNET requires reboot to activate")); + addRowLabel_tr_id(F("Ethernet PHY type"), "ethtype"); + String ethPhyTypes[2] = { F("LAN8710"), F("TLK110") }; + addSelector("ethtype", 2, ethPhyTypes, NULL, NULL, Settings.ETH_Phy_Type, false, true); + addFormNumericBox(F("Ethernet PHY Address"), "ethphy", Settings.ETH_Phy_Addr, 0, 255); + addFormNote(F("I²C-address of Ethernet PHY (0 or 1 for LAN8720, 31 for TLK110)")); + addFormPinSelect(formatGpioName_output("Ethernet MDC pin"), "ethmdc", Settings.ETH_Pin_mdc); + addFormPinSelect(formatGpioName_input("Ethernet MIO pin"), "ethmdio", Settings.ETH_Pin_mdio); + addFormPinSelect(formatGpioName_output("Ethernet Power pin"), "ethpower", Settings.ETH_Pin_power); + addRowLabel_tr_id(F("Ethernet Clock"), "ethclock"); + String ethClockOptions[4] = { F("External crystal oscillator"), + F("50MHz APLL Output on GPIO0"), + F("50MHz APLL Output on GPIO16"), + F("50MHz APLL Inverted Output on GPIO17") }; + addSelector("ethclock", 4, ethClockOptions, NULL, NULL, Settings.ETH_Clock_Mode, false, true); +#endif // ifdef HAS_ETHERNET addFormSubHeader(F("GPIO boot states")); int gpio = 0; diff --git a/src/WebServer_JSON.ino b/src/WebServer_JSON.ino index c54e88068..1e5e9ecaa 100644 --- a/src/WebServer_JSON.ino +++ b/src/WebServer_JSON.ino @@ -90,6 +90,9 @@ void handle_json() const bool showSpecificTask = validTaskIndex(taskNr); bool showSystem = true; bool showWifi = true; + #ifdef HAS_ETHERNET + bool showEthernet = true; + #endif bool showDataAcquisition = true; bool showTaskDetails = true; bool showNodes = true; @@ -100,6 +103,9 @@ void handle_json() if (view == F("sensorupdate")) { showSystem = false; showWifi = false; + #ifdef HAS_ETHERNET + showEthernet = false; + #endif showDataAcquisition = false; showTaskDetails = false; showNodes = false; @@ -174,9 +180,22 @@ void handle_json() #endif // ifdef SUPPORT_ARP stream_next_json_object_value(LabelType::CONNECTION_FAIL_THRESH); stream_last_json_object_value(LabelType::WIFI_RSSI); + // TODO: PKR: Add ETH Objects addHtml(F(",\n")); } + #ifdef HAS_ETHERNET + if (showEthernet) { + addHtml(F("\"Ethernet\":{\n")); + stream_next_json_object_value(LabelType::ETH_WIFI_MODE); + stream_next_json_object_value(LabelType::ETH_CONNECTED); + stream_next_json_object_value(LabelType::ETH_DUPLEX); + stream_next_json_object_value(LabelType::ETH_SPEED); + stream_next_json_object_value(LabelType::ETH_STATE); + stream_last_json_object_value(LabelType::ETH_SPEED_STATE); + } + #endif + if (showNodes) { bool comma_between = false; diff --git a/src/WebServer_RootPage.ino b/src/WebServer_RootPage.ino index 1ddc50d5c..2869dcf25 100644 --- a/src/WebServer_RootPage.ino +++ b/src/WebServer_RootPage.ino @@ -46,8 +46,8 @@ void handle_root() { ExecuteCommand_internal(EventValueSource::Enum::VALUE_SOURCE_HTTP, sCommand.c_str()); } - // IPAddress ip = WiFi.localIP(); - // IPAddress gw = WiFi.gatewayIP(); + // IPAddress ip = NetworkLocalIP(); + // IPAddress gw = NetwrokGatewayIP(); addHtml(printWebString); addHtml(F("
")); @@ -110,7 +110,7 @@ void handle_root() { addRowLabelValue(LabelType::IP_ADDRESS); addRowLabel(getLabel(LabelType::WIFI_RSSI)); - if (WiFiConnected()) + if (NetworkConnected()) { String html; html.reserve(32); @@ -121,6 +121,14 @@ void handle_root() { addHtml(html); } +#ifdef HAS_ETHERNET + addRowLabelValue(LabelType::ETH_WIFI_MODE); + if(eth_wifi_mode == ETHERNET) { + addRowLabelValue(LabelType::ETH_SPEED_STATE); + addRowLabelValue(LabelType::ETH_IP_ADDRESS); + } +#endif + #ifdef FEATURE_MDNS { addRowLabel(getLabel(LabelType::M_DNS)); diff --git a/src/WebServer_SetupPage.ino b/src/WebServer_SetupPage.ino index b7c7b510f..11f2bc513 100644 --- a/src/WebServer_SetupPage.ino +++ b/src/WebServer_SetupPage.ino @@ -14,7 +14,7 @@ void handle_setup() { // Do not check client IP range allowed. TXBuffer.startStream(); - if (!WiFiConnected()) + if (!NetworkConnected()) { sendHeadandTail(F("TmplAP")); static byte status = 0; @@ -188,7 +188,7 @@ void handle_setup_finish() { html_TD(); if (!clientIPinSubnet()) { - String host = formatIP(WiFi.localIP()); + String host = formatIP(NetworkLocalIP()); String url = F("http://"); url += host; url += F("/config"); diff --git a/src/WebServer_SysInfoPage.ino b/src/WebServer_SysInfoPage.ino index 2e9f85796..979507234 100644 --- a/src/WebServer_SysInfoPage.ino +++ b/src/WebServer_SysInfoPage.ino @@ -64,33 +64,33 @@ void handle_sysinfo_json() { } json_number(F("rssi"), String(WiFi.RSSI())); json_prop(F("dhcp"), useStaticIP() ? getLabel(LabelType::IP_CONFIG_STATIC) : getLabel(LabelType::IP_CONFIG_DYNAMIC)); - json_prop(F("ip"), formatIP(WiFi.localIP())); - json_prop(F("subnet"), formatIP(WiFi.subnetMask())); - json_prop(F("gw"), formatIP(WiFi.gatewayIP())); - json_prop(F("dns1"), formatIP(WiFi.dnsIP(0))); - json_prop(F("dns2"), formatIP(WiFi.dnsIP(1))); + json_prop(F("ip"), formatIP(NetworkLocalIP())); + json_prop(F("subnet"), formatIP(NetworkSubnetMask())); + json_prop(F("gw"), formatIP(NetworkGatewayIP())); + json_prop(F("dns1"), formatIP(NetworkDnsIP(0))); + json_prop(F("dns2"), formatIP(NetworkDnsIP(1))); json_prop(F("allowed_range"), describeAllowedIPrange()); - - - uint8_t mac[] = { 0, 0, 0, 0, 0, 0 }; - uint8_t *macread = WiFi.macAddress(mac); - char macaddress[20]; - formatMAC(macread, macaddress); - - json_prop(F("sta_mac"), macaddress); - - macread = WiFi.softAPmacAddress(mac); - formatMAC(macread, macaddress); - - json_prop(F("ap_mac"), macaddress); - json_prop(F("ssid"), WiFi.SSID()); - json_prop(F("bssid"), WiFi.BSSIDstr()); - json_number(F("channel"), String(WiFi.channel())); - json_prop(F("connected"), format_msec_duration(timeDiff(lastConnectMoment, millis()))); - json_prop(F("ldr"), getLastDisconnectReason()); + json_prop(F("sta_mac"), NetworkMacAddress()); + json_prop(F("ap_mac"), WifiSoftAPmacAddress()); + json_prop(F("ssid"), WiFi.SSID()); + json_prop(F("bssid"), WiFi.BSSIDstr()); + json_number(F("channel"), String(WiFi.channel())); + json_prop(F("connected"), format_msec_duration(timeDiff(lastConnectMoment, millis()))); + json_prop(F("ldr"), getLastDisconnectReason()); json_number(F("reconnects"), String(wifi_reconnects)); json_close(); +#ifdef HAS_ETHERNET + json_open(false, F("ethernet")); + json_prop(F("ethwifimode"), getValue(LabelType::ETH_WIFI_MODE)); + json_prop(F("ethconnected"), getValue(LabelType::ETH_CONNECTED); + json_prop(F("ethduplex"), getValue(LabelType::ETH_DUPLEX); + json_prop(F("ethspeed"), getValue(LabelType::ETH_SPEED); + json_prop(F("ethstate"), getValue(LabelType::ETH_STATE); + json_prop(F("ethspeedstate"), getValue(LabelType::ETH_SPEED_STATE); + json.close(); +#endif + json_open(false, F("firmware")); json_prop(F("build"), String(BUILD)); json_prop(F("notes"), F(BUILD_NOTES)); @@ -224,6 +224,10 @@ void handle_sysinfo() { handle_sysinfo_Network(); +#ifdef HAS_ETHERNET + handle_sysinfo_Ethernet(); +#endif + handle_sysinfo_WiFiSettings(); handle_sysinfo_Firmware(); @@ -315,12 +319,36 @@ void handle_sysinfo_basicInfo() { addRowLabelValue(LabelType::RESET_REASON); addRowLabelValue(LabelType::LAST_TASK_BEFORE_REBOOT); addRowLabelValue(LabelType::SW_WD_COUNT); + + #ifdef HAS_ETHERNET + addRowLabel(F("Network Type")); + addRowLabelValue(LabelType::ETH_WIFI_MODE); + #endif } +#ifdef HAS_ETHERNET +void handle_sysinfo_Ethernet() { + if(eth_wifi_mode == ETHERNET) { + addTableSeparator(F("Ethernet"), 2, 3); + addRowLabelValue(LabelType::ETH_STATE); + addRowLabelValue(LabelType::ETH_SPEED); + addRowLabelValue(LabelType::ETH_DUPLEX); + addRowLabelValue(LabelType::ETH_MAC); + addRowLabelValue(LabelType::ETH_IP_ADDRESS_SUBNET); + addRowLabelValue(LabelType::ETH_IP_GATEWAY); + addRowLabelValue(LabelType::ETH_IP_DNS); + } +} +#endif + void handle_sysinfo_Network() { addTableSeparator(F("Network"), 2, 3, F("Wifi")); - if (WiFiConnected()) + if ( + #ifdef HAS_ETHERNET + eth_wifi_mode == WIFI && + #endif + NetworkConnected()) { addRowLabel(F("Wifi")); # if defined(ESP8266) @@ -358,20 +386,8 @@ void handle_sysinfo_Network() { addRowLabelValue(LabelType::CLIENT_IP); addRowLabelValue(LabelType::DNS); addRowLabelValue(LabelType::ALLOWED_IP_RANGE); - addRowLabel(getLabel(LabelType::STA_MAC)); - - { - uint8_t mac[] = { 0, 0, 0, 0, 0, 0 }; - uint8_t *macread = WiFi.macAddress(mac); - char macaddress[20]; - formatMAC(macread, macaddress); - addHtml(macaddress); - - addRowLabel(getLabel(LabelType::AP_MAC)); - macread = WiFi.softAPmacAddress(mac); - formatMAC(macread, macaddress); - addHtml(macaddress); - } + addRowLabelValue(LabelType::STA_MAC); + addRowLabelValue(LabelType::AP_MAC); addRowLabel(getLabel(LabelType::SSID)); { diff --git a/src/WebServer_SysVarPage.ino b/src/WebServer_SysVarPage.ino index c480a2297..f0e70f2e8 100644 --- a/src/WebServer_SysVarPage.ino +++ b/src/WebServer_SysVarPage.ino @@ -44,11 +44,24 @@ void handle_sysvars() { #endif // if defined(ESP8266) addSysVar_enum_html(SystemVariables::IP); addSysVar_enum_html(SystemVariables::IP4); + addSysVar_enum_html(SystemVariables::SUBNET); + addSysVar_enum_html(SystemVariables::GATEWAY); + addSysVar_enum_html(SystemVariables::DNS); addSysVar_enum_html(SystemVariables::RSSI); addSysVar_enum_html(SystemVariables::SSID); addSysVar_enum_html(SystemVariables::BSSID); addSysVar_enum_html(SystemVariables::WI_CH); +#ifdef HAS_ETHERNET + addTableSeparator(F("Ethernet"), 3, 3); + addSysVar_enum_html(SystemVariables::ETHWIFIMODE); + addSysVar_enum_html(SystemVariables::ETHCONNECTED); + addSysVar_enum_html(SystemVariables::ETHDUPLEX); + addSysVar_enum_html(SystemVariables::ETHSPEED); + addSysVar_enum_html(SystemVariables::ETHSTATE); + addSysVar_enum_html(SystemVariables::ETHSPEEDSTATE); + #endif + addTableSeparator(F("System"), 3, 3); addSysVar_enum_html(SystemVariables::UNIT_sysvar); addSysVar_enum_html(SystemVariables::SYSLOAD); diff --git a/src/_C006.ino b/src/_C006.ino index 6cc4fa7f0..453cccf1d 100644 --- a/src/_C006.ino +++ b/src/_C006.ino @@ -87,7 +87,7 @@ bool CPlugin_006(CPlugin::Function function, struct EventStruct *event, String& case CPlugin::Function::CPLUGIN_PROTOCOL_SEND: { - if (!WiFiConnected(10)) { + if (!NetworkConnected(10)) { success = false; break; } diff --git a/src/_C009.ino b/src/_C009.ino index c7a86ad3b..af1f77fd2 100644 --- a/src/_C009.ino +++ b/src/_C009.ino @@ -123,9 +123,9 @@ bool do_process_c009_delay_queue(int controller_number, const C009_queue_element // embed IP, important if there is NAT/PAT // char ipStr[20]; - // IPAddress ip = WiFi.localIP(); + // IPAddress ip = NetworkLocalIP(); // sprintf_P(ipStr, PSTR("%u.%u.%u.%u"), ip[0], ip[1], ip[2], ip[3]); - ESP[F("ip")] = WiFi.localIP().toString(); + ESP[F("ip")] = NetworkLocalIP().toString(); // Create nested SENSOR json object JsonObject SENSOR = data.createNestedObject(String(F("SENSOR"))); diff --git a/src/_C011.ino b/src/_C011.ino index 6beab4c61..080402f5f 100644 --- a/src/_C011.ino +++ b/src/_C011.ino @@ -155,7 +155,7 @@ bool do_process_c011_delay_queue(int controller_number, const C011_queue_element boolean Create_schedule_HTTP_C011(struct EventStruct *event) { int controller_number = CPLUGIN_ID_011; - if (!WiFiConnected(10)) { + if (!NetworkConnected(10)) { return false; } MakeControllerSettings(ControllerSettings); diff --git a/src/_C012.ino b/src/_C012.ino index 00c0c8715..ce1f10439 100644 --- a/src/_C012.ino +++ b/src/_C012.ino @@ -95,7 +95,7 @@ bool do_process_c012_delay_queue(int controller_number, const C012_queue_element if (element.checkDone(true)) return true; } - if (!WiFiConnected()) { + if (!NetworkConnected()) { return false; } return element.checkDone(Blynk_get(element.txt[element.valuesSent], element.controller_idx)); diff --git a/src/_C013.ino b/src/_C013.ino index 2b17d2332..005119814 100644 --- a/src/_C013.ino +++ b/src/_C013.ino @@ -114,7 +114,7 @@ bool CPlugin_013(CPlugin::Function function, struct EventStruct *event, String& // ******************************************************************************** void C013_SendUDPTaskInfo(byte destUnit, byte sourceTaskIndex, byte destTaskIndex) { - if (!WiFiConnected(10)) { + if (!NetworkConnected(10)) { return; } @@ -158,7 +158,7 @@ void C013_SendUDPTaskInfo(byte destUnit, byte sourceTaskIndex, byte destTaskInde void C013_SendUDPTaskData(byte destUnit, byte sourceTaskIndex, byte destTaskIndex) { - if (!WiFiConnected(10)) { + if (!NetworkConnected(10)) { return; } struct C013_SensorDataStruct dataReply; @@ -196,7 +196,7 @@ void C013_SendUDPTaskData(byte destUnit, byte sourceTaskIndex, byte destTaskInde \*********************************************************************************************/ void C013_sendUDP(byte unit, byte *data, byte size) { - if (!WiFiConnected(10)) { + if (!NetworkConnected(10)) { return; } NodesMap::iterator it; diff --git a/src/_C014.ino b/src/_C014.ino index 24a946909..674143c32 100644 --- a/src/_C014.ino +++ b/src/_C014.ino @@ -243,10 +243,10 @@ bool CPlugin_014(CPlugin::Function function, struct EventStruct *event, String& // $localip Device → Controller IP of the device on the local network Yes Yes #ifdef CPLUGIN_014_V3 - CPlugin_014_sendMQTTdevice(pubname,"$localip",formatIP(WiFi.localIP()).c_str(),errorCounter); + CPlugin_014_sendMQTTdevice(pubname,"$localip",formatIP(NetworkLocalIP()).c_str(),errorCounter); // $mac Device → Controller Mac address of the device network interface. The format MUST be of the type A1:B2:C3:D4:E5:F6 Yes Yes - CPlugin_014_sendMQTTdevice(pubname,"$mac",WiFi.macAddress().c_str(),errorCounter); + CPlugin_014_sendMQTTdevice(pubname,"$mac",NetworkMacAddress().c_str(),errorCounter); // $implementation Device → Controller An identifier for the Homie implementation (example esp8266) Yes Yes #if defined(ESP8266) diff --git a/src/_C015.ino b/src/_C015.ino index ed64025a3..7d1ccca0e 100644 --- a/src/_C015.ino +++ b/src/_C015.ino @@ -212,7 +212,7 @@ bool do_process_c015_delay_queue(int controller_plugin_number, const C015_queue_ // controller has been disabled. Answer true to flush queue. return true; - if (!WiFiConnected()) { + if (!NetworkConnected()) { return false; } @@ -231,7 +231,7 @@ bool do_process_c015_delay_queue(int controller_plugin_number, const C015_queue_ boolean Blynk_keep_connection_c015(int controllerIndex, ControllerSettingsStruct& ControllerSettings){ - if (!WiFiConnected()) + if (!NetworkConnected()) return false; if (!Blynk.connected()){ diff --git a/src/_C016.ino b/src/_C016.ino index d700ae3a8..56fb346c7 100644 --- a/src/_C016.ino +++ b/src/_C016.ino @@ -49,7 +49,7 @@ bool CPlugin_016(CPlugin::Function function, struct EventStruct *event, String& Protocol[protocolCount].usesHost = false; Protocol[protocolCount].usesPort = false; Protocol[protocolCount].usesSampleSets = false; - Protocol[protocolCount].needsWiFi = false; + Protocol[protocolCount].needsNetwork = false; break; } diff --git a/src/_C017.ino b/src/_C017.ino index 8e9cf7190..0ba051f5f 100644 --- a/src/_C017.ino +++ b/src/_C017.ino @@ -86,7 +86,7 @@ bool do_process_c017_delay_queue(int controller_number, const C017_queue_element if (valueCount == 0) return true; //exit if we don't have anything to send. - if (!WiFiConnected(10)) + if (!NetworkConnected(10)) { return false; } diff --git a/src/_C018.ino b/src/_C018.ino index 9e49ddc74..18dd98364 100644 --- a/src/_C018.ino +++ b/src/_C018.ino @@ -431,7 +431,7 @@ bool CPlugin_018(CPlugin::Function function, struct EventStruct *event, String& Protocol[protocolCount].usesCheckReply = false; Protocol[protocolCount].usesTimeout = false; Protocol[protocolCount].usesSampleSets = true; - Protocol[protocolCount].needsWiFi = false; + Protocol[protocolCount].needsNetwork = false; break; } diff --git a/src/_CPlugin_Helper.cpp b/src/_CPlugin_Helper.cpp index 43c8d2beb..fc92c2e45 100644 --- a/src/_CPlugin_Helper.cpp +++ b/src/_CPlugin_Helper.cpp @@ -272,7 +272,7 @@ bool count_connection_results(bool success, const String& prefix, int controller bool try_connect_host(int controller_number, WiFiUDP& client, ControllerSettingsStruct& ControllerSettings) { START_TIMER; - if (!WiFiConnected()) { return false; } + if (!NetworkConnected()) { return false; } client.setTimeout(ControllerSettings.ClientTimeout); #ifndef BUILD_NO_DEBUG log_connecting_to(F("UDP : "), controller_number, ControllerSettings); @@ -292,7 +292,7 @@ bool try_connect_host(int controller_number, WiFiClient& client, ControllerSetti bool try_connect_host(int controller_number, WiFiClient& client, ControllerSettingsStruct& ControllerSettings, const String& loglabel) { START_TIMER; - if (!WiFiConnected()) { return false; } + if (!NetworkConnected()) { return false; } // Use WiFiClient class to create TCP connections client.setTimeout(ControllerSettings.ClientTimeout); diff --git a/src/_P026_Sysinfo.ino b/src/_P026_Sysinfo.ino index 33ed4424b..d1f60864b 100644 --- a/src/_P026_Sysinfo.ino +++ b/src/_P026_Sysinfo.ino @@ -212,22 +212,22 @@ float P026_get_value(int type) } case 5: { - value = WiFi.localIP()[0]; + value = NetworkLocalIP()[0]; break; } case 6: { - value = WiFi.localIP()[1]; + value = NetworkLocalIP()[1]; break; } case 7: { - value = WiFi.localIP()[2]; + value = NetworkLocalIP()[2]; break; } case 8: { - value = WiFi.localIP()[3]; + value = NetworkLocalIP()[3]; break; } case 9: diff --git a/src/_P036_FrameOLED.ino b/src/_P036_FrameOLED.ino index 37c59c5a8..c0c90d3a4 100644 --- a/src/_P036_FrameOLED.ino +++ b/src/_P036_FrameOLED.ino @@ -864,7 +864,7 @@ void display_header() { } switch (_HeaderContent) { case eSSID: - if (WiFiConnected()) { + if (NetworkConnected()) { strHeader = WiFi.SSID(); } else { @@ -1341,7 +1341,7 @@ void display_scrolling_lines(int nlines) { //Draw Signal Strength Bars, return true when there was an update. bool display_wifibars() { - const bool connected = WiFiConnected(); + const bool connected = NetworkConnected(); const int nbars_filled = (WiFi.RSSI() + 100) / 12; // all bars filled if RSSI better than -46dB const int newState = connected ? nbars_filled : P36_WIFI_STATE_NOT_CONNECTED; if (newState == lastWiFiState) @@ -1363,7 +1363,7 @@ bool display_wifibars() { display->setColor(BLACK); display->fillRect(x , y, size_x, size_y); display->setColor(WHITE); - if (WiFiConnected()) { + if (NetworkConnected()) { for (uint8_t ibar = 0; ibar < nbars; ibar++) { int16_t height = size_y * (ibar + 1) / nbars; int16_t xpos = x + ibar * width; diff --git a/src/_P037_MQTTImport.ino b/src/_P037_MQTTImport.ino index 594ca60ab..31ffa64f9 100644 --- a/src/_P037_MQTTImport.ino +++ b/src/_P037_MQTTImport.ino @@ -418,7 +418,7 @@ boolean MQTTConnect_037() if (MQTTclient_037->connected()) return true; // define stuff for the client - this could also be done in the intial declaration of MQTTclient_037 - if (!WiFiConnected(100)) { + if (!NetworkConnected(100)) { Plugin_037_update_connect_status(); return false; // Not connected, so no use in wasting time to connect to a host. } diff --git a/src/_P089_Ping.ino b/src/_P089_Ping.ino index 5ad4a6dd5..1273eebc4 100644 --- a/src/_P089_Ping.ino +++ b/src/_P089_Ping.ino @@ -76,7 +76,7 @@ public: is_failure = true; /* This ping lost for sure */ - if (!WiFiConnected()) { + if (!NetworkConnected()) { return true; } diff --git a/src/src/Commands/Common.cpp b/src/src/Commands/Common.cpp index af86da75a..5470ba592 100644 --- a/src/src/Commands/Common.cpp +++ b/src/src/Commands/Common.cpp @@ -153,3 +153,63 @@ String Command_GetORSetBool(struct EventStruct *event, } return return_command_success(); } + +String Command_GetORSetUint8_t(struct EventStruct *event, + const String & targetDescription, + const char *Line, + uint8_t *value, + int arg) +{ + bool hasArgument = false; + { + // Check if command is valid. Leave in separate scope to delete the TmpStr1 + String TmpStr1; + + if (GetArgv(Line, TmpStr1, arg + 1)) { + hasArgument = true; + TmpStr1.toLowerCase(); + + if (isInt(TmpStr1)) { + *value = (uint8_t)atoi(TmpStr1.c_str()); + } + else if (strcmp_P(PSTR("WIFI"), TmpStr1.c_str()) == 0) { *value = 0; } + else if (strcmp_P(PSTR("ETHERNET"), TmpStr1.c_str()) == 0) { *value = 1; } + } + } + + if (hasArgument) { + String result = targetDescription; + result += *value; + return return_result(event, result); + } + return return_command_success(); +} + +String Command_GetORSetInt8_t(struct EventStruct *event, + const String & targetDescription, + const char *Line, + int8_t *value, + int arg) +{ + bool hasArgument = false; + { + // Check if command is valid. Leave in separate scope to delete the TmpStr1 + String TmpStr1; + + if (GetArgv(Line, TmpStr1, arg + 1)) { + hasArgument = true; + TmpStr1.toLowerCase(); + + if (isInt(TmpStr1)) { + *value = (int8_t)atoi(TmpStr1.c_str()); + } + } + } + + if (hasArgument) { + String result = targetDescription; + result += *value; + return return_result(event, result); + } + return return_command_success(); +} diff --git a/src/src/Commands/Common.h b/src/src/Commands/Common.h index 4fc0e86f6..014d870f8 100644 --- a/src/src/Commands/Common.h +++ b/src/src/Commands/Common.h @@ -37,4 +37,16 @@ String Command_GetORSetBool(struct EventStruct *event, bool *value, int arg); +String Command_GetORSetUint8_t(struct EventStruct *event, + const String & targetDescription, + const char *Line, + uint8_t *value, + int arg); + +String Command_GetORSetInt8_t(struct EventStruct *event, + const String & targetDescription, + const char *Line, + int8_t *value, + int arg); + #endif // COMMAND_COMMON_H diff --git a/src/src/Commands/HTTP.cpp b/src/src/Commands/HTTP.cpp index bd69b7394..96abdbcb1 100644 --- a/src/src/Commands/HTTP.cpp +++ b/src/src/Commands/HTTP.cpp @@ -14,7 +14,7 @@ String Command_HTTP_SendToHTTP(struct EventStruct *event, const char* Line) { - if (WiFiConnected()) { + if (NetworkConnected()) { String host = parseString(Line, 2); const int port = parseCommandArgumentInt(Line, 2); if (loglevelActiveFor(LOG_LEVEL_DEBUG)) { diff --git a/src/src/Commands/InternalCommands.cpp b/src/src/Commands/InternalCommands.cpp index 4fadb2e64..590f22e1d 100644 --- a/src/src/Commands/InternalCommands.cpp +++ b/src/src/Commands/InternalCommands.cpp @@ -170,6 +170,19 @@ bool executeInternalCommand(const char *cmd, struct EventStruct *event, const ch break; } case 'e': { + #ifdef HAS_ETHERNET + COMMAND_CASE( "ethphyadr", Command_ETH_Phy_Addr, 1); // Network Command + COMMAND_CASE( "ethpinmdc", Command_ETH_Pin_mdc, 1); // Network Command + COMMAND_CASE( "ethpinmdio", Command_ETH_Pin_mdio, 1); // Network Command + COMMAND_CASE( "ethpinpower", Command_ETH_Pin_power, 1); // Network Command + COMMAND_CASE( "ethphytype", Command_ETH_Phy_Type, 1); // Network Command + COMMAND_CASE("ethclockmode", Command_ETH_Clock_Mode, 1); // Network Command + COMMAND_CASE( "ethip", Command_ETH_IP, 1); // Network Command + COMMAND_CASE( "ethgateway", Command_ETH_Gateway, 1); // Network Command + COMMAND_CASE( "ethsubnet", Command_ETH_Subnet, 1); // Network Command + COMMAND_CASE( "ethdns", Command_ETH_DNS, 1); // Network Command + COMMAND_CASE( "ethwifimode", Command_ETH_Wifi_Mode, 1); // Network Command + #endif // HAS_ETHERNET COMMAND_CASE("erasesdkwifi", Command_WiFi_Erase, 0); // WiFi.h COMMAND_CASE( "event", Command_Rules_Events, -1); // Rule.h COMMAND_CASE("executerules", Command_Rules_Execute, -1); // Rule.h diff --git a/src/src/Commands/Networks.cpp b/src/src/Commands/Networks.cpp index a1c2a36e7..737c756c6 100644 --- a/src/src/Commands/Networks.cpp +++ b/src/src/Commands/Networks.cpp @@ -5,7 +5,9 @@ #include "../Globals/Settings.h" #include "../../ESPEasy_fdwdecl.h" - +#ifdef HAS_ETHERNET +#include "ETH.h" +#endif String Command_AccessInfo_Ls(struct EventStruct *event, const char* Line) { @@ -38,4 +40,62 @@ String Command_IP (struct EventStruct *event, const char* Line) String Command_Subnet (struct EventStruct *event, const char* Line) { return Command_GetORSetIP(event, F("Subnet:"), Line, Settings.Subnet,WiFi.subnetMask(),1); -} \ No newline at end of file +} + +#ifdef HAS_ETHERNET +String Command_ETH_Phy_Addr (struct EventStruct *event, const char* Line) +{ + return Command_GetORSetUint8_t(event, F("ETH_Phy_Addr:"), Line, (uint8_t*)&Settings.ETH_Phy_Addr,1); +} + +String Command_ETH_Pin_mdc (struct EventStruct *event, const char* Line) +{ + return Command_GetORSetInt8_t(event, F("ETH_Pin_mdc:"), Line, (int8_t*)&Settings.ETH_Pin_mdc,1); +} + +String Command_ETH_Pin_mdio (struct EventStruct *event, const char* Line) +{ + return Command_GetORSetInt8_t(event, F("ETH_Pin_mdio:"), Line, (int8_t*)&Settings.ETH_Pin_mdio,1); +} + +String Command_ETH_Pin_power (struct EventStruct *event, const char* Line) +{ + return Command_GetORSetInt8_t(event, F("ETH_Pin_power:"), Line, (int8_t*)&Settings.ETH_Pin_power,1); +} + +String Command_ETH_Phy_Type (struct EventStruct *event, const char* Line) +{ + return Command_GetORSetInt8_t(event, F("ETH_Phy_Type:"), Line, (int8_t*)&Settings.ETH_Phy_Type,1); +} + +String Command_ETH_Clock_Mode (struct EventStruct *event, const char* Line) +{ + return Command_GetORSetUint8_t(event, F("ETH_Clock_Mode:"), Line, (uint8_t*)&Settings.ETH_Clock_Mode,1); +} + +String Command_ETH_IP (struct EventStruct *event, const char* Line) +{ + return Command_GetORSetIP(event, F("ETH_IP:"), Line, Settings.ETH_IP,ETH.localIP(),1); +} + +String Command_ETH_Gateway (struct EventStruct *event, const char* Line) +{ + return Command_GetORSetIP(event, F("ETH_Gateway:"), Line, Settings.ETH_Gateway,ETH.gatewayIP(),1); +} + +String Command_ETH_Subnet (struct EventStruct *event, const char* Line) +{ + return Command_GetORSetIP(event, F("ETH_Subnet:"), Line, Settings.ETH_Subnet,ETH.subnetMask(),1); +} + +String Command_ETH_DNS (struct EventStruct *event, const char* Line) +{ + return Command_GetORSetIP(event, F("ETH_DNS:"), Line, Settings.ETH_DNS,ETH.dnsIP(),1); +} + +String Command_ETH_Wifi_Mode (struct EventStruct *event, const char* Line) +{ + return Command_GetORSetUint8_t(event, F("ETH_Wifi_Mode:"), Line, (uint8_t*)&Settings.ETH_Wifi_Mode,1); +} + +#endif \ No newline at end of file diff --git a/src/src/Commands/Networks.h b/src/src/Commands/Networks.h index 4a55c7676..1b6745f52 100644 --- a/src/src/Commands/Networks.h +++ b/src/src/Commands/Networks.h @@ -10,5 +10,16 @@ String Command_DNS (struct EventStruct *event, const char* Line); String Command_Gateway (struct EventStruct *event, const char* Line); String Command_IP (struct EventStruct *event, const char* Line); String Command_Subnet (struct EventStruct *event, const char* Line); +String Command_ETH_Phy_Addr (struct EventStruct *event, const char* Line); +String Command_ETH_Pin_mdc (struct EventStruct *event, const char* Line); +String Command_ETH_Pin_mdio (struct EventStruct *event, const char* Line); +String Command_ETH_Pin_power (struct EventStruct *event, const char* Line); +String Command_ETH_Phy_Type (struct EventStruct *event, const char* Line); +String Command_ETH_Clock_Mode (struct EventStruct *event, const char* Line); +String Command_ETH_IP (struct EventStruct *event, const char* Line); +String Command_ETH_Gateway (struct EventStruct *event, const char* Line); +String Command_ETH_Subnet (struct EventStruct *event, const char* Line); +String Command_ETH_DNS (struct EventStruct *event, const char* Line); +String Command_ETH_Wifi_Mode (struct EventStruct *event, const char* Line); #endif // COMMAND_NETWORKS_H diff --git a/src/src/Commands/Settings.cpp b/src/src/Commands/Settings.cpp index 00637baab..23022d996 100644 --- a/src/src/Commands/Settings.cpp +++ b/src/src/Commands/Settings.cpp @@ -71,7 +71,7 @@ String Command_Settings_Print(struct EventStruct *event, const char* Line) serialPrintln(); serialPrintln(F("System Info")); - serialPrint(F(" IP Address : ")); serialPrintln(WiFi.localIP().toString()); + serialPrint(F(" IP Address : ")); serialPrintln(NetworkLocalIP().toString()); serialPrint(F(" Build : ")); serialPrintln(String((int)BUILD)); serialPrint(F(" Name : ")); serialPrintln(Settings.Name); serialPrint(F(" Unit : ")); serialPrintln(String((int)Settings.Unit)); diff --git a/src/src/Commands/UDP.cpp b/src/src/Commands/UDP.cpp index 252386c23..09c58e11c 100644 --- a/src/src/Commands/UDP.cpp +++ b/src/src/Commands/UDP.cpp @@ -39,7 +39,7 @@ String Command_UPD_SendTo(struct EventStruct *event, const char *Line) String Command_UDP_SendToUPD(struct EventStruct *event, const char *Line) { - if (WiFiConnected()) { + if (NetworkConnected()) { String ip = parseString(Line, 2); int port = parseCommandArgumentInt(Line, 2); diff --git a/src/src/ControllerQueue/ControllerDelayHandlerStruct.h b/src/src/ControllerQueue/ControllerDelayHandlerStruct.h index 79b76de5f..20095a336 100644 --- a/src/src/ControllerQueue/ControllerDelayHandlerStruct.h +++ b/src/src/ControllerQueue/ControllerDelayHandlerStruct.h @@ -48,8 +48,8 @@ struct ControllerDelayHandlerStruct { if (protocolIndex == INVALID_PROTOCOL_INDEX) { return false; } - if (Protocol[protocolIndex].needsWiFi) { - return WiFiConnected(10); + if (Protocol[protocolIndex].needsNetwork) { + return NetworkConnected(10); } return true; } diff --git a/src/src/DataStructs/ControllerSettingsStruct.cpp b/src/src/DataStructs/ControllerSettingsStruct.cpp index 509b113b9..af5c88ceb 100644 --- a/src/src/DataStructs/ControllerSettingsStruct.cpp +++ b/src/src/DataStructs/ControllerSettingsStruct.cpp @@ -85,7 +85,7 @@ void ControllerSettingsStruct::setHostname(const String& controllerhostname) { } boolean ControllerSettingsStruct::checkHostReachable(bool quick) { - if (!WiFiConnected(10)) { + if (!NetworkConnected(10)) { return false; // Not connected, so no use in wasting time to connect to a host. } delay(1); // Make sure the Watchdog will not trigger a reset. @@ -166,7 +166,7 @@ bool ControllerSettingsStruct::updateIPcache() { return true; } - if (!WiFiConnected()) { return false; } + if (!NetworkConnected()) { return false; } IPAddress tmpIP; if (resolveHostByName(HostName, tmpIP)) { diff --git a/src/src/DataStructs/DeviceModel.h b/src/src/DataStructs/DeviceModel.h index 148308c27..1c89795ef 100644 --- a/src/src/DataStructs/DeviceModel.h +++ b/src/src/DataStructs/DeviceModel.h @@ -19,6 +19,7 @@ enum DeviceModel { DeviceModel_Sonoff_POWr2, DeviceModel_Shelly1, DeviceModel_ShellyPLUG_S, + DeviceMode_Olimex_ESP32_PoE, DeviceModel_MAX }; diff --git a/src/src/DataStructs/ESPEasyDefaults.h b/src/src/DataStructs/ESPEasyDefaults.h index 860ae4113..8bf9fcf67 100644 --- a/src/src/DataStructs/ESPEasyDefaults.h +++ b/src/src/DataStructs/ESPEasyDefaults.h @@ -171,6 +171,30 @@ #ifndef DEFAULT_PIN_RESET_BUTTON #define DEFAULT_PIN_RESET_BUTTON (-1) #endif +#ifndef DEFAULT_ETH_PHY_ADDR +#define DEFAULT_ETH_PHY_ADDR 0 +#endif +#ifndef DEFAULT_ETH_PHY_TYPE +#define DEFAULT_ETH_PHY_TYPE 0 +#endif +#ifndef DEFAULT_ETH_PIN_MDC +#define DEFAULT_ETH_PIN_MDC 23 +#endif +#ifndef DEFAULT_ETH_PIN_MDIO +#define DEFAULT_ETH_PIN_MDIO 18 +#endif +#ifndef DEFAULT_ETH_PIN_POWER +#define DEFAULT_ETH_PIN_POWER -1 +#endif +#ifndef DEFAULT_ETH_CLOCK_MODE +#define DEFAULT_ETH_CLOCK_MODE 0 +#endif +#ifndef DEFAULT_ETH_WIFI_MODE +#define DEFAULT_ETH_WIFI_MODE 0 + // 0 WIFI + // 1 ETHERNET +#endif + // --- Advanced Settings --------------------------------------------------------------------------------- diff --git a/src/src/DataStructs/ProtocolStruct.cpp b/src/src/DataStructs/ProtocolStruct.cpp index 7dd95a7cf..107081225 100644 --- a/src/src/DataStructs/ProtocolStruct.cpp +++ b/src/src/DataStructs/ProtocolStruct.cpp @@ -4,7 +4,7 @@ ProtocolStruct::ProtocolStruct() : defaultPort(0), Number(0), usesMQTT(false), usesAccount(false), usesPassword(false), usesTemplate(false), usesID(false), Custom(false), usesHost(true), usesPort(true), usesQueue(true), usesCheckReply(true), usesTimeout(true), usesSampleSets(false), - usesExtCreds(false), needsWiFi(true) {} + usesExtCreds(false), needsNetwork(true) {} bool ProtocolStruct::useExtendedCredentials() const { diff --git a/src/src/DataStructs/ProtocolStruct.h b/src/src/DataStructs/ProtocolStruct.h index cdfb70943..3277d69fd 100644 --- a/src/src/DataStructs/ProtocolStruct.h +++ b/src/src/DataStructs/ProtocolStruct.h @@ -28,7 +28,7 @@ struct ProtocolStruct bool usesTimeout : 1; bool usesSampleSets : 1; bool usesExtCreds : 1; - bool needsWiFi : 1; + bool needsNetwork : 1; }; typedef std::vector ProtocolVector; diff --git a/src/src/DataStructs/SettingsStruct.cpp b/src/src/DataStructs/SettingsStruct.cpp index df02916ce..1c1df4ebe 100644 --- a/src/src/DataStructs/SettingsStruct.cpp +++ b/src/src/DataStructs/SettingsStruct.cpp @@ -140,6 +140,10 @@ void SettingsStruct_tmpl::clearNetworkSettings() { Gateway[i] = 0; Subnet[i] = 0; DNS[i] = 0; + ETH_IP[i] = 0; + ETH_Gateway[i] = 0; + ETH_Subnet[i] = 0; + ETH_DNS[i] = 0; } } @@ -207,6 +211,13 @@ void SettingsStruct_tmpl::clearMisc() { Pin_i2c_scl = -1; Pin_status_led = -1; Pin_sd_cs = -1; + ETH_Phy_Addr = 0; + ETH_Pin_mdc = -1; + ETH_Pin_mdio = -1; + ETH_Pin_power = -1; + ETH_Phy_Type = 0; + ETH_Clock_Mode = 0; + ETH_Wifi_Mode = 0; for (byte i = 0; i < 17; ++i) { PinBootStates[i] = 0; } BaudRate = 0; diff --git a/src/src/DataStructs/SettingsStruct.h b/src/src/DataStructs/SettingsStruct.h index 190b223a9..07e13b998 100644 --- a/src/src/DataStructs/SettingsStruct.h +++ b/src/src/DataStructs/SettingsStruct.h @@ -183,6 +183,17 @@ class SettingsStruct_tmpl // Try to extend settings to make the checksum 4-byte aligned. // uint8_t ProgmemMd5[16]; // crc of the binary that last saved the struct to file. // uint8_t md5[16]; + uint8_t ETH_Phy_Addr; + int8_t ETH_Pin_mdc; + int8_t ETH_Pin_mdio; + int8_t ETH_Pin_power; + int8_t ETH_Phy_Type; + uint8_t ETH_Clock_Mode; + byte ETH_IP[4]; + byte ETH_Gateway[4]; + byte ETH_Subnet[4]; + byte ETH_DNS[4]; + uint8_t ETH_Wifi_Mode; }; /* diff --git a/src/src/Helpers/ESPEasy_time.cpp b/src/src/Helpers/ESPEasy_time.cpp index c9c4bab43..3b71877da 100644 --- a/src/src/Helpers/ESPEasy_time.cpp +++ b/src/src/Helpers/ESPEasy_time.cpp @@ -223,7 +223,7 @@ bool ESPEasy_time::systemTimePresent() const { bool ESPEasy_time::getNtpTime(double& unixTime_d) { - if (!Settings.UseNTP || !WiFiConnected(10)) { + if (!Settings.UseNTP || !NetworkConnected(10)) { return false; } IPAddress timeServerIP; diff --git a/src/src/Helpers/SystemVariables.cpp b/src/src/Helpers/SystemVariables.cpp index 9c96988af..9967a82b2 100644 --- a/src/src/Helpers/SystemVariables.cpp +++ b/src/src/Helpers/SystemVariables.cpp @@ -73,7 +73,11 @@ void SystemVariables::parseSystemVariables(String& s, boolean useURLencode) case BSSID: value = String((wifiStatus == ESPEASY_WIFI_DISCONNECTED) ? F("00:00:00:00:00:00") : WiFi.BSSIDstr()); break; case CR: value = "\r"; break; case IP: value = getValue(LabelType::IP_ADDRESS); break; - case IP4: value = String( (int) WiFi.localIP()[3] ); break; // 4th IP octet + case IP4: value = String( (int) NetworkLocalIP()[3] ); break; // 4th IP octet + case SUBNET: value = getValue(LabelType::IP_SUBNET); break; + case DNS: value = getValue(LabelType::DNS); break; + case GATEWAY: value = getValue(LabelType::GATEWAY); break; + case CLIENTIP: value = getValue(LabelType::CLIENT_IP); break; #ifdef USES_MQTT case ISMQTT: value = String(MQTTclient_connected); break; #else // ifdef USES_MQTT @@ -89,6 +93,16 @@ void SystemVariables::parseSystemVariables(String& s, boolean useURLencode) case ISNTP: value = String(statusNTPInitialized); break; case ISWIFI: value = String(wifiStatus); break; // 0=disconnected, 1=connected, 2=got ip, 3=services initialized + // TODO: PKR: Add ETH Objects + #ifdef HAS_ETHERNET + + case ETHWIFIMODE: value = getValue(LabelType::ETH_WIFI_MODE); break; // 0=WIFI, 1=ETH + case ETHCONNECTED: value = getValue(LabelType::ETH_CONNECTED); break; // 0=disconnected, 1=connected + case ETHDUPLEX: value = getValue(LabelType::ETH_DUPLEX); break; + case ETHSPEED: value = getValue(LabelType::ETH_SPEED); break; + case ETHSTATE: value = getValue(LabelType::ETH_STATE); break; + case ETHSPEEDSTATE: value = getValue(LabelType::ETH_SPEED_STATE); break; + #endif case LCLTIME: value = getValue(LabelType::LOCAL_TIME); break; case LCLTIME_AM: value = node_time.getDateTimeString_ampm('-', ':', ' '); break; case LF: value = "\n"; break; @@ -239,10 +253,22 @@ String SystemVariables::toString(SystemVariables::Enum enumval) case Enum::CR: return F("%CR%"); case Enum::IP4: return F("%ip4%"); case Enum::IP: return F("%ip%"); + case Enum::SUBNET: return F("%subnet%"); + case Enum::DNS: return F("%dns%"); + case Enum::GATEWAY: return F("%gateway%"); + case Enum::CLIENTIP: return F("%clientip%"); case Enum::ISMQTT: return F("%ismqtt%"); case Enum::ISMQTTIMP: return F("%ismqttimp%"); case Enum::ISNTP: return F("%isntp%"); case Enum::ISWIFI: return F("%iswifi%"); + #ifdef HAS_ETHERNET + case Enum::ETHWIFIMODE: return F("%ethwifimode%"); + case Enum::ETHCONNECTED: return F("%ethconnected%"); + case Enum::ETHDUPLEX: return F("%ethduplex%"); + case Enum::ETHSPEED: return F("%ethspeed%"); + case Enum::ETHSTATE: return F("%ethstate%"); + case Enum::ETHSPEEDSTATE: return F("%ethspeedstate%"); + #endif case Enum::LCLTIME: return F("%lcltime%"); case Enum::LCLTIME_AM: return F("%lcltime_am%"); case Enum::LF: return F("%LF%"); diff --git a/src/src/Helpers/SystemVariables.h b/src/src/Helpers/SystemVariables.h index 67421791b..d44920ce7 100644 --- a/src/src/Helpers/SystemVariables.h +++ b/src/src/Helpers/SystemVariables.h @@ -13,10 +13,22 @@ public: CR, IP, IP4, // 4th IP octet + SUBNET, + GATEWAY, + DNS, + CLIENTIP, ISMQTT, ISMQTTIMP, ISNTP, ISWIFI, + #ifdef HAS_ETHERNET + ETHWIFIMODE, + ETHCONNECTED, + ETHDUPLEX, + ETHSPEED, + ETHSTATE, + ETHSPEEDSTATE, + #endif LCLTIME, LCLTIME_AM, LF, diff --git a/tools/pio/pre_custom_esp32.py b/tools/pio/pre_custom_esp32.py index 72c301729..7f6b4ed02 100644 --- a/tools/pio/pre_custom_esp32.py +++ b/tools/pio/pre_custom_esp32.py @@ -38,7 +38,8 @@ else: "USES_P087", # Serial Proxy "USES_P097", # Touch (ESP32) - "USE_SETTINGS_ARCHIVE" + "USE_SETTINGS_ARCHIVE", + "FEATURE_ARDUINO_OTA" ]) print(env['CPPDEFINES'])