From 21c5bdabb2e0862b8126202f4e0df6640b9374fc Mon Sep 17 00:00:00 2001 From: rejoe2 Date: Wed, 8 Feb 2023 08:04:46 +0100 Subject: [PATCH 1/4] MI integration in 0.5.82 Seems to still work for 3rd Gen... --- src/defines.h | 4 +- src/hm/hmPayload.h | 12 +++--- src/hm/hmRadio.h | 6 +-- src/hm/miPayload.h | 104 +++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 106 insertions(+), 20 deletions(-) diff --git a/src/defines.h b/src/defines.h index af32bc156..609acacb7 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 5 -#define VERSION_PATCH 82 +#define VERSION_PATCH 821 //------------------------------------- typedef struct { @@ -69,7 +69,7 @@ union serial_u { uint8_t b[8]; }; -#define MIN_SERIAL_INTERVAL 5 +#define MIN_SERIAL_INTERVAL 2 // 5 #define MIN_SEND_INTERVAL 15 #define MIN_MQTT_INTERVAL 60 diff --git a/src/hm/hmPayload.h b/src/hm/hmPayload.h index ab9a8e327..d59ca5dd3 100644 --- a/src/hm/hmPayload.h +++ b/src/hm/hmPayload.h @@ -148,8 +148,8 @@ class HmPayload { //iv->enqueCommand(SystemConfigPara); // read back power limit } else { uint8_t cmd = iv->getQueuedCmd(); - DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") sendTimePacket")); // + String(cmd, HEX)); - mSys->Radio.sendTimePacket(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmMesIndex, false); + DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") prepareDevInformCmd")); // + String(cmd, HEX)); + mSys->Radio.prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmMesIndex, false); mPayload[iv->id].txCmd = cmd; } } @@ -232,8 +232,8 @@ class HmPayload { /* DPRINTLN(DBG_WARN, F("nothing received: Request Complete Retransmit")); mPayload[iv->id].txCmd = iv->getQueuedCmd(); - DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") sendTimePacket 0x") + String(mPayload[iv->id].txCmd, HEX)); - mSys->Radio.sendTimePacket(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true); + 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); */ DPRINTLN(DBG_WARN, F("(#") + String(iv->id) + F(") nothing received")); mPayload[iv->id].retransmits = mMaxRetrans; @@ -255,8 +255,8 @@ class HmPayload { mPayload[iv->id].retransmits++; DPRINTLN(DBG_WARN, F("CRC Error: Request Complete Retransmit")); mPayload[iv->id].txCmd = iv->getQueuedCmd(); - DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") sendTimePacket 0x") + String(mPayload[iv->id].txCmd, HEX)); - mSys->Radio.sendTimePacket(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true); + 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); } } else { // payload complete DPRINTLN(DBG_INFO, F("procPyld: cmd: 0x") + String(mPayload[iv->id].txCmd, HEX)); diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index 790fca3d6..203e3b7fd 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -191,9 +191,9 @@ class HmRadio { sendPacket(invId, cnt, isRetransmit, true); } - void sendTimePacket(uint64_t invId, uint8_t cmd, uint32_t ts, uint16_t alarmMesId, bool isRetransmit) { - DPRINTLN(DBG_DEBUG, F("sendTimePacket 0x") + String(cmd, HEX)); - initPacket(invId, TX_REQ_INFO, ALL_FRAMES); + void prepareDevInformCmd(uint64_t invId, uint8_t cmd, uint32_t ts, uint16_t alarmMesId, bool isRetransmit, uint8_t reqfld=TX_REQ_INFO) { // might not be necessary to add additional arg. + DPRINTLN(DBG_DEBUG, F("prepareDevInformCmd 0x") + String(cmd, HEX)); + initPacket(invId, reqfld, ALL_FRAMES); mTxBuf[10] = cmd; // cid mTxBuf[11] = 0x00; CP_U32_LittleEndian(&mTxBuf[12], ts); diff --git a/src/hm/miPayload.h b/src/hm/miPayload.h index bce671a6e..592f5552b 100644 --- a/src/hm/miPayload.h +++ b/src/hm/miPayload.h @@ -16,11 +16,14 @@ typedef struct { bool requested; uint8_t txCmd; uint8_t len[MAX_PAYLOAD_ENTRIES]; - /* + bool complete; + bool stsa; + bool stsb; uint8_t txId; uint8_t invId; + /* uint8_t data[MAX_PAYLOAD_ENTRIES][MAX_RF_PAYLOAD_SIZE]; - bool complete; + uint8_t maxPackId; bool lastFound; uint8_t retransmits; @@ -68,15 +71,96 @@ class MiPayload { if (mSerialDebug) DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") Requesting Inv SN ") + String(iv->config->serial.u64, HEX)); - uint8_t cmd = 0x09; //iv->getQueuedCmd(); - DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") sendTimePacket")); - mSys->Radio.sendTimePacket(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmMesIndex, false); + uint8_t cmd = iv->type == INV_TYPE_4CH ? 0x36 : 0x09; //iv->getQueuedCmd(); + DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") prepareDevInformCmd")); + mSys->Radio.prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmMesIndex, false, cmd); mPayload[iv->id].txCmd = cmd; } void add(Inverter<> *iv, packet_t *p) { DPRINTLN(DBG_INFO, F("MI got data [0]=") + String(p->packet[0], HEX)); + if (p->packet[0] == (0x08 + ALL_FRAMES)) { // MI status response to 0x09 + mPayload[iv->id].stsa = true; + /*decode here or memcopy payload for later decoding? + for decoding see + void MI600StsMsg (NRF24_packet_t *p){ + STAT = (int)((p->packet[11] << 8) + p->packet[12]); + FCNT = (int)((p->packet[13] << 8) + p->packet[14]); + FCODE = (int)((p->packet[15] << 8) + p->packet[16]); + #ifdef ESP8266 + VALUES[PV][5]=STAT; + VALUES[PV][6]=FCNT; + VALUES[PV][7]=FCODE; + #endif + } + */ + DPRINTLN(DBG_INFO, F("Inverter ") + String(iv->id) + F(": status msg ") + p->packet[0]); + } else if (p->packet[0] == (0x12 + ALL_FRAMES)) { // MI status response to 0x11 + mPayload[iv->id].stsb = true; + DPRINTLN(DBG_INFO, F("Inverter ") + String(iv->id) + F(": status msg ") + p->packet[0]); + } else if (p->packet[0] == (0x09 + ALL_FRAMES)) { // MI data response to 0x09 + mPayload[iv->id].txId = p->packet[0]; + if (INV_TYPE_2CH == iv->type) { + mSys->Radio.prepareDevInformCmd(iv->radioId.u64, iv->getQueuedCmd(), mPayload[iv->id].ts, iv->alarmMesIndex, false, 0x11); + } else { // additional check for mPayload[iv->id].stsa == true might be a good idea (request retransmit?) + mPayload[iv->id].complete = true; + } + /*decode here or memcopy payload for later decoding? + void MI600DataMsg(NRF24_packet_t *p){ + U_DC = (float) ((p->packet[11] << 8) + p->packet[12])/10; + I_DC = (float) ((p->packet[13] << 8) + p->packet[14])/10; + U_AC = (float) ((p->packet[15] << 8) + p->packet[16])/10; + F_AC = (float) ((p->packet[17] << 8) + p->packet[18])/100; + P_DC = (float)((p->packet[19] << 8) + p->packet[20])/10; + Q_DC = (float)((p->packet[21] << 8) + p->packet[22])/1; + TEMP = (float) ((p->packet[23] << 8) + p->packet[24])/10; + + if ((30packet[2] == 0x89) {PV= 0; TotalP[1]=P_DC; pvCnt[0]=1;}//port 1 + if (p->packet[2] == 0x91) {PV= 1; TotalP[2]=P_DC; pvCnt[1]=1;}//port 2 + + TotalP[0]=TotalP[1]+TotalP[2]+TotalP[3]+TotalP[4];//in TotalP[0] is the totalPV power + if((P_DC>400) || (P_DC<0) || (TotalP[0]>MAXPOWER)){// cant be!! + TotalP[0]=0; + return; + } + #ifdef ESP8266 + VALUES[PV][0]=PV; + VALUES[PV][1]=P_DC; + VALUES[PV][2]=U_DC; + VALUES[PV][3]=I_DC; + VALUES[PV][4]=Q_DC; + #endif + PMI=TotalP[0]; + LIM=(uint16_t)Limit; + PrintOutValues(); + }*/ + DPRINTLN(DBG_INFO, F("Inverter ") + String(iv->id) + F(": data msg ") + p->packet[0]); + + + } else if (p->packet[0] == (0x11 + ALL_FRAMES)) { // MI data response to 0x11 + mPayload[iv->id].txId = p->packet[0]; + mPayload[iv->id].complete = true; + //decode here or memcopy payload for later decoding? + DPRINTLN(DBG_INFO, F("Inverter ") + String(iv->id) + F(": data msg ") + p->packet[0]); + + + } else if (p->packet[0] >= (0x36 + ALL_FRAMES) && p->packet[0] <= (0x39 + ALL_FRAMES)) { // MI 1500 data response to 0x11 + mPayload[iv->id].txId = p->packet[0]; + if (p->packet[0] < (0x39 + ALL_FRAMES)) { + mSys->Radio.prepareDevInformCmd(iv->radioId.u64, iv->getQueuedCmd(), mPayload[iv->id].ts, iv->alarmMesIndex, false, p->packet[0] + 1 - ALL_FRAMES); + } else { + mPayload[iv->id].complete = true; + } + //decode here or memcopy payload for later decoding? + DPRINTLN(DBG_INFO, F("Inverter MI1500 ") + String(iv->id) + F(": data msg ") + p->packet[0]); + + } + /*if (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES)) { // response from get information command mPayload[iv->id].txId = p->packet[0]; DPRINTLN(DBG_DEBUG, F("Response from info request received")); @@ -171,8 +255,8 @@ class MiPayload { mPayload[iv->id].retransmits++; DPRINTLN(DBG_WARN, F("CRC Error: Request Complete Retransmit")); mPayload[iv->id].txCmd = iv->getQueuedCmd(); - DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") sendTimePacket 0x") + String(mPayload[iv->id].txCmd, HEX)); - mSys->Radio.sendTimePacket(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true); + 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); } } else { // payload complete DPRINTLN(DBG_INFO, F("procPyld: cmd: 0x") + String(mPayload[iv->id].txCmd, HEX)); @@ -280,11 +364,13 @@ class MiPayload { mPayload[id].gotFragment = false; mPayload[id].retransmits = 0; mPayload[id].maxPackId = MAX_PAYLOAD_ENTRIES; - mPayload[id].lastFound = false; - mPayload[id].complete = false;*/ + mPayload[id].lastFound = false;*/ + mPayload[id].complete = false; mPayload[id].txCmd = 0; mPayload[id].requested = false; mPayload[id].ts = *mTimestamp; + mPayload[id].stsa = false; + mPayload[id].stsb = false; } IApp *mApp; From 1a96d2868238178eaa4f4113352eeed6fefd4064 Mon Sep 17 00:00:00 2001 From: rejoe2 Date: Thu, 9 Feb 2023 08:46:24 +0100 Subject: [PATCH 2/4] decoding of status for MI600 seems to work... Data is unclear (no packets received yet?) --- src/hm/miPayload.h | 359 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 291 insertions(+), 68 deletions(-) diff --git a/src/hm/miPayload.h b/src/hm/miPayload.h index 592f5552b..3e73eaa6b 100644 --- a/src/hm/miPayload.h +++ b/src/hm/miPayload.h @@ -6,6 +6,7 @@ #ifndef __MI_PAYLOAD_H__ #define __MI_PAYLOAD_H__ +//#include "hmInverter.h" #include "../utils/dbg.h" #include "../utils/crc.h" #include "../config/config.h" @@ -21,12 +22,12 @@ typedef struct { bool stsb; uint8_t txId; uint8_t invId; + uint8_t retransmits; /* uint8_t data[MAX_PAYLOAD_ENTRIES][MAX_RF_PAYLOAD_SIZE]; uint8_t maxPackId; bool lastFound; - uint8_t retransmits; bool gotFragment;*/ } miPayload_t; @@ -60,6 +61,9 @@ class MiPayload { mCbMiPayload = cb; } + void addAlarmListener(alarmListenerType cb) { + mCbMiAlarm = cb; + } void loop() {} @@ -80,88 +84,42 @@ class MiPayload { void add(Inverter<> *iv, packet_t *p) { DPRINTLN(DBG_INFO, F("MI got data [0]=") + String(p->packet[0], HEX)); - if (p->packet[0] == (0x08 + ALL_FRAMES)) { // MI status response to 0x09 + if (p->packet[0] == (0x08 + ALL_FRAMES)) { // 0x88; MI status response to 0x09 mPayload[iv->id].stsa = true; - /*decode here or memcopy payload for later decoding? - for decoding see - void MI600StsMsg (NRF24_packet_t *p){ - STAT = (int)((p->packet[11] << 8) + p->packet[12]); - FCNT = (int)((p->packet[13] << 8) + p->packet[14]); - FCODE = (int)((p->packet[15] << 8) + p->packet[16]); - #ifdef ESP8266 - VALUES[PV][5]=STAT; - VALUES[PV][6]=FCNT; - VALUES[PV][7]=FCODE; - #endif - } - */ - DPRINTLN(DBG_INFO, F("Inverter ") + String(iv->id) + F(": status msg ") + p->packet[0]); - } else if (p->packet[0] == (0x12 + ALL_FRAMES)) { // MI status response to 0x11 + miStsDecode(iv, p); + } else if (p->packet[0] == (0x11 + SINGLE_FRAME)) { // 0x92; MI status response to 0x11 mPayload[iv->id].stsb = true; - DPRINTLN(DBG_INFO, F("Inverter ") + String(iv->id) + F(": status msg ") + p->packet[0]); + miStsDecode(iv, p, 2); } else if (p->packet[0] == (0x09 + ALL_FRAMES)) { // MI data response to 0x09 mPayload[iv->id].txId = p->packet[0]; + miDataDecode(iv,p); if (INV_TYPE_2CH == iv->type) { mSys->Radio.prepareDevInformCmd(iv->radioId.u64, iv->getQueuedCmd(), mPayload[iv->id].ts, iv->alarmMesIndex, false, 0x11); } else { // additional check for mPayload[iv->id].stsa == true might be a good idea (request retransmit?) mPayload[iv->id].complete = true; + iv->setQueuedCmdFinished(); } - /*decode here or memcopy payload for later decoding? - void MI600DataMsg(NRF24_packet_t *p){ - U_DC = (float) ((p->packet[11] << 8) + p->packet[12])/10; - I_DC = (float) ((p->packet[13] << 8) + p->packet[14])/10; - U_AC = (float) ((p->packet[15] << 8) + p->packet[16])/10; - F_AC = (float) ((p->packet[17] << 8) + p->packet[18])/100; - P_DC = (float)((p->packet[19] << 8) + p->packet[20])/10; - Q_DC = (float)((p->packet[21] << 8) + p->packet[22])/1; - TEMP = (float) ((p->packet[23] << 8) + p->packet[24])/10; - - if ((30packet[2] == 0x89) {PV= 0; TotalP[1]=P_DC; pvCnt[0]=1;}//port 1 - if (p->packet[2] == 0x91) {PV= 1; TotalP[2]=P_DC; pvCnt[1]=1;}//port 2 - - TotalP[0]=TotalP[1]+TotalP[2]+TotalP[3]+TotalP[4];//in TotalP[0] is the totalPV power - if((P_DC>400) || (P_DC<0) || (TotalP[0]>MAXPOWER)){// cant be!! - TotalP[0]=0; - return; - } - #ifdef ESP8266 - VALUES[PV][0]=PV; - VALUES[PV][1]=P_DC; - VALUES[PV][2]=U_DC; - VALUES[PV][3]=I_DC; - VALUES[PV][4]=Q_DC; - #endif - PMI=TotalP[0]; - LIM=(uint16_t)Limit; - PrintOutValues(); - }*/ - DPRINTLN(DBG_INFO, F("Inverter ") + String(iv->id) + F(": data msg ") + p->packet[0]); } else if (p->packet[0] == (0x11 + ALL_FRAMES)) { // MI data response to 0x11 mPayload[iv->id].txId = p->packet[0]; mPayload[iv->id].complete = true; - //decode here or memcopy payload for later decoding? - DPRINTLN(DBG_INFO, F("Inverter ") + String(iv->id) + F(": data msg ") + p->packet[0]); - + miDataDecode(iv,p); + iv->setQueuedCmdFinished(); - } else if (p->packet[0] >= (0x36 + ALL_FRAMES) && p->packet[0] <= (0x39 + ALL_FRAMES)) { // MI 1500 data response to 0x11 + } else if (p->packet[0] >= (0x36 + ALL_FRAMES) && p->packet[0] < (0x39 + SINGLE_FRAME)) { // MI 1500 data response to 0x36, 0x37, 0x38 and 0x39 mPayload[iv->id].txId = p->packet[0]; + miDataDecode(iv,p); if (p->packet[0] < (0x39 + ALL_FRAMES)) { mSys->Radio.prepareDevInformCmd(iv->radioId.u64, iv->getQueuedCmd(), mPayload[iv->id].ts, iv->alarmMesIndex, false, p->packet[0] + 1 - ALL_FRAMES); } else { mPayload[iv->id].complete = true; + iv->setQueuedCmdFinished(); } - //decode here or memcopy payload for later decoding? - DPRINTLN(DBG_INFO, F("Inverter MI1500 ") + String(iv->id) + F(": data msg ") + p->packet[0]); - } + /*} - /*if (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES)) { // response from get information command + if (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES)) { // response from get information command mPayload[iv->id].txId = p->packet[0]; DPRINTLN(DBG_DEBUG, F("Response from info request received")); uint8_t *pid = &p->packet[9]; @@ -184,6 +142,7 @@ class MiPayload { } } } + } */ } else if (p->packet[0] == (TX_REQ_DEVCONTROL + ALL_FRAMES)) { // response from dev control command DPRINTLN(DBG_DEBUG, F("Response from devcontrol request received")); @@ -201,7 +160,64 @@ class MiPayload { iv->enqueCommand(SystemConfigPara); // read back power limit } iv->devControlCmd = Init; - }*/ + } else { // some other response; copied from hmPayload:process; might not be correct to do that here!!! + DPRINTLN(DBG_INFO, F("procPyld: cmd: 0x") + String(mPayload[iv->id].txCmd, HEX)); + DPRINTLN(DBG_INFO, F("procPyld: txid: 0x") + String(mPayload[iv->id].txId, HEX)); + //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; + + uint8_t payload[128]; + uint8_t payloadLen = 0; + + memset(payload, 0, 128); + + /*for (uint8_t i = 0; i < (mPayload[iv->id].maxPackId); i++) { + memcpy(&payload[payloadLen], mPayload[iv->id].data[i], (mPayload[iv->id].len[i])); + payloadLen += (mPayload[iv->id].len[i]); + yield(); + }*/ + payloadLen -= 2; + + if (mSerialDebug) { + DPRINT(DBG_INFO, F("Payload (") + String(payloadLen) + "): "); + mSys->Radio.dumpBuf(payload, payloadLen); + } + + if (NULL == rec) { + DPRINTLN(DBG_ERROR, F("record is NULL!")); + } else if ((rec->pyldLen == payloadLen) || (0 == rec->pyldLen)) { + if (mPayload[iv->id].txId == (TX_REQ_INFO + ALL_FRAMES)) + mStat->rxSuccess++; + + rec->ts = mPayload[iv->id].ts; + for (uint8_t i = 0; i < rec->length; i++) { + iv->addValue(i, payload, rec); + yield(); + } + iv->doCalculations(); + notify(mPayload[iv->id].txCmd); + + if(AlarmData == mPayload[iv->id].txCmd) { + uint8_t i = 0; + uint16_t code; + uint32_t start, end; + while(1) { + code = iv->parseAlarmLog(i++, payload, payloadLen, &start, &end); + if(0 == code) + break; + if (NULL != mCbMiAlarm) + (mCbMiAlarm)(code, start, end); + yield(); + } + } + } else { + DPRINTLN(DBG_ERROR, F("plausibility check failed, expected ") + String(rec->pyldLen) + F(" bytes")); + mStat->rxFail++; + } + + iv->setQueuedCmdFinished(); + } } void process(bool retransmit) { @@ -217,7 +233,7 @@ class MiPayload { // no processing needed if txId is not 0x95 mPayload[iv->id].complete = true; continue; // skip to next inverter - } + }*/ if (!mPayload[iv->id].complete) { bool crcPass, pyldComplete; @@ -231,7 +247,7 @@ class MiPayload { } else if(iv->devControlCmd == ActivePowerContr) { DPRINTLN(DBG_INFO, F("retransmit power limit")); mSys->Radio.sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, true); - } else { + } /*else { if (mPayload[iv->id].retransmits < mMaxRetrans) { mPayload[iv->id].retransmits++; if(false == mPayload[iv->id].gotFragment) { @@ -248,7 +264,7 @@ class MiPayload { } } } - } + }*/ } } else if(!crcPass && pyldComplete) { // crc error on complete Payload if (mPayload[iv->id].retransmits < mMaxRetrans) { @@ -258,7 +274,7 @@ class MiPayload { 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); } - } else { // payload complete + } /*else { // payload complete DPRINTLN(DBG_INFO, F("procPyld: cmd: 0x") + String(mPayload[iv->id].txCmd, HEX)); DPRINTLN(DBG_INFO, F("procPyld: txid: 0x") + String(mPayload[iv->id].txId, HEX)); DPRINTLN(DBG_DEBUG, F("procPyld: max: ") + String(mPayload[iv->id].maxPackId)); @@ -315,8 +331,8 @@ class MiPayload { } iv->setQueuedCmdFinished(); - } - }*/ + }*/ + } yield(); } } @@ -327,6 +343,212 @@ class MiPayload { (mCbMiPayload)(val); } + void addMiValue(uint8_t pos, packet_t *p, record_t<> *rec, uint8_t ptr, uint8_t end) { + DPRINTLN(DBG_VERBOSE, F("miPAyload.h:addMiValue")); + + /* + pos = iv->getPosByChFld(ch, fld, rec); + iv->setValue(pos, rec, 0.0f); + */ + /*if(NULL != rec) { + //uint8_t ptr = rec->assign[pos].start; + //uint8_t end = ptr + rec->assign[pos].num; + uint16_t div = rec->assign[pos].div; + + if(NULL != rec) { + if(CMD_CALC != div) { + uint32_t val = 0; + do { + val <<= 8; + val |= p->[ptr]; + } while(++ptr != end); + if (FLD_T == rec->assign[pos].fieldId) { + // temperature is a signed value! + rec->record[pos] = (REC_TYP)((int16_t)val) / (REC_TYP)(div); + } else if ((FLD_YT == rec->assign[pos].fieldId) + && (config->yieldCor != 0)) { + rec->record[pos] = ((REC_TYP)(val) / (REC_TYP)(div)) - ((REC_TYP)config->yieldCor); + } else { + if ((REC_TYP)(div) > 1) + rec->record[pos] = (REC_TYP)(val) / (REC_TYP)(div); + else + rec->record[pos] = (REC_TYP)(val); + } + } + } + + if(rec == &recordMeas) { + DPRINTLN(DBG_VERBOSE, "add real time"); + + // get last alarm message index and save it in the inverter object + if (getPosByChFld(0, FLD_EVT, rec) == pos){ + if (alarmMesIndex < rec->record[pos]){ + alarmMesIndex = rec->record[pos]; + //enqueCommand(AlarmUpdate); // What is the function of AlarmUpdate? + + DPRINTLN(DBG_INFO, "alarm ID incremented to " + String(alarmMesIndex)); + enqueCommand(AlarmData); + } + } + } + else if (rec->assign == InfoAssignment) { + DPRINTLN(DBG_DEBUG, "add info"); + // eg. fw version ... + isConnected = true; + } + else if (rec->assign == SystemConfigParaAssignment) { + 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)); + } + } + else if (rec->assign == AlarmDataAssignment) { + DPRINTLN(DBG_DEBUG, "add alarm"); + if (getPosByChFld(0, FLD_LAST_ALARM_CODE, rec) == pos){ + lastAlarmMsg = getAlarmStr(rec->record[pos]); + } + } + else + DPRINTLN(DBG_WARN, F("add with unknown assginment")); + } + else + DPRINTLN(DBG_ERROR, F("addValue: assignment not found with cmd 0x")); + */ + } + + void miStsDecode(Inverter<> *iv, packet_t *p, uint8_t chan = 1) { + record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug); // choose the parser + rec->ts = mPayload[iv->id].ts; + //addMiValue(uint8_t pos, packet_t *p, record_t<> *rec, uint8_t ptr, uint8_t end) + iv->setValue(iv->getPosByChFld(chan, FLD_YD, rec), rec, (int)((p->packet[11] << 8) + p->packet[12])); + //iv->setValue(iv->getPosByChFld(chan, FLD_EVT, rec), rec, (int)((p->packet[13] << 8) + p->packet[14])); + iv->setValue(iv->getPosByChFld(chan, FLD_EVT, rec), rec, (int)((p->packet[15] << 8) + p->packet[16])); + //addMiValue(FLD_EVT, p, rec, 11, 12); + /* + pos = iv->getPosByChFld(ch, fld, rec); + iv->setValue(pos, rec, 0.0f); + */ + + + /* for decoding see + void MI600StsMsg (NRF24_packet_t *p){ + STAT = (int)((p->packet[11] << 8) + p->packet[12]); + FCNT = (int)((p->packet[13] << 8) + p->packet[14]); + FCODE = (int)((p->packet[15] << 8) + p->packet[16]); + #ifdef ESP8266 + VALUES[PV][5]=STAT; + VALUES[PV][6]=FCNT; + VALUES[PV][7]=FCODE; + #endif + } + */ + DPRINTLN(DBG_INFO, F("Inverter ") + String(iv->id) + F(": status msg ") + p->packet[0]); + } + + void miDataDecode(Inverter<> *iv, packet_t *p) { + record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug); // choose the parser + rec->ts = mPayload[iv->id].ts; + + uint8_t chan = ( p->packet[2] == 0x89 || p->packet[2] == (0x36 + ALL_FRAMES) ) ? 1 : + ( p->packet[2] == 0x91 || p->packet[2] == (0x37 + ALL_FRAMES) ) ? 2 : + p->packet[2] == (0x38 + ALL_FRAMES) ? 3 : + 4; + + // U_DC = (float) ((p->packet[11] << 8) + p->packet[12])/10; + iv->setValue(iv->getPosByChFld(chan, FLD_UDC, rec), rec, (float)((p->packet[11] << 8) + p->packet[12])/10); + yield(); + // I_DC = (float) ((p->packet[13] << 8) + p->packet[14])/10; + iv->setValue(iv->getPosByChFld(chan, FLD_IDC, rec), rec, (float)((p->packet[13] << 8) + p->packet[14])/10); + yield(); + // U_AC = (float) ((p->packet[15] << 8) + p->packet[16])/10; + iv->setValue(iv->getPosByChFld(0, FLD_UAC, rec), rec, (float)((p->packet[15] << 8) + p->packet[16])/10); + yield(); + // F_AC = (float) ((p->packet[17] << 8) + p->packet[18])/100; + iv->setValue(iv->getPosByChFld(0, FLD_IAC, rec), rec, (float)((p->packet[17] << 8) + p->packet[18])/100); + yield(); + // P_DC = (float)((p->packet[19] << 8) + p->packet[20])/10; + iv->setValue(iv->getPosByChFld(chan, FLD_PDC, rec), rec, (float)((p->packet[19] << 8) + p->packet[20])/10); + yield(); + // Q_DC = (float)((p->packet[21] << 8) + p->packet[22])/1; + iv->setValue(iv->getPosByChFld(chan, FLD_Q, rec), rec, (float)((p->packet[21] << 8) + p->packet[22])/1); + yield(); + iv->setValue(iv->getPosByChFld(0, FLD_T, rec), rec, (float) ((int16_t)(p->packet[23] << 8) + p->packet[24])/10); + yield(); + + if (p->packet[2] >= (0x36 + ALL_FRAMES) ) { + /*STAT = (uint8_t)(p->packet[25] ); + FCNT = (uint8_t)(p->packet[26]); + FCODE = (uint8_t)(p->packet[27]); // MI300: (int)((p->packet[15] << 8) + p->packet[16]); */ + iv->setValue(iv->getPosByChFld(chan, FLD_YD, rec), rec, (uint8_t)(p->packet[25])); + iv->setValue(iv->getPosByChFld(0, FLD_EVT, rec), rec, (uint8_t)(p->packet[27])); + yield(); + } + + /* for (uint8_t i = 0; i < rec->length; i++) { + iv->addValue(i, payload, rec); + yield(); + }*/ + iv->doCalculations(); + notify(mPayload[iv->id].txCmd); +/* + if(AlarmData == mPayload[iv->id].txCmd) { + uint8_t i = 0; + uint16_t code; + uint32_t start, end; + while(1) { + code = iv->parseAlarmLog(i++, payload, payloadLen, &start, &end); + if(0 == code) + break; + if (NULL != mCbMiAlarm) + (mCbAlarm)(code, start, end); + yield(); + } + }*/ +/*decode here or memcopy payload for later decoding? + void MI600DataMsg(NRF24_packet_t *p){ + U_DC = (float) ((p->packet[11] << 8) + p->packet[12])/10; + I_DC = (float) ((p->packet[13] << 8) + p->packet[14])/10; + U_AC = (float) ((p->packet[15] << 8) + p->packet[16])/10; + F_AC = (float) ((p->packet[17] << 8) + p->packet[18])/100; + P_DC = (float)((p->packet[19] << 8) + p->packet[20])/10; + Q_DC = (float)((p->packet[21] << 8) + p->packet[22])/1; + TEMP = (float) ((p->packet[23] << 8) + p->packet[24])/10; //(int16_t) + + if ((30packet[2] == 0x89) {PV= 0; TotalP[1]=P_DC; pvCnt[0]=1;}//port 1 + if (p->packet[2] == 0x91) {PV= 1; TotalP[2]=P_DC; pvCnt[1]=1;}//port 2 + + TotalP[0]=TotalP[1]+TotalP[2]+TotalP[3]+TotalP[4];//in TotalP[0] is the totalPV power + if((P_DC>400) || (P_DC<0) || (TotalP[0]>MAXPOWER)){// cant be!! + TotalP[0]=0; + return; + } + #ifdef ESP8266 + VALUES[PV][0]=PV; + VALUES[PV][1]=P_DC; + VALUES[PV][2]=U_DC; + VALUES[PV][3]=I_DC; + VALUES[PV][4]=Q_DC; + #endif + PMI=TotalP[0]; + LIM=(uint16_t)Limit; + PrintOutValues(); + }*/ + + /*For MI1500: + if (MI1500) { + STAT = (uint8_t)(p->packet[25] ); + FCNT = (uint8_t)(p->packet[26]); + FCODE = (uint8_t)(p->packet[27]); + } + */ + DPRINTLN(DBG_INFO, F("Inverter ") + String(iv->id) + F(": data msg ") + p->packet[0]); + } + bool build(uint8_t id, bool *complete) { /*DPRINTLN(DBG_VERBOSE, F("build")); uint16_t crc = 0xffff, crcRcv = 0x0000; @@ -362,9 +584,9 @@ class MiPayload { memset(mPayload[id].len, 0, MAX_PAYLOAD_ENTRIES); /* mPayload[id].gotFragment = false; - mPayload[id].retransmits = 0; mPayload[id].maxPackId = MAX_PAYLOAD_ENTRIES; mPayload[id].lastFound = false;*/ + mPayload[id].retransmits = 0; mPayload[id].complete = false; mPayload[id].txCmd = 0; mPayload[id].requested = false; @@ -381,6 +603,7 @@ class MiPayload { miPayload_t mPayload[MAX_NUM_INVERTERS]; bool mSerialDebug; + alarmListenerType mCbMiAlarm; payloadListenerType mCbMiPayload; }; From 4d0bac9267c1f8ccfccdf462aa12942dbf91f956 Mon Sep 17 00:00:00 2001 From: rejoe2 Date: Thu, 9 Feb 2023 14:38:40 +0100 Subject: [PATCH 3/4] further updates for MI compiles... for the rest still untested --- src/hm/miPayload.h | 144 +++++++++++++++------------------------------ 1 file changed, 47 insertions(+), 97 deletions(-) diff --git a/src/hm/miPayload.h b/src/hm/miPayload.h index 3e73eaa6b..dad0d076a 100644 --- a/src/hm/miPayload.h +++ b/src/hm/miPayload.h @@ -50,6 +50,7 @@ class MiPayload { reset(i); } mSerialDebug = false; + mHighPrioIv = NULL; mCbMiPayload = NULL; } @@ -64,8 +65,16 @@ class MiPayload { void addAlarmListener(alarmListenerType cb) { mCbMiAlarm = cb; } - void loop() {} + void loop() { + /*if(NULL != mHighPrioIv) { + iv->ivSend(mHighPrioIv, true); // should request firmware version etc.? + mHighPrioIv = NULL; + }*/ + } + void ivSendHighPrio(Inverter<> *iv) { + mHighPrioIv = iv; + } void ivSend(Inverter<> *iv) { reset(iv->id); @@ -114,6 +123,7 @@ class MiPayload { mSys->Radio.prepareDevInformCmd(iv->radioId.u64, iv->getQueuedCmd(), mPayload[iv->id].ts, iv->alarmMesIndex, false, p->packet[0] + 1 - ALL_FRAMES); } else { mPayload[iv->id].complete = true; + //iv->setValue(iv->getPosByChFld(0, FLD_YD, rec), rec, CALC_YD_CH0); iv->setQueuedCmdFinished(); } @@ -247,10 +257,12 @@ class MiPayload { } else if(iv->devControlCmd == ActivePowerContr) { DPRINTLN(DBG_INFO, F("retransmit power limit")); mSys->Radio.sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, true); - } /*else { + } else { if (mPayload[iv->id].retransmits < mMaxRetrans) { mPayload[iv->id].retransmits++; - if(false == mPayload[iv->id].gotFragment) { + //mSys->Radio.prepareDevInformCmd(iv->radioId.u64, iv->getQueuedCmd(), mPayload[iv->id].ts, iv->alarmMesIndex, false, 0x11); + mSys->Radio.sendCmdPacket(iv->radioId.u64, iv->getQueuedCmd(), 24, true); + /*if(false == mPayload[iv->id].gotFragment) { DPRINTLN(DBG_WARN, F("(#") + String(iv->id) + F(") nothing received")); mPayload[iv->id].retransmits = mMaxRetrans; } else { @@ -262,9 +274,9 @@ class MiPayload { } yield(); } - } + }*/ } - }*/ + } } } else if(!crcPass && pyldComplete) { // crc error on complete Payload if (mPayload[iv->id].retransmits < mMaxRetrans) { @@ -343,92 +355,23 @@ class MiPayload { (mCbMiPayload)(val); } - void addMiValue(uint8_t pos, packet_t *p, record_t<> *rec, uint8_t ptr, uint8_t end) { - DPRINTLN(DBG_VERBOSE, F("miPAyload.h:addMiValue")); + void miStsDecode(Inverter<> *iv, packet_t *p, uint8_t chan = 1) { + record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug); // choose the record structure + rec->ts = mPayload[iv->id].ts; + iv->setValue(iv->getPosByChFld(chan, FLD_YD, rec), rec, (int)((p->packet[11] << 8) + p->packet[12])); // most likely wrong! - /* - pos = iv->getPosByChFld(ch, fld, rec); - iv->setValue(pos, rec, 0.0f); - */ - /*if(NULL != rec) { - //uint8_t ptr = rec->assign[pos].start; - //uint8_t end = ptr + rec->assign[pos].num; - uint16_t div = rec->assign[pos].div; - - if(NULL != rec) { - if(CMD_CALC != div) { - uint32_t val = 0; - do { - val <<= 8; - val |= p->[ptr]; - } while(++ptr != end); - if (FLD_T == rec->assign[pos].fieldId) { - // temperature is a signed value! - rec->record[pos] = (REC_TYP)((int16_t)val) / (REC_TYP)(div); - } else if ((FLD_YT == rec->assign[pos].fieldId) - && (config->yieldCor != 0)) { - rec->record[pos] = ((REC_TYP)(val) / (REC_TYP)(div)) - ((REC_TYP)config->yieldCor); - } else { - if ((REC_TYP)(div) > 1) - rec->record[pos] = (REC_TYP)(val) / (REC_TYP)(div); - else - rec->record[pos] = (REC_TYP)(val); - } - } - } + if (INV_TYPE_1CH == iv->type) + iv->setValue(iv->getPosByChFld(0, FLD_YD, rec), rec, (int)((p->packet[11] << 8) + p->packet[12])); - if(rec == &recordMeas) { - DPRINTLN(DBG_VERBOSE, "add real time"); + //iv->setValue(iv->getPosByChFld(chan, FLD_EVT, rec), rec, (int)((p->packet[13] << 8) + p->packet[14])); - // get last alarm message index and save it in the inverter object - if (getPosByChFld(0, FLD_EVT, rec) == pos){ - if (alarmMesIndex < rec->record[pos]){ - alarmMesIndex = rec->record[pos]; - //enqueCommand(AlarmUpdate); // What is the function of AlarmUpdate? + iv->setValue(iv->getPosByChFld(0, FLD_EVT, rec), rec, (int)((p->packet[15] << 8) + p->packet[16])); + if (iv->alarmMesIndex < rec->record[iv->getPosByChFld(0, FLD_EVT, rec)]){ + iv->alarmMesIndex = rec->record[iv->getPosByChFld(0, FLD_EVT, rec)]; - DPRINTLN(DBG_INFO, "alarm ID incremented to " + String(alarmMesIndex)); - enqueCommand(AlarmData); - } - } - } - else if (rec->assign == InfoAssignment) { - DPRINTLN(DBG_DEBUG, "add info"); - // eg. fw version ... - isConnected = true; - } - else if (rec->assign == SystemConfigParaAssignment) { - 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)); - } - } - else if (rec->assign == AlarmDataAssignment) { - DPRINTLN(DBG_DEBUG, "add alarm"); - if (getPosByChFld(0, FLD_LAST_ALARM_CODE, rec) == pos){ - lastAlarmMsg = getAlarmStr(rec->record[pos]); - } - } - else - DPRINTLN(DBG_WARN, F("add with unknown assginment")); + DPRINTLN(DBG_INFO, "alarm ID incremented to " + String(iv->alarmMesIndex)); + iv->enqueCommand(AlarmData); } - else - DPRINTLN(DBG_ERROR, F("addValue: assignment not found with cmd 0x")); - */ - } - - void miStsDecode(Inverter<> *iv, packet_t *p, uint8_t chan = 1) { - record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug); // choose the parser - rec->ts = mPayload[iv->id].ts; - //addMiValue(uint8_t pos, packet_t *p, record_t<> *rec, uint8_t ptr, uint8_t end) - iv->setValue(iv->getPosByChFld(chan, FLD_YD, rec), rec, (int)((p->packet[11] << 8) + p->packet[12])); - //iv->setValue(iv->getPosByChFld(chan, FLD_EVT, rec), rec, (int)((p->packet[13] << 8) + p->packet[14])); - iv->setValue(iv->getPosByChFld(chan, FLD_EVT, rec), rec, (int)((p->packet[15] << 8) + p->packet[16])); - //addMiValue(FLD_EVT, p, rec, 11, 12); - /* - pos = iv->getPosByChFld(ch, fld, rec); - iv->setValue(pos, rec, 0.0f); - */ /* for decoding see @@ -456,39 +399,45 @@ class MiPayload { 4; // U_DC = (float) ((p->packet[11] << 8) + p->packet[12])/10; - iv->setValue(iv->getPosByChFld(chan, FLD_UDC, rec), rec, (float)((p->packet[11] << 8) + p->packet[12])/10); + iv->setValue(iv->getPosByChFld(chan, FLD_UDC, rec), rec, (float)((p->packet[17] << 8) + p->packet[18])/10); yield(); // I_DC = (float) ((p->packet[13] << 8) + p->packet[14])/10; - iv->setValue(iv->getPosByChFld(chan, FLD_IDC, rec), rec, (float)((p->packet[13] << 8) + p->packet[14])/10); + iv->setValue(iv->getPosByChFld(chan, FLD_IDC, rec), rec, (float)((p->packet[19] << 8) + p->packet[20])/10); yield(); // U_AC = (float) ((p->packet[15] << 8) + p->packet[16])/10; - iv->setValue(iv->getPosByChFld(0, FLD_UAC, rec), rec, (float)((p->packet[15] << 8) + p->packet[16])/10); + iv->setValue(iv->getPosByChFld(0, FLD_UAC, rec), rec, (float)((p->packet[21] << 8) + p->packet[22])/10); yield(); // F_AC = (float) ((p->packet[17] << 8) + p->packet[18])/100; - iv->setValue(iv->getPosByChFld(0, FLD_IAC, rec), rec, (float)((p->packet[17] << 8) + p->packet[18])/100); + iv->setValue(iv->getPosByChFld(0, FLD_IAC, rec), rec, (float)((p->packet[23] << 8) + p->packet[24])/100); yield(); // P_DC = (float)((p->packet[19] << 8) + p->packet[20])/10; - iv->setValue(iv->getPosByChFld(chan, FLD_PDC, rec), rec, (float)((p->packet[19] << 8) + p->packet[20])/10); + iv->setValue(iv->getPosByChFld(chan, FLD_PDC, rec), rec, (float)((p->packet[25] << 8) + p->packet[26])/10); yield(); // Q_DC = (float)((p->packet[21] << 8) + p->packet[22])/1; iv->setValue(iv->getPosByChFld(chan, FLD_Q, rec), rec, (float)((p->packet[21] << 8) + p->packet[22])/1); yield(); - iv->setValue(iv->getPosByChFld(0, FLD_T, rec), rec, (float) ((int16_t)(p->packet[23] << 8) + p->packet[24])/10); + iv->setValue(iv->getPosByChFld(0, FLD_T, rec), rec, (float) ((int16_t)(p->packet[29] << 8) + p->packet[30])/10); + iv->setValue(iv->getPosByChFld(0, FLD_F, rec), rec, (float) ((p->packet[23] << 8) + p->packet[24])/100); yield(); + //FLD_YD if (p->packet[2] >= (0x36 + ALL_FRAMES) ) { /*STAT = (uint8_t)(p->packet[25] ); FCNT = (uint8_t)(p->packet[26]); FCODE = (uint8_t)(p->packet[27]); // MI300: (int)((p->packet[15] << 8) + p->packet[16]); */ - iv->setValue(iv->getPosByChFld(chan, FLD_YD, rec), rec, (uint8_t)(p->packet[25])); + //iv->setValue(iv->getPosByChFld(chan, FLD_YD, rec), rec, (uint8_t)(p->packet[25])); + //iv->setValue(iv->getPosByChFld(chan, FLD_EVT, rec), rec, (uint8_t)(p->packet[27])); iv->setValue(iv->getPosByChFld(0, FLD_EVT, rec), rec, (uint8_t)(p->packet[27])); yield(); + if (iv->alarmMesIndex < rec->record[iv->getPosByChFld(0, FLD_EVT, rec)]){ + iv->alarmMesIndex = rec->record[iv->getPosByChFld(0, FLD_EVT, rec)]; + + DPRINTLN(DBG_INFO, "alarm ID incremented to " + String(iv->alarmMesIndex)); + iv->enqueCommand(AlarmData); + } } + iv->setValue(iv->getPosByChFld(0, FLD_YD, rec), rec, CALC_YD_CH0); // (getValue(iv->getPosByChFld(1, FLD_YD, rec), rec) + getValue(iv->getPosByChFld(2, FLD_YD, rec), rec))); - /* for (uint8_t i = 0; i < rec->length; i++) { - iv->addValue(i, payload, rec); - yield(); - }*/ iv->doCalculations(); notify(mPayload[iv->id].txCmd); /* @@ -603,6 +552,7 @@ class MiPayload { miPayload_t mPayload[MAX_NUM_INVERTERS]; bool mSerialDebug; + Inverter<> *mHighPrioIv; alarmListenerType mCbMiAlarm; payloadListenerType mCbMiPayload; }; From d94af14618c4be85ad71cc69808dd3715df2871b Mon Sep 17 00:00:00 2001 From: rejoe2 Date: Fri, 10 Feb 2023 10:59:58 +0100 Subject: [PATCH 4/4] MI - partially working --- src/CHANGES.md | 4 ++++ src/hm/miPayload.h | 46 ++++++++++++++++++++++++++-------------------- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index 0c0963214..ff50872c9 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -2,6 +2,10 @@ (starting from release version `0.5.66`) +## 0.5.84 +* add MI 3rd generation inverters (10x2 serial numbers) +* first decodings of messages from MI 2nd generation inverters + ## 0.5.83 * fix MQTT publishing, `callback` was set but reset by following `setup()` diff --git a/src/hm/miPayload.h b/src/hm/miPayload.h index dad0d076a..9d2944982 100644 --- a/src/hm/miPayload.h +++ b/src/hm/miPayload.h @@ -102,14 +102,15 @@ class MiPayload { } else if (p->packet[0] == (0x09 + ALL_FRAMES)) { // MI data response to 0x09 mPayload[iv->id].txId = p->packet[0]; miDataDecode(iv,p); + iv->setQueuedCmdFinished(); if (INV_TYPE_2CH == iv->type) { - mSys->Radio.prepareDevInformCmd(iv->radioId.u64, iv->getQueuedCmd(), mPayload[iv->id].ts, iv->alarmMesIndex, false, 0x11); + //mSys->Radio.prepareDevInformCmd(iv->radioId.u64, iv->getQueuedCmd(), mPayload[iv->id].ts, iv->alarmMesIndex, false, 0x11); + mSys->Radio.prepareDevInformCmd(iv->radioId.u64, 0x11, mPayload[iv->id].ts, iv->alarmMesIndex, false, 0x11); } else { // additional check for mPayload[iv->id].stsa == true might be a good idea (request retransmit?) mPayload[iv->id].complete = true; - iv->setQueuedCmdFinished(); + //iv->setQueuedCmdFinished(); } - } else if (p->packet[0] == (0x11 + ALL_FRAMES)) { // MI data response to 0x11 mPayload[iv->id].txId = p->packet[0]; mPayload[iv->id].complete = true; @@ -119,12 +120,14 @@ class MiPayload { } else if (p->packet[0] >= (0x36 + ALL_FRAMES) && p->packet[0] < (0x39 + SINGLE_FRAME)) { // MI 1500 data response to 0x36, 0x37, 0x38 and 0x39 mPayload[iv->id].txId = p->packet[0]; miDataDecode(iv,p); + iv->setQueuedCmdFinished(); if (p->packet[0] < (0x39 + ALL_FRAMES)) { - mSys->Radio.prepareDevInformCmd(iv->radioId.u64, iv->getQueuedCmd(), mPayload[iv->id].ts, iv->alarmMesIndex, false, p->packet[0] + 1 - ALL_FRAMES); + //mSys->Radio.prepareDevInformCmd(iv->radioId.u64, iv->getQueuedCmd(), mPayload[iv->id].ts, iv->alarmMesIndex, false, p->packet[0] + 1 - ALL_FRAMES); + mSys->Radio.prepareDevInformCmd(iv->radioId.u64, p->packet[0] + 1 - ALL_FRAMES, mPayload[iv->id].ts, iv->alarmMesIndex, false, p->packet[0] + 1 - ALL_FRAMES); } else { mPayload[iv->id].complete = true; //iv->setValue(iv->getPosByChFld(0, FLD_YD, rec), rec, CALC_YD_CH0); - iv->setQueuedCmdFinished(); + //iv->setQueuedCmdFinished(); } /*} @@ -358,14 +361,17 @@ class MiPayload { void miStsDecode(Inverter<> *iv, packet_t *p, uint8_t chan = 1) { record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug); // choose the record structure rec->ts = mPayload[iv->id].ts; - iv->setValue(iv->getPosByChFld(chan, FLD_YD, rec), rec, (int)((p->packet[11] << 8) + p->packet[12])); // most likely wrong! - if (INV_TYPE_1CH == iv->type) - iv->setValue(iv->getPosByChFld(0, FLD_YD, rec), rec, (int)((p->packet[11] << 8) + p->packet[12])); + int8_t offset = -2; + + //iv->setValue(iv->getPosByChFld(chan, FLD_YD, rec), rec, (int)((p->packet[11+6] << 8) + p->packet[12+6])); // was 11/12, might be wrong! + + //if (INV_TYPE_1CH == iv->type) + //iv->setValue(iv->getPosByChFld(0, FLD_YD, rec), rec, (int)((p->packet[11+6] << 8) + p->packet[12+6])); //iv->setValue(iv->getPosByChFld(chan, FLD_EVT, rec), rec, (int)((p->packet[13] << 8) + p->packet[14])); - iv->setValue(iv->getPosByChFld(0, FLD_EVT, rec), rec, (int)((p->packet[15] << 8) + p->packet[16])); + iv->setValue(iv->getPosByChFld(0, FLD_EVT, rec), rec, (int)((p->packet[11+offset] << 8) + p->packet[12+offset])); if (iv->alarmMesIndex < rec->record[iv->getPosByChFld(0, FLD_EVT, rec)]){ iv->alarmMesIndex = rec->record[iv->getPosByChFld(0, FLD_EVT, rec)]; @@ -397,27 +403,27 @@ class MiPayload { ( p->packet[2] == 0x91 || p->packet[2] == (0x37 + ALL_FRAMES) ) ? 2 : p->packet[2] == (0x38 + ALL_FRAMES) ? 3 : 4; - + int8_t offset = -2; // U_DC = (float) ((p->packet[11] << 8) + p->packet[12])/10; - iv->setValue(iv->getPosByChFld(chan, FLD_UDC, rec), rec, (float)((p->packet[17] << 8) + p->packet[18])/10); + iv->setValue(iv->getPosByChFld(chan, FLD_UDC, rec), rec, (float)((p->packet[11+offset] << 8) + p->packet[12+offset])/10); yield(); // I_DC = (float) ((p->packet[13] << 8) + p->packet[14])/10; - iv->setValue(iv->getPosByChFld(chan, FLD_IDC, rec), rec, (float)((p->packet[19] << 8) + p->packet[20])/10); + iv->setValue(iv->getPosByChFld(chan, FLD_IDC, rec), rec, (float)((p->packet[13+offset] << 8) + p->packet[14+offset])/10); yield(); // U_AC = (float) ((p->packet[15] << 8) + p->packet[16])/10; - iv->setValue(iv->getPosByChFld(0, FLD_UAC, rec), rec, (float)((p->packet[21] << 8) + p->packet[22])/10); + iv->setValue(iv->getPosByChFld(0, FLD_UAC, rec), rec, (float)((p->packet[15+offset] << 8) + p->packet[16+offset])/10); yield(); // F_AC = (float) ((p->packet[17] << 8) + p->packet[18])/100; - iv->setValue(iv->getPosByChFld(0, FLD_IAC, rec), rec, (float)((p->packet[23] << 8) + p->packet[24])/100); - yield(); + //iv->setValue(iv->getPosByChFld(0, FLD_IAC, rec), rec, (float)((p->packet[17+offset] << 8) + p->packet[18+offset])/100); + //yield(); // P_DC = (float)((p->packet[19] << 8) + p->packet[20])/10; - iv->setValue(iv->getPosByChFld(chan, FLD_PDC, rec), rec, (float)((p->packet[25] << 8) + p->packet[26])/10); + iv->setValue(iv->getPosByChFld(chan, FLD_PDC, rec), rec, (float)((p->packet[19+offset] << 8) + p->packet[20+offset])/10); yield(); // Q_DC = (float)((p->packet[21] << 8) + p->packet[22])/1; - iv->setValue(iv->getPosByChFld(chan, FLD_Q, rec), rec, (float)((p->packet[21] << 8) + p->packet[22])/1); + iv->setValue(iv->getPosByChFld(chan, FLD_Q, rec), rec, (float)((p->packet[21+offset] << 8) + p->packet[22+offset])/1); yield(); - iv->setValue(iv->getPosByChFld(0, FLD_T, rec), rec, (float) ((int16_t)(p->packet[29] << 8) + p->packet[30])/10); - iv->setValue(iv->getPosByChFld(0, FLD_F, rec), rec, (float) ((p->packet[23] << 8) + p->packet[24])/100); + iv->setValue(iv->getPosByChFld(0, FLD_T, rec), rec, (float) ((int16_t)(p->packet[23+offset] << 8) + p->packet[24+offset])/10); + iv->setValue(iv->getPosByChFld(0, FLD_F, rec), rec, (float) ((p->packet[17+offset] << 8) + p->packet[18+offset])/100); //23 is freq or IAC? yield(); //FLD_YD @@ -427,7 +433,7 @@ class MiPayload { FCODE = (uint8_t)(p->packet[27]); // MI300: (int)((p->packet[15] << 8) + p->packet[16]); */ //iv->setValue(iv->getPosByChFld(chan, FLD_YD, rec), rec, (uint8_t)(p->packet[25])); //iv->setValue(iv->getPosByChFld(chan, FLD_EVT, rec), rec, (uint8_t)(p->packet[27])); - iv->setValue(iv->getPosByChFld(0, FLD_EVT, rec), rec, (uint8_t)(p->packet[27])); + iv->setValue(iv->getPosByChFld(0, FLD_EVT, rec), rec, (uint8_t)(p->packet[21+offset])); yield(); if (iv->alarmMesIndex < rec->record[iv->getPosByChFld(0, FLD_EVT, rec)]){ iv->alarmMesIndex = rec->record[iv->getPosByChFld(0, FLD_EVT, rec)];