160 lines
3.3 KiB
C++
160 lines
3.3 KiB
C++
#include "wifi.h"
|
|
#include "log.h"
|
|
|
|
#include <WiFi.h>
|
|
#include <ArduinoOTA.h>
|
|
|
|
#define NTP_SERVER "pool.ntp.org"
|
|
|
|
#define TIMEZONE_OFFSET 3600
|
|
|
|
#define DST_OFFSET 3600
|
|
|
|
#define MIN_EPOCH_SECONDS 1712675973
|
|
|
|
uint8_t otaLastLogStep = 0;
|
|
|
|
bool wifiConnected = false;
|
|
|
|
bool timeSet = false;
|
|
|
|
time_t preTimeOffset = 0;
|
|
|
|
unsigned long wifiLastConnectTry = 0;
|
|
|
|
void otaSetup();
|
|
|
|
void bootDelay();
|
|
|
|
void wifiSetup() {
|
|
WiFi.softAPdisconnect();
|
|
WiFi.setAutoReconnect(false);
|
|
wifiConnect();
|
|
otaSetup();
|
|
configTime(TIMEZONE_OFFSET, DST_OFFSET, NTP_SERVER, WiFi.gatewayIP().toString().c_str());
|
|
bootDelay();
|
|
}
|
|
|
|
void wifiConnect() {
|
|
WiFi.disconnect();
|
|
yield();
|
|
wifiLastConnectTry = millis();
|
|
info("WIFI", "Connecting WiFi: %s", WIFI_SSID);
|
|
WiFi.begin(WIFI_SSID, WIFI_PKEY);
|
|
yield();
|
|
}
|
|
|
|
void otaSetup() {
|
|
ArduinoOTA.onStart([] {
|
|
info("OTA", "OTA start...");
|
|
otaLastLogStep = 0;
|
|
});
|
|
ArduinoOTA.onProgress([](unsigned int received, unsigned int total) {
|
|
uint8_t currentStep = 20 * received / total;
|
|
if (otaLastLogStep != currentStep) {
|
|
info("OTA", "OTA Progress: %3d%%", currentStep * 5);
|
|
otaLastLogStep = currentStep;
|
|
}
|
|
});
|
|
ArduinoOTA.onEnd([] {
|
|
info("OTA", "OTA Complete!");
|
|
});
|
|
ArduinoOTA.onError([](ota_error_t e) {
|
|
const char *name;
|
|
switch (e) {
|
|
case OTA_AUTH_ERROR:
|
|
name = "AUTH";
|
|
break;
|
|
case OTA_BEGIN_ERROR:
|
|
name = "BEGIN";
|
|
break;
|
|
case OTA_CONNECT_ERROR:
|
|
name = "CONNECT";
|
|
break;
|
|
case OTA_RECEIVE_ERROR:
|
|
name = "RECEIVE";
|
|
break;
|
|
case OTA_END_ERROR:
|
|
name = "END";
|
|
break;
|
|
default:
|
|
name = "[???]";
|
|
break;
|
|
}
|
|
error("OTA", name);
|
|
});
|
|
ArduinoOTA.begin();
|
|
}
|
|
|
|
void bootDelay() {
|
|
#ifdef BOOT_DELAY
|
|
info("BOOT DELAY", "Waiting for WiFi...");
|
|
while ((uint32_t) WiFi.localIP() == 0) {
|
|
delay(100);
|
|
yield();
|
|
wifiLoop();
|
|
}
|
|
info("BOOT DELAY", "WiFi connected!");
|
|
unsigned long begin = millis();
|
|
while (millis() - begin < 10000) {
|
|
delay(100);
|
|
yield();
|
|
wifiLoop();
|
|
}
|
|
info("BOOT DELAY", "Boot delay completed!");
|
|
#endif
|
|
}
|
|
|
|
void wifiLoop() {
|
|
const time_t epochSeconds = getTime();
|
|
if (!timeSet) {
|
|
timeSet = epochSeconds >= MIN_EPOCH_SECONDS;
|
|
if (!timeSet) {
|
|
preTimeOffset = epochSeconds;
|
|
} else {
|
|
info("NTP", "Time set!");
|
|
}
|
|
}
|
|
|
|
const bool hasIp = static_cast<uint32_t>(WiFi.localIP()) != 0;
|
|
if (wifiConnected) {
|
|
if (!hasIp) {
|
|
wifiConnected = false;
|
|
info("WIFI", "WiFi disconnected!");
|
|
wifiConnect();
|
|
}
|
|
} else {
|
|
if (hasIp) {
|
|
wifiConnected = true;
|
|
info("WIFI", "Connected as: %s", WiFi.localIP().toString().c_str());
|
|
} else if (millis() - wifiLastConnectTry > 10000) {
|
|
info("WIFI", "WiFi timeout!");
|
|
wifiConnect();
|
|
}
|
|
}
|
|
}
|
|
|
|
bool isTimeSet() {
|
|
return timeSet;
|
|
}
|
|
|
|
time_t getTime() {
|
|
time_t epochSeconds;
|
|
time(&epochSeconds);
|
|
return epochSeconds;
|
|
}
|
|
|
|
time_t correctTime(const time_t value) {
|
|
if (!timeSet) {
|
|
return value;
|
|
}
|
|
if (value < MIN_EPOCH_SECONDS) {
|
|
return getTime() - preTimeOffset + value;
|
|
}
|
|
return value;
|
|
}
|
|
|
|
bool isOlderThan(time_t time, time_t seconds) {
|
|
return getTime() > correctTime(time) + seconds;
|
|
}
|