mirror of https://github.com/lumapu/ahoy.git
7 changed files with 759 additions and 603 deletions
@ -1,328 +0,0 @@ |
|||
//-----------------------------------------------------------------------------
|
|||
// 2022 Ahoy, https://www.mikrocontroller.net/topic/525778
|
|||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
|||
//-----------------------------------------------------------------------------
|
|||
|
|||
#include "main.h" |
|||
#include "version.h" |
|||
|
|||
//-----------------------------------------------------------------------------
|
|||
Main::Main(void) { |
|||
mDns = new DNSServer(); |
|||
mWeb = new ESP8266WebServer(80); |
|||
mUdp = new WiFiUDP(); |
|||
|
|||
memset(&config, 0, sizeof(config_t)); |
|||
|
|||
config.apActive = true; |
|||
mWifiSettingsValid = false; |
|||
mSettingsValid = false; |
|||
|
|||
mLimit = 10; |
|||
mNextTryTs = 0; |
|||
mApLastTick = 0; |
|||
|
|||
// default config
|
|||
snprintf(config.version, 12, "%d.%d.%d", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH); |
|||
config.apActive = false; |
|||
config.sendInterval = SEND_INTERVAL; |
|||
|
|||
|
|||
mEep = new eep(); |
|||
Serial.begin(115200); |
|||
DPRINTLN(DBG_VERBOSE, F("Main::Main")); |
|||
|
|||
mUptimeSecs = 0; |
|||
mUptimeTicker = 0xffffffff; |
|||
mUptimeInterval = 1000; |
|||
|
|||
#ifdef AP_ONLY |
|||
mTimestamp = 1; |
|||
#else |
|||
mTimestamp = 0; |
|||
#endif |
|||
|
|||
mHeapStatCnt = 0; |
|||
} |
|||
|
|||
|
|||
//-----------------------------------------------------------------------------
|
|||
void Main::setup(uint32_t timeout) { |
|||
DPRINTLN(DBG_VERBOSE, F("Main::setup")); |
|||
bool startAp = config.apActive; |
|||
mLimit = timeout; |
|||
|
|||
|
|||
startAp = getConfig(); |
|||
|
|||
#ifndef AP_ONLY |
|||
if(false == startAp) |
|||
startAp = setupStation(timeout); |
|||
#endif |
|||
|
|||
config.apActive = startAp; |
|||
mStActive = !startAp; |
|||
} |
|||
|
|||
|
|||
//-----------------------------------------------------------------------------
|
|||
void Main::loop(void) { |
|||
//DPRINTLN(DBG_VERBOSE, F("M"));
|
|||
if(config.apActive) { |
|||
mDns->processNextRequest(); |
|||
#ifndef AP_ONLY |
|||
if(checkTicker(&mNextTryTs, (WIFI_AP_ACTIVE_TIME * 1000))) { |
|||
config.apActive = setupStation(mLimit); |
|||
if(config.apActive) { |
|||
if(strlen(WIFI_AP_PWD) < 8) |
|||
DPRINTLN(DBG_ERROR, F("password must be at least 8 characters long")); |
|||
mApLastTick = millis(); |
|||
mNextTryTs = (millis() + (WIFI_AP_ACTIVE_TIME * 1000)); |
|||
setupAp(WIFI_AP_SSID, WIFI_AP_PWD); |
|||
} |
|||
} |
|||
else { |
|||
if(millis() - mApLastTick > 10000) { |
|||
uint8_t cnt = WiFi.softAPgetStationNum(); |
|||
if(cnt > 0) { |
|||
DPRINTLN(DBG_INFO, String(cnt) + F(" clients connected, resetting AP timeout")); |
|||
mNextTryTs = (millis() + (WIFI_AP_ACTIVE_TIME * 1000)); |
|||
} |
|||
mApLastTick = millis(); |
|||
DPRINTLN(DBG_INFO, F("AP will be closed in ") + String((mNextTryTs - mApLastTick) / 1000) + F(" seconds")); |
|||
} |
|||
} |
|||
#endif |
|||
} |
|||
mWeb->handleClient(); |
|||
|
|||
if(checkTicker(&mUptimeTicker, mUptimeInterval)) { |
|||
mUptimeSecs++; |
|||
if(0 != mTimestamp) |
|||
mTimestamp++; |
|||
else { |
|||
if(!config.apActive) { |
|||
mTimestamp = getNtpTime(); |
|||
DPRINTLN(DBG_INFO, "[NTP]: " + getDateTimeStr(mTimestamp)); |
|||
} |
|||
} |
|||
|
|||
/*if(++mHeapStatCnt >= 10) {
|
|||
mHeapStatCnt = 0; |
|||
stats(); |
|||
}*/ |
|||
} |
|||
if (WiFi.status() != WL_CONNECTED) { |
|||
DPRINTLN(DBG_INFO, "[WiFi]: Connection Lost"); |
|||
mStActive = false; |
|||
} |
|||
} |
|||
|
|||
|
|||
//-----------------------------------------------------------------------------
|
|||
bool Main::getConfig(void) { |
|||
DPRINTLN(DBG_VERBOSE, F("Main::getConfig")); |
|||
config.apActive = false; |
|||
|
|||
mWifiSettingsValid = checkEEpCrc(ADDR_START, ADDR_WIFI_CRC, ADDR_WIFI_CRC); |
|||
mSettingsValid = checkEEpCrc(ADDR_START_SETTINGS, ((ADDR_NEXT)-(ADDR_START_SETTINGS)), ADDR_SETTINGS_CRC); |
|||
|
|||
if(mWifiSettingsValid) { |
|||
mEep->read(ADDR_SSID, config.stationSsid, SSID_LEN); |
|||
mEep->read(ADDR_PWD, config.stationPwd, PWD_LEN); |
|||
mEep->read(ADDR_DEVNAME, config.deviceName, DEVNAME_LEN); |
|||
} |
|||
|
|||
if((!mWifiSettingsValid) || (config.stationSsid[0] == 0xff)) { |
|||
snprintf(config.stationSsid, SSID_LEN, "%s", FB_WIFI_SSID); |
|||
snprintf(config.stationPwd, PWD_LEN, "%s", FB_WIFI_PWD); |
|||
snprintf(config.deviceName, DEVNAME_LEN, "%s", DEF_DEVICE_NAME); |
|||
} |
|||
|
|||
return config.apActive; |
|||
} |
|||
|
|||
|
|||
//-----------------------------------------------------------------------------
|
|||
void Main::setupAp(const char *ssid, const char *pwd) { |
|||
DPRINTLN(DBG_VERBOSE, F("Main::setupAp")); |
|||
IPAddress apIp(192, 168, 1, 1); |
|||
|
|||
DPRINTLN(DBG_INFO, F("\n---------\nAP MODE\nSSID: ") |
|||
+ String(ssid) + F("\nPWD: ") |
|||
+ String(pwd) + F("\nActive for: ") |
|||
+ String(WIFI_AP_ACTIVE_TIME) + F(" seconds") |
|||
+ F("\n---------\n")); |
|||
DPRINTLN(DBG_DEBUG, String(mNextTryTs)); |
|||
|
|||
WiFi.mode(WIFI_AP); |
|||
WiFi.softAPConfig(apIp, apIp, IPAddress(255, 255, 255, 0)); |
|||
WiFi.softAP(ssid, pwd); |
|||
|
|||
mDns->start(mDnsPort, "*", apIp); |
|||
|
|||
/*mWeb->onNotFound([&]() {
|
|||
showSetup(); |
|||
}); |
|||
mWeb->on("/", std::bind(&Main::showSetup, this)); |
|||
|
|||
mWeb->begin();*/ |
|||
} |
|||
|
|||
|
|||
//-----------------------------------------------------------------------------
|
|||
bool Main::setupStation(uint32_t timeout) { |
|||
DPRINTLN(DBG_VERBOSE, F("Main::setupStation")); |
|||
int32_t cnt; |
|||
bool startAp = false; |
|||
|
|||
if(timeout >= 3) |
|||
cnt = (timeout - 3) / 2 * 10; |
|||
else { |
|||
timeout = 1; |
|||
cnt = 1; |
|||
} |
|||
|
|||
WiFi.mode(WIFI_STA); |
|||
WiFi.begin(config.stationSsid, config.stationPwd); |
|||
if(String(config.deviceName) != "") |
|||
WiFi.hostname(config.deviceName); |
|||
|
|||
delay(2000); |
|||
DPRINTLN(DBG_INFO, F("connect to network '") + String(config.stationSsid) + F("' ...")); |
|||
while (WiFi.status() != WL_CONNECTED) { |
|||
delay(100); |
|||
if(cnt % 100 == 0) |
|||
Serial.println("."); |
|||
else |
|||
Serial.print("."); |
|||
|
|||
if(timeout > 0) { // limit == 0 -> no limit
|
|||
if(--cnt <= 0) { |
|||
if(WiFi.status() != WL_CONNECTED) { |
|||
startAp = true; |
|||
WiFi.disconnect(); |
|||
} |
|||
delay(100); |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
Serial.println("."); |
|||
|
|||
if(false == startAp) { |
|||
mWeb->begin(); |
|||
} |
|||
|
|||
delay(1000); |
|||
|
|||
return startAp; |
|||
} |
|||
|
|||
|
|||
|
|||
//-----------------------------------------------------------------------------
|
|||
void Main::saveValues(uint32_t saveMask = 0) { |
|||
DPRINTLN(DBG_VERBOSE, F("Main::saveValues")); |
|||
|
|||
if(CHK_MSK(saveMask, SAVE_SSID)) |
|||
mEep->write(ADDR_SSID, config.stationSsid, SSID_LEN); |
|||
if(CHK_MSK(saveMask, SAVE_PWD)) |
|||
mEep->write(ADDR_PWD, config.stationPwd, SSID_LEN); |
|||
if(CHK_MSK(saveMask, SAVE_DEVICE_NAME)) |
|||
mEep->write(ADDR_DEVNAME, config.deviceName, DEVNAME_LEN); |
|||
|
|||
if(saveMask > 0) { |
|||
updateCrc(); |
|||
mEep->commit(); |
|||
} |
|||
} |
|||
|
|||
|
|||
//-----------------------------------------------------------------------------
|
|||
void Main::updateCrc(void) { |
|||
DPRINTLN(DBG_VERBOSE, F("Main::updateCrc")); |
|||
uint16_t crc; |
|||
crc = buildEEpCrc(ADDR_START, ADDR_WIFI_CRC); |
|||
//Serial.println("new CRC: " + String(crc, HEX));
|
|||
mEep->write(ADDR_WIFI_CRC, crc); |
|||
mEep->commit(); |
|||
} |
|||
|
|||
|
|||
//-----------------------------------------------------------------------------
|
|||
time_t Main::getNtpTime(void) { |
|||
//DPRINTLN(DBG_VERBOSE, F("Main::getNtpTime"));
|
|||
time_t date = 0; |
|||
IPAddress timeServer; |
|||
uint8_t buf[NTP_PACKET_SIZE]; |
|||
uint8_t retry = 0; |
|||
|
|||
WiFi.hostByName(NTP_SERVER_NAME, timeServer); |
|||
mUdp->begin(NTP_LOCAL_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 = (buf[40] << 24); |
|||
secsSince1900 |= (buf[41] << 16); |
|||
secsSince1900 |= (buf[42] << 8); |
|||
secsSince1900 |= (buf[43] ); |
|||
|
|||
date = secsSince1900 - 2208988800UL; // UTC time
|
|||
date += (TIMEZONE + offsetDayLightSaving(date)) * 3600; |
|||
break; |
|||
} |
|||
else |
|||
delay(10); |
|||
} |
|||
} |
|||
|
|||
return date; |
|||
} |
|||
|
|||
|
|||
//-----------------------------------------------------------------------------
|
|||
void Main::sendNTPpacket(IPAddress& address) { |
|||
//DPRINTLN(DBG_VERBOSE, F("Main::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(); |
|||
} |
|||
|
|||
|
|||
//-----------------------------------------------------------------------------
|
|||
// calculates the daylight saving time for middle Europe. Input: Unixtime in UTC
|
|||
// from: https://forum.arduino.cc/index.php?topic=172044.msg1278536#msg1278536
|
|||
time_t Main::offsetDayLightSaving (uint32_t local_t) { |
|||
//DPRINTLN(DBG_VERBOSE, F("Main::offsetDayLightSaving"));
|
|||
int m = month (local_t); |
|||
if(m < 3 || m > 10) return 0; // no DSL in Jan, Feb, Nov, Dez
|
|||
if(m > 3 && m < 10) return 1; // DSL in Apr, May, Jun, Jul, Aug, Sep
|
|||
int y = year (local_t); |
|||
int h = hour (local_t); |
|||
int hToday = (h + 24 * day(local_t)); |
|||
if((m == 3 && hToday >= (1 + TIMEZONE + 24 * (31 - (5 * y /4 + 4) % 7))) |
|||
|| (m == 10 && hToday < (1 + TIMEZONE + 24 * (31 - (5 * y /4 + 1) % 7))) ) |
|||
return 1; |
|||
else |
|||
return 0; |
|||
} |
@ -1,183 +0,0 @@ |
|||
//-----------------------------------------------------------------------------
|
|||
// 2022 Ahoy, https://www.mikrocontroller.net/topic/525778
|
|||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
|||
//-----------------------------------------------------------------------------
|
|||
|
|||
#ifndef __MAIN_H__ |
|||
#define __MAIN_H__ |
|||
|
|||
#include "dbg.h" |
|||
#include "Arduino.h" |
|||
|
|||
#include <ESP8266WiFi.h> |
|||
#include <DNSServer.h> |
|||
#include <ESP8266WebServer.h> |
|||
|
|||
// NTP
|
|||
#include <WiFiUdp.h> |
|||
#include <TimeLib.h> |
|||
|
|||
#include "eep.h" |
|||
#include "defines.h" |
|||
#include "crc.h" |
|||
|
|||
|
|||
const byte mDnsPort = 53; |
|||
|
|||
/* NTP TIMESERVER CONFIG */ |
|||
#define NTP_SERVER_NAME "pool.ntp.org" |
|||
#define NTP_LOCAL_PORT 8888 |
|||
#define NTP_PACKET_SIZE 48 |
|||
#define TIMEZONE 1 // Central European time +1
|
|||
|
|||
|
|||
typedef struct { |
|||
char version[12]; |
|||
char deviceName[DEVNAME_LEN]; |
|||
|
|||
// wifi
|
|||
char stationSsid[SSID_LEN]; |
|||
char stationPwd[PWD_LEN]; |
|||
bool apActive; |
|||
|
|||
// nrf24
|
|||
uint16_t sendInterval; |
|||
} config_t; |
|||
|
|||
|
|||
#define SAVE_SSID 0x00000001 |
|||
#define SAVE_PWD 0x00000002 |
|||
#define SAVE_DEVICE_NAME 0x00000004 |
|||
|
|||
#define CHK_MSK(v, m) ((m & v) == m) |
|||
|
|||
class Main { |
|||
public: |
|||
Main(void); |
|||
virtual void setup(uint32_t timeout); |
|||
virtual void loop(); |
|||
void saveValues(uint32_t saveMask); |
|||
|
|||
String getDateTimeStr(time_t t) { |
|||
char str[20] = {0}; |
|||
if(0 == t) |
|||
sprintf(str, "n/a"); |
|||
else |
|||
sprintf(str, "%04d-%02d-%02d %02d:%02d:%02d", year(t), month(t), day(t), hour(t), minute(t), second(t)); |
|||
return String(str); |
|||
} |
|||
|
|||
inline uint32_t getUptime(void) { |
|||
return mUptimeSecs; |
|||
} |
|||
|
|||
inline uint32_t getTimestamp(void) { |
|||
return mTimestamp; |
|||
} |
|||
|
|||
void eraseSettings(bool all = false) { |
|||
//DPRINTLN(DBG_VERBOSE, F("main.h:eraseSettings"));
|
|||
uint8_t buf[64] = {0}; |
|||
uint16_t addr = (all) ? ADDR_START : ADDR_START_SETTINGS; |
|||
uint16_t end; |
|||
do { |
|||
end = addr + 64; |
|||
if(end > (ADDR_SETTINGS_CRC + 2)) |
|||
end = (ADDR_SETTINGS_CRC + 2); |
|||
DPRINTLN(DBG_DEBUG, F("erase: 0x") + String(addr, HEX) + " - 0x" + String(end, HEX)); |
|||
mEep->write(addr, buf, (end-addr)); |
|||
addr = end; |
|||
} while(addr < (ADDR_SETTINGS_CRC + 2)); |
|||
mEep->commit(); |
|||
} |
|||
|
|||
ESP8266WebServer *mWeb; |
|||
config_t config; |
|||
|
|||
|
|||
protected: |
|||
virtual void updateCrc(void); |
|||
|
|||
inline uint16_t buildEEpCrc(uint32_t start, uint32_t length) { |
|||
DPRINTLN(DBG_VERBOSE, F("main.h:buildEEpCrc")); |
|||
uint8_t buf[32]; |
|||
uint16_t crc = 0xffff; |
|||
uint8_t len; |
|||
|
|||
while(length > 0) { |
|||
len = (length < 32) ? length : 32; |
|||
mEep->read(start, buf, len); |
|||
crc = crc16(buf, len, crc); |
|||
start += len; |
|||
length -= len; |
|||
} |
|||
return crc; |
|||
} |
|||
|
|||
bool checkEEpCrc(uint32_t start, uint32_t length, uint32_t crcPos) { |
|||
DPRINTLN(DBG_VERBOSE, F("main.h:checkEEpCrc")); |
|||
DPRINTLN(DBG_DEBUG, F("start: ") + String(start) + F(", length: ") + String(length)); |
|||
uint16_t crcRd, crcCheck; |
|||
crcCheck = buildEEpCrc(start, length); |
|||
mEep->read(crcPos, &crcRd); |
|||
DPRINTLN(DBG_DEBUG, "CRC RD: " + String(crcRd, HEX) + " CRC CALC: " + String(crcCheck, HEX)); |
|||
return (crcCheck == crcRd); |
|||
} |
|||
|
|||
inline bool checkTicker(uint32_t *ticker, uint32_t interval) { |
|||
//DPRINTLN(DBG_VERBOSE, F("c"));
|
|||
uint32_t mil = millis(); |
|||
if(mil >= *ticker) { |
|||
*ticker = mil + interval; |
|||
return true; |
|||
} |
|||
else if(mil < (*ticker - interval)) { |
|||
*ticker = mil + interval; |
|||
return true; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
void stats(void) { |
|||
DPRINTLN(DBG_VERBOSE, F("main.h:stats")); |
|||
uint32_t free; |
|||
uint16_t max; |
|||
uint8_t frag; |
|||
ESP.getHeapStats(&free, &max, &frag); |
|||
DPRINT(DBG_VERBOSE, F("free: ") + String(free)); |
|||
DPRINT(DBG_VERBOSE, F(" - max: ") + String(max) + "%"); |
|||
DPRINTLN(DBG_VERBOSE, F(" - frag: ") + String(frag)); |
|||
} |
|||
|
|||
bool mWifiSettingsValid; |
|||
bool mSettingsValid; |
|||
bool mStActive; |
|||
|
|||
eep *mEep; |
|||
uint32_t mTimestamp; |
|||
uint32_t mLimit; |
|||
uint32_t mNextTryTs; |
|||
uint32_t mApLastTick; |
|||
|
|||
private: |
|||
bool getConfig(void); |
|||
void setupAp(const char *ssid, const char *pwd); |
|||
bool setupStation(uint32_t timeout); |
|||
|
|||
|
|||
time_t getNtpTime(void); |
|||
void sendNTPpacket(IPAddress& address); |
|||
time_t offsetDayLightSaving (uint32_t local_t); |
|||
|
|||
uint32_t mUptimeTicker; |
|||
uint16_t mUptimeInterval; |
|||
uint32_t mUptimeSecs; |
|||
uint8_t mHeapStatCnt; |
|||
|
|||
DNSServer *mDns; |
|||
|
|||
WiFiUDP *mUdp; // for time server
|
|||
}; |
|||
|
|||
#endif /*__MAIN_H__*/ |
@ -0,0 +1,218 @@ |
|||
//-----------------------------------------------------------------------------
|
|||
// 2022 Ahoy, https://www.mikrocontroller.net/topic/525778
|
|||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
|||
//-----------------------------------------------------------------------------
|
|||
|
|||
#ifndef __WEB_H__ |
|||
#define __WEB_H__ |
|||
|
|||
#include "dbg.h" |
|||
#include <ESP8266WebServer.h> |
|||
#include <ESP8266HTTPUpdateServer.h> |
|||
|
|||
#include "app.h" |
|||
|
|||
#include "html/h/index_html.h" |
|||
#include "html/h/style_css.h" |
|||
#include "favicon.h" |
|||
#include "html/h/setup_html.h" |
|||
|
|||
|
|||
class web { |
|||
public: |
|||
web(app *main) { |
|||
mMain = main; |
|||
mWeb = main->mWeb; |
|||
//mWeb = new ESP8266WebServer(80);
|
|||
mUpdater = new ESP8266HTTPUpdateServer(); |
|||
mUpdater->setup(mWeb); |
|||
} |
|||
|
|||
void setup(void) { |
|||
mWeb->on("/", std::bind(&web::showIndex, this)); |
|||
mWeb->on("/style.css", std::bind(&web::showCss, this)); |
|||
mWeb->on("/favicon.ico", std::bind(&web::showFavicon, this)); |
|||
mWeb->onNotFound ( std::bind(&web::showNotFound, this)); |
|||
mWeb->on("/uptime", std::bind(&web::showUptime, this)); |
|||
mWeb->on("/reboot", std::bind(&web::showReboot, this)); |
|||
mWeb->on("/erase", std::bind(&web::showErase, this)); |
|||
mWeb->on("/factory", std::bind(&web::showFactoryRst, this)); |
|||
|
|||
mWeb->on("/setup", std::bind(&web::showSetup, this)); |
|||
mWeb->on("/save", std::bind(&web::showSave, this)); |
|||
} |
|||
|
|||
void showIndex(void) { |
|||
DPRINTLN(DBG_VERBOSE, F("showIndex")); |
|||
String html = FPSTR(index_html); |
|||
html.replace(F("{DEVICE}"), mMain->config.deviceName); |
|||
html.replace(F("{VERSION}"), mMain->config.version); |
|||
html.replace(F("{TS}"), String(mMain->config.sendInterval) + " "); |
|||
html.replace(F("{JS_TS}"), String(mMain->config.sendInterval * 1000)); |
|||
html.replace(F("{BUILD}"), String(AUTO_GIT_HASH)); |
|||
mWeb->send(200, "text/html", html); |
|||
} |
|||
|
|||
void showCss(void) { |
|||
mWeb->send(200, "text/css", FPSTR(style_css)); |
|||
} |
|||
|
|||
void showFavicon(void) { |
|||
static const char favicon_type[] PROGMEM = "image/x-icon"; |
|||
static const char favicon_content[] PROGMEM = FAVICON_PANEL_16; |
|||
mWeb->send_P(200, favicon_type, favicon_content, sizeof(favicon_content)); |
|||
} |
|||
|
|||
void showNotFound(void) { |
|||
DPRINTLN(DBG_VERBOSE, F("showNotFound - ") + mWeb->uri()); |
|||
String msg = F("File Not Found\n\nURI: "); |
|||
msg += mWeb->uri(); |
|||
mWeb->send(404, F("text/plain"), msg); |
|||
} |
|||
|
|||
void showUptime(void) { |
|||
char time[21] = {0}; |
|||
uint32_t uptime = mMain->getUptime(); |
|||
|
|||
uint32_t upTimeSc = uint32_t((uptime) % 60); |
|||
uint32_t upTimeMn = uint32_t((uptime / (60)) % 60); |
|||
uint32_t upTimeHr = uint32_t((uptime / (60 * 60)) % 24); |
|||
uint32_t upTimeDy = uint32_t((uptime / (60 * 60 * 24)) % 365); |
|||
|
|||
snprintf(time, 20, "%d Days, %02d:%02d:%02d;", upTimeDy, upTimeHr, upTimeMn, upTimeSc); |
|||
|
|||
mWeb->send(200, "text/plain", String(time) + mMain->getDateTimeStr(mMain->getTimestamp())); |
|||
} |
|||
|
|||
void showReboot(void) { |
|||
mWeb->send(200, F("text/html"), F("<!doctype html><html><head><title>Rebooting ...</title><meta http-equiv=\"refresh\" content=\"10; URL=/\"></head><body>rebooting ... auto reload after 10s</body></html>")); |
|||
delay(1000); |
|||
ESP.restart(); |
|||
} |
|||
|
|||
void showErase() { |
|||
DPRINTLN(DBG_VERBOSE, F("showErase")); |
|||
mMain->eraseSettings(); |
|||
showReboot(); |
|||
} |
|||
|
|||
void showFactoryRst(void) { |
|||
DPRINTLN(DBG_VERBOSE, F("showFactoryRst")); |
|||
String content = ""; |
|||
int refresh = 3; |
|||
if(mWeb->args() > 0) { |
|||
if(mWeb->arg("reset").toInt() == 1) { |
|||
mMain->eraseSettings(true); |
|||
content = F("factory reset: success\n\nrebooting ... "); |
|||
refresh = 10; |
|||
} |
|||
else { |
|||
content = F("factory reset: aborted"); |
|||
refresh = 3; |
|||
} |
|||
} |
|||
else { |
|||
content = F("<h1>Factory Reset</h1>" |
|||
"<p><a href=\"/factory?reset=1\">RESET</a><br/><br/><a href=\"/factory?reset=0\">CANCEL</a><br/></p>"); |
|||
refresh = 120; |
|||
} |
|||
mWeb->send(200, F("text/html"), F("<!doctype html><html><head><title>Factory Reset</title><meta http-equiv=\"refresh\" content=\"") + String(refresh) + F("; URL=/\"></head><body>") + content + F("</body></html>")); |
|||
if(refresh == 10) { |
|||
delay(1000); |
|||
ESP.restart(); |
|||
} |
|||
} |
|||
|
|||
void showSetup(void) { |
|||
DPRINTLN(DBG_VERBOSE, F("showSetup")); |
|||
String html = FPSTR(setup_html); |
|||
html.replace(F("{SSID}"), mMain->config.stationSsid); |
|||
// PWD will be left at the default value (for protection)
|
|||
// -> the PWD will only be changed if it does not match the default "{PWD}"
|
|||
html.replace(F("{DEVICE}"), String(mMain->config.deviceName)); |
|||
html.replace(F("{VERSION}"), String(mMain->config.version)); |
|||
if(mMain->config.apActive) |
|||
html.replace("{IP}", String(F("http://192.168.1.1"))); |
|||
else |
|||
html.replace("{IP}", (F("http://") + String(WiFi.localIP().toString()))); |
|||
|
|||
mWeb->send(200, F("text/html"), html); |
|||
} |
|||
|
|||
void showSave(void) { |
|||
DPRINTLN(DBG_VERBOSE, F("showSave")); |
|||
|
|||
if(mWeb->args() > 0) { |
|||
uint32_t saveMask = 0; |
|||
char buf[20] = {0}; |
|||
|
|||
// general
|
|||
if(mWeb->arg("ssid") != "") { |
|||
mWeb->arg("ssid").toCharArray(mMain->config.stationSsid, SSID_LEN); |
|||
saveMask |= SAVE_SSID; |
|||
} |
|||
if(mWeb->arg("pwd") != "{PWD}") { |
|||
mWeb->arg("pwd").toCharArray(mMain->config.stationPwd, PWD_LEN); |
|||
saveMask |= SAVE_PWD; |
|||
} |
|||
if(mWeb->arg("device") != "") { |
|||
mWeb->arg("device").toCharArray(mMain->config.deviceName, DEVNAME_LEN); |
|||
saveMask |= SAVE_DEVICE_NAME; |
|||
} |
|||
|
|||
// inverter
|
|||
Inverter<> *iv; |
|||
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) { |
|||
iv = mMain->mSys->getInverterByPos(i, false); |
|||
// address
|
|||
mWeb->arg("inv" + String(i) + "Addr").toCharArray(buf, 20); |
|||
if(strlen(buf) == 0) |
|||
memset(buf, 0, 20); |
|||
else |
|||
saveMask |= SAVE_INVERTERS; |
|||
iv->serial.u64 = mMain->Serial2u64(buf); |
|||
|
|||
// active power limit
|
|||
uint16_t actPwrLimit = mWeb->arg("inv" + String(i) + "ActivePowerLimit").toInt(); |
|||
if (actPwrLimit != 0xffff && actPwrLimit > 0) |
|||
iv->powerLimit[0] = actPwrLimit; |
|||
|
|||
// name
|
|||
mWeb->arg("inv" + String(i) + "Name").toCharArray(iv->name, MAX_NAME_LENGTH); |
|||
|
|||
// max channel power / name
|
|||
for(uint8_t j = 0; j < 4; j++) { |
|||
iv->chMaxPwr[j] = mWeb->arg("inv" + String(i) + "ModPwr" + String(j)).toInt() & 0xffff; |
|||
mWeb->arg("inv" + String(i) + "ModName" + String(j)).toCharArray(iv->chName[j], MAX_NAME_LENGTH); |
|||
} |
|||
} |
|||
if(mWeb->arg("invInterval") != "") { |
|||
mMain->config.sendInterval = mWeb->arg("invInterval").toInt(); |
|||
saveMask |= SAVE_INV_SEND_INTERVAL; |
|||
} |
|||
if(mWeb->arg("invRetry") != "") { |
|||
mMain->config.sendInterval = mWeb->arg("invRetry").toInt(); |
|||
saveMask |= SAVE_INV_RETRY; |
|||
} |
|||
|
|||
mMain->saveValues(saveMask); |
|||
|
|||
if(mWeb->arg("reboot") == "on") |
|||
showReboot(); |
|||
else |
|||
mWeb->send(200, F("text/html"), F("<!doctype html><html><head><title>Setup saved</title><meta http-equiv=\"refresh\" content=\"0; URL=/setup\"></head><body>" |
|||
"<p>saved</p></body></html>")); |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
private: |
|||
ESP8266WebServer *mWeb; |
|||
ESP8266HTTPUpdateServer *mUpdater; |
|||
app *mMain; |
|||
|
|||
}; |
|||
|
|||
#endif /*__WEB_H__*/ |
Loading…
Reference in new issue