mirror of
https://github.com/lumapu/ahoy.git
synced 2025-04-29 02:06:21 +02:00
parent
e039820dba
commit
77b1f96c03
21 changed files with 290 additions and 273 deletions
4
src/.vscode/settings.json
vendored
4
src/.vscode/settings.json
vendored
|
@ -84,5 +84,5 @@
|
|||
},
|
||||
"cmake.configureOnOpen": false,
|
||||
"editor.formatOnSave": false,
|
||||
"cmake.sourceDirectory": "C:/lpusch/github/ahoy/src/.pio/libdeps/esp32-wroom32-release-prometheus/Adafruit BusIO",
|
||||
}
|
||||
"cmake.sourceDirectory": "C:/lpusch/github/ahoy/src/.pio/libdeps/esp32-wroom32-release-prometheus/Adafruit BusIO"
|
||||
}
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
# Development Changes
|
||||
|
||||
## 0.8.63 - 2024-01-22
|
||||
* made code review
|
||||
* fixed endless loop #1387
|
||||
|
||||
## 0.8.62 - 2024-01-21
|
||||
* updated version in footer #1381
|
||||
* repaired radio statistics #1382
|
||||
|
|
24
src/app.cpp
24
src/app.cpp
|
@ -143,22 +143,20 @@ void app::loop(void) {
|
|||
esp_task_wdt_reset();
|
||||
|
||||
if(mConfig->nrf.enabled)
|
||||
mNrfActive = mNrfRadio.loop();
|
||||
mNrfRadio.loop();
|
||||
|
||||
if(!mNrfActive) {
|
||||
#if defined(ESP32)
|
||||
if(mConfig->cmt.enabled)
|
||||
mNrfActive = mCmtRadio.loop();
|
||||
#endif
|
||||
#if defined(ESP32)
|
||||
if(mConfig->cmt.enabled)
|
||||
mCmtRadio.loop();
|
||||
#endif
|
||||
|
||||
ah::Scheduler::loop();
|
||||
mCommunication.loop();
|
||||
ah::Scheduler::loop();
|
||||
mCommunication.loop();
|
||||
|
||||
#if defined(ENABLE_MQTT)
|
||||
if (mMqttEnabled && mNetworkConnected)
|
||||
mMqtt.loop();
|
||||
#endif
|
||||
}
|
||||
#if defined(ENABLE_MQTT)
|
||||
if (mMqttEnabled && mNetworkConnected)
|
||||
mMqtt.loop();
|
||||
#endif
|
||||
yield();
|
||||
}
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ class app : public IApp, public ah::Scheduler {
|
|||
~app() {}
|
||||
|
||||
void setup(void);
|
||||
void loop(void);
|
||||
void loop(void) override;
|
||||
void onNetwork(bool gotIp);
|
||||
void regularTickers(void);
|
||||
|
||||
|
@ -405,7 +405,6 @@ class app : public IApp, public ah::Scheduler {
|
|||
uint8_t mSendLastIvId;
|
||||
bool mSendFirst;
|
||||
bool mAllIvNotAvail;
|
||||
bool mNrfActive = false;
|
||||
|
||||
bool mNetworkConnected;
|
||||
|
||||
|
|
|
@ -824,8 +824,10 @@ class settings {
|
|||
|
||||
#if defined(ESP32)
|
||||
void getChar(JsonObject obj, const char *key, char *dst, int maxLen) {
|
||||
if(obj.containsKey(key))
|
||||
if(obj.containsKey(key)) {
|
||||
snprintf(dst, maxLen, "%s", obj[key].as<const char*>());
|
||||
dst[maxLen-1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T=uint8_t>
|
||||
|
@ -835,8 +837,10 @@ class settings {
|
|||
}
|
||||
#else
|
||||
void getChar(JsonObject obj, const __FlashStringHelper *key, char *dst, int maxLen) {
|
||||
if(obj.containsKey(key))
|
||||
if(obj.containsKey(key)) {
|
||||
snprintf(dst, maxLen, "%s", obj[key].as<const char*>());
|
||||
dst[maxLen-1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T=uint8_t>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
//-------------------------------------
|
||||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 8
|
||||
#define VERSION_PATCH 62
|
||||
#define VERSION_PATCH 63
|
||||
|
||||
//-------------------------------------
|
||||
typedef struct {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 2023 Ahoy, https://www.mikrocontroller.net/topic/525778
|
||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
||||
// 2024 Ahoy, https://github.com/lumpapu/ahoy
|
||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/4.0/deed
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if defined(ETHERNET)
|
||||
|
@ -49,7 +49,7 @@ class ahoyeth {
|
|||
#if defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||
EthSpi mEthSpi;
|
||||
#endif
|
||||
settings_t *mConfig;
|
||||
settings_t *mConfig = NULL;
|
||||
|
||||
uint32_t *mUtcTimestamp;
|
||||
AsyncUDP mUdp; // for time server
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 2023 Ahoy, https://www.mikrocontroller.net/topic/525778
|
||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
||||
// 2024 Ahoy, https://github.com/lumpapu/ahoy
|
||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/4.0/deed
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __NRF_HAL_H__
|
||||
|
@ -144,6 +144,8 @@ class nrfHal: public RF24_hal, public SpiPatcherHandle {
|
|||
uint8_t read(uint8_t cmd, uint8_t* buf, uint8_t len) override {
|
||||
uint8_t data[NRF_MAX_TRANSFER_SZ];
|
||||
data[0] = cmd;
|
||||
if(len > NRF_MAX_TRANSFER_SZ)
|
||||
len = NRF_MAX_TRANSFER_SZ;
|
||||
memset(&data[1], 0xff, len);
|
||||
|
||||
request_spi();
|
||||
|
@ -168,13 +170,16 @@ class nrfHal: public RF24_hal, public SpiPatcherHandle {
|
|||
}
|
||||
|
||||
uint8_t read(uint8_t cmd, uint8_t* buf, uint8_t data_len, uint8_t blank_len) override {
|
||||
uint8_t data[NRF_MAX_TRANSFER_SZ];
|
||||
uint8_t data[NRF_MAX_TRANSFER_SZ + 1];
|
||||
uint8_t len = data_len + blank_len;
|
||||
data[0] = cmd;
|
||||
memset(&data[1], 0xff, (data_len + blank_len));
|
||||
if(len > (NRF_MAX_TRANSFER_SZ + 1))
|
||||
len = (NRF_MAX_TRANSFER_SZ + 1);
|
||||
memset(&data[1], 0xff, len);
|
||||
|
||||
request_spi();
|
||||
|
||||
size_t spiLen = (static_cast<size_t>(data_len) + static_cast<size_t>(blank_len) + 1u) << 3;
|
||||
size_t spiLen = (static_cast<size_t>(len) + 1u) << 3;
|
||||
spi_transaction_t t = {
|
||||
.flags = 0,
|
||||
.cmd = 0,
|
||||
|
|
|
@ -19,226 +19,226 @@
|
|||
|
||||
template <class HMSYSTEM, class RADIO>
|
||||
class Display {
|
||||
public:
|
||||
Display() {
|
||||
mMono = NULL;
|
||||
}
|
||||
|
||||
void setup(IApp *app, display_t *cfg, HMSYSTEM *sys, RADIO *hmradio, RADIO *hmsradio, uint32_t *utcTs) {
|
||||
mApp = app;
|
||||
mHmRadio = hmradio;
|
||||
mHmsRadio = hmsradio;
|
||||
mCfg = cfg;
|
||||
mSys = sys;
|
||||
mUtcTs = utcTs;
|
||||
mNewPayload = false;
|
||||
mLoopCnt = 0;
|
||||
|
||||
mDisplayData.version = app->getVersion(); // version never changes, so only set once
|
||||
|
||||
switch (mCfg->type) {
|
||||
case DISP_TYPE_T0_NONE: mMono = NULL; break; // None
|
||||
case DISP_TYPE_T1_SSD1306_128X64: mMono = new DisplayMono128X64(); break; // SSD1306_128X64 (0.96", 1.54")
|
||||
case DISP_TYPE_T2_SH1106_128X64: mMono = new DisplayMono128X64(); break; // SH1106_128X64 (1.3")
|
||||
case DISP_TYPE_T3_PCD8544_84X48: mMono = new DisplayMono84X48(); break; // PCD8544_84X48 (1.6" - Nokia 5110)
|
||||
case DISP_TYPE_T4_SSD1306_128X32: mMono = new DisplayMono128X32(); break; // SSD1306_128X32 (0.91")
|
||||
case DISP_TYPE_T5_SSD1306_64X48: mMono = new DisplayMono64X48(); break; // SSD1306_64X48 (0.66" - Wemos OLED Shield)
|
||||
case DISP_TYPE_T6_SSD1309_128X64: mMono = new DisplayMono128X64(); break; // SSD1309_128X64 (2.42")
|
||||
#if defined(ESP32) && !defined(ETHERNET)
|
||||
case DISP_TYPE_T10_EPAPER:
|
||||
mMono = NULL; // ePaper does not use this
|
||||
mRefreshCycle = 0;
|
||||
mEpaper.config(mCfg->rot, mCfg->pwrSaveAtIvOffline);
|
||||
mEpaper.init(mCfg->type, mCfg->disp_cs, mCfg->disp_dc, mCfg->disp_reset, mCfg->disp_busy, mCfg->disp_clk, mCfg->disp_data, mUtcTs, mDisplayData.version);
|
||||
break;
|
||||
#endif
|
||||
default: mMono = NULL; break;
|
||||
}
|
||||
if(mMono) {
|
||||
mMono->config(mCfg);
|
||||
mMono->init(&mDisplayData);
|
||||
public:
|
||||
Display() {
|
||||
mMono = NULL;
|
||||
}
|
||||
|
||||
// setup PIR pin for motion sensor
|
||||
#ifdef ESP32
|
||||
if ((mCfg->screenSaver == 2) && (mCfg->pirPin != DEF_PIN_OFF))
|
||||
pinMode(mCfg->pirPin, INPUT);
|
||||
#endif
|
||||
#ifdef ESP8266
|
||||
if ((mCfg->screenSaver == 2) && (mCfg->pirPin != DEF_PIN_OFF) && (mCfg->pirPin != A0))
|
||||
pinMode(mCfg->pirPin, INPUT);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void payloadEventListener(uint8_t cmd) {
|
||||
mNewPayload = true;
|
||||
}
|
||||
|
||||
void tickerSecond() {
|
||||
bool request_refresh = false;
|
||||
|
||||
if (mMono != NULL)
|
||||
request_refresh = mMono->loop(motionSensorActive());
|
||||
|
||||
if (mNewPayload || (((++mLoopCnt) % 5) == 0) || request_refresh) {
|
||||
DataScreen();
|
||||
void setup(IApp *app, display_t *cfg, HMSYSTEM *sys, RADIO *hmradio, RADIO *hmsradio, uint32_t *utcTs) {
|
||||
mApp = app;
|
||||
mHmRadio = hmradio;
|
||||
mHmsRadio = hmsradio;
|
||||
mCfg = cfg;
|
||||
mSys = sys;
|
||||
mUtcTs = utcTs;
|
||||
mNewPayload = false;
|
||||
mLoopCnt = 0;
|
||||
}
|
||||
#if defined(ESP32) && !defined(ETHERNET)
|
||||
mEpaper.tickerSecond();
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
void DataScreen() {
|
||||
if (DISP_TYPE_T0_NONE == mCfg->type)
|
||||
return;
|
||||
mDisplayData.version = app->getVersion(); // version never changes, so only set once
|
||||
|
||||
float totalPower = 0.0;
|
||||
float totalYieldDay = 0.0;
|
||||
float totalYieldTotal = 0.0;
|
||||
|
||||
uint8_t nrprod = 0;
|
||||
uint8_t nrsleep = 0;
|
||||
int8_t minQAllInv = 4;
|
||||
|
||||
Inverter<> *iv;
|
||||
record_t<> *rec;
|
||||
bool allOff = true;
|
||||
uint8_t nInv = mSys->getNumInverters();
|
||||
for (uint8_t i = 0; i < nInv; i++) {
|
||||
iv = mSys->getInverterByPos(i);
|
||||
if (iv == NULL)
|
||||
continue;
|
||||
|
||||
if (iv->isProducing()) // also updates inverter state engine
|
||||
nrprod++;
|
||||
else
|
||||
nrsleep++;
|
||||
|
||||
rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
||||
|
||||
if (iv->isAvailable()) { // consider only radio quality of inverters still communicating
|
||||
int8_t maxQInv = -6;
|
||||
for(uint8_t ch = 0; ch < RF_MAX_CHANNEL_ID; ch++) {
|
||||
int8_t q = iv->heuristics.txRfQuality[ch];
|
||||
if (q > maxQInv)
|
||||
maxQInv = q;
|
||||
}
|
||||
if (maxQInv < minQAllInv)
|
||||
minQAllInv = maxQInv;
|
||||
|
||||
totalPower += iv->getChannelFieldValue(CH0, FLD_PAC, rec); // add only FLD_PAC from inverters still communicating
|
||||
allOff = false;
|
||||
switch (mCfg->type) {
|
||||
case DISP_TYPE_T0_NONE: mMono = NULL; break; // None
|
||||
case DISP_TYPE_T1_SSD1306_128X64: mMono = new DisplayMono128X64(); break; // SSD1306_128X64 (0.96", 1.54")
|
||||
case DISP_TYPE_T2_SH1106_128X64: mMono = new DisplayMono128X64(); break; // SH1106_128X64 (1.3")
|
||||
case DISP_TYPE_T3_PCD8544_84X48: mMono = new DisplayMono84X48(); break; // PCD8544_84X48 (1.6" - Nokia 5110)
|
||||
case DISP_TYPE_T4_SSD1306_128X32: mMono = new DisplayMono128X32(); break; // SSD1306_128X32 (0.91")
|
||||
case DISP_TYPE_T5_SSD1306_64X48: mMono = new DisplayMono64X48(); break; // SSD1306_64X48 (0.66" - Wemos OLED Shield)
|
||||
case DISP_TYPE_T6_SSD1309_128X64: mMono = new DisplayMono128X64(); break; // SSD1309_128X64 (2.42")
|
||||
#if defined(ESP32) && !defined(ETHERNET)
|
||||
case DISP_TYPE_T10_EPAPER:
|
||||
mMono = NULL; // ePaper does not use this
|
||||
mRefreshCycle = 0;
|
||||
mEpaper.config(mCfg->rot, mCfg->pwrSaveAtIvOffline);
|
||||
mEpaper.init(mCfg->type, mCfg->disp_cs, mCfg->disp_dc, mCfg->disp_reset, mCfg->disp_busy, mCfg->disp_clk, mCfg->disp_data, mUtcTs, mDisplayData.version);
|
||||
break;
|
||||
#endif
|
||||
default: mMono = NULL; break;
|
||||
}
|
||||
if(mMono) {
|
||||
mMono->config(mCfg);
|
||||
mMono->init(&mDisplayData);
|
||||
}
|
||||
|
||||
totalYieldDay += iv->getChannelFieldValue(CH0, FLD_YD, rec);
|
||||
totalYieldTotal += iv->getChannelFieldValue(CH0, FLD_YT, rec);
|
||||
// setup PIR pin for motion sensor
|
||||
#ifdef ESP32
|
||||
if ((mCfg->screenSaver == 2) && (mCfg->pirPin != DEF_PIN_OFF))
|
||||
pinMode(mCfg->pirPin, INPUT);
|
||||
#endif
|
||||
#ifdef ESP8266
|
||||
if ((mCfg->screenSaver == 2) && (mCfg->pirPin != DEF_PIN_OFF) && (mCfg->pirPin != A0))
|
||||
pinMode(mCfg->pirPin, INPUT);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
if (allOff)
|
||||
minQAllInv = -6;
|
||||
|
||||
// prepare display data
|
||||
mDisplayData.nrProducing = nrprod;
|
||||
mDisplayData.nrSleeping = nrsleep;
|
||||
mDisplayData.totalPower = totalPower;
|
||||
mDisplayData.totalYieldDay = totalYieldDay;
|
||||
mDisplayData.totalYieldTotal = totalYieldTotal;
|
||||
bool nrf_en = mApp->getNrfEnabled();
|
||||
bool nrf_ok = nrf_en && mHmRadio->isChipConnected();
|
||||
#if defined(ESP32)
|
||||
bool cmt_en = mApp->getCmtEnabled();
|
||||
bool cmt_ok = cmt_en && mHmsRadio->isChipConnected();
|
||||
#else
|
||||
bool cmt_en = false;
|
||||
bool cmt_ok = false;
|
||||
#endif
|
||||
mDisplayData.RadioSymbol = (nrf_ok && !cmt_en) || (cmt_ok && !nrf_en) || (nrf_ok && cmt_ok);
|
||||
mDisplayData.WifiSymbol = (WiFi.status() == WL_CONNECTED);
|
||||
mDisplayData.MQTTSymbol = mApp->getMqttIsConnected();
|
||||
mDisplayData.RadioRSSI = ivQuality2RadioRSSI(minQAllInv); // Workaround as NRF24 has no RSSI. Approximation by quality levels from heuristic function
|
||||
mDisplayData.WifiRSSI = (WiFi.status() == WL_CONNECTED) ? WiFi.RSSI() : SCHAR_MIN;
|
||||
mDisplayData.ipAddress = WiFi.localIP();
|
||||
|
||||
// provide localized times to display classes
|
||||
time_t utc= mApp->getTimestamp();
|
||||
if (year(utc) > 2020)
|
||||
mDisplayData.utcTs = gTimezone.toLocal(utc);
|
||||
else
|
||||
mDisplayData.utcTs = 0;
|
||||
mDisplayData.pGraphStartTime = gTimezone.toLocal(mApp->getSunrise());
|
||||
mDisplayData.pGraphEndTime = gTimezone.toLocal(mApp->getSunset());
|
||||
|
||||
if (mMono ) {
|
||||
mMono->disp();
|
||||
}
|
||||
#if defined(ESP32) && !defined(ETHERNET)
|
||||
else if (DISP_TYPE_T10_EPAPER == mCfg->type) {
|
||||
mEpaper.loop((totalPower), totalYieldDay, totalYieldTotal, nrprod);
|
||||
mRefreshCycle++;
|
||||
void payloadEventListener(uint8_t cmd) {
|
||||
mNewPayload = true;
|
||||
}
|
||||
|
||||
if (mRefreshCycle > 480) {
|
||||
mEpaper.fullRefresh();
|
||||
mRefreshCycle = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
void tickerSecond() {
|
||||
bool request_refresh = false;
|
||||
|
||||
bool motionSensorActive() {
|
||||
if ((mCfg->screenSaver == 2) && (mCfg->pirPin != DEF_PIN_OFF)) {
|
||||
#if defined(ESP8266)
|
||||
if (mCfg->pirPin == A0)
|
||||
return((analogRead(A0) >= 512));
|
||||
if (mMono != NULL)
|
||||
request_refresh = mMono->loop(motionSensorActive());
|
||||
|
||||
if (mNewPayload || (((++mLoopCnt) % 5) == 0) || request_refresh) {
|
||||
DataScreen();
|
||||
mNewPayload = false;
|
||||
mLoopCnt = 0;
|
||||
}
|
||||
#if defined(ESP32) && !defined(ETHERNET)
|
||||
mEpaper.tickerSecond();
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
void DataScreen() {
|
||||
if (DISP_TYPE_T0_NONE == mCfg->type)
|
||||
return;
|
||||
|
||||
float totalPower = 0.0;
|
||||
float totalYieldDay = 0.0;
|
||||
float totalYieldTotal = 0.0;
|
||||
|
||||
uint8_t nrprod = 0;
|
||||
uint8_t nrsleep = 0;
|
||||
int8_t minQAllInv = 4;
|
||||
|
||||
Inverter<> *iv;
|
||||
record_t<> *rec;
|
||||
bool allOff = true;
|
||||
uint8_t nInv = mSys->getNumInverters();
|
||||
for (uint8_t i = 0; i < nInv; i++) {
|
||||
iv = mSys->getInverterByPos(i);
|
||||
if (iv == NULL)
|
||||
continue;
|
||||
|
||||
if (iv->isProducing()) // also updates inverter state engine
|
||||
nrprod++;
|
||||
else
|
||||
nrsleep++;
|
||||
|
||||
rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
||||
|
||||
if (iv->isAvailable()) { // consider only radio quality of inverters still communicating
|
||||
int8_t maxQInv = -6;
|
||||
for(uint8_t ch = 0; ch < RF_MAX_CHANNEL_ID; ch++) {
|
||||
int8_t q = iv->heuristics.txRfQuality[ch];
|
||||
if (q > maxQInv)
|
||||
maxQInv = q;
|
||||
}
|
||||
if (maxQInv < minQAllInv)
|
||||
minQAllInv = maxQInv;
|
||||
|
||||
totalPower += iv->getChannelFieldValue(CH0, FLD_PAC, rec); // add only FLD_PAC from inverters still communicating
|
||||
allOff = false;
|
||||
}
|
||||
|
||||
totalYieldDay += iv->getChannelFieldValue(CH0, FLD_YD, rec);
|
||||
totalYieldTotal += iv->getChannelFieldValue(CH0, FLD_YT, rec);
|
||||
}
|
||||
|
||||
if (allOff)
|
||||
minQAllInv = -6;
|
||||
|
||||
// prepare display data
|
||||
mDisplayData.nrProducing = nrprod;
|
||||
mDisplayData.nrSleeping = nrsleep;
|
||||
mDisplayData.totalPower = totalPower;
|
||||
mDisplayData.totalYieldDay = totalYieldDay;
|
||||
mDisplayData.totalYieldTotal = totalYieldTotal;
|
||||
bool nrf_en = mApp->getNrfEnabled();
|
||||
bool nrf_ok = nrf_en && mHmRadio->isChipConnected();
|
||||
#if defined(ESP32)
|
||||
bool cmt_en = mApp->getCmtEnabled();
|
||||
bool cmt_ok = cmt_en && mHmsRadio->isChipConnected();
|
||||
#else
|
||||
bool cmt_en = false;
|
||||
bool cmt_ok = false;
|
||||
#endif
|
||||
mDisplayData.RadioSymbol = (nrf_ok && !cmt_en) || (cmt_ok && !nrf_en) || (nrf_ok && cmt_ok);
|
||||
mDisplayData.WifiSymbol = (WiFi.status() == WL_CONNECTED);
|
||||
mDisplayData.MQTTSymbol = mApp->getMqttIsConnected();
|
||||
mDisplayData.RadioRSSI = ivQuality2RadioRSSI(minQAllInv); // Workaround as NRF24 has no RSSI. Approximation by quality levels from heuristic function
|
||||
mDisplayData.WifiRSSI = (WiFi.status() == WL_CONNECTED) ? WiFi.RSSI() : SCHAR_MIN;
|
||||
mDisplayData.ipAddress = WiFi.localIP();
|
||||
|
||||
// provide localized times to display classes
|
||||
time_t utc= mApp->getTimestamp();
|
||||
if (year(utc) > 2020)
|
||||
mDisplayData.utcTs = gTimezone.toLocal(utc);
|
||||
else
|
||||
mDisplayData.utcTs = 0;
|
||||
mDisplayData.pGraphStartTime = gTimezone.toLocal(mApp->getSunrise());
|
||||
mDisplayData.pGraphEndTime = gTimezone.toLocal(mApp->getSunset());
|
||||
|
||||
if (mMono ) {
|
||||
mMono->disp();
|
||||
}
|
||||
#if defined(ESP32) && !defined(ETHERNET)
|
||||
else if (DISP_TYPE_T10_EPAPER == mCfg->type) {
|
||||
mEpaper.loop((totalPower), totalYieldDay, totalYieldTotal, nrprod);
|
||||
mRefreshCycle++;
|
||||
}
|
||||
|
||||
if (mRefreshCycle > 480) {
|
||||
mEpaper.fullRefresh();
|
||||
mRefreshCycle = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool motionSensorActive() {
|
||||
if ((mCfg->screenSaver == 2) && (mCfg->pirPin != DEF_PIN_OFF)) {
|
||||
#if defined(ESP8266)
|
||||
if (mCfg->pirPin == A0)
|
||||
return((analogRead(A0) >= 512));
|
||||
else
|
||||
return(digitalRead(mCfg->pirPin));
|
||||
#elif defined(ESP32)
|
||||
return(digitalRead(mCfg->pirPin));
|
||||
#elif defined(ESP32)
|
||||
return(digitalRead(mCfg->pirPin));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
else
|
||||
return(false);
|
||||
}
|
||||
else
|
||||
return(false);
|
||||
}
|
||||
|
||||
// approximate RSSI in dB by invQuality levels from heuristic function (very unscientific but better than nothing :-) )
|
||||
int8_t ivQuality2RadioRSSI(int8_t invQuality) {
|
||||
int8_t pseudoRSSIdB;
|
||||
switch(invQuality) {
|
||||
case 4: pseudoRSSIdB = -55; break;
|
||||
case 3:
|
||||
case 2:
|
||||
case 1: pseudoRSSIdB = -65; break;
|
||||
case 0:
|
||||
case -1:
|
||||
case -2: pseudoRSSIdB = -75; break;
|
||||
case -3:
|
||||
case -4:
|
||||
case -5: pseudoRSSIdB = -85; break;
|
||||
case -6:
|
||||
default: pseudoRSSIdB = -95; break;
|
||||
// approximate RSSI in dB by invQuality levels from heuristic function (very unscientific but better than nothing :-) )
|
||||
int8_t ivQuality2RadioRSSI(int8_t invQuality) {
|
||||
int8_t pseudoRSSIdB;
|
||||
switch(invQuality) {
|
||||
case 4: pseudoRSSIdB = -55; break;
|
||||
case 3:
|
||||
case 2:
|
||||
case 1: pseudoRSSIdB = -65; break;
|
||||
case 0:
|
||||
case -1:
|
||||
case -2: pseudoRSSIdB = -75; break;
|
||||
case -3:
|
||||
case -4:
|
||||
case -5: pseudoRSSIdB = -85; break;
|
||||
case -6:
|
||||
default: pseudoRSSIdB = -95; break;
|
||||
}
|
||||
return (pseudoRSSIdB);
|
||||
}
|
||||
return (pseudoRSSIdB);
|
||||
}
|
||||
|
||||
// private member variables
|
||||
IApp *mApp;
|
||||
DisplayData mDisplayData;
|
||||
bool mNewPayload;
|
||||
uint8_t mLoopCnt;
|
||||
uint32_t *mUtcTs;
|
||||
display_t *mCfg;
|
||||
HMSYSTEM *mSys;
|
||||
RADIO *mHmRadio;
|
||||
RADIO *mHmsRadio;
|
||||
uint16_t mRefreshCycle;
|
||||
// private member variables
|
||||
IApp *mApp;
|
||||
DisplayData mDisplayData;
|
||||
bool mNewPayload;
|
||||
uint8_t mLoopCnt;
|
||||
uint32_t *mUtcTs;
|
||||
display_t *mCfg;
|
||||
HMSYSTEM *mSys;
|
||||
RADIO *mHmRadio;
|
||||
RADIO *mHmsRadio;
|
||||
uint16_t mRefreshCycle;
|
||||
|
||||
#if defined(ESP32) && !defined(ETHERNET)
|
||||
DisplayEPaper mEpaper;
|
||||
#endif
|
||||
DisplayMono *mMono;
|
||||
#if defined(ESP32) && !defined(ETHERNET)
|
||||
DisplayEPaper mEpaper;
|
||||
#endif
|
||||
DisplayMono *mMono;
|
||||
};
|
||||
|
||||
#endif /*PLUGIN_DISPLAY*/
|
||||
|
|
|
@ -20,6 +20,7 @@ SPIClass hspi(HSPI);
|
|||
DisplayEPaper::DisplayEPaper() {
|
||||
mDisplayRotation = 2;
|
||||
mHeadFootPadding = 16;
|
||||
memset(_fmtText, 0, EPAPER_MAX_TEXT_LEN);
|
||||
}
|
||||
|
||||
|
||||
|
@ -114,9 +115,9 @@ void DisplayEPaper::headlineIP() {
|
|||
|
||||
do {
|
||||
if ((WiFi.isConnected() == true) && (WiFi.localIP() > 0)) {
|
||||
snprintf(_fmtText, sizeof(_fmtText), "%s", WiFi.localIP().toString().c_str());
|
||||
snprintf(_fmtText, EPAPER_MAX_TEXT_LEN, "%s", WiFi.localIP().toString().c_str());
|
||||
} else {
|
||||
snprintf(_fmtText, sizeof(_fmtText), "WiFi not connected");
|
||||
snprintf(_fmtText, EPAPER_MAX_TEXT_LEN, "WiFi not connected");
|
||||
}
|
||||
_display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh);
|
||||
uint16_t x = ((_display->width() - tbw) / 2) - tbx;
|
||||
|
@ -137,7 +138,7 @@ void DisplayEPaper::lastUpdatePaged() {
|
|||
_display->fillScreen(GxEPD_BLACK);
|
||||
do {
|
||||
if (NULL != mUtcTs) {
|
||||
snprintf(_fmtText, sizeof(_fmtText), ah::getDateTimeStr(gTimezone.toLocal(*mUtcTs)).c_str());
|
||||
snprintf(_fmtText, EPAPER_MAX_TEXT_LEN, ah::getDateTimeStr(gTimezone.toLocal(*mUtcTs)).c_str());
|
||||
|
||||
_display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh);
|
||||
uint16_t x = ((_display->width() - tbw) / 2) - tbx;
|
||||
|
@ -158,7 +159,7 @@ void DisplayEPaper::versionFooter() {
|
|||
_display->setPartialWindow(0, _display->height() - mHeadFootPadding, _display->width(), mHeadFootPadding);
|
||||
_display->fillScreen(GxEPD_BLACK);
|
||||
do {
|
||||
snprintf(_fmtText, sizeof(_fmtText), "Version: %s", _version);
|
||||
snprintf(_fmtText, EPAPER_MAX_TEXT_LEN, "Version: %s", _version);
|
||||
|
||||
_display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh);
|
||||
uint16_t x = ((_display->width() - tbw) / 2) - tbx;
|
||||
|
@ -179,7 +180,7 @@ void DisplayEPaper::offlineFooter() {
|
|||
_display->fillScreen(GxEPD_BLACK);
|
||||
do {
|
||||
if (NULL != mUtcTs) {
|
||||
snprintf(_fmtText, sizeof(_fmtText), "offline");
|
||||
snprintf(_fmtText, EPAPER_MAX_TEXT_LEN, "offline");
|
||||
|
||||
_display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh);
|
||||
uint16_t x = ((_display->width() - tbw) / 2) - tbx;
|
||||
|
@ -203,13 +204,13 @@ void DisplayEPaper::actualPowerPaged(float totalPower, float totalYieldDay, floa
|
|||
do {
|
||||
// actual Production
|
||||
if (totalPower > 9999) {
|
||||
snprintf(_fmtText, sizeof(_fmtText), "%.1f kW", (totalPower / 1000));
|
||||
snprintf(_fmtText, EPAPER_MAX_TEXT_LEN, "%.1f kW", (totalPower / 1000));
|
||||
_changed = true;
|
||||
} else if ((totalPower > 0) && (totalPower <= 9999)) {
|
||||
snprintf(_fmtText, sizeof(_fmtText), "%.0f W", totalPower);
|
||||
snprintf(_fmtText, EPAPER_MAX_TEXT_LEN, "%.0f W", totalPower);
|
||||
_changed = true;
|
||||
} else
|
||||
snprintf(_fmtText, sizeof(_fmtText), "offline");
|
||||
snprintf(_fmtText, EPAPER_MAX_TEXT_LEN, "offline");
|
||||
|
||||
if ((totalPower == 0) && (mEnPowerSave)) {
|
||||
_display->fillRect(0, mHeadFootPadding, 200, 200, GxEPD_BLACK);
|
||||
|
@ -264,7 +265,7 @@ void DisplayEPaper::actualPowerPaged(float totalPower, float totalYieldDay, floa
|
|||
// Inverter online
|
||||
_display->setFont(&FreeSans12pt7b);
|
||||
y = _display->height() - (mHeadFootPadding + 10);
|
||||
snprintf(_fmtText, sizeof(_fmtText), " %d online", isprod);
|
||||
snprintf(_fmtText, EPAPER_MAX_TEXT_LEN, " %d online", isprod);
|
||||
_display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh);
|
||||
_display->drawInvertedBitmap(10, y - tbh, myWR, 20, 20, GxEPD_BLACK);
|
||||
x = ((_display->width() - tbw - 20) / 2) - tbx;
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
// enable GxEPD2_GFX base class
|
||||
#define ENABLE_GxEPD2_GFX 1
|
||||
|
||||
#define EPAPER_MAX_TEXT_LEN 35
|
||||
|
||||
#include <GxEPD2_BW.h>
|
||||
#include <SPI.h>
|
||||
|
||||
|
@ -49,7 +51,7 @@ class DisplayEPaper {
|
|||
|
||||
uint8_t mDisplayRotation;
|
||||
bool _changed = false;
|
||||
char _fmtText[35];
|
||||
char _fmtText[EPAPER_MAX_TEXT_LEN];
|
||||
String _settedIP;
|
||||
uint8_t mHeadFootPadding;
|
||||
GxEPD2_GFX* _display;
|
||||
|
|
|
@ -70,8 +70,8 @@ class PubMqtt {
|
|||
|
||||
if(strlen(mCfgMqtt->clientId) > 0)
|
||||
snprintf(mClientId, 23, "%s", mCfgMqtt->clientId);
|
||||
else{
|
||||
snprintf(mClientId, 24, "%s-", mDevName);
|
||||
else {
|
||||
snprintf(mClientId, 23, "%s-", mDevName);
|
||||
uint8_t pos = strlen(mClientId);
|
||||
mClientId[pos++] = WiFi.macAddress().substring( 9, 10).c_str()[0];
|
||||
mClientId[pos++] = WiFi.macAddress().substring(10, 11).c_str()[0];
|
||||
|
@ -308,7 +308,7 @@ class PubMqtt {
|
|||
bool limitAbs = false;
|
||||
if(len > 0) {
|
||||
char *pyld = new char[len + 1];
|
||||
strncpy(pyld, (const char*)payload, len);
|
||||
memcpy(pyld, payload, len);
|
||||
pyld[len] = '\0';
|
||||
if(NULL == strstr(topic, "limit"))
|
||||
root[F("val")] = atoi(pyld);
|
||||
|
@ -326,7 +326,7 @@ class PubMqtt {
|
|||
|
||||
while(1) {
|
||||
if(('/' == p[pos]) || ('\0' == p[pos])) {
|
||||
strncpy(tmp, p, pos);
|
||||
memcpy(tmp, p, pos);
|
||||
tmp[pos] = '\0';
|
||||
switch(elm++) {
|
||||
case 1: root[F("path")] = String(tmp); break;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 2022 Ahoy, https://github.com/lumpapu/ahoy
|
||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
||||
// 2024 Ahoy, https://github.com/lumpapu/ahoy
|
||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/4.0/deed
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "crc.h"
|
||||
|
@ -19,7 +19,7 @@ namespace ah {
|
|||
|
||||
uint16_t crc16(uint8_t buf[], uint8_t len, uint16_t start) {
|
||||
uint16_t crc = start;
|
||||
uint8_t shift = 0;
|
||||
uint8_t shift;
|
||||
|
||||
for(uint8_t i = 0; i < len; i ++) {
|
||||
crc = crc ^ buf[i];
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 2023 Ahoy, https://github.com/lumpapu/ahoy
|
||||
// 2024 Ahoy, https://github.com/lumpapu/ahoy
|
||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/4.0/deed
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -72,10 +72,10 @@ class Improv {
|
|||
|
||||
void dumpBuf(uint8_t buf[], uint8_t len) {
|
||||
for(uint8_t i = 0; i < len; i++) {
|
||||
DHEX(buf[i], false);
|
||||
DBGPRINT(" ", false);
|
||||
DHEX(buf[i]);
|
||||
DBGPRINT(F(" "));
|
||||
}
|
||||
DBGPRINTLN("", false);
|
||||
DBGPRINTLN("");
|
||||
}
|
||||
|
||||
inline uint8_t buildChecksum(uint8_t buf[], uint8_t len) {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 2023 Ahoy, https://ahoydtu.de
|
||||
// Lukas Pusch, lukas@lpusch.de
|
||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
||||
// 2024 Ahoy, https://ahoydtu.de
|
||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/4.0/deed
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __SCHEDULER_H__
|
||||
|
@ -40,7 +39,7 @@ namespace ah {
|
|||
resetTicker();
|
||||
}
|
||||
|
||||
void loop(void) {
|
||||
virtual void loop(void) {
|
||||
mMillis = millis();
|
||||
mDiff = mMillis - mPrevMillis;
|
||||
if (mDiff < 1000)
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 2024 Ahoy, https://github.com/lumpapu/ahoy
|
||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/4.0/deed
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <algorithm>
|
||||
#include "syslog.h"
|
||||
|
||||
|
@ -87,7 +92,7 @@ void DbgSyslog::log(const char *hostname, uint8_t facility, uint8_t severity, ch
|
|||
|
||||
// This is a unit8 instead of a char because that's what udp.write() wants
|
||||
uint8_t buffer[SYSLOG_MAX_PACKET_SIZE];
|
||||
int len = snprintf((char*)buffer, SYSLOG_MAX_PACKET_SIZE, "<%d>%s %s: %s", priority, hostname, SYSLOG_APP, msg);
|
||||
int len = snprintf(static_cast<char*>(buffer), SYSLOG_MAX_PACKET_SIZE, "<%d>%s %s: %s", priority, hostname, SYSLOG_APP, msg);
|
||||
//printf("syslog::log %s\n",mSyslogIP.toString().c_str());
|
||||
//printf("syslog::log %d %s\n",len,buffer);
|
||||
// Send the raw UDP packet
|
||||
|
@ -96,4 +101,4 @@ void DbgSyslog::log(const char *hostname, uint8_t facility, uint8_t severity, ch
|
|||
mSyslogUdp.endPacket();
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -1,42 +1,42 @@
|
|||
/* SVG ICONS - https://icons.getbootstrap.com */
|
||||
|
||||
iconWifi1 = [
|
||||
var iconWifi1 = [
|
||||
"M11.046 10.454c.226-.226.185-.605-.1-.75A6.473 6.473 0 0 0 8 9c-1.06 0-2.062.254-2.946.704-.285.145-.326.524-.1.75l.015.015c.16.16.407.19.611.09A5.478 5.478 0 0 1 8 10c.868 0 1.69.201 2.42.56.203.1.45.07.611-.091l.015-.015zM9.06 12.44c.196-.196.198-.52-.04-.66A1.99 1.99 0 0 0 8 11.5a1.99 1.99 0 0 0-1.02.28c-.238.14-.236.464-.04.66l.706.706a.5.5 0 0 0 .707 0l.708-.707z"
|
||||
];
|
||||
|
||||
iconWifi2 = [
|
||||
var iconWifi2 = [
|
||||
"M13.229 8.271c.216-.216.194-.578-.063-.745A9.456 9.456 0 0 0 8 6c-1.905 0-3.68.56-5.166 1.526a.48.48 0 0 0-.063.745.525.525 0 0 0 .652.065A8.46 8.46 0 0 1 8 7a8.46 8.46 0 0 1 4.577 1.336c.205.132.48.108.652-.065zm-2.183 2.183c.226-.226.185-.605-.1-.75A6.473 6.473 0 0 0 8 9c-1.06 0-2.062.254-2.946.704-.285.145-.326.524-.1.75l.015.015c.16.16.408.19.611.09A5.478 5.478 0 0 1 8 10c.868 0 1.69.201 2.42.56.203.1.45.07.611-.091l.015-.015zM9.06 12.44c.196-.196.198-.52-.04-.66A1.99 1.99 0 0 0 8 11.5a1.99 1.99 0 0 0-1.02.28c-.238.14-.236.464-.04.66l.706.706a.5.5 0 0 0 .708 0l.707-.707z"
|
||||
];
|
||||
|
||||
iconWifi3 = [
|
||||
var iconWifi3 = [
|
||||
"M15.384 6.115a.485.485 0 0 0-.047-.736A12.444 12.444 0 0 0 8 3C5.259 3 2.723 3.882.663 5.379a.485.485 0 0 0-.048.736.518.518 0 0 0 .668.05A11.448 11.448 0 0 1 8 4c2.507 0 4.827.802 6.716 2.164.205.148.49.13.668-.049z",
|
||||
"M13.229 8.271a.482.482 0 0 0-.063-.745A9.455 9.455 0 0 0 8 6c-1.905 0-3.68.56-5.166 1.526a.48.48 0 0 0-.063.745.525.525 0 0 0 .652.065A8.46 8.46 0 0 1 8 7a8.46 8.46 0 0 1 4.576 1.336c.206.132.48.108.653-.065zm-2.183 2.183c.226-.226.185-.605-.1-.75A6.473 6.473 0 0 0 8 9c-1.06 0-2.062.254-2.946.704-.285.145-.326.524-.1.75l.015.015c.16.16.407.19.611.09A5.478 5.478 0 0 1 8 10c.868 0 1.69.201 2.42.56.203.1.45.07.61-.091l.016-.015zM9.06 12.44c.196-.196.198-.52-.04-.66A1.99 1.99 0 0 0 8 11.5a1.99 1.99 0 0 0-1.02.28c-.238.14-.236.464-.04.66l.706.706a.5.5 0 0 0 .707 0l.707-.707z"
|
||||
];
|
||||
|
||||
iconWarn = [
|
||||
var iconWarn = [
|
||||
"M7.938 2.016A.13.13 0 0 1 8.002 2a.13.13 0 0 1 .063.016.146.146 0 0 1 .054.057l6.857 11.667c.036.06.035.124.002.183a.163.163 0 0 1-.054.06.116.116 0 0 1-.066.017H1.146a.115.115 0 0 1-.066-.017.163.163 0 0 1-.054-.06.176.176 0 0 1 .002-.183L7.884 2.073a.147.147 0 0 1 .054-.057zm1.044-.45a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566z",
|
||||
"M7.002 12a1 1 0 1 1 2 0 1 1 0 0 1-2 0zM7.1 5.995a.905.905 0 1 1 1.8 0l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995z"
|
||||
];
|
||||
|
||||
iconInfo = [
|
||||
var iconInfo = [
|
||||
"M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z",
|
||||
"m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"
|
||||
];
|
||||
|
||||
iconSuccess = [
|
||||
var iconSuccess = [
|
||||
"M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z",
|
||||
"M10.97 4.97a.235.235 0 0 0-.02.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-1.071-1.05z"
|
||||
];
|
||||
|
||||
iconSuccessFull = [
|
||||
var iconSuccessFull = [
|
||||
"M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z"
|
||||
];
|
||||
|
||||
iconGear = [
|
||||
var iconGear = [
|
||||
"M9.405 1.05c-.413-1.4-2.397-1.4-2.81 0l-.1.34a1.464 1.464 0 0 1-2.105.872l-.31-.17c-1.283-.698-2.686.705-1.987 1.987l.169.311c.446.82.023 1.841-.872 2.105l-.34.1c-1.4.413-1.4 2.397 0 2.81l.34.1a1.464 1.464 0 0 1 .872 2.105l-.17.31c-.698 1.283.705 2.686 1.987 1.987l.311-.169a1.464 1.464 0 0 1 2.105.872l.1.34c.413 1.4 2.397 1.4 2.81 0l.1-.34a1.464 1.464 0 0 1 2.105-.872l.31.17c1.283.698 2.686-.705 1.987-1.987l-.169-.311a1.464 1.464 0 0 1 .872-2.105l.34-.1c1.4-.413 1.4-2.397 0-2.81l-.34-.1a1.464 1.464 0 0 1-.872-2.105l.17-.31c.698-1.283-.705-2.686-1.987-1.987l-.311.169a1.464 1.464 0 0 1-2.105-.872l-.1-.34zM8 10.93a2.929 2.929 0 1 1 0-5.86 2.929 2.929 0 0 1 0 5.858z"
|
||||
];
|
||||
|
||||
iconDel = [
|
||||
var iconDel = [
|
||||
"M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z",
|
||||
"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z"
|
||||
];
|
||||
|
|
|
@ -280,7 +280,7 @@
|
|||
},
|
||||
{
|
||||
"token": "INV_GAP",
|
||||
"en": "Communication Gap [ms]",
|
||||
"en": "Communication Gap",
|
||||
"de": "Kommunikationslücke"
|
||||
},
|
||||
{
|
||||
|
|
|
@ -828,10 +828,9 @@ class Web {
|
|||
if (0 == channel) {
|
||||
// Report a _total value if also channel values were reported. Otherwise report without _total
|
||||
char total[7];
|
||||
total[0] = 0;
|
||||
if (metricDeclared) {
|
||||
// A declaration and value for channels have been delivered. So declare and deliver a _total metric
|
||||
strncpy(total,"_total",sizeof(total));
|
||||
strncpy(total, "_total", 6);
|
||||
}
|
||||
if (!metricTotalDeclard) {
|
||||
snprintf(type, sizeof(type), "# TYPE %s%s%s%s %s\n",metricConstPrefix, iv->getFieldName(metricsChannelId, rec), promUnit.c_str(), total, promType.c_str());
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 2023 Ahoy, https://ahoydtu.de
|
||||
// 2024 Ahoy, https://ahoydtu.de
|
||||
// Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -293,7 +293,7 @@ bool ahoywifi::getNtpTime(void) {
|
|||
if(NTP_PACKET_SIZE <= mUdp.parsePacket()) {
|
||||
uint64_t secsSince1900;
|
||||
mUdp.read(buf, NTP_PACKET_SIZE);
|
||||
secsSince1900 = (buf[40] << 24);
|
||||
secsSince1900 = ((uint64_t)buf[40] << 24);
|
||||
secsSince1900 |= (buf[41] << 16);
|
||||
secsSince1900 |= (buf[42] << 8);
|
||||
secsSince1900 |= (buf[43] );
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
//------------------------------------//-----------------------------------------------------------------------------
|
||||
// 2024 Ahoy, https://github.com/lumpapu/ahoy
|
||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/4.0/deed
|
||||
//-----------------------------------------------------------------------------
|
||||
// 2023 Ahoy, https://www.mikrocontroller.net/topic/525778
|
||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if !defined(ETHERNET)
|
||||
#ifndef __AHOYWIFI_H__
|
||||
#define __AHOYWIFI_H__
|
||||
|
@ -66,7 +67,7 @@ class ahoywifi {
|
|||
void welcome(String ip, String mode);
|
||||
|
||||
|
||||
settings_t *mConfig;
|
||||
settings_t *mConfig = NULL;
|
||||
appWifiCb mAppWifiCb;
|
||||
|
||||
DNSServer mDns;
|
||||
|
|
Loading…
Add table
Reference in a new issue