Browse Source

Merge branch 'development03' into Zero-Export

pull/1155/head
DanielR92 2 years ago
parent
commit
e2e441b46b
  1. 9
      src/CHANGES.md
  2. 2
      src/defines.h
  3. 40
      src/hm/Communication.h
  4. 4
      src/hm/hmRadio.h
  5. 11
      src/plugins/Display/Display_Mono.h
  6. 20
      src/plugins/Display/Display_Mono_128X64.h
  7. 18
      src/plugins/Display/Display_Mono_84X48.h
  8. 126
      src/utils/timemonitor.h
  9. 1
      src/web/html/grid_info.json
  10. 20
      src/web/html/setup.html
  11. 9
      src/web/html/visualization.html

9
src/CHANGES.md

@ -1,5 +1,14 @@
# Development Changes # Development Changes
## 0.8.31 - 2023-12-29
* added class to handle timeouts PR #1298
## 0.8.30 - 2023-12-28
* added info if grid profile was not found
* merge PR #1293
* merge PR #1295 fix ESP8266 pin settings
* merge PR #1297 fix layout for OLED displays
## 0.8.29 - 2023-12-27 ## 0.8.29 - 2023-12-27
* fix MqTT generic topic `comm_disabled` #1265 #1286 * fix MqTT generic topic `comm_disabled` #1265 #1286
* potential fix of #1285 (reset yield day) * potential fix of #1285 (reset yield day)

2
src/defines.h

