Browse Source

fix night communication enable

improved different WiFi connection scenarios (STA WiFi not found, reconnect #509, redirect for AP to configuration)
pull/518/head
lumapu 2 years ago
parent
commit
de4c572ee2
  1. 12
      src/.vscode/settings.json
  2. 12
      src/CHANGES.md
  3. 1
      src/app.cpp
  4. 4
      src/app.h
  5. 1
      src/appInterface.h
  6. 6
      src/utils/scheduler.h
  7. 5
      src/web/RestApi.h
  8. 18
      src/web/web.h
  9. 249
      src/wifi/ahoywifi.cpp
  10. 15
      src/wifi/ahoywifi.h

12
src/.vscode/settings.json

@ -73,6 +73,16 @@
"sstream": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"cinttypes": "cpp"
"cinttypes": "cpp",
"bit": "cpp",
"compare": "cpp",
"concepts": "cpp",
"condition_variable": "cpp",
"set": "cpp",
"iostream": "cpp",
"mutex": "cpp",
"ranges": "cpp",
"stop_token": "cpp",
"thread": "cpp"
},
}

12
src/CHANGES.md

@ -1,17 +1,21 @@
# Changelog
## 0.5.59
* fix night communication enable
* improved different WiFi connection scenarios (STA WiFi not found, reconnect #509, redirect for AP to configuration)
## 0.5.58
* improved stability
* improved wifi initial connection - especially if station wifi is not available
* improved WiFi initial connection - especially if station WiFi is not available
* removed new operators from web.h (reduce dynamic allocation)
* improved sun calculation #515, #505
* fixed wifi auto reconnect #509
* fixed WiFi auto reconnect #509
* added disable night communication flag to MQTT #505
* changed MQTT publish of `available` and `available_text` to sunset #468
## 0.5.57
* improved stability
* added icons to index.html, added wifi-strength symbol on each page
* added icons to index.html, added WiFi-strength symbol on each page
* moved packet stats and sun to system.html
* refactored communication offset (adjustable in minutes now)
@ -32,7 +36,7 @@
## 0.5.53
* Mono-Display: show values in offline mode #498
* improved wifi class #483
* improved WiFi class #483
* added communication enable / disable (to test mutliple DTUs with the same inverter)
* fix factory reset #495

1
src/app.cpp

@ -266,6 +266,7 @@ void app::resetSystem(void) {
mSendLastIvId = 0;
mShowRebootRequest = false;
mIVCommunicationOn = true;
memset(&mStat, 0, sizeof(statistics_t));
}

4
src/app.h

@ -151,6 +151,10 @@ class app : public IApp, public ah::Scheduler {
return mApi.getTimezoneOffset();
}
void getSchedulerInfo(uint16_t *everyMax, uint16_t *atMax) {
return getStat(everyMax, atMax);
}
void setTimestamp(uint32_t newTime) {
DPRINTLN(DBG_DEBUG, F("setTimestamp: ") + String(newTime));
if(0 == newTime)

1
src/appInterface.h

@ -28,6 +28,7 @@ class IApp {
virtual void setTimestamp(uint32_t newTime) = 0;
virtual String getTimeStr(uint32_t offset) = 0;
virtual uint32_t getTimezoneOffset() = 0;
virtual void getSchedulerInfo(uint16_t *everyMax, uint16_t *atMax);
virtual bool getRebootRequestState() = 0;
virtual bool getSettingsValid() = 0;

6
src/utils/scheduler.h

@ -93,9 +93,9 @@ namespace ah {
return mTimestamp;
}
void stat() {
DPRINTLN(DBG_INFO, "max fill every: " + String(mStack.getMaxFill()));
DPRINTLN(DBG_INFO, "max fill at: " + String(mStackAt.getMaxFill()));
void getStat(uint16_t *everyMax, uint16_t *atMax) {
*everyMax = mStack.getMaxFill();
*atMax = mStackAt.getMaxFill();
}
protected:

5
src/web/RestApi.h

@ -199,6 +199,11 @@ class RestApi {
#endif
//obj[F("littlefs_total")] = LittleFS.totalBytes();
//obj[F("littlefs_used")] = LittleFS.usedBytes();
uint16_t evry, at;
mApp->getSchedulerInfo(&evry, &at);
obj[F("schEvryMax")] = evry;
obj[F("schAtMax")] = at;
}
void getHtmlSystem(JsonObject obj) {

18
src/web/web.h

@ -285,20 +285,10 @@ class Web {
}
void showNotFound(AsyncWebServerRequest *request) {
DPRINTLN(DBG_VERBOSE, F("showNotFound - ") + request->url());
String msg = F("File Not Found\n\nURL: ");
msg += request->url();
msg += F("\nMethod: ");
msg += ( request->method() == HTTP_GET ) ? "GET" : "POST";
msg += F("\nArguments: ");
msg += request->args();
msg += "\n";
for(uint8_t i = 0; i < request->args(); i++ ) {
msg += " " + request->argName(i) + ": " + request->arg(i) + "\n";
}
request->send(404, F("text/plain"), msg);
if(mProtected)
request->redirect("/login");
else
request->redirect("/setup");
}
void onReboot(AsyncWebServerRequest *request) {

249
src/wifi/ahoywifi.cpp

@ -12,39 +12,50 @@
// NTP CONFIG
#define NTP_PACKET_SIZE 48
enum {WIFI_NOT_FOUND = 0, WIFI_FOUND, WIFI_NOT_COMPLETE};
//-----------------------------------------------------------------------------
ahoywifi::ahoywifi() : mApIp(192, 168, 4, 1), mApMask(255, 255, 255, 0) {
mDnsActive = false;
mClientCnt = 0;
mLoopCnt = 250;
mExtScan = false;
}
ahoywifi::ahoywifi() : mApIp(192, 168, 4, 1) {}
//-----------------------------------------------------------------------------
void ahoywifi::setup(settings_t *config, uint32_t *utcTimestamp) {
mCnt = 0;
mConnected = false;
mReconnect = false;
mConfig = config;
mUtcTimestamp = utcTimestamp;
if(String(mConfig->sys.deviceName) != "")
WiFi.hostname(mConfig->sys.deviceName);
#if !defined(FB_WIFI_OVERRIDDEN)
setupAp();
#endif
mCnt = 0;
mConnected = false;
mReconnect = false;
mScanActive = false;
#if defined(ESP8266)
wifiConnectHandler = WiFi.onStationModeGotIP(std::bind(&ahoywifi::onConnect, this, std::placeholders::_1));
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();
}
//-----------------------------------------------------------------------------
void ahoywifi::setupWifi(void) {
#if !defined(FB_WIFI_OVERRIDDEN)
//if(strncmp(mConfig->sys.stationSsid, FB_WIFI_SSID, 14) == 0)
setupAp();
delay(1000);
#endif
#if !defined(AP_ONLY)
if(mConfig->valid) {
#if !defined(FB_WIFI_OVERRIDDEN)
if(strncmp(mConfig->sys.stationSsid, FB_WIFI_SSID, 14) != 0)
setupStation();
#else
setupStation();
#endif
}
#endif
}
@ -53,38 +64,29 @@ void ahoywifi::loop() {
#if !defined(AP_ONLY)
if(mReconnect) {
delay(100);
mCnt++;
if((mCnt % 50) == 0)
WiFi.disconnect();
else if((mCnt % 60) == 0) {
DPRINTLN(DBG_INFO, F("[WiFi] reconnect"));
WiFi.begin(mConfig->sys.stationSsid, mConfig->sys.stationPwd);
mCnt = 0;
if (WiFi.softAPgetStationNum() > 0) { // do not reconnect if any AP connection exists
mDns.processNextRequest();
if((WIFI_AP_STA == WiFi.getMode()) && !mScanActive) {
DBGPRINTLN(F("AP client connected"));
welcome(mApIp.toString());
WiFi.mode(WIFI_AP);
}
return;
}
}
yield();
if(mDnsActive) {
mDns.processNextRequest();
uint8_t cnt = WiFi.softAPgetStationNum();
if(cnt != mClientCnt) {
mClientCnt = cnt;
DPRINTLN(DBG_INFO, String(cnt) + F(" client(s) connected"));
else if(WIFI_AP == WiFi.getMode()) {
mCnt = 0;
WiFi.mode(WIFI_AP_STA);
}
mCnt++;
if(!mExtScan && (mLoopCnt == 240)) {
if(scanStationNetwork()) {
setupStation();
mLoopCnt = 0;
}
if ((mCnt % 10) == 0) {
DBGPRINT(F("reconnect in "));
DBGPRINT(String((100-mCnt)/10));
DBGPRINTLN(F(" seconds"));
}
if(0 != mLoopCnt) {
if(++mLoopCnt > 250) {
mLoopCnt = 1;
if(!mExtScan)
scanAvailNetworks(false);
}
delay(25);
if((mCnt % 100) == 0) { // try to reconnect after 10 sec without connection
WiFi.reconnect();
mCnt = 0;
}
}
#endif
@ -93,7 +95,7 @@ void ahoywifi::loop() {
//-----------------------------------------------------------------------------
void ahoywifi::setupAp(void) {
DPRINTLN(DBG_INFO, F("wifi::setupAp"));
DPRINTLN(DBG_VERBOSE, F("wifi::setupAp"));
DBGPRINTLN(F("\n---------\nAhoyDTU Info:"));
DBGPRINT(F("Version: "));
@ -109,18 +111,16 @@ void ahoywifi::setupAp(void) {
DBGPRINTLN(F("---------\n"));
WiFi.mode(WIFI_AP_STA);
WiFi.softAPConfig(mApIp, mApIp, mApMask);
WiFi.softAPConfig(mApIp, mApIp, IPAddress(255, 255, 255, 0));
WiFi.softAP(WIFI_AP_SSID, WIFI_AP_PWD);
mDns.setErrorReplyCode(DNSReplyCode::NoError);
mDns.start(53, "*", WiFi.softAPIP());
mDnsActive = true;
mDns.start(53, "*", mApIp);
}
//-----------------------------------------------------------------------------
void ahoywifi::setupStation(void) {
DPRINTLN(DBG_INFO, F("wifi::setupStation"));
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);
@ -130,34 +130,18 @@ void ahoywifi::setupStation(void) {
if(!WiFi.config(ip, gateway, mask, dns1, dns2))
DPRINTLN(DBG_ERROR, F("failed to set static IP!"));
}
WiFi.begin(mConfig->sys.stationSsid, mConfig->sys.stationPwd);
mReconnect = (WiFi.begin(mConfig->sys.stationSsid, mConfig->sys.stationPwd) != WL_CONNECTED);
if(String(mConfig->sys.deviceName) != "")
WiFi.hostname(mConfig->sys.deviceName);
DBGPRINT(F("connect to network '"));
DBGPRINT(mConfig->sys.stationSsid);
}
//-----------------------------------------------------------------------------
bool ahoywifi::scanStationNetwork(void) {
bool found = false;
int n = WiFi.scanComplete();
if(n > 0) {
for (int i = 0; i < n; i++) {
DPRINTLN(DBG_INFO, "found network: " + WiFi.SSID(i));
if(String(mConfig->sys.stationSsid) == WiFi.SSID(i)) {
found = true;
break;
}
}
WiFi.scanDelete();
}
return found;
DBGPRINTLN(F("' ..."));
}
//-----------------------------------------------------------------------------
bool ahoywifi::getNtpTime(void) {
//DPRINTLN(DBG_VERBOSE, F("wifi::getNtpTime"));
if(!mConnected)
return false;
@ -165,9 +149,10 @@ bool ahoywifi::getNtpTime(void) {
uint8_t buf[NTP_PACKET_SIZE];
uint8_t retry = 0;
WiFi.hostByName(mConfig->ntp.addr, timeServer);
mUdp.begin(mConfig->ntp.port);
if (WiFi.hostByName(mConfig->ntp.addr, timeServer) != 1)
return false;
mUdp.begin(mConfig->ntp.port);
sendNTPpacket(timeServer);
while(retry++ < 5) {
@ -195,11 +180,34 @@ bool ahoywifi::getNtpTime(void) {
//-----------------------------------------------------------------------------
void ahoywifi::scanAvailNetworks(bool externalCall) {
if(externalCall)
mExtScan = true;
if(-2 == WiFi.scanComplete())
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::scanAvailNetworks(void) {
if(-2 == WiFi.scanComplete()) {
mScanActive = true;
if(WIFI_AP == WiFi.getMode())
WiFi.mode(WIFI_AP_STA);
WiFi.scanNetworks(true);
}
}
@ -220,86 +228,69 @@ void ahoywifi::getAvailNetworks(JsonObject obj) {
nets[i]["ssid"] = WiFi.SSID(sort[i]);
nets[i]["rssi"] = WiFi.RSSI(sort[i]);
}
mScanActive = false;
WiFi.scanDelete();
}
mExtScan = 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();
}
//-----------------------------------------------------------------------------
#if defined(ESP8266)
void ahoywifi::onConnect(const WiFiEventStationModeGotIP& event) {
void ahoywifi::connectionEvent(bool connected) {
if (connected) {
if(!mConnected) {
mConnected = true;
mReconnect = false;
DBGPRINTLN(F("\n[WiFi] Connected"));
WiFi.mode(WIFI_STA);
DBGPRINTLN(F("[WiFi] AP disabled"));
mDnsActive = false;
mDns.stop();
welcome(WiFi.localIP().toString() + F(" (Station)"));
}
}
//-------------------------------------------------------------------------
void ahoywifi::onDisconnect(const WiFiEventStationModeDisconnected& event) {
} else {
if(mConnected) {
mConnected = false;
mReconnect = true;
mCnt = 0;
mCnt = 50; // try to reconnect in 5 sec
setupWifi(); // reconnect with AP / Station setup
DPRINTLN(DBG_INFO, "[WiFi] Connection Lost");
}
}
}
//-----------------------------------------------------------------------------
#if defined(ESP8266)
//-------------------------------------------------------------------------
void ahoywifi::onConnect(const WiFiEventStationModeConnected& event) {
connectionEvent(true);
}
//-------------------------------------------------------------------------
void ahoywifi::onGotIP(const WiFiEventStationModeGotIP& event) {
welcome(WiFi.localIP().toString() + F(" (Station)"));
}
//-------------------------------------------------------------------------
void ahoywifi::onDisconnect(const WiFiEventStationModeDisconnected& event) {
connectionEvent(false);
}
#else
//-------------------------------------------------------------------------
void ahoywifi::onWiFiEvent(WiFiEvent_t event) {
DBGPRINT(F("Wifi event: "));
DBGPRINTLN(String(event));
switch(event) {
case SYSTEM_EVENT_STA_CONNECTED:
connectionEvent(true);
break;
case SYSTEM_EVENT_STA_GOT_IP:
if(!mConnected) {
delay(1000);
mConnected = true;
DBGPRINTLN(F("\n[WiFi] Connected"));
welcome(WiFi.localIP().toString() + F(" (Station)"));
WiFi.mode(WIFI_STA);
WiFi.begin();
DBGPRINTLN(F("[WiFi] AP disabled"));
mDnsActive = false;
mDns.stop();
mReconnect = false;
}
welcome(WiFi.localIP().toString() + F(" (Station)"));
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
if(mConnected) {
mConnected = false;
mReconnect = true;
mCnt = 0;
DPRINTLN(DBG_INFO, "[WiFi] Connection Lost");
}
connectionEvent(false);
break;
default:

15
src/wifi/ahoywifi.h

@ -23,16 +23,18 @@ class ahoywifi {
void setup(settings_t *config, uint32_t *utcTimestamp);
void loop(void);
bool getNtpTime(void);
void scanAvailNetworks(bool externalCall = true);
void scanAvailNetworks(void);
void getAvailNetworks(JsonObject obj);
private:
void setupWifi(void);
void setupAp(void);
void setupStation(void);
bool scanStationNetwork(void);
void sendNTPpacket(IPAddress& address);
#if defined(ESP8266)
void onConnect(const WiFiEventStationModeGotIP& event);
void connectionEvent(bool connected);
void onConnect(const WiFiEventStationModeConnected& event);
void onGotIP(const WiFiEventStationModeGotIP& event);
void onDisconnect(const WiFiEventStationModeDisconnected& event);
#else
void onWiFiEvent(WiFiEvent_t event);
@ -43,11 +45,10 @@ class ahoywifi {
settings_t *mConfig;
DNSServer mDns;
IPAddress mApIp, mApMask;
IPAddress mApIp;
WiFiUDP mUdp; // for time server
#if defined(ESP8266)
WiFiEventHandler wifiConnectHandler;
WiFiEventHandler wifiDisconnectHandler;
WiFiEventHandler wifiConnectHandler, wifiDisconnectHandler, wifiGotIPHandler;
#endif
bool mConnected, mReconnect, mDnsActive;
@ -55,7 +56,7 @@ class ahoywifi {
uint32_t *mUtcTimestamp;
uint8_t mLoopCnt;
bool mExtScan;
bool mScanActive;
};
#endif /*__AHOYWIFI_H__*/

Loading…
Cancel
Save