From 32092ede0d72c66f8e526b82a1d9a4b7e692d1e4 Mon Sep 17 00:00:00 2001 From: rejoe2 Date: Fri, 24 Mar 2023 15:26:14 +0100 Subject: [PATCH 1/6] debug review - DPRINT_IVID - MI: some small changes --- src/hm/hmInverter.h | 14 +++--- src/hm/hmPayload.h | 98 ++++++++++++++++++++++---------------- src/hm/hmRadio.h | 4 +- src/hm/miPayload.h | 113 +++++++++++++++++++++----------------------- src/utils/dbg.h | 7 +-- 5 files changed, 123 insertions(+), 113 deletions(-) diff --git a/src/hm/hmInverter.h b/src/hm/hmInverter.h index 6f6efe38..c098a081 100644 --- a/src/hm/hmInverter.h +++ b/src/hm/hmInverter.h @@ -143,10 +143,11 @@ class Inverter { template void enqueCommand(uint8_t cmd) { _commandQueue.push(std::make_shared(cmd)); - DPRINT(DBG_INFO, F("(#")); - DBGPRINT(String(id)); - DBGPRINT(F(") enqueCommand: 0x")); - DHEX(cmd); + DPRINT_IVID(DBG_INFO, id); + //DPRINT(DBG_INFO, F("(#")); + //DBGPRINT(String(id)); + DBGPRINTLN(F("enqueCommand: 0x") + String(cmd, HEX)); + //DBGHEXLN(cmd); } void setQueuedCmdFinished() { @@ -289,7 +290,8 @@ class Inverter { alarmMesIndex = rec->record[pos]; //enqueCommand(AlarmUpdate); // What is the function of AlarmUpdate? - DPRINTLN(DBG_INFO, "alarm ID incremented to " + String(alarmMesIndex)); + DPRINT(DBG_INFO, "alarm ID incremented to "); + DBGPRINTLN(String(alarmMesIndex)); enqueCommand(AlarmData); } } @@ -303,7 +305,7 @@ class Inverter { DPRINTLN(DBG_DEBUG, "add config"); if (getPosByChFld(0, FLD_ACT_ACTIVE_PWR_LIMIT, rec) == pos){ actPowerLimit = rec->record[pos]; - DPRINT(DBG_DEBUG, F("Inverter actual power limit: ") + String(actPowerLimit, 1)); + DPRINTLN(DBG_DEBUG, F("Inverter actual power limit: ") + String(actPowerLimit, 1)); } } else if (rec->assign == AlarmDataAssignment) { diff --git a/src/hm/hmPayload.h b/src/hm/hmPayload.h index 7660c46b..7dda7e6f 100644 --- a/src/hm/hmPayload.h +++ b/src/hm/hmPayload.h @@ -116,12 +116,14 @@ class HmPayload { mStat->rxFail++; // got fragments but not complete response iv->setQueuedCmdFinished(); // command failed - if (mSerialDebug) - DPRINTLN(DBG_INFO, F("enqueued cmd failed/timeout")); if (mSerialDebug) { - DPRINT(DBG_INFO, F("(#")); - DBGPRINT(String(iv->id)); - DBGPRINT(F(") no Payload received! (retransmits: ")); + DPRINTLN(DBG_INFO, F("enqueued cmd failed/timeout")); + //if (mSerialDebug) { + //DPRINT(DBG_INFO, F("(#")); + //DBGPRINT(String(iv->id)); + //DBGPRINT(F(") no Payload received! (retransmits: ")); + DPRINT_IVID(DBG_INFO, iv->id); + DBGPRINT(F("no Payload received! (retransmits: ")); DBGPRINT(String(mPayload[iv->id].retransmits)); DBGPRINTLN(F(")")); } @@ -134,17 +136,21 @@ class HmPayload { yield(); if (mSerialDebug) { - DPRINT(DBG_INFO, F("(#")); - DBGPRINT(String(iv->id)); - DBGPRINT(F(") Requesting Inv SN ")); + DPRINT_IVID(DBG_INFO, iv->id); + //DPRINT(DBG_INFO, F("(#")); + //DBGPRINT(String(iv->id)); + //DBGPRINT(F(") Requesting Inv SN ")); + DBGPRINT(F("Requesting Inv SN ")); DBGPRINTLN(String(iv->config->serial.u64, HEX)); } if (iv->getDevControlRequest()) { if (mSerialDebug) { - DPRINT(DBG_INFO, F("(#")); - DBGPRINT(String(iv->id)); - DBGPRINT(F(") Devcontrol request 0x")); + //DPRINT(DBG_INFO, F("(#")); + //DBGPRINT(String(iv->id)); + //DBGPRINT(F(") Devcontrol request 0x")); + DPRINT_IVID(DBG_INFO, iv->id); + DBGPRINT(F("Devcontrol request 0x")); DBGPRINT(String(iv->devControlCmd, HEX)); DBGPRINT(F(" power limit ")); DBGPRINTLN(String(iv->powerLimit[0])); @@ -155,10 +161,12 @@ class HmPayload { //iv->enqueCommand(SystemConfigPara); // read back power limit } else { uint8_t cmd = iv->getQueuedCmd(); - DPRINT(DBG_INFO, F("(#")); - DBGPRINT(String(iv->id)); - DBGPRINT(F(") prepareDevInformCmd 0x")); - DBGPRINTLN(String(cmd, HEX)); + //DPRINT(DBG_INFO, F("(#")); + //DBGPRINT(String(iv->id)); + //DBGPRINT(F(") prepareDevInformCmd 0x")); + DPRINT_IVID(DBG_INFO, iv->id); + DBGPRINT(F("prepareDevInformCmd 0x")); + DBGHEXLN(cmd); mSys->Radio.prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmMesIndex, false); mPayload[iv->id].txCmd = cmd; } @@ -170,9 +178,9 @@ class HmPayload { DPRINTLN(DBG_DEBUG, F("Response from info request received")); uint8_t *pid = &p->packet[9]; if (*pid == 0x00) { - DPRINT(DBG_DEBUG, F("fragment number zero received and ignored")); + DPRINTLN(DBG_DEBUG, F("fragment number zero received and ignored")); } else { - DPRINTLN(DBG_DEBUG, "PID: 0x" + String(*pid, HEX)); + DPRINTLN(DBG_DEBUG, F("PID: 0x") + String(*pid, HEX)); if ((*pid & 0x7F) < MAX_PAYLOAD_ENTRIES) { memcpy(mPayload[iv->id].data[(*pid & 0x7F) - 1], &p->packet[10], p->len - 11); mPayload[iv->id].len[(*pid & 0x7F) - 1] = p->len - 11; @@ -200,14 +208,17 @@ class HmPayload { mApp->setMqttPowerLimitAck(iv); else ok = false; - DPRINT(DBG_INFO, F("(#")); - DBGPRINT(String(iv->id)); - DBGPRINT(F(" has ")); - if(!ok) DBGPRINT(F("not ")); - DBGPRINT(F("accepted power limit set point ")); - DBGPRINT(String(iv->powerLimit[0])); - DBGPRINT(F(" with PowerLimitControl ")); - DBGPRINTLN(String(iv->powerLimit[1])); + //DPRINT(DBG_INFO, F("(#")); + //DBGPRINT(String(iv->id)); + if (mSerialDebug) { + DPRINT_IVID(DBG_INFO, iv->id); + DBGPRINT(F(" has ")); + if(!ok) DBGPRINT(F("not ")); + DBGPRINT(F("accepted power limit set point ")); + DBGPRINT(String(iv->powerLimit[0])); + DBGPRINT(F(" with PowerLimitControl ")); + DBGPRINTLN(String(iv->powerLimit[1])); + } iv->clearCmdQueue(); iv->enqueCommand(SystemConfigPara); // read back power limit @@ -243,9 +254,10 @@ class HmPayload { DPRINTLN(DBG_INFO, F("Prevent retransmit on Restart / CleanState_LockAndAlarm...")); mPayload[iv->id].retransmits = mMaxRetrans; } else if(iv->devControlCmd == ActivePowerContr) { - DPRINT(DBG_INFO, F("(#")); - DBGPRINT(String(iv->id)); - DPRINTLN(DBG_INFO, F(") retransmit power limit")); + //DPRINT(DBG_INFO, F("(#")); + //DBGPRINT(String(iv->id)); + DPRINT_IVID(DBG_INFO, iv->id); + DPRINTLN(DBG_INFO, F("retransmit power limit")); mSys->Radio.sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, true); } else { if(false == mPayload[iv->id].gotFragment) { @@ -255,16 +267,18 @@ class HmPayload { DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") prepareDevInformCmd 0x") + String(mPayload[iv->id].txCmd, HEX)); mSys->Radio.prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true); */ - DPRINT(DBG_INFO, F("(#")); - DBGPRINT(String(iv->id)); - DBGPRINTLN(F(") nothing received")); + //DPRINT(DBG_INFO, F("(#")); + //DBGPRINT(String(iv->id)); + DPRINT_IVID(DBG_INFO, iv->id); + DBGPRINTLN(F("nothing received")); mPayload[iv->id].retransmits = mMaxRetrans; } else { for (uint8_t i = 0; i < (mPayload[iv->id].maxPackId - 1); i++) { if (mPayload[iv->id].len[i] == 0) { - DPRINT(DBG_WARN, F("(#")); - DBGPRINT(String(iv->id)); - DBGPRINT(F(") Frame ")); + //DPRINT(DBG_WARN, F("(#")); + //DBGPRINT(String(iv->id)); + DPRINT_IVID(DBG_WARN, iv->id); + DBGPRINT(F("Frame ")); DBGPRINT(String(i + 1)); DBGPRINTLN(F(" missing: Request Retransmit")); mSys->Radio.sendCmdPacket(iv->radioId.u64, TX_REQ_INFO, (SINGLE_FRAME + i), true); @@ -281,19 +295,19 @@ class HmPayload { mPayload[iv->id].retransmits++; DPRINTLN(DBG_WARN, F("CRC Error: Request Complete Retransmit")); mPayload[iv->id].txCmd = iv->getQueuedCmd(); - DPRINT(DBG_INFO, F("(#")); - DBGPRINT(String(iv->id)); - DBGPRINT(F(") prepareDevInformCmd 0x")); - DHEXLN(mPayload[iv->id].txCmd); + //DPRINT(DBG_INFO, F("(#")); + //DBGPRINT(String(iv->id)); + DPRINT_IVID(DBG_INFO, iv->id); + DBGPRINT(F("prepareDevInformCmd 0x")); + DBGHEXLN(mPayload[iv->id].txCmd); mSys->Radio.prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true); } } else { // payload complete DPRINT(DBG_INFO, F("procPyld: cmd: 0x")); - DHEXLN(mPayload[iv->id].txCmd); + DBGHEXLN(mPayload[iv->id].txCmd); DPRINT(DBG_INFO, F("procPyld: txid: 0x")); - DHEXLN(mPayload[iv->id].txId); - DPRINTLN(DBG_DEBUG, F("procPyld: max: ")); - DBGPRINT(String(mPayload[iv->id].maxPackId)); + DBGHEXLN(mPayload[iv->id].txId); + DPRINTLN(DBG_DEBUG, F("procPyld: max: ") + String(mPayload[iv->id].maxPackId)); record_t<> *rec = iv->getRecordStruct(mPayload[iv->id].txCmd); // choose the parser mPayload[iv->id].complete = true; diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index 40c92889..ff45a72d 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -177,7 +177,7 @@ class HmRadio { void sendControlPacket(uint64_t invId, uint8_t cmd, uint16_t *data, bool isRetransmit, bool isNoMI = true) { DPRINT(DBG_INFO, F("sendControlPacket cmd: 0x")); - DBGPRINTLN(String(cmd, HEX)); + DBGHEXLN(cmd); initPacket(invId, TX_REQ_DEVCONTROL, SINGLE_FRAME); uint8_t cnt = 10; if (isNoMI) { @@ -295,7 +295,7 @@ class HmRadio { } void initPacket(uint64_t invId, uint8_t mid, uint8_t pid) { - DPRINTLN(DBG_VERBOSE, F("initPacket, mid: ") + String(mid, HEX) + F(" pid: ") + String(pid, HEX)); + DPRINT(DBG_VERBOSE, F("initPacket, mid: ") + String(mid, HEX) + F(" pid: ") + String(pid, HEX)); memset(mTxBuf, 0, MAX_RF_PAYLOAD_SIZE); mTxBuf[0] = mid; // message id CP_U32_BigEndian(&mTxBuf[1], (invId >> 8)); diff --git a/src/hm/miPayload.h b/src/hm/miPayload.h index c5a6eb9a..753134d5 100644 --- a/src/hm/miPayload.h +++ b/src/hm/miPayload.h @@ -94,10 +94,10 @@ class MiPayload { iv->setQueuedCmdFinished(); // command failed if (mSerialDebug) - DPRINTHEAD(DBG_INFO, iv->id); + DPRINT_IVID(DBG_INFO, iv->id); DBGPRINTLN(F("enqueued cmd failed/timeout")); if (mSerialDebug) { - DPRINTHEAD(DBG_INFO, iv->id); + DPRINT_IVID(DBG_INFO, iv->id); DBGPRINT(F("no Payload received! (retransmits: ")); DBGPRINT(String(mPayload[iv->id].retransmits)); DBGPRINTLN(F(")")); @@ -111,14 +111,14 @@ class MiPayload { yield(); if (mSerialDebug){ - DPRINTHEAD(DBG_INFO, iv->id); + DPRINT_IVID(DBG_INFO, iv->id); DBGPRINT(F("Requesting Inv SN ")); DBGPRINTLN(String(iv->config->serial.u64, HEX)); } if (iv->getDevControlRequest()) { if (mSerialDebug) { - DPRINTHEAD(DBG_INFO, iv->id); + DPRINT_IVID(DBG_INFO, iv->id); DBGPRINT(F("Devcontrol request 0x")); DHEX(iv->devControlCmd); DBGPRINT(F(" power limit ")); @@ -132,9 +132,9 @@ class MiPayload { iv->enqueCommand(SystemConfigPara); // try to read back power limit } else { uint8_t cmd = iv->getQueuedCmd(); - DPRINTHEAD(DBG_INFO, iv->id); + DPRINT_IVID(DBG_INFO, iv->id); DBGPRINT(F("prepareDevInformCmd 0x")); - DHEXLN(cmd); + DBGHEXLN(cmd); uint8_t cmd2 = cmd; if ( cmd == SystemConfigPara ) { //0x05 for HM-types if (!mPayload[iv->id].limitrequested) { // only do once at startup @@ -180,7 +180,8 @@ class MiPayload { else if ( p->packet[0] == 0x09 + ALL_FRAMES || p->packet[0] == 0x11 + ALL_FRAMES || - ( p->packet[0] >= (0x36 + ALL_FRAMES) && p->packet[0] < (0x39 + SINGLE_FRAME) ) ) { // small MI or MI 1500 data responses to 0x09, 0x11, 0x36, 0x37, 0x38 and 0x39 + ( p->packet[0] >= (0x36 + ALL_FRAMES) && p->packet[0] < (0x39 + SINGLE_FRAME) + && mPayload[iv->id].txCmd != 0x0f) ) { // small MI or MI 1500 data responses to 0x09, 0x11, 0x36, 0x37, 0x38 and 0x39 mPayload[iv->id].txId = p->packet[0]; miDataDecode(iv,p); } @@ -231,13 +232,15 @@ const byteAssign_t InfoAssignment[] = { iv->setValue(i, rec, (float) ((p->packet[(12+2*i)] << 8) + p->packet[(13+2*i)])/1); } iv->isConnected = true; - DPRINTHEAD(DBG_INFO, iv->id); - DPRINT(DBG_INFO,F("HW_VER is ")); - DBGPRINTLN(String((p->packet[24] << 8) + p->packet[25])); + if(mSerialDebug) { + DPRINT_IVID(DBG_INFO, iv->id); + DPRINT(DBG_INFO,F("HW_VER is ")); + DBGPRINTLN(String((p->packet[24] << 8) + p->packet[25])); + } /*iv->setQueuedCmdFinished(); mSys->Radio.sendCmdPacket(iv->radioId.u64, 0x0f, 0x01, false);*/ } else if ( p->packet[9] == 0x01 || p->packet[9] == 0x10 ) {//second frame for MI, 3rd gen. answers in 0x10 - DPRINTHEAD(DBG_INFO, iv->id); + DPRINT_IVID(DBG_INFO, iv->id); if ( p->packet[9] == 0x01 ) { DBGPRINTLN(F("got 2nd frame (hw info)")); } else { @@ -248,18 +251,21 @@ const byteAssign_t InfoAssignment[] = { DBGPRINTLN(String((uint32_t) (((p->packet[10] << 8) | p->packet[11]) << 8 | p->packet[12]) << 8 | p->packet[13])); //DBGPRINTLN(String((p->packet[12] << 8) + p->packet[13])); if ( p->packet[9] == 0x01 ) { - DPRINT(DBG_INFO,F("HW_ECapValue ")); - DBGPRINTLN(String((p->packet[20] << 8) + p->packet[21])); iv->setValue(iv->getPosByChFld(0, FLD_YT, rec), rec, (float) ((p->packet[20] << 8) + p->packet[21])/1); - DPRINT(DBG_INFO,F("HW_FB_TLmValue ")); - DBGPRINTLN(String((p->packet[14] << 8) + p->packet[15])); - DPRINT(DBG_INFO,F("HW_FB_ReSPRT ")); - DBGPRINTLN(String((p->packet[16] << 8) + p->packet[17])); - DPRINT(DBG_INFO,F("HW_GridSamp_ResValule ")); - DBGPRINTLN(String((p->packet[18] << 8) + p->packet[19])); + if(mSerialDebug) { + DPRINT(DBG_INFO,F("HW_ECapValue ")); + DBGPRINTLN(String((p->packet[20] << 8) + p->packet[21])); + + DPRINT(DBG_INFO,F("HW_FB_TLmValue ")); + DBGPRINTLN(String((p->packet[14] << 8) + p->packet[15])); + DPRINT(DBG_INFO,F("HW_FB_ReSPRT ")); + DBGPRINTLN(String((p->packet[16] << 8) + p->packet[17])); + DPRINT(DBG_INFO,F("HW_GridSamp_ResValule ")); + DBGPRINTLN(String((p->packet[18] << 8) + p->packet[19])); + } } } else if ( p->packet[9] == 0x12 ) {//3rd frame - DPRINTHEAD(DBG_INFO, iv->id); + DPRINT_IVID(DBG_INFO, iv->id); DBGPRINTLN(F("got 3rd frame (hw info)")); iv->setQueuedCmdFinished(); mStat->rxSuccess++; @@ -276,9 +282,8 @@ const byteAssign_t InfoAssignment[] = { DPRINT(DBG_DEBUG, F("fragment number zero received")); iv->setQueuedCmdFinished(); } else if (p->packet[9] == 0x81) { // might need some additional check, as this is only ment for short answers! - DPRINT(DBG_WARN, F("(#")); - DBGPRINT(String(iv->id)); - DBGPRINTLN(F(") seems to use 3rd gen. protocol - switching ivGen!")); + DPRINT_IVID(DBG_WARN, iv->id); + DBGPRINTLN(F("seems to use 3rd gen. protocol - switching ivGen!")); iv->ivGen = IV_HM; iv->setQueuedCmdFinished(); iv->clearCmdQueue(); @@ -301,7 +306,7 @@ const byteAssign_t InfoAssignment[] = { //} } else if (p->packet[0] == (TX_REQ_DEVCONTROL + ALL_FRAMES ) // response from dev control command || p->packet[0] == (TX_REQ_DEVCONTROL + ALL_FRAMES -1)) { // response from DRED instruction - DPRINTHEAD(DBG_DEBUG, iv->id); + DPRINT_IVID(DBG_DEBUG, iv->id); DBGPRINTLN(F("Response from devcontrol request received")); mPayload[iv->id].txId = p->packet[0]; @@ -309,7 +314,7 @@ const byteAssign_t InfoAssignment[] = { if ((p->packet[9] == 0x5a) && (p->packet[10] == 0x5a)) { mApp->setMqttPowerLimitAck(iv); - DPRINTHEAD(DBG_INFO, iv->id); + DPRINT_IVID(DBG_INFO, iv->id); DBGPRINT(F("has accepted power limit set point ")); DBGPRINT(String(iv->powerLimit[0])); DBGPRINT(F(" with PowerLimitControl ")); @@ -321,9 +326,9 @@ const byteAssign_t InfoAssignment[] = { iv->devControlCmd = Init; } else { // some other response; copied from hmPayload:process; might not be correct to do that here!!! DPRINT(DBG_INFO, F("procPyld: cmd: 0x")); - DHEXLN(mPayload[iv->id].txCmd); + DBGHEXLN(mPayload[iv->id].txCmd); DPRINT(DBG_INFO, F("procPyld: txid: 0x")); - DHEXLN(mPayload[iv->id].txId); + DBGHEXLN(mPayload[iv->id].txId); //DPRINT(DBG_DEBUG, F("procPyld: max: ")); //DBGPRINTLN(String(mPayload[iv->id].maxPackId)); record_t<> *rec = iv->getRecordStruct(mPayload[iv->id].txCmd); // choose the parser @@ -420,11 +425,11 @@ const byteAssign_t InfoAssignment[] = { if ((mPayload[iv->id].requested) && (retransmit)) { if (iv->devControlCmd == Restart || iv->devControlCmd == CleanState_LockAndAlarm) { // This is required to prevent retransmissions without answer. - DPRINTHEAD(DBG_INFO, iv->id); + DPRINT_IVID(DBG_INFO, iv->id); DBGPRINTLN(F("Prevent retransmit on Restart / CleanState_LockAndAlarm...")); mPayload[iv->id].retransmits = mMaxRetrans; } else if(iv->devControlCmd == ActivePowerContr) { - DPRINTHEAD(DBG_INFO, iv->id); + DPRINT_IVID(DBG_INFO, iv->id); DBGPRINTLN(F("retransmit power limit")); mSys->Radio.sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, true, false); } else { @@ -432,7 +437,7 @@ const byteAssign_t InfoAssignment[] = { if (mPayload[iv->id].retransmits < mMaxRetrans) { mPayload[iv->id].retransmits++; if( !mPayload[iv->id].gotFragment ) { - DPRINTHEAD(DBG_INFO, iv->id); + DPRINT_IVID(DBG_INFO, iv->id); DBGPRINTLN(F("nothing received")); mPayload[iv->id].retransmits = mMaxRetrans; } else if ( cmd == 0x0f ) { @@ -463,7 +468,7 @@ const byteAssign_t InfoAssignment[] = { } } } - DPRINTHEAD(DBG_INFO, iv->id); + DPRINT_IVID(DBG_INFO, iv->id); if (change) { DBGPRINT(F("next request is")); //mPayload[iv->id].skipfirstrepeat = 0; @@ -472,7 +477,7 @@ const byteAssign_t InfoAssignment[] = { DBGPRINT(F(" missing: Request Retransmit")); } DBGPRINT(F(" 0x")); - DHEXLN(cmd); + DBGHEXLN(cmd); //mSys->Radio.sendCmdPacket(iv->radioId.u64, cmd, cmd, true); mSys->Radio.prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmMesIndex, true, cmd); mPayload[iv->id].txCmd = cmd; @@ -484,13 +489,13 @@ const byteAssign_t InfoAssignment[] = { } else if(!crcPass && pyldComplete) { // crc error on complete Payload if (mPayload[iv->id].retransmits < mMaxRetrans) { mPayload[iv->id].retransmits++; - DPRINTHEAD(DBG_WARN, iv->id); + DPRINT_IVID(DBG_WARN, iv->id); DBGPRINTLN(F("CRC Error: Request Complete Retransmit")); mPayload[iv->id].txCmd = iv->getQueuedCmd(); - DPRINTHEAD(DBG_INFO, iv->id); + DPRINT_IVID(DBG_INFO, iv->id); DBGPRINT(F("prepareDevInformCmd 0x")); - DHEXLN(mPayload[iv->id].txCmd); + DBGHEXLN(mPayload[iv->id].txCmd); mSys->Radio.prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true); } } @@ -574,8 +579,8 @@ const byteAssign_t InfoAssignment[] = { void miStsConsolidate(Inverter<> *iv, uint8_t stschan, record_t<> *rec, uint8_t uState, uint8_t uEnum, uint8_t lState = 0, uint8_t lEnum = 0) { //uint8_t status = (p->packet[11] << 8) + p->packet[12]; uint16_t status = 3; // regular status for MI, change to 1 later? - if ( uState < 3 ) { - status = uState*100 + stschan; //first approach, needs review! + if ( uState == 2 ) { + status = 5050 + stschan; //first approach, needs review! if (lState) status += lState*10; } else if ( uState > 3 ) { @@ -587,13 +592,16 @@ const byteAssign_t InfoAssignment[] = { if (uEnum < 6) { status += stschan; } + if (status == 8000) + status == 8310; //trick? } uint16_t prntsts = status == 3 ? 1 : status; if ( status != mPayload[iv->id].sts[stschan] ) { //sth.'s changed? mPayload[iv->id].sts[stschan] = status; DPRINT(DBG_WARN, F("Status change for CH")); - DBGPRINT(String(stschan)); DBGPRINT(F(": ")); + DBGPRINT(String(stschan)); DBGPRINT(F(" (")); + DBGPRINT(String(prntsts)); DBGPRINT(F("): ")); DBGPRINTLN(iv->getAlarmStr(prntsts)); } @@ -605,7 +613,7 @@ const byteAssign_t InfoAssignment[] = { if (iv->alarmMesIndex < rec->record[iv->getPosByChFld(0, FLD_EVT, rec)]){ iv->alarmMesIndex = rec->record[iv->getPosByChFld(0, FLD_EVT, rec)]; // seems there's no status per channel in 3rd gen. models?!? - DPRINTHEAD(DBG_INFO, iv->id); + DPRINT_IVID(DBG_INFO, iv->id); DBGPRINT(F("alarm ID incremented to ")); DBGPRINTLN(String(iv->alarmMesIndex)); } @@ -692,7 +700,7 @@ const byteAssign_t InfoAssignment[] = { /*if (iv->alarmMesIndex < rec->record[iv->getPosByChFld(0, FLD_EVT, rec)]){ iv->alarmMesIndex = rec->record[iv->getPosByChFld(0, FLD_EVT, rec)]; - DPRINTHEAD(DBG_INFO, iv->id); + DPRINT_IVID(DBG_INFO, iv->id); DBGPRINT_TXT(TXT_INCRALM); DBGPRINTLN(String(iv->alarmMesIndex)); }*/ @@ -728,7 +736,7 @@ const byteAssign_t InfoAssignment[] = { if (mPayload[iv->id].complete) return; //if we got second message as well in repreated attempt mPayload[iv->id].complete = true; // For 2 CH devices, this might be too short... - DPRINTHEAD(DBG_INFO, iv->id); + DPRINT_IVID(DBG_INFO, iv->id); DBGPRINTLN(F("got all msgs")); record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug); iv->setValue(iv->getPosByChFld(0, FLD_YD, rec), rec, calcYieldDayCh0(iv,0)); @@ -753,38 +761,23 @@ const byteAssign_t InfoAssignment[] = { bool build(uint8_t id, bool *complete) { DPRINTLN(DBG_VERBOSE, F("build")); - //DPRINTLN_TXT(DBG_VERBOSE, TXT_BUILD); - /*uint16_t crc = 0xffff, crcRcv = 0x0000; - if (mPayload[id].maxPackId > MAX_PAYLOAD_ENTRIES) - mPayload[id].maxPackId = MAX_PAYLOAD_ENTRIES; - */ // check if all messages are there *complete = mPayload[id].complete; uint8_t txCmd = mPayload[id].txCmd; - //uint8_t cmd = getQueuedCmd(); + if(!*complete) { - DPRINTLN(DBG_VERBOSE, F("incomlete, txCmd is 0x") + String(txCmd, HEX)); // + F("cmd is 0x") + String(cmd, HEX)); + DPRINTLN(DBG_VERBOSE, F("incomlete, txCmd is 0x") + String(txCmd, HEX)); + //DBGHEXLN(txCmd); if (txCmd == 0x09 || txCmd == 0x11 || (txCmd >= 0x36 && txCmd <= 0x39)) return false; } - /*for (uint8_t i = 0; i < mPayload[id].maxPackId; i++) { - if (mPayload[id].len[i] > 0) { - if (i == (mPayload[id].maxPackId - 1)) { - crc = ah::crc16(mPayload[id].data[i], mPayload[id].len[i] - 2, crc); - crcRcv = (mPayload[id].data[i][mPayload[id].len[i] - 2] << 8) | (mPayload[id].data[i][mPayload[id].len[i] - 1]); - } else - crc = ah::crc16(mPayload[id].data[i], mPayload[id].len[i], crc); - } - yield(); - } - return (crc == crcRcv) ? true : false;*/ return true; } void reset(uint8_t id, bool clrSts = false) { - DPRINTHEAD(DBG_INFO, id); + DPRINT_IVID(DBG_INFO, id); DBGPRINTLN(F("resetPayload")); memset(mPayload[id].len, 0, MAX_PAYLOAD_ENTRIES); mPayload[id].gotFragment = false; diff --git a/src/utils/dbg.h b/src/utils/dbg.h index cae96447..c9947dd0 100644 --- a/src/utils/dbg.h +++ b/src/utils/dbg.h @@ -61,8 +61,9 @@ } } - inline void DHEXLN(uint8_t b) { - DHEX(b); + inline void DBGHEXLN(uint8_t b) { + if( b<0x10 ) DBGPRINT(F("0")); + DBGPRINT(String(b, HEX)); DBGPRINT(F("\r\n")); } /*inline void DHEX(uint16_t b) { @@ -151,7 +152,7 @@ }\ }) -#define DPRINTHEAD(level, id) ({\ +#define DPRINT_IVID(level, id) ({\ DPRINT(level, F("(#")); DBGPRINT(String(id)); DBGPRINT(F(") "));\ }) From c1e71288464fba993a82edf7120bfa069f05c4a2 Mon Sep 17 00:00:00 2001 From: rejoe2 Date: Fri, 24 Mar 2023 15:33:26 +0100 Subject: [PATCH 2/6] debug review --- src/hm/hmRadio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index ff45a72d..c47d0fec 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -295,7 +295,7 @@ class HmRadio { } void initPacket(uint64_t invId, uint8_t mid, uint8_t pid) { - DPRINT(DBG_VERBOSE, F("initPacket, mid: ") + String(mid, HEX) + F(" pid: ") + String(pid, HEX)); + DPRINTLN(DBG_VERBOSE, F("initPacket, mid: ") + String(mid, HEX) + F(" pid: ") + String(pid, HEX)); memset(mTxBuf, 0, MAX_RF_PAYLOAD_SIZE); mTxBuf[0] = mid; // message id CP_U32_BigEndian(&mTxBuf[1], (invId >> 8)); From 03b1eb126c652045fff35d629ece92dcfb26a765 Mon Sep 17 00:00:00 2001 From: rejoe2 Date: Fri, 24 Mar 2023 16:12:21 +0100 Subject: [PATCH 3/6] MI - small bugfix --- src/hm/miPayload.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hm/miPayload.h b/src/hm/miPayload.h index 753134d5..44f79e08 100644 --- a/src/hm/miPayload.h +++ b/src/hm/miPayload.h @@ -593,7 +593,7 @@ const byteAssign_t InfoAssignment[] = { status += stschan; } if (status == 8000) - status == 8310; //trick? + status = 8310; //trick? } uint16_t prntsts = status == 3 ? 1 : status; From a1fb4aa911fad7562d62e0481dd6ebfb5ae34b5e Mon Sep 17 00:00:00 2001 From: rejoe2 Date: Fri, 24 Mar 2023 17:01:43 +0100 Subject: [PATCH 4/6] MI - fix length for command packets --- src/hm/hmRadio.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index c47d0fec..a9564196 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -208,6 +208,7 @@ class HmRadio { default: return; } + cnt++; } sendPacket(invId, cnt, isRetransmit, true); } From 3f2e40848ecbbefa2727884cf1038a623783fdb9 Mon Sep 17 00:00:00 2001 From: lumapu Date: Fri, 24 Mar 2023 23:26:35 +0100 Subject: [PATCH 5/6] review #804 --- src/hm/hmInverter.h | 9 ++++----- src/hm/hmPayload.h | 46 ++++++++++++--------------------------------- src/utils/dbg.h | 3 +-- 3 files changed, 17 insertions(+), 41 deletions(-) diff --git a/src/hm/hmInverter.h b/src/hm/hmInverter.h index c098a081..e8c20423 100644 --- a/src/hm/hmInverter.h +++ b/src/hm/hmInverter.h @@ -144,10 +144,8 @@ class Inverter { void enqueCommand(uint8_t cmd) { _commandQueue.push(std::make_shared(cmd)); DPRINT_IVID(DBG_INFO, id); - //DPRINT(DBG_INFO, F("(#")); - //DBGPRINT(String(id)); - DBGPRINTLN(F("enqueCommand: 0x") + String(cmd, HEX)); - //DBGHEXLN(cmd); + DBGPRINTLN(F("enqueCommand: 0x")); + DBGHEXLN(cmd); } void setQueuedCmdFinished() { @@ -305,7 +303,8 @@ class Inverter { DPRINTLN(DBG_DEBUG, "add config"); if (getPosByChFld(0, FLD_ACT_ACTIVE_PWR_LIMIT, rec) == pos){ actPowerLimit = rec->record[pos]; - DPRINTLN(DBG_DEBUG, F("Inverter actual power limit: ") + String(actPowerLimit, 1)); + DPRINT(DBG_DEBUG, F("Inverter actual power limit: ")); + DBGPRINTLN(String(actPowerLimit, 1)); } } else if (rec->assign == AlarmDataAssignment) { diff --git a/src/hm/hmPayload.h b/src/hm/hmPayload.h index 7dda7e6f..01282b00 100644 --- a/src/hm/hmPayload.h +++ b/src/hm/hmPayload.h @@ -118,10 +118,6 @@ class HmPayload { iv->setQueuedCmdFinished(); // command failed if (mSerialDebug) { DPRINTLN(DBG_INFO, F("enqueued cmd failed/timeout")); - //if (mSerialDebug) { - //DPRINT(DBG_INFO, F("(#")); - //DBGPRINT(String(iv->id)); - //DBGPRINT(F(") no Payload received! (retransmits: ")); DPRINT_IVID(DBG_INFO, iv->id); DBGPRINT(F("no Payload received! (retransmits: ")); DBGPRINT(String(mPayload[iv->id].retransmits)); @@ -137,18 +133,12 @@ class HmPayload { yield(); if (mSerialDebug) { DPRINT_IVID(DBG_INFO, iv->id); - //DPRINT(DBG_INFO, F("(#")); - //DBGPRINT(String(iv->id)); - //DBGPRINT(F(") Requesting Inv SN ")); DBGPRINT(F("Requesting Inv SN ")); DBGPRINTLN(String(iv->config->serial.u64, HEX)); } if (iv->getDevControlRequest()) { if (mSerialDebug) { - //DPRINT(DBG_INFO, F("(#")); - //DBGPRINT(String(iv->id)); - //DBGPRINT(F(") Devcontrol request 0x")); DPRINT_IVID(DBG_INFO, iv->id); DBGPRINT(F("Devcontrol request 0x")); DBGPRINT(String(iv->devControlCmd, HEX)); @@ -161,9 +151,6 @@ class HmPayload { //iv->enqueCommand(SystemConfigPara); // read back power limit } else { uint8_t cmd = iv->getQueuedCmd(); - //DPRINT(DBG_INFO, F("(#")); - //DBGPRINT(String(iv->id)); - //DBGPRINT(F(") prepareDevInformCmd 0x")); DPRINT_IVID(DBG_INFO, iv->id); DBGPRINT(F("prepareDevInformCmd 0x")); DBGHEXLN(cmd); @@ -180,7 +167,8 @@ class HmPayload { if (*pid == 0x00) { DPRINTLN(DBG_DEBUG, F("fragment number zero received and ignored")); } else { - DPRINTLN(DBG_DEBUG, F("PID: 0x") + String(*pid, HEX)); + DPRINT(DBG_DEBUG, F("PID: 0x")); + DBGHEXLN(*pid); if ((*pid & 0x7F) < MAX_PAYLOAD_ENTRIES) { memcpy(mPayload[iv->id].data[(*pid & 0x7F) - 1], &p->packet[10], p->len - 11); mPayload[iv->id].len[(*pid & 0x7F) - 1] = p->len - 11; @@ -208,17 +196,14 @@ class HmPayload { mApp->setMqttPowerLimitAck(iv); else ok = false; - //DPRINT(DBG_INFO, F("(#")); - //DBGPRINT(String(iv->id)); - if (mSerialDebug) { - DPRINT_IVID(DBG_INFO, iv->id); - DBGPRINT(F(" has ")); - if(!ok) DBGPRINT(F("not ")); - DBGPRINT(F("accepted power limit set point ")); - DBGPRINT(String(iv->powerLimit[0])); - DBGPRINT(F(" with PowerLimitControl ")); - DBGPRINTLN(String(iv->powerLimit[1])); - } + + DPRINT_IVID(DBG_INFO, iv->id); + DBGPRINT(F("has ")); + if(!ok) DBGPRINT(F("not ")); + DBGPRINT(F("accepted power limit set point ")); + DBGPRINT(String(iv->powerLimit[0])); + DBGPRINT(F(" with PowerLimitControl ")); + DBGPRINTLN(String(iv->powerLimit[1])); iv->clearCmdQueue(); iv->enqueCommand(SystemConfigPara); // read back power limit @@ -254,8 +239,6 @@ class HmPayload { DPRINTLN(DBG_INFO, F("Prevent retransmit on Restart / CleanState_LockAndAlarm...")); mPayload[iv->id].retransmits = mMaxRetrans; } else if(iv->devControlCmd == ActivePowerContr) { - //DPRINT(DBG_INFO, F("(#")); - //DBGPRINT(String(iv->id)); DPRINT_IVID(DBG_INFO, iv->id); DPRINTLN(DBG_INFO, F("retransmit power limit")); mSys->Radio.sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, true); @@ -267,16 +250,12 @@ class HmPayload { DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") prepareDevInformCmd 0x") + String(mPayload[iv->id].txCmd, HEX)); mSys->Radio.prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true); */ - //DPRINT(DBG_INFO, F("(#")); - //DBGPRINT(String(iv->id)); DPRINT_IVID(DBG_INFO, iv->id); DBGPRINTLN(F("nothing received")); mPayload[iv->id].retransmits = mMaxRetrans; } else { for (uint8_t i = 0; i < (mPayload[iv->id].maxPackId - 1); i++) { if (mPayload[iv->id].len[i] == 0) { - //DPRINT(DBG_WARN, F("(#")); - //DBGPRINT(String(iv->id)); DPRINT_IVID(DBG_WARN, iv->id); DBGPRINT(F("Frame ")); DBGPRINT(String(i + 1)); @@ -295,8 +274,6 @@ class HmPayload { mPayload[iv->id].retransmits++; DPRINTLN(DBG_WARN, F("CRC Error: Request Complete Retransmit")); mPayload[iv->id].txCmd = iv->getQueuedCmd(); - //DPRINT(DBG_INFO, F("(#")); - //DBGPRINT(String(iv->id)); DPRINT_IVID(DBG_INFO, iv->id); DBGPRINT(F("prepareDevInformCmd 0x")); DBGHEXLN(mPayload[iv->id].txCmd); @@ -307,7 +284,8 @@ class HmPayload { DBGHEXLN(mPayload[iv->id].txCmd); DPRINT(DBG_INFO, F("procPyld: txid: 0x")); DBGHEXLN(mPayload[iv->id].txId); - DPRINTLN(DBG_DEBUG, F("procPyld: max: ") + String(mPayload[iv->id].maxPackId)); + DPRINT(DBG_DEBUG, F("procPyld: max: ")); + DBGPRINTLN(String(mPayload[iv->id].maxPackId)); record_t<> *rec = iv->getRecordStruct(mPayload[iv->id].txCmd); // choose the parser mPayload[iv->id].complete = true; diff --git a/src/utils/dbg.h b/src/utils/dbg.h index c9947dd0..4716d7ae 100644 --- a/src/utils/dbg.h +++ b/src/utils/dbg.h @@ -62,8 +62,7 @@ } inline void DBGHEXLN(uint8_t b) { - if( b<0x10 ) DBGPRINT(F("0")); - DBGPRINT(String(b, HEX)); + DHEX(b); DBGPRINT(F("\r\n")); } /*inline void DHEX(uint16_t b) { From 850cda3c384c104fc46f2b29043d4e739e88c2a5 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sat, 25 Mar 2023 02:10:16 +0100 Subject: [PATCH 6/6] 0.5.106 * merged MI and debug message changes #804 * fixed MQTT autodiscover #794, #632 --- src/CHANGES.md | 4 + src/defines.h | 2 +- src/platformio.ini | 19 ++-- src/publisher/pubMqtt.h | 191 ++++++++++++++++++++++------------------ 4 files changed, 117 insertions(+), 99 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index 4223ad99..70b87e0f 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -2,6 +2,10 @@ (starting from release version `0.5.66`) +## 0.5.106 +* merged MI and debug message changes #804 +* fixed MQTT autodiscover #794, #632 + ## 0.5.105 * merged MI, thx @rejoe2 #788 * fixed reboot message #793 diff --git a/src/defines.h b/src/defines.h index dafcb9ec..d0c57264 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 5 -#define VERSION_PATCH 105 +#define VERSION_PATCH 106 //------------------------------------- typedef struct { diff --git a/src/platformio.ini b/src/platformio.ini index 6d3f8d23..38e67c95 100644 --- a/src/platformio.ini +++ b/src/platformio.ini @@ -35,25 +35,20 @@ extra_scripts = lib_deps = https://github.com/yubox-node-org/ESPAsyncWebServer - nrf24/RF24 - paulstoffregen/Time + nrf24/RF24 @ ^1.4.5 + paulstoffregen/Time @ ^1.6.1 https://github.com/bertmelis/espMqttClient#v1.4.1 - bblanchon/ArduinoJson - https://github.com/JChristensen/Timezone - olikraus/U8g2 - zinggjm/GxEPD2@^1.5.0 - ;esp8266/DNSServer - ;esp8266/EEPROM - ;esp8266/ESP8266WiFi - ;esp8266/SPI - ;esp8266/Ticker + bblanchon/ArduinoJson @ ^6.21.0 + https://github.com/JChristensen/Timezone @ ^1.2.4 + olikraus/U8g2 @ ^2.34.16 + zinggjm/GxEPD2 @ ^1.5.0 [env:esp8266-release] platform = espressif8266 board = esp12e board_build.f_cpu = 80000000L -build_flags = -D RELEASE +build_flags = -D RELEASE -Wl,-Map,output.map monitor_filters = ;default ; Remove typical terminal control codes from input ;time ; Add timestamp with milliseconds for each new line diff --git a/src/publisher/pubMqtt.h b/src/publisher/pubMqtt.h index 73196918..a529d1fc 100644 --- a/src/publisher/pubMqtt.h +++ b/src/publisher/pubMqtt.h @@ -34,6 +34,12 @@ struct alarm_t { alarm_t(uint16_t c, uint32_t s, uint32_t e) : code(c), start(s), end(e) {} }; +typedef struct { + bool running; + uint8_t lastIvId; + uint8_t sub; +} discovery_t; + template class PubMqtt { public: @@ -55,6 +61,8 @@ class PubMqtt { mUtcTimestamp = utcTs; mIntervalTimeout = 1; + mDiscovery.running = false; + snprintf(mLwtTopic, MQTT_TOPIC_LEN + 5, "%s/mqtt", mCfgMqtt->topic); if((strlen(mCfgMqtt->user) > 0) && (strlen(mCfgMqtt->pwd) > 0)) @@ -82,6 +90,9 @@ class PubMqtt { mClient.loop(); yield(); #endif + + if(mDiscovery.running) + discoveryConfigLoop(); } @@ -210,92 +221,9 @@ class PubMqtt { void sendDiscoveryConfig(void) { DPRINTLN(DBG_VERBOSE, F("sendMqttDiscoveryConfig")); - - char topic[64], name[32], uniq_id[32]; - DynamicJsonDocument doc(256); - - uint8_t fldTotal[4] = {FLD_PAC, FLD_YT, FLD_YD, FLD_PDC}; - const char* unitTotal[4] = {"W", "kWh", "Wh", "W"}; - - String node_mac = WiFi.macAddress().substring(12,14)+ WiFi.macAddress().substring(15,17); - String node_id = "AHOY_DTU_" + node_mac; - bool total = false; - - for (uint8_t id = 0; id < mSys->getNumInverters() ; id++) { - doc.clear(); - - if (total) // total become true at iv = NULL next cycle - continue; - - Inverter<> *iv = mSys->getInverterByPos(id); - if (NULL == iv) - total = true; - record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug); - - if (!total) { - doc[F("name")] = iv->config->name; - doc[F("ids")] = String(iv->config->serial.u64, HEX); - doc[F("mdl")] = iv->config->name; - } - else { - doc[F("name")] = node_id; - doc[F("ids")] = node_id; - doc[F("mdl")] = node_id; - } - - doc[F("cu")] = F("http://") + String(WiFi.localIP().toString()); - doc[F("mf")] = F("Hoymiles"); - JsonObject deviceObj = doc.as(); // deviceObj is only pointer!? - - for (uint8_t i = 0; i < ((!total) ? (rec->length) : (4) ) ; i++) { - const char *devCls, *stateCls; - if (!total) { - if (rec->assign[i].ch == CH0) - snprintf(name, 32, "%s %s", iv->config->name, iv->getFieldName(i, rec)); - else - snprintf(name, 32, "%s CH%d %s", iv->config->name, rec->assign[i].ch, iv->getFieldName(i, rec)); - snprintf(topic, 64, "/ch%d/%s", rec->assign[i].ch, iv->getFieldName(i, rec)); - snprintf(uniq_id, 32, "ch%d_%s", rec->assign[i].ch, iv->getFieldName(i, rec)); - - devCls = getFieldDeviceClass(rec->assign[i].fieldId); - stateCls = getFieldStateClass(rec->assign[i].fieldId); - } - - else { // total values - snprintf(name, 32, "Total %s", fields[fldTotal[i]]); - snprintf(topic, 64, "/%s", fields[fldTotal[i]]); - snprintf(uniq_id, 32, "total_%s", fields[fldTotal[i]]); - devCls = getFieldDeviceClass(fldTotal[i]); - stateCls = getFieldStateClass(fldTotal[i]); - } - - DynamicJsonDocument doc2(512); - doc2[F("name")] = name; - doc2[F("stat_t")] = String(mCfgMqtt->topic) + "/" + ((!total) ? String(iv->config->name) : "total" ) + String(topic); - doc2[F("unit_of_meas")] = ((!total) ? (iv->getUnit(i,rec)) : (unitTotal[i])); - doc2[F("uniq_id")] = ((!total) ? (String(iv->config->serial.u64, HEX)) : (node_id)) + "_" + uniq_id; - doc2[F("dev")] = deviceObj; - if (!(String(stateCls) == String("total_increasing"))) - doc2[F("exp_aft")] = MQTT_INTERVAL + 5; // add 5 sec if connection is bad or ESP too slow @TODO: stimmt das wirklich als expire!? - if (devCls != NULL) - doc2[F("dev_cla")] = String(devCls); - if (stateCls != NULL) - doc2[F("stat_cla")] = String(stateCls); - - if (!total) - snprintf(topic, 64, "%s/sensor/%s/ch%d_%s/config", MQTT_DISCOVERY_PREFIX, iv->config->name, rec->assign[i].ch, iv->getFieldName(i, rec)); - else // total values - snprintf(topic, 64, "%s/sensor/%s/total_%s/config", MQTT_DISCOVERY_PREFIX, node_id.c_str(),fields[fldTotal[i]]); - size_t size = measureJson(doc2) + 1; - char *buf = new char[size]; - memset(buf, 0, size); - serializeJson(doc2, buf, size); - publish(topic, buf, true, false); - delete[] buf; - } - - yield(); - } + mDiscovery.running = true; + mDiscovery.lastIvId = 0; + mDiscovery.sub = 0; } void setPowerLimitAck(Inverter<> *iv) { @@ -415,6 +343,95 @@ class PubMqtt { mRxCnt++; } + void discoveryConfigLoop(void) { + char topic[64], name[32], uniq_id[32], buf[350]; + DynamicJsonDocument doc(256); + + uint8_t fldTotal[4] = {FLD_PAC, FLD_YT, FLD_YD, FLD_PDC}; + const char* unitTotal[4] = {"W", "kWh", "Wh", "W"}; + + String node_mac = WiFi.macAddress().substring(12,14)+ WiFi.macAddress().substring(15,17); + String node_id = "AHOY_DTU_" + node_mac; + bool total = (mDiscovery.lastIvId == MAX_NUM_INVERTERS); + + Inverter<> *iv = mSys->getInverterByPos(mDiscovery.lastIvId); + record_t<> *rec; + if (NULL != iv) + rec = iv->getRecordStruct(RealTimeRunData_Debug); + + if ((NULL != iv) || total) { + if (!total) { + doc[F("name")] = iv->config->name; + doc[F("ids")] = String(iv->config->serial.u64, HEX); + doc[F("mdl")] = iv->config->name; + } + else { + doc[F("name")] = node_id; + doc[F("ids")] = node_id; + doc[F("mdl")] = node_id; + } + + doc[F("cu")] = F("http://") + String(WiFi.localIP().toString()); + doc[F("mf")] = F("Hoymiles"); + JsonObject deviceObj = doc.as(); // deviceObj is only pointer!? + + const char *devCls, *stateCls; + if (!total) { + if (rec->assign[mDiscovery.sub].ch == CH0) + snprintf(name, 32, "%s %s", iv->config->name, iv->getFieldName(mDiscovery.sub, rec)); + else + snprintf(name, 32, "%s CH%d %s", iv->config->name, rec->assign[mDiscovery.sub].ch, iv->getFieldName(mDiscovery.sub, rec)); + snprintf(topic, 64, "/ch%d/%s", rec->assign[mDiscovery.sub].ch, iv->getFieldName(mDiscovery.sub, rec)); + snprintf(uniq_id, 32, "ch%d_%s", rec->assign[mDiscovery.sub].ch, iv->getFieldName(mDiscovery.sub, rec)); + + devCls = getFieldDeviceClass(rec->assign[mDiscovery.sub].fieldId); + stateCls = getFieldStateClass(rec->assign[mDiscovery.sub].fieldId); + } + + else { // total values + snprintf(name, 32, "Total %s", fields[fldTotal[mDiscovery.sub]]); + snprintf(topic, 64, "/%s", fields[fldTotal[mDiscovery.sub]]); + snprintf(uniq_id, 32, "total_%s", fields[fldTotal[mDiscovery.sub]]); + devCls = getFieldDeviceClass(fldTotal[mDiscovery.sub]); + stateCls = getFieldStateClass(fldTotal[mDiscovery.sub]); + } + + DynamicJsonDocument doc2(512); + doc2[F("name")] = name; + doc2[F("stat_t")] = String(mCfgMqtt->topic) + "/" + ((!total) ? String(iv->config->name) : "total" ) + String(topic); + doc2[F("unit_of_meas")] = ((!total) ? (iv->getUnit(mDiscovery.sub, rec)) : (unitTotal[mDiscovery.sub])); + doc2[F("uniq_id")] = ((!total) ? (String(iv->config->serial.u64, HEX)) : (node_id)) + "_" + uniq_id; + doc2[F("dev")] = deviceObj; + if (!(String(stateCls) == String("total_increasing"))) + doc2[F("exp_aft")] = MQTT_INTERVAL + 5; // add 5 sec if connection is bad or ESP too slow @TODO: stimmt das wirklich als expire!? + if (devCls != NULL) + doc2[F("dev_cla")] = String(devCls); + if (stateCls != NULL) + doc2[F("stat_cla")] = String(stateCls); + + if (!total) + snprintf(topic, 64, "%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 + snprintf(topic, 64, "%s/sensor/%s/total_%s/config", MQTT_DISCOVERY_PREFIX, node_id.c_str(),fields[fldTotal[mDiscovery.sub]]); + size_t size = measureJson(doc2) + 1; + memset(buf, 0, size); + serializeJson(doc2, buf, size); + publish(topic, buf, true, false); + + if(++mDiscovery.sub == ((!total) ? (rec->length) : 4)) { + mDiscovery.sub = 0; + if(++mDiscovery.lastIvId == (MAX_NUM_INVERTERS + 1)) + mDiscovery.running = false; + } + } else { + mDiscovery.sub = 0; + if(++mDiscovery.lastIvId == (MAX_NUM_INVERTERS + 1)) + mDiscovery.running = false; + } + + yield(); + } + const char *getFieldDeviceClass(uint8_t fieldId) { uint8_t pos = 0; for (; pos < DEVICE_CLS_ASSIGN_LIST_LEN; pos++) { @@ -643,6 +660,8 @@ class PubMqtt { char mClientId[24]; // number of chars is limited to 23 up to v3.1 of MQTT // global buffer for mqtt topic. Used when publishing mqtt messages. char mTopic[MQTT_TOPIC_LEN + 32 + MAX_NAME_LENGTH + 1]; + + discovery_t mDiscovery; }; #endif /*__PUB_MQTT_H__*/