@ -13,7 +13,7 @@
//------------------------------------- //-------------------------------------
#define VERSION_MAJOR 0 #define VERSION_MAJOR 0
#define VERSION_MINOR 8 #define VERSION_MINOR 8
#define VERSION_PATCH 29 #define VERSION_PATCH 31
//------------------------------------- //-------------------------------------
typedef struct { typedef struct {

40
src/hm/Communication.h

@ -9,6 +9,7 @@
#include "CommQueue.h" #include "CommQueue.h"
#include <Arduino.h> #include <Arduino.h>
#include "../utils/crc.h" #include "../utils/crc.h"
#include "../utils/timemonitor.h"
#include "Heuristic.h" #include "Heuristic.h"
#define MI_TIMEOUT 250 // timeout for MI type requests #define MI_TIMEOUT 250 // timeout for MI type requests
@ -59,8 +60,7 @@ class Communication : public CommQueue<> {
mLastEmptyQueueMillis = millis(); mLastEmptyQueueMillis = millis();
mPrintSequenceDuration = true; mPrintSequenceDuration = true;
uint16_t timeout = (q->iv->ivGen == IV_MI) ? MI_TIMEOUT : (((q->iv->mGotFragment && q->iv->mGotLastMsg) || mIsRetransmit) ? SINGLEFR_TIMEOUT : ((q->cmd != AlarmData) ? DEFAULT_TIMEOUT : (1.5 * DEFAULT_TIMEOUT))); uint16_t timeout = (q->iv->ivGen == IV_MI) ? MI_TIMEOUT : (((q->iv->mGotFragment && q->iv->mGotLastMsg) || mIsRetransmit) ? SINGLEFR_TIMEOUT : ((q->cmd != AlarmData) && (q->cmd != GridOnProFilePara) ? DEFAULT_TIMEOUT : (1.5 * DEFAULT_TIMEOUT)));
uint16_t timeout_min = (q->iv->ivGen == IV_MI) ? MI_TIMEOUT : ((q->iv->mGotFragment || mIsRetransmit)) ? SINGLEFR_TIMEOUT : FRSTMSG_TIMEOUT;
/*if(mDebugState != mState) { /*if(mDebugState != mState) {
DPRINT(DBG_INFO, F("State: ")); DPRINT(DBG_INFO, F("State: "));
@ -69,8 +69,9 @@ class Communication : public CommQueue<> {
}*/ }*/
switch(mState) { switch(mState) {
case States::RESET: case States::RESET:
if(millis() < mWaitTimeout) if (!mWaitTime.isTimeout())
return; return;
mMaxFrameId = 0; mMaxFrameId = 0;
for(uint8_t i = 0; i < MAX_PAYLOAD_ENTRIES; i++) { for(uint8_t i = 0; i < MAX_PAYLOAD_ENTRIES; i++) {
mLocalBuf[i].len = 0; mLocalBuf[i].len = 0;
@ -108,16 +109,17 @@ class Communication : public CommQueue<> {
q->iv->radio->prepareDevInformCmd(q->iv, q->cmd, q->ts, q->iv->alarmLastId, false); q->iv->radio->prepareDevInformCmd(q->iv, q->cmd, q->ts, q->iv->alarmLastId, false);
q->iv->radioStatistics.txCnt++; q->iv->radioStatistics.txCnt++;
mWaitTimeout = millis() + timeout; mWaitTime.startTimeMonitor(timeout);
mWaitTimeout_min = millis() + timeout_min;
mIsRetransmit = false; mIsRetransmit = false;
mlastTO_min = timeout_min;
setAttempt(); setAttempt();
if((q->cmd == AlarmData) || (q->cmd == GridOnProFilePara))
incrAttempt(q->cmd == AlarmData? 5 : 3);
mState = States::WAIT; mState = States::WAIT;
break; break;
case States::WAIT: case States::WAIT:
if(millis() < mWaitTimeout) if (!mWaitTime.isTimeout())
return; return;
mState = States::CHECK_FRAMES; mState = States::CHECK_FRAMES;
break; break;
@ -127,13 +129,13 @@ class Communication : public CommQueue<> {
if(*mSerialDebug) { if(*mSerialDebug) {
DPRINT_IVID(DBG_INFO, q->iv->id); DPRINT_IVID(DBG_INFO, q->iv->id);
DBGPRINT(F("request timeout: ")); DBGPRINT(F("request timeout: "));
DBGPRINT(String(millis() - mWaitTimeout + timeout)); DBGPRINT(String(mWaitTime.getRunTime()));
DBGPRINTLN(F("ms")); DBGPRINTLN(F("ms"));
} }
if(!q->iv->mGotFragment) { if(!q->iv->mGotFragment) {
if((IV_HMS == q->iv->ivGen) || (IV_HMT == q->iv->ivGen)) { if((IV_HMS == q->iv->ivGen) || (IV_HMT == q->iv->ivGen)) {
q->iv->radio->switchFrequency(q->iv, HOY_BOOT_FREQ_KHZ, (q->iv->config->frequency*FREQ_STEP_KHZ + HOY_BASE_FREQ_KHZ)); q->iv->radio->switchFrequency(q->iv, HOY_BOOT_FREQ_KHZ, (q->iv->config->frequency*FREQ_STEP_KHZ + HOY_BASE_FREQ_KHZ));
mWaitTimeout = millis() + 1000; mWaitTime.startTimeMonitor(1000);
} }
} }
closeRequest(q, false); closeRequest(q, false);
@ -182,7 +184,7 @@ class Communication : public CommQueue<> {
bool fastNext = true; bool fastNext = true;
if(q->iv->miMultiParts < 6) { if(q->iv->miMultiParts < 6) {
mState = States::WAIT; mState = States::WAIT;
if((millis() > mWaitTimeout && mIsRetransmit) || !mIsRetransmit) { if((mWaitTime.isTimeout() && mIsRetransmit) || !mIsRetransmit) {
miRepeatRequest(q); miRepeatRequest(q);
return; return;
} }
@ -242,7 +244,6 @@ class Communication : public CommQueue<> {
q->iv->mIsSingleframeReq = true; q->iv->mIsSingleframeReq = true;
sendRetransmit(q, (framnr-1)); sendRetransmit(q, (framnr-1));
mIsRetransmit = true; mIsRetransmit = true;
mlastTO_min = timeout_min;
return; return;
} }
@ -446,7 +447,6 @@ class Communication : public CommQueue<> {
if(NULL == rec) { if(NULL == rec) {
if(GetLossRate == q->cmd) { if(GetLossRate == q->cmd) {
q->iv->parseGetLossRate(mPayload, len); q->iv->parseGetLossRate(mPayload, len);
//closeRequest(q, true); //@lumapu: Activating would crash most esp's!
return; return;
} else { } else {
DPRINTLN(DBG_ERROR, F("record is NULL!")); DPRINTLN(DBG_ERROR, F("record is NULL!"));
@ -490,7 +490,7 @@ class Communication : public CommQueue<> {
if(q->attempts) { if(q->attempts) {
q->iv->radio->sendCmdPacket(q->iv, TX_REQ_INFO, (SINGLE_FRAME + i), true); q->iv->radio->sendCmdPacket(q->iv, TX_REQ_INFO, (SINGLE_FRAME + i), true);
q->iv->radioStatistics.retransmits++; q->iv->radioStatistics.retransmits++;
mWaitTimeout = millis() + SINGLEFR_TIMEOUT; // timeout mWaitTime.startTimeMonitor(SINGLEFR_TIMEOUT); // timeout
mState = States::WAIT; mState = States::WAIT;
} else { } else {
//add(q, true); //add(q, true);
@ -507,7 +507,7 @@ class Communication : public CommQueue<> {
q->iv->radioStatistics.rxFail++; // got no complete payload q->iv->radioStatistics.rxFail++; // got no complete payload
else else
q->iv->radioStatistics.rxFailNoAnser++; // got nothing q->iv->radioStatistics.rxFailNoAnser++; // got nothing
mWaitTimeout = millis() + *mInverterGap; mWaitTime.startTimeMonitor(*mInverterGap);
bool keep = false; bool keep = false;
if(q->isDevControl) if(q->isDevControl)
@ -729,8 +729,7 @@ class Communication : public CommQueue<> {
//q->iv->radioStatistics.retransmits++; //q->iv->radioStatistics.retransmits++;
q->iv->radio->sendCmdPacket(q->iv, cmd, 0x00, true); q->iv->radio->sendCmdPacket(q->iv, cmd, 0x00, true);
mWaitTimeout = millis() + MI_TIMEOUT; mWaitTime.startTimeMonitor(MI_TIMEOUT);
mWaitTimeout_min = mWaitTimeout;
q->iv->miMultiParts = 0; q->iv->miMultiParts = 0;
q->iv->mGotFragment = 0; q->iv->mGotFragment = 0;
mIsRetransmit = true; mIsRetransmit = true;
@ -750,8 +749,7 @@ class Communication : public CommQueue<> {
q->iv->radio->sendCmdPacket(q->iv, q->cmd, 0x00, true); q->iv->radio->sendCmdPacket(q->iv, q->cmd, 0x00, true);
mWaitTimeout = millis() + MI_TIMEOUT; mWaitTime.startTimeMonitor(MI_TIMEOUT);
mWaitTimeout_min = mWaitTimeout;
//mState = States::WAIT; //mState = States::WAIT;
mIsRetransmit = false; mIsRetransmit = false;
} }
@ -885,12 +883,10 @@ class Communication : public CommQueue<> {
uint32_t *mTimestamp; uint32_t *mTimestamp;
bool *mPrivacyMode, *mSerialDebug, *mPrintWholeTrace; bool *mPrivacyMode, *mSerialDebug, *mPrintWholeTrace;
uint16_t *mInverterGap; uint16_t *mInverterGap;
uint32_t mWaitTimeout = 0; TimeMonitor mWaitTime = TimeMonitor(0, true); // start as expired (due to code in RESET state)
uint32_t mWaitTimeout_min = 0;
std::array<frame_t, MAX_PAYLOAD_ENTRIES> mLocalBuf; std::array<frame_t, MAX_PAYLOAD_ENTRIES> mLocalBuf;
bool mFirstTry = false; // see, if we should do a second try bool mFirstTry = false; // see, if we should do a second try
bool mIsRetransmit = false; // we alrady had waited one complete cycle bool mIsRetransmit = false; // we already had waited one complete cycle
uint16_t mlastTO_min = DEFAULT_TIMEOUT; // remember timeout_min for correct calculation
uint8_t mMaxFrameId; uint8_t mMaxFrameId;
uint8_t mPayload[MAX_BUFFER]; uint8_t mPayload[MAX_BUFFER];
payloadListenerType mCbPayload = NULL; payloadListenerType mCbPayload = NULL;

4
src/hm/hmRadio.h

@ -121,9 +121,10 @@ class HmRadio : public Radio {
uint32_t startMicros = micros(); uint32_t startMicros = micros();
uint32_t loopMillis = millis(); uint32_t loopMillis = millis();
uint32_t outerLoopTimeout = (mLastIv->mIsSingleframeReq) ? 100 : ((mLastIv->mCmd != AlarmData) ? 400 : 600); uint32_t outerLoopTimeout = (mLastIv->mIsSingleframeReq) ? 100 : ((mLastIv->mCmd != AlarmData) && (mLastIv->mCmd != GridOnProFilePara)) ? 400 : 600;
while ((millis() - loopMillis) < outerLoopTimeout) { while ((millis() - loopMillis) < outerLoopTimeout) {
startMicros = micros();
while ((micros() - startMicros) < 5110) { // listen (4088us or?) 5110us to each channel while ((micros() - startMicros) < 5110) { // listen (4088us or?) 5110us to each channel
if (mIrqRcvd) { if (mIrqRcvd) {
mIrqRcvd = false; mIrqRcvd = false;
@ -137,7 +138,6 @@ class HmRadio : public Radio {
// switch to next RX channel // switch to next RX channel
mRxChIdx = (mRxChIdx + 1) % RF_CHANNELS; mRxChIdx = (mRxChIdx + 1) % RF_CHANNELS;
mNrf24->setChannel(mRfChLst[mRxChIdx]); mNrf24->setChannel(mRfChLst[mRxChIdx]);
startMicros = micros();
} }
// not finished but time is over // not finished but time is over
mRxChIdx = (mRxChIdx + 1) % RF_CHANNELS; mRxChIdx = (mRxChIdx + 1) % RF_CHANNELS;

11
src/plugins/Display/Display_Mono.h

@ -19,6 +19,7 @@
#include "../../utils/helper.h" #include "../../utils/helper.h"
#include "Display_data.h" #include "Display_data.h"
#include "../../utils/dbg.h" #include "../../utils/dbg.h"
#include "../../utils/timemonitor.h"
class DisplayMono { class DisplayMono {
public: public:
@ -37,19 +38,19 @@ class DisplayMono {
if (mDisplayActive) { if (mDisplayActive) {
if (!dispConditions) { if (!dispConditions) {
if ((millis() - mStarttime) > DISP_DEFAULT_TIMEOUT * 1000ul) { // switch display off after timeout if (mDisplayTime.isTimeout()) { // switch display off after timeout
mDisplayActive = false; mDisplayActive = false;
mDisplay->setPowerSave(true); mDisplay->setPowerSave(true);
DBGPRINTLN("**** Display off ****"); DBGPRINTLN("**** Display off ****");
} }
} }
else else
mStarttime = millis(); // keep display on mDisplayTime.reStartTimeMonitor(); // keep display on
} }
else { else {
if (dispConditions) { if (dispConditions) {
mDisplayActive = true; // switch display on mDisplayActive = true;
mStarttime = millis(); mDisplayTime.reStartTimeMonitor(); // switch display on
mDisplay->setPowerSave(false); mDisplay->setPowerSave(false);
DBGPRINTLN("**** Display on ****"); DBGPRINTLN("**** Display on ****");
} }
@ -79,7 +80,7 @@ class DisplayMono {
uint8_t mExtra; uint8_t mExtra;
int8_t mPixelshift=0; int8_t mPixelshift=0;
uint32_t mStarttime = millis(); TimeMonitor mDisplayTime = TimeMonitor(1000 * 15, true);
bool mDisplayActive = true; // always start with display on bool mDisplayActive = true; // always start with display on
char mFmtText[DISP_FMT_TEXT_LEN]; char mFmtText[DISP_FMT_TEXT_LEN];

20
src/plugins/Display/Display_Mono_128X64.h

@ -49,9 +49,9 @@ class DisplayMono128X64 : public DisplayMono {
/* /*
mDisplayData->nrSleeping = 10; mDisplayData->nrSleeping = 10;
mDisplayData->nrProducing = 10; mDisplayData->nrProducing = 10;
mDisplayData->totalPower = 54321.9; // W mDisplayData->totalPower = 15432.9; // W
mDisplayData->totalYieldDay = 4321.9; // Wh mDisplayData->totalYieldDay = 14321.9; // Wh
mDisplayData->totalYieldTotal = 4321.9; // kWh mDisplayData->totalYieldTotal = 15432.9; // kWh
mDisplay->drawPixel(0, 0); mDisplay->drawPixel(0, 0);
mDisplay->drawPixel(mDispWidth-1, 0); mDisplay->drawPixel(mDispWidth-1, 0);
mDisplay->drawPixel(0, mDispHeight-1); mDisplay->drawPixel(0, mDispHeight-1);
@ -63,8 +63,8 @@ class DisplayMono128X64 : public DisplayMono {
// print total power // print total power
if (mDisplayData->nrProducing > 0) { if (mDisplayData->nrProducing > 0) {
if (mDisplayData->totalPower > 999) if (mDisplayData->totalPower > 9999.0)
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.1f kW", (mDisplayData->totalPower / 1000.0)); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.2f kW", (mDisplayData->totalPower / 1000.0));
else else
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.0f W", mDisplayData->totalPower); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.0f W", mDisplayData->totalPower);
@ -120,16 +120,16 @@ class DisplayMono128X64 : public DisplayMono {
mDisplay->drawStr(16 + mPixelshift, mLineYOffsets[l_YieldDay], "I"); // day symbol mDisplay->drawStr(16 + mPixelshift, mLineYOffsets[l_YieldDay], "I"); // day symbol
mDisplay->drawStr(16 + mPixelshift, mLineYOffsets[l_YieldTotal], "D"); // total symbol mDisplay->drawStr(16 + mPixelshift, mLineYOffsets[l_YieldTotal], "D"); // total symbol
if (mDisplayData->totalYieldDay > 999.0) if (mDisplayData->totalYieldDay > 9999.0)
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.1f kWh", mDisplayData->totalYieldDay / 1000.0); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.2f kWh", mDisplayData->totalYieldDay / 1000.0);
else else
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.0f Wh", mDisplayData->totalYieldDay); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.0f Wh", mDisplayData->totalYieldDay);
printText(mFmtText, l_YieldDay, 0xff); printText(mFmtText, l_YieldDay, 0xff);
if (mDisplayData->totalYieldTotal > 999.0) if (mDisplayData->totalYieldTotal > 9999.0)
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.1f MWh", mDisplayData->totalYieldTotal / 1000.0); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.2f MWh", mDisplayData->totalYieldTotal / 1000.0);
else else
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.1f kWh", mDisplayData->totalYieldTotal); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.0f kWh", mDisplayData->totalYieldTotal);
printText(mFmtText, l_YieldTotal, 0xff); printText(mFmtText, l_YieldTotal, 0xff);
// draw dynamic RSSI bars // draw dynamic RSSI bars

18
src/plugins/Display/Display_Mono_84X48.h

@ -36,8 +36,8 @@ class DisplayMono84X48 : public DisplayMono {
/* /*
mDisplayData->nrSleeping = 10; mDisplayData->nrSleeping = 10;
mDisplayData->nrProducing = 10; mDisplayData->nrProducing = 10;
mDisplayData->totalPower = 111.91; // W mDisplayData->totalPower = 19897.6; // W
mDisplayData->totalYieldDay = 54321.9; // Wh mDisplayData->totalYieldDay = 15521.9; // Wh
mDisplayData->totalYieldTotal = 654321.9; // kWh mDisplayData->totalYieldTotal = 654321.9; // kWh
mDisplay->drawPixel(0, 0); mDisplay->drawPixel(0, 0);
mDisplay->drawPixel(mDispWidth-1, 0); mDisplay->drawPixel(mDispWidth-1, 0);
@ -47,8 +47,8 @@ class DisplayMono84X48 : public DisplayMono {
// print total power // print total power
if (mDisplayData->nrProducing > 0) { if (mDisplayData->nrProducing > 0) {
if (mDisplayData->totalPower > 999) if (mDisplayData->totalPower > 9999.0)
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.1f kW", (mDisplayData->totalPower / 1000)); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.2f kW", (mDisplayData->totalPower / 1000.0));
else else
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.0f W", mDisplayData->totalPower); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.0f W", mDisplayData->totalPower);
@ -84,16 +84,16 @@ class DisplayMono84X48 : public DisplayMono {
printText("\x88", l_YieldDay, 10); // day symbol printText("\x88", l_YieldDay, 10); // day symbol
printText("\x83", l_YieldTotal, 10); // total symbol printText("\x83", l_YieldTotal, 10); // total symbol
if (mDisplayData->totalYieldDay > 999.0) if (mDisplayData->totalYieldDay > 9999.0)
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.1f kWh", mDisplayData->totalYieldDay / 1000.0); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.2f kWh", mDisplayData->totalYieldDay / 1000.0);
else else
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.0f Wh", mDisplayData->totalYieldDay); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.0f Wh", mDisplayData->totalYieldDay);
printText(mFmtText, l_YieldDay, 0xff); printText(mFmtText, l_YieldDay, 0xff);
if (mDisplayData->totalYieldTotal > 999.0) if (mDisplayData->totalYieldTotal > 9999.0)
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.1f MWh", mDisplayData->totalYieldTotal / 1000.0); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.2f MWh", mDisplayData->totalYieldTotal / 1000.0);
else else
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.1f kWh", mDisplayData->totalYieldTotal); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.0f kWh", mDisplayData->totalYieldTotal);
printText(mFmtText, l_YieldTotal, 0xff); printText(mFmtText, l_YieldTotal, 0xff);
// draw dynamic Nokia RSSI bars // draw dynamic Nokia RSSI bars

126
src/utils/timemonitor.h

@ -0,0 +1,126 @@
//-----------------------------------------------------------
// You69Man, 2023
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// version 2 as published by the Free Software Foundation.
//-----------------------------------------------------------
/**
* @file timemonitor.h
*
* Class declaration for TimeMonitor
*/
#ifndef __TIMEMONITOR_H__
#define __TIMEMONITOR_H__
#include <Arduino.h>
class TimeMonitor {
public:
/**
* A constructor for initializing a TimeMonitor
* @note TimeMonitor witch default constructor is stopped
*/
TimeMonitor(void) {}
/**
* A constructor for initializing a TimeMonitor
* @param timeout timeout in ms
* @param start (optional) if true, start TimeMonitor immediately
* @note TimeMonitor witch default constructor is stopped
*/
TimeMonitor(uint32_t timeout, bool start = false) {
if (start)
startTimeMonitor(timeout);
else
configureTimeMonitor(timeout);
}
/**
* Start the TimeMonitor with new timeout configuration
* @param timeout timout in ms
*/
void startTimeMonitor(uint32_t timeout) {
mStartTime = millis();
mTimeout = timeout;
mStarted = true;
}
/**
* Restart the TimeMonitor with already set timeout configuration
* @note returns nothing
*/
void reStartTimeMonitor(void) {
mStartTime = millis();
mStarted = true;
}
/**
* Configure the TimeMonitor to new timeout configuration
* @param timeout timeout in ms
* @note This doesn't restart an already running TimeMonitor.
* If timer is already running and new timeout is longer that current timeout runtime of the running timer is expanded
* If timer is already running and new timeout is shorter that current timeout this can immediately lead to a timeout
*/
void configureTimeMonitor(uint32_t timeout) {
mTimeout = timeout;
}
/**
* Stop the TimeMonitor
*/
void stopTimeMonitor(void) {
mStarted = false;
}
/**
* Get timeout status of the TimeMonitor
* @return bool
* true: TimeMonitor already timed out
* false: TimeMonitor still in time or TimeMonitor was stopped
*/
bool isTimeout(void) {
if ((mStarted) && (millis() - mStartTime >= mTimeout))
return true;
else
return false;
}
/**
* Get timeout configuration of the TimeMonitor
* @return uint32_t timeout value in ms
*/
uint32_t getTimeout(void) const {
return mTimeout;
}
/**
* Get residual time of the TimeMonitor until timeout
* @return uint32_t residual time until timeout in ms
* @note in case of a stopped TimeMonitor residual time is always 0xFFFFFFFFUL
* in case of a timed out TimeMonitor residual time is always 0UL (zero)
*/
uint32_t getResidualTime(void) const {
uint32_t delayed = millis() - mStartTime;
return(mStarted ? (delayed < mTimeout ? mTimeout - delayed : 0UL) : 0xFFFFFFFFUL);
}
/**
* Get overall run time of the TimeMonitor
* @return uint32_t residual time until timeout in ms
* @note in case of a stopped TimeMonitor residual time is always 0xFFFFFFFFUL
* in case of a timed out TimeMonitor residual time is always 0UL (zero)
*/
uint32_t getRunTime(void) const {
return(mStarted ? millis() - mStartTime : 0UL);
}
private:
uint32_t mStartTime = 0UL; // start time of the TimeMonitor
uint32_t mTimeout = 0UL; // timeout configuration of the TimeMonitor
bool mStarted = false; // start/stop state of the TimeMonitor
};
#endif

1
src/web/html/grid_info.json

@ -159,6 +159,7 @@
{ {
"name": "Nominal Voltage", "name": "Nominal Voltage",
"div": 10, "div": 10,
"def": 230,
"unit": "V" "unit": "V"
}, },
{ {

20
src/web/html/setup.html

@ -944,10 +944,12 @@
function parsePinout(obj, type, system) { function parsePinout(obj, type, system) {
var e = document.getElementById("pinout"); var e = document.getElementById("pinout");
var pinList = esp8266pins;
/*IF_ESP32*/
var pinList = esp32pins; var pinList = esp32pins;
if("ESP8266" == type) pinList = esp8266pins; if ("ESP32-S3" == system.chip_model) pinList = esp32s3pins;
else if ("ESP32-S3" == system["chip_model"]) pinList = esp32s3pins;
else if("ESP32-C3" == system["chip_model"]) pinList = esp32c3pins; else if("ESP32-C3" == system["chip_model"]) pinList = esp32c3pins;
/*ENDIF_ESP32*/
pins = [['led0', 'pinLed0', 'At least one inverter is producing'], ['led1', 'pinLed1', 'MqTT connected']]; pins = [['led0', 'pinLed0', 'At least one inverter is producing'], ['led1', 'pinLed1', 'MqTT connected']];
for(p of pins) { for(p of pins) {
e.append( e.append(
@ -974,10 +976,12 @@
var en = inp("nrfEnable", null, null, ["cb"], "nrfEnable", "checkbox"); var en = inp("nrfEnable", null, null, ["cb"], "nrfEnable", "checkbox");
en.checked = obj["en"]; en.checked = obj["en"];
var pinList = esp8266pins;
/*IF_ESP32*/
var pinList = esp32pins; var pinList = esp32pins;
if("ESP8266" == type) pinList = esp8266pins; if ("ESP32-S3" == system.chip_model) pinList = esp32s3pins;
else if ("ESP32-S3" == system["chip_model"]) pinList = esp32s3pins;
else if("ESP32-C3" == system["chip_model"]) pinList = esp32c3pins; else if("ESP32-C3" == system["chip_model"]) pinList = esp32c3pins;
/*ENDIF_ESP32*/
e.replaceChildren ( e.replaceChildren (
ml("div", {class: "row mb-3"}, [ ml("div", {class: "row mb-3"}, [
@ -1039,10 +1043,12 @@
} }
function parseDisplay(obj, type, system) { function parseDisplay(obj, type, system) {
var pinList = esp8266pins;
/*IF_ESP32*/
var pinList = esp32pins; var pinList = esp32pins;
if("ESP8266" == type) pinList = esp8266pirpins; if ("ESP32-S3" == system.chip_model) pinList = esp32s3pins;
else if ("ESP32-S3" == system["chip_model"]) pinList = esp32s3pins;
else if("ESP32-C3" == system["chip_model"]) pinList = esp32c3pins; else if("ESP32-C3" == system["chip_model"]) pinList = esp32c3pins;
/*ENDIF_ESP32*/
for(var i of ["disp_pwr"]) for(var i of ["disp_pwr"])
document.getElementsByName(i)[0].checked = obj[i]; document.getElementsByName(i)[0].checked = obj[i];
@ -1108,7 +1114,7 @@
document.getElementById("pirPin").append( document.getElementById("pirPin").append(
ml("div", {class: "row mb-3"}, [ ml("div", {class: "row mb-3"}, [
ml("div", {class: "col-12 col-sm-3 my-2"}, "PIR sensor"), ml("div", {class: "col-12 col-sm-3 my-2"}, "PIR sensor"),
ml("div", {class: "col-12 col-sm-9"}, sel("pir_pin", pinList, obj["pir_pin"])) ml("div", {class: "col-12 col-sm-9"}, sel("pir_pin", ("ESP8266" == type) ? esp8266pirpins : pinList, obj["pir_pin"]))
]) ])
); );

9
src/web/html/visualization.html

@ -356,13 +356,20 @@
getJSON("/grid_info.json").then(data => { getJSON("/grid_info.json").then(data => {
var glob = {offs:0, grid:obj.grid, info: data} var glob = {offs:0, grid:obj.grid, info: data}
var content = []; var content = [];
var g = getGridType(glob.info.type, getGridIdentifier(glob))
if(null === g) {
content.push(ml("div", {class: "row"}, ml("div", {class: "col"}, ml("h5", {}, "Unknown Profile"))))
content.push(ml("div", {class: "row"}, ml("div", {class: "col"}, ml("p", {}, "Please open a new issue at https://github.com/lumapu/ahoy and copy the raw data into it."))))
content.push(ml("div", {class: "row"}, ml("div", {class: "col my-2"}, ml("pre", {}, obj.grid))))
} else {
content.push(ml("div", {class: "row"}, content.push(ml("div", {class: "row"},
ml("div", {class: "col my-3"}, ml("h5", {}, getGridType(glob.info.type, getGridIdentifier(glob)) + " (Version " + getGridValue(glob).toString(16) + ")")) ml("div", {class: "col my-3"}, ml("h5", {}, g + " (Version " + getGridValue(glob).toString(16) + ")"))
)) ))
while((glob.offs*3) < glob.grid.length) { while((glob.offs*3) < glob.grid.length) {
content.push(parseGridGroup(glob)) content.push(parseGridGroup(glob))
} }
}
modal("Grid Profile for inverter " + obj.name, ml("div", {}, ml("div", {class: "col mb-2"}, [...content]))) modal("Grid Profile for inverter " + obj.name, ml("div", {}, ml("div", {class: "col mb-2"}, [...content])))
}) })

Loading…
Cancel
Save