mirror of
https://github.com/lumapu/ahoy.git
synced 2025-05-25 14:56:11 +02:00
improved stability
improved wifi initial connection - especially if station wifi is not available #509 removed new operators from web.h (reduce dynamic allocation) improved sun calculation #515, #505 fixed wifi auto reconnect #509 added disable night communication flag to MQTT #505 changed MQTT publish of `available` and `available_text` to sunset #468
This commit is contained in:
parent
5977bbaee6
commit
07bf947ff7
14 changed files with 324 additions and 262 deletions
|
@ -1,5 +1,14 @@
|
|||
# Changelog
|
||||
|
||||
## 0.5.58
|
||||
* improved stability
|
||||
* 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
|
||||
* 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
|
||||
|
@ -8,7 +17,7 @@
|
|||
|
||||
## 0.5.56
|
||||
* factory reset formats entire little fs
|
||||
* renamed sunrise / sunset on indext.html to start / stop communication
|
||||
* renamed sunrise / sunset on index.html to start / stop communication
|
||||
* show system information only if called directly from menu
|
||||
* beautified system.html
|
||||
|
||||
|
|
57
src/app.cpp
57
src/app.cpp
|
@ -45,18 +45,13 @@ void app::setup() {
|
|||
every(std::bind(&app::tickSend, this), mConfig->nrf.sendInterval);
|
||||
#if !defined(AP_ONLY)
|
||||
once(std::bind(&app::tickNtpUpdate, this), 2);
|
||||
if((mConfig->sun.lat) && (mConfig->sun.lon)) {
|
||||
mCalculatedTimezoneOffset = (int8_t)((mConfig->sun.lon >= 0 ? mConfig->sun.lon + 7.5 : mConfig->sun.lon - 7.5) / 15) * 3600;
|
||||
once(std::bind(&app::tickCalcSunrise, this), 5);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(mSys->Radio.isChipConnected()) {
|
||||
mSys->addInverters(&mConfig->inst);
|
||||
mPayload.setup(mSys);
|
||||
mPayload.enableSerialDebug(mConfig->serial.debug);
|
||||
}
|
||||
else
|
||||
mSys->addInverters(&mConfig->inst);
|
||||
mPayload.setup(mSys);
|
||||
mPayload.enableSerialDebug(mConfig->serial.debug);
|
||||
|
||||
if(!mSys->Radio.isChipConnected())
|
||||
DPRINTLN(DBG_WARN, F("WARNING! your NRF24 module can't be reached, check the wiring"));
|
||||
|
||||
// when WiFi is in client mode, then enable mqtt broker
|
||||
|
@ -95,8 +90,6 @@ void app::loop(void) {
|
|||
mWifi.loop();
|
||||
#endif
|
||||
|
||||
mWeb.loop();
|
||||
|
||||
mSys->Radio.loop();
|
||||
|
||||
yield();
|
||||
|
@ -134,26 +127,46 @@ void app::loop(void) {
|
|||
//-----------------------------------------------------------------------------
|
||||
void app::tickNtpUpdate(void) {
|
||||
uint32_t nxtTrig = 5; // default: check again in 5 sec
|
||||
if (mWifi.getNtpTime())
|
||||
if (mWifi.getNtpTime()) {
|
||||
nxtTrig = 43200; // check again in 12 h
|
||||
if((mSunrise == 0) && (mConfig->sun.lat) && (mConfig->sun.lon)) {
|
||||
mCalculatedTimezoneOffset = (int8_t)((mConfig->sun.lon >= 0 ? mConfig->sun.lon + 7.5 : mConfig->sun.lon - 7.5) / 15) * 3600;
|
||||
tickCalcSunrise();
|
||||
}
|
||||
}
|
||||
once(std::bind(&app::tickNtpUpdate, this), nxtTrig);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void app::tickCalcSunrise(void) {
|
||||
if (0 == mTimestamp) {
|
||||
once(std::bind(&app::tickCalcSunrise, this), 5); // check again in 5 secs
|
||||
return;
|
||||
}
|
||||
ah::calculateSunriseSunset(mTimestamp, mCalculatedTimezoneOffset, mConfig->sun.lat, mConfig->sun.lon, &mSunrise, &mSunset);
|
||||
tickIVCommunication();
|
||||
|
||||
uint32_t nxtTrig = mTimestamp - ((mTimestamp - 10) % 86400) + 86400; // next midnight, -10 for safety that it is certain next day
|
||||
uint32_t nxtTrig = mTimestamp - ((mTimestamp - 1) % 86400) + 86400; // next midnight, -10 for safety that it is certain next day
|
||||
onceAt(std::bind(&app::tickCalcSunrise, this), nxtTrig);
|
||||
if (mConfig->mqtt.broker[0] > 0) {
|
||||
mMqtt.tickerSun(mSunrise, mSunset, mConfig->sun.offsetSec);
|
||||
mMqtt.tickerSun(mSunrise, mSunset, mConfig->sun.offsetSec, mConfig->sun.disNightCom);
|
||||
onceAt(std::bind(&PubMqttType::tickSunrise, &mMqtt), (mSunrise - mConfig->sun.offsetSec));
|
||||
onceAt(std::bind(&PubMqttType::tickSunset, &mMqtt), (mSunset + mConfig->sun.offsetSec));
|
||||
onceAt(std::bind(&PubMqttType::tickSunset, &mMqtt), mSunset);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void app::tickIVCommunication(void) {
|
||||
mIVCommunicationOn = !mConfig->sun.disNightCom; // if sun.disNightCom is false, communication is always on
|
||||
if (!mIVCommunicationOn) { // inverter communication only during the day
|
||||
uint32_t nxtTrig;
|
||||
if (mTimestamp < (mSunrise - mConfig->sun.offsetSec)) { // current time is before communication start, set next trigger to communication start
|
||||
nxtTrig = mSunrise - mConfig->sun.offsetSec;
|
||||
} else {
|
||||
if (mTimestamp > (mSunset + mConfig->sun.offsetSec)) { // current time is past communication stop, nothing to do. Next update will be done at midnight by tickCalcSunrise
|
||||
return;
|
||||
} else { // current time lies within communication start/stop time, set next trigger to communication stop
|
||||
mIVCommunicationOn = true;
|
||||
nxtTrig = mSunset + mConfig->sun.offsetSec;
|
||||
}
|
||||
}
|
||||
onceAt(std::bind(&app::tickIVCommunication, this), nxtTrig);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -163,7 +176,7 @@ void app::tickSend(void) {
|
|||
DPRINTLN(DBG_WARN, "NRF24 not connected!");
|
||||
return;
|
||||
}
|
||||
if ((mTimestamp > 0) && (!mConfig->sun.disNightCom || (mTimestamp >= (mSunrise - mConfig->sun.offsetSec) && mTimestamp <= (mSunset + mConfig->sun.offsetSec)))) { // Timestamp is set and (inverter communication only during the day if the option is activated and sunrise/sunset is set)
|
||||
if (mIVCommunicationOn) {
|
||||
if (!mSys->BufCtrl.empty()) {
|
||||
if (mConfig->serial.debug)
|
||||
DPRINTLN(DBG_DEBUG, F("recbuf not empty! #") + String(mSys->BufCtrl.getFill()));
|
||||
|
|
23
src/app.h
23
src/app.h
|
@ -184,31 +184,12 @@ class app : public IApp, public ah::Scheduler {
|
|||
}
|
||||
|
||||
void tickNtpUpdate(void);
|
||||
|
||||
void tickCalcSunrise(void);
|
||||
void tickIVCommunication(void);
|
||||
void tickSend(void);
|
||||
|
||||
void stats(void) {
|
||||
DPRINTLN(DBG_VERBOSE, F("main.h:stats"));
|
||||
#ifdef ESP8266
|
||||
uint32_t free;
|
||||
uint16_t max;
|
||||
uint8_t frag;
|
||||
ESP.getHeapStats(&free, &max, &frag);
|
||||
#elif defined(ESP32)
|
||||
uint32_t free;
|
||||
uint32_t max;
|
||||
uint8_t frag;
|
||||
free = ESP.getFreeHeap();
|
||||
max = ESP.getMaxAllocHeap();
|
||||
frag = 0;
|
||||
#endif
|
||||
DPRINT(DBG_VERBOSE, F("free: ") + String(free));
|
||||
DPRINT(DBG_VERBOSE, F(" - max: ") + String(max) + "%");
|
||||
DPRINTLN(DBG_VERBOSE, F(" - frag: ") + String(frag));
|
||||
}
|
||||
|
||||
bool mShowRebootRequest;
|
||||
bool mIVCommunicationOn;
|
||||
|
||||
ahoywifi mWifi;
|
||||
WebType mWeb;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
//-------------------------------------
|
||||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 5
|
||||
#define VERSION_PATCH 57
|
||||
#define VERSION_PATCH 58
|
||||
|
||||
//-------------------------------------
|
||||
typedef struct {
|
||||
|
|
|
@ -151,8 +151,8 @@ class HmRadio {
|
|||
}
|
||||
|
||||
void loop(void) {
|
||||
DISABLE_IRQ;
|
||||
if(mIrqRcvd) {
|
||||
DISABLE_IRQ;
|
||||
mIrqRcvd = false;
|
||||
bool tx_ok, tx_fail, rx_ready;
|
||||
mNrf24.whatHappened(tx_ok, tx_fail, rx_ready); // resets the IRQ pin to HIGH
|
||||
|
@ -175,9 +175,8 @@ class HmRadio {
|
|||
break;
|
||||
}
|
||||
mNrf24.flush_rx(); // drop the packet
|
||||
}
|
||||
else
|
||||
RESTORE_IRQ;
|
||||
}
|
||||
}
|
||||
|
||||
void enableDebug() {
|
||||
|
@ -185,7 +184,6 @@ class HmRadio {
|
|||
}
|
||||
|
||||
void handleIntr(void) {
|
||||
//DPRINTLN(DBG_VERBOSE, F("hmRadio.h:handleIntr"));
|
||||
mIrqRcvd = true;
|
||||
}
|
||||
|
||||
|
@ -267,7 +265,8 @@ class HmRadio {
|
|||
}
|
||||
|
||||
bool switchRxCh(uint16_t addLoop = 0) {
|
||||
//DPRINTLN(DBG_VERBOSE, F("hmRadio.h:switchRxCh"));
|
||||
if(!mNrf24.isChipConnected())
|
||||
return true;
|
||||
mRxLoopCnt += addLoop;
|
||||
if(mRxLoopCnt != 0) {
|
||||
mRxLoopCnt--;
|
||||
|
|
|
@ -104,14 +104,15 @@ class HmSystem {
|
|||
}
|
||||
|
||||
uint8_t getNumInverters(void) {
|
||||
uint8_t num = 0;
|
||||
/*uint8_t num = 0;
|
||||
INVERTERTYPE *p;
|
||||
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) {
|
||||
p = &mInverter[i];
|
||||
if(p->config->serial.u64 != 0ULL)
|
||||
num++;
|
||||
}
|
||||
return num;
|
||||
return num;*/
|
||||
return MAX_NUM_INVERTERS;
|
||||
}
|
||||
|
||||
void enableDebug() {
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "../utils/dbg.h"
|
||||
#include "../utils/crc.h"
|
||||
#include "../utils/handler.h"
|
||||
#include "../config/config.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -91,11 +91,12 @@ class PubMqtt {
|
|||
tickSunset();
|
||||
}
|
||||
|
||||
void tickerSun(uint32_t sunrise, uint32_t sunset, uint32_t offs) {
|
||||
void tickerSun(uint32_t sunrise, uint32_t sunset, uint32_t offs, bool disNightCom) {
|
||||
publish("sunrise", String(sunrise).c_str(), true);
|
||||
publish("sunset", String(sunset).c_str(), true);
|
||||
publish("comm_start", String(sunrise - offs).c_str(), true);
|
||||
publish("comm_stop", String(sunset + offs).c_str(), true);
|
||||
publish("dis_night_comm", ((disNightCom) ? "true" : "false"), true);
|
||||
}
|
||||
|
||||
void tickSunrise() {
|
||||
|
|
|
@ -353,6 +353,7 @@ class RestApi {
|
|||
obj[F("ts_sunrise")] = mApp->getSunrise();
|
||||
obj[F("ts_sunset")] = mApp->getSunset();
|
||||
obj[F("ts_offset")] = mConfig->sun.offsetSec;
|
||||
obj[F("disNightComm")] = mConfig->sun.disNightCom;
|
||||
|
||||
JsonArray inv = obj.createNestedArray(F("inverter"));
|
||||
Inverter<> *iv;
|
||||
|
|
|
@ -47,10 +47,11 @@
|
|||
<div id="note">
|
||||
<h3>Support this project:</h3>
|
||||
<ul>
|
||||
<li><a href="https://github.com/lumapu/ahoy/blob/main/src/CHANGES.md" target="_blank">Changelog</a></li>
|
||||
<li>Discuss with us on <a href="https://discord.gg/WzhxEY62mB">Discord</a></li>
|
||||
<li>Report <a href="https://github.com/lumapu/ahoy/issues" target="_blank">issues</a></li>
|
||||
<li>Contribute to <a href="https://github.com/lumapu/ahoy/blob/main/User_Manual.md" target="_blank">documentation</a></li>
|
||||
<li>Test <a href="https://github.com/lumapu/ahoy/actions/workflows/compile_development.yml" target="_blank">development firmware</a></li>
|
||||
<li><a href="https://nightly.link/lumapu/ahoy/workflows/compile_development/development03/ahoydtu_dev.zip" target="_blank">Download</a> & Test development firmware, <a href="https://github.com/lumapu/ahoy/blob/development03/src/CHANGES.md" target="_blank">Changelog</a></li>
|
||||
<li>make a <a href="https://paypal.me/lupusch" target="_blank">donation</a></li>
|
||||
</ul>
|
||||
<p class="lic">
|
||||
|
@ -145,7 +146,7 @@
|
|||
&& ((obj["ts_sunset"] + obj["ts_offset"]) > obj["ts_now"])) {
|
||||
commInfo = "Polling inverter(s), will stop at " + (new Date((obj["ts_sunset"] + obj["ts_offset"]) * 1000).toLocaleString('de-DE'));
|
||||
}
|
||||
else {
|
||||
else if(obj["disNightComm"]) {
|
||||
commInfo = "Night time, no Communication to Inverter, ";
|
||||
if(obj["ts_now"] > (obj["ts_sunrise"] - obj["ts_offset"])) {
|
||||
commInfo += "stopped polling at " + (new Date((obj["ts_sunset"] + obj["ts_offset"]) * 1000).toLocaleString('de-DE'));
|
||||
|
@ -176,6 +177,8 @@
|
|||
avail = "available and is ";
|
||||
if(false == i["is_producing"])
|
||||
avail += "not ";
|
||||
else
|
||||
color = "#090";
|
||||
avail += "producing";
|
||||
}
|
||||
|
||||
|
|
|
@ -103,18 +103,21 @@
|
|||
}
|
||||
|
||||
function parseIndex(obj) {
|
||||
var h = div(["head", "p-2"]);
|
||||
var r = div(["row"]);
|
||||
r.appendChild(div(["col", "a-c"], "Sun"));
|
||||
h.appendChild(r);
|
||||
if(obj["ts_sunrise"] > 0) {
|
||||
var h = div(["head", "p-2"]);
|
||||
var r = div(["row"]);
|
||||
r.appendChild(div(["col", "a-c"], "Sun"));
|
||||
h.appendChild(r);
|
||||
|
||||
document.getElementById("sun").append (
|
||||
h,
|
||||
genTabRow("Sunrise", new Date(obj["ts_sunrise"] * 1000).toLocaleString('de-DE')),
|
||||
genTabRow("Sunset", new Date(obj["ts_sunset"] * 1000).toLocaleString('de-DE')),
|
||||
genTabRow("Communication start", new Date((obj["ts_sunrise"] - obj["ts_offset"]) * 1000).toLocaleString('de-DE')),
|
||||
genTabRow("Communication stop", new Date((obj["ts_sunset"] + obj["ts_offset"]) * 1000).toLocaleString('de-DE'))
|
||||
);
|
||||
document.getElementById("sun").append (
|
||||
h,
|
||||
genTabRow("Sunrise", new Date(obj["ts_sunrise"] * 1000).toLocaleString('de-DE')),
|
||||
genTabRow("Sunset", new Date(obj["ts_sunset"] * 1000).toLocaleString('de-DE')),
|
||||
genTabRow("Communication start", new Date((obj["ts_sunrise"] - obj["ts_offset"]) * 1000).toLocaleString('de-DE')),
|
||||
genTabRow("Communication stop", new Date((obj["ts_sunset"] + obj["ts_offset"]) * 1000).toLocaleString('de-DE')),
|
||||
genTabRow("Night Communication", ((obj["disNightComm"]) ? "disabled" : "enabled"))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function parse(obj) {
|
||||
|
|
327
src/web/web.h
327
src/web/web.h
|
@ -39,74 +39,61 @@ const char* const pinArgNames[] = {"pinCs", "pinCe", "pinIrq", "pinLed0", "pinLe
|
|||
template<class HMSYSTEM>
|
||||
class Web {
|
||||
public:
|
||||
Web(void) {
|
||||
Web(void) : mWeb(80), mEvts("/events") {
|
||||
mProtected = true;
|
||||
mLogoutTimeout = 0;
|
||||
|
||||
memset(mSerialBuf, 0, WEB_SERIAL_BUF_SIZE);
|
||||
mSerialBufFill = 0;
|
||||
mWebSerialTicker = 0;
|
||||
mWebSerialInterval = 1000; // [ms]
|
||||
mSerialAddTime = true;
|
||||
mSerialClientConnnected = false;
|
||||
}
|
||||
|
||||
void setup(IApp *app, HMSYSTEM *sys, settings_t *config) {
|
||||
mApp = app;
|
||||
mSys = sys;
|
||||
mConfig = config;
|
||||
mWeb = new AsyncWebServer(80);
|
||||
mEvts = new AsyncEventSource("/events");
|
||||
|
||||
DPRINTLN(DBG_VERBOSE, F("app::setup-begin"));
|
||||
mWeb->begin();
|
||||
DPRINTLN(DBG_VERBOSE, F("app::setup-on"));
|
||||
mWeb->on("/", HTTP_GET, std::bind(&Web::onIndex, this, std::placeholders::_1));
|
||||
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("/style.css", HTTP_GET, std::bind(&Web::onCss, this, std::placeholders::_1));
|
||||
mWeb->on("/api.js", HTTP_GET, std::bind(&Web::onApiJs, this, std::placeholders::_1));
|
||||
mWeb->on("/favicon.ico", HTTP_GET, std::bind(&Web::onFavicon, this, std::placeholders::_1));
|
||||
mWeb->onNotFound ( std::bind(&Web::showNotFound, this, std::placeholders::_1));
|
||||
mWeb->on("/reboot", HTTP_ANY, std::bind(&Web::onReboot, this, std::placeholders::_1));
|
||||
mWeb->on("/system", HTTP_ANY, std::bind(&Web::onSystem, this, std::placeholders::_1));
|
||||
mWeb->on("/erase", HTTP_ANY, std::bind(&Web::showErase, this, std::placeholders::_1));
|
||||
mWeb->on("/factory", HTTP_ANY, std::bind(&Web::showFactoryRst, this, std::placeholders::_1));
|
||||
mWeb.on("/", HTTP_GET, std::bind(&Web::onIndex, this, std::placeholders::_1));
|
||||
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("/style.css", HTTP_GET, std::bind(&Web::onCss, this, std::placeholders::_1));
|
||||
mWeb.on("/api.js", HTTP_GET, std::bind(&Web::onApiJs, this, std::placeholders::_1));
|
||||
mWeb.on("/favicon.ico", HTTP_GET, std::bind(&Web::onFavicon, this, std::placeholders::_1));
|
||||
mWeb.onNotFound ( std::bind(&Web::showNotFound, this, std::placeholders::_1));
|
||||
mWeb.on("/reboot", HTTP_ANY, std::bind(&Web::onReboot, this, std::placeholders::_1));
|
||||
mWeb.on("/system", HTTP_ANY, std::bind(&Web::onSystem, this, std::placeholders::_1));
|
||||
mWeb.on("/erase", HTTP_ANY, std::bind(&Web::showErase, this, std::placeholders::_1));
|
||||
mWeb.on("/factory", HTTP_ANY, std::bind(&Web::showFactoryRst, this, std::placeholders::_1));
|
||||
|
||||
mWeb->on("/setup", HTTP_GET, std::bind(&Web::onSetup, this, std::placeholders::_1));
|
||||
mWeb->on("/save", HTTP_ANY, std::bind(&Web::showSave, this, std::placeholders::_1));
|
||||
mWeb.on("/setup", HTTP_GET, std::bind(&Web::onSetup, this, std::placeholders::_1));
|
||||
mWeb.on("/save", HTTP_ANY, std::bind(&Web::showSave, this, std::placeholders::_1));
|
||||
|
||||
mWeb->on("/live", HTTP_ANY, std::bind(&Web::onLive, this, std::placeholders::_1));
|
||||
mWeb->on("/api1", HTTP_POST, std::bind(&Web::showWebApi, this, std::placeholders::_1));
|
||||
mWeb.on("/live", HTTP_ANY, std::bind(&Web::onLive, this, std::placeholders::_1));
|
||||
mWeb.on("/api1", HTTP_POST, std::bind(&Web::showWebApi, this, std::placeholders::_1));
|
||||
|
||||
#ifdef ENABLE_JSON_EP
|
||||
mWeb->on("/json", HTTP_ANY, std::bind(&Web::showJson, this, std::placeholders::_1));
|
||||
mWeb.on("/json", HTTP_ANY, std::bind(&Web::showJson, this, std::placeholders::_1));
|
||||
#endif
|
||||
#ifdef ENABLE_PROMETHEUS_EP
|
||||
mWeb->on("/metrics", HTTP_ANY, std::bind(&Web::showMetrics, this, std::placeholders::_1));
|
||||
mWeb.on("/metrics", HTTP_ANY, std::bind(&Web::showMetrics, this, std::placeholders::_1));
|
||||
#endif
|
||||
|
||||
mWeb->on("/update", HTTP_GET, std::bind(&Web::onUpdate, this, std::placeholders::_1));
|
||||
mWeb->on("/update", HTTP_POST, std::bind(&Web::showUpdate, this, std::placeholders::_1),
|
||||
mWeb.on("/update", HTTP_GET, std::bind(&Web::onUpdate, this, std::placeholders::_1));
|
||||
mWeb.on("/update", HTTP_POST, std::bind(&Web::showUpdate, this, std::placeholders::_1),
|
||||
std::bind(&Web::showUpdate2, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6));
|
||||
mWeb->on("/serial", HTTP_GET, std::bind(&Web::onSerial, this, std::placeholders::_1));
|
||||
mWeb.on("/serial", HTTP_GET, std::bind(&Web::onSerial, this, std::placeholders::_1));
|
||||
|
||||
|
||||
mEvts->onConnect(std::bind(&Web::onConnect, this, std::placeholders::_1));
|
||||
mWeb->addHandler(mEvts);
|
||||
mEvts.onConnect(std::bind(&Web::onConnect, this, std::placeholders::_1));
|
||||
mWeb.addHandler(&mEvts);
|
||||
|
||||
mWeb.begin();
|
||||
|
||||
registerDebugCb(std::bind(&Web::serialCb, this, std::placeholders::_1)); // dbg.h
|
||||
}
|
||||
|
||||
void loop(void) {
|
||||
if(ah::checkTicker(&mWebSerialTicker, mWebSerialInterval)) {
|
||||
if(mSerialBufFill > 0) {
|
||||
mEvts->send(mSerialBuf, "serial", millis());
|
||||
memset(mSerialBuf, 0, WEB_SERIAL_BUF_SIZE);
|
||||
mSerialBufFill = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tickSecond() {
|
||||
if(0 != mLogoutTimeout) {
|
||||
mLogoutTimeout -= 1;
|
||||
|
@ -117,10 +104,18 @@ class Web {
|
|||
|
||||
DPRINTLN(DBG_DEBUG, "auto logout in " + String(mLogoutTimeout));
|
||||
}
|
||||
|
||||
if(mSerialClientConnnected) {
|
||||
if(mSerialBufFill > 0) {
|
||||
mEvts.send(mSerialBuf, "serial", millis());
|
||||
memset(mSerialBuf, 0, WEB_SERIAL_BUF_SIZE);
|
||||
mSerialBufFill = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AsyncWebServer *getWebSrvPtr(void) {
|
||||
return mWeb;
|
||||
return &mWeb;
|
||||
}
|
||||
|
||||
void setProtection(bool protect) {
|
||||
|
@ -151,6 +146,9 @@ class Web {
|
|||
}
|
||||
|
||||
void serialCb(String msg) {
|
||||
if(!mSerialClientConnnected)
|
||||
return;
|
||||
|
||||
msg.replace("\r\n", "<rn>");
|
||||
if(mSerialAddTime) {
|
||||
if((9 + mSerialBufFill) <= WEB_SERIAL_BUF_SIZE) {
|
||||
|
@ -159,7 +157,7 @@ class Web {
|
|||
}
|
||||
else {
|
||||
mSerialBufFill = 0;
|
||||
mEvts->send("webSerial, buffer overflow!", "serial", millis());
|
||||
mEvts.send("webSerial, buffer overflow!", "serial", millis());
|
||||
}
|
||||
mSerialAddTime = false;
|
||||
}
|
||||
|
@ -174,7 +172,7 @@ class Web {
|
|||
}
|
||||
else {
|
||||
mSerialBufFill = 0;
|
||||
mEvts->send("webSerial, buffer overflow!", "serial", millis());
|
||||
mEvts.send("webSerial, buffer overflow!", "serial", millis());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -212,6 +210,8 @@ class Web {
|
|||
void onConnect(AsyncEventSourceClient *client) {
|
||||
DPRINTLN(DBG_VERBOSE, "onConnect");
|
||||
|
||||
mSerialClientConnnected = true;
|
||||
|
||||
if(client->lastId())
|
||||
DPRINTLN(DBG_VERBOSE, "Client reconnected! Last message ID that it got is: " + String(client->lastId()));
|
||||
|
||||
|
@ -262,6 +262,7 @@ class Web {
|
|||
}
|
||||
|
||||
void onCss(AsyncWebServerRequest *request) {
|
||||
DPRINTLN(DBG_VERBOSE, F("onCss"));
|
||||
mLogoutTimeout = LOGOUT_TIMEOUT;
|
||||
AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/css"), style_css, style_css_len);
|
||||
response->addHeader(F("Content-Encoding"), "gzip");
|
||||
|
@ -373,136 +374,137 @@ class Web {
|
|||
return;
|
||||
}
|
||||
|
||||
if(request->args() > 0) {
|
||||
char buf[20] = {0};
|
||||
if(request->args() == 0)
|
||||
return;
|
||||
|
||||
// general
|
||||
if(request->arg("ssid") != "")
|
||||
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("device") != "")
|
||||
request->arg("device").toCharArray(mConfig->sys.deviceName, DEVNAME_LEN);
|
||||
if(request->arg("adminpwd") != "{PWD}") {
|
||||
request->arg("adminpwd").toCharArray(mConfig->sys.adminPwd, PWD_LEN);
|
||||
mProtected = (strlen(mConfig->sys.adminPwd) > 0);
|
||||
char buf[20] = {0};
|
||||
|
||||
// general
|
||||
if(request->arg("ssid") != "")
|
||||
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("device") != "")
|
||||
request->arg("device").toCharArray(mConfig->sys.deviceName, DEVNAME_LEN);
|
||||
if(request->arg("adminpwd") != "{PWD}") {
|
||||
request->arg("adminpwd").toCharArray(mConfig->sys.adminPwd, PWD_LEN);
|
||||
mProtected = (strlen(mConfig->sys.adminPwd) > 0);
|
||||
}
|
||||
|
||||
|
||||
// static ip
|
||||
request->arg("ipAddr").toCharArray(buf, 20);
|
||||
ah::ip2Arr(mConfig->sys.ip.ip, buf);
|
||||
request->arg("ipMask").toCharArray(buf, 20);
|
||||
ah::ip2Arr(mConfig->sys.ip.mask, buf);
|
||||
request->arg("ipDns1").toCharArray(buf, 20);
|
||||
ah::ip2Arr(mConfig->sys.ip.dns1, buf);
|
||||
request->arg("ipDns2").toCharArray(buf, 20);
|
||||
ah::ip2Arr(mConfig->sys.ip.dns2, buf);
|
||||
request->arg("ipGateway").toCharArray(buf, 20);
|
||||
ah::ip2Arr(mConfig->sys.ip.gateway, buf);
|
||||
|
||||
|
||||
// inverter
|
||||
Inverter<> *iv;
|
||||
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) {
|
||||
iv = mSys->getInverterByPos(i, false);
|
||||
// enable communication
|
||||
iv->config->enabled = (request->arg("inv" + String(i) + "Enable") == "on");
|
||||
// address
|
||||
request->arg("inv" + String(i) + "Addr").toCharArray(buf, 20);
|
||||
if(strlen(buf) == 0)
|
||||
memset(buf, 0, 20);
|
||||
iv->config->serial.u64 = ah::Serial2u64(buf);
|
||||
switch(iv->config->serial.b[4]) {
|
||||
case 0x21: iv->type = INV_TYPE_1CH; iv->channels = 1; break;
|
||||
case 0x41: iv->type = INV_TYPE_2CH; iv->channels = 2; break;
|
||||
case 0x61: iv->type = INV_TYPE_4CH; iv->channels = 4; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
// name
|
||||
request->arg("inv" + String(i) + "Name").toCharArray(iv->config->name, MAX_NAME_LENGTH);
|
||||
|
||||
// static ip
|
||||
request->arg("ipAddr").toCharArray(buf, 20);
|
||||
ah::ip2Arr(mConfig->sys.ip.ip, buf);
|
||||
request->arg("ipMask").toCharArray(buf, 20);
|
||||
ah::ip2Arr(mConfig->sys.ip.mask, buf);
|
||||
request->arg("ipDns1").toCharArray(buf, 20);
|
||||
ah::ip2Arr(mConfig->sys.ip.dns1, buf);
|
||||
request->arg("ipDns2").toCharArray(buf, 20);
|
||||
ah::ip2Arr(mConfig->sys.ip.dns2, buf);
|
||||
request->arg("ipGateway").toCharArray(buf, 20);
|
||||
ah::ip2Arr(mConfig->sys.ip.gateway, buf);
|
||||
|
||||
|
||||
// inverter
|
||||
Inverter<> *iv;
|
||||
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) {
|
||||
iv = mSys->getInverterByPos(i, false);
|
||||
// enable communication
|
||||
iv->config->enabled = (request->arg("inv" + String(i) + "Enable") == "on");
|
||||
// address
|
||||
request->arg("inv" + String(i) + "Addr").toCharArray(buf, 20);
|
||||
if(strlen(buf) == 0)
|
||||
memset(buf, 0, 20);
|
||||
iv->config->serial.u64 = ah::Serial2u64(buf);
|
||||
switch(iv->config->serial.b[4]) {
|
||||
case 0x21: iv->type = INV_TYPE_1CH; iv->channels = 1; break;
|
||||
case 0x41: iv->type = INV_TYPE_2CH; iv->channels = 2; break;
|
||||
case 0x61: iv->type = INV_TYPE_4CH; iv->channels = 4; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
// name
|
||||
request->arg("inv" + String(i) + "Name").toCharArray(iv->config->name, MAX_NAME_LENGTH);
|
||||
|
||||
// max channel power / name
|
||||
for(uint8_t j = 0; j < 4; j++) {
|
||||
iv->config->chMaxPwr[j] = request->arg("inv" + String(i) + "ModPwr" + String(j)).toInt() & 0xffff;
|
||||
request->arg("inv" + String(i) + "ModName" + String(j)).toCharArray(iv->config->chName[j], MAX_NAME_LENGTH);
|
||||
}
|
||||
iv->initialized = true;
|
||||
// max channel power / name
|
||||
for(uint8_t j = 0; j < 4; j++) {
|
||||
iv->config->chMaxPwr[j] = request->arg("inv" + String(i) + "ModPwr" + String(j)).toInt() & 0xffff;
|
||||
request->arg("inv" + String(i) + "ModName" + String(j)).toCharArray(iv->config->chName[j], MAX_NAME_LENGTH);
|
||||
}
|
||||
iv->initialized = true;
|
||||
}
|
||||
|
||||
if(request->arg("invInterval") != "")
|
||||
mConfig->nrf.sendInterval = request->arg("invInterval").toInt();
|
||||
if(request->arg("invRetry") != "")
|
||||
mConfig->nrf.maxRetransPerPyld = request->arg("invRetry").toInt();
|
||||
if(request->arg("invInterval") != "")
|
||||
mConfig->nrf.sendInterval = request->arg("invInterval").toInt();
|
||||
if(request->arg("invRetry") != "")
|
||||
mConfig->nrf.maxRetransPerPyld = request->arg("invRetry").toInt();
|
||||
|
||||
// pinout
|
||||
uint8_t pin;
|
||||
for(uint8_t i = 0; i < 5; i ++) {
|
||||
pin = request->arg(String(pinArgNames[i])).toInt();
|
||||
switch(i) {
|
||||
default: mConfig->nrf.pinCs = ((pin != 0xff) ? pin : DEF_CS_PIN); break;
|
||||
case 1: mConfig->nrf.pinCe = ((pin != 0xff) ? pin : DEF_CE_PIN); break;
|
||||
case 2: mConfig->nrf.pinIrq = ((pin != 0xff) ? pin : DEF_IRQ_PIN); break;
|
||||
case 3: mConfig->led.led0 = pin; break;
|
||||
case 4: mConfig->led.led1 = pin; break;
|
||||
}
|
||||
// pinout
|
||||
uint8_t pin;
|
||||
for(uint8_t i = 0; i < 5; i ++) {
|
||||
pin = request->arg(String(pinArgNames[i])).toInt();
|
||||
switch(i) {
|
||||
default: mConfig->nrf.pinCs = ((pin != 0xff) ? pin : DEF_CS_PIN); break;
|
||||
case 1: mConfig->nrf.pinCe = ((pin != 0xff) ? pin : DEF_CE_PIN); break;
|
||||
case 2: mConfig->nrf.pinIrq = ((pin != 0xff) ? pin : DEF_IRQ_PIN); break;
|
||||
case 3: mConfig->led.led0 = pin; break;
|
||||
case 4: mConfig->led.led1 = pin; break;
|
||||
}
|
||||
}
|
||||
|
||||
// nrf24 amplifier power
|
||||
mConfig->nrf.amplifierPower = request->arg("rf24Power").toInt() & 0x03;
|
||||
// nrf24 amplifier power
|
||||
mConfig->nrf.amplifierPower = request->arg("rf24Power").toInt() & 0x03;
|
||||
|
||||
// ntp
|
||||
if(request->arg("ntpAddr") != "") {
|
||||
request->arg("ntpAddr").toCharArray(mConfig->ntp.addr, NTP_ADDR_LEN);
|
||||
mConfig->ntp.port = request->arg("ntpPort").toInt() & 0xffff;
|
||||
}
|
||||
// ntp
|
||||
if(request->arg("ntpAddr") != "") {
|
||||
request->arg("ntpAddr").toCharArray(mConfig->ntp.addr, NTP_ADDR_LEN);
|
||||
mConfig->ntp.port = request->arg("ntpPort").toInt() & 0xffff;
|
||||
}
|
||||
|
||||
// sun
|
||||
if(request->arg("sunLat") == "" || (request->arg("sunLon") == "")) {
|
||||
mConfig->sun.lat = 0.0;
|
||||
mConfig->sun.lon = 0.0;
|
||||
mConfig->sun.disNightCom = false;
|
||||
mConfig->sun.offsetSec = 0;
|
||||
} else {
|
||||
mConfig->sun.lat = request->arg("sunLat").toFloat();
|
||||
mConfig->sun.lon = request->arg("sunLon").toFloat();
|
||||
mConfig->sun.disNightCom = (request->arg("sunDisNightCom") == "on");
|
||||
mConfig->sun.offsetSec = request->arg("sunOffs").toInt() * 60;
|
||||
}
|
||||
// sun
|
||||
if(request->arg("sunLat") == "" || (request->arg("sunLon") == "")) {
|
||||
mConfig->sun.lat = 0.0;
|
||||
mConfig->sun.lon = 0.0;
|
||||
mConfig->sun.disNightCom = false;
|
||||
mConfig->sun.offsetSec = 0;
|
||||
} else {
|
||||
mConfig->sun.lat = request->arg("sunLat").toFloat();
|
||||
mConfig->sun.lon = request->arg("sunLon").toFloat();
|
||||
mConfig->sun.disNightCom = (request->arg("sunDisNightCom") == "on");
|
||||
mConfig->sun.offsetSec = request->arg("sunOffs").toInt() * 60;
|
||||
}
|
||||
|
||||
// mqtt
|
||||
if(request->arg("mqttAddr") != "") {
|
||||
String addr = request->arg("mqttAddr");
|
||||
addr.trim();
|
||||
addr.toCharArray(mConfig->mqtt.broker, MQTT_ADDR_LEN);
|
||||
}
|
||||
else
|
||||
mConfig->mqtt.broker[0] = '\0';
|
||||
request->arg("mqttUser").toCharArray(mConfig->mqtt.user, MQTT_USER_LEN);
|
||||
if(request->arg("mqttPwd") != "{PWD}")
|
||||
request->arg("mqttPwd").toCharArray(mConfig->mqtt.pwd, MQTT_PWD_LEN);
|
||||
request->arg("mqttTopic").toCharArray(mConfig->mqtt.topic, MQTT_TOPIC_LEN);
|
||||
mConfig->mqtt.port = request->arg("mqttPort").toInt();
|
||||
// mqtt
|
||||
if(request->arg("mqttAddr") != "") {
|
||||
String addr = request->arg("mqttAddr");
|
||||
addr.trim();
|
||||
addr.toCharArray(mConfig->mqtt.broker, MQTT_ADDR_LEN);
|
||||
}
|
||||
else
|
||||
mConfig->mqtt.broker[0] = '\0';
|
||||
request->arg("mqttUser").toCharArray(mConfig->mqtt.user, MQTT_USER_LEN);
|
||||
if(request->arg("mqttPwd") != "{PWD}")
|
||||
request->arg("mqttPwd").toCharArray(mConfig->mqtt.pwd, MQTT_PWD_LEN);
|
||||
request->arg("mqttTopic").toCharArray(mConfig->mqtt.topic, MQTT_TOPIC_LEN);
|
||||
mConfig->mqtt.port = request->arg("mqttPort").toInt();
|
||||
|
||||
// serial console
|
||||
if(request->arg("serIntvl") != "") {
|
||||
mConfig->serial.interval = request->arg("serIntvl").toInt() & 0xffff;
|
||||
// serial console
|
||||
if(request->arg("serIntvl") != "") {
|
||||
mConfig->serial.interval = request->arg("serIntvl").toInt() & 0xffff;
|
||||
|
||||
mConfig->serial.debug = (request->arg("serDbg") == "on");
|
||||
mConfig->serial.showIv = (request->arg("serEn") == "on");
|
||||
// Needed to log TX buffers to serial console
|
||||
mSys->Radio.mSerialDebug = mConfig->serial.debug;
|
||||
}
|
||||
mApp->saveSettings();
|
||||
mConfig->serial.debug = (request->arg("serDbg") == "on");
|
||||
mConfig->serial.showIv = (request->arg("serEn") == "on");
|
||||
// Needed to log TX buffers to serial console
|
||||
mSys->Radio.mSerialDebug = mConfig->serial.debug;
|
||||
}
|
||||
mApp->saveSettings();
|
||||
|
||||
if(request->arg("reboot") == "on")
|
||||
onReboot(request);
|
||||
else {
|
||||
AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/html"), system_html, system_html_len);
|
||||
response->addHeader(F("Content-Encoding"), "gzip");
|
||||
request->send(response);
|
||||
}
|
||||
if(request->arg("reboot") == "on")
|
||||
onReboot(request);
|
||||
else {
|
||||
AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/html"), system_html, system_html_len);
|
||||
response->addHeader(F("Content-Encoding"), "gzip");
|
||||
request->send(response);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -632,7 +634,7 @@ class Web {
|
|||
}
|
||||
modJson += F("\"json_ts\": \"") + String(ah::getDateTimeStr(mMain->mTimestamp)) + F("\"\n}\n");
|
||||
|
||||
mWeb->send(200, F("application/json"), modJson);
|
||||
mWeb.send(200, F("application/json"), modJson);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -663,7 +665,7 @@ class Web {
|
|||
}
|
||||
}
|
||||
|
||||
mWeb->send(200, F("text/plain"), metrics);
|
||||
mWeb.send(200, F("text/plain"), metrics);
|
||||
}
|
||||
|
||||
std::pair<String, String> convertToPromUnits(String shortUnit) {
|
||||
|
@ -679,8 +681,8 @@ class Web {
|
|||
}
|
||||
#endif
|
||||
|
||||
AsyncWebServer *mWeb;
|
||||
AsyncEventSource *mEvts;
|
||||
AsyncWebServer mWeb;
|
||||
AsyncEventSource mEvts;
|
||||
bool mProtected;
|
||||
uint32_t mLogoutTimeout;
|
||||
IApp *mApp;
|
||||
|
@ -691,8 +693,7 @@ class Web {
|
|||
bool mSerialAddTime;
|
||||
char mSerialBuf[WEB_SERIAL_BUF_SIZE];
|
||||
uint16_t mSerialBufFill;
|
||||
uint32_t mWebSerialTicker;
|
||||
uint32_t mWebSerialInterval;
|
||||
bool mSerialClientConnnected;
|
||||
};
|
||||
|
||||
#endif /*__WEB_H__*/
|
||||
|
|
|
@ -12,33 +12,31 @@
|
|||
// NTP CONFIG
|
||||
#define NTP_PACKET_SIZE 48
|
||||
|
||||
enum {WIFI_NOT_FOUND = 0, WIFI_FOUND, WIFI_NOT_COMPLETE};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
ahoywifi::ahoywifi() {
|
||||
mCnt = 0;
|
||||
mConnected = false;
|
||||
mReconnect = false;
|
||||
ahoywifi::ahoywifi() : mApIp(192, 168, 4, 1), mApMask(255, 255, 255, 0) {
|
||||
mDnsActive = false;
|
||||
mClientCnt = 0;
|
||||
mLoopCnt = 250;
|
||||
mExtScan = false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
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)
|
||||
if(strncmp(mConfig->sys.stationSsid, FB_WIFI_SSID, 14) == 0)
|
||||
setupAp();
|
||||
#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
|
||||
}
|
||||
setupAp();
|
||||
#endif
|
||||
|
||||
#if defined(ESP8266)
|
||||
|
@ -59,19 +57,43 @@ void ahoywifi::loop() {
|
|||
if((mCnt % 50) == 0)
|
||||
WiFi.disconnect();
|
||||
else if((mCnt % 60) == 0) {
|
||||
WiFi.reconnect();
|
||||
DPRINTLN(DBG_INFO, F("[WiFi] reconnect"));
|
||||
WiFi.begin(mConfig->sys.stationSsid, mConfig->sys.stationPwd);
|
||||
mCnt = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
yield();
|
||||
if(mDnsActive) {
|
||||
mDns.processNextRequest();
|
||||
uint8_t cnt = WiFi.softAPgetStationNum();
|
||||
if(cnt != mClientCnt) {
|
||||
mClientCnt = cnt;
|
||||
DPRINTLN(DBG_INFO, String(cnt) + F(" client(s) connected"));
|
||||
}
|
||||
|
||||
if(!mExtScan && (mLoopCnt == 240)) {
|
||||
if(scanStationNetwork()) {
|
||||
setupStation();
|
||||
mLoopCnt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(0 != mLoopCnt) {
|
||||
if(++mLoopCnt > 250) {
|
||||
mLoopCnt = 1;
|
||||
if(!mExtScan)
|
||||
scanAvailNetworks(false);
|
||||
}
|
||||
delay(25);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ahoywifi::setupAp(void) {
|
||||
DPRINTLN(DBG_VERBOSE, F("wifi::setupAp"));
|
||||
IPAddress apIp(192, 168, 4, 1);
|
||||
DPRINTLN(DBG_INFO, F("wifi::setupAp"));
|
||||
|
||||
DBGPRINTLN(F("\n---------\nAhoyDTU Info:"));
|
||||
DBGPRINT(F("Version: "));
|
||||
|
@ -83,20 +105,22 @@ void ahoywifi::setupAp(void) {
|
|||
DBGPRINTLN(WIFI_AP_SSID);
|
||||
DBGPRINT(F("PWD: "));
|
||||
DBGPRINTLN(WIFI_AP_PWD);
|
||||
DBGPRINTLN("IP Address: http://" + apIp.toString());
|
||||
DBGPRINTLN("IP Address: http://" + mApIp.toString());
|
||||
DBGPRINTLN(F("---------\n"));
|
||||
|
||||
WiFi.mode(WIFI_AP_STA);
|
||||
WiFi.softAPConfig(apIp, apIp, IPAddress(255, 255, 255, 0));
|
||||
WiFi.softAPConfig(mApIp, mApIp, mApMask);
|
||||
WiFi.softAP(WIFI_AP_SSID, WIFI_AP_PWD);
|
||||
|
||||
mDns.start(53, "*", apIp);
|
||||
mDns.setErrorReplyCode(DNSReplyCode::NoError);
|
||||
mDns.start(53, "*", WiFi.softAPIP());
|
||||
mDnsActive = true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ahoywifi::setupStation(void) {
|
||||
DPRINTLN(DBG_VERBOSE, F("wifi::setupStation"));
|
||||
DPRINTLN(DBG_INFO, F("wifi::setupStation"));
|
||||
if(mConfig->sys.ip.ip[0] != 0) {
|
||||
IPAddress ip(mConfig->sys.ip.ip);
|
||||
IPAddress mask(mConfig->sys.ip.mask);
|
||||
|
@ -107,12 +131,27 @@ void ahoywifi::setupStation(void) {
|
|||
DPRINTLN(DBG_ERROR, F("failed to set static IP!"));
|
||||
}
|
||||
WiFi.begin(mConfig->sys.stationSsid, mConfig->sys.stationPwd);
|
||||
if(String(mConfig->sys.deviceName) != "")
|
||||
WiFi.hostname(mConfig->sys.deviceName);
|
||||
|
||||
DBGPRINT(F("connect to network '"));
|
||||
DBGPRINT(mConfig->sys.stationSsid);
|
||||
DBGPRINTLN(F("' ..."));
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -156,9 +195,10 @@ bool ahoywifi::getNtpTime(void) {
|
|||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ahoywifi::scanAvailNetworks(void) {
|
||||
int n = WiFi.scanComplete();
|
||||
if(n == -2)
|
||||
void ahoywifi::scanAvailNetworks(bool externalCall) {
|
||||
if(externalCall)
|
||||
mExtScan = true;
|
||||
if(-2 == WiFi.scanComplete())
|
||||
WiFi.scanNetworks(true);
|
||||
}
|
||||
|
||||
|
@ -182,6 +222,7 @@ void ahoywifi::getAvailNetworks(JsonObject obj) {
|
|||
}
|
||||
WiFi.scanDelete();
|
||||
}
|
||||
mExtScan = false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -215,6 +256,7 @@ void ahoywifi::sendNTPpacket(IPAddress& address) {
|
|||
DBGPRINTLN(F("\n[WiFi] Connected"));
|
||||
WiFi.mode(WIFI_STA);
|
||||
DBGPRINTLN(F("[WiFi] AP disabled"));
|
||||
mDnsActive = false;
|
||||
mDns.stop();
|
||||
|
||||
welcome(WiFi.localIP().toString() + F(" (Station)"));
|
||||
|
@ -245,6 +287,7 @@ void ahoywifi::sendNTPpacket(IPAddress& address) {
|
|||
WiFi.mode(WIFI_STA);
|
||||
WiFi.begin();
|
||||
DBGPRINTLN(F("[WiFi] AP disabled"));
|
||||
mDnsActive = false;
|
||||
mDns.stop();
|
||||
mReconnect = false;
|
||||
}
|
||||
|
|
|
@ -23,12 +23,13 @@ class ahoywifi {
|
|||
void setup(settings_t *config, uint32_t *utcTimestamp);
|
||||
void loop(void);
|
||||
bool getNtpTime(void);
|
||||
void scanAvailNetworks(void);
|
||||
void scanAvailNetworks(bool externalCall = true);
|
||||
void getAvailNetworks(JsonObject obj);
|
||||
|
||||
private:
|
||||
void setupAp(void);
|
||||
void setupStation(void);
|
||||
bool scanStationNetwork(void);
|
||||
void sendNTPpacket(IPAddress& address);
|
||||
#if defined(ESP8266)
|
||||
void onConnect(const WiFiEventStationModeGotIP& event);
|
||||
|
@ -38,18 +39,23 @@ class ahoywifi {
|
|||
#endif
|
||||
void welcome(String msg);
|
||||
|
||||
|
||||
settings_t *mConfig;
|
||||
|
||||
DNSServer mDns;
|
||||
IPAddress mApIp, mApMask;
|
||||
WiFiUDP mUdp; // for time server
|
||||
#if defined(ESP8266)
|
||||
WiFiEventHandler wifiConnectHandler;
|
||||
WiFiEventHandler wifiDisconnectHandler;
|
||||
#endif
|
||||
|
||||
bool mConnected, mReconnect;
|
||||
uint8_t mCnt;
|
||||
bool mConnected, mReconnect, mDnsActive;
|
||||
uint8_t mCnt, mClientCnt;
|
||||
uint32_t *mUtcTimestamp;
|
||||
|
||||
uint8_t mLoopCnt;
|
||||
bool mExtScan;
|
||||
};
|
||||
|
||||
#endif /*__AHOYWIFI_H__*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue