From a44a5833cae9f1c49134e72a315e892844693d43 Mon Sep 17 00:00:00 2001 From: lumapu Date: Tue, 19 Mar 2024 00:15:10 +0100 Subject: [PATCH 01/21] * made ethernet pinout configurable * combined common network functions into class * seperated wifi station from AP mode --- src/config/settings.h | 48 ++++- src/eth/ahoyeth.cpp | 2 +- src/network/AhoyEthernet.h | 82 ++++++++ .../ethSpi.h => network/AhoyEthernetSpi.h} | 8 +- src/network/AhoyNetwork.h | 194 ++++++++++++++++++ src/network/AhoyNetworkHelper.h | 29 +++ src/network/AhoyWifiAp.h | 70 +++++++ src/web/RestApi.h | 14 ++ src/web/html/setup.html | 64 +++++- src/web/lang.json | 5 + src/web/web.h | 47 ++++- src/wifi/ahoywifi.h | 2 +- 12 files changed, 540 insertions(+), 25 deletions(-) create mode 100644 src/network/AhoyEthernet.h rename src/{eth/ethSpi.h => network/AhoyEthernetSpi.h} (96%) create mode 100644 src/network/AhoyNetwork.h create mode 100644 src/network/AhoyNetworkHelper.h create mode 100644 src/network/AhoyWifiAp.h diff --git a/src/config/settings.h b/src/config/settings.h index fe0053a9..f130434c 100644 --- a/src/config/settings.h +++ b/src/config/settings.h @@ -63,6 +63,19 @@ typedef struct { uint8_t gateway[4]; // standard gateway } cfgIp_t; + +#if defined(ETHERNET) +typedef struct { + bool enabled; + uint8_t pinCs; + uint8_t pinSclk; + uint8_t pinMiso; + uint8_t pinMosi; + uint8_t pinIrq; + uint8_t pinRst; +} cfgEth_t; +#endif + typedef struct { char deviceName[DEVNAME_LEN]; char adminPwd[PWD_LEN]; @@ -72,15 +85,16 @@ typedef struct { uint8_t region; int8_t timezone; + char apPwd[PWD_LEN]; #if !defined(ETHERNET) // wifi char stationSsid[SSID_LEN]; char stationPwd[PWD_LEN]; - char apPwd[PWD_LEN]; bool isHidden; #endif /* !defined(ETHERNET) */ cfgIp_t ip; + cfgEth_t eth; } cfgSys_t; typedef struct { @@ -393,7 +407,17 @@ class settings { snprintf(mCfg.sys.apPwd, PWD_LEN, WIFI_AP_PWD); mCfg.sys.isHidden = false; } - #endif /* !defined(ETHERNET) */ + #endif + + #if defined(ETHERNET) + mCfg.sys.eth.enabled = false; + mCfg.sys.eth.pinCs = DEF_ETH_CS_PIN; + mCfg.sys.eth.pinSclk = DEF_ETH_SCK_PIN; + mCfg.sys.eth.pinMiso = DEF_ETH_MISO_PIN; + mCfg.sys.eth.pinMosi = DEF_ETH_MOSI_PIN; + mCfg.sys.eth.pinIrq = DEF_ETH_IRQ_PIN; + mCfg.sys.eth.pinRst = DEF_ETH_RST_PIN; + #endif snprintf(mCfg.sys.deviceName, DEVNAME_LEN, DEF_DEVICE_NAME); mCfg.sys.region = 0; // Europe @@ -544,6 +568,16 @@ class settings { ah::ip2Char(mCfg.sys.ip.dns1, buf); obj[F("dns1")] = String(buf); ah::ip2Char(mCfg.sys.ip.dns2, buf); obj[F("dns2")] = String(buf); ah::ip2Char(mCfg.sys.ip.gateway, buf); obj[F("gtwy")] = String(buf); + + #if defined(ETHERNET) + obj[F("en")] = mCfg.sys.eth.enabled; + obj[F("cs")] = mCfg.sys.eth.pinCs; + obj[F("sclk")] = mCfg.sys.eth.pinSclk; + obj[F("miso")] = mCfg.sys.eth.pinMiso; + obj[F("mosi")] = mCfg.sys.eth.pinMosi; + obj[F("irq")] = mCfg.sys.eth.pinIrq; + obj[F("rst")] = mCfg.sys.eth.pinRst; + #endif } else { #if !defined(ETHERNET) getChar(obj, F("ssid"), mCfg.sys.stationSsid, SSID_LEN); @@ -567,6 +601,16 @@ class settings { if(mCfg.sys.protectionMask == 0) mCfg.sys.protectionMask = DEF_PROT_INDEX | DEF_PROT_LIVE | DEF_PROT_SERIAL | DEF_PROT_SETUP | DEF_PROT_UPDATE | DEF_PROT_SYSTEM | DEF_PROT_API | DEF_PROT_MQTT | DEF_PROT_HISTORY; + + #if defined(ETHERNET) + getVal(obj, F("en"), &mCfg.sys.eth.enabled); + getVal(obj, F("cs"), &mCfg.sys.eth.pinCs); + getVal(obj, F("sclk"), &mCfg.sys.eth.pinSclk); + getVal(obj, F("miso"), &mCfg.sys.eth.pinMiso); + getVal(obj, F("mosi"), &mCfg.sys.eth.pinMosi); + getVal(obj, F("irq"), &mCfg.sys.eth.pinIrq); + getVal(obj, F("rst"), &mCfg.sys.eth.pinRst); + #endif } } diff --git a/src/eth/ahoyeth.cpp b/src/eth/ahoyeth.cpp index 83f0aef0..497a542f 100644 --- a/src/eth/ahoyeth.cpp +++ b/src/eth/ahoyeth.cpp @@ -31,7 +31,7 @@ void ahoyeth::setup(settings_t *config, uint32_t *utcTimestamp, OnNetworkCB onNe WiFi.onEvent([this](WiFiEvent_t event, arduino_event_info_t info) -> void { this->onEthernetEvent(event, info); }); Serial.flush(); - mEthSpi.begin(DEF_ETH_MISO_PIN, DEF_ETH_MOSI_PIN, DEF_ETH_SCK_PIN, DEF_ETH_CS_PIN, DEF_ETH_IRQ_PIN, DEF_ETH_RST_PIN); + mEthSpi.begin(config->sys.eth.pinMiso, config->sys.eth.pinMosi, config->sys.eth.pinSclk, config->sys.eth.pinCs, config->sys.eth.pinIrq, config->sys.eth.pinRst); if(mConfig->sys.ip.ip[0] != 0) { IPAddress ip(mConfig->sys.ip.ip); diff --git a/src/network/AhoyEthernet.h b/src/network/AhoyEthernet.h new file mode 100644 index 00000000..c56b4338 --- /dev/null +++ b/src/network/AhoyEthernet.h @@ -0,0 +1,82 @@ +//----------------------------------------------------------------------------- +// 2024 Ahoy, https://ahoydtu.de +// Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed +//----------------------------------------------------------------------------- + +#ifndef __AHOY_ETHERNET_H__ +#define __AHOY_ETHERNET_H__ + +#include +#include +#include +#include "AhoyEthernetSpi.h" +#include "AhoyEthernet.h" + +class AhoyEthernet : public AhoyNetwork { + public: + void begin() override { + setupIp([this](IPAddress ip, IPAddress gateway, IPAddress mask, IPAddress dns1, IPAddress dns2) -> bool { + return ETH.config(ip, gateway, mask, dns1, dns2); + }); + } + + void tickNetworkLoop() override { + switch(mState) { + case NetworkState::DISCONNECTED: + break; + } + } + + private: + + /*switch (event) { + case ARDUINO_EVENT_ETH_START: + DPRINTLN(DBG_VERBOSE, F("ETH Started")); + + if(String(mConfig->sys.deviceName) != "") + ETH.setHostname(mConfig->sys.deviceName); + else + ETH.setHostname(F("ESP32_W5500")); + break; + + case ARDUINO_EVENT_ETH_CONNECTED: + DPRINTLN(DBG_VERBOSE, F("ETH Connected")); + break; + + case ARDUINO_EVENT_ETH_GOT_IP: + if (!mEthConnected) { + welcome(ETH.localIP().toString(), F(" (Station)")); + + mEthConnected = true; + mOnNetworkCB(true); + } + + if (!MDNS.begin(mConfig->sys.deviceName)) { + DPRINTLN(DBG_ERROR, F("Error setting up MDNS responder!")); + } else { + DBGPRINT(F("mDNS established: ")); + DBGPRINT(mConfig->sys.deviceName); + DBGPRINTLN(F(".local")); + } + break; + + case ARDUINO_EVENT_ETH_DISCONNECTED: + DPRINTLN(DBG_INFO, F("ETH Disconnected")); + mEthConnected = false; + mUdp.close(); + mOnNetworkCB(false); + break; + + case ARDUINO_EVENT_ETH_STOP: + DPRINTLN(DBG_INFO, F("ETH Stopped")); + mEthConnected = false; + mUdp.close(); + mOnNetworkCB(false); + break; + + default: + break; + }*/ +}; + +#endif /*__AHOY_ETHERNET_H__*/ diff --git a/src/eth/ethSpi.h b/src/network/AhoyEthernetSpi.h similarity index 96% rename from src/eth/ethSpi.h rename to src/network/AhoyEthernetSpi.h index 1339c8ec..12e58e4d 100644 --- a/src/eth/ethSpi.h +++ b/src/network/AhoyEthernetSpi.h @@ -1,6 +1,6 @@ //----------------------------------------------------------------------------- -// 2024 Ahoy, https://www.mikrocontroller.net/topic/525778 -// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/ +// 2024 Ahoy, https://ahoydtu.de +// Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed //----------------------------------------------------------------------------- #if defined(ETHERNET) @@ -18,10 +18,10 @@ void tcpipInit(); void add_esp_interface_netif(esp_interface_t interface, esp_netif_t* esp_netif); -class EthSpi { +class AhoyEthernetSpi { public: - EthSpi() : + AhoyEthernetSpi() : eth_handle(nullptr), eth_netif(nullptr) {} diff --git a/src/network/AhoyNetwork.h b/src/network/AhoyNetwork.h new file mode 100644 index 00000000..01d7cd8c --- /dev/null +++ b/src/network/AhoyNetwork.h @@ -0,0 +1,194 @@ +//----------------------------------------------------------------------------- +// 2024 Ahoy, https://ahoydtu.de +// Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed +//----------------------------------------------------------------------------- + +#ifndef __AHOY_NETWORK_H__ +#define __AHOY_NETWORK_H__ + +#include "AhoyNetworkHelper.h" +#include +#include "../config/settings.h" +#include "../utils/helper.h" + +#if defined(ESP32) +#include +#else +#include +#endif + +#define NTP_PACKET_SIZE 48 + +class AhoyNetwork { + public: + typedef std::function OnNetworkCB; + typedef std::function OnTimeCB; + + public: + void setup(settings_t *config, uint32_t *utcTimestamp, OnNetworkCB onNetworkCB, OnTimeCB onTimeCB) { + mConfig = config; + mUtcTimestamp = utcTimestamp; + mOnNetworkCB = onNetworkCB; + mOnTimeCB = onTimeCB; + + #if defined(ESP32) + WiFi.onEvent([this](WiFiEvent_t event) -> void { + this->OnEvent(event); + }); + #else + wifiConnectHandler = WiFi.onStationModeConnected( + [this](const WiFiEventStationModeConnected& event) -> void { + OnEvent(SYSTEM_EVENT_STA_CONNECTED); + }); + wifiGotIPHandler = WiFi.onStationModeGotIP( + [this](const WiFiEventStationModeGotIP& event) -> void { + OnEvent(SYSTEM_EVENT_STA_GOT_IP); + }); + wifiDisconnectHandler = WiFi.onStationModeDisconnected( + [this](const WiFiEventStationModeDisconnected& event) -> void { + OnEvent(SYSTEM_EVENT_STA_DISCONNECTED); + }); + #endif + } + + bool isConnected() const { + return (mStatus == NetworkState.CONNECTED); + } + + bool updateNtpTime(void) { + if(CONNECTED != mStatus) + return; + + if (!mUdp.connected()) { + IPAddress timeServer; + if (!WiFi.hostByName(mConfig->ntp.addr, timeServer)) + return false; + if (!mUdp.connect(timeServer, mConfig->ntp.port)) + return false; + } + + mUdp.onPacket([this](AsyncUDPPacket packet) { + this->handleNTPPacket(packet); + }); + sendNTPpacket(timeServer); + + return true; + } + + public: + virtual void begin() = 0; + virtual void tickNetworkLoop() = 0; + virtual void connectionEvent(WiFiStatus_t status) = 0; + + protected: + void setupIp(void) { + if(mConfig->sys.ip.ip[0] != 0) { + IPAddress ip(mConfig->sys.ip.ip); + IPAddress mask(mConfig->sys.ip.mask); + IPAddress dns1(mConfig->sys.ip.dns1); + IPAddress dns2(mConfig->sys.ip.dns2); + IPAddress gateway(mConfig->sys.ip.gateway); + if(!ETH.config(ip, gateway, mask, dns1, dns2)) + DPRINTLN(DBG_ERROR, F("failed to set static IP!")); + } + } + + void OnEvent(WiFiEvent_t event) { + switch(event) { + case SYSTEM_EVENT_STA_CONNECTED: + [[fallthrough]]; + case ARDUINO_EVENT_ETH_CONNECTED: + if(NetworkState::CONNECTED != mStatus) { + mStatus = NetworkState::CONNECTED; + DPRINTLN(DBG_INFO, F("Network connected")); + } + break; + + case SYSTEM_EVENT_STA_GOT_IP: + [[fallthrough]]; + case ARDUINO_EVENT_ETH_GOT_IP: + mStatus = NetworkState::GOT_IP; + break; + + case ARDUINO_EVENT_WIFI_STA_LOST_IP: + [[fallthrough]]; + case ARDUINO_EVENT_WIFI_STA_STOP: + [[fallthrough]]; + case SYSTEM_EVENT_STA_DISCONNECTED: + [[fallthrough]]; + case ARDUINO_EVENT_ETH_STOP: + [[fallthrough]]; + case ARDUINO_EVENT_ETH_DISCONNECTED: + mStatus = NetworkState::DISCONNECTED; + break; + + default: + break; + } + } + + private: + void sendNTPpacket(IPAddress& address) { + //DPRINTLN(DBG_VERBOSE, F("wifi::sendNTPpacket")); + uint8_t buf[NTP_PACKET_SIZE]; + memset(buf, 0, NTP_PACKET_SIZE); + + buf[0] = 0b11100011; // LI, Version, Mode + buf[1] = 0; // Stratum + buf[2] = 6; // Max Interval between messages in seconds + buf[3] = 0xEC; // Clock Precision + // bytes 4 - 11 are for Root Delay and Dispersion and were set to 0 by memset + buf[12] = 49; // four-byte reference ID identifying + buf[13] = 0x4E; + buf[14] = 49; + buf[15] = 52; + + //mUdp.beginPacket(address, 123); // NTP request, port 123 + mUdp.write(buf, NTP_PACKET_SIZE); + //mUdp.endPacket(); + } + + void handleNTPPacket(AsyncUDPPacket packet) { + char buf[80]; + + memcpy(buf, packet.data(), sizeof(buf)); + + unsigned long highWord = word(buf[40], buf[41]); + unsigned long lowWord = word(buf[42], buf[43]); + + // combine the four bytes (two words) into a long integer + // this is NTP time (seconds since Jan 1 1900): + unsigned long secsSince1900 = highWord << 16 | lowWord; + + *mUtcTimestamp = secsSince1900 - 2208988800UL; // UTC time + DPRINTLN(DBG_INFO, "[NTP]: " + ah::getDateTimeStr(*mUtcTimestamp) + " UTC"); + mOnTimeCB(true); + mUdp.close(); + } + + protected: + enum class NetworkState : uint8_t { + DISCONNECTED, + CONNECTING, + CONNECTED, + IN_AP_MODE, + GOT_IP, + IN_STA_MODE, + RESET, + SCAN_READY + }; + + protected: + settings_t *mConfig = nullptr; + uint32_t *mUtcTimestamp = nullptr; + + OnNetworkCB mOnNetworkCB; + OnTimeCB mOnTimeCB; + + NetworkState mStatus = NetworkState.DISCONNECTED; + + WiFiUDP mUdp; // for time server + DNSServer mDns; +}; + +#endif /*__AHOY_NETWORK_H__*/ diff --git a/src/network/AhoyNetworkHelper.h b/src/network/AhoyNetworkHelper.h new file mode 100644 index 00000000..ab23f5bc --- /dev/null +++ b/src/network/AhoyNetworkHelper.h @@ -0,0 +1,29 @@ +//----------------------------------------------------------------------------- +// 2024 Ahoy, https://ahoydtu.de +// Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed +//----------------------------------------------------------------------------- + +#ifndef __AHOY_NETWORK_HELPER_H__ +#define __AHOY_NETWORK_HELPER_H__ + +#include "../utils/dbg.h" +#include +#include +#include +#include + +namespace ah { + void welcome(String ip, String info) { + DBGPRINTLN(F("\n\n-------------------")); + DBGPRINTLN(F("Welcome to AHOY!")); + DBGPRINT(F("\npoint your browser to http://")); + DBGPRINT(ip); + DBGPRINT(" ("); + DBGPRINT(info); + DBGPRINTLN(")"); + DBGPRINTLN(F("to configure your device")); + DBGPRINTLN(F("-------------------\n")); + } +} + +#endif /*__AHOY_NETWORK_HELPER_H__*/ diff --git a/src/network/AhoyWifiAp.h b/src/network/AhoyWifiAp.h new file mode 100644 index 00000000..f919e030 --- /dev/null +++ b/src/network/AhoyWifiAp.h @@ -0,0 +1,70 @@ +//----------------------------------------------------------------------------- +// 2024 Ahoy, https://ahoydtu.de +// Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed +//----------------------------------------------------------------------------- + +#ifndef __AHOY_WIFI_AP_H__ +#define __AHOY_WIFI_AP_H__ + +#include "../utils/dbg.h" +#include +#include "../config/settings.h" +#include "AhoyNetworkHelper.h" + +class AhoyWifiAp { + public: + AhoyWifiAp() : mIp(192, 168, 4, 1) {} + + void setup(cfgSys_t *cfg) { + mCfg = cfg; + } + + void tickLoop() { + if(mEnabled) + mDns.processNextRequest(); + } + + void enable() { + ah::welcome(mIp.toString(), String(F("Password: ") + String(mCfg->apPwd))); + if('\0' == mCfg->deviceName[0]) + snprintf(mCfg->deviceName, DEVNAME_LEN, "%s", DEF_DEVICE_NAME); + WiFi.hostname(mCfg->deviceName); + + #if defined(ETHERNET) + WiFi.mode(WIFI_AP); + #else + WiFi.mode(WIFI_AP_STA); + #endif + WiFi.softAPConfig(mIp, mIp, IPAddress(255, 255, 255, 0)); + WiFi.softAP(WIFI_AP_SSID, mCfg->apPwd); + + mDns.start(53, "*", mIp); + + mEnabled = true; + tickLoop(); + } + + void disable() { + mDns.stop(); + WiFi.softAPdisconnect(); + #if defined(ETHERNET) + WiFi.mode(WIFI_OFF); + #else + WiFi.mode(WIFI_STA); + #endif + + mEnabled = false; + } + + bool getEnable() const { + return mEnabled; + } + + private: + cfgSys_t *mCfg = nullptr; + DNSServer mDns; + IPAddress mIp; + bool mEnabled = false; +}; + +#endif /*__AHOY_WIFI_AP_H__*/ diff --git a/src/web/RestApi.h b/src/web/RestApi.h index 399ea91f..197c6982 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -381,6 +381,8 @@ class RestApi { obj[F("hidd")] = mConfig->sys.isHidden; obj[F("mac")] = WiFi.macAddress(); obj[F("wifi_channel")] = WiFi.channel(); + #else + getEthernet(obj.createNestedObject(F("eth"))); #endif /* !defined(ETHERNET) */ obj[F("device_name")] = mConfig->sys.deviceName; obj[F("dark_mode")] = (bool)mConfig->sys.darkMode; @@ -762,6 +764,18 @@ class RestApi { } #endif + #if defined(ETHERNET) + void getEthernet(JsonObject obj) { + obj[F("en")] = mConfig->sys.eth.enabled; + obj[F("cs")] = mConfig->sys.eth.pinCs; + obj[F("sclk")] = mConfig->sys.eth.pinSclk; + obj[F("miso")] = mConfig->sys.eth.pinMiso; + obj[F("mosi")] = mConfig->sys.eth.pinMosi; + obj[F("irq")] = mConfig->sys.eth.pinIrq; + obj[F("reset")] = mConfig->sys.eth.pinRst; + } + #endif + void getRadioNrf(JsonObject obj) { obj[F("en")] = (bool) mConfig->nrf.enabled; if(mConfig->nrf.enabled) { diff --git a/src/web/html/setup.html b/src/web/html/setup.html index b6b8929e..8f3fe07c 100644 --- a/src/web/html/setup.html +++ b/src/web/html/setup.html @@ -245,7 +245,7 @@

{#MQTT_NOTE}

{#INTERVAL}
-
+
Discovery Config (homeassistant)
@@ -270,6 +270,10 @@

{#RADIO} (CMT2300A)

+ +

Ethernet

+
+
@@ -986,7 +990,7 @@ ) } - function parseNrfRadio(obj, objPin, type, system) { + function parseNrfRadio(obj, objPin) { var e = document.getElementById("rf24"); var en = inp("nrfEnable", null, null, ["cb"], "nrfEnable", "checkbox"); en.checked = obj["en"]; @@ -1013,11 +1017,11 @@ ]) ); - if ("ESP8266" == type) { - pins = [['cs', 'pinCs'], ['ce', 'pinCe'], ['irq', 'pinIrq']]; - } else { - pins = [['cs', 'pinCs'], ['ce', 'pinCe'], ['irq', 'pinIrq'], ['sclk', 'pinSclk'], ['mosi', 'pinMosi'], ['miso', 'pinMiso']]; - } + /*IF_ESP32*/ + var pins = [['cs', 'pinCs'], ['ce', 'pinCe'], ['irq', 'pinIrq'], ['sclk', 'pinSclk'], ['mosi', 'pinMosi'], ['miso', 'pinMiso']]; + /*ELSE*/ + var pins = [['cs', 'pinCs'], ['ce', 'pinCe'], ['irq', 'pinIrq']]; + /*ENDIF_ESP32*/ for(p of pins) { e.append( ml("div", {class: "row mb-3"}, [ @@ -1031,7 +1035,7 @@ } /*IF_ESP32*/ - function parseCmtRadio(obj, type, system) { + function parseCmtRadio(obj) { var e = document.getElementById("cmt"); var en = inp("cmtEnable", null, null, ["cb"], "cmtEnable", "checkbox"); var pinList = esp32pins; @@ -1046,7 +1050,6 @@ /*ENDIF_ESP32-C3*/ en.checked = obj["en"]; - e.replaceChildren ( ml("div", {class: "row mb-3"}, [ ml("div", {class: "col-8 col-sm-3 my-2"}, "{#CMT_ENABLE}"), @@ -1073,6 +1076,42 @@ } /*ENDIF_ESP32*/ + /*IF_ETHERNET*/ + function parseEth(obj) { + var e = document.getElementById("eth"); + var en = inp("ethEn", null, null, ["cb"], "ethEn", "checkbox"); + var pinList = esp32pins; + /*IF_ESP32-S2*/ + pinList = esp32sXpins; + /*ENDIF_ESP32-S2*/ + /*IF_ESP32-S3*/ + pinList = esp32sXpins; + /*ENDIF_ESP32-S3*/ + /*IF_ESP32-C3*/ + pinList = esp32c3pins; + /*ENDIF_ESP32-C3*/ + + en.checked = obj["en"]; + e.replaceChildren ( + ml("div", {class: "row mb-3"}, [ + ml("div", {class: "col-8 col-sm-3 my-2"}, "{#ETH_ENABLE}"), + ml("div", {class: "col-4 col-sm-9"}, en) + ]) + ); + pins = [['cs', 'ethCs'], ['sclk', 'ethSclk'], ['miso', 'ethMiso'], ['mosi', 'ethMosi'], ['irq', 'ethIrq'], ['reset', 'ethRst']]; + for(p of pins) { + e.append( + ml("div", {class: "row mb-3"}, [ + ml("div", {class: "col-12 col-sm-3 my-2"}, p[0].toUpperCase()), + ml("div", {class: "col-12 col-sm-9"}, + sel(p[1], pinList, obj[p[0]]) + ) + ]) + ); + } + } + /*ENDIF_ETHERNET*/ + function parseSerial(obj) { var e = document.getElementById("serialCb") var l = [["serEn", "show_live_data", "{#LOG_PRINT_INVERTER_DATA}"], ["serDbg", "debug", "{#LOG_SERIAL_DEBUG}"], ["priv", "priv", "{#LOG_PRIVACY_MODE}"], ["wholeTrace", "wholeTrace", "{#LOG_PRINT_TRACES}"], ["log2mqtt", "log2mqtt", "{#LOG_TO_MQTT}"]] @@ -1253,10 +1292,13 @@ parseNtp(root["ntp"]); parseSun(root["sun"]); parsePinout(root["pinout"], root["system"]["esp_type"], root["system"]); - parseNrfRadio(root["radioNrf"], root["pinout"], root["system"]["esp_type"], root["system"]); + parseNrfRadio(root["radioNrf"], root["pinout"]); /*IF_ESP32*/ - parseCmtRadio(root["radioCmt"], root["system"]["esp_type"], root["system"]); + parseCmtRadio(root["radioCmt"]); /*ENDIF_ESP32*/ + /*IF_ETHERNET*/ + parseEth(root.system.eth) + /*ENDIF_ETHERNET*/ parseSerial(root["serial"]); /*IF_PLUGIN_DISPLAY*/ parseDisplay(root["display"], root["system"]["esp_type"], root["system"]); diff --git a/src/web/lang.json b/src/web/lang.json index f1723688..419dd4f4 100644 --- a/src/web/lang.json +++ b/src/web/lang.json @@ -723,6 +723,11 @@ "en": "CMT2300A radio enable", "de": "CMT2300A Funkmodul aktivieren" }, + { + "token": "ETH_ENABLE", + "en": "Ethernet enable", + "de": "Ethernet aktivieren" + }, { "token": "DISP_NONE", "en": "None", diff --git a/src/web/web.h b/src/web/web.h index 3e7d00a8..f4389163 100644 --- a/src/web/web.h +++ b/src/web/web.h @@ -37,14 +37,19 @@ #define WEB_SERIAL_BUF_SIZE 2048 -const char* const pinArgNames[] = {"pinCs", "pinCe", "pinIrq", "pinSclk", "pinMosi", "pinMiso", "pinLed0", "pinLed1", "pinLed2", "pinLedHighActive", "pinLedLum", "pinCmtSclk", "pinSdio", "pinCsb", "pinFcsb", "pinGpio3"}; +const char* const pinArgNames[] = { + "pinCs", "pinCe", "pinIrq", "pinSclk", "pinMosi", "pinMiso", "pinLed0", + "pinLed1", "pinLed2", "pinLedHighActive", "pinLedLum", "pinCmtSclk", + "pinSdio", "pinCsb", "pinFcsb", "pinGpio3" + #if defined (ETHERNET) + , "ethCs", "ethSclk", "ethMiso", "ethMosi", "ethIrq", "ethRst" + #endif +}; template class Web { public: - Web(void) : mWeb(80), mEvts("/events") { - memset(mSerialBuf, 0, WEB_SERIAL_BUF_SIZE); - } + Web(void) : mWeb(80), mEvts("/events") {} void setup(IApp *app, HMSYSTEM *sys, settings_t *config) { mApp = app; @@ -101,11 +106,17 @@ class Web { void tickSecond() { if (mSerialClientConnnected) { + if(nullptr == mSerialBuf) + return; + if (mSerialBufFill > 0) { mEvts.send(mSerialBuf, "serial", millis()); memset(mSerialBuf, 0, WEB_SERIAL_BUF_SIZE); mSerialBufFill = 0; } + } else if(nullptr != mSerialBuf) { + delete[] mSerialBuf; + mSerialBuf = nullptr; } } @@ -177,6 +188,9 @@ class Web { if (!mSerialClientConnnected) return; + if(nullptr == mSerialBuf) + return; + msg.replace("\r\n", ""); if (mSerialAddTime) { if ((13 + mSerialBufFill) < WEB_SERIAL_BUF_SIZE) { @@ -293,6 +307,10 @@ class Web { void onConnect(AsyncEventSourceClient *client) { DPRINTLN(DBG_VERBOSE, "onConnect"); + if(nullptr == mSerialBuf) { + mSerialBuf = new char[WEB_SERIAL_BUF_SIZE]; + memset(mSerialBuf, 0, WEB_SERIAL_BUF_SIZE); + } mSerialClientConnnected = true; if (client->lastId()) @@ -482,7 +500,12 @@ class Web { // pinout - for (uint8_t i = 0; i < 16; i++) { + #if defined(ETHERNET) + for (uint8_t i = 0; i < 22; i++) + #else + for (uint8_t i = 0; i < 16; i++) + #endif + { uint8_t pin = request->arg(String(pinArgNames[i])).toInt(); switch(i) { case 0: mConfig->nrf.pinCs = ((pin != 0xff) ? pin : DEF_NRF_CS_PIN); break; @@ -501,11 +524,23 @@ class Web { case 13: mConfig->cmt.pinCsb = pin; break; case 14: mConfig->cmt.pinFcsb = pin; break; case 15: mConfig->cmt.pinIrq = pin; break; + + #if defined(ETHERNET) + case 16: mConfig->sys.eth.pinCs = pin; break; + case 17: mConfig->sys.eth.pinSclk = pin; break; + case 18: mConfig->sys.eth.pinMiso = pin; break; + case 19: mConfig->sys.eth.pinMosi = pin; break; + case 20: mConfig->sys.eth.pinIrq = pin; break; + case 21: mConfig->sys.eth.pinRst = pin; break; + #endif } } mConfig->nrf.enabled = (request->arg("nrfEnable") == "on"); mConfig->cmt.enabled = (request->arg("cmtEnable") == "on"); + #if defined(ETHERNET) + mConfig->sys.eth.enabled = (request->arg("ethEn") == "on"); + #endif // ntp if (request->arg("ntpAddr") != "") { @@ -906,7 +941,7 @@ class Web { settings_t *mConfig = nullptr; bool mSerialAddTime = true; - char mSerialBuf[WEB_SERIAL_BUF_SIZE]; + char *mSerialBuf = nullptr; uint16_t mSerialBufFill = 0; bool mSerialClientConnnected = false; diff --git a/src/wifi/ahoywifi.h b/src/wifi/ahoywifi.h index 78ec6ab1..acf6d7d4 100644 --- a/src/wifi/ahoywifi.h +++ b/src/wifi/ahoywifi.h @@ -63,7 +63,7 @@ class ahoywifi { void connectionEvent(WiFiStatus_t status); bool isTimeout(uint8_t timeout) { return (mCnt % timeout) == 0; } -#if defined(ESP8266) + #if defined(ESP8266) void onConnect(const WiFiEventStationModeConnected& event); void onGotIP(const WiFiEventStationModeGotIP& event); void onDisconnect(const WiFiEventStationModeDisconnected& event); From 89f7b4f1c6ff22238fa1749be7b487fb185d3b5c Mon Sep 17 00:00:00 2001 From: lumapu Date: Thu, 21 Mar 2024 21:06:02 +0100 Subject: [PATCH 02/21] ethernet and wifi are working for ESP32 --- src/app.cpp | 38 +-- src/app.h | 39 +-- src/appInterface.h | 4 +- src/config/settings.h | 3 +- src/eth/ahoyeth.cpp | 179 ----------- src/eth/ahoyeth.h | 65 ---- src/network/AhoyEthernet.h | 87 +++--- src/network/AhoyNetwork.h | 43 +-- src/network/AhoyNetworkHelper.cpp | 20 ++ src/network/AhoyNetworkHelper.h | 12 +- src/network/AhoyWifiAp.h | 11 +- src/network/AhoyWifiEsp32.h | 112 +++++++ src/publisher/pubMqtt.h | 14 +- src/web/RestApi.h | 4 +- src/wifi/ahoywifi.cpp | 490 ------------------------------ src/wifi/ahoywifi.h | 100 ------ 16 files changed, 238 insertions(+), 983 deletions(-) delete mode 100644 src/eth/ahoyeth.cpp delete mode 100644 src/eth/ahoyeth.h create mode 100644 src/network/AhoyNetworkHelper.cpp create mode 100644 src/network/AhoyWifiEsp32.h delete mode 100644 src/wifi/ahoywifi.cpp delete mode 100644 src/wifi/ahoywifi.h diff --git a/src/app.cpp b/src/app.cpp index 37b0a37a..0d0d2698 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -53,17 +53,16 @@ void app::setup() { mCmtRadio.setup(&mConfig->serial.debug, &mConfig->serial.privacyLog, &mConfig->serial.printWholeTrace, mConfig->cmt.pinSclk, mConfig->cmt.pinSdio, mConfig->cmt.pinCsb, mConfig->cmt.pinFcsb, mConfig->sys.region); } #endif + #ifdef ETHERNET delay(1000); - mEth.setup(mConfig, &mTimestamp, [this](bool gotIp) { this->onNetwork(gotIp); }, [this](bool gotTime) { this->onNtpUpdate(gotTime); }); + mNetwork = (AhoyNetwork*) new AhoyEthernet(); + #else + mNetwork = (AhoyNetwork*) new AhoyWifi(); #endif // ETHERNET - - #if !defined(ETHERNET) - mWifi.setup(mConfig, &mTimestamp, [this](bool gotIp) { this->onNetwork(gotIp); }, [this](bool gotTime) { this->onNtpUpdate(gotTime); }); - #if !defined(AP_ONLY) - everySec(std::bind(&ahoywifi::tickWifiLoop, &mWifi), "wifiL"); - #endif - #endif /* defined(ETHERNET) */ + mNetwork->setup(mConfig, &mTimestamp, [this](bool gotIp) { this->onNetwork(gotIp); }, [this](bool gotTime) { this->onNtpUpdate(gotTime); }); + mNetwork->begin(); + everySec(std::bind(&AhoyNetwork::tickNetworkLoop, mNetwork), "net"); esp_task_wdt_reset(); @@ -89,7 +88,7 @@ void app::setup() { #if defined(ENABLE_MQTT) mMqttEnabled = (mConfig->mqtt.broker[0] > 0); if (mMqttEnabled) { - mMqtt.setup(&mConfig->mqtt, mConfig->sys.deviceName, mVersion, &mSys, &mTimestamp, &mUptime); + mMqtt.setup(this, &mConfig->mqtt, mConfig->sys.deviceName, mVersion, &mSys, &mTimestamp, &mUptime); mMqtt.setSubscriptionCb(std::bind(&app::mqttSubRxCb, this, std::placeholders::_1)); mCommunication.addAlarmListener([this](Inverter<> *iv) { mMqtt.alarmEvent(iv); }); } @@ -171,12 +170,6 @@ void app::onNetwork(bool gotIp) { mMqttReconnect = true; mSunrise = 0; // needs to be set to 0, to reinstall sunrise and ivComm tickers! once(std::bind(&app::tickNtpUpdate, this), 2, "ntp2"); - #if !defined(ETHERNET) - if (WIFI_AP == WiFi.getMode()) { - mMqttEnabled = false; - } - everySec(std::bind(&ahoywifi::tickWifiLoop, &mWifi), "wifiL"); - #endif /* !defined(ETHERNET) */ } //----------------------------------------------------------------------------- @@ -248,17 +241,10 @@ void app::updateNtp(void) { void app::tickNtpUpdate(void) { uint32_t nxtTrig = 5; // default: check again in 5 sec - #if defined(ETHERNET) - if (!mNtpReceived) - mEth.updateNtpTime(); - else - mNtpReceived = false; - #else - if (!mNtpReceived) - mWifi.updateNtpTime(); - else - mNtpReceived = false; - #endif + if (!mNtpReceived) + mNetwork->updateNtpTime(); + else + mNtpReceived = false; updateNtp(); nxtTrig = mConfig->ntp.interval * 60; // check again in 12h diff --git a/src/app.h b/src/app.h index a699bac0..b3e5cffa 100644 --- a/src/app.h +++ b/src/app.h @@ -37,9 +37,9 @@ #include "web/web.h" #include "hm/Communication.h" #if defined(ETHERNET) - #include "eth/ahoyeth.h" + #include "network/AhoyEthernet.h" #else /* defined(ETHERNET) */ - #include "wifi/ahoywifi.h" + #include "network/AhoyWifiEsp32.h" #include "utils/improv.h" #endif /* defined(ETHERNET) */ @@ -164,31 +164,30 @@ class app : public IApp, public ah::Scheduler { #if !defined(ETHERNET) void scanAvailNetworks() override { - mWifi.scanAvailNetworks(); + mNetwork->scanAvailNetworks(); } bool getAvailNetworks(JsonObject obj) override { - return mWifi.getAvailNetworks(obj); + return mNetwork->getAvailNetworks(obj); } void setupStation(void) override { - mWifi.setupStation(); + mNetwork->begin(); } - void setStopApAllowedMode(bool allowed) override { + /*void setStopApAllowedMode(bool allowed) override { mWifi.setStopApAllowedMode(allowed); - } - - String getStationIp(void) override { - return mWifi.getStationIp(); - } + }*/ bool getWasInCh12to14(void) const override { - return mWifi.getWasInCh12to14(); + return false; // @todo mWifi.getWasInCh12to14(); } - #endif /* !defined(ETHERNET) */ + String getIp(void) override { + return mNetwork->getIp(); + } + void setRebootFlag() override { once(std::bind(&app::tickReboot, this), 3, "rboot"); } @@ -295,13 +294,7 @@ class app : public IApp, public ah::Scheduler { DPRINT(DBG_DEBUG, F("setTimestamp: ")); DBGPRINTLN(String(newTime)); if(0 == newTime) - { - #if defined(ETHERNET) - mEth.updateNtpTime(); - #else /* defined(ETHERNET) */ - mWifi.updateNtpTime(); - #endif /* defined(ETHERNET) */ - } + mNetwork->updateNtpTime(); else Scheduler::setTimestamp(newTime); } @@ -414,11 +407,7 @@ class app : public IApp, public ah::Scheduler { bool mShowRebootRequest = false; - #if defined(ETHERNET) - ahoyeth mEth; - #else /* defined(ETHERNET) */ - ahoywifi mWifi; - #endif /* defined(ETHERNET) */ + AhoyNetwork *mNetwork; WebType mWeb; RestApiType mApi; Protection *mProtection = nullptr; diff --git a/src/appInterface.h b/src/appInterface.h index b465edf9..b7ee2aaf 100644 --- a/src/appInterface.h +++ b/src/appInterface.h @@ -29,10 +29,10 @@ class IApp { virtual void scanAvailNetworks() = 0; virtual bool getAvailNetworks(JsonObject obj) = 0; virtual void setupStation(void) = 0; - virtual void setStopApAllowedMode(bool allowed) = 0; - virtual String getStationIp(void) = 0; + //virtual void setStopApAllowedMode(bool allowed) = 0; virtual bool getWasInCh12to14(void) const = 0; #endif /* defined(ETHERNET) */ + virtual String getIp(void) = 0; virtual uint32_t getUptime() = 0; virtual uint32_t getTimestamp() = 0; diff --git a/src/config/settings.h b/src/config/settings.h index f130434c..ace968fb 100644 --- a/src/config/settings.h +++ b/src/config/settings.h @@ -91,10 +91,11 @@ typedef struct { char stationSsid[SSID_LEN]; char stationPwd[PWD_LEN]; bool isHidden; +#else + cfgEth_t eth; #endif /* !defined(ETHERNET) */ cfgIp_t ip; - cfgEth_t eth; } cfgSys_t; typedef struct { diff --git a/src/eth/ahoyeth.cpp b/src/eth/ahoyeth.cpp deleted file mode 100644 index 497a542f..00000000 --- a/src/eth/ahoyeth.cpp +++ /dev/null @@ -1,179 +0,0 @@ -//----------------------------------------------------------------------------- -// 2023 Ahoy, https://www.mikrocontroller.net/topic/525778 -// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/ -//----------------------------------------------------------------------------- - -#if defined(ETHERNET) - -#if defined(ESP32) && defined(F) - #undef F - #define F(sl) (sl) -#endif -#include "ahoyeth.h" -#include - -//----------------------------------------------------------------------------- -ahoyeth::ahoyeth() -{ - // WiFi.onEvent(ESP32_W5500_event); -} - - -//----------------------------------------------------------------------------- -void ahoyeth::setup(settings_t *config, uint32_t *utcTimestamp, OnNetworkCB onNetworkCB, OnTimeCB onTimeCB) { - mConfig = config; - mUtcTimestamp = utcTimestamp; - mOnNetworkCB = onNetworkCB; - mOnTimeCB = onTimeCB; - mEthConnected = false; - - Serial.flush(); - WiFi.onEvent([this](WiFiEvent_t event, arduino_event_info_t info) -> void { this->onEthernetEvent(event, info); }); - - Serial.flush(); - mEthSpi.begin(config->sys.eth.pinMiso, config->sys.eth.pinMosi, config->sys.eth.pinSclk, config->sys.eth.pinCs, config->sys.eth.pinIrq, config->sys.eth.pinRst); - - if(mConfig->sys.ip.ip[0] != 0) { - IPAddress ip(mConfig->sys.ip.ip); - IPAddress mask(mConfig->sys.ip.mask); - IPAddress dns1(mConfig->sys.ip.dns1); - IPAddress dns2(mConfig->sys.ip.dns2); - IPAddress gateway(mConfig->sys.ip.gateway); - if(!ETH.config(ip, gateway, mask, dns1, dns2)) - DPRINTLN(DBG_ERROR, F("failed to set static IP!")); - } -} - - -//----------------------------------------------------------------------------- -bool ahoyeth::updateNtpTime(void) { - if (!ETH.localIP()) - return false; - - DPRINTLN(DBG_DEBUG, F("updateNtpTime: checking udp \"connection\"...")); Serial.flush(); - if (!mUdp.connected()) { - DPRINTLN(DBG_DEBUG, F("updateNtpTime: About to (re)connect...")); Serial.flush(); - IPAddress timeServer; - if (!WiFi.hostByName(mConfig->ntp.addr, timeServer)) - return false; - - if (!mUdp.connect(timeServer, mConfig->ntp.port)) - return false; - - DPRINTLN(DBG_DEBUG, F("updateNtpTime: Connected...")); Serial.flush(); - mUdp.onPacket([this](AsyncUDPPacket packet) { - DPRINTLN(DBG_DEBUG, F("updateNtpTime: about to handle ntp packet...")); Serial.flush(); - this->handleNTPPacket(packet); - }); - } - - DPRINTLN(DBG_DEBUG, F("updateNtpTime: prepare packet...")); Serial.flush(); - - // set all bytes in the buffer to 0 - memset(mUdpPacketBuffer, 0, NTP_PACKET_SIZE); - // Initialize values needed to form NTP request - // (see URL above for details on the packets) - - mUdpPacketBuffer[0] = 0b11100011; // LI, Version, Mode - mUdpPacketBuffer[1] = 0; // Stratum, or type of clock - mUdpPacketBuffer[2] = 6; // Polling Interval - mUdpPacketBuffer[3] = 0xEC; // Peer Clock Precision - - // 8 bytes of zero for Root Delay & Root Dispersion - mUdpPacketBuffer[12] = 49; - mUdpPacketBuffer[13] = 0x4E; - mUdpPacketBuffer[14] = 49; - mUdpPacketBuffer[15] = 52; - - //Send unicast - DPRINTLN(DBG_DEBUG, F("updateNtpTime: send packet...")); Serial.flush(); - mUdp.write(mUdpPacketBuffer, sizeof(mUdpPacketBuffer)); - - return true; -} - -//----------------------------------------------------------------------------- -void ahoyeth::handleNTPPacket(AsyncUDPPacket packet) { - char buf[80]; - - memcpy(buf, packet.data(), sizeof(buf)); - - unsigned long highWord = word(buf[40], buf[41]); - unsigned long lowWord = word(buf[42], buf[43]); - - // combine the four bytes (two words) into a long integer - // this is NTP time (seconds since Jan 1 1900): - unsigned long secsSince1900 = highWord << 16 | lowWord; - - *mUtcTimestamp = secsSince1900 - 2208988800UL; // UTC time - DPRINTLN(DBG_INFO, "[NTP]: " + ah::getDateTimeStr(*mUtcTimestamp) + " UTC"); - mOnTimeCB(true); -} - -//----------------------------------------------------------------------------- -void ahoyeth::welcome(String ip, String mode) { - DBGPRINTLN(F("\n\n--------------------------------")); - DBGPRINTLN(F("Welcome to AHOY!")); - DBGPRINT(F("\npoint your browser to http://")); - DBGPRINT(ip); - DBGPRINTLN(mode); - DBGPRINTLN(F("to configure your device")); - DBGPRINTLN(F("--------------------------------\n")); -} - -void ahoyeth::onEthernetEvent(WiFiEvent_t event, arduino_event_info_t info) { - DPRINTLN(DBG_VERBOSE, F("[ETH]: Got event...")); - switch (event) { - case ARDUINO_EVENT_ETH_START: - DPRINTLN(DBG_VERBOSE, F("ETH Started")); - - if(String(mConfig->sys.deviceName) != "") - ETH.setHostname(mConfig->sys.deviceName); - else - ETH.setHostname(F("ESP32_W5500")); - break; - - case ARDUINO_EVENT_ETH_CONNECTED: - DPRINTLN(DBG_VERBOSE, F("ETH Connected")); - break; - - case ARDUINO_EVENT_ETH_GOT_IP: - if (!mEthConnected) { - /*DPRINT(DBG_INFO, F("ETH MAC: ")); - DBGPRINT(mEthSpi.macAddress());*/ - welcome(ETH.localIP().toString(), F(" (Station)")); - - mEthConnected = true; - mOnNetworkCB(true); - } - - if (!MDNS.begin(mConfig->sys.deviceName)) { - DPRINTLN(DBG_ERROR, F("Error setting up MDNS responder!")); - } else { - DBGPRINT(F("mDNS established: ")); - DBGPRINT(mConfig->sys.deviceName); - DBGPRINTLN(F(".local")); - } - break; - - case ARDUINO_EVENT_ETH_DISCONNECTED: - DPRINTLN(DBG_INFO, F("ETH Disconnected")); - mEthConnected = false; - mUdp.close(); - mOnNetworkCB(false); - break; - - case ARDUINO_EVENT_ETH_STOP: - DPRINTLN(DBG_INFO, F("ETH Stopped")); - mEthConnected = false; - mUdp.close(); - mOnNetworkCB(false); - break; - - default: - break; - } - -} - -#endif /* defined(ETHERNET) */ diff --git a/src/eth/ahoyeth.h b/src/eth/ahoyeth.h deleted file mode 100644 index 557db5ec..00000000 --- a/src/eth/ahoyeth.h +++ /dev/null @@ -1,65 +0,0 @@ -//----------------------------------------------------------------------------- -// 2024 Ahoy, https://github.com/lumpapu/ahoy -// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/4.0/deed -//----------------------------------------------------------------------------- - -#if defined(ETHERNET) -#ifndef __AHOYETH_H__ -#define __AHOYETH_H__ - -#include - -#include "../utils/dbg.h" -#include -#include -#include - -#include "ethSpi.h" -#include -#include "../utils/dbg.h" -#include "../config/config.h" -#include "../config/settings.h" - - -class app; - -#define NTP_PACKET_SIZE 48 - -class ahoyeth { - public: /* types */ - typedef std::function OnNetworkCB; - typedef std::function OnTimeCB; - - public: - ahoyeth(); - - void setup(settings_t *config, uint32_t *utcTimestamp, OnNetworkCB onNetworkCB, OnTimeCB onTimeCB); - bool updateNtpTime(void); - - private: - void setupEthernet(); - - void handleNTPPacket(AsyncUDPPacket packet); - - void welcome(String ip, String mode); - - void onEthernetEvent(WiFiEvent_t event, arduino_event_info_t info); - - private: - //#if defined(CONFIG_IDF_TARGET_ESP32S3) - EthSpi mEthSpi; - //#endif - settings_t *mConfig = nullptr; - - uint32_t *mUtcTimestamp; - AsyncUDP mUdp; // for time server - byte mUdpPacketBuffer[NTP_PACKET_SIZE]; // buffer to hold incoming and outgoing packets - - OnNetworkCB mOnNetworkCB; - OnTimeCB mOnTimeCB; - bool mEthConnected; - -}; - -#endif /*__AHOYETH_H__*/ -#endif /* defined(ETHERNET) */ diff --git a/src/network/AhoyEthernet.h b/src/network/AhoyEthernet.h index c56b4338..ce176ec3 100644 --- a/src/network/AhoyEthernet.h +++ b/src/network/AhoyEthernet.h @@ -6,77 +6,64 @@ #ifndef __AHOY_ETHERNET_H__ #define __AHOY_ETHERNET_H__ +#if defined(ETHERNET) #include #include #include #include "AhoyEthernetSpi.h" -#include "AhoyEthernet.h" +#include "AhoyNetwork.h" class AhoyEthernet : public AhoyNetwork { public: void begin() override { + mAp.enable(); + + // static IP setupIp([this](IPAddress ip, IPAddress gateway, IPAddress mask, IPAddress dns1, IPAddress dns2) -> bool { return ETH.config(ip, gateway, mask, dns1, dns2); }); + + ETH.setHostname(mConfig->sys.deviceName); } void tickNetworkLoop() override { - switch(mState) { + if(mAp.isEnabled()) + mAp.tickLoop(); + + switch(mStatus) { case NetworkState::DISCONNECTED: + if(mConnected) { + mConnected = false; + mOnNetworkCB(false); + mAp.enable(); + } break; - } - } - - private: - - /*switch (event) { - case ARDUINO_EVENT_ETH_START: - DPRINTLN(DBG_VERBOSE, F("ETH Started")); - - if(String(mConfig->sys.deviceName) != "") - ETH.setHostname(mConfig->sys.deviceName); - else - ETH.setHostname(F("ESP32_W5500")); - break; - case ARDUINO_EVENT_ETH_CONNECTED: - DPRINTLN(DBG_VERBOSE, F("ETH Connected")); - break; - - case ARDUINO_EVENT_ETH_GOT_IP: - if (!mEthConnected) { - welcome(ETH.localIP().toString(), F(" (Station)")); - - mEthConnected = true; - mOnNetworkCB(true); - } + case NetworkState::CONNECTED: + break; - if (!MDNS.begin(mConfig->sys.deviceName)) { - DPRINTLN(DBG_ERROR, F("Error setting up MDNS responder!")); - } else { - DBGPRINT(F("mDNS established: ")); - DBGPRINT(mConfig->sys.deviceName); - DBGPRINTLN(F(".local")); - } - break; + case NetworkState::GOT_IP: + mAp.disable(); - case ARDUINO_EVENT_ETH_DISCONNECTED: - DPRINTLN(DBG_INFO, F("ETH Disconnected")); - mEthConnected = false; - mUdp.close(); - mOnNetworkCB(false); - break; + if(!mConnected) { + mConnected = true; + ah::welcome(ETH.localIP().toString(), F("Station")); + MDNS.begin(mConfig->sys.deviceName); + mOnNetworkCB(true); + } + break; + } + } - case ARDUINO_EVENT_ETH_STOP: - DPRINTLN(DBG_INFO, F("ETH Stopped")); - mEthConnected = false; - mUdp.close(); - mOnNetworkCB(false); - break; + String getIp(void) override { + return ETH.localIP().toString(); + } - default: - break; - }*/ + void scanAvailNetworks(void) override {}; + bool getAvailNetworks(JsonObject obj) override { + return false; + } }; +#endif /*ETHERNET*/ #endif /*__AHOY_ETHERNET_H__*/ diff --git a/src/network/AhoyNetwork.h b/src/network/AhoyNetwork.h index 01d7cd8c..952206f0 100644 --- a/src/network/AhoyNetwork.h +++ b/src/network/AhoyNetwork.h @@ -7,9 +7,11 @@ #define __AHOY_NETWORK_H__ #include "AhoyNetworkHelper.h" -#include +#include #include "../config/settings.h" #include "../utils/helper.h" +#include "AhoyWifiAp.h" +#include "AsyncJson.h" #if defined(ESP32) #include @@ -31,9 +33,15 @@ class AhoyNetwork { mOnNetworkCB = onNetworkCB; mOnTimeCB = onTimeCB; + if('\0' == mConfig->sys.deviceName[0]) + snprintf(mConfig->sys.deviceName, DEVNAME_LEN, "%s", DEF_DEVICE_NAME); + WiFi.hostname(mConfig->sys.deviceName); + + mAp.setup(&mConfig->sys); + #if defined(ESP32) - WiFi.onEvent([this](WiFiEvent_t event) -> void { - this->OnEvent(event); + WiFi.onEvent([this](WiFiEvent_t event, arduino_event_info_t info) -> void { + OnEvent(event); }); #else wifiConnectHandler = WiFi.onStationModeConnected( @@ -52,15 +60,15 @@ class AhoyNetwork { } bool isConnected() const { - return (mStatus == NetworkState.CONNECTED); + return (mStatus == NetworkState::CONNECTED); } bool updateNtpTime(void) { - if(CONNECTED != mStatus) - return; + if(NetworkState::CONNECTED != mStatus) + return false; + IPAddress timeServer; if (!mUdp.connected()) { - IPAddress timeServer; if (!WiFi.hostByName(mConfig->ntp.addr, timeServer)) return false; if (!mUdp.connect(timeServer, mConfig->ntp.port)) @@ -78,17 +86,19 @@ class AhoyNetwork { public: virtual void begin() = 0; virtual void tickNetworkLoop() = 0; - virtual void connectionEvent(WiFiStatus_t status) = 0; + virtual String getIp(void) = 0; + virtual void scanAvailNetworks(void) = 0; + virtual bool getAvailNetworks(JsonObject obj) = 0; protected: - void setupIp(void) { + void setupIp(std::function cb) { if(mConfig->sys.ip.ip[0] != 0) { IPAddress ip(mConfig->sys.ip.ip); IPAddress mask(mConfig->sys.ip.mask); IPAddress dns1(mConfig->sys.ip.dns1); IPAddress dns2(mConfig->sys.ip.dns2); IPAddress gateway(mConfig->sys.ip.gateway); - if(!ETH.config(ip, gateway, mask, dns1, dns2)) + if(cb(ip, gateway, mask, dns1, dns2)) DPRINTLN(DBG_ERROR, F("failed to set static IP!")); } } @@ -169,25 +179,22 @@ class AhoyNetwork { protected: enum class NetworkState : uint8_t { DISCONNECTED, - CONNECTING, CONNECTED, - IN_AP_MODE, - GOT_IP, - IN_STA_MODE, - RESET, - SCAN_READY + GOT_IP }; protected: settings_t *mConfig = nullptr; uint32_t *mUtcTimestamp = nullptr; + bool mConnected = false; OnNetworkCB mOnNetworkCB; OnTimeCB mOnTimeCB; - NetworkState mStatus = NetworkState.DISCONNECTED; + NetworkState mStatus = NetworkState::DISCONNECTED; - WiFiUDP mUdp; // for time server + AhoyWifiAp mAp; + AsyncUDP mUdp; // for time server DNSServer mDns; }; diff --git a/src/network/AhoyNetworkHelper.cpp b/src/network/AhoyNetworkHelper.cpp new file mode 100644 index 00000000..09678023 --- /dev/null +++ b/src/network/AhoyNetworkHelper.cpp @@ -0,0 +1,20 @@ +//----------------------------------------------------------------------------- +// 2024 Ahoy, https://ahoydtu.de +// Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed +//----------------------------------------------------------------------------- + +#include "AhoyNetworkHelper.h" + +namespace ah { + void welcome(String ip, String info) { + DBGPRINTLN(F("\n\n-------------------")); + DBGPRINTLN(F("Welcome to AHOY!")); + DBGPRINT(F("\npoint your browser to http://")); + DBGPRINT(ip); + DBGPRINT(" ("); + DBGPRINT(info); + DBGPRINTLN(")"); + DBGPRINTLN(F("to configure your device")); + DBGPRINTLN(F("-------------------\n")); + } +} diff --git a/src/network/AhoyNetworkHelper.h b/src/network/AhoyNetworkHelper.h index ab23f5bc..f814f1db 100644 --- a/src/network/AhoyNetworkHelper.h +++ b/src/network/AhoyNetworkHelper.h @@ -13,17 +13,7 @@ #include namespace ah { - void welcome(String ip, String info) { - DBGPRINTLN(F("\n\n-------------------")); - DBGPRINTLN(F("Welcome to AHOY!")); - DBGPRINT(F("\npoint your browser to http://")); - DBGPRINT(ip); - DBGPRINT(" ("); - DBGPRINT(info); - DBGPRINTLN(")"); - DBGPRINTLN(F("to configure your device")); - DBGPRINTLN(F("-------------------\n")); - } + void welcome(String ip, String info); } #endif /*__AHOY_NETWORK_HELPER_H__*/ diff --git a/src/network/AhoyWifiAp.h b/src/network/AhoyWifiAp.h index f919e030..3c75dc12 100644 --- a/src/network/AhoyWifiAp.h +++ b/src/network/AhoyWifiAp.h @@ -25,10 +25,10 @@ class AhoyWifiAp { } void enable() { + if(mEnabled) + return; + ah::welcome(mIp.toString(), String(F("Password: ") + String(mCfg->apPwd))); - if('\0' == mCfg->deviceName[0]) - snprintf(mCfg->deviceName, DEVNAME_LEN, "%s", DEF_DEVICE_NAME); - WiFi.hostname(mCfg->deviceName); #if defined(ETHERNET) WiFi.mode(WIFI_AP); @@ -45,6 +45,9 @@ class AhoyWifiAp { } void disable() { + if(!mEnabled) + return; + mDns.stop(); WiFi.softAPdisconnect(); #if defined(ETHERNET) @@ -56,7 +59,7 @@ class AhoyWifiAp { mEnabled = false; } - bool getEnable() const { + bool isEnabled() const { return mEnabled; } diff --git a/src/network/AhoyWifiEsp32.h b/src/network/AhoyWifiEsp32.h new file mode 100644 index 00000000..53d39af3 --- /dev/null +++ b/src/network/AhoyWifiEsp32.h @@ -0,0 +1,112 @@ +//----------------------------------------------------------------------------- +// 2024 Ahoy, https://ahoydtu.de +// Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed +//----------------------------------------------------------------------------- + +#ifndef __AHOY_Wifi_ESP32_H__ +#define __AHOY_Wifi_ESP32_H__ + +#if defined(ESP32) && !defined(ETHERNET) +#include +#include +#include +#include "AhoyNetwork.h" + +class AhoyWifi : public AhoyNetwork { + public: + void begin() override { + mAp.enable(); + + // static IP + setupIp([this](IPAddress ip, IPAddress gateway, IPAddress mask, IPAddress dns1, IPAddress dns2) -> bool { + return WiFi.config(ip, gateway, mask, dns1, dns2); + }); + + WiFi.setHostname(mConfig->sys.deviceName); + WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN); + WiFi.setSortMethod(WIFI_CONNECT_AP_BY_SIGNAL); + WiFi.begin(mConfig->sys.stationSsid, mConfig->sys.stationPwd, WIFI_ALL_CHANNEL_SCAN); + + DBGPRINT(F("connect to network '")); Serial.flush(); + DBGPRINT(mConfig->sys.stationSsid); + } + + void tickNetworkLoop() override { + if(mAp.isEnabled()) + mAp.tickLoop(); + + switch(mStatus) { + case NetworkState::DISCONNECTED: + if(mConnected) { + mConnected = false; + mOnNetworkCB(false); + mAp.enable(); + } + + if (WiFi.softAPgetStationNum() > 0) { + DBGPRINTLN(F("AP client connected")); + } + break; + + case NetworkState::CONNECTED: + break; + + case NetworkState::GOT_IP: + if(!mConnected) { + mAp.disable(); + mConnected = true; + ah::welcome(WiFi.localIP().toString(), F("Station")); + MDNS.begin(mConfig->sys.deviceName); + mOnNetworkCB(true); + } + break; + } + } + + String getIp(void) override { + return WiFi.localIP().toString(); + } + + void scanAvailNetworks(void) override { + if(!mScanActive) { + mScanActive = true; + WiFi.scanNetworks(true); + } + } + + bool getAvailNetworks(JsonObject obj) override { + JsonArray nets = obj.createNestedArray(F("networks")); + + int n = WiFi.scanComplete(); + if (n < 0) + return false; + if(n > 0) { + int sort[n]; + sortRSSI(&sort[0], n); + for (int i = 0; i < n; ++i) { + nets[i][F("ssid")] = WiFi.SSID(sort[i]); + nets[i][F("rssi")] = WiFi.RSSI(sort[i]); + } + } + mScanActive = false; + WiFi.scanDelete(); + + return true; + } + + private: + void sortRSSI(int *sort, int n) { + for (int i = 0; i < n; i++) + sort[i] = i; + for (int i = 0; i < n; i++) + for (int j = i + 1; j < n; j++) + if (WiFi.RSSI(sort[j]) > WiFi.RSSI(sort[i])) + std::swap(sort[i], sort[j]); + } + + private: + bool mScanActive = false; +}; + +#endif /*ESP32 & !ETHERNET*/ +#endif /*__AHOY_Wifi_ESP32_H__*/ diff --git a/src/publisher/pubMqtt.h b/src/publisher/pubMqtt.h index 2dbf67ec..2d393b8b 100644 --- a/src/publisher/pubMqtt.h +++ b/src/publisher/pubMqtt.h @@ -16,10 +16,6 @@ #endif #include -#if defined(ETHERNET) -#include "../eth/ahoyeth.h" -#endif - #include "../utils/dbg.h" #include "../config/config.h" #include @@ -56,7 +52,8 @@ class PubMqtt { ~PubMqtt() { } - void setup(cfgMqtt_t *cfg_mqtt, const char *devName, const char *version, HMSYSTEM *sys, uint32_t *utcTs, uint32_t *uptime) { + void setup(IApp *app, cfgMqtt_t *cfg_mqtt, const char *devName, const char *version, HMSYSTEM *sys, uint32_t *utcTs, uint32_t *uptime) { + mApp = app; mCfgMqtt = cfg_mqtt; mDevName = devName; mVersion = version; @@ -256,11 +253,7 @@ class PubMqtt { publish(subtopics[MQTT_VERSION], mVersion, true); publish(subtopics[MQTT_DEVICE], mDevName, true); - #if defined(ETHERNET) - publish(subtopics[MQTT_IP_ADDR], ETH.localIP().toString().c_str(), true); - #else - publish(subtopics[MQTT_IP_ADDR], WiFi.localIP().toString().c_str(), true); - #endif + publish(subtopics[MQTT_IP_ADDR], mApp->getIp().c_str(), true); tickerMinute(); publish(mLwtTopic.data(), mqttStr[MQTT_STR_LWT_CONN], true, false); @@ -611,6 +604,7 @@ class PubMqtt { espMqttClient mClient; cfgMqtt_t *mCfgMqtt = nullptr; + IApp *mApp; #if defined(ESP8266) WiFiEventHandler mHWifiCon, mHWifiDiscon; #endif diff --git a/src/web/RestApi.h b/src/web/RestApi.h index 197c6982..4dcd7c9b 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -893,7 +893,7 @@ class RestApi { mApp->getAvailNetworks(obj); } void getWifiIp(JsonObject obj) { - obj[F("ip")] = mApp->getStationIp(); + obj[F("ip")] = mApp->getIp(); } #endif /* !defined(ETHERNET) */ @@ -1048,7 +1048,7 @@ class RestApi { snprintf(mConfig->sys.stationSsid, SSID_LEN, "%s", jsonIn[F("ssid")].as()); snprintf(mConfig->sys.stationPwd, PWD_LEN, "%s", jsonIn[F("pwd")].as()); mApp->saveSettings(false); // without reboot - mApp->setStopApAllowedMode(false); + //mApp->setStopApAllowedMode(false); mApp->setupStation(); } #endif /* !defined(ETHERNET */ diff --git a/src/wifi/ahoywifi.cpp b/src/wifi/ahoywifi.cpp deleted file mode 100644 index 95bf0b8a..00000000 --- a/src/wifi/ahoywifi.cpp +++ /dev/null @@ -1,490 +0,0 @@ -//----------------------------------------------------------------------------- -// 2024 Ahoy, https://ahoydtu.de -// Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed -//----------------------------------------------------------------------------- - -#if !defined(ETHERNET) -#if defined(ESP32) && defined(F) - #undef F - #define F(sl) (sl) -#endif -#include "ahoywifi.h" - -#if defined(ESP32) -#include -#else -#include -#endif - -// NTP CONFIG -#define NTP_PACKET_SIZE 48 - -//----------------------------------------------------------------------------- -ahoywifi::ahoywifi() : mApIp(192, 168, 4, 1) {} - - -/** - * TODO: ESP32 has native strongest AP support! - * WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN); - WiFi.setSortMethod(WIFI_CONNECT_AP_BY_SIGNAL); -*/ - -//----------------------------------------------------------------------------- -void ahoywifi::setup(settings_t *config, uint32_t *utcTimestamp, appWifiCb cb, OnTimeCB onTimeCb) { - mConfig = config; - mUtcTimestamp = utcTimestamp; - mAppWifiCb = cb; - mOnTimeCb = onTimeCb; - - mGotDisconnect = false; - mStaConn = DISCONNECTED; - mCnt = 0; - mScanActive = false; - mScanCnt = 0; - mStopApAllowed = true; - - #if defined(ESP8266) - wifiConnectHandler = WiFi.onStationModeConnected(std::bind(&ahoywifi::onConnect, this, std::placeholders::_1)); - wifiGotIPHandler = WiFi.onStationModeGotIP(std::bind(&ahoywifi::onGotIP, this, std::placeholders::_1)); - wifiDisconnectHandler = WiFi.onStationModeDisconnected(std::bind(&ahoywifi::onDisconnect, this, std::placeholders::_1)); - #else - WiFi.onEvent(std::bind(&ahoywifi::onWiFiEvent, this, std::placeholders::_1)); - #endif - - setupWifi(true); -} - - -//----------------------------------------------------------------------------- -void ahoywifi::setupWifi(bool startAP = false) { - #if !defined(FB_WIFI_OVERRIDDEN) - if(startAP) { - setupAp(); - delay(1000); - } - #endif - #if !defined(AP_ONLY) - #if defined(FB_WIFI_OVERRIDDEN) - snprintf(mConfig->sys.stationSsid, SSID_LEN, "%s", FB_WIFI_SSID); - snprintf(mConfig->sys.stationPwd, PWD_LEN, "%s", FB_WIFI_PWD); - setupStation(); - #else - if(mConfig->valid) { - if(strncmp(mConfig->sys.stationSsid, FB_WIFI_SSID, 14) != 0) - setupStation(); - } - #endif - #endif -} - - -void ahoywifi::tickWifiLoop() { - static const uint8_t TIMEOUT = 20; - static const uint8_t SCAN_TIMEOUT = 10; - #if !defined(AP_ONLY) - - mCnt++; - - switch (mStaConn) { - case IN_STA_MODE: - // Nothing to do - if (mGotDisconnect) { - mStaConn = RESET; - } - #if !defined(ESP32) - MDNS.update(); - if(WiFi.channel() > 11) - mWasInCh12to14 = true; - #endif - return; - case IN_AP_MODE: - if ((WiFi.softAPgetStationNum() == 0) || (!mStopApAllowed)) { - mCnt = 0; - mDns.stop(); - WiFi.mode(WIFI_AP_STA); - mStaConn = DISCONNECTED; - } else { - mDns.processNextRequest(); - return; - } - break; - case DISCONNECTED: - if ((WiFi.softAPgetStationNum() > 0) && (mStopApAllowed)) { - mStaConn = IN_AP_MODE; - // first time switch to AP Mode - if (mScanActive) { - WiFi.scanDelete(); - mScanActive = false; - } - DBGPRINTLN(F("AP client connected")); - welcome(mApIp.toString(), ""); - WiFi.mode(WIFI_AP); - mDns.start(53, "*", mApIp); - mAppWifiCb(true); - mDns.processNextRequest(); - return; - } else if (!mScanActive) { - DBGPRINT(F("scanning APs with SSID ")); - DBGPRINTLN(String(mConfig->sys.stationSsid)); - mScanCnt = 0; - mCnt = 0; - mScanActive = true; -#if defined(ESP8266) - WiFi.scanNetworks(true, true, 0U, ([this]() { - if (mConfig->sys.isHidden) - return (uint8_t*)NULL; - return (uint8_t*)(mConfig->sys.stationSsid); - })()); -#else - WiFi.scanNetworks(true, true, false, 300U, 0U, ([this]() { - if (mConfig->sys.isHidden) - return (char*)NULL; - return (mConfig->sys.stationSsid); - })()); -#endif - return; - } else if(getBSSIDs()) { - // Scan ready - mStaConn = SCAN_READY; - } else { - // In case of a timeout, what do we do? - // For now we start scanning again as the original code did. - // Would be better to into PA mode - - if (isTimeout(SCAN_TIMEOUT)) { - WiFi.scanDelete(); - mScanActive = false; - } - } - break; - case SCAN_READY: - mStaConn = CONNECTING; - mCnt = 0; - DBGPRINT(F("try to connect to AP with BSSID:")); - uint8_t bssid[6]; - for (int j = 0; j < 6; j++) { - bssid[j] = mBSSIDList.front(); - mBSSIDList.pop_front(); - DBGPRINT(" " + String(bssid[j], HEX)); - } - DBGPRINTLN(""); - mGotDisconnect = false; - WiFi.begin(mConfig->sys.stationSsid, mConfig->sys.stationPwd, 0, &bssid[0]); - - break; - case CONNECTING: - if (isTimeout(TIMEOUT)) { - WiFi.disconnect(); - mStaConn = mBSSIDList.empty() ? DISCONNECTED : SCAN_READY; - } - break; - case CONNECTED: - // Connection but no IP yet - if (isTimeout(TIMEOUT) || mGotDisconnect) { - mStaConn = RESET; - } - break; - case GOT_IP: - welcome(WiFi.localIP().toString(), F(" (Station)")); - if(mStopApAllowed) { - WiFi.softAPdisconnect(); - WiFi.mode(WIFI_STA); - DBGPRINTLN(F("[WiFi] AP disabled")); - delay(100); - } - mAppWifiCb(true); - mGotDisconnect = false; - mStaConn = IN_STA_MODE; - - if (!MDNS.begin(mConfig->sys.deviceName)) { - DPRINTLN(DBG_ERROR, F("Error setting up MDNS responder!")); - } else { - DBGPRINT(F("mDNS established: ")); - DBGPRINT(mConfig->sys.deviceName); - DBGPRINTLN(F(".local")); - } - - break; - case RESET: - mGotDisconnect = false; - mStaConn = DISCONNECTED; - mCnt = 5; // try to reconnect in 5 sec - setupWifi(); // reconnect with AP / Station setup - mAppWifiCb(false); - DPRINTLN(DBG_INFO, "[WiFi] Connection Lost"); - break; - default: - DBGPRINTLN(F("Unhandled status")); - break; - } - -#endif -} - -//----------------------------------------------------------------------------- -void ahoywifi::setupAp(void) { - DPRINTLN(DBG_VERBOSE, F("wifi::setupAp")); - - DBGPRINTLN(F("\n---------\nAhoyDTU Info:")); - DBGPRINT(F("Version: ")); - DBGPRINT(String(VERSION_MAJOR)); - DBGPRINT(F(".")); - DBGPRINT(String(VERSION_MINOR)); - DBGPRINT(F(".")); - DBGPRINTLN(String(VERSION_PATCH)); - DBGPRINT(F("Github Hash: ")); - DBGPRINTLN(String(AUTO_GIT_HASH)); - - DBGPRINT(F("\n---------\nAP MODE\nSSID: ")); - DBGPRINTLN(WIFI_AP_SSID); - DBGPRINT(F("PWD: ")); - DBGPRINTLN(mConfig->sys.apPwd); - DBGPRINT(F("IP Address: http://")); - DBGPRINTLN(mApIp.toString()); - DBGPRINTLN(F("---------\n")); - - if(String(mConfig->sys.deviceName) != "") - WiFi.hostname(mConfig->sys.deviceName); - - WiFi.mode(WIFI_AP_STA); - WiFi.softAPConfig(mApIp, mApIp, IPAddress(255, 255, 255, 0)); - WiFi.softAP(WIFI_AP_SSID, mConfig->sys.apPwd); -} - - -//----------------------------------------------------------------------------- -void ahoywifi::setupStation(void) { - DPRINTLN(DBG_VERBOSE, F("wifi::setupStation")); - if(mConfig->sys.ip.ip[0] != 0) { - IPAddress ip(mConfig->sys.ip.ip); - IPAddress mask(mConfig->sys.ip.mask); - IPAddress dns1(mConfig->sys.ip.dns1); - IPAddress dns2(mConfig->sys.ip.dns2); - IPAddress gateway(mConfig->sys.ip.gateway); - if(!WiFi.config(ip, gateway, mask, dns1, dns2)) - DPRINTLN(DBG_ERROR, F("failed to set static IP!")); - } - mBSSIDList.clear(); - if(String(mConfig->sys.deviceName) != "") - WiFi.hostname(mConfig->sys.deviceName); - WiFi.mode(WIFI_AP_STA); - - DBGPRINT(F("connect to network '")); - DBGPRINT(mConfig->sys.stationSsid); - DBGPRINTLN(F("' ...")); -} - - -//----------------------------------------------------------------------------- -bool ahoywifi::updateNtpTime(void) { - if(IN_STA_MODE != mStaConn) - return false; - - IPAddress timeServer; - uint8_t buf[NTP_PACKET_SIZE]; - uint8_t retry = 0; - - if (WiFi.hostByName(mConfig->ntp.addr, timeServer) != 1) - return false; - - mUdp.begin(mConfig->ntp.port); - sendNTPpacket(timeServer); - - while(retry++ < 5) { - int wait = 150; - while(--wait) { - if(NTP_PACKET_SIZE <= mUdp.parsePacket()) { - uint64_t secsSince1900; - mUdp.read(buf, NTP_PACKET_SIZE); - secsSince1900 = ((uint64_t)buf[40] << 24); - secsSince1900 |= (buf[41] << 16); - secsSince1900 |= (buf[42] << 8); - secsSince1900 |= (buf[43] ); - - *mUtcTimestamp = secsSince1900 - 2208988800UL; // UTC time - DPRINTLN(DBG_INFO, "[NTP]: " + ah::getDateTimeStr(*mUtcTimestamp) + " UTC"); - mOnTimeCb(true); - return true; - } else - delay(10); - } - } - - DPRINTLN(DBG_INFO, F("[NTP]: getNtpTime failed")); - return false; -} - - -//----------------------------------------------------------------------------- -void ahoywifi::sendNTPpacket(IPAddress& address) { - //DPRINTLN(DBG_VERBOSE, F("wifi::sendNTPpacket")); - uint8_t buf[NTP_PACKET_SIZE] = {0}; - - buf[0] = B11100011; // LI, Version, Mode - buf[1] = 0; // Stratum - buf[2] = 6; // Max Interval between messages in seconds - buf[3] = 0xEC; // Clock Precision - // bytes 4 - 11 are for Root Delay and Dispersion and were set to 0 by memset - buf[12] = 49; // four-byte reference ID identifying - buf[13] = 0x4E; - buf[14] = 49; - buf[15] = 52; - - mUdp.beginPacket(address, 123); // NTP request, port 123 - mUdp.write(buf, NTP_PACKET_SIZE); - mUdp.endPacket(); -} - -//----------------------------------------------------------------------------- -void ahoywifi::sortRSSI(int *sort, int n) { - for (int i = 0; i < n; i++) - sort[i] = i; - for (int i = 0; i < n; i++) - for (int j = i + 1; j < n; j++) - if (WiFi.RSSI(sort[j]) > WiFi.RSSI(sort[i])) - std::swap(sort[i], sort[j]); -} - -//----------------------------------------------------------------------------- -void ahoywifi::scanAvailNetworks(void) { - if(!mScanActive) { - mScanActive = true; - if(WIFI_AP == WiFi.getMode()) - WiFi.mode(WIFI_AP_STA); - WiFi.scanNetworks(true); - } -} - -//----------------------------------------------------------------------------- -bool ahoywifi::getAvailNetworks(JsonObject obj) { - JsonArray nets = obj.createNestedArray("networks"); - - int n = WiFi.scanComplete(); - if (n < 0) - return false; - if(n > 0) { - int sort[n]; - sortRSSI(&sort[0], n); - for (int i = 0; i < n; ++i) { - nets[i]["ssid"] = WiFi.SSID(sort[i]); - nets[i]["rssi"] = WiFi.RSSI(sort[i]); - } - } - mScanActive = false; - WiFi.scanDelete(); - if(mStaConn == IN_AP_MODE) - WiFi.mode(WIFI_AP); - - return true; -} - -//----------------------------------------------------------------------------- -bool ahoywifi::getBSSIDs() { - bool result = false; - int n = WiFi.scanComplete(); - if (n < 0) { - if (++mScanCnt < 20) - return false; - } - if(n > 0) { - mBSSIDList.clear(); - int sort[n]; - sortRSSI(&sort[0], n); - for (int i = 0; i < n; i++) { - DBGPRINT("BSSID " + String(i) + ":"); - uint8_t *bssid = WiFi.BSSID(sort[i]); - for (int j = 0; j < 6; j++){ - DBGPRINT(" " + String(bssid[j], HEX)); - mBSSIDList.push_back(bssid[j]); - } - DBGPRINTLN(""); - } - result = true; - } - mScanActive = false; - WiFi.scanDelete(); - return result; -} - -//----------------------------------------------------------------------------- -void ahoywifi::connectionEvent(WiFiStatus_t status) { - DPRINTLN(DBG_INFO, "connectionEvent"); - - switch(status) { - case CONNECTED: - if(mStaConn != CONNECTED) { - mStaConn = CONNECTED; - mGotDisconnect = false; - DBGPRINTLN(F("\n[WiFi] Connected")); - } - break; - - case GOT_IP: - mStaConn = GOT_IP; - break; - - case DISCONNECTED: - mGotDisconnect = true; - break; - - default: - break; - } -} - - -//----------------------------------------------------------------------------- -#if defined(ESP8266) - //------------------------------------------------------------------------- - void ahoywifi::onConnect(const WiFiEventStationModeConnected& event) { - connectionEvent(CONNECTED); - } - - //------------------------------------------------------------------------- - void ahoywifi::onGotIP(const WiFiEventStationModeGotIP& event) { - connectionEvent(GOT_IP); - } - - //------------------------------------------------------------------------- - void ahoywifi::onDisconnect(const WiFiEventStationModeDisconnected& event) { - connectionEvent(DISCONNECTED); - } - -#else - //------------------------------------------------------------------------- - void ahoywifi::onWiFiEvent(WiFiEvent_t event) { - DBGPRINT(F("Wifi event: ")); - DBGPRINTLN(String(event)); - - switch(event) { - case SYSTEM_EVENT_STA_CONNECTED: - connectionEvent(CONNECTED); - break; - - case SYSTEM_EVENT_STA_GOT_IP: - connectionEvent(GOT_IP); - break; - - case SYSTEM_EVENT_STA_DISCONNECTED: - connectionEvent(DISCONNECTED); - break; - - default: - break; - } - } -#endif - - -//----------------------------------------------------------------------------- -void ahoywifi::welcome(String ip, String mode) { - DBGPRINTLN(F("\n\n--------------------------------")); - DBGPRINTLN(F("Welcome to AHOY!")); - DBGPRINT(F("\npoint your browser to http://")); - DBGPRINT(ip); - DBGPRINTLN(mode); - DBGPRINTLN(F("to configure your device")); - DBGPRINTLN(F("--------------------------------\n")); -} - -#endif /* !defined(ETHERNET) */ diff --git a/src/wifi/ahoywifi.h b/src/wifi/ahoywifi.h deleted file mode 100644 index acf6d7d4..00000000 --- a/src/wifi/ahoywifi.h +++ /dev/null @@ -1,100 +0,0 @@ -//------------------------------------//----------------------------------------------------------------------------- -// 2024 Ahoy, https://github.com/lumpapu/ahoy -// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/4.0/deed -//----------------------------------------------------------------------------- - -#if !defined(ETHERNET) -#ifndef __AHOYWIFI_H__ -#define __AHOYWIFI_H__ - -#include "../utils/dbg.h" -#include -#include -#include -#include -#include "ESPAsyncWebServer.h" - -#include "../config/settings.h" - -class app; - -class ahoywifi { - public: - typedef std::function appWifiCb; - typedef std::function OnTimeCB; - - ahoywifi(); - - - void setup(settings_t *config, uint32_t *utcTimestamp, appWifiCb cb, OnTimeCB onTimeCB); - void tickWifiLoop(void); - bool updateNtpTime(void); - void scanAvailNetworks(void); - bool getAvailNetworks(JsonObject obj); - void setStopApAllowedMode(bool allowed) { - mStopApAllowed = allowed; - } - String getStationIp(void) { - return WiFi.localIP().toString(); - } - void setupStation(void); - - bool getWasInCh12to14() const { - return mWasInCh12to14; - } - - private: - typedef enum WiFiStatus { - DISCONNECTED = 0, - SCAN_READY, - CONNECTING, - CONNECTED, - IN_AP_MODE, - GOT_IP, - IN_STA_MODE, - RESET - } WiFiStatus_t; - - void setupWifi(bool startAP); - void setupAp(void); - void sendNTPpacket(IPAddress& address); - void sortRSSI(int *sort, int n); - bool getBSSIDs(void); - void connectionEvent(WiFiStatus_t status); - bool isTimeout(uint8_t timeout) { return (mCnt % timeout) == 0; } - - #if defined(ESP8266) - void onConnect(const WiFiEventStationModeConnected& event); - void onGotIP(const WiFiEventStationModeGotIP& event); - void onDisconnect(const WiFiEventStationModeDisconnected& event); - #else - void onWiFiEvent(WiFiEvent_t event); - #endif - void welcome(String ip, String mode); - - - settings_t *mConfig = nullptr; - appWifiCb mAppWifiCb; - OnTimeCB mOnTimeCb; - - DNSServer mDns; - IPAddress mApIp; - WiFiUDP mUdp; // for time server - #if defined(ESP8266) - WiFiEventHandler wifiConnectHandler, wifiDisconnectHandler, wifiGotIPHandler; - #endif - - WiFiStatus_t mStaConn = DISCONNECTED; - uint8_t mCnt = 0; - uint32_t *mUtcTimestamp = nullptr; - - uint8_t mScanCnt = 0; - bool mScanActive = false; - bool mGotDisconnect = false; - std::list mBSSIDList; - bool mStopApAllowed = false; - bool mWasInCh12to14 = false; -}; - -#endif /*__AHOYWIFI_H__*/ -#endif /* !defined(ETHERNET) */ From bb3f466c925f002c138bf6727a3622efffb60692 Mon Sep 17 00:00:00 2001 From: lumapu Date: Thu, 21 Mar 2024 22:41:02 +0100 Subject: [PATCH 03/21] started ESP8266 wifi refactored platformio.ini --- src/app.h | 6 +- src/network/AhoyNetwork.h | 21 ++-- src/network/AhoyNetworkHelper.h | 24 +++- src/network/AhoyWifiEsp32.h | 6 +- src/network/AhoyWifiEsp8266.h | 110 +++++++++++++++++ src/platformio.ini | 212 ++++---------------------------- 6 files changed, 175 insertions(+), 204 deletions(-) create mode 100644 src/network/AhoyWifiEsp8266.h diff --git a/src/app.h b/src/app.h index b3e5cffa..05b11469 100644 --- a/src/app.h +++ b/src/app.h @@ -39,7 +39,11 @@ #if defined(ETHERNET) #include "network/AhoyEthernet.h" #else /* defined(ETHERNET) */ - #include "network/AhoyWifiEsp32.h" + #if defined(ESP32) + #include "network/AhoyWifiEsp32.h" + #else + #include "network/AhoyWifiEsp8266.h" + #endif #include "utils/improv.h" #endif /* defined(ETHERNET) */ diff --git a/src/network/AhoyNetwork.h b/src/network/AhoyNetwork.h index 952206f0..7c51c38d 100644 --- a/src/network/AhoyNetwork.h +++ b/src/network/AhoyNetwork.h @@ -7,18 +7,11 @@ #define __AHOY_NETWORK_H__ #include "AhoyNetworkHelper.h" -#include #include "../config/settings.h" #include "../utils/helper.h" #include "AhoyWifiAp.h" #include "AsyncJson.h" -#if defined(ESP32) -#include -#else -#include -#endif - #define NTP_PACKET_SIZE 48 class AhoyNetwork { @@ -46,15 +39,15 @@ class AhoyNetwork { #else wifiConnectHandler = WiFi.onStationModeConnected( [this](const WiFiEventStationModeConnected& event) -> void { - OnEvent(SYSTEM_EVENT_STA_CONNECTED); + OnEvent((WiFiEvent_t)SYSTEM_EVENT_STA_CONNECTED); }); wifiGotIPHandler = WiFi.onStationModeGotIP( [this](const WiFiEventStationModeGotIP& event) -> void { - OnEvent(SYSTEM_EVENT_STA_GOT_IP); + OnEvent((WiFiEvent_t)SYSTEM_EVENT_STA_GOT_IP); }); wifiDisconnectHandler = WiFi.onStationModeDisconnected( [this](const WiFiEventStationModeDisconnected& event) -> void { - OnEvent(SYSTEM_EVENT_STA_DISCONNECTED); + OnEvent((WiFiEvent_t)SYSTEM_EVENT_STA_DISCONNECTED); }); #endif } @@ -194,8 +187,14 @@ class AhoyNetwork { NetworkState mStatus = NetworkState::DISCONNECTED; AhoyWifiAp mAp; - AsyncUDP mUdp; // for time server DNSServer mDns; + + #if defined(ESP32) + AsyncUDP mUdp; // for time server + #else + WiFiUDP mUdp; // for time server + WiFiEventHandler wifiConnectHandler, wifiDisconnectHandler, wifiGotIPHandler; + #endif }; #endif /*__AHOY_NETWORK_H__*/ diff --git a/src/network/AhoyNetworkHelper.h b/src/network/AhoyNetworkHelper.h index f814f1db..33f71029 100644 --- a/src/network/AhoyNetworkHelper.h +++ b/src/network/AhoyNetworkHelper.h @@ -8,8 +8,28 @@ #include "../utils/dbg.h" #include -#include -#include +#if defined(ESP32) + #include + #include + #include +#else + #include + #include + //#include + #include "ESPAsyncUDP.h" + + enum { + SYSTEM_EVENT_STA_CONNECTED = 1, + ARDUINO_EVENT_ETH_CONNECTED, + SYSTEM_EVENT_STA_GOT_IP, + ARDUINO_EVENT_ETH_GOT_IP, + ARDUINO_EVENT_WIFI_STA_LOST_IP, + ARDUINO_EVENT_WIFI_STA_STOP, + SYSTEM_EVENT_STA_DISCONNECTED, + ARDUINO_EVENT_ETH_STOP, + ARDUINO_EVENT_ETH_DISCONNECTED + }; +#endif #include namespace ah { diff --git a/src/network/AhoyWifiEsp32.h b/src/network/AhoyWifiEsp32.h index 53d39af3..f9fc064a 100644 --- a/src/network/AhoyWifiEsp32.h +++ b/src/network/AhoyWifiEsp32.h @@ -3,8 +3,8 @@ // Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed //----------------------------------------------------------------------------- -#ifndef __AHOY_Wifi_ESP32_H__ -#define __AHOY_Wifi_ESP32_H__ +#ifndef __AHOY_WIFI_ESP32_H__ +#define __AHOY_WIFI_ESP32_H__ #if defined(ESP32) && !defined(ETHERNET) #include @@ -109,4 +109,4 @@ class AhoyWifi : public AhoyNetwork { }; #endif /*ESP32 & !ETHERNET*/ -#endif /*__AHOY_Wifi_ESP32_H__*/ +#endif /*__AHOY_WIFI_ESP32_H__*/ diff --git a/src/network/AhoyWifiEsp8266.h b/src/network/AhoyWifiEsp8266.h new file mode 100644 index 00000000..1a068797 --- /dev/null +++ b/src/network/AhoyWifiEsp8266.h @@ -0,0 +1,110 @@ +//----------------------------------------------------------------------------- +// 2024 Ahoy, https://ahoydtu.de +// Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed +//----------------------------------------------------------------------------- + +#ifndef __AHOY_WIFI_ESP8266_H__ +#define __AHOY_WIFI_ESP8266_H__ + +#if defined(ESP8266) +#include +#include +#include "AhoyNetwork.h" +#include "ESPAsyncWebServer.h" + +class AhoyWifi : public AhoyNetwork { + public: + void begin() override { + mAp.enable(); + + // static IP + setupIp([this](IPAddress ip, IPAddress gateway, IPAddress mask, IPAddress dns1, IPAddress dns2) -> bool { + return WiFi.config(ip, gateway, mask, dns1, dns2); + }); + + WiFi.setHostname(mConfig->sys.deviceName); + WiFi.begin(mConfig->sys.stationSsid, mConfig->sys.stationPwd); + + DBGPRINT(F("connect to network '")); Serial.flush(); + DBGPRINT(mConfig->sys.stationSsid); + } + + void tickNetworkLoop() override { + if(mAp.isEnabled()) + mAp.tickLoop(); + + switch(mStatus) { + case NetworkState::DISCONNECTED: + if(mConnected) { + mConnected = false; + mOnNetworkCB(false); + mAp.enable(); + } + + if (WiFi.softAPgetStationNum() > 0) { + DBGPRINTLN(F("AP client connected")); + } + break; + + case NetworkState::CONNECTED: + break; + + case NetworkState::GOT_IP: + if(!mConnected) { + mAp.disable(); + mConnected = true; + ah::welcome(WiFi.localIP().toString(), F("Station")); + MDNS.begin(mConfig->sys.deviceName); + mOnNetworkCB(true); + } + break; + } + } + + String getIp(void) override { + return WiFi.localIP().toString(); + } + + void scanAvailNetworks(void) override { + if(!mScanActive) { + mScanActive = true; + WiFi.scanNetworks(true); + } + } + + bool getAvailNetworks(JsonObject obj) override { + JsonArray nets = obj.createNestedArray(F("networks")); + + int n = WiFi.scanComplete(); + if (n < 0) + return false; + if(n > 0) { + int sort[n]; + sortRSSI(&sort[0], n); + for (int i = 0; i < n; ++i) { + nets[i][F("ssid")] = WiFi.SSID(sort[i]); + nets[i][F("rssi")] = WiFi.RSSI(sort[i]); + } + } + mScanActive = false; + WiFi.scanDelete(); + + return true; + } + + private: + void sortRSSI(int *sort, int n) { + for (int i = 0; i < n; i++) + sort[i] = i; + for (int i = 0; i < n; i++) + for (int j = i + 1; j < n; j++) + if (WiFi.RSSI(sort[j]) > WiFi.RSSI(sort[i])) + std::swap(sort[i], sort[j]); + } + + private: + bool mScanActive = false; +}; + +#endif /*ESP8266*/ +#endif /*__AHOY_WIFI_ESP8266_H__*/ diff --git a/src/platformio.ini b/src/platformio.ini index 20f8005a..de9028d0 100644 --- a/src/platformio.ini +++ b/src/platformio.ini @@ -33,6 +33,7 @@ lib_deps = https://github.com/JChristensen/Timezone @ ^1.2.4 olikraus/U8g2 @ ^2.35.9 https://github.com/zinggjm/GxEPD2#1.5.3 + build_flags = -std=c++17 -std=gnu++17 @@ -44,6 +45,9 @@ build_unflags = platform = espressif8266 board = esp12e board_build.f_cpu = 80000000L +lib_deps = + ${env.lib_deps} + https://github.com/me-no-dev/ESPAsyncUDP build_flags = ${env.build_flags} -DEMC_MIN_FREE_MEMORY=4096 -DENABLE_MQTT @@ -156,33 +160,28 @@ build_flags = ${env.build_flags} monitor_filters = esp8266_exception_decoder -[env:esp32-wroom32] +[env:esp32-wroom32-minimal] platform = espressif32@6.5.0 board = lolin_d32 build_flags = ${env.build_flags} -DUSE_HSPI_FOR_EPD - -DENABLE_MQTT - -DPLUGIN_DISPLAY - -DENABLE_HISTORY monitor_filters = esp32_exception_decoder -[env:esp32-wroom32-minimal] +[env:esp32-wroom32] platform = espressif32@6.5.0 board = lolin_d32 -build_flags = ${env.build_flags} - -DUSE_HSPI_FOR_EPD +build_flags = ${env:esp32-wroom32-minimal.build_flags} + -DENABLE_MQTT + -DPLUGIN_DISPLAY + -DENABLE_HISTORY monitor_filters = esp32_exception_decoder [env:esp32-wroom32-de] platform = espressif32@6.5.0 board = lolin_d32 -build_flags = ${env.build_flags} - -DUSE_HSPI_FOR_EPD - -DENABLE_MQTT - -DPLUGIN_DISPLAY - -DENABLE_HISTORY +build_flags = ${env:esp32-wroom32.build_flags} -DLANG_DE monitor_filters = esp32_exception_decoder @@ -190,38 +189,24 @@ monitor_filters = [env:esp32-wroom32-prometheus] platform = espressif32@6.5.0 board = lolin_d32 -build_flags = ${env.build_flags} - -DUSE_HSPI_FOR_EPD +build_flags = ${env:esp32-wroom32.build_flags} -DENABLE_PROMETHEUS_EP - -DENABLE_MQTT - -DPLUGIN_DISPLAY - -DENABLE_HISTORY monitor_filters = esp32_exception_decoder [env:esp32-wroom32-prometheus-de] platform = espressif32@6.5.0 board = lolin_d32 -build_flags = ${env.build_flags} - -DUSE_HSPI_FOR_EPD +build_flags = ${env:esp32-wroom32-prometheus.build_flags} -DLANG_DE - -DENABLE_PROMETHEUS_EP - -DENABLE_MQTT - -DPLUGIN_DISPLAY - -DENABLE_HISTORY monitor_filters = esp32_exception_decoder [env:esp32-wroom32-ethernet] platform = espressif32 board = lolin_d32 -build_flags = ${env.build_flags} +build_flags = ${env:esp32-wroom32.build_flags} -DETHERNET - -DRELEASE - -DUSE_HSPI_FOR_EPD - -DENABLE_MQTT - -DPLUGIN_DISPLAY - -DENABLE_HISTORY -DDEF_ETH_CS_PIN=15 -DDEF_ETH_SCK_PIN=14 -DDEF_ETH_MISO_PIN=12 @@ -240,26 +225,8 @@ monitor_filters = [env:esp32-wroom32-ethernet-de] platform = espressif32 board = lolin_d32 -build_flags = ${env.build_flags} - -DETHERNET - -DRELEASE - -DUSE_HSPI_FOR_EPD +build_flags = ${env:esp32-wroom32-ethernet.build_flags} -DLANG_DE - -DENABLE_MQTT - -DPLUGIN_DISPLAY - -DENABLE_HISTORY - -DDEF_ETH_CS_PIN=15 - -DDEF_ETH_SCK_PIN=14 - -DDEF_ETH_MISO_PIN=12 - -DDEF_ETH_MOSI_PIN=13 - -DDEF_ETH_IRQ_PIN=4 - -DDEF_ETH_RST_PIN=2 - -DDEF_NRF_CS_PIN=5 - -DDEF_NRF_CE_PIN=17 - -DDEF_NRF_IRQ_PIN=16 - -DDEF_NRF_MISO_PIN=19 - -DDEF_NRF_MOSI_PIN=23 - -DDEF_NRF_SCLK_PIN=18 monitor_filters = esp32_exception_decoder @@ -288,22 +255,7 @@ monitor_filters = [env:esp32-s2-mini-de] platform = espressif32@6.5.0 board = lolin_s2_mini -build_flags = ${env.build_flags} - -DUSE_HSPI_FOR_EPD - -DENABLE_MQTT - -DPLUGIN_DISPLAY - -DENABLE_HISTORY - -DDEF_NRF_CS_PIN=12 - -DDEF_NRF_CE_PIN=3 - -DDEF_NRF_IRQ_PIN=5 - -DDEF_NRF_MISO_PIN=9 - -DDEF_NRF_MOSI_PIN=11 - -DDEF_NRF_SCLK_PIN=7 - -DDEF_CMT_CSB=16 - -DDEF_CMT_FCSB=18 - -DDEF_CMT_IRQ=33 - -DDEF_CMT_SDIO=35 - -DDEF_CMT_SCLK=37 +build_flags = ${env:esp32-s2-mini.build_flags} -DLANG_DE monitor_filters = esp32_exception_decoder @@ -333,34 +285,16 @@ monitor_filters = [env:esp32-c3-mini-de] platform = espressif32@6.5.0 board = lolin_c3_mini -build_flags = ${env.build_flags} - -DUSE_HSPI_FOR_EPD - -DENABLE_MQTT - -DPLUGIN_DISPLAY - -DENABLE_HISTORY - -DDEF_NRF_CS_PIN=5 - -DDEF_NRF_CE_PIN=0 - -DDEF_NRF_IRQ_PIN=1 - -DDEF_NRF_MISO_PIN=3 - -DDEF_NRF_MOSI_PIN=4 - -DDEF_NRF_SCLK_PIN=2 - -DDEF_CMT_CSB=255 - -DDEF_CMT_FCSB=255 - -DDEF_CMT_IRQ=255 - -DDEF_CMT_SDIO=255 - -DDEF_CMT_SCLK=255 +build_flags = ${env:esp32-c3-mini.build_flags} -DLANG_DE monitor_filters = esp32_exception_decoder -[env:opendtufusion] +[env:opendtufusion-minimal] platform = espressif32@6.5.0 board = esp32-s3-devkitc-1 upload_protocol = esp-builtin build_flags = ${env.build_flags} - -DENABLE_MQTT - -DPLUGIN_DISPLAY - -DENABLE_HISTORY -DSPI_HAL -DDEF_NRF_CS_PIN=37 -DDEF_NRF_CE_PIN=38 @@ -381,75 +315,32 @@ build_flags = ${env.build_flags} monitor_filters = esp32_exception_decoder, colorize -[env:opendtufusion-de] +[env:opendtufusion] platform = espressif32@6.5.0 board = esp32-s3-devkitc-1 upload_protocol = esp-builtin -build_flags = ${env.build_flags} - -DLANG_DE +build_flags = ${env:opendtufusion-minimal.build_flags} -DENABLE_MQTT -DPLUGIN_DISPLAY -DENABLE_HISTORY - -DSPI_HAL - -DDEF_NRF_CS_PIN=37 - -DDEF_NRF_CE_PIN=38 - -DDEF_NRF_IRQ_PIN=47 - -DDEF_NRF_MISO_PIN=48 - -DDEF_NRF_MOSI_PIN=35 - -DDEF_NRF_SCLK_PIN=36 - -DDEF_CMT_CSB=4 - -DDEF_CMT_FCSB=21 - -DDEF_CMT_IRQ=8 - -DDEF_CMT_SDIO=5 - -DDEF_CMT_SCLK=6 - -DDEF_LED0=18 - -DDEF_LED1=17 - -DLED_ACTIVE_HIGH - -DARDUINO_USB_MODE=1 monitor_filters = esp32_exception_decoder, colorize -[env:opendtufusion-minimal] +[env:opendtufusion-de] platform = espressif32@6.5.0 board = esp32-s3-devkitc-1 upload_protocol = esp-builtin -build_flags = ${env.build_flags} - -DSPI_HAL - -DDEF_NRF_CS_PIN=37 - -DDEF_NRF_CE_PIN=38 - -DDEF_NRF_IRQ_PIN=47 - -DDEF_NRF_MISO_PIN=48 - -DDEF_NRF_MOSI_PIN=35 - -DDEF_NRF_SCLK_PIN=36 - -DDEF_CMT_CSB=4 - -DDEF_CMT_FCSB=21 - -DDEF_CMT_IRQ=8 - -DDEF_CMT_SDIO=5 - -DDEF_CMT_SCLK=6 - -DDEF_LED0=18 - -DDEF_LED1=17 - -DLED_ACTIVE_HIGH - -DARDUINO_USB_MODE=1 +build_flags = ${env:opendtufusion.build_flags} + -DLANG_DE monitor_filters = esp32_exception_decoder, colorize [env:opendtufusion-ethernet] platform = espressif32@6.5.0 board = esp32-s3-devkitc-1 -#lib_deps = -# khoih-prog/AsyncWebServer_ESP32_W5500 -# khoih-prog/AsyncUDP_ESP32_W5500 -# https://github.com/nrf24/RF24 @ ^1.4.8 -# paulstoffregen/Time @ ^1.6.1 -# https://github.com/bertmelis/espMqttClient#v1.6.0 -# bblanchon/ArduinoJson @ ^6.21.3 -# https://github.com/JChristensen/Timezone @ ^1.2.4 -# olikraus/U8g2 @ ^2.35.9 -# https://github.com/zinggjm/GxEPD2#1.5.3 upload_protocol = esp-builtin -build_flags = ${env.build_flags} +build_flags = ${env:opendtufusion-minimal.build_flags} -DETHERNET - -DSPI_HAL -DENABLE_MQTT -DPLUGIN_DISPLAY -DENABLE_HISTORY @@ -459,67 +350,14 @@ build_flags = ${env.build_flags} -DDEF_ETH_MOSI_PIN=40 -DDEF_ETH_IRQ_PIN=44 -DDEF_ETH_RST_PIN=43 - -DDEF_NRF_CS_PIN=37 - -DDEF_NRF_CE_PIN=38 - -DDEF_NRF_IRQ_PIN=47 - -DDEF_NRF_MISO_PIN=48 - -DDEF_NRF_MOSI_PIN=35 - -DDEF_NRF_SCLK_PIN=36 - -DDEF_CMT_CSB=4 - -DDEF_CMT_FCSB=21 - -DDEF_CMT_IRQ=8 - -DDEF_CMT_SDIO=5 - -DDEF_CMT_SCLK=6 - -DDEF_LED0=18 - -DDEF_LED1=17 - -DLED_ACTIVE_HIGH - -DARDUINO_USB_MODE=1 - #-DARDUINO_USB_CDC_ON_BOOT=1 monitor_filters = esp32_exception_decoder, colorize [env:opendtufusion-ethernet-de] platform = espressif32@6.5.0 board = esp32-s3-devkitc-1 -#lib_deps = -# khoih-prog/AsyncWebServer_ESP32_W5500 -# khoih-prog/AsyncUDP_ESP32_W5500 -# https://github.com/nrf24/RF24 @ ^1.4.8 -# paulstoffregen/Time @ ^1.6.1 -# https://github.com/bertmelis/espMqttClient#v1.6.0 -# bblanchon/ArduinoJson @ ^6.21.3 -# https://github.com/JChristensen/Timezone @ ^1.2.4 -# olikraus/U8g2 @ ^2.35.9 -# https://github.com/zinggjm/GxEPD2#1.5.3 upload_protocol = esp-builtin -build_flags = ${env.build_flags} - -DETHERNET - -DSPI_HAL +build_flags = ${env:opendtufusion-ethernet.build_flags} -DLANG_DE - -DENABLE_MQTT - -DPLUGIN_DISPLAY - -DENABLE_HISTORY - -DDEF_ETH_CS_PIN=42 - -DDEF_ETH_SCK_PIN=39 - -DDEF_ETH_MISO_PIN=41 - -DDEF_ETH_MOSI_PIN=40 - -DDEF_ETH_IRQ_PIN=44 - -DDEF_ETH_RST_PIN=43 - -DDEF_NRF_CS_PIN=37 - -DDEF_NRF_CE_PIN=38 - -DDEF_NRF_IRQ_PIN=47 - -DDEF_NRF_MISO_PIN=48 - -DDEF_NRF_MOSI_PIN=35 - -DDEF_NRF_SCLK_PIN=36 - -DDEF_CMT_CSB=4 - -DDEF_CMT_FCSB=21 - -DDEF_CMT_IRQ=8 - -DDEF_CMT_SDIO=5 - -DDEF_CMT_SCLK=6 - -DDEF_LED0=18 - -DDEF_LED1=17 - -DLED_ACTIVE_HIGH - -DARDUINO_USB_MODE=1 - #-DARDUINO_USB_CDC_ON_BOOT=1 monitor_filters = esp32_exception_decoder, colorize From 825c90c59cd3305ad409a3cfc2cc1263f834fc17 Mon Sep 17 00:00:00 2001 From: lumapu Date: Thu, 21 Mar 2024 22:43:27 +0100 Subject: [PATCH 04/21] fix compile --- src/network/AhoyNetwork.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/network/AhoyNetwork.h b/src/network/AhoyNetwork.h index 7c51c38d..3c3489bd 100644 --- a/src/network/AhoyNetwork.h +++ b/src/network/AhoyNetwork.h @@ -189,10 +189,8 @@ class AhoyNetwork { AhoyWifiAp mAp; DNSServer mDns; - #if defined(ESP32) - AsyncUDP mUdp; // for time server - #else - WiFiUDP mUdp; // for time server + AsyncUDP mUdp; // for time server + #if defined(ESP8266) WiFiEventHandler wifiConnectHandler, wifiDisconnectHandler, wifiGotIPHandler; #endif }; From 73c48fab9c1dd887bafe2a9be060d9e5bed54ffd Mon Sep 17 00:00:00 2001 From: lumapu Date: Sun, 24 Mar 2024 16:27:24 +0100 Subject: [PATCH 05/21] esp8266 works --- src/CHANGES.md | 2 ++ src/network/AhoyWifiEsp32.h | 14 ++++++++------ src/network/AhoyWifiEsp8266.h | 8 +++++--- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index af1ecd86..8d89f003 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,7 @@ # Development Changes +## 0.8.98 - 2024-03-23 + ## 0.8.97 - 2024-03-22 * add support for newest generation of inverters with A-F in their serial number * fix NTP and sunrise / sunset diff --git a/src/network/AhoyWifiEsp32.h b/src/network/AhoyWifiEsp32.h index f9fc064a..99733ad2 100644 --- a/src/network/AhoyWifiEsp32.h +++ b/src/network/AhoyWifiEsp32.h @@ -23,12 +23,14 @@ class AhoyWifi : public AhoyNetwork { }); WiFi.setHostname(mConfig->sys.deviceName); - WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN); - WiFi.setSortMethod(WIFI_CONNECT_AP_BY_SIGNAL); - WiFi.begin(mConfig->sys.stationSsid, mConfig->sys.stationPwd, WIFI_ALL_CHANNEL_SCAN); - - DBGPRINT(F("connect to network '")); Serial.flush(); - DBGPRINT(mConfig->sys.stationSsid); + #if !defined(AP_ONLY) + WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN); + WiFi.setSortMethod(WIFI_CONNECT_AP_BY_SIGNAL); + WiFi.begin(mConfig->sys.stationSsid, mConfig->sys.stationPwd, WIFI_ALL_CHANNEL_SCAN); + + DBGPRINT(F("connect to network '")); Serial.flush(); + DBGPRINT(mConfig->sys.stationSsid); + #endif } void tickNetworkLoop() override { diff --git a/src/network/AhoyWifiEsp8266.h b/src/network/AhoyWifiEsp8266.h index 1a068797..16a62b4b 100644 --- a/src/network/AhoyWifiEsp8266.h +++ b/src/network/AhoyWifiEsp8266.h @@ -23,10 +23,12 @@ class AhoyWifi : public AhoyNetwork { }); WiFi.setHostname(mConfig->sys.deviceName); - WiFi.begin(mConfig->sys.stationSsid, mConfig->sys.stationPwd); + #if !defined(AP_ONLY) + WiFi.begin(mConfig->sys.stationSsid, mConfig->sys.stationPwd); - DBGPRINT(F("connect to network '")); Serial.flush(); - DBGPRINT(mConfig->sys.stationSsid); + DBGPRINT(F("connect to network '")); Serial.flush(); + DBGPRINT(mConfig->sys.stationSsid); + #endif } void tickNetworkLoop() override { From 444c97e933d6cc51b9085f87e5fb85b44a92e678 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sun, 24 Mar 2024 16:58:13 +0100 Subject: [PATCH 06/21] 0.8.98 * new network routines --- src/CHANGES.md | 3 +- src/app.cpp | 1 - src/network/AhoyNetwork.h | 4 +- src/network/AhoyWifiEsp8266.h | 86 ++++++++++++++++++++++++++++++++--- 4 files changed, 85 insertions(+), 9 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index 8d89f003..f2cc8785 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,6 +1,7 @@ # Development Changes -## 0.8.98 - 2024-03-23 +## 0.8.98 - 2024-03-24 +* new network routines ## 0.8.97 - 2024-03-22 * add support for newest generation of inverters with A-F in their serial number diff --git a/src/app.cpp b/src/app.cpp index f06e4a53..2dd8c49c 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -162,7 +162,6 @@ void app::loop(void) { //----------------------------------------------------------------------------- void app::onNetwork(bool gotIp) { - DPRINTLN(DBG_INFO, F("onNetwork")); mNetworkConnected = gotIp; ah::Scheduler::resetTicker(); regularTickers(); //reinstall regular tickers diff --git a/src/network/AhoyNetwork.h b/src/network/AhoyNetwork.h index 3c3489bd..59e000bd 100644 --- a/src/network/AhoyNetwork.h +++ b/src/network/AhoyNetwork.h @@ -173,7 +173,9 @@ class AhoyNetwork { enum class NetworkState : uint8_t { DISCONNECTED, CONNECTED, - GOT_IP + GOT_IP, + SCAN_READY, // ESP8266 + CONNECTING // ESP8266 }; protected: diff --git a/src/network/AhoyWifiEsp8266.h b/src/network/AhoyWifiEsp8266.h index 16a62b4b..2db24c21 100644 --- a/src/network/AhoyWifiEsp8266.h +++ b/src/network/AhoyWifiEsp8266.h @@ -8,6 +8,7 @@ #if defined(ESP8266) #include +#include #include #include "AhoyNetwork.h" #include "ESPAsyncWebServer.h" @@ -23,18 +24,15 @@ class AhoyWifi : public AhoyNetwork { }); WiFi.setHostname(mConfig->sys.deviceName); - #if !defined(AP_ONLY) - WiFi.begin(mConfig->sys.stationSsid, mConfig->sys.stationPwd); - - DBGPRINT(F("connect to network '")); Serial.flush(); - DBGPRINT(mConfig->sys.stationSsid); - #endif + mBSSIDList.clear(); } void tickNetworkLoop() override { if(mAp.isEnabled()) mAp.tickLoop(); + mCnt++; + switch(mStatus) { case NetworkState::DISCONNECTED: if(mConnected) { @@ -46,6 +44,45 @@ class AhoyWifi : public AhoyNetwork { if (WiFi.softAPgetStationNum() > 0) { DBGPRINTLN(F("AP client connected")); } + #if !defined(AP_ONLY) + else if (!mScanActive) { + DBGPRINT(F("scanning APs with SSID ")); + DBGPRINTLN(String(mConfig->sys.stationSsid)); + mScanCnt = 0; + mCnt = 0; + mScanActive = true; + WiFi.scanNetworks(true, true, 0U, ([this]() { + if (mConfig->sys.isHidden) + return (uint8_t*)NULL; + return (uint8_t*)(mConfig->sys.stationSsid); + })()); + } else if(getBSSIDs()) { + mStatus = NetworkState::SCAN_READY; + DBGPRINT(F("connect to network '")); Serial.flush(); + DBGPRINTLN(mConfig->sys.stationSsid); + } + #endif + break; + + case NetworkState::SCAN_READY: + mStatus = NetworkState::CONNECTING; + DBGPRINT(F("try to connect to BSSID:")); + uint8_t bssid[6]; + for (int j = 0; j < 6; j++) { + bssid[j] = mBSSIDList.front(); + mBSSIDList.pop_front(); + DBGPRINT(" " + String(bssid[j], HEX)); + } + DBGPRINTLN(""); + mGotDisconnect = false; + WiFi.begin(mConfig->sys.stationSsid, mConfig->sys.stationPwd, 0, &bssid[0]); + break; + + case NetworkState::CONNECTING: + if (isTimeout(TIMEOUT)) { + WiFi.disconnect(); + mStatus = mBSSIDList.empty() ? NetworkState::DISCONNECTED : NetworkState::SCAN_READY; + } break; case NetworkState::CONNECTED: @@ -104,8 +141,45 @@ class AhoyWifi : public AhoyNetwork { std::swap(sort[i], sort[j]); } + bool getBSSIDs() { + bool result = false; + int n = WiFi.scanComplete(); + if (n < 0) { + if (++mScanCnt < 20) + return false; + } + if(n > 0) { + mBSSIDList.clear(); + int sort[n]; + sortRSSI(&sort[0], n); + for (int i = 0; i < n; i++) { + DBGPRINT("BSSID " + String(i) + ":"); + uint8_t *bssid = WiFi.BSSID(sort[i]); + for (int j = 0; j < 6; j++){ + DBGPRINT(" " + String(bssid[j], HEX)); + mBSSIDList.push_back(bssid[j]); + } + DBGPRINTLN(""); + } + result = true; + } + mScanActive = false; + WiFi.scanDelete(); + return result; + } + + bool isTimeout(uint8_t timeout) { + return ((mCnt % timeout) == 0); + } + private: + uint8_t mCnt = 0; + uint8_t mScanCnt = 0; bool mScanActive = false; + bool mGotDisconnect = false; + std::list mBSSIDList; + static constexpr uint8_t TIMEOUT = 20; + static constexpr uint8_t SCAN_TIMEOUT = 10; }; #endif /*ESP8266*/ From 104033073ec36b0a8688d76985c1d241f8a6f1b5 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sun, 24 Mar 2024 16:59:08 +0100 Subject: [PATCH 07/21] 0.8.98 * new network routines --- src/defines.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/defines.h b/src/defines.h index 16a1adf9..2058ce3a 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 97 +#define VERSION_PATCH 98 //------------------------------------- typedef struct { From 92231672e87e514c4f3c6343a0c023ad55b63c8d Mon Sep 17 00:00:00 2001 From: lumapu Date: Mon, 25 Mar 2024 22:25:50 +0100 Subject: [PATCH 08/21] 0.8.98 * fix Ethernet * modified wizard * fix github compile? --- src/app.h | 6 +- src/config/config.h | 2 +- src/config/settings.h | 12 +- src/network/AhoyEthernet.h | 17 +-- src/network/AhoyEthernetSpi.h | 17 ++- src/network/AhoyNetwork.h | 47 ++++++- src/network/AhoyNetworkHelper.h | 2 +- src/network/AhoyWifiEsp32.h | 32 +---- src/network/AhoyWifiEsp8266.h | 43 +------ src/platformio.ini | 55 +++------ src/web/RestApi.h | 18 ++- src/web/html/setup.html | 8 +- src/web/html/wizard.html | 212 +++++++++++++++++++++++++++++++- src/web/lang.json | 35 ++++++ src/web/web.h | 4 +- 15 files changed, 371 insertions(+), 139 deletions(-) diff --git a/src/app.h b/src/app.h index 05b11469..cb546267 100644 --- a/src/app.h +++ b/src/app.h @@ -184,7 +184,11 @@ class app : public IApp, public ah::Scheduler { }*/ bool getWasInCh12to14(void) const override { - return false; // @todo mWifi.getWasInCh12to14(); + #if defined(ESP8266) + return mNetwork->getWasInCh12to14(); + #else + return false; + #endif } #endif /* !defined(ETHERNET) */ diff --git a/src/config/config.h b/src/config/config.h index 23e27a8c..a4b84934 100644 --- a/src/config/config.h +++ b/src/config/config.h @@ -78,7 +78,7 @@ #define DEF_ETH_CS_PIN 15 #endif #ifndef DEF_ETH_RST_PIN - #define DEF_ETH_RST_PIN 2 + #define DEF_ETH_RST_PIN DEF_PIN_OFF #endif #else /* defined(ETHERNET) */ // time in seconds how long the station info (ssid + pwd) will be tried diff --git a/src/config/settings.h b/src/config/settings.h index fb8689b9..8f20ba8f 100644 --- a/src/config/settings.h +++ b/src/config/settings.h @@ -405,13 +405,17 @@ class settings { else { snprintf(mCfg.sys.stationSsid, SSID_LEN, FB_WIFI_SSID); snprintf(mCfg.sys.stationPwd, PWD_LEN, FB_WIFI_PWD); - snprintf(mCfg.sys.apPwd, PWD_LEN, WIFI_AP_PWD); mCfg.sys.isHidden = false; } #endif + snprintf(mCfg.sys.apPwd, PWD_LEN, WIFI_AP_PWD); #if defined(ETHERNET) - mCfg.sys.eth.enabled = false; + #if defined(DEF_ETH_ENABLED) + mCfg.sys.eth.enabled = true; + #else + mCfg.sys.eth.enabled = false; + #endif mCfg.sys.eth.pinCs = DEF_ETH_CS_PIN; mCfg.sys.eth.pinSclk = DEF_ETH_SCK_PIN; mCfg.sys.eth.pinMiso = DEF_ETH_MISO_PIN; @@ -431,7 +435,11 @@ class settings { mCfg.nrf.pinMosi = DEF_NRF_MOSI_PIN; mCfg.nrf.pinSclk = DEF_NRF_SCLK_PIN; + #if defined(ETHERNET) + mCfg.nrf.enabled = false; + #else mCfg.nrf.enabled = true; + #endif #if defined(ESP32) mCfg.cmt.pinSclk = DEF_CMT_SCLK; diff --git a/src/network/AhoyEthernet.h b/src/network/AhoyEthernet.h index ce176ec3..db624a41 100644 --- a/src/network/AhoyEthernet.h +++ b/src/network/AhoyEthernet.h @@ -18,12 +18,16 @@ class AhoyEthernet : public AhoyNetwork { void begin() override { mAp.enable(); + if(!mConfig->sys.eth.enabled) + return; + + mEthSpi.begin(mConfig->sys.eth.pinMiso, mConfig->sys.eth.pinMosi, mConfig->sys.eth.pinSclk, mConfig->sys.eth.pinCs, mConfig->sys.eth.pinIrq, mConfig->sys.eth.pinRst); + ETH.setHostname(mConfig->sys.deviceName); + // static IP setupIp([this](IPAddress ip, IPAddress gateway, IPAddress mask, IPAddress dns1, IPAddress dns2) -> bool { return ETH.config(ip, gateway, mask, dns1, dns2); }); - - ETH.setHostname(mConfig->sys.deviceName); } void tickNetworkLoop() override { @@ -43,9 +47,8 @@ class AhoyEthernet : public AhoyNetwork { break; case NetworkState::GOT_IP: - mAp.disable(); - if(!mConnected) { + mAp.disable(); mConnected = true; ah::welcome(ETH.localIP().toString(), F("Station")); MDNS.begin(mConfig->sys.deviceName); @@ -59,10 +62,8 @@ class AhoyEthernet : public AhoyNetwork { return ETH.localIP().toString(); } - void scanAvailNetworks(void) override {}; - bool getAvailNetworks(JsonObject obj) override { - return false; - } + private: + AhoyEthernetSpi mEthSpi; }; #endif /*ETHERNET*/ diff --git a/src/network/AhoyEthernetSpi.h b/src/network/AhoyEthernetSpi.h index 12e58e4d..b41431b4 100644 --- a/src/network/AhoyEthernetSpi.h +++ b/src/network/AhoyEthernetSpi.h @@ -26,9 +26,11 @@ class AhoyEthernetSpi { eth_netif(nullptr) {} void begin(int8_t pin_miso, int8_t pin_mosi, int8_t pin_sclk, int8_t pin_cs, int8_t pin_int, int8_t pin_rst) { - gpio_reset_pin(static_cast(pin_rst)); - gpio_set_direction(static_cast(pin_rst), GPIO_MODE_OUTPUT); - gpio_set_level(static_cast(pin_rst), 0); + if(-1 != pin_rst) { + gpio_reset_pin(static_cast(pin_rst)); + gpio_set_direction(static_cast(pin_rst), GPIO_MODE_OUTPUT); + gpio_set_level(static_cast(pin_rst), 0); + } gpio_reset_pin(static_cast(pin_sclk)); gpio_reset_pin(static_cast(pin_mosi)); @@ -42,6 +44,7 @@ class AhoyEthernetSpi { gpio_reset_pin(static_cast(pin_int)); gpio_set_pull_mode(static_cast(pin_int), GPIO_PULLUP_ONLY); + spi_bus_config_t buscfg = { .mosi_io_num = pin_mosi, .miso_io_num = pin_miso, @@ -80,9 +83,11 @@ class AhoyEthernetSpi { ESP_ERROR_CHECK(spi_bus_add_device(SPI3_HOST, &devcfg, &spi)); // Reset sequence - delayMicroseconds(500); - gpio_set_level(static_cast(pin_rst), 1); - delayMicroseconds(1000); + if(-1 != pin_rst) { + delayMicroseconds(500); + gpio_set_level(static_cast(pin_rst), 1); + delayMicroseconds(1000); + } // Arduino function to start networking stack if not already started tcpipInit(); diff --git a/src/network/AhoyNetwork.h b/src/network/AhoyNetwork.h index 59e000bd..5ce668df 100644 --- a/src/network/AhoyNetwork.h +++ b/src/network/AhoyNetwork.h @@ -80,8 +80,39 @@ class AhoyNetwork { virtual void begin() = 0; virtual void tickNetworkLoop() = 0; virtual String getIp(void) = 0; - virtual void scanAvailNetworks(void) = 0; - virtual bool getAvailNetworks(JsonObject obj) = 0; + + virtual bool getWasInCh12to14() { + return false; + } + + #if !defined(ETHERNET) + void scanAvailNetworks(void) { + if(!mScanActive) { + mScanActive = true; + WiFi.scanNetworks(true); + } + } + + bool getAvailNetworks(JsonObject obj) { + JsonArray nets = obj.createNestedArray(F("networks")); + + int n = WiFi.scanComplete(); + if (n < 0) + return false; + if(n > 0) { + int sort[n]; + sortRSSI(&sort[0], n); + for (int i = 0; i < n; ++i) { + nets[i][F("ssid")] = WiFi.SSID(sort[i]); + nets[i][F("rssi")] = WiFi.RSSI(sort[i]); + } + } + mScanActive = false; + WiFi.scanDelete(); + + return true; + } + #endif protected: void setupIp(std::function cb) { @@ -169,6 +200,17 @@ class AhoyNetwork { mUdp.close(); } + #if !defined(ETHERNET) + void sortRSSI(int *sort, int n) { + for (int i = 0; i < n; i++) + sort[i] = i; + for (int i = 0; i < n; i++) + for (int j = i + 1; j < n; j++) + if (WiFi.RSSI(sort[j]) > WiFi.RSSI(sort[i])) + std::swap(sort[i], sort[j]); + } + #endif + protected: enum class NetworkState : uint8_t { DISCONNECTED, @@ -182,6 +224,7 @@ class AhoyNetwork { settings_t *mConfig = nullptr; uint32_t *mUtcTimestamp = nullptr; bool mConnected = false; + bool mScanActive = false; OnNetworkCB mOnNetworkCB; OnTimeCB mOnTimeCB; diff --git a/src/network/AhoyNetworkHelper.h b/src/network/AhoyNetworkHelper.h index 33f71029..378ba033 100644 --- a/src/network/AhoyNetworkHelper.h +++ b/src/network/AhoyNetworkHelper.h @@ -9,7 +9,7 @@ #include "../utils/dbg.h" #include #if defined(ESP32) - #include + #include "ESPAsyncWebServer.h" #include #include #else diff --git a/src/network/AhoyWifiEsp32.h b/src/network/AhoyWifiEsp32.h index 99733ad2..255f2b03 100644 --- a/src/network/AhoyWifiEsp32.h +++ b/src/network/AhoyWifiEsp32.h @@ -9,8 +9,8 @@ #if defined(ESP32) && !defined(ETHERNET) #include #include -#include #include "AhoyNetwork.h" +#include "ESPAsyncWebServer.h" class AhoyWifi : public AhoyNetwork { public: @@ -69,33 +69,6 @@ class AhoyWifi : public AhoyNetwork { return WiFi.localIP().toString(); } - void scanAvailNetworks(void) override { - if(!mScanActive) { - mScanActive = true; - WiFi.scanNetworks(true); - } - } - - bool getAvailNetworks(JsonObject obj) override { - JsonArray nets = obj.createNestedArray(F("networks")); - - int n = WiFi.scanComplete(); - if (n < 0) - return false; - if(n > 0) { - int sort[n]; - sortRSSI(&sort[0], n); - for (int i = 0; i < n; ++i) { - nets[i][F("ssid")] = WiFi.SSID(sort[i]); - nets[i][F("rssi")] = WiFi.RSSI(sort[i]); - } - } - mScanActive = false; - WiFi.scanDelete(); - - return true; - } - private: void sortRSSI(int *sort, int n) { for (int i = 0; i < n; i++) @@ -105,9 +78,6 @@ class AhoyWifi : public AhoyNetwork { if (WiFi.RSSI(sort[j]) > WiFi.RSSI(sort[i])) std::swap(sort[i], sort[j]); } - - private: - bool mScanActive = false; }; #endif /*ESP32 & !ETHERNET*/ diff --git a/src/network/AhoyWifiEsp8266.h b/src/network/AhoyWifiEsp8266.h index 2db24c21..b9417556 100644 --- a/src/network/AhoyWifiEsp8266.h +++ b/src/network/AhoyWifiEsp8266.h @@ -74,7 +74,6 @@ class AhoyWifi : public AhoyNetwork { DBGPRINT(" " + String(bssid[j], HEX)); } DBGPRINTLN(""); - mGotDisconnect = false; WiFi.begin(mConfig->sys.stationSsid, mConfig->sys.stationPwd, 0, &bssid[0]); break; @@ -96,6 +95,9 @@ class AhoyWifi : public AhoyNetwork { MDNS.begin(mConfig->sys.deviceName); mOnNetworkCB(true); } + + if(WiFi.channel() > 11) + mWasInCh12to14 = true; break; } } @@ -104,43 +106,11 @@ class AhoyWifi : public AhoyNetwork { return WiFi.localIP().toString(); } - void scanAvailNetworks(void) override { - if(!mScanActive) { - mScanActive = true; - WiFi.scanNetworks(true); - } - } - - bool getAvailNetworks(JsonObject obj) override { - JsonArray nets = obj.createNestedArray(F("networks")); - - int n = WiFi.scanComplete(); - if (n < 0) - return false; - if(n > 0) { - int sort[n]; - sortRSSI(&sort[0], n); - for (int i = 0; i < n; ++i) { - nets[i][F("ssid")] = WiFi.SSID(sort[i]); - nets[i][F("rssi")] = WiFi.RSSI(sort[i]); - } - } - mScanActive = false; - WiFi.scanDelete(); - - return true; + bool getWasInCh12to14() override { + return mWasInCh12to14; } private: - void sortRSSI(int *sort, int n) { - for (int i = 0; i < n; i++) - sort[i] = i; - for (int i = 0; i < n; i++) - for (int j = i + 1; j < n; j++) - if (WiFi.RSSI(sort[j]) > WiFi.RSSI(sort[i])) - std::swap(sort[i], sort[j]); - } - bool getBSSIDs() { bool result = false; int n = WiFi.scanComplete(); @@ -175,9 +145,8 @@ class AhoyWifi : public AhoyNetwork { private: uint8_t mCnt = 0; uint8_t mScanCnt = 0; - bool mScanActive = false; - bool mGotDisconnect = false; std::list mBSSIDList; + bool mWasInCh12to14 = false; static constexpr uint8_t TIMEOUT = 20; static constexpr uint8_t SCAN_TIMEOUT = 10; }; diff --git a/src/platformio.ini b/src/platformio.ini index de9028d0..4d0d528d 100644 --- a/src/platformio.ini +++ b/src/platformio.ini @@ -41,6 +41,16 @@ build_unflags = -std=gnu++11 +[env:esp8266-minimal] +platform = espressif8266 +board = esp12e +board_build.f_cpu = 80000000L +build_flags = ${env.build_flags} + -DEMC_MIN_FREE_MEMORY=4096 + ;-Wl,-Map,output.map +monitor_filters = + esp8266_exception_decoder + [env:esp8266] platform = espressif8266 board = esp12e @@ -48,10 +58,8 @@ board_build.f_cpu = 80000000L lib_deps = ${env.lib_deps} https://github.com/me-no-dev/ESPAsyncUDP -build_flags = ${env.build_flags} - -DEMC_MIN_FREE_MEMORY=4096 +build_flags = ${env:esp8266-minimal.build_flags} -DENABLE_MQTT - ;-Wl,-Map,output.map monitor_filters = esp8266_exception_decoder @@ -59,11 +67,8 @@ monitor_filters = platform = espressif8266 board = esp12e board_build.f_cpu = 80000000L -build_flags = ${env.build_flags} - -DEMC_MIN_FREE_MEMORY=4096 +build_flags = ${env:esp8266.build_flags} -DLANG_DE - -DENABLE_MQTT - ;-Wl,-Map,output.map monitor_filters = esp8266_exception_decoder @@ -71,12 +76,9 @@ monitor_filters = platform = espressif8266 board = esp12e board_build.f_cpu = 80000000L -build_flags = ${env.build_flags} - -DEMC_MIN_FREE_MEMORY=4096 - -DENABLE_MQTT +build_flags = ${env:esp8266.build_flags} -DPLUGIN_DISPLAY -DENABLE_HISTORY - ;-Wl,-Map,output.map monitor_filters = esp8266_exception_decoder @@ -84,13 +86,8 @@ monitor_filters = platform = espressif8266 board = esp12e board_build.f_cpu = 80000000L -build_flags = ${env.build_flags} - -DEMC_MIN_FREE_MEMORY=4096 +build_flags = ${env:esp8266-all.build_flags} -DLANG_DE - -DENABLE_MQTT - -DPLUGIN_DISPLAY - -DENABLE_HISTORY - ;-Wl,-Map,output.map monitor_filters = esp8266_exception_decoder @@ -98,12 +95,8 @@ monitor_filters = platform = espressif8266 board = esp12e board_build.f_cpu = 80000000L -build_flags = ${env.build_flags} - -DEMC_MIN_FREE_MEMORY=4096 +build_flags = ${env:esp8266-all.build_flags} -DENABLE_PROMETHEUS_EP - -DENABLE_MQTT - -DPLUGIN_DISPLAY - -DENABLE_HISTORY monitor_filters = esp8266_exception_decoder @@ -111,23 +104,8 @@ monitor_filters = platform = espressif8266 board = esp12e board_build.f_cpu = 80000000L -build_flags = ${env.build_flags} - -DEMC_MIN_FREE_MEMORY=4096 - -DENABLE_PROMETHEUS_EP +build_flags = ${env:esp8266-prometheus.build_flags} -DLANG_DE - -DENABLE_MQTT - -DPLUGIN_DISPLAY - -DENABLE_HISTORY -monitor_filters = - esp8266_exception_decoder - -[env:esp8266-minimal] -platform = espressif8266 -board = esp12e -board_build.f_cpu = 80000000L -build_flags = ${env.build_flags} - -DEMC_MIN_FREE_MEMORY=4096 - ;-Wl,-Map,output.map monitor_filters = esp8266_exception_decoder @@ -350,6 +328,7 @@ build_flags = ${env:opendtufusion-minimal.build_flags} -DDEF_ETH_MOSI_PIN=40 -DDEF_ETH_IRQ_PIN=44 -DDEF_ETH_RST_PIN=43 + -DDEF_ETH_ENABLED monitor_filters = esp32_exception_decoder, colorize diff --git a/src/web/RestApi.h b/src/web/RestApi.h index f4c655b5..8087883e 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -375,14 +375,12 @@ class RestApi { } void getSysInfo(AsyncWebServerRequest *request, JsonObject obj) { + obj[F("ap_pwd")] = mConfig->sys.apPwd; #if !defined(ETHERNET) obj[F("ssid")] = mConfig->sys.stationSsid; - obj[F("ap_pwd")] = mConfig->sys.apPwd; obj[F("hidd")] = mConfig->sys.isHidden; obj[F("mac")] = WiFi.macAddress(); obj[F("wifi_channel")] = WiFi.channel(); - #else - getEthernet(obj.createNestedObject(F("eth"))); #endif /* !defined(ETHERNET) */ obj[F("device_name")] = mConfig->sys.deviceName; obj[F("dark_mode")] = (bool)mConfig->sys.darkMode; @@ -882,6 +880,9 @@ class RestApi { #if defined(ESP32) getRadioCmt(obj.createNestedObject(F("radioCmt"))); #endif + #if defined(ETHERNET) + getEthernet(obj.createNestedObject(F("eth"))); + #endif getRadioNrf(obj.createNestedObject(F("radioNrf"))); getSerial(obj.createNestedObject(F("serial"))); getStaticIp(obj.createNestedObject(F("static_ip"))); @@ -1051,6 +1052,17 @@ class RestApi { //mApp->setStopApAllowedMode(false); mApp->setupStation(); } + #else + else if(F("save_eth") == jsonIn[F("cmd")]) { + mConfig->sys.eth.enabled = jsonIn[F("en")].as(); + mConfig->sys.eth.pinCs = jsonIn[F("cs")].as(); + mConfig->sys.eth.pinSclk = jsonIn[F("sclk")].as(); + mConfig->sys.eth.pinMiso = jsonIn[F("miso")].as(); + mConfig->sys.eth.pinMosi = jsonIn[F("mosi")].as(); + mConfig->sys.eth.pinIrq = jsonIn[F("irq")].as(); + mConfig->sys.eth.pinRst = jsonIn[F("reset")].as(); + mApp->saveSettings(true); + } #endif /* !defined(ETHERNET */ else if(F("save_iv") == jsonIn[F("cmd")]) { Inverter<> *iv = mSys->getInverterByPos(jsonIn[F("id")], false); diff --git a/src/web/html/setup.html b/src/web/html/setup.html index 9af66314..fb1eff97 100644 --- a/src/web/html/setup.html +++ b/src/web/html/setup.html @@ -949,7 +949,7 @@ } } - function parsePinout(obj, type, system) { + function parsePinout(obj) { var e = document.getElementById("pinout"); /*IF_ESP32*/ var pinList = esp32pins; @@ -1291,13 +1291,13 @@ parseMqtt(root["mqtt"]); parseNtp(root["ntp"]); parseSun(root["sun"]); - parsePinout(root["pinout"], root["system"]["esp_type"], root["system"]); + parsePinout(root.pinout); parseNrfRadio(root["radioNrf"], root["pinout"]); /*IF_ESP32*/ - parseCmtRadio(root["radioCmt"]); + parseCmtRadio(root.radioCmt); /*ENDIF_ESP32*/ /*IF_ETHERNET*/ - parseEth(root.system.eth) + parseEth(root.eth) /*ENDIF_ETHERNET*/ parseSerial(root["serial"]); /*IF_PLUGIN_DISPLAY*/ diff --git a/src/web/html/wizard.html b/src/web/html/wizard.html index 3df44dc4..179adb5a 100644 --- a/src/web/html/wizard.html +++ b/src/web/html/wizard.html @@ -15,6 +15,165 @@ var found = false; var c = document.getElementById("con"); + /*IF_ESP32*/ + var pinList = [ + [255, "{#PIN_OFF}"], + [0, "GPIO0"], + [1, "TX (GPIO1)"], + [2, "GPIO2 (LED)"], + [3, "RX (GPIO3)"], + [4, "GPIO4"], + [5, "GPIO5"], + [12, "GPIO12 (HSPI MISO)"], + [13, "GPIO13 (HSPI MOSI)"], + [14, "GPIO14 (HSPI SCLK)"], + [15, "GPIO15"], + [16, "GPIO16"], + [17, "GPIO17"], + [18, "GPIO18 (VSPI SCLK)"], + [19, "GPIO19 (VSPI MISO)"], + [21, "GPIO21 (SDA)"], + [22, "GPIO22 (SCL)"], + [23, "GPIO23 (VSPI MOSI)"], + [25, "GPIO25"], + [26, "GPIO26"], + [27, "GPIO27"], + [32, "GPIO32"], + [33, "GPIO33"], + [34, "GPIO34 ({#PIN_INPUT_ONLY})"], + [35, "GPIO35 ({#PIN_INPUT_ONLY})"], + [36, "VP (GPIO36, {#PIN_INPUT_ONLY})"], + [39, "VN (GPIO39, {#PIN_INPUT_ONLY})"] + ]; + /*IF_ESP32-S2*/ + pinList = [ + [255, "off / default"], + [0, "GPIO0 ({#PIN_DONT_USE} - BOOT)"], + [1, "GPIO1"], + [2, "GPIO2"], + [3, "GPIO3"], + [4, "GPIO4"], + [5, "GPIO5"], + [6, "GPIO6"], + [7, "GPIO7"], + [8, "GPIO8"], + [9, "GPIO9"], + [10, "GPIO10"], + [11, "GPIO11"], + [12, "GPIO12"], + [13, "GPIO13"], + [14, "GPIO14"], + [15, "GPIO15"], + [16, "GPIO16"], + [17, "GPIO17"], + [18, "GPIO18"], + [19, "GPIO19 ({#PIN_DONT_USE} - USB-)"], + [20, "GPIO20 ({#PIN_DONT_USE} - USB+)"], + [21, "GPIO21"], + [26, "GPIO26 (PSRAM - {#PIN_NOT_AVAIL})"], + [27, "GPIO27 (FLASH - {#PIN_NOT_AVAIL})"], + [28, "GPIO28 (FLASH - {#PIN_NOT_AVAIL})"], + [29, "GPIO29 (FLASH - {#PIN_NOT_AVAIL})"], + [30, "GPIO30 (FLASH - {#PIN_NOT_AVAIL})"], + [31, "GPIO31 (FLASH - {#PIN_NOT_AVAIL})"], + [32, "GPIO32 (FLASH - {#PIN_NOT_AVAIL})"], + [33, "GPIO33 (not exposed on S3-WROOM modules)"], + [34, "GPIO34 (not exposed on S3-WROOM modules)"], + [35, "GPIO35"], + [36, "GPIO36"], + [37, "GPIO37"], + [38, "GPIO38"], + [39, "GPIO39"], + [40, "GPIO40"], + [41, "GPIO41"], + [42, "GPIO42"], + [43, "GPIO43"], + [44, "GPIO44"], + [45, "GPIO45 ({#PIN_DONT_USE} - STRAPPING PIN)"], + [46, "GPIO46 ({#PIN_DONT_USE} - STRAPPING PIN)"], + [47, "GPIO47"], + [48, "GPIO48"], + ]; + /*ENDIF_ESP32-S2*/ + /*IF_ESP32-S3*/ + pinList = [ + [255, "off / default"], + [0, "GPIO0 ({#PIN_DONT_USE} - BOOT)"], + [1, "GPIO1"], + [2, "GPIO2"], + [3, "GPIO3"], + [4, "GPIO4"], + [5, "GPIO5"], + [6, "GPIO6"], + [7, "GPIO7"], + [8, "GPIO8"], + [9, "GPIO9"], + [10, "GPIO10"], + [11, "GPIO11"], + [12, "GPIO12"], + [13, "GPIO13"], + [14, "GPIO14"], + [15, "GPIO15"], + [16, "GPIO16"], + [17, "GPIO17"], + [18, "GPIO18"], + [19, "GPIO19 ({#PIN_DONT_USE} - USB-)"], + [20, "GPIO20 ({#PIN_DONT_USE} - USB+)"], + [21, "GPIO21"], + [26, "GPIO26 (PSRAM - {#PIN_NOT_AVAIL})"], + [27, "GPIO27 (FLASH - {#PIN_NOT_AVAIL})"], + [28, "GPIO28 (FLASH - {#PIN_NOT_AVAIL})"], + [29, "GPIO29 (FLASH - {#PIN_NOT_AVAIL})"], + [30, "GPIO30 (FLASH - {#PIN_NOT_AVAIL})"], + [31, "GPIO31 (FLASH - {#PIN_NOT_AVAIL})"], + [32, "GPIO32 (FLASH - {#PIN_NOT_AVAIL})"], + [33, "GPIO33 (not exposed on S3-WROOM modules)"], + [34, "GPIO34 (not exposed on S3-WROOM modules)"], + [35, "GPIO35"], + [36, "GPIO36"], + [37, "GPIO37"], + [38, "GPIO38"], + [39, "GPIO39"], + [40, "GPIO40"], + [41, "GPIO41"], + [42, "GPIO42"], + [43, "GPIO43"], + [44, "GPIO44"], + [45, "GPIO45 ({#PIN_DONT_USE} - STRAPPING PIN)"], + [46, "GPIO46 ({#PIN_DONT_USE} - STRAPPING PIN)"], + [47, "GPIO47"], + [48, "GPIO48"], + ]; + /*ENDIF_ESP32-S3*/ + /*IF_ESP32-C3*/ + pinList = [ + [255, "off / default"], + [0, "GPIO0"], + [1, "GPIO1"], + [2, "GPIO2"], + [3, "GPIO3"], + [4, "GPIO4"], + [5, "GPIO5"], + [6, "GPIO6"], + [7, "GPIO7"], + [8, "GPIO8"], + [9, "GPIO9"], + [10, "GPIO10"], + [11, "GPIO11"], + [12, "GPIO12 (PSRAM/FLASH)"], + [13, "GPIO13 (PSRAM/FLASH)"], + [14, "GPIO14 (PSRAM/FLASH)"], + [15, "GPIO15 (PSRAM/FLASH)"], + [16, "GPIO16 (PSRAM/FLASH)"], + [17, "GPIO17 (PSRAM/FLASH)"], + [18, "GPIO18 ({#PIN_DONT_USE} - USB-)"], + [19, "GPIO19 ({#PIN_DONT_USE} - USB+)"], + [20, "GPIO20 (RX)"], + [21, "GPIO21 (TX)"], + ]; + /*ENDIF_ESP32-C3*/ + /*ENDIF_ESP32*/ + function sect(e1, e2) { return ml("div", {class: "row"}, [ ml("div", {class: "col-12"}, ml("p", {}, e1)), @@ -22,7 +181,36 @@ ]) } - function wifi() { + /*IF_ETHERNET*/ + var pins = ['cs', 'sclk', 'miso', 'mosi', 'irq', 'reset'] + function step1(obj) { + console.log(obj) + lst = [] + for(p of pins) { + lst.push( + ml("div", {class: "row mb-3"}, [ + ml("div", {class: "col-12 col-sm-3 my-2"}, p.toUpperCase()), + ml("div", {class: "col-12 col-sm-9"}, + sel(p, pinList, obj[p]) + ) + ]) + ) + } + let en = inp("en", null, null, ["cb"], "en", "checkbox"); + en.checked = obj["en"]; + + return sect("{#NETWORK_SETUP}", [ + ml("div", {class: "row mb-3"}, [ + ml("div", {class: "col-8"}, "{#ETH_ENABLE}"), + ml("div", {class: "col-4"}, en) + ]), + ...lst, + ml("div", {class: "row my-4"}, ml("div", {class: "col a-r"}, ml("input", {type: "button", class:"btn", value: "{#BTN_REBOOT}", onclick: () => {saveEth()}}, null))), + ml("div", {class: "row mt-5"}, ml("div", {class: "col a-c"}, ml("a", {href: "http://192.168.4.1/"}, "{#STOP_WIZARD}"))) + ]) + } + /*ELSE*/ + function step1() { return ml("div", {}, [ ml("div", {class: "row my-5"}, ml("div", {class: "col"}, ml("span", {class: "fs-1"}, "{#WELCOME}"))), ml("div", {class: "row"}, ml("div", {class: "col"}, ml("span", {class: "fs-5"}, "{#NETWORK_SETUP}"))), @@ -33,6 +221,7 @@ ml("div", {class: "row mt-5"}, ml("div", {class: "col a-c"}, ml("a", {href: "http://192.168.4.1/"}, "{#STOP_WIZARD}"))) ]) } + /*ENDIF_ETHERNET*/ function checkWifi() { c.replaceChildren( @@ -57,13 +246,29 @@ } } + /*IF_ETHERNET*/ + function saveEth() { + let o = { + cmd: "save_eth", + en: document.getElementsByName("en")[0].checked + } + for(p of pins) { + o[p] = document.getElementsByName(p)[0].value + } + getAjax("/api/setup", ((o) => {}), "POST", JSON.stringify(o)); + } + /*ELSE*/ function saveWifi() { var ssid = document.getElementById("net").value; if(-1 == ssid) ssid = document.getElementById("man").value; getAjax("/api/setup", ((o) => {if(!o.error) checkWifi()}), "POST", JSON.stringify({cmd: "save_wifi", ssid: ssid, pwd: document.getElementById("pwd").value})); } + /*ENDIF_ETHERNET*/ + /*IF_ETHERNET*/ + getAjax("/api/setup", ((o) => c.append(step1(o.eth)))); + /*ELSE*/ function nets(obj) { var e = document.getElementById("net"); if(obj.networks.length > 0) { @@ -79,9 +284,10 @@ } getAjax("/api/setup", ((o) => {}), "POST", JSON.stringify({cmd: "scan_wifi"})); - c.append(wifi()) - + c.append(step1()) v = setInterval(() => {getAjax('/api/setup/networks', nets)}, 2500); + /*ENDIF_ETHERNET*/ + diff --git a/src/web/lang.json b/src/web/lang.json index 22449f30..f2274b69 100644 --- a/src/web/lang.json +++ b/src/web/lang.json @@ -83,6 +83,11 @@ "en": "next >>", "de": "prüfen >>" }, + { + "token": "BTN_REBOOT", + "en": "reboot >>", + "de": "Ahoy neustarten >>" + }, { "token": "TEST_CONNECTION", "en": "Test Connection", @@ -112,6 +117,36 @@ "token": "NUM_NETWORKS_FOUND", "en": "Network(s) found", "de": "Netzwerk(e) gefunden" + }, + { + "token": "PIN_OFF", + "en": "off / default", + "de": "aus / Standard" + }, + { + "token": "PIN_NO_IRQ", + "en": "no IRQ!", + "de": "kein Interrupt!" + }, + { + "token": "PIN_INPUT_ONLY", + "en": "in only", + "de": "nur Eingang" + }, + { + "token": "PIN_DONT_USE", + "en": "DONT USE", + "de": "nicht benutzen" + }, + { + "token": "PIN_NOT_AVAIL", + "en": "not available", + "de": "nicht verfügbar" + }, + { + "token": "ETH_ENABLE", + "en": "Ethernet enable", + "de": "Ethernet aktivieren" } ] }, diff --git a/src/web/web.h b/src/web/web.h index f4389163..419d6826 100644 --- a/src/web/web.h +++ b/src/web/web.h @@ -447,10 +447,10 @@ class Web { request->arg("ssid").toCharArray(mConfig->sys.stationSsid, SSID_LEN); if (request->arg("pwd") != "{PWD}") request->arg("pwd").toCharArray(mConfig->sys.stationPwd, PWD_LEN); - if (request->arg("ap_pwd") != "") - request->arg("ap_pwd").toCharArray(mConfig->sys.apPwd, PWD_LEN); mConfig->sys.isHidden = (request->arg("hidd") == "on"); #endif /* !defined(ETHERNET) */ + if (request->arg("ap_pwd") != "") + request->arg("ap_pwd").toCharArray(mConfig->sys.apPwd, PWD_LEN); if (request->arg("device") != "") request->arg("device").toCharArray(mConfig->sys.deviceName, DEVNAME_LEN); mConfig->sys.darkMode = (request->arg("darkMode") == "on"); From 4291b4c83f31930564401838655ed2116a35264e Mon Sep 17 00:00:00 2001 From: lumapu Date: Tue, 26 Mar 2024 00:03:27 +0100 Subject: [PATCH 09/21] 0.8.98 fix RF24_Hal.patch --- patches/RF24_Hal.patch | 116 ++++++++++++++--------------------------- 1 file changed, 38 insertions(+), 78 deletions(-) diff --git a/patches/RF24_Hal.patch b/patches/RF24_Hal.patch index 88a53bf9..e0f44819 100644 --- a/patches/RF24_Hal.patch +++ b/patches/RF24_Hal.patch @@ -1,5 +1,5 @@ diff --git a/RF24.cpp b/RF24.cpp -index 9e5b4a8..af00758 100644 +index 2e500b6..af00758 100644 --- a/RF24.cpp +++ b/RF24.cpp @@ -12,228 +12,24 @@ @@ -605,8 +605,7 @@ index 9e5b4a8..af00758 100644 /****************************************************************************/ -bool RF24::begin(_SPI* spiBus, rf24_gpio_pin_t _cepin, rf24_gpio_pin_t _cspin) -+bool RF24::begin(RF24_hal* _hal) - { +-{ - ce_pin = _cepin; - csn_pin = _cspin; - return begin(spiBus); @@ -617,7 +616,8 @@ index 9e5b4a8..af00758 100644 -/****************************************************************************/ - -bool RF24::begin(rf24_gpio_pin_t _cepin, rf24_gpio_pin_t _cspin) --{ ++bool RF24::begin(RF24_hal* _hal) + { - ce_pin = _cepin; - csn_pin = _cspin; + hal = _hal; @@ -670,17 +670,12 @@ index 9e5b4a8..af00758 100644 bool RF24::_init_pins() { if (!isValid()) { -@@ -1028,46 +527,7 @@ bool RF24::_init_pins() +@@ -1028,41 +527,7 @@ bool RF24::_init_pins() return false; } -#if defined(RF24_LINUX) - -- #if defined(MRAA) -- GPIO(); -- gpio.begin(ce_pin, csn_pin); -- #endif -- - pinMode(ce_pin, OUTPUT); - ce(LOW); - delay(100); @@ -718,7 +713,7 @@ index 9e5b4a8..af00758 100644 } /****************************************************************************/ -@@ -1151,7 +611,7 @@ bool RF24::isChipConnected() +@@ -1146,7 +611,7 @@ bool RF24::isChipConnected() bool RF24::isValid() { @@ -727,7 +722,7 @@ index 9e5b4a8..af00758 100644 } /****************************************************************************/ -@@ -1675,15 +1135,8 @@ void RF24::closeReadingPipe(uint8_t pipe) +@@ -1670,15 +1135,8 @@ void RF24::closeReadingPipe(uint8_t pipe) void RF24::toggle_features(void) { @@ -745,7 +740,7 @@ index 9e5b4a8..af00758 100644 } /****************************************************************************/ -@@ -1871,6 +1324,11 @@ uint8_t RF24::getARC(void) +@@ -1866,6 +1324,11 @@ uint8_t RF24::getARC(void) return read_register(OBSERVE_TX) & 0x0F; } @@ -758,7 +753,7 @@ index 9e5b4a8..af00758 100644 bool RF24::setDataRate(rf24_datarate_e speed) diff --git a/RF24.h b/RF24.h -index dbd32ae..74ae35d 100644 +index c029c8e..c9d612a 100644 --- a/RF24.h +++ b/RF24.h @@ -16,12 +16,7 @@ @@ -775,7 +770,7 @@ index dbd32ae..74ae35d 100644 /** * @defgroup PALevel Power Amplifier level -@@ -115,29 +110,8 @@ typedef enum +@@ -115,26 +110,8 @@ typedef enum class RF24 { private: @@ -784,18 +779,15 @@ index dbd32ae..74ae35d 100644 -#elif defined(SPI_UART) - SPIUARTClass uspi; -#endif -- ++ RF24_hal *hal; + -#if defined(RF24_LINUX) || defined(XMEGA_D3) /* XMEGA can use SPI class */ - SPI spi; -#endif // defined (RF24_LINUX) || defined (XMEGA_D3) -#if defined(RF24_SPI_PTR) - _SPI* _spi; -#endif // defined (RF24_SPI_PTR) --#if defined(MRAA) -- GPIO gpio; --#endif -+ RF24_hal *hal; - +- - rf24_gpio_pin_t ce_pin; /* "Chip Enable" pin, activates the RX or TX role */ - rf24_gpio_pin_t csn_pin; /* SPI Chip select */ - uint32_t spi_speed; /* SPI Bus Speed */ @@ -806,7 +798,7 @@ index dbd32ae..74ae35d 100644 uint8_t status; /* The status byte returned from every SPI transaction */ uint8_t payload_size; /* Fixed size of payloads */ uint8_t pipe0_reading_address[5]; /* Last address set on pipe 0 for reading. */ -@@ -146,16 +120,6 @@ private: +@@ -143,16 +120,6 @@ private: bool _is_p0_rx; /* For keeping track of pipe 0's usage in user-triggered RX mode. */ protected: @@ -823,7 +815,7 @@ index dbd32ae..74ae35d 100644 /** Whether ack payloads are enabled. */ bool ack_payloads_enabled; /** The address width to use (3, 4 or 5 bytes). */ -@@ -198,30 +162,15 @@ public: +@@ -195,30 +162,15 @@ public: * * See [Related Pages](pages.html) for device specific information * @@ -858,7 +850,7 @@ index dbd32ae..74ae35d 100644 #if defined(RF24_LINUX) virtual ~RF24() {}; -@@ -243,58 +192,16 @@ public: +@@ -240,58 +192,16 @@ public: */ bool begin(void); @@ -869,15 +861,16 @@ index dbd32ae..74ae35d 100644 - * @note This function assumes the `SPI::begin()` method was called before to - * calling this function. - * -- * @warning This function is for the Arduino platforms only -- * + * @warning This function is for the Arduino platforms only + * - * @param spiBus A pointer or reference to an instantiated SPI bus object. - * The `_SPI` datatype is a "wrapped" definition that will represent - * various SPI implementations based on the specified platform. - * @see Review the [Arduino support page](md_docs_arduino.html). -- * -- * @return same result as begin() -- */ ++ * @param _hal A pointer to the device specific hardware abstraction layer + * + * @return same result as begin() + */ - bool begin(_SPI* spiBus); - - /** @@ -887,8 +880,8 @@ index dbd32ae..74ae35d 100644 - * @note This function assumes the `SPI::begin()` method was called before to - * calling this function. - * - * @warning This function is for the Arduino platforms only - * +- * @warning This function is for the Arduino platforms only +- * - * @param spiBus A pointer or reference to an instantiated SPI bus object. - * The `_SPI` datatype is a "wrapped" definition that will represent - * various SPI implementations based on the specified platform. @@ -896,8 +889,7 @@ index dbd32ae..74ae35d 100644 - * @param _cspin The pin attached to Chip Select (often labeled CSN) on the radio module. - * - For the Arduino Due board, the [Arduino Due extended SPI feature](https://www.arduino.cc/en/Reference/DueExtendedSPI) - * is not supported. This means that the Due's pins 4, 10, or 52 are not mandated options (can use any digital output pin) for the radio's CSN pin. -+ * @param _hal A pointer to the device specific hardware abstraction layer - * +- * - * @see Review the [Arduino support page](md_docs_arduino.html). - * - * @return same result as begin() @@ -912,14 +904,14 @@ index dbd32ae..74ae35d 100644 - * @param _cspin The pin attached to Chip Select (often labeled CSN) on the radio module. - * - For the Arduino Due board, the [Arduino Due extended SPI feature](https://www.arduino.cc/en/Reference/DueExtendedSPI) - * is not supported. This means that the Due's pins 4, 10, or 52 are not mandated options (can use any digital output pin) for the radio's CSN pin. - * @return same result as begin() - */ +- * @return same result as begin() +- */ - bool begin(rf24_gpio_pin_t _cepin, rf24_gpio_pin_t _cspin); + bool begin(RF24_hal* _hal); /** * Checks if the chip is connected to the SPI bus -@@ -667,12 +574,12 @@ public: +@@ -664,12 +574,12 @@ public: * This function uses much less ram than other `*print*Details()` methods. * * @code @@ -934,17 +926,7 @@ index dbd32ae..74ae35d 100644 * cause undefined behavior. * * Registers names and/or data corresponding to the index of the `encoded_details` array: -@@ -704,9 +611,6 @@ public: - * | 35 | FIFO_STATUS | - * | 36 | DYNPD | - * | 37 | FEATURE | -- * | 38-39 | ce_pin | -- * | 40-41 | csn_pin | -- * | 42 | SPI speed (in MHz) or'd with (isPlusVariant << 4) | - */ - void encodeRadioDetails(uint8_t* encoded_status); - -@@ -1644,6 +1548,7 @@ public: +@@ -1641,6 +1551,7 @@ public: * @return Returns values from 0 to 15. */ uint8_t getARC(void); @@ -952,7 +934,7 @@ index dbd32ae..74ae35d 100644 /** * Set the transmission @ref Datarate -@@ -1896,18 +1801,6 @@ private: +@@ -1893,17 +1804,6 @@ private: */ bool _init_pins(); @@ -967,35 +949,13 @@ index dbd32ae..74ae35d 100644 - * @param mode HIGH to take this unit off the SPI bus, LOW to put it on - */ - void csn(bool mode); -- + /** * Set chip enable - * -diff --git a/RF24_hal.cpp b/RF24_hal.cpp -new file mode 100644 -index 0000000..3cc78e4 ---- /dev/null -+++ b/RF24_hal.cpp -@@ -0,0 +1 @@ -+#include "RF24_hal.h" -diff --git a/RF24_hal.h b/RF24_hal.h -new file mode 100644 -index 0000000..baceab3 ---- /dev/null -+++ b/RF24_hal.h -@@ -0,0 +1,15 @@ -+#pragma once -+ -+#include "RF24_config.h" -+ -+class RF24_hal -+{ -+public: -+ virtual void ce(bool level) = 0; -+ virtual uint8_t read(uint8_t cmd, uint8_t* buf, uint8_t len) = 0; -+ virtual uint8_t read(uint8_t cmd, uint8_t* buf, uint8_t data_len, uint8_t blank_len) = 0; -+ virtual uint8_t write(uint8_t cmd, const uint8_t* buf, uint8_t len) = 0; -+ virtual uint8_t write(uint8_t cmd, const uint8_t* buf, uint8_t len, uint8_t blank_len) = 0; -+ virtual bool begin() = 0; -+ virtual void end() = 0; -+}; +@@ -2412,4 +2312,4 @@ private: + * Use `ctrl+c` to quit at any time. + */ + +-#endif // __RF24_H__ +\ No newline at end of file ++#endif // __RF24_H__ From 8a0b9e90299d385dd7d1de972f0a98da06add4c3 Mon Sep 17 00:00:00 2001 From: lumapu Date: Tue, 26 Mar 2024 00:18:24 +0100 Subject: [PATCH 10/21] 0.8.98 fix compile --- src/network/AhoyNetwork.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/network/AhoyNetwork.h b/src/network/AhoyNetwork.h index 5ce668df..f90096db 100644 --- a/src/network/AhoyNetwork.h +++ b/src/network/AhoyNetwork.h @@ -161,6 +161,17 @@ class AhoyNetwork { } } + #if !defined(ETHERNET) + void sortRSSI(int *sort, int n) { + for (int i = 0; i < n; i++) + sort[i] = i; + for (int i = 0; i < n; i++) + for (int j = i + 1; j < n; j++) + if (WiFi.RSSI(sort[j]) > WiFi.RSSI(sort[i])) + std::swap(sort[i], sort[j]); + } + #endif + private: void sendNTPpacket(IPAddress& address) { //DPRINTLN(DBG_VERBOSE, F("wifi::sendNTPpacket")); @@ -200,17 +211,6 @@ class AhoyNetwork { mUdp.close(); } - #if !defined(ETHERNET) - void sortRSSI(int *sort, int n) { - for (int i = 0; i < n; i++) - sort[i] = i; - for (int i = 0; i < n; i++) - for (int j = i + 1; j < n; j++) - if (WiFi.RSSI(sort[j]) > WiFi.RSSI(sort[i])) - std::swap(sort[i], sort[j]); - } - #endif - protected: enum class NetworkState : uint8_t { DISCONNECTED, From f47cb107f32a248b4c5abf05d154b9d18f7c1004 Mon Sep 17 00:00:00 2001 From: lumapu Date: Tue, 26 Mar 2024 00:31:09 +0100 Subject: [PATCH 11/21] 0.8.98 fix compile --- src/hm/nrfHal.h | 2 +- src/platformio.ini | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/hm/nrfHal.h b/src/hm/nrfHal.h index b9265626..89fe0885 100644 --- a/src/hm/nrfHal.h +++ b/src/hm/nrfHal.h @@ -11,7 +11,7 @@ #include "../utils/spiPatcher.h" #include -#include +#include #define NRF_MAX_TRANSFER_SZ 64 #define NRF_DEFAULT_SPI_SPEED 10000000 // 10 MHz diff --git a/src/platformio.ini b/src/platformio.ini index 4d0d528d..7edf99ba 100644 --- a/src/platformio.ini +++ b/src/platformio.ini @@ -67,6 +67,7 @@ monitor_filters = platform = espressif8266 board = esp12e board_build.f_cpu = 80000000L +lib_deps = ${env:esp8266.lib_deps} build_flags = ${env:esp8266.build_flags} -DLANG_DE monitor_filters = @@ -76,6 +77,7 @@ monitor_filters = platform = espressif8266 board = esp12e board_build.f_cpu = 80000000L +lib_deps = ${env:esp8266.lib_deps} build_flags = ${env:esp8266.build_flags} -DPLUGIN_DISPLAY -DENABLE_HISTORY @@ -86,6 +88,7 @@ monitor_filters = platform = espressif8266 board = esp12e board_build.f_cpu = 80000000L +lib_deps = ${env:esp8266.lib_deps} build_flags = ${env:esp8266-all.build_flags} -DLANG_DE monitor_filters = @@ -95,6 +98,7 @@ monitor_filters = platform = espressif8266 board = esp12e board_build.f_cpu = 80000000L +lib_deps = ${env:esp8266.lib_deps} build_flags = ${env:esp8266-all.build_flags} -DENABLE_PROMETHEUS_EP monitor_filters = @@ -104,6 +108,7 @@ monitor_filters = platform = espressif8266 board = esp12e board_build.f_cpu = 80000000L +lib_deps = ${env:esp8266.lib_deps} build_flags = ${env:esp8266-prometheus.build_flags} -DLANG_DE monitor_filters = @@ -116,6 +121,7 @@ platform = espressif8266 board = esp8285 board_build.ldscript = eagle.flash.1m64.ld board_build.f_cpu = 80000000L +lib_deps = ${env:esp8266.lib_deps} build_flags = ${env.build_flags} -DEMC_MIN_FREE_MEMORY=4096 -DENABLE_MQTT @@ -129,6 +135,7 @@ platform = espressif8266 board = esp8285 board_build.ldscript = eagle.flash.1m64.ld board_build.f_cpu = 80000000L +lib_deps = ${env:esp8266.lib_deps} build_flags = ${env.build_flags} -DEMC_MIN_FREE_MEMORY=4096 -DLANG_DE From d5ed0272e9f3211a04d0e60a12f1ded02f8a599f Mon Sep 17 00:00:00 2001 From: lumapu Date: Tue, 26 Mar 2024 22:30:11 +0100 Subject: [PATCH 12/21] 0.8.99 * fix compilation of all environments --- patches/RF24_Hal.patch | 21 +++++++++++++++++++++ src/CHANGES.md | 3 +++ src/defines.h | 2 +- src/platformio.ini | 6 ++++-- 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/patches/RF24_Hal.patch b/patches/RF24_Hal.patch index e0f44819..ed2c5bec 100644 --- a/patches/RF24_Hal.patch +++ b/patches/RF24_Hal.patch @@ -959,3 +959,24 @@ index c029c8e..c9d612a 100644 -#endif // __RF24_H__ \ No newline at end of file +#endif // __RF24_H__ +diff --git a/RF24_hal.h b/RF24_hal.h +new file mode 100644 +index 0000000..baceab3 +--- /dev/null ++++ b/RF24_hal.h +@@ -0,0 +1,15 @@ ++#pragma once ++ ++#include "RF24_config.h" ++ ++class RF24_hal ++{ ++public: ++ virtual void ce(bool level) = 0; ++ virtual uint8_t read(uint8_t cmd, uint8_t* buf, uint8_t len) = 0; ++ virtual uint8_t read(uint8_t cmd, uint8_t* buf, uint8_t data_len, uint8_t blank_len) = 0; ++ virtual uint8_t write(uint8_t cmd, const uint8_t* buf, uint8_t len) = 0; ++ virtual uint8_t write(uint8_t cmd, const uint8_t* buf, uint8_t len, uint8_t blank_len) = 0; ++ virtual bool begin() = 0; ++ virtual void end() = 0; ++}; diff --git a/src/CHANGES.md b/src/CHANGES.md index f2cc8785..3193ac15 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,8 @@ # Development Changes +## 0.8.99 - 2024-03-27 +* fix compilation of all environments + ## 0.8.98 - 2024-03-24 * new network routines diff --git a/src/defines.h b/src/defines.h index 2058ce3a..5c09041d 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 98 +#define VERSION_PATCH 99 //------------------------------------- typedef struct { diff --git a/src/platformio.ini b/src/platformio.ini index 7edf99ba..cde08cb1 100644 --- a/src/platformio.ini +++ b/src/platformio.ini @@ -45,6 +45,9 @@ build_unflags = platform = espressif8266 board = esp12e board_build.f_cpu = 80000000L +lib_deps = + ${env.lib_deps} + https://github.com/me-no-dev/ESPAsyncUDP build_flags = ${env.build_flags} -DEMC_MIN_FREE_MEMORY=4096 ;-Wl,-Map,output.map @@ -55,8 +58,7 @@ monitor_filters = platform = espressif8266 board = esp12e board_build.f_cpu = 80000000L -lib_deps = - ${env.lib_deps} +lib_deps = ${env:esp8266-minimal.lib_deps} https://github.com/me-no-dev/ESPAsyncUDP build_flags = ${env:esp8266-minimal.build_flags} -DENABLE_MQTT From 4b75e72bf3efde5aad73510169fd1fd43751b18d Mon Sep 17 00:00:00 2001 From: lumapu Date: Tue, 26 Mar 2024 23:39:09 +0100 Subject: [PATCH 13/21] 0.8.100 * fix captions in `/history #1532 * fix get NTP time #1529 #1530 * fix translation #1516 --- src/CHANGES.md | 5 +++++ src/app.cpp | 12 +++--------- src/app.h | 1 - src/defines.h | 3 +-- src/network/AhoyNetwork.h | 10 ++++------ src/web/html/history.html | 2 +- src/web/lang.json | 10 +++++----- 7 files changed, 19 insertions(+), 24 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index 3193ac15..15b9a380 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,10 @@ # Development Changes +## 0.8.100 - 2024-03-27 +* fix captions in `/history #1532 +* fix get NTP time #1529 #1530 +* fix translation #1516 + ## 0.8.99 - 2024-03-27 * fix compilation of all environments diff --git a/src/app.cpp b/src/app.cpp index 2dd8c49c..506074c5 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -245,17 +245,12 @@ void app::tickNtpUpdate(void) { if (!mNtpReceived) mNetwork->updateNtpTime(); - else + else { + nxtTrig = mConfig->ntp.interval * 60; // check again in configured interval mNtpReceived = false; + } updateNtp(); - nxtTrig = mConfig->ntp.interval * 60; // check again in 12h - - // immediately start communicating - if (mSendFirst) { - mSendFirst = false; - once(std::bind(&app::tickSend, this), 1, "senOn"); - } mMqttReconnect = false; @@ -532,7 +527,6 @@ void app::resetSystem(void) { mTimestamp = 1; #endif - mSendFirst = true; mAllIvNotAvail = true; mSunrise = 0; diff --git a/src/app.h b/src/app.h index cb546267..66234a31 100644 --- a/src/app.h +++ b/src/app.h @@ -440,7 +440,6 @@ class app : public IApp, public ah::Scheduler { bool mSaveReboot = false; uint8_t mSendLastIvId = 0; - bool mSendFirst = false; bool mAllIvNotAvail = false; bool mNetworkConnected = false; diff --git a/src/defines.h b/src/defines.h index 5c09041d..86c8a888 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,8 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 99 - +#define VERSION_PATCH 100 //------------------------------------- typedef struct { uint8_t ch; diff --git a/src/network/AhoyNetwork.h b/src/network/AhoyNetwork.h index f90096db..9573f48f 100644 --- a/src/network/AhoyNetwork.h +++ b/src/network/AhoyNetwork.h @@ -57,11 +57,11 @@ class AhoyNetwork { } bool updateNtpTime(void) { - if(NetworkState::CONNECTED != mStatus) + if(NetworkState::GOT_IP != mStatus) return false; - IPAddress timeServer; if (!mUdp.connected()) { + IPAddress timeServer; if (!WiFi.hostByName(mConfig->ntp.addr, timeServer)) return false; if (!mUdp.connect(timeServer, mConfig->ntp.port)) @@ -71,7 +71,7 @@ class AhoyNetwork { mUdp.onPacket([this](AsyncUDPPacket packet) { this->handleNTPPacket(packet); }); - sendNTPpacket(timeServer); + sendNTPpacket(); return true; } @@ -173,7 +173,7 @@ class AhoyNetwork { #endif private: - void sendNTPpacket(IPAddress& address) { + void sendNTPpacket(void) { //DPRINTLN(DBG_VERBOSE, F("wifi::sendNTPpacket")); uint8_t buf[NTP_PACKET_SIZE]; memset(buf, 0, NTP_PACKET_SIZE); @@ -188,9 +188,7 @@ class AhoyNetwork { buf[14] = 49; buf[15] = 52; - //mUdp.beginPacket(address, 123); // NTP request, port 123 mUdp.write(buf, NTP_PACKET_SIZE); - //mUdp.endPacket(); } void handleNTPPacket(AsyncUDPPacket packet) { diff --git a/src/web/html/history.html b/src/web/html/history.html index 57bff2fc..7ec9be7e 100644 --- a/src/web/html/history.html +++ b/src/web/html/history.html @@ -136,7 +136,7 @@ return [ mlNs("polyline", {stroke: "url(#gLine)", fill: "none", points: pts}), mlNs("polyline", {stroke: "none", fill: "url(#gFill)", points: pts2}), - mlNs("text", {x: i*.8, y: 10}, "{#MAX_DAY}: " + String(obj.max) + "W"), + mlNs("text", {x: i*.8, y: 10}, "{#MAXIMUM}: " + String(obj.max) + "W"), mlNs("text", {x: i*.8, y: 25}, "{#LAST_VALUE}: " + String(lastVal) + "W") ] } diff --git a/src/web/lang.json b/src/web/lang.json index f2274b69..ee942608 100644 --- a/src/web/lang.json +++ b/src/web/lang.json @@ -631,7 +631,7 @@ { "token": "BTN_INV_ADD", "en": "add Inverter", - "de": "Wechselrichter hinzufuegen" + "de": "Wechselrichter hinzuf\u00FCgen" }, { "token": "INV_INPUT", @@ -656,7 +656,7 @@ { "token": "TAB_INPUTS", "en": "Inputs", - "de": "Eingaenge" + "de": "Eingänge" }, { "token": "TAB_RADIO", @@ -1579,9 +1579,9 @@ "de": "Gesamtertrag pro Tag" }, { - "token": "MAX_DAY", - "en": "Maximum day", - "de": "Tagesmaximum" + "token": "MAXIMUM", + "en": "Maximum", + "de": "Maximum" }, { "token": "LAST_VALUE", From 2a4c83647af2c832de06ecf9a10b552d22e377b0 Mon Sep 17 00:00:00 2001 From: lumapu Date: Wed, 27 Mar 2024 22:49:18 +0100 Subject: [PATCH 14/21] 0.8.101 * updated converter scripts to include all enabled features again (redundant scan of build flags) #1534 --- scripts/convertHtml.py | 20 +++++++++++++++----- scripts/htmlPreprocessorDefines.py | 2 +- src/CHANGES.md | 3 +++ src/defines.h | 2 +- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/scripts/convertHtml.py b/scripts/convertHtml.py index ec16b5f3..026c28da 100644 --- a/scripts/convertHtml.py +++ b/scripts/convertHtml.py @@ -9,19 +9,29 @@ from pathlib import Path import subprocess import configparser Import("env") +build_flags = [] import htmlPreprocessorDefines as prepro +def getFlagsOfEnv(env): + config = configparser.ConfigParser() + config.read('platformio.ini') + global build_flags + flags = config[env]['build_flags'].split('\n') + + for i in range(len(flags)): + if flags[i][:2] == "-D" or flags[i][:2] == "${": + flags[i] = flags[i][2:] + if flags[i][-13:-1] == ".build_flags": + getFlagsOfEnv(flags[i].split(".build_flags")[0]) + elif len(flags[i]) > 0: + build_flags = build_flags + [flags[i]] def get_build_flags(): + getFlagsOfEnv("env:" + env['PIOENV']) config = configparser.ConfigParser() config.read('platformio.ini') - global build_flags - build_flags = config["env:" + env['PIOENV']]['build_flags'].split('\n') - - for i in range(len(build_flags)): - build_flags[i] = build_flags[i][2:] # translate board board = config["env:" + env['PIOENV']]['board'] diff --git a/scripts/htmlPreprocessorDefines.py b/scripts/htmlPreprocessorDefines.py index f5d7cc31..f8230a90 100644 --- a/scripts/htmlPreprocessorDefines.py +++ b/scripts/htmlPreprocessorDefines.py @@ -35,6 +35,6 @@ def check(inp, lst, pattern): return out def conv(inp, lst): - #print(lst) + print(lst) out = check(inp, lst, r'\/\*(?:IF_|ELS|ENDIF_)([A-Z0-9\-_]+)?\*\/') return check(out, lst, r'\<\!\-\-(?:IF_|ELS|ENDIF_)([A-Z0-9\-_]+)?\-\-\>') diff --git a/src/CHANGES.md b/src/CHANGES.md index 15b9a380..f8b8ba84 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,8 @@ # Development Changes +## 0.8.101 - 2024-03-28 +* updated converter scripts to include all enabled features again (redundant scan of build flags) #1534 + ## 0.8.100 - 2024-03-27 * fix captions in `/history #1532 * fix get NTP time #1529 #1530 diff --git a/src/defines.h b/src/defines.h index 86c8a888..3edc6f09 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 100 +#define VERSION_PATCH 101 //------------------------------------- typedef struct { uint8_t ch; From d0741a91e8d0e9edcff94c16d3e0a86c5b83e0fc Mon Sep 17 00:00:00 2001 From: rejoe2 Date: Mon, 1 Apr 2024 13:42:48 +0200 Subject: [PATCH 15/21] shorten last cmt waiting time after last frame is received. Works, see around this discord post: https://discord.com/channels/984173303147155506/1029761098381017098/1220679912587792404 --- src/hms/hmsRadio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hms/hmsRadio.h b/src/hms/hmsRadio.h index d074442b..54975197 100644 --- a/src/hms/hmsRadio.h +++ b/src/hms/hmsRadio.h @@ -183,7 +183,7 @@ class CmtRadio : public Radio { if(p.packet[9] > ALL_FRAMES) { // indicates last frame setExpectedFrames(p.packet[9] - ALL_FRAMES); - mRadioWaitTime.startTimeMonitor(DURATION_PAUSE_LASTFR); // let the inverter first get back to rx mode? + mRadioWaitTime.startTimeMonitor(2); // let the inverter first get back to rx mode? } } From bcc52c793c6c9e582dbadd725cfbda36bbcc8130 Mon Sep 17 00:00:00 2001 From: lumapu Date: Mon, 1 Apr 2024 14:54:08 +0200 Subject: [PATCH 16/21] 0.8.102 - 2024-04-01 * fix NTP for `opendtufusion` #1542 * fix scan WiFi in AP mode --- scripts/htmlPreprocessorDefines.py | 2 +- src/CHANGES.md | 4 ++++ src/app.cpp | 2 +- src/app.h | 8 -------- src/appInterface.h | 2 -- src/defines.h | 2 +- src/network/AhoyNetwork.h | 16 ++++++++-------- src/network/AhoyWifiAp.h | 7 +++++++ src/network/AhoyWifiEsp32.h | 6 +----- src/network/AhoyWifiEsp8266.h | 2 ++ src/utils/improv.h | 8 +++++--- src/web/RestApi.h | 15 +++++---------- src/web/html/wizard.html | 9 +++++---- src/web/web.h | 1 + 14 files changed, 41 insertions(+), 43 deletions(-) diff --git a/scripts/htmlPreprocessorDefines.py b/scripts/htmlPreprocessorDefines.py index f8230a90..f5d7cc31 100644 --- a/scripts/htmlPreprocessorDefines.py +++ b/scripts/htmlPreprocessorDefines.py @@ -35,6 +35,6 @@ def check(inp, lst, pattern): return out def conv(inp, lst): - print(lst) + #print(lst) out = check(inp, lst, r'\/\*(?:IF_|ELS|ENDIF_)([A-Z0-9\-_]+)?\*\/') return check(out, lst, r'\<\!\-\-(?:IF_|ELS|ENDIF_)([A-Z0-9\-_]+)?\-\-\>') diff --git a/src/CHANGES.md b/src/CHANGES.md index f8b8ba84..5cc43614 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,9 @@ # Development Changes +## 0.8.102 - 2024-04-01 +* fix NTP for `opendtufusion` #1542 +* fix scan WiFi in AP mode + ## 0.8.101 - 2024-03-28 * updated converter scripts to include all enabled features again (redundant scan of build flags) #1534 diff --git a/src/app.cpp b/src/app.cpp index 506074c5..ae50ba49 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -62,7 +62,6 @@ void app::setup() { #endif // ETHERNET mNetwork->setup(mConfig, &mTimestamp, [this](bool gotIp) { this->onNetwork(gotIp); }, [this](bool gotTime) { this->onNtpUpdate(gotTime); }); mNetwork->begin(); - everySec(std::bind(&AhoyNetwork::tickNetworkLoop, mNetwork), "net"); esp_task_wdt_reset(); @@ -176,6 +175,7 @@ void app::regularTickers(void) { DPRINTLN(DBG_DEBUG, F("regularTickers")); everySec(std::bind(&WebType::tickSecond, &mWeb), "webSc"); everySec([this]() { mProtection->tickSecond(); }, "prot"); + everySec([this]() {mNetwork->tickNetworkLoop(); }, "net"); // Plugins #if defined(PLUGIN_DISPLAY) diff --git a/src/app.h b/src/app.h index 66234a31..300c1c25 100644 --- a/src/app.h +++ b/src/app.h @@ -167,10 +167,6 @@ class app : public IApp, public ah::Scheduler { } #if !defined(ETHERNET) - void scanAvailNetworks() override { - mNetwork->scanAvailNetworks(); - } - bool getAvailNetworks(JsonObject obj) override { return mNetwork->getAvailNetworks(obj); } @@ -179,10 +175,6 @@ class app : public IApp, public ah::Scheduler { mNetwork->begin(); } - /*void setStopApAllowedMode(bool allowed) override { - mWifi.setStopApAllowedMode(allowed); - }*/ - bool getWasInCh12to14(void) const override { #if defined(ESP8266) return mNetwork->getWasInCh12to14(); diff --git a/src/appInterface.h b/src/appInterface.h index b7ee2aaf..49470e02 100644 --- a/src/appInterface.h +++ b/src/appInterface.h @@ -26,10 +26,8 @@ class IApp { virtual const char *getVersionModules() = 0; #if !defined(ETHERNET) - virtual void scanAvailNetworks() = 0; virtual bool getAvailNetworks(JsonObject obj) = 0; virtual void setupStation(void) = 0; - //virtual void setStopApAllowedMode(bool allowed) = 0; virtual bool getWasInCh12to14(void) const = 0; #endif /* defined(ETHERNET) */ virtual String getIp(void) = 0; diff --git a/src/defines.h b/src/defines.h index 3edc6f09..ab7c860b 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 101 +#define VERSION_PATCH 102 //------------------------------------- typedef struct { uint8_t ch; diff --git a/src/network/AhoyNetwork.h b/src/network/AhoyNetwork.h index 9573f48f..c98d9866 100644 --- a/src/network/AhoyNetwork.h +++ b/src/network/AhoyNetwork.h @@ -86,19 +86,20 @@ class AhoyNetwork { } #if !defined(ETHERNET) - void scanAvailNetworks(void) { + bool getAvailNetworks(JsonObject obj) { + JsonArray nets = obj.createNestedArray(F("networks")); + if(!mScanActive) { mScanActive = true; - WiFi.scanNetworks(true); + WiFi.disconnect(); + WiFi.scanNetworks(true, true); + return false; } - } - - bool getAvailNetworks(JsonObject obj) { - JsonArray nets = obj.createNestedArray(F("networks")); int n = WiFi.scanComplete(); - if (n < 0) + if (WIFI_SCAN_RUNNING == n) return false; + if(n > 0) { int sort[n]; sortRSSI(&sort[0], n); @@ -174,7 +175,6 @@ class AhoyNetwork { private: void sendNTPpacket(void) { - //DPRINTLN(DBG_VERBOSE, F("wifi::sendNTPpacket")); uint8_t buf[NTP_PACKET_SIZE]; memset(buf, 0, NTP_PACKET_SIZE); diff --git a/src/network/AhoyWifiAp.h b/src/network/AhoyWifiAp.h index 3c75dc12..56ff63d7 100644 --- a/src/network/AhoyWifiAp.h +++ b/src/network/AhoyWifiAp.h @@ -22,6 +22,12 @@ class AhoyWifiAp { void tickLoop() { if(mEnabled) mDns.processNextRequest(); + + if (WiFi.softAPgetStationNum() != mLast) { + mLast = WiFi.softAPgetStationNum(); + if(mLast > 0) + DBGPRINTLN(F("AP client connected")); + } } void enable() { @@ -68,6 +74,7 @@ class AhoyWifiAp { DNSServer mDns; IPAddress mIp; bool mEnabled = false; + uint8_t mLast = 0; }; #endif /*__AHOY_WIFI_AP_H__*/ diff --git a/src/network/AhoyWifiEsp32.h b/src/network/AhoyWifiEsp32.h index 255f2b03..58f5dc5d 100644 --- a/src/network/AhoyWifiEsp32.h +++ b/src/network/AhoyWifiEsp32.h @@ -28,7 +28,7 @@ class AhoyWifi : public AhoyNetwork { WiFi.setSortMethod(WIFI_CONNECT_AP_BY_SIGNAL); WiFi.begin(mConfig->sys.stationSsid, mConfig->sys.stationPwd, WIFI_ALL_CHANNEL_SCAN); - DBGPRINT(F("connect to network '")); Serial.flush(); + DBGPRINT(F("connect to network '")); DBGPRINT(mConfig->sys.stationSsid); #endif } @@ -44,10 +44,6 @@ class AhoyWifi : public AhoyNetwork { mOnNetworkCB(false); mAp.enable(); } - - if (WiFi.softAPgetStationNum() > 0) { - DBGPRINTLN(F("AP client connected")); - } break; case NetworkState::CONNECTED: diff --git a/src/network/AhoyWifiEsp8266.h b/src/network/AhoyWifiEsp8266.h index b9417556..93597f72 100644 --- a/src/network/AhoyWifiEsp8266.h +++ b/src/network/AhoyWifiEsp8266.h @@ -96,6 +96,8 @@ class AhoyWifi : public AhoyNetwork { mOnNetworkCB(true); } + MDNS.update(); + if(WiFi.channel() > 11) mWasInCh12to14 = true; break; diff --git a/src/utils/improv.h b/src/utils/improv.h index 20b2bcad..d2ccc0c3 100644 --- a/src/utils/improv.h +++ b/src/utils/improv.h @@ -147,10 +147,12 @@ class Improv { } void getNetworks(void) { - if(!mScanRunning) - mApp->scanAvailNetworks(); - JsonObject obj; + if(!mScanRunning) { + mApp->getAvailNetworks(obj); + return; + } + if(!mApp->getAvailNetworks(obj)) return; diff --git a/src/web/RestApi.h b/src/web/RestApi.h index 8087883e..0f256f25 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -100,7 +100,7 @@ class RestApi { else if(path == "setup") getSetup(request, root); #if !defined(ETHERNET) else if(path == "setup/networks") getNetworks(root); - else if(path == "setup/getip") getWifiIp(root); + else if(path == "setup/getip") getIp(root); #endif /* !defined(ETHERNET) */ else if(path == "live") getLive(request,root); else if (path == "powerHistory") getPowerHistory(request, root); @@ -891,12 +891,13 @@ class RestApi { #if !defined(ETHERNET) void getNetworks(JsonObject obj) { - mApp->getAvailNetworks(obj); + obj[F("success")] = mApp->getAvailNetworks(obj); } - void getWifiIp(JsonObject obj) { + #endif /* !defined(ETHERNET) */ + + void getIp(JsonObject obj) { obj[F("ip")] = mApp->getIp(); } - #endif /* !defined(ETHERNET) */ void getLive(AsyncWebServerRequest *request, JsonObject obj) { getGeneric(request, obj.createNestedObject(F("generic"))); @@ -1031,11 +1032,6 @@ class RestApi { if(isProtected(jsonIn, jsonOut, clientIP)) return false; - #if !defined(ETHERNET) - if(F("scan_wifi") == jsonIn[F("cmd")]) - mApp->scanAvailNetworks(); - else - #endif /* !defined(ETHERNET) */ if(F("set_time") == jsonIn[F("cmd")]) mApp->setTimestamp(jsonIn[F("val")]); else if(F("sync_ntp") == jsonIn[F("cmd")]) @@ -1049,7 +1045,6 @@ class RestApi { snprintf(mConfig->sys.stationSsid, SSID_LEN, "%s", jsonIn[F("ssid")].as()); snprintf(mConfig->sys.stationPwd, PWD_LEN, "%s", jsonIn[F("pwd")].as()); mApp->saveSettings(false); // without reboot - //mApp->setStopApAllowedMode(false); mApp->setupStation(); } #else diff --git a/src/web/html/wizard.html b/src/web/html/wizard.html index 179adb5a..d57562d1 100644 --- a/src/web/html/wizard.html +++ b/src/web/html/wizard.html @@ -231,7 +231,7 @@ ml("div", {class: "row my-4"}, ml("div", {class: "col a-r"}, ml("input", {type: "button", class:"btn hide", id: "btn", value: "{#BTN_FINISH}", onclick: () => {redirect()}}, null))), ml("div", {class: "row mt-5"}, ml("div", {class: "col a-c"}, ml("a", {href: "http://192.168.4.1/"}, "{#STOP_WIZARD}"))) ) - v = setInterval(() => {getAjax('/api/setup/getip', printIp)}, 2500); + v = setInterval(() => {getAjax('/api/setup/getip', printIp)}, 1000); } function redirect() { @@ -270,6 +270,9 @@ getAjax("/api/setup", ((o) => c.append(step1(o.eth)))); /*ELSE*/ function nets(obj) { + if(!obj.success) + return; + var e = document.getElementById("net"); if(obj.networks.length > 0) { var a = [] @@ -280,12 +283,10 @@ } e.replaceChildren(...a) } - getAjax("/api/setup", ((o) => {}), "POST", JSON.stringify({cmd: "scan_wifi"})); } - getAjax("/api/setup", ((o) => {}), "POST", JSON.stringify({cmd: "scan_wifi"})); c.append(step1()) - v = setInterval(() => {getAjax('/api/setup/networks', nets)}, 2500); + v = setInterval(() => {getAjax('/api/setup/networks', nets)}, 1000); /*ENDIF_ETHERNET*/ diff --git a/src/web/web.h b/src/web/web.h index 419d6826..56ff577e 100644 --- a/src/web/web.h +++ b/src/web/web.h @@ -402,6 +402,7 @@ class Web { void showNotFound(AsyncWebServerRequest *request) { checkProtection(request); + //DBGPRINTLN(request->url()); request->redirect("/wizard"); } From 1033ddc11aa06a288f87095ed9166c6bebb15ccf Mon Sep 17 00:00:00 2001 From: Sebastian Rothe Date: Mon, 1 Apr 2024 16:48:38 +0200 Subject: [PATCH 17/21] Fix typos and spelling --- .github/ISSUE_TEMPLATE/report.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/report.yaml b/.github/ISSUE_TEMPLATE/report.yaml index 9a2824c4..19b71de2 100644 --- a/.github/ISSUE_TEMPLATE/report.yaml +++ b/.github/ISSUE_TEMPLATE/report.yaml @@ -12,7 +12,7 @@ body: Wir lesen auch gerne Deutsch, bitte fülle die u.a. Fragen aus damit wir Dir bestmöglich helfen können Danke! Bitte unser FAQ als Hilfestellung prüfen: https://ahoydtu.de/faq - Please read, copy & fill in the template from our Posting Guide lines into your Support Forum post. + Please read, then copy & fill in the template from our Posting Guide lines into your Support Forum post. We do enjoy the english language, but we need a couple of things to best support you in your goal, please fill in all / most of the details given below. Thanks! Check our FAQ: https://ahoydtu.de/faq - type: markdown @@ -35,7 +35,7 @@ body: label: Assembly description: options: - - I did the assebly by myself + - I did the assembly by myself - the DTU was already assembled validations: required: true @@ -84,7 +84,7 @@ body: label: Connection picture description: options: - - label: I will attach/upload an Image of my wiring + - label: I will attach/upload an image of my wiring validations: required: true - type: markdown From 4d5ae72cb6d1050ac81ed4f21e9b62328561527d Mon Sep 17 00:00:00 2001 From: lumapu Date: Mon, 1 Apr 2024 17:02:43 +0200 Subject: [PATCH 18/21] 0.8.102 * fix MDNS #1538 * improved Wizard * improved MqTT on devcontrol e.g. set power limit --- .gitignore | 1 + src/.gitignore | 2 ++ src/CHANGES.md | 3 ++ src/app.cpp | 55 ++++++++++++++++++++--------------- src/app.h | 11 +++++-- src/appInterface.h | 3 +- src/network/AhoyNetwork.h | 7 ++++- src/network/AhoyWifiAp.h | 3 ++ src/network/AhoyWifiEsp32.h | 6 +++- src/network/AhoyWifiEsp8266.h | 4 +++ src/web/RestApi.h | 2 +- src/web/html/setup.html | 28 +----------------- src/web/html/wizard.html | 9 +++--- src/web/lang.json | 20 ++++--------- src/web/web.h | 9 ++++-- 15 files changed, 86 insertions(+), 77 deletions(-) diff --git a/.gitignore b/.gitignore index 21ae2a57..b5c699cc 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ src/web/html/tmp/* src/output.map /.venv +/scripts/__pycache__/htmlPreprocessorDefines.cpython-311.pyc diff --git a/src/.gitignore b/src/.gitignore index 89cc49cb..30f1d1ca 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -3,3 +3,5 @@ .vscode/c_cpp_properties.json .vscode/launch.json .vscode/ipch +scripts/__pycache__/* +*.pyc diff --git a/src/CHANGES.md b/src/CHANGES.md index 5cc43614..1ba9edd1 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -3,6 +3,9 @@ ## 0.8.102 - 2024-04-01 * fix NTP for `opendtufusion` #1542 * fix scan WiFi in AP mode +* fix MDNS #1538 +* improved Wizard +* improved MqTT on devcontrol e.g. set power limit ## 0.8.101 - 2024-03-28 * updated converter scripts to include all enabled features again (redundant scan of build flags) #1534 diff --git a/src/app.cpp b/src/app.cpp index ae50ba49..5166c035 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -403,29 +403,7 @@ void app::tickSend(void) { for (uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) { Inverter<> *iv = mSys.getInverterByPos(i); - if(NULL == iv) - continue; - - if(iv->config->enabled) { - if(!iv->commEnabled) { - DPRINT_IVID(DBG_INFO, iv->id); - DBGPRINTLN(F("no communication to the inverter (night time)")); - continue; - } - - if(!iv->radio->isChipConnected()) - continue; - - if(InverterStatus::OFF != iv->status) - notAvail = false; - - iv->tickSend([this, iv](uint8_t cmd, bool isDevControl) { - if(isDevControl) - mCommunication.addImportant(iv, cmd); - else - mCommunication.add(iv, cmd); - }); - } + sendIv(iv); } if(mAllIvNotAvail != notAvail) @@ -435,6 +413,37 @@ void app::tickSend(void) { updateLed(); } +//----------------------------------------------------------------------------- +bool app::sendIv(Inverter<> *iv) { + bool notAvail = true; + if(NULL == iv) + return notAvail; + + if(!iv->config->enabled) + return notAvail; + + if(!iv->commEnabled) { + DPRINT_IVID(DBG_INFO, iv->id); + DBGPRINTLN(F("no communication to the inverter (night time)")); + return notAvail; + } + + if(!iv->radio->isChipConnected()) + return notAvail; + + if(InverterStatus::OFF != iv->status) + notAvail = false; + + iv->tickSend([this, iv](uint8_t cmd, bool isDevControl) { + if(isDevControl) + mCommunication.addImportant(iv, cmd); + else + mCommunication.add(iv, cmd); + }); + + return notAvail; +} + //----------------------------------------------------------------------------- void app:: zeroIvValues(bool checkAvail, bool skipYieldDay) { Inverter<> *iv; diff --git a/src/app.h b/src/app.h index 300c1c25..8fe9420d 100644 --- a/src/app.h +++ b/src/app.h @@ -188,6 +188,10 @@ class app : public IApp, public ah::Scheduler { return mNetwork->getIp(); } + bool isApActive(void) override { + return mNetwork->isApActive(); + } + void setRebootFlag() override { once(std::bind(&app::tickReboot, this), 3, "rboot"); } @@ -386,8 +390,10 @@ class app : public IApp, public ah::Scheduler { bool mNtpReceived = false; void updateNtp(void); - void triggerTickSend() override { - once(std::bind(&app::tickSend, this), 0, "tSend"); + void triggerTickSend(uint8_t id) override { + once([this, id]() { + sendIv(mSys.getInverterByPos(id)); + }, 0, "devct"); } void tickCalcSunrise(void); @@ -396,6 +402,7 @@ class app : public IApp, public ah::Scheduler { void tickSunrise(void); void tickComm(void); void tickSend(void); + bool sendIv(Inverter<> *iv); void tickMinute(void); void tickZeroValues(void); void tickMidnight(void); diff --git a/src/appInterface.h b/src/appInterface.h index 49470e02..a1f5cd0e 100644 --- a/src/appInterface.h +++ b/src/appInterface.h @@ -31,6 +31,7 @@ class IApp { virtual bool getWasInCh12to14(void) const = 0; #endif /* defined(ETHERNET) */ virtual String getIp(void) = 0; + virtual bool isApActive(void) = 0; virtual uint32_t getUptime() = 0; virtual uint32_t getTimestamp() = 0; @@ -42,7 +43,7 @@ class IApp { virtual void getSchedulerInfo(uint8_t *max) = 0; virtual void getSchedulerNames() = 0; - virtual void triggerTickSend() = 0; + virtual void triggerTickSend(uint8_t id) = 0; virtual bool getRebootRequestState() = 0; virtual bool getSettingsValid() = 0; diff --git a/src/network/AhoyNetwork.h b/src/network/AhoyNetwork.h index c98d9866..55c5d193 100644 --- a/src/network/AhoyNetwork.h +++ b/src/network/AhoyNetwork.h @@ -85,13 +85,18 @@ class AhoyNetwork { return false; } + bool isApActive() { + return mAp.isEnabled(); + } + #if !defined(ETHERNET) bool getAvailNetworks(JsonObject obj) { JsonArray nets = obj.createNestedArray(F("networks")); if(!mScanActive) { mScanActive = true; - WiFi.disconnect(); + if(NetworkState::GOT_IP != mStatus) + WiFi.disconnect(); WiFi.scanNetworks(true, true); return false; } diff --git a/src/network/AhoyWifiAp.h b/src/network/AhoyWifiAp.h index 56ff63d7..ce2bbd1b 100644 --- a/src/network/AhoyWifiAp.h +++ b/src/network/AhoyWifiAp.h @@ -54,6 +54,9 @@ class AhoyWifiAp { if(!mEnabled) return; + if(WiFi.softAPgetStationNum() > 0) + return; + mDns.stop(); WiFi.softAPdisconnect(); #if defined(ETHERNET) diff --git a/src/network/AhoyWifiEsp32.h b/src/network/AhoyWifiEsp32.h index 58f5dc5d..41956dfc 100644 --- a/src/network/AhoyWifiEsp32.h +++ b/src/network/AhoyWifiEsp32.h @@ -43,6 +43,7 @@ class AhoyWifi : public AhoyNetwork { mConnected = false; mOnNetworkCB(false); mAp.enable(); + MDNS.end(); } break; @@ -50,11 +51,14 @@ class AhoyWifi : public AhoyNetwork { break; case NetworkState::GOT_IP: - if(!mConnected) { + if(mAp.isEnabled()) mAp.disable(); + + if(!mConnected) { mConnected = true; ah::welcome(WiFi.localIP().toString(), F("Station")); MDNS.begin(mConfig->sys.deviceName); + MDNS.addServiceTxt("http", "tcp", "path", "/"); mOnNetworkCB(true); } break; diff --git a/src/network/AhoyWifiEsp8266.h b/src/network/AhoyWifiEsp8266.h index 93597f72..2497448b 100644 --- a/src/network/AhoyWifiEsp8266.h +++ b/src/network/AhoyWifiEsp8266.h @@ -39,6 +39,7 @@ class AhoyWifi : public AhoyNetwork { mConnected = false; mOnNetworkCB(false); mAp.enable(); + MDNS.end(); } if (WiFi.softAPgetStationNum() > 0) { @@ -93,6 +94,9 @@ class AhoyWifi : public AhoyNetwork { mConnected = true; ah::welcome(WiFi.localIP().toString(), F("Station")); MDNS.begin(mConfig->sys.deviceName); + MDNSResponder::hMDNSService hRes = MDNS.addService(NULL, "http", "tcp", 80); + MDNS.addServiceTxt(hRes, "path", "/"); + MDNS.announce(); mOnNetworkCB(true); } diff --git a/src/web/RestApi.h b/src/web/RestApi.h index 0f256f25..a9756944 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -1011,7 +1011,7 @@ class RestApi { accepted = iv->setDevControlRequest(ActivePowerContr); if(accepted) - mApp->triggerTickSend(); + mApp->triggerTickSend(iv->id); } else if(F("dev") == jsonIn[F("cmd")]) { DPRINTLN(DBG_INFO, F("dev cmd")); iv->setDevCommand(jsonIn[F("val")].as()); diff --git a/src/web/html/setup.html b/src/web/html/setup.html index fb1eff97..51d48f7c 100644 --- a/src/web/html/setup.html +++ b/src/web/html/setup.html @@ -57,22 +57,9 @@
{#AP_PWD}
-
-
{#SEARCH_NETWORKS}
-
-
- -
-
{#AVAIL_NETWORKS}
-
- -
-
SSID
-
+
{#SSID_HIDDEN}
@@ -606,12 +593,6 @@ setTimeout(function() {getAjax('/api/index', apiCbNtp2)}, 2000) } - function scan() { - var obj = {cmd: "scan_wifi", token: "*"} - getAjax("/api/setup", apiCbWifi, "POST", JSON.stringify(obj)); - setTimeout(function() {getAjax('/api/setup/networks', listNetworks)}, 5000); - } - function syncTime() { var obj = {cmd: "sync_ntp", token: "*"} getAjax("/api/setup", apiCbNtp, "POST", JSON.stringify(obj)) @@ -1319,13 +1300,6 @@ s.appendChild(opt("-1", "{#NO_NETWORK_FOUND}")); } - function selNet() { - var s = document.getElementById("networks"); - var e = document.getElementsByName("ssid")[0]; - if(-1 != s.value) - e.value = s.value; - } - getAjax("/api/setup", parse); diff --git a/src/web/html/wizard.html b/src/web/html/wizard.html index d57562d1..1fc8503c 100644 --- a/src/web/html/wizard.html +++ b/src/web/html/wizard.html @@ -218,7 +218,7 @@ sect("{#WIFI_MANUAL}", ml("input", {id: "man", type: "text"})), sect("{#WIFI_PASSWORD}", ml("input", {id: "pwd", type: "password"})), ml("div", {class: "row my-4"}, ml("div", {class: "col a-r"}, ml("input", {type: "button", class:"btn", value: "{#BTN_NEXT}", onclick: () => {saveWifi()}}, null))), - ml("div", {class: "row mt-5"}, ml("div", {class: "col a-c"}, ml("a", {href: "http://192.168.4.1/"}, "{#STOP_WIZARD}"))) + ml("div", {class: "row mt-5"}, ml("div", {class: "col a-c"}, ml("a", {href: "http://192.168.4.1/index"}, "{#STOP_WIZARD}"))) ]) } /*ENDIF_ETHERNET*/ @@ -229,9 +229,9 @@ ml("div", {class: "row"}, ml("div", {class: "col"}, ml("span", {class: "fs-5"}, "{#TEST_CONNECTION}"))), sect("{#TRY_TO_CONNECT}", ml("span", {id: "state"}, "{#CONNECTING}")), ml("div", {class: "row my-4"}, ml("div", {class: "col a-r"}, ml("input", {type: "button", class:"btn hide", id: "btn", value: "{#BTN_FINISH}", onclick: () => {redirect()}}, null))), - ml("div", {class: "row mt-5"}, ml("div", {class: "col a-c"}, ml("a", {href: "http://192.168.4.1/"}, "{#STOP_WIZARD}"))) + ml("div", {class: "row mt-5"}, ml("div", {class: "col a-c"}, ml("a", {href: "http://192.168.4.1/index"}, "{#STOP_WIZARD}"))) ) - v = setInterval(() => {getAjax('/api/setup/getip', printIp)}, 1000); + v = setInterval(() => {getAjax('/api/setup/getip', printIp)}, 300); } function redirect() { @@ -286,7 +286,8 @@ } c.append(step1()) - v = setInterval(() => {getAjax('/api/setup/networks', nets)}, 1000); + getAjax('/api/setup/networks', nets) + v = setInterval(() => {getAjax('/api/setup/networks', nets)}, 1000) /*ENDIF_ETHERNET*/ diff --git a/src/web/lang.json b/src/web/lang.json index ee942608..57ded1dd 100644 --- a/src/web/lang.json +++ b/src/web/lang.json @@ -81,7 +81,7 @@ { "token": "BTN_NEXT", "en": "next >>", - "de": "prüfen >>" + "de": "prüfen >>" }, { "token": "BTN_REBOOT", @@ -91,7 +91,7 @@ { "token": "TEST_CONNECTION", "en": "Test Connection", - "de": "Verbindung wird überprüft" + "de": "Verbindung wird überprüft" }, { "token": "TRY_TO_CONNECT", @@ -259,19 +259,9 @@ "de": "Netzwerke suchen" }, { - "token": "BTN_SCAN", - "en": "scan", - "de": "Suche starten" - }, - { - "token": "AVAIL_NETWORKS", - "en": "Avail Networks", - "de": "Verfügbare Netzwerke" - }, - { - "token": "NETWORK_NOT_SCANNED", - "en": "not scanned", - "de": "nicht gesucht" + "token": "SCAN_WIFI", + "en": "scan for WiFi networks", + "de": "nach WiFi Netzwerken suchen" }, { "token": "SSID_HIDDEN", diff --git a/src/web/web.h b/src/web/web.h index 56ff577e..4f93b905 100644 --- a/src/web/web.h +++ b/src/web/web.h @@ -57,7 +57,8 @@ class Web { mConfig = config; DPRINTLN(DBG_VERBOSE, F("app::setup-on")); - mWeb.on("/", HTTP_GET, std::bind(&Web::onIndex, this, std::placeholders::_1)); + mWeb.on("/", HTTP_GET, std::bind(&Web::onIndex, this, std::placeholders::_1, true)); + mWeb.on("/index", HTTP_GET, std::bind(&Web::onIndex, this, std::placeholders::_1, false)); mWeb.on("/login", HTTP_ANY, std::bind(&Web::onLogin, this, std::placeholders::_1)); mWeb.on("/logout", HTTP_GET, std::bind(&Web::onLogout, this, std::placeholders::_1)); mWeb.on("/colors.css", HTTP_GET, std::bind(&Web::onColor, this, std::placeholders::_1)); @@ -319,7 +320,11 @@ class Web { client->send("hello!", NULL, millis(), 1000); } - void onIndex(AsyncWebServerRequest *request) { + void onIndex(AsyncWebServerRequest *request, bool checkAp = true) { + if(mApp->isApActive() && checkAp) { + onWizard(request); + return; + } getPage(request, PROT_MASK_INDEX, index_html, index_html_len); } From 1e6f7c1247ddfbb51a78df92c07ad5d30e41c7b4 Mon Sep 17 00:00:00 2001 From: Sebastian Rothe Date: Mon, 1 Apr 2024 18:45:16 +0200 Subject: [PATCH 19/21] fix: get refresh property from object --- src/web/html/history.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/web/html/history.html b/src/web/html/history.html index 7ec9be7e..d21e6b96 100644 --- a/src/web/html/history.html +++ b/src/web/html/history.html @@ -150,11 +150,11 @@ parseRssi(obj.generic) window.setInterval("getAjax('/api/powerHistory', parsePowerHistory)", obj.refresh * 1000) setTimeout(() => { - window.setInterval("getAjax('/api/powerHistoryDay', parsePowerHistoryDay)", refresh * 1000) + window.setInterval("getAjax('/api/powerHistoryDay', parsePowerHistoryDay)", obj.refresh * 1000) }, 200) /*IF_ENABLE_HISTORY_YIELD_PER_DAY*/ setTimeout(() => { - window.setInterval("getAjax('/api/yieldDayHistory', parseYieldDayHistory)", refresh * 1000) + window.setInterval("getAjax('/api/yieldDayHistory', parseYieldDayHistory)", obj.refresh * 1000) }, 400) /*ENDIF_ENABLE_HISTORY_YIELD_PER_DAY*/ } From 1887d6cea5cc79b0d51ef767e880d6261e6aa700 Mon Sep 17 00:00:00 2001 From: lumapu Date: Tue, 2 Apr 2024 11:55:57 +0200 Subject: [PATCH 20/21] 0.8.103 * merge PR: fix: get refresh property from object #1552 * merge PR: fix typos and spelling in Github Issue template #1550 * merge PR: shorten last cmt waiting time #1549 --- src/CHANGES.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/CHANGES.md b/src/CHANGES.md index 1ba9edd1..3705c785 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,10 @@ # Development Changes +## 0.8.103 - 2024-04-02 +* merge PR: fix: get refresh property from object #1552 +* merge PR: fix typos and spelling in Github Issue template #1550 +* merge PR: shorten last cmt waiting time #1549 + ## 0.8.102 - 2024-04-01 * fix NTP for `opendtufusion` #1542 * fix scan WiFi in AP mode From 7ee1f992cb4d3c59a9b7f1fdb5f4d797f4a24085 Mon Sep 17 00:00:00 2001 From: lumapu Date: Tue, 2 Apr 2024 13:09:19 +0200 Subject: [PATCH 21/21] 0.8.103 * fix cppcheck warnings * changed MqTT retained flags of some topics --- src/CHANGES.md | 2 ++ src/app.cpp | 17 +++++++++-------- src/app.h | 2 +- src/defines.h | 2 +- src/network/AhoyWifiEsp32.h | 10 ---------- src/publisher/pubMqtt.h | 4 ++-- src/publisher/pubMqttIvData.h | 2 -- src/web/RestApi.h | 2 +- 8 files changed, 16 insertions(+), 25 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index 3705c785..73c5c5d4 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -4,6 +4,8 @@ * merge PR: fix: get refresh property from object #1552 * merge PR: fix typos and spelling in Github Issue template #1550 * merge PR: shorten last cmt waiting time #1549 +* fix cppcheck warnings +* changed MqTT retained flags of some topics ## 0.8.102 - 2024-04-01 * fix NTP for `opendtufusion` #1542 diff --git a/src/app.cpp b/src/app.cpp index 5166c035..f22e6906 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -56,9 +56,9 @@ void app::setup() { #ifdef ETHERNET delay(1000); - mNetwork = (AhoyNetwork*) new AhoyEthernet(); + mNetwork = static_cast(new AhoyEthernet()); #else - mNetwork = (AhoyNetwork*) new AhoyWifi(); + mNetwork = static_cast(new AhoyWifi()); #endif // ETHERNET mNetwork->setup(mConfig, &mTimestamp, [this](bool gotIp) { this->onNetwork(gotIp); }, [this](bool gotTime) { this->onNtpUpdate(gotTime); }); mNetwork->begin(); @@ -403,7 +403,8 @@ void app::tickSend(void) { for (uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) { Inverter<> *iv = mSys.getInverterByPos(i); - sendIv(iv); + if(!sendIv(iv)) + notAvail = false; } if(mAllIvNotAvail != notAvail) @@ -415,22 +416,22 @@ void app::tickSend(void) { //----------------------------------------------------------------------------- bool app::sendIv(Inverter<> *iv) { - bool notAvail = true; if(NULL == iv) - return notAvail; + return true; if(!iv->config->enabled) - return notAvail; + return true; if(!iv->commEnabled) { DPRINT_IVID(DBG_INFO, iv->id); DBGPRINTLN(F("no communication to the inverter (night time)")); - return notAvail; + return true; } if(!iv->radio->isChipConnected()) - return notAvail; + return true; + bool notAvail = true; if(InverterStatus::OFF != iv->status) notAvail = false; diff --git a/src/app.h b/src/app.h index 8fe9420d..2fc37ea8 100644 --- a/src/app.h +++ b/src/app.h @@ -414,7 +414,7 @@ class app : public IApp, public ah::Scheduler { bool mShowRebootRequest = false; - AhoyNetwork *mNetwork; + AhoyNetwork *mNetwork = nullptr; WebType mWeb; RestApiType mApi; Protection *mProtection = nullptr; diff --git a/src/defines.h b/src/defines.h index ab7c860b..502568a8 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 102 +#define VERSION_PATCH 103 //------------------------------------- typedef struct { uint8_t ch; diff --git a/src/network/AhoyWifiEsp32.h b/src/network/AhoyWifiEsp32.h index 41956dfc..a3bbb9cf 100644 --- a/src/network/AhoyWifiEsp32.h +++ b/src/network/AhoyWifiEsp32.h @@ -68,16 +68,6 @@ class AhoyWifi : public AhoyNetwork { String getIp(void) override { return WiFi.localIP().toString(); } - - private: - void sortRSSI(int *sort, int n) { - for (int i = 0; i < n; i++) - sort[i] = i; - for (int i = 0; i < n; i++) - for (int j = i + 1; j < n; j++) - if (WiFi.RSSI(sort[j]) > WiFi.RSSI(sort[i])) - std::swap(sort[i], sort[j]); - } }; #endif /*ESP32 & !ETHERNET*/ diff --git a/src/publisher/pubMqtt.h b/src/publisher/pubMqtt.h index 2d393b8b..35dc2b71 100644 --- a/src/publisher/pubMqtt.h +++ b/src/publisher/pubMqtt.h @@ -251,8 +251,8 @@ class PubMqtt { void onConnect(bool sessionPreset) { DPRINTLN(DBG_INFO, F("MQTT connected")); - publish(subtopics[MQTT_VERSION], mVersion, true); - publish(subtopics[MQTT_DEVICE], mDevName, true); + publish(subtopics[MQTT_VERSION], mVersion, false); + publish(subtopics[MQTT_DEVICE], mDevName, false); publish(subtopics[MQTT_IP_ADDR], mApp->getIp().c_str(), true); tickerMinute(); publish(mLwtTopic.data(), mqttStr[MQTT_STR_LWT_CONN], true, false); diff --git a/src/publisher/pubMqttIvData.h b/src/publisher/pubMqttIvData.h index 6ddd63a9..cd212aa4 100644 --- a/src/publisher/pubMqttIvData.h +++ b/src/publisher/pubMqttIvData.h @@ -187,7 +187,6 @@ class PubMqttIvData { static_cast(mIv->getChannelFieldValue(CH0, FLD_FW_BUILD_MONTH_DAY, rec)), static_cast(mIv->getChannelFieldValue(CH0, FLD_FW_BUILD_HOUR_MINUTE, rec)), static_cast(mIv->getChannelFieldValue(CH0, FLD_BOOTLOADER_VER, rec))); - retained = true; } else if(InverterDevInform_Simple == mCmd) { snprintf(mSubTopic.data(), mSubTopic.size(), "%s/hardware", mIv->config->name); snprintf(mVal.data(), mVal.size(), "{\"part\":%d,\"version\":\"%d\",\"grid_profile_code\":%d,\"grid_profile_version\":%d}", @@ -195,7 +194,6 @@ class PubMqttIvData { static_cast(mIv->getChannelFieldValue(CH0, FLD_HW_VERSION, rec)), static_cast(mIv->getChannelFieldValue(CH0, FLD_GRID_PROFILE_CODE, rec)), static_cast(mIv->getChannelFieldValue(CH0, FLD_GRID_PROFILE_VERSION, rec))); - retained = true; } else { snprintf(mSubTopic.data(), mSubTopic.size(), "%s/ch%d/%s", mIv->config->name, rec->assign[mPos].ch, fields[rec->assign[mPos].fieldId]); snprintf(mVal.data(), mVal.size(), "%g", ah::round3(mIv->getValue(mPos, rec))); diff --git a/src/web/RestApi.h b/src/web/RestApi.h index a9756944..665a3333 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -166,7 +166,7 @@ class RestApi { #else DynamicJsonDocument json(12000); // does this work? I have no ESP32 :-( #endif - DeserializationError err = deserializeJson(json, (const char *)mTmpBuf, mTmpSize); + DeserializationError err = deserializeJson(json, static_cast(mTmpBuf, mTmpSize)); json.shrinkToFit(); JsonObject obj = json.as();