mirror of
https://github.com/lumapu/ahoy.git
synced 2025-06-07 13:11:38 +02:00
0.8.76
* revert changes from yesterday regarding snprintf and its size #1410, #1411 * reduced cppcheck linter warnings significantly * try to improve ePaper (ghosting) #1107
This commit is contained in:
parent
c447049e84
commit
7c532ca1cc
23 changed files with 164 additions and 158 deletions
|
@ -1,5 +1,10 @@
|
||||||
# Development Changes
|
# Development Changes
|
||||||
|
|
||||||
|
## 0.8.76 - 2024-02-07
|
||||||
|
* revert changes from yesterday regarding snprintf and its size #1410, #1411
|
||||||
|
* reduced cppcheck linter warnings significantly
|
||||||
|
* try to improve ePaper (ghosting) #1107
|
||||||
|
|
||||||
## 0.8.75 - 2024-02-06
|
## 0.8.75 - 2024-02-06
|
||||||
* fix active power control value #1406, #1409
|
* fix active power control value #1406, #1409
|
||||||
* update Mqtt lib to version `1.6.0`
|
* update Mqtt lib to version `1.6.0`
|
||||||
|
|
|
@ -264,11 +264,10 @@ void app::tickNtpUpdate(void) {
|
||||||
#endif
|
#endif
|
||||||
if (isOK) {
|
if (isOK) {
|
||||||
this->updateNtp();
|
this->updateNtp();
|
||||||
|
nxtTrig = mConfig->ntp.interval * 60; // check again in 12h
|
||||||
nxtTrig = isOK ? (mConfig->ntp.interval * 60) : 60; // depending on NTP update success check again in 12h (depends on setting) or in 1 min
|
|
||||||
|
|
||||||
// immediately start communicating
|
// immediately start communicating
|
||||||
if (isOK && mSendFirst) {
|
if (mSendFirst) {
|
||||||
mSendFirst = false;
|
mSendFirst = false;
|
||||||
once(std::bind(&app::tickSend, this), 1, "senOn");
|
once(std::bind(&app::tickSend, this), 1, "senOn");
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
#define VERSION_MAJOR 0
|
#define VERSION_MAJOR 0
|
||||||
#define VERSION_MINOR 8
|
#define VERSION_MINOR 8
|
||||||
#define VERSION_PATCH 75
|
#define VERSION_PATCH 76
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -698,7 +698,7 @@ class Communication : public CommQueue<> {
|
||||||
byte[23] to byte[26] Matching_APPFW_PN*/
|
byte[23] to byte[26] Matching_APPFW_PN*/
|
||||||
DPRINT(DBG_INFO,F("HW_PartNo "));
|
DPRINT(DBG_INFO,F("HW_PartNo "));
|
||||||
DBGPRINTLN(String((uint32_t) (((p->packet[10] << 8) | p->packet[11]) << 8 | p->packet[12]) << 8 | p->packet[13]));
|
DBGPRINTLN(String((uint32_t) (((p->packet[10] << 8) | p->packet[11]) << 8 | p->packet[12]) << 8 | p->packet[13]));
|
||||||
record_t<> *rec = q->iv->getRecordStruct(InverterDevInform_Simple); // choose the record structure
|
rec = q->iv->getRecordStruct(InverterDevInform_Simple); // choose the record structure
|
||||||
rec->ts = q->ts;
|
rec->ts = q->ts;
|
||||||
q->iv->setValue(0, rec, (uint32_t) ((((p->packet[10] << 8) | p->packet[11]) << 8 | p->packet[12]) << 8 | p->packet[13])/1);
|
q->iv->setValue(0, rec, (uint32_t) ((((p->packet[10] << 8) | p->packet[11]) << 8 | p->packet[12]) << 8 | p->packet[13])/1);
|
||||||
rec->mqttSentStatus = MqttSentStatus::NEW_DATA;
|
rec->mqttSentStatus = MqttSentStatus::NEW_DATA;
|
||||||
|
@ -899,14 +899,16 @@ class Communication : public CommQueue<> {
|
||||||
q->iv->alarmCnt = 1; // minimum...
|
q->iv->alarmCnt = 1; // minimum...
|
||||||
stsok = false;
|
stsok = false;
|
||||||
//sth is or was wrong?
|
//sth is or was wrong?
|
||||||
if ( (q->iv->type != INV_TYPE_1CH) && ( (statusMi != 3)
|
if ((q->iv->type != INV_TYPE_1CH)
|
||||||
|| ((q->iv->lastAlarm[stschan].code) && (statusMi == 3) && (q->iv->lastAlarm[stschan].code != 1)))
|
&& ((statusMi != 3)
|
||||||
|
|| ((q->iv->lastAlarm[stschan].code) && (q->iv->lastAlarm[stschan].code != 1)))
|
||||||
) {
|
) {
|
||||||
q->iv->lastAlarm[stschan+q->iv->type==INV_TYPE_2CH ? 2: 4] = alarm_t(q->iv->lastAlarm[stschan].code, q->iv->lastAlarm[stschan].start,q->ts);
|
q->iv->lastAlarm[stschan+q->iv->type==INV_TYPE_2CH ? 2: 4] = alarm_t(q->iv->lastAlarm[stschan].code, q->iv->lastAlarm[stschan].start,q->ts);
|
||||||
q->iv->lastAlarm[stschan] = alarm_t(prntsts, q->ts,0);
|
q->iv->lastAlarm[stschan] = alarm_t(prntsts, q->ts,0);
|
||||||
q->iv->alarmCnt = q->iv->type == INV_TYPE_2CH ? 3 : 5;
|
q->iv->alarmCnt = q->iv->type == INV_TYPE_2CH ? 3 : 5;
|
||||||
} else if ( (q->iv->type == INV_TYPE_1CH) && ( (statusMi != 3)
|
} else if ((q->iv->type == INV_TYPE_1CH)
|
||||||
|| ((q->iv->lastAlarm[stschan].code) && (statusMi == 3) && (q->iv->lastAlarm[stschan].code != 1)))
|
&& ( (statusMi != 3)
|
||||||
|
|| ((q->iv->lastAlarm[stschan].code) && (q->iv->lastAlarm[stschan].code != 1)))
|
||||||
) {
|
) {
|
||||||
q->iv->lastAlarm[stschan] = alarm_t(q->iv->lastAlarm[0].code, q->iv->lastAlarm[0].start,q->ts);
|
q->iv->lastAlarm[stschan] = alarm_t(q->iv->lastAlarm[0].code, q->iv->lastAlarm[0].start,q->ts);
|
||||||
} else if (q->iv->type == INV_TYPE_1CH)
|
} else if (q->iv->type == INV_TYPE_1CH)
|
||||||
|
@ -962,7 +964,7 @@ class Communication : public CommQueue<> {
|
||||||
iv->radioStatistics.ivLoss = iv->radioStatistics.ivSent - iv->mDtuRxCnt; // this is what we didn't receive
|
iv->radioStatistics.ivLoss = iv->radioStatistics.ivSent - iv->mDtuRxCnt; // this is what we didn't receive
|
||||||
iv->radioStatistics.dtuLoss = iv->mIvTxCnt; // this is somehow the requests w/o answers in that periode
|
iv->radioStatistics.dtuLoss = iv->mIvTxCnt; // this is somehow the requests w/o answers in that periode
|
||||||
iv->radioStatistics.dtuSent = iv->mDtuTxCnt;
|
iv->radioStatistics.dtuSent = iv->mDtuTxCnt;
|
||||||
if (mSerialDebug) {
|
if (*mSerialDebug) {
|
||||||
DPRINT_IVID(DBG_INFO, iv->id);
|
DPRINT_IVID(DBG_INFO, iv->id);
|
||||||
DBGPRINTLN("DTU loss: " +
|
DBGPRINTLN("DTU loss: " +
|
||||||
String (iv->radioStatistics.ivLoss) + "/" +
|
String (iv->radioStatistics.ivLoss) + "/" +
|
||||||
|
|
|
@ -132,7 +132,7 @@ class Heuristic {
|
||||||
ih->lastRxFragments = rxFragments;
|
ih->lastRxFragments = rxFragments;
|
||||||
}
|
}
|
||||||
|
|
||||||
void printStatus(Inverter<> *iv) {
|
void printStatus(const Inverter<> *iv) {
|
||||||
DPRINT_IVID(DBG_INFO, iv->id);
|
DPRINT_IVID(DBG_INFO, iv->id);
|
||||||
DBGPRINT(F("Radio infos:"));
|
DBGPRINT(F("Radio infos:"));
|
||||||
if((IV_HMS != iv->ivGen) && (IV_HMT != iv->ivGen)) {
|
if((IV_HMS != iv->ivGen) && (IV_HMT != iv->ivGen)) {
|
||||||
|
|
|
@ -395,9 +395,9 @@ class HmRadio : public Radio {
|
||||||
#endif*/
|
#endif*/
|
||||||
if(*mPrintWholeTrace) {
|
if(*mPrintWholeTrace) {
|
||||||
if(*mPrivacyMode)
|
if(*mPrivacyMode)
|
||||||
ah::dumpBuf(mTxBuf, len, 1, 4);
|
ah::dumpBuf(mTxBuf.data(), len, 1, 4);
|
||||||
else
|
else
|
||||||
ah::dumpBuf(mTxBuf, len);
|
ah::dumpBuf(mTxBuf.data(), len);
|
||||||
} else {
|
} else {
|
||||||
DHEX(mTxBuf[0]);
|
DHEX(mTxBuf[0]);
|
||||||
DBGPRINT(F(" "));
|
DBGPRINT(F(" "));
|
||||||
|
@ -415,7 +415,7 @@ class HmRadio : public Radio {
|
||||||
}
|
}
|
||||||
mNrf24->setChannel(mRfChLst[mTxChIdx]);
|
mNrf24->setChannel(mRfChLst[mTxChIdx]);
|
||||||
mNrf24->openWritingPipe(reinterpret_cast<uint8_t*>(&iv->radioId.u64));
|
mNrf24->openWritingPipe(reinterpret_cast<uint8_t*>(&iv->radioId.u64));
|
||||||
mNrf24->startWrite(mTxBuf, len, false); // false = request ACK response
|
mNrf24->startWrite(mTxBuf.data(), len, false); // false = request ACK response
|
||||||
mMillis = millis();
|
mMillis = millis();
|
||||||
|
|
||||||
mLastIv = iv;
|
mLastIv = iv;
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#define ALL_FRAMES 0x80
|
#define ALL_FRAMES 0x80
|
||||||
#define SINGLE_FRAME 0x81
|
#define SINGLE_FRAME 0x81
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include "../utils/dbg.h"
|
#include "../utils/dbg.h"
|
||||||
#include "../utils/crc.h"
|
#include "../utils/crc.h"
|
||||||
|
@ -34,6 +35,8 @@ class Radio {
|
||||||
virtual std::pair<uint16_t,uint16_t> getFreqRangeMhz(void) { return std::make_pair(0, 0); }
|
virtual std::pair<uint16_t,uint16_t> getFreqRangeMhz(void) { return std::make_pair(0, 0); }
|
||||||
virtual bool loop(void) = 0;
|
virtual bool loop(void) = 0;
|
||||||
|
|
||||||
|
Radio() : mTxBuf{} {}
|
||||||
|
|
||||||
void handleIntr(void) {
|
void handleIntr(void) {
|
||||||
mIrqRcvd = true;
|
mIrqRcvd = true;
|
||||||
mIrqOk = IRQ_OK;
|
mIrqOk = IRQ_OK;
|
||||||
|
@ -107,7 +110,7 @@ class Radio {
|
||||||
mTxBuf[(*len)++] = (crc ) & 0xff;
|
mTxBuf[(*len)++] = (crc ) & 0xff;
|
||||||
}
|
}
|
||||||
// crc over all
|
// crc over all
|
||||||
mTxBuf[*len] = ah::crc8(mTxBuf, *len);
|
mTxBuf[*len] = ah::crc8(mTxBuf.data(), *len);
|
||||||
(*len)++;
|
(*len)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,12 +132,11 @@ class Radio {
|
||||||
mDtuSn |= 0x80000000; // the first digit is an 8 for DTU production year 2022, the rest is filled with the ESP chipID in decimal
|
mDtuSn |= 0x80000000; // the first digit is an 8 for DTU production year 2022, the rest is filled with the ESP chipID in decimal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uint32_t mDtuSn = 0;
|
||||||
uint32_t mDtuSn;
|
std::atomic<bool> mIrqRcvd = false;
|
||||||
std::atomic<bool> mIrqRcvd;
|
|
||||||
bool *mSerialDebug = nullptr, *mPrivacyMode = nullptr, *mPrintWholeTrace = nullptr;
|
bool *mSerialDebug = nullptr, *mPrivacyMode = nullptr, *mPrintWholeTrace = nullptr;
|
||||||
uint8_t mTxBuf[MAX_RF_PAYLOAD_SIZE];
|
std::array<uint8_t, MAX_RF_PAYLOAD_SIZE> mTxBuf;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /*__RADIO_H__*/
|
#endif /*__RADIO_H__*/
|
||||||
|
|
|
@ -118,9 +118,9 @@ class Simulator {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HMSYSTEM *mSys;
|
HMSYSTEM *mSys = nullptr;
|
||||||
uint8_t mIvId;
|
uint8_t mIvId = 0;
|
||||||
uint32_t *mTimestamp;
|
uint32_t *mTimestamp = nullptr;
|
||||||
payloadListenerType mCbPayload = nullptr;
|
payloadListenerType mCbPayload = nullptr;
|
||||||
uint8_t payloadCtrl = 0;
|
uint8_t payloadCtrl = 0;
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ class CmtRadio : public Radio {
|
||||||
mPrivacyMode = privacyMode;
|
mPrivacyMode = privacyMode;
|
||||||
mSerialDebug = serialDebug;
|
mSerialDebug = serialDebug;
|
||||||
mPrintWholeTrace = printWholeTrace;
|
mPrintWholeTrace = printWholeTrace;
|
||||||
|
mTxBuf.fill(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool loop() override {
|
bool loop() override {
|
||||||
|
@ -102,9 +103,9 @@ class CmtRadio : public Radio {
|
||||||
DBGPRINT(F("Mhz | "));
|
DBGPRINT(F("Mhz | "));
|
||||||
if(*mPrintWholeTrace) {
|
if(*mPrintWholeTrace) {
|
||||||
if(*mPrivacyMode)
|
if(*mPrivacyMode)
|
||||||
ah::dumpBuf(mTxBuf, len, 1, 4);
|
ah::dumpBuf(mTxBuf.data(), len, 1, 4);
|
||||||
else
|
else
|
||||||
ah::dumpBuf(mTxBuf, len);
|
ah::dumpBuf(mTxBuf.data(), len);
|
||||||
} else {
|
} else {
|
||||||
DHEX(mTxBuf[0]);
|
DHEX(mTxBuf[0]);
|
||||||
DBGPRINT(F(" "));
|
DBGPRINT(F(" "));
|
||||||
|
@ -114,7 +115,7 @@ class CmtRadio : public Radio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CmtStatus status = mCmt.tx(mTxBuf, len);
|
CmtStatus status = mCmt.tx(mTxBuf.data(), len);
|
||||||
mMillis = millis();
|
mMillis = millis();
|
||||||
if(CmtStatus::SUCCESS != status) {
|
if(CmtStatus::SUCCESS != status) {
|
||||||
DPRINT(DBG_WARN, F("CMT TX failed, code: "));
|
DPRINT(DBG_WARN, F("CMT TX failed, code: "));
|
||||||
|
|
|
@ -223,21 +223,21 @@ class Display {
|
||||||
}
|
}
|
||||||
|
|
||||||
// private member variables
|
// private member variables
|
||||||
IApp *mApp;
|
IApp *mApp = nullptr;
|
||||||
DisplayData mDisplayData;
|
DisplayData mDisplayData;
|
||||||
bool mNewPayload;
|
bool mNewPayload = false;
|
||||||
uint8_t mLoopCnt;
|
uint8_t mLoopCnt = 0;
|
||||||
uint32_t *mUtcTs;
|
uint32_t *mUtcTs = nullptr;
|
||||||
display_t *mCfg;
|
display_t *mCfg = nullptr;
|
||||||
HMSYSTEM *mSys;
|
HMSYSTEM *mSys = nullptr;
|
||||||
RADIO *mHmRadio;
|
RADIO *mHmRadio = nullptr;
|
||||||
RADIO *mHmsRadio;
|
RADIO *mHmsRadio = nullptr;
|
||||||
uint16_t mRefreshCycle;
|
uint16_t mRefreshCycle = 0;
|
||||||
|
|
||||||
#if defined(ESP32) && !defined(ETHERNET)
|
#if defined(ESP32) && !defined(ETHERNET)
|
||||||
DisplayEPaper mEpaper;
|
DisplayEPaper mEpaper;
|
||||||
#endif
|
#endif
|
||||||
DisplayMono *mMono;
|
DisplayMono *mMono = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /*PLUGIN_DISPLAY*/
|
#endif /*PLUGIN_DISPLAY*/
|
||||||
|
|
|
@ -12,11 +12,11 @@ class DisplayMono128X32 : public DisplayMono {
|
||||||
mExtra = 0;
|
mExtra = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void config(display_t *cfg) {
|
void config(display_t *cfg) override {
|
||||||
mCfg = cfg;
|
mCfg = cfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init(DisplayData *displayData) {
|
void init(DisplayData *displayData) override {
|
||||||
u8g2_cb_t *rot = (u8g2_cb_t *)((mCfg->rot != 0x00) ? U8G2_R2 : U8G2_R0);
|
u8g2_cb_t *rot = (u8g2_cb_t *)((mCfg->rot != 0x00) ? U8G2_R2 : U8G2_R0);
|
||||||
monoInit(new U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C(rot, 0xff, mCfg->disp_clk, mCfg->disp_data), displayData);
|
monoInit(new U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C(rot, 0xff, mCfg->disp_clk, mCfg->disp_data), displayData);
|
||||||
calcLinePositions();
|
calcLinePositions();
|
||||||
|
@ -26,7 +26,7 @@ class DisplayMono128X32 : public DisplayMono {
|
||||||
mDisplay->sendBuffer();
|
mDisplay->sendBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void disp(void) {
|
void disp(void) override {
|
||||||
mDisplay->clearBuffer();
|
mDisplay->clearBuffer();
|
||||||
|
|
||||||
// calculate current pixelshift for pixelshift screensaver
|
// calculate current pixelshift for pixelshift screensaver
|
||||||
|
|
|
@ -13,11 +13,11 @@ class DisplayMono128X64 : public DisplayMono {
|
||||||
mExtra = 0;
|
mExtra = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void config(display_t *cfg) {
|
void config(display_t *cfg) override {
|
||||||
mCfg = cfg;
|
mCfg = cfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init(DisplayData *displayData) {
|
void init(DisplayData *displayData) override {
|
||||||
u8g2_cb_t *rot = (u8g2_cb_t *)(( mCfg->rot != 0x00) ? U8G2_R2 : U8G2_R0);
|
u8g2_cb_t *rot = (u8g2_cb_t *)(( mCfg->rot != 0x00) ? U8G2_R2 : U8G2_R0);
|
||||||
switch (mCfg->type) {
|
switch (mCfg->type) {
|
||||||
case DISP_TYPE_T1_SSD1306_128X64:
|
case DISP_TYPE_T1_SSD1306_128X64:
|
||||||
|
@ -68,9 +68,7 @@ class DisplayMono128X64 : public DisplayMono {
|
||||||
mDisplay->sendBuffer();
|
mDisplay->sendBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void disp(void) {
|
void disp(void) override {
|
||||||
uint8_t pos, sun_pos, moon_pos;
|
|
||||||
|
|
||||||
mDisplay->clearBuffer();
|
mDisplay->clearBuffer();
|
||||||
|
|
||||||
// Layout-Test
|
// Layout-Test
|
||||||
|
@ -106,8 +104,8 @@ class DisplayMono128X64 : public DisplayMono {
|
||||||
}
|
}
|
||||||
// print status of inverters
|
// print status of inverters
|
||||||
else {
|
else {
|
||||||
sun_pos = -1;
|
int8_t sun_pos = -1;
|
||||||
moon_pos = -1;
|
int8_t moon_pos = -1;
|
||||||
setLineFont(l_Status);
|
setLineFont(l_Status);
|
||||||
if (0 == mDisplayData->nrSleeping + mDisplayData->nrProducing)
|
if (0 == mDisplayData->nrSleeping + mDisplayData->nrProducing)
|
||||||
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "no inverter");
|
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "no inverter");
|
||||||
|
@ -128,11 +126,11 @@ class DisplayMono128X64 : public DisplayMono {
|
||||||
}
|
}
|
||||||
printText(mFmtText, l_Status, 0xff);
|
printText(mFmtText, l_Status, 0xff);
|
||||||
|
|
||||||
pos = (mDispWidth - mDisplay->getStrWidth(mFmtText)) / 2;
|
uint8_t pos = (mDispWidth - mDisplay->getStrWidth(mFmtText)) / 2;
|
||||||
mDisplay->setFont(u8g2_font_ncenB08_symbols8_ahoy);
|
mDisplay->setFont(u8g2_font_ncenB08_symbols8_ahoy);
|
||||||
if (sun_pos!=-1)
|
if (sun_pos != -1)
|
||||||
mDisplay->drawStr(pos + sun_pos + mPixelshift, mLineYOffsets[l_Status], "G"); // sun symbol
|
mDisplay->drawStr(pos + sun_pos + mPixelshift, mLineYOffsets[l_Status], "G"); // sun symbol
|
||||||
if (moon_pos!=-1)
|
if (moon_pos != -1)
|
||||||
mDisplay->drawStr(pos + moon_pos + mPixelshift, mLineYOffsets[l_Status], "H"); // moon symbol
|
mDisplay->drawStr(pos + moon_pos + mPixelshift, mLineYOffsets[l_Status], "H"); // moon symbol
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,12 +179,11 @@ class DisplayMono128X64 : public DisplayMono {
|
||||||
// draw dynamic RSSI bars
|
// draw dynamic RSSI bars
|
||||||
int rssi_bar_height = 9;
|
int rssi_bar_height = 9;
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
int radio_rssi_threshold = -60 - i * 10;
|
int rssi_threshold = -60 - i * 10;
|
||||||
int wifi_rssi_threshold = -60 - i * 10;
|
|
||||||
uint8_t barwidth = std::min(4 - i, 3);
|
uint8_t barwidth = std::min(4 - i, 3);
|
||||||
if (mDisplayData->RadioRSSI > radio_rssi_threshold)
|
if (mDisplayData->RadioRSSI > rssi_threshold)
|
||||||
mDisplay->drawBox(widthShrink / 2 + mPixelshift, 8 + (rssi_bar_height + 1) * i, barwidth, rssi_bar_height);
|
mDisplay->drawBox(widthShrink / 2 + mPixelshift, 8 + (rssi_bar_height + 1) * i, barwidth, rssi_bar_height);
|
||||||
if (mDisplayData->WifiRSSI > wifi_rssi_threshold)
|
if (mDisplayData->WifiRSSI > rssi_threshold)
|
||||||
mDisplay->drawBox(mDispWidth - barwidth - widthShrink / 2 + mPixelshift, 8 + (rssi_bar_height + 1) * i, barwidth, rssi_bar_height);
|
mDisplay->drawBox(mDispWidth - barwidth - widthShrink / 2 + mPixelshift, 8 + (rssi_bar_height + 1) * i, barwidth, rssi_bar_height);
|
||||||
}
|
}
|
||||||
// draw dynamic antenna and WiFi symbols
|
// draw dynamic antenna and WiFi symbols
|
||||||
|
@ -223,23 +220,22 @@ class DisplayMono128X64 : public DisplayMono {
|
||||||
l_MAX_LINES = 5,
|
l_MAX_LINES = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t graph_first_line;
|
uint8_t graph_first_line = 0;
|
||||||
uint8_t graph_last_line;
|
uint8_t graph_last_line = 0;
|
||||||
|
|
||||||
const uint8_t pixelShiftRange = 11; // number of pixels to shift from left to right (centered -> must be odd!)
|
const uint8_t pixelShiftRange = 11; // number of pixels to shift from left to right (centered -> must be odd!)
|
||||||
uint8_t widthShrink;
|
uint8_t widthShrink = 0;
|
||||||
|
|
||||||
void calcLinePositions() {
|
void calcLinePositions() {
|
||||||
uint8_t yOff = 0;
|
uint8_t yOff = 0;
|
||||||
uint8_t i = 0;
|
uint8_t i = 0;
|
||||||
uint8_t asc, dsc;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
setLineFont(i);
|
setLineFont(i);
|
||||||
asc = mDisplay->getAscent();
|
uint8_t asc = mDisplay->getAscent();
|
||||||
yOff += asc;
|
yOff += asc;
|
||||||
mLineYOffsets[i] = yOff;
|
mLineYOffsets[i] = yOff;
|
||||||
dsc = mDisplay->getDescent();
|
uint8_t dsc = mDisplay->getDescent();
|
||||||
yOff -= dsc;
|
yOff -= dsc;
|
||||||
if (l_Time == i) // prevent time and status line to touch
|
if (l_Time == i) // prevent time and status line to touch
|
||||||
yOff++; // -> one pixels space
|
yOff++; // -> one pixels space
|
||||||
|
@ -248,8 +244,7 @@ class DisplayMono128X64 : public DisplayMono {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void setLineFont(uint8_t line) {
|
inline void setLineFont(uint8_t line) {
|
||||||
if ((line == l_TotalPower) ||
|
if (line == l_TotalPower) // || (line == l_Ahoy) -> l_TotalPower == l_Ahoy == 2
|
||||||
(line == l_Ahoy))
|
|
||||||
mDisplay->setFont(u8g2_font_ncenB14_tr);
|
mDisplay->setFont(u8g2_font_ncenB14_tr);
|
||||||
else if ((line == l_YieldDay) ||
|
else if ((line == l_YieldDay) ||
|
||||||
(line == l_YieldTotal))
|
(line == l_YieldTotal))
|
||||||
|
|
|
@ -12,11 +12,11 @@ class DisplayMono64X48 : public DisplayMono {
|
||||||
mExtra = 0;
|
mExtra = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void config(display_t *cfg) {
|
void config(display_t *cfg) override {
|
||||||
mCfg = cfg;
|
mCfg = cfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init(DisplayData *displayData) {
|
void init(DisplayData *displayData) override {
|
||||||
u8g2_cb_t *rot = (u8g2_cb_t *)((mCfg->rot != 0x00) ? U8G2_R2 : U8G2_R0);
|
u8g2_cb_t *rot = (u8g2_cb_t *)((mCfg->rot != 0x00) ? U8G2_R2 : U8G2_R0);
|
||||||
// Wemos OLed Shield is not defined in u8 lib -> use nearest compatible
|
// Wemos OLed Shield is not defined in u8 lib -> use nearest compatible
|
||||||
monoInit(new U8G2_SSD1306_64X48_ER_F_HW_I2C(rot, 0xff, mCfg->disp_clk, mCfg->disp_data), displayData);
|
monoInit(new U8G2_SSD1306_64X48_ER_F_HW_I2C(rot, 0xff, mCfg->disp_clk, mCfg->disp_data), displayData);
|
||||||
|
@ -28,7 +28,7 @@ class DisplayMono64X48 : public DisplayMono {
|
||||||
mDisplay->sendBuffer();
|
mDisplay->sendBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void disp(void) {
|
void disp(void) override {
|
||||||
mDisplay->clearBuffer();
|
mDisplay->clearBuffer();
|
||||||
|
|
||||||
// calculate current pixelshift for pixelshift screensaver
|
// calculate current pixelshift for pixelshift screensaver
|
||||||
|
|
|
@ -12,11 +12,11 @@ class DisplayMono84X48 : public DisplayMono {
|
||||||
mExtra = 0;
|
mExtra = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void config(display_t *cfg) {
|
void config(display_t *cfg) override {
|
||||||
mCfg = cfg;
|
mCfg = cfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init(DisplayData *displayData) {
|
void init(DisplayData *displayData) override {
|
||||||
u8g2_cb_t *rot = (u8g2_cb_t *)((mCfg->rot != 0x00) ? U8G2_R2 : U8G2_R0);
|
u8g2_cb_t *rot = (u8g2_cb_t *)((mCfg->rot != 0x00) ? U8G2_R2 : U8G2_R0);
|
||||||
|
|
||||||
monoInit(new U8G2_PCD8544_84X48_F_4W_SW_SPI(rot, mCfg->disp_clk, mCfg->disp_data, mCfg->disp_cs, mCfg->disp_dc, 0xff), displayData);
|
monoInit(new U8G2_PCD8544_84X48_F_4W_SW_SPI(rot, mCfg->disp_clk, mCfg->disp_data, mCfg->disp_cs, mCfg->disp_dc, 0xff), displayData);
|
||||||
|
@ -55,7 +55,7 @@ class DisplayMono84X48 : public DisplayMono {
|
||||||
mDisplay->sendBuffer();
|
mDisplay->sendBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void disp(void) {
|
void disp(void) override {
|
||||||
mDisplay->clearBuffer();
|
mDisplay->clearBuffer();
|
||||||
|
|
||||||
// Layout-Test
|
// Layout-Test
|
||||||
|
@ -143,12 +143,11 @@ class DisplayMono84X48 : public DisplayMono {
|
||||||
// draw dynamic RSSI bars
|
// draw dynamic RSSI bars
|
||||||
int rssi_bar_height = 7;
|
int rssi_bar_height = 7;
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
int radio_rssi_threshold = -60 - i * 10;
|
int rssi_threshold = -60 - i * 10;
|
||||||
int wifi_rssi_threshold = -60 - i * 10;
|
|
||||||
uint8_t barwidth = std::min(4 - i, 3);
|
uint8_t barwidth = std::min(4 - i, 3);
|
||||||
if (mDisplayData->RadioRSSI > radio_rssi_threshold)
|
if (mDisplayData->RadioRSSI > rssi_threshold)
|
||||||
mDisplay->drawBox(0, 8 + (rssi_bar_height + 1) * i, barwidth, rssi_bar_height);
|
mDisplay->drawBox(0, 8 + (rssi_bar_height + 1) * i, barwidth, rssi_bar_height);
|
||||||
if (mDisplayData->WifiRSSI > wifi_rssi_threshold)
|
if (mDisplayData->WifiRSSI > rssi_threshold)
|
||||||
mDisplay->drawBox(mDispWidth - barwidth, 8 + (rssi_bar_height + 1) * i, barwidth, rssi_bar_height);
|
mDisplay->drawBox(mDispWidth - barwidth, 8 + (rssi_bar_height + 1) * i, barwidth, rssi_bar_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,30 +183,28 @@ class DisplayMono84X48 : public DisplayMono {
|
||||||
l_MAX_LINES = 5,
|
l_MAX_LINES = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t graph_first_line;
|
uint8_t graph_first_line = 0;
|
||||||
uint8_t graph_last_line;
|
uint8_t graph_last_line = 0;
|
||||||
|
|
||||||
void calcLinePositions() {
|
void calcLinePositions() {
|
||||||
uint8_t yOff = 0;
|
uint8_t yOff = 0;
|
||||||
uint8_t i = 0;
|
uint8_t i = 0;
|
||||||
uint8_t asc, dsc;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
setLineFont(i);
|
setLineFont(i);
|
||||||
asc = mDisplay->getAscent();
|
uint8_t asc = mDisplay->getAscent();
|
||||||
yOff += asc;
|
yOff += asc;
|
||||||
mLineYOffsets[i] = yOff;
|
mLineYOffsets[i] = yOff;
|
||||||
dsc = mDisplay->getDescent();
|
uint8_t dsc = mDisplay->getDescent();
|
||||||
if (l_TotalPower != i) // power line needs no descent spacing
|
if (l_TotalPower != i) // power line needs no descent spacing
|
||||||
yOff -= dsc;
|
yOff -= dsc;
|
||||||
yOff++; // instead lets spend one pixel space between all lines
|
yOff++; // instead lets spend one pixel space between all lines
|
||||||
i++;
|
i++;
|
||||||
} while(l_MAX_LINES>i);
|
} while(l_MAX_LINES > i);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void setLineFont(uint8_t line) {
|
inline void setLineFont(uint8_t line) {
|
||||||
if ((line == l_TotalPower) ||
|
if (line == l_TotalPower) // || (line == l_Ahoy) -> l_TotalPower == l_Ahoy == 2
|
||||||
(line == l_Ahoy))
|
|
||||||
mDisplay->setFont(u8g2_font_logisoso16_tr);
|
mDisplay->setFont(u8g2_font_logisoso16_tr);
|
||||||
else
|
else
|
||||||
mDisplay->setFont(u8g2_font_5x8_symbols_ahoy);
|
mDisplay->setFont(u8g2_font_5x8_symbols_ahoy);
|
||||||
|
|
|
@ -67,7 +67,7 @@ void DisplayEPaper::refreshLoop() {
|
||||||
case RefreshStatus::LOGO:
|
case RefreshStatus::LOGO:
|
||||||
_display->fillScreen(GxEPD_BLACK);
|
_display->fillScreen(GxEPD_BLACK);
|
||||||
_display->drawBitmap(0, 0, logo, 200, 200, GxEPD_WHITE);
|
_display->drawBitmap(0, 0, logo, 200, 200, GxEPD_WHITE);
|
||||||
_display->display(false); // full update
|
mSecondCnt = 2;
|
||||||
mNextRefreshState = RefreshStatus::PARTITIALS;
|
mNextRefreshState = RefreshStatus::PARTITIALS;
|
||||||
mRefreshState = RefreshStatus::WAIT;
|
mRefreshState = RefreshStatus::WAIT;
|
||||||
break;
|
break;
|
||||||
|
@ -79,11 +79,11 @@ void DisplayEPaper::refreshLoop() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RefreshStatus::WHITE:
|
case RefreshStatus::WHITE:
|
||||||
if(mSecondCnt == 0) {
|
if(0 != mSecondCnt)
|
||||||
_display->fillScreen(GxEPD_WHITE);
|
break;
|
||||||
mNextRefreshState = RefreshStatus::PARTITIALS;
|
_display->fillScreen(GxEPD_WHITE);
|
||||||
mRefreshState = RefreshStatus::WAIT;
|
mNextRefreshState = RefreshStatus::PARTITIALS;
|
||||||
}
|
mRefreshState = RefreshStatus::WAIT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RefreshStatus::WAIT:
|
case RefreshStatus::WAIT:
|
||||||
|
@ -92,10 +92,13 @@ void DisplayEPaper::refreshLoop() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RefreshStatus::PARTITIALS:
|
case RefreshStatus::PARTITIALS:
|
||||||
|
if(0 != mSecondCnt)
|
||||||
|
break;
|
||||||
headlineIP();
|
headlineIP();
|
||||||
versionFooter();
|
versionFooter();
|
||||||
mSecondCnt = 4; // display Logo time during boot up
|
mSecondCnt = 4; // display Logo time during boot up
|
||||||
mRefreshState = RefreshStatus::DONE;
|
mNextRefreshState = RefreshStatus::DONE;
|
||||||
|
mRefreshState = RefreshStatus::WAIT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: // RefreshStatus::DONE
|
default: // RefreshStatus::DONE
|
||||||
|
|
|
@ -47,14 +47,13 @@ class HistoryData {
|
||||||
}
|
}
|
||||||
|
|
||||||
void tickerSecond() {
|
void tickerSecond() {
|
||||||
Inverter<> *iv;
|
;
|
||||||
record_t<> *rec;
|
|
||||||
float curPwr = 0;
|
float curPwr = 0;
|
||||||
float maxPwr = 0;
|
float maxPwr = 0;
|
||||||
float yldDay = -0.1;
|
float yldDay = -0.1;
|
||||||
for (uint8_t i = 0; i < mSys->getNumInverters(); i++) {
|
for (uint8_t i = 0; i < mSys->getNumInverters(); i++) {
|
||||||
iv = mSys->getInverterByPos(i);
|
Inverter<> *iv = mSys->getInverterByPos(i);
|
||||||
rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
||||||
if (iv == NULL)
|
if (iv == NULL)
|
||||||
continue;
|
continue;
|
||||||
curPwr += iv->getChannelFieldValue(CH0, FLD_PAC, rec);
|
curPwr += iv->getChannelFieldValue(CH0, FLD_PAC, rec);
|
||||||
|
|
|
@ -38,7 +38,7 @@ typedef struct {
|
||||||
template<class HMSYSTEM>
|
template<class HMSYSTEM>
|
||||||
class PubMqtt {
|
class PubMqtt {
|
||||||
public:
|
public:
|
||||||
PubMqtt() {
|
PubMqtt() : SendIvData() {
|
||||||
mLastIvState.fill(InverterStatus::OFF);
|
mLastIvState.fill(InverterStatus::OFF);
|
||||||
mIvLastRTRpub.fill(0);
|
mIvLastRTRpub.fill(0);
|
||||||
|
|
||||||
|
@ -61,21 +61,21 @@ class PubMqtt {
|
||||||
mUptime = uptime;
|
mUptime = uptime;
|
||||||
mIntervalTimeout = 1;
|
mIntervalTimeout = 1;
|
||||||
|
|
||||||
mSendIvData.setup(sys, utcTs, &mSendList);
|
SendIvData.setup(sys, utcTs, &mSendList);
|
||||||
mSendIvData.setPublishFunc([this](const char *subTopic, const char *payload, bool retained, uint8_t qos) {
|
SendIvData.setPublishFunc([this](const char *subTopic, const char *payload, bool retained, uint8_t qos) {
|
||||||
publish(subTopic, payload, retained, true, qos);
|
publish(subTopic, payload, retained, true, qos);
|
||||||
});
|
});
|
||||||
mDiscovery.running = false;
|
mDiscovery.running = false;
|
||||||
|
|
||||||
snprintf(mLwtTopic.data(), mLwtTopic.size() - 1, "%s/mqtt", mCfgMqtt->topic);
|
snprintf(mLwtTopic.data(), mLwtTopic.size(), "%s/mqtt", mCfgMqtt->topic);
|
||||||
|
|
||||||
if((strlen(mCfgMqtt->user) > 0) && (strlen(mCfgMqtt->pwd) > 0))
|
if((strlen(mCfgMqtt->user) > 0) && (strlen(mCfgMqtt->pwd) > 0))
|
||||||
mClient.setCredentials(mCfgMqtt->user, mCfgMqtt->pwd);
|
mClient.setCredentials(mCfgMqtt->user, mCfgMqtt->pwd);
|
||||||
|
|
||||||
if(strlen(mCfgMqtt->clientId) > 0)
|
if(strlen(mCfgMqtt->clientId) > 0)
|
||||||
snprintf(mClientId.data(), mClientId.size() - 1, "%s", mCfgMqtt->clientId);
|
snprintf(mClientId.data(), mClientId.size(), "%s", mCfgMqtt->clientId);
|
||||||
else {
|
else {
|
||||||
snprintf(mClientId.data(), mClientId.size() - 1, "%s-", mDevName);
|
snprintf(mClientId.data(), mClientId.size(), "%s-", mDevName);
|
||||||
uint8_t pos = strlen(mClientId.data());
|
uint8_t pos = strlen(mClientId.data());
|
||||||
mClientId[pos++] = WiFi.macAddress().substring( 9, 10).c_str()[0];
|
mClientId[pos++] = WiFi.macAddress().substring( 9, 10).c_str()[0];
|
||||||
mClientId[pos++] = WiFi.macAddress().substring(10, 11).c_str()[0];
|
mClientId[pos++] = WiFi.macAddress().substring(10, 11).c_str()[0];
|
||||||
|
@ -95,7 +95,7 @@ class PubMqtt {
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
mSendIvData.loop();
|
SendIvData.loop();
|
||||||
|
|
||||||
#if defined(ESP8266)
|
#if defined(ESP8266)
|
||||||
mClient.loop();
|
mClient.loop();
|
||||||
|
@ -129,7 +129,7 @@ class PubMqtt {
|
||||||
}
|
}
|
||||||
|
|
||||||
void tickerMinute() {
|
void tickerMinute() {
|
||||||
snprintf(mVal.data(), mVal.size() - 1, "%u", (*mUptime));
|
snprintf(mVal.data(), mVal.size(), "%u", (*mUptime));
|
||||||
publish(subtopics[MQTT_UPTIME], mVal.data());
|
publish(subtopics[MQTT_UPTIME], mVal.data());
|
||||||
publish(subtopics[MQTT_RSSI], String(WiFi.RSSI()).c_str());
|
publish(subtopics[MQTT_RSSI], String(WiFi.RSSI()).c_str());
|
||||||
publish(subtopics[MQTT_FREE_HEAP], String(ESP.getFreeHeap()).c_str());
|
publish(subtopics[MQTT_FREE_HEAP], String(ESP.getFreeHeap()).c_str());
|
||||||
|
@ -152,11 +152,11 @@ class PubMqtt {
|
||||||
if(NULL == iv)
|
if(NULL == iv)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
snprintf(mSubTopic.data(), mSubTopic.size() - 1, "%s/dis_night_comm", iv->config->name);
|
snprintf(mSubTopic.data(), mSubTopic.size(), "%s/dis_night_comm", iv->config->name);
|
||||||
publish(mSubTopic.data(), ((iv->commEnabled) ? dict[STR_TRUE] : dict[STR_FALSE]), true);
|
publish(mSubTopic.data(), ((iv->commEnabled) ? dict[STR_TRUE] : dict[STR_FALSE]), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(mSubTopic.data(), mSubTopic.size() - 1, "comm_disabled");
|
snprintf(mSubTopic.data(), mSubTopic.size(), "comm_disabled");
|
||||||
publish(mSubTopic.data(), (((*mUtcTimestamp > (sunset + offsE)) || (*mUtcTimestamp < (sunrise + offsM))) ? dict[STR_TRUE] : dict[STR_FALSE]), true);
|
publish(mSubTopic.data(), (((*mUtcTimestamp > (sunset + offsE)) || (*mUtcTimestamp < (sunrise + offsM))) ? dict[STR_TRUE] : dict[STR_FALSE]), true);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -164,7 +164,7 @@ class PubMqtt {
|
||||||
|
|
||||||
void notAvailChanged(bool allNotAvail) {
|
void notAvailChanged(bool allNotAvail) {
|
||||||
if(!allNotAvail)
|
if(!allNotAvail)
|
||||||
mSendIvData.resetYieldDay();
|
SendIvData.resetYieldDay();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tickerComm(bool disabled) {
|
bool tickerComm(bool disabled) {
|
||||||
|
@ -179,8 +179,8 @@ class PubMqtt {
|
||||||
|
|
||||||
void tickerMidnight() {
|
void tickerMidnight() {
|
||||||
// set Total YieldDay to zero
|
// set Total YieldDay to zero
|
||||||
snprintf(mSubTopic.data(), mSubTopic.size() - 1, "total/%s", fields[FLD_YD]);
|
snprintf(mSubTopic.data(), mSubTopic.size(), "total/%s", fields[FLD_YD]);
|
||||||
snprintf(mVal.data(), mVal.size() - 1, "0");
|
snprintf(mVal.data(), mVal.size(), "0");
|
||||||
publish(mSubTopic.data(), mVal.data(), true);
|
publish(mSubTopic.data(), mVal.data(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,9 +200,9 @@ class PubMqtt {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(addTopic)
|
if(addTopic)
|
||||||
snprintf(mTopic.data(), mTopic.size() - 1, "%s/%s", mCfgMqtt->topic, subTopic);
|
snprintf(mTopic.data(), mTopic.size(), "%s/%s", mCfgMqtt->topic, subTopic);
|
||||||
else
|
else
|
||||||
snprintf(mTopic.data(), mTopic.size() - 1, "%s", subTopic);
|
snprintf(mTopic.data(), mTopic.size(), "%s", subTopic);
|
||||||
|
|
||||||
mClient.publish(mTopic.data(), qos, retained, payload);
|
mClient.publish(mTopic.data(), qos, retained, payload);
|
||||||
yield();
|
yield();
|
||||||
|
@ -241,7 +241,7 @@ class PubMqtt {
|
||||||
|
|
||||||
void setPowerLimitAck(Inverter<> *iv) {
|
void setPowerLimitAck(Inverter<> *iv) {
|
||||||
if (NULL != iv) {
|
if (NULL != iv) {
|
||||||
snprintf(mSubTopic.data(), mSubTopic.size() - 1, "%s/%s", iv->config->name, subtopics[MQTT_ACK_PWR_LMT]);
|
snprintf(mSubTopic.data(), mSubTopic.size(), "%s/%s", iv->config->name, subtopics[MQTT_ACK_PWR_LMT]);
|
||||||
publish(mSubTopic.data(), "true", true, true, QOS_2);
|
publish(mSubTopic.data(), "true", true, true, QOS_2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -261,11 +261,11 @@ class PubMqtt {
|
||||||
publish(mLwtTopic.data(), mqttStr[MQTT_STR_LWT_CONN], true, false);
|
publish(mLwtTopic.data(), mqttStr[MQTT_STR_LWT_CONN], true, false);
|
||||||
|
|
||||||
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) {
|
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) {
|
||||||
snprintf(mVal.data(), mVal.size() - 1, "ctrl/limit/%d", i);
|
snprintf(mVal.data(), mVal.size(), "ctrl/limit/%d", i);
|
||||||
subscribe(mVal.data(), QOS_2);
|
subscribe(mVal.data(), QOS_2);
|
||||||
snprintf(mVal.data(), mVal.size() - 1, "ctrl/restart/%d", i);
|
snprintf(mVal.data(), mVal.size(), "ctrl/restart/%d", i);
|
||||||
subscribe(mVal.data());
|
subscribe(mVal.data());
|
||||||
snprintf(mVal.data(), mVal.size() - 1, "ctrl/power/%d", i);
|
snprintf(mVal.data(), mVal.size(), "ctrl/power/%d", i);
|
||||||
subscribe(mVal.data());
|
subscribe(mVal.data());
|
||||||
}
|
}
|
||||||
subscribe(subscr[MQTT_SUBS_SET_TIME]);
|
subscribe(subscr[MQTT_SUBS_SET_TIME]);
|
||||||
|
@ -400,20 +400,20 @@ class PubMqtt {
|
||||||
const char *devCls, *stateCls;
|
const char *devCls, *stateCls;
|
||||||
if (!total) {
|
if (!total) {
|
||||||
if (rec->assign[mDiscovery.sub].ch == CH0)
|
if (rec->assign[mDiscovery.sub].ch == CH0)
|
||||||
snprintf(name.data(), name.size() - 1, "%s", iv->getFieldName(mDiscovery.sub, rec));
|
snprintf(name.data(), name.size(), "%s", iv->getFieldName(mDiscovery.sub, rec));
|
||||||
else
|
else
|
||||||
snprintf(name.data(), name.size() - 1, "CH%d_%s", rec->assign[mDiscovery.sub].ch, iv->getFieldName(mDiscovery.sub, rec));
|
snprintf(name.data(), name.size(), "CH%d_%s", rec->assign[mDiscovery.sub].ch, iv->getFieldName(mDiscovery.sub, rec));
|
||||||
snprintf(topic.data(), name.size() - 1, "/ch%d/%s", rec->assign[mDiscovery.sub].ch, iv->getFieldName(mDiscovery.sub, rec));
|
snprintf(topic.data(), name.size(), "/ch%d/%s", rec->assign[mDiscovery.sub].ch, iv->getFieldName(mDiscovery.sub, rec));
|
||||||
snprintf(uniq_id.data(), uniq_id.size() - 1, "ch%d_%s", rec->assign[mDiscovery.sub].ch, iv->getFieldName(mDiscovery.sub, rec));
|
snprintf(uniq_id.data(), uniq_id.size(), "ch%d_%s", rec->assign[mDiscovery.sub].ch, iv->getFieldName(mDiscovery.sub, rec));
|
||||||
|
|
||||||
devCls = getFieldDeviceClass(rec->assign[mDiscovery.sub].fieldId);
|
devCls = getFieldDeviceClass(rec->assign[mDiscovery.sub].fieldId);
|
||||||
stateCls = getFieldStateClass(rec->assign[mDiscovery.sub].fieldId);
|
stateCls = getFieldStateClass(rec->assign[mDiscovery.sub].fieldId);
|
||||||
}
|
}
|
||||||
|
|
||||||
else { // total values
|
else { // total values
|
||||||
snprintf(name.data(), name.size() - 1, "Total %s", fields[fldTotal[mDiscovery.sub]]);
|
snprintf(name.data(), name.size(), "Total %s", fields[fldTotal[mDiscovery.sub]]);
|
||||||
snprintf(topic.data(), topic.size() - 1, "/%s", fields[fldTotal[mDiscovery.sub]]);
|
snprintf(topic.data(), topic.size(), "/%s", fields[fldTotal[mDiscovery.sub]]);
|
||||||
snprintf(uniq_id.data(), uniq_id.size() - 1, "total_%s", fields[fldTotal[mDiscovery.sub]]);
|
snprintf(uniq_id.data(), uniq_id.size(), "total_%s", fields[fldTotal[mDiscovery.sub]]);
|
||||||
devCls = getFieldDeviceClass(fldTotal[mDiscovery.sub]);
|
devCls = getFieldDeviceClass(fldTotal[mDiscovery.sub]);
|
||||||
stateCls = getFieldStateClass(fldTotal[mDiscovery.sub]);
|
stateCls = getFieldStateClass(fldTotal[mDiscovery.sub]);
|
||||||
}
|
}
|
||||||
|
@ -433,9 +433,9 @@ class PubMqtt {
|
||||||
doc2[F("stat_cla")] = String(stateCls);
|
doc2[F("stat_cla")] = String(stateCls);
|
||||||
|
|
||||||
if (!total)
|
if (!total)
|
||||||
snprintf(topic.data(), topic.size() - 1, "%s/sensor/%s/ch%d_%s/config", MQTT_DISCOVERY_PREFIX, iv->config->name, rec->assign[mDiscovery.sub].ch, iv->getFieldName(mDiscovery.sub, rec));
|
snprintf(topic.data(), topic.size(), "%s/sensor/%s/ch%d_%s/config", MQTT_DISCOVERY_PREFIX, iv->config->name, rec->assign[mDiscovery.sub].ch, iv->getFieldName(mDiscovery.sub, rec));
|
||||||
else // total values
|
else // total values
|
||||||
snprintf(topic.data(), topic.size() - 1, "%s/sensor/%s/total_%s/config", MQTT_DISCOVERY_PREFIX, node_id.c_str(), fields[fldTotal[mDiscovery.sub]]);
|
snprintf(topic.data(), topic.size(), "%s/sensor/%s/total_%s/config", MQTT_DISCOVERY_PREFIX, node_id.c_str(), fields[fldTotal[mDiscovery.sub]]);
|
||||||
size_t size = measureJson(doc2) + 1;
|
size_t size = measureJson(doc2) + 1;
|
||||||
buf.fill(0);
|
buf.fill(0);
|
||||||
serializeJson(doc2, buf.data(), size);
|
serializeJson(doc2, buf.data(), size);
|
||||||
|
@ -509,14 +509,14 @@ class PubMqtt {
|
||||||
mLastIvState[id] = status;
|
mLastIvState[id] = status;
|
||||||
changed = true;
|
changed = true;
|
||||||
|
|
||||||
snprintf(mSubTopic.data(), mSubTopic.size() - 1, "%s/available", iv->config->name);
|
snprintf(mSubTopic.data(), mSubTopic.size(), "%s/available", iv->config->name);
|
||||||
snprintf(mVal.data(), mVal.size() - 1, "%d", (uint8_t)status);
|
snprintf(mVal.data(), mVal.size(), "%d", (uint8_t)status);
|
||||||
publish(mSubTopic.data(), mVal.data(), true);
|
publish(mSubTopic.data(), mVal.data(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(changed) {
|
if(changed) {
|
||||||
snprintf(mVal.data(), mVal.size() - 1, "%d", ((allAvail) ? MQTT_STATUS_ONLINE : ((anyAvail) ? MQTT_STATUS_PARTIAL : MQTT_STATUS_OFFLINE)));
|
snprintf(mVal.data(), mVal.size(), "%d", ((allAvail) ? MQTT_STATUS_ONLINE : ((anyAvail) ? MQTT_STATUS_PARTIAL : MQTT_STATUS_OFFLINE)));
|
||||||
publish("status", mVal.data(), true);
|
publish("status", mVal.data(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,14 +539,14 @@ class PubMqtt {
|
||||||
|
|
||||||
mSendAlarm[i] = false;
|
mSendAlarm[i] = false;
|
||||||
|
|
||||||
snprintf(mSubTopic.data(), mSubTopic.size() - 1, "%s/alarm/cnt", iv->config->name);
|
snprintf(mSubTopic.data(), mSubTopic.size(), "%s/alarm/cnt", iv->config->name);
|
||||||
snprintf(mVal.data(), mVal.size() - 1, "%d", iv->alarmCnt);
|
snprintf(mVal.data(), mVal.size(), "%d", iv->alarmCnt);
|
||||||
publish(mSubTopic.data(), mVal.data(), false);
|
publish(mSubTopic.data(), mVal.data(), false);
|
||||||
|
|
||||||
for(uint8_t j = 0; j < 10; j++) {
|
for(uint8_t j = 0; j < 10; j++) {
|
||||||
if(0 != iv->lastAlarm[j].code) {
|
if(0 != iv->lastAlarm[j].code) {
|
||||||
snprintf(mSubTopic.data(), mSubTopic.size() - 1, "%s/alarm/%d", iv->config->name, j);
|
snprintf(mSubTopic.data(), mSubTopic.size(), "%s/alarm/%d", iv->config->name, j);
|
||||||
snprintf(mVal.data(), mVal.size() - 1, "{\"code\":%d,\"str\":\"%s\",\"start\":%d,\"end\":%d}",
|
snprintf(mVal.data(), mVal.size(), "{\"code\":%d,\"str\":\"%s\",\"start\":%d,\"end\":%d}",
|
||||||
iv->lastAlarm[j].code,
|
iv->lastAlarm[j].code,
|
||||||
iv->getAlarmStr(iv->lastAlarm[j].code).c_str(),
|
iv->getAlarmStr(iv->lastAlarm[j].code).c_str(),
|
||||||
iv->lastAlarm[j].start + lastMidnight,
|
iv->lastAlarm[j].start + lastMidnight,
|
||||||
|
@ -581,8 +581,8 @@ class PubMqtt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(mSubTopic.data(), mSubTopic.size() - 1, "%s/ch%d/%s", iv->config->name, rec->assign[i].ch, fields[rec->assign[i].fieldId]);
|
snprintf(mSubTopic.data(), mSubTopic.size(), "%s/ch%d/%s", iv->config->name, rec->assign[i].ch, fields[rec->assign[i].fieldId]);
|
||||||
snprintf(mVal.data(), mVal.size() - 1, "%g", ah::round3(iv->getValue(i, rec)));
|
snprintf(mVal.data(), mVal.size(), "%g", ah::round3(iv->getValue(i, rec)));
|
||||||
publish(mSubTopic.data(), mVal.data(), retained);
|
publish(mSubTopic.data(), mVal.data(), retained);
|
||||||
|
|
||||||
yield();
|
yield();
|
||||||
|
@ -598,7 +598,7 @@ class PubMqtt {
|
||||||
if(mSendList.empty())
|
if(mSendList.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mSendIvData.start();
|
SendIvData.start();
|
||||||
mLastAnyAvail = anyAvail;
|
mLastAnyAvail = anyAvail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -609,7 +609,7 @@ class PubMqtt {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
HMSYSTEM *mSys = nullptr;
|
HMSYSTEM *mSys = nullptr;
|
||||||
PubMqttIvData<HMSYSTEM> mSendIvData;
|
PubMqttIvData<HMSYSTEM> SendIvData;
|
||||||
|
|
||||||
uint32_t *mUtcTimestamp = nullptr, *mUptime = nullptr;
|
uint32_t *mUtcTimestamp = nullptr, *mUptime = nullptr;
|
||||||
uint32_t mRxCnt = 0, mTxCnt = 0;
|
uint32_t mRxCnt = 0, mTxCnt = 0;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// 2024 Ahoy, https://ahoydtu.de
|
// 2024 Ahoy, https://ahoydtu.de
|
||||||
// Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed
|
// Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -21,6 +21,8 @@ struct sendListCmdIv {
|
||||||
template<class HMSYSTEM>
|
template<class HMSYSTEM>
|
||||||
class PubMqttIvData {
|
class PubMqttIvData {
|
||||||
public:
|
public:
|
||||||
|
PubMqttIvData() : mTotal{}, mSubTopic{}, mVal{} {}
|
||||||
|
|
||||||
void setup(HMSYSTEM *sys, uint32_t *utcTs, std::queue<sendListCmdIv> *sendList) {
|
void setup(HMSYSTEM *sys, uint32_t *utcTs, std::queue<sendListCmdIv> *sendList) {
|
||||||
mSys = sys;
|
mSys = sys;
|
||||||
mUtcTimestamp = utcTs;
|
mUtcTimestamp = utcTs;
|
||||||
|
@ -249,25 +251,25 @@ class PubMqttIvData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HMSYSTEM *mSys;
|
HMSYSTEM *mSys = nullptr;
|
||||||
uint32_t *mUtcTimestamp;
|
uint32_t *mUtcTimestamp = nullptr;
|
||||||
pubMqttPublisherType mPublish;
|
pubMqttPublisherType mPublish;
|
||||||
State mState;
|
State mState = IDLE;
|
||||||
StateFunction mTable[NUM_STATES];
|
StateFunction mTable[NUM_STATES];
|
||||||
|
|
||||||
uint8_t mCmd;
|
uint8_t mCmd = 0;
|
||||||
uint8_t mLastIvId;
|
uint8_t mLastIvId = 0;
|
||||||
bool mSendTotals, mTotalFound, mAllTotalFound, mSendTotalYd;
|
bool mSendTotals = false, mTotalFound = false, mAllTotalFound = false, mSendTotalYd = false;
|
||||||
float mTotal[5], mYldTotalStore;
|
float mTotal[5], mYldTotalStore = 0;
|
||||||
|
|
||||||
Inverter<> *mIv, *mIvSend;
|
Inverter<> *mIv = nullptr, *mIvSend = nullptr;
|
||||||
uint8_t mPos;
|
uint8_t mPos = 0;
|
||||||
bool mRTRDataHasBeenSent;
|
bool mRTRDataHasBeenSent = false;
|
||||||
|
|
||||||
char mSubTopic[32 + MAX_NAME_LENGTH + 1];
|
char mSubTopic[32 + MAX_NAME_LENGTH + 1];
|
||||||
char mVal[140];
|
char mVal[140];
|
||||||
|
|
||||||
std::queue<sendListCmdIv> *mSendList;
|
std::queue<sendListCmdIv> *mSendList = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /*__PUB_MQTT_IV_DATA_H__*/
|
#endif /*__PUB_MQTT_IV_DATA_H__*/
|
||||||
|
|
|
@ -71,7 +71,7 @@ class Improv {
|
||||||
TYPE_RPC_RESPONSE = 0x04
|
TYPE_RPC_RESPONSE = 0x04
|
||||||
};
|
};
|
||||||
|
|
||||||
void dumpBuf(uint8_t buf[], uint8_t len) {
|
void dumpBuf(const uint8_t buf[], uint8_t len) {
|
||||||
for(uint8_t i = 0; i < len; i++) {
|
for(uint8_t i = 0; i < len; i++) {
|
||||||
DHEX(buf[i]);
|
DHEX(buf[i]);
|
||||||
DBGPRINT(F(" "));
|
DBGPRINT(F(" "));
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#define SYSLOG_MAX_PACKET_SIZE 256
|
#define SYSLOG_MAX_PACKET_SIZE 256
|
||||||
|
|
||||||
|
DbgSyslog::DbgSyslog() : mSyslogBuffer{} {}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void DbgSyslog::setup(settings_t *config) {
|
void DbgSyslog::setup(settings_t *config) {
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
|
|
||||||
class DbgSyslog {
|
class DbgSyslog {
|
||||||
public:
|
public:
|
||||||
|
DbgSyslog();
|
||||||
void setup (settings_t *config);
|
void setup (settings_t *config);
|
||||||
void syslogCb(String msg);
|
void syslogCb(String msg);
|
||||||
void log(const char *hostname, uint8_t facility, uint8_t severity, char* msg);
|
void log(const char *hostname, uint8_t facility, uint8_t severity, char* msg);
|
||||||
|
@ -43,7 +44,7 @@ class DbgSyslog {
|
||||||
private:
|
private:
|
||||||
WiFiUDP mSyslogUdp;
|
WiFiUDP mSyslogUdp;
|
||||||
IPAddress mSyslogIP;
|
IPAddress mSyslogIP;
|
||||||
settings_t *mConfig;
|
settings_t *mConfig = nullptr;
|
||||||
char mSyslogBuffer[SYSLOG_BUF_SIZE+1];
|
char mSyslogBuffer[SYSLOG_BUF_SIZE+1];
|
||||||
uint16_t mSyslogBufFill = 0;
|
uint16_t mSyslogBufFill = 0;
|
||||||
int mSyslogSeverity = PRI_NOTICE;
|
int mSyslogSeverity = PRI_NOTICE;
|
||||||
|
@ -51,4 +52,4 @@ class DbgSyslog {
|
||||||
|
|
||||||
#endif /*ENABLE_SYSLOG*/
|
#endif /*ENABLE_SYSLOG*/
|
||||||
|
|
||||||
#endif /*__SYSLOG_H__*/
|
#endif /*__SYSLOG_H__*/
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
class Protection {
|
class Protection {
|
||||||
protected:
|
protected:
|
||||||
Protection(const char *pwd) {
|
explicit Protection(const char *pwd) {
|
||||||
mPwd = pwd;
|
mPwd = pwd;
|
||||||
mLogoutTimeout = 0;
|
mLogoutTimeout = 0;
|
||||||
mLoginIp.fill(0);
|
mLoginIp.fill(0);
|
||||||
|
|
|
@ -684,7 +684,6 @@ class Web {
|
||||||
char type[60], topic[100], val[25];
|
char type[60], topic[100], val[25];
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
int alarmChannelId;
|
int alarmChannelId;
|
||||||
int metricsChannelId;
|
|
||||||
|
|
||||||
// Perform grouping on metrics according to format specification
|
// Perform grouping on metrics according to format specification
|
||||||
// Each step must return at least one character. Otherwise the processing of AsyncWebServerResponse stops.
|
// Each step must return at least one character. Otherwise the processing of AsyncWebServerResponse stops.
|
||||||
|
@ -766,7 +765,7 @@ class Web {
|
||||||
iv = mSys->getInverterByPos(metricsInverterId);
|
iv = mSys->getInverterByPos(metricsInverterId);
|
||||||
if (NULL != iv) {
|
if (NULL != iv) {
|
||||||
rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
||||||
for (metricsChannelId=0; metricsChannelId < rec->length;metricsChannelId++) {
|
for (int metricsChannelId=0; metricsChannelId < rec->length;metricsChannelId++) {
|
||||||
uint8_t channel = rec->assign[metricsChannelId].ch;
|
uint8_t channel = rec->assign[metricsChannelId].ch;
|
||||||
|
|
||||||
// Try inverter channel (channel 0) or any channel with maxPwr > 0
|
// Try inverter channel (channel 0) or any channel with maxPwr > 0
|
||||||
|
@ -786,14 +785,14 @@ class Web {
|
||||||
char total[7];
|
char total[7];
|
||||||
if (metricDeclared) {
|
if (metricDeclared) {
|
||||||
// A declaration and value for channels have been delivered. So declare and deliver a _total metric
|
// A declaration and value for channels have been delivered. So declare and deliver a _total metric
|
||||||
snprintf(total, sizeof(total)-1, "_total");
|
snprintf(total, sizeof(total), "_total");
|
||||||
}
|
}
|
||||||
if (!metricTotalDeclard) {
|
if (!metricTotalDeclard) {
|
||||||
snprintf(type, sizeof(type)-1, "# TYPE %s%s%s%s %s\n",metricConstPrefix, iv->getFieldName(metricsChannelId, rec), promUnit.c_str(), total, promType.c_str());
|
snprintf(type, sizeof(type), "# TYPE %s%s%s%s %s\n",metricConstPrefix, iv->getFieldName(metricsChannelId, rec), promUnit.c_str(), total, promType.c_str());
|
||||||
metrics += type;
|
metrics += type;
|
||||||
metricTotalDeclard = true;
|
metricTotalDeclard = true;
|
||||||
}
|
}
|
||||||
snprintf(topic, sizeof(topic)-1, "%s%s%s%s{inverter=\"%s\"}",metricConstPrefix, iv->getFieldName(metricsChannelId, rec), promUnit.c_str(), total,iv->config->name);
|
snprintf(topic, sizeof(topic), "%s%s%s%s{inverter=\"%s\"}",metricConstPrefix, iv->getFieldName(metricsChannelId, rec), promUnit.c_str(), total,iv->config->name);
|
||||||
} else {
|
} else {
|
||||||
// Report (non zero) channel value
|
// Report (non zero) channel value
|
||||||
// Use a fallback channel name (ch0, ch1, ...)if non is given by user
|
// Use a fallback channel name (ch0, ch1, ...)if non is given by user
|
||||||
|
@ -801,11 +800,11 @@ class Web {
|
||||||
if (iv->config->chName[channel-1][0] != 0) {
|
if (iv->config->chName[channel-1][0] != 0) {
|
||||||
strncpy(chName, iv->config->chName[channel-1], sizeof(chName));
|
strncpy(chName, iv->config->chName[channel-1], sizeof(chName));
|
||||||
} else {
|
} else {
|
||||||
snprintf(chName,sizeof(chName)-1,"ch%1d",channel);
|
snprintf(chName,sizeof(chName),"ch%1d",channel);
|
||||||
}
|
}
|
||||||
snprintf(topic, sizeof(topic)-1, "%s%s%s{inverter=\"%s\",channel=\"%s\"}",metricConstPrefix, iv->getFieldName(metricsChannelId, rec), promUnit.c_str(), iv->config->name,chName);
|
snprintf(topic, sizeof(topic), "%s%s%s{inverter=\"%s\",channel=\"%s\"}",metricConstPrefix, iv->getFieldName(metricsChannelId, rec), promUnit.c_str(), iv->config->name,chName);
|
||||||
}
|
}
|
||||||
snprintf(val, sizeof(val)-1, " %.3f\n", iv->getValue(metricsChannelId, rec));
|
snprintf(val, sizeof(val), " %.3f\n", iv->getValue(metricsChannelId, rec));
|
||||||
metrics += topic;
|
metrics += topic;
|
||||||
metrics += val;
|
metrics += val;
|
||||||
}
|
}
|
||||||
|
@ -835,7 +834,7 @@ class Web {
|
||||||
|
|
||||||
case metricsStateAlarmData: // Alarm Info loop : fit to one packet
|
case metricsStateAlarmData: // Alarm Info loop : fit to one packet
|
||||||
// Perform grouping on metrics according to Prometheus exposition format specification
|
// Perform grouping on metrics according to Prometheus exposition format specification
|
||||||
snprintf(type, sizeof(type)-1,"# TYPE %s%s gauge\n",metricConstPrefix,fields[FLD_LAST_ALARM_CODE]);
|
snprintf(type, sizeof(type),"# TYPE %s%s gauge\n",metricConstPrefix,fields[FLD_LAST_ALARM_CODE]);
|
||||||
metrics = type;
|
metrics = type;
|
||||||
|
|
||||||
for (metricsInverterId = 0; metricsInverterId < mSys->getNumInverters();metricsInverterId++) {
|
for (metricsInverterId = 0; metricsInverterId < mSys->getNumInverters();metricsInverterId++) {
|
||||||
|
@ -847,8 +846,8 @@ class Web {
|
||||||
alarmChannelId = 0;
|
alarmChannelId = 0;
|
||||||
if (alarmChannelId < rec->length) {
|
if (alarmChannelId < rec->length) {
|
||||||
std::tie(promUnit, promType) = convertToPromUnits(iv->getUnit(alarmChannelId, rec));
|
std::tie(promUnit, promType) = convertToPromUnits(iv->getUnit(alarmChannelId, rec));
|
||||||
snprintf(topic, sizeof(topic)-1, "%s%s%s{inverter=\"%s\"}",metricConstPrefix, iv->getFieldName(alarmChannelId, rec), promUnit.c_str(), iv->config->name);
|
snprintf(topic, sizeof(topic), "%s%s%s{inverter=\"%s\"}",metricConstPrefix, iv->getFieldName(alarmChannelId, rec), promUnit.c_str(), iv->config->name);
|
||||||
snprintf(val, sizeof(val)-1, " %.3f\n", iv->getValue(alarmChannelId, rec));
|
snprintf(val, sizeof(val), " %.3f\n", iv->getValue(alarmChannelId, rec));
|
||||||
metrics += topic;
|
metrics += topic;
|
||||||
metrics += val;
|
metrics += val;
|
||||||
}
|
}
|
||||||
|
@ -874,8 +873,8 @@ class Web {
|
||||||
// Traverse all inverters and collect the metric via valueFunc
|
// Traverse all inverters and collect the metric via valueFunc
|
||||||
String inverterMetric(char *buffer, size_t len, const char *format, std::function<uint64_t(Inverter<> *iv)> valueFunc) {
|
String inverterMetric(char *buffer, size_t len, const char *format, std::function<uint64_t(Inverter<> *iv)> valueFunc) {
|
||||||
String metric = "";
|
String metric = "";
|
||||||
for (int metricsInverterId = 0; metricsInverterId < mSys->getNumInverters();metricsInverterId++) {
|
for (int id = 0; id < mSys->getNumInverters();id++) {
|
||||||
Inverter<> *iv = mSys->getInverterByPos(metricsInverterId);
|
Inverter<> *iv = mSys->getInverterByPos(id);
|
||||||
if (NULL != iv) {
|
if (NULL != iv) {
|
||||||
snprintf(buffer,len,format,iv->config->name, valueFunc(iv));
|
snprintf(buffer,len,format,iv->config->name, valueFunc(iv));
|
||||||
metric += String(buffer);
|
metric += String(buffer);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue