mirror of
https://github.com/lumapu/ahoy.git
synced 2025-05-29 08:46:11 +02:00
various fixes
- increase buffer - fix incomplete miHwDecode - shorten timeout for MI
This commit is contained in:
parent
3282f44e37
commit
810afaac8b
4 changed files with 196 additions and 214 deletions
|
@ -22,6 +22,10 @@ class CommQueue {
|
|||
|
||||
void add(Inverter<> *iv, uint8_t cmd, bool delOnPop = true) {
|
||||
mQueue[mWrPtr] = queue_s(iv, cmd, delOnPop, false);
|
||||
/*mQueue[mRdPtr].firstTry = false;
|
||||
if((IV_HM == mQueue[mRdPtr].iv->ivGen) || (IV_MI == mQueue[mRdPtr].iv->ivGen)) {
|
||||
mQueue[mRdPtr].firstTry = ((mQueue[mRdPtr].iv->isAvailable()) || (millis() < 120000));
|
||||
}*/
|
||||
inc(&mWrPtr);
|
||||
}
|
||||
|
||||
|
@ -30,9 +34,9 @@ class CommQueue {
|
|||
Inverter<> *iv;
|
||||
uint8_t cmd;
|
||||
uint8_t attempts;
|
||||
uint32_t ts;
|
||||
bool delOnPop;
|
||||
bool isDevControl;
|
||||
uint32_t ts;
|
||||
queue_s() {}
|
||||
queue_s(Inverter<> *i, uint8_t c, bool d, bool dev) :
|
||||
iv(i), cmd(c), attempts(5), ts(0), delOnPop(d), isDevControl(dev) {}
|
||||
|
@ -48,6 +52,10 @@ class CommQueue {
|
|||
mQueue[mWrPtr] = *q;
|
||||
if(rstAttempts)
|
||||
mQueue[mWrPtr].attempts = 5;
|
||||
/*mQueue[mRdPtr].firstTry = false;
|
||||
if((IV_HM == mQueue[mRdPtr].iv->ivGen) || (IV_MI == mQueue[mRdPtr].iv->ivGen)) {
|
||||
mQueue[mRdPtr].firstTry = ((mQueue[mRdPtr].iv->isAvailable()) || (millis() < 120000));
|
||||
}*/
|
||||
inc(&mWrPtr);
|
||||
}
|
||||
|
||||
|
@ -67,6 +75,13 @@ class CommQueue {
|
|||
inc(&mRdPtr);
|
||||
}
|
||||
|
||||
bool isFirstTry(void) {
|
||||
if(!mQueue[mRdPtr].firstTry)
|
||||
return false;
|
||||
mQueue[mRdPtr].firstTry = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void setTs(uint32_t *ts) {
|
||||
mQueue[mRdPtr].ts = *ts;
|
||||
}
|
||||
|
|
|
@ -10,8 +10,9 @@
|
|||
#include <Arduino.h>
|
||||
#include "../utils/crc.h"
|
||||
|
||||
#define MI_TIMEOUT 500
|
||||
#define MI_TIMEOUT 250
|
||||
#define DEFAULT_TIMEOUT 500
|
||||
#define MAX_BUFFER 200 //was: 150 (hardcoded)
|
||||
|
||||
typedef std::function<void(uint8_t, Inverter<> *)> payloadListenerType;
|
||||
typedef std::function<void(Inverter<> *)> alarmListenerType;
|
||||
|
@ -40,7 +41,7 @@ class Communication : public CommQueue<> {
|
|||
if(!valid)
|
||||
return; // empty
|
||||
|
||||
uint16_t lcl_tmo = q->iv->ivGen != IV_MI ? DEFAULT_TIMEOUT : MI_TIMEOUT;
|
||||
uint16_t timeout = q->iv->ivGen != IV_MI ? DEFAULT_TIMEOUT : MI_TIMEOUT;
|
||||
|
||||
switch(mState) {
|
||||
case States::RESET:
|
||||
|
@ -59,22 +60,10 @@ class Communication : public CommQueue<> {
|
|||
if(ActivePowerContr == q->cmd)
|
||||
q->iv->powerLimitAck = false;
|
||||
q->iv->radio->sendControlPacket(q->iv, q->cmd, q->iv->powerLimit, false);
|
||||
}
|
||||
else if (q->iv->ivGen != IV_MI)
|
||||
} else
|
||||
q->iv->radio->prepareDevInformCmd(q->iv, q->cmd, q->ts, q->iv->alarmLastId, false);
|
||||
else { // IV_MI
|
||||
//uint8_t cmd = q->iv->type == INV_TYPE_4CH ? MI_REQ_4CH : MI_REQ_CH1;
|
||||
//q->iv->radio->sendCmdPacket(q->iv, cmd, cmd, false, false);
|
||||
q->iv->radio->sendCmdPacket(q->iv, q->cmd, q->cmd, false, false);
|
||||
//if (q->iv->radio->mSerialDebug) {
|
||||
DPRINT_IVID(DBG_INFO, q->iv->id);
|
||||
DBGPRINT(F("legacy cmd 0x"));
|
||||
DBGHEXLN(q->cmd);
|
||||
//}
|
||||
//mPayload[q->iv->id]. = cmd;
|
||||
}
|
||||
q->iv->radioStatistics.txCnt++;
|
||||
mWaitTimeout = millis() + lcl_tmo;
|
||||
mWaitTimeout = millis() + timeout;
|
||||
setAttempt();
|
||||
mState = States::WAIT;
|
||||
break;
|
||||
|
@ -90,7 +79,7 @@ class Communication : public CommQueue<> {
|
|||
cmdDone();
|
||||
DPRINT_IVID(DBG_INFO, q->iv->id);
|
||||
DBGPRINT(F("request timeout: "));
|
||||
DBGPRINT(String(millis() - mWaitTimeout + lcl_tmo));
|
||||
DBGPRINT(String(millis() - mWaitTimeout + timeout));
|
||||
DBGPRINTLN(F("ms"));
|
||||
|
||||
q->iv->radioStatistics.rxFailNoAnser++; // got nothing
|
||||
|
@ -109,15 +98,14 @@ class Communication : public CommQueue<> {
|
|||
DPRINT_IVID(DBG_INFO, q->iv->id);
|
||||
DBGPRINT(F("RX "));
|
||||
if(p->millis < 100)
|
||||
DBGPRINT(F("0"));
|
||||
DBGPRINT(F(" "));
|
||||
DBGPRINT(String(p->millis));
|
||||
DBGPRINT(F("ms "));
|
||||
DBGPRINT(String(p->len));
|
||||
if((IV_HM == q->iv->ivGen) || (IV_MI == q->iv->ivGen)) {
|
||||
DBGPRINT(F(" CH"));
|
||||
if(3 == p->ch)
|
||||
DBGPRINT(F("03"));
|
||||
else
|
||||
DBGPRINT(F("0"));
|
||||
DBGPRINT(String(p->ch));
|
||||
}
|
||||
DBGPRINT(F(", "));
|
||||
|
@ -137,13 +125,20 @@ class Communication : public CommQueue<> {
|
|||
} else if(IV_MI == q->iv->ivGen) {
|
||||
parseMiFrame(p, q);
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
DPRINTLN(DBG_WARN, F("Inverter serial does not match"));
|
||||
mWaitTimeout = millis() + timeout;
|
||||
}
|
||||
|
||||
q->iv->radio->mBufCtrl.pop();
|
||||
yield();
|
||||
}
|
||||
if(0 == q->attempts) {
|
||||
cmdDone(q);
|
||||
mState = States::RESET;
|
||||
} else
|
||||
mState = nextState;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -158,14 +153,15 @@ class Communication : public CommQueue<> {
|
|||
|
||||
uint8_t i = 0;
|
||||
while(i < MAX_PAYLOAD_ENTRIES) {
|
||||
if(mLocalBuf[i++].len == 0)
|
||||
if(mLocalBuf[i].len == 0)
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
|
||||
if(q->attempts) {
|
||||
q->iv->radio->sendCmdPacket(q->iv, TX_REQ_INFO, (ALL_FRAMES + i), true);
|
||||
q->iv->radio->sendCmdPacket(q->iv, TX_REQ_INFO, (SINGLE_FRAME + i), true);
|
||||
q->iv->radioStatistics.retransmits++;
|
||||
mWaitTimeout = millis() + lcl_tmo;
|
||||
mWaitTimeout = millis() + timeout;
|
||||
mState = States::WAIT;
|
||||
} else {
|
||||
add(q, true);
|
||||
|
@ -187,9 +183,9 @@ class Communication : public CommQueue<> {
|
|||
DBGPRINTLN(F(" attempts left)"));
|
||||
|
||||
if(q->attempts) {
|
||||
q->iv->radio->sendCmdPacket(q->iv, TX_REQ_INFO, (ALL_FRAMES + i), true);
|
||||
q->iv->radio->sendCmdPacket(q->iv, TX_REQ_INFO, (SINGLE_FRAME + i), true);
|
||||
q->iv->radioStatistics.retransmits++;
|
||||
mWaitTimeout = millis() + lcl_tmo;
|
||||
mWaitTimeout = millis() + timeout;
|
||||
mState = States::WAIT;
|
||||
} else {
|
||||
add(q, true);
|
||||
|
@ -257,65 +253,165 @@ class Communication : public CommQueue<> {
|
|||
|| (p->packet[0] == MI_REQ_CH2 + ALL_FRAMES)
|
||||
|| ((p->packet[0] >= (MI_REQ_4CH + ALL_FRAMES))
|
||||
&& (p->packet[0] < (0x39 + SINGLE_FRAME))
|
||||
&& (q->cmd != 0x0f))) {
|
||||
)) { //&& (p->packet[0] != (0x0f + ALL_FRAMES)))) {
|
||||
// small MI or MI 1500 data responses to 0x09, 0x11, 0x36, 0x37, 0x38 and 0x39
|
||||
//mPayload[iv->id].txId = p->packet[0];
|
||||
miDataDecode(p, q);
|
||||
|
||||
}
|
||||
else if (p->packet[0] == 0x0f + ALL_FRAMES)
|
||||
} else if (p->packet[0] == (0x0f + ALL_FRAMES))
|
||||
miHwDecode(p, q);
|
||||
|
||||
else if ((p->packet[0] == 0x88) || (p->packet[0] == 0x92)) {
|
||||
record_t<> *rec = q->iv->getRecordStruct(RealTimeRunData_Debug); // choose the record structure
|
||||
rec->ts = q->ts;
|
||||
miStsConsolidate(q, p->packet[0] == 0x88 ? 1 : 2, rec, p->packet[10], p->packet[12], p->packet[9], p->packet[11]);
|
||||
miStsConsolidate(q, ((p->packet[0] == 0x88) ? 1 : 2), rec, p->packet[10], p->packet[12], p->packet[9], p->packet[11]);
|
||||
}
|
||||
}
|
||||
|
||||
inline void parseDevCtrl(packet_t *p, const queue_s *q) {
|
||||
if((p->packet[12] != ActivePowerContr) || (p->packet[13] != 0x00))
|
||||
return;
|
||||
bool accepted = true;
|
||||
if((p->packet[10] == 0x00) && (p->packet[11] == 0x00))
|
||||
q->iv->powerLimitAck = true;
|
||||
else
|
||||
accepted = false;
|
||||
|
||||
DPRINT_IVID(DBG_INFO, q->iv->id);
|
||||
DBGPRINT(F(" has "));
|
||||
if(!accepted) DBGPRINT(F("not "));
|
||||
DBGPRINT(F("accepted power limit set point "));
|
||||
DBGPRINT(String(q->iv->powerLimit[0]));
|
||||
DBGPRINT(F(" with PowerLimitControl "));
|
||||
DBGPRINTLN(String(q->iv->powerLimit[1]));
|
||||
q->iv->actPowerLimit = 0xffff; // unknown, readback current value
|
||||
}
|
||||
|
||||
inline void compilePayload(const queue_s *q) {
|
||||
uint16_t crc = 0xffff, crcRcv = 0x0000;
|
||||
for(uint8_t i = 0; i < mMaxFrameId; i++) {
|
||||
if(i == (mMaxFrameId - 1)) {
|
||||
crc = ah::crc16(mLocalBuf[i].buf, mLocalBuf[i].len - 2, crc);
|
||||
crcRcv = (mLocalBuf[i].buf[mLocalBuf[i].len-2] << 8);
|
||||
crcRcv |= mLocalBuf[i].buf[mLocalBuf[i].len-1];
|
||||
} else
|
||||
crc = ah::crc16(mLocalBuf[i].buf, mLocalBuf[i].len, crc);
|
||||
}
|
||||
|
||||
if(crc != crcRcv) {
|
||||
DPRINT_IVID(DBG_WARN, q->iv->id);
|
||||
DBGPRINT(F("CRC Error "));
|
||||
if(q->attempts == 0) {
|
||||
DBGPRINTLN(F("-> Fail"));
|
||||
q->iv->radioStatistics.rxFail++; // got fragments but not complete response
|
||||
cmdDone();
|
||||
} else
|
||||
DBGPRINTLN(F("-> complete retransmit"));
|
||||
mState = States::RESET;
|
||||
return;
|
||||
}
|
||||
|
||||
/*DPRINT_IVID(DBG_INFO, q->iv->id);
|
||||
DBGPRINT(F("procPyld: cmd: 0x"));
|
||||
DBGHEXLN(q->cmd);*/
|
||||
|
||||
memset(mPayload, 0, MAX_BUFFER);
|
||||
int8_t rssi = -127;
|
||||
uint8_t len = 0;
|
||||
|
||||
for(uint8_t i = 0; i < mMaxFrameId; i++) {
|
||||
if(mLocalBuf[i].len + len > MAX_BUFFER) {
|
||||
DPRINTLN(DBG_ERROR, F("payload buffer to small!"));
|
||||
return;
|
||||
}
|
||||
memcpy(&mPayload[len], mLocalBuf[i].buf, mLocalBuf[i].len);
|
||||
len += mLocalBuf[i].len;
|
||||
// get worst RSSI (high value is better)
|
||||
if(mLocalBuf[i].rssi > rssi)
|
||||
rssi = mLocalBuf[i].rssi;
|
||||
}
|
||||
|
||||
len -= 2;
|
||||
|
||||
DPRINT_IVID(DBG_INFO, q->iv->id);
|
||||
DBGPRINT(F("Payload ("));
|
||||
DBGPRINT(String(len));
|
||||
DBGPRINT(F("): "));
|
||||
ah::dumpBuf(mPayload, len);
|
||||
|
||||
record_t<> *rec = q->iv->getRecordStruct(q->cmd);
|
||||
if(NULL == rec) {
|
||||
DPRINTLN(DBG_ERROR, F("record is NULL!"));
|
||||
return;
|
||||
}
|
||||
if((rec->pyldLen != len) && (0 != rec->pyldLen)) {
|
||||
DPRINT(DBG_ERROR, F("plausibility check failed, expected "));
|
||||
DBGPRINT(String(rec->pyldLen));
|
||||
DBGPRINTLN(F(" bytes"));
|
||||
q->iv->radioStatistics.rxFail++;
|
||||
return;
|
||||
}
|
||||
|
||||
q->iv->radioStatistics.rxSuccess++;
|
||||
|
||||
rec->ts = q->ts;
|
||||
for (uint8_t i = 0; i < rec->length; i++) {
|
||||
q->iv->addValue(i, mPayload, rec);
|
||||
}
|
||||
|
||||
q->iv->rssi = rssi;
|
||||
q->iv->doCalculations();
|
||||
|
||||
if(AlarmData == q->cmd) {
|
||||
uint8_t i = 0;
|
||||
while(1) {
|
||||
if(0 == q->iv->parseAlarmLog(i++, mPayload, len))
|
||||
break;
|
||||
if (NULL != mCbAlarm)
|
||||
(mCbAlarm)(q->iv);
|
||||
yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
inline void miHwDecode(packet_t *p, const queue_s *q) {
|
||||
record_t<> *rec = q->iv->getRecordStruct(InverterDevInform_All); // choose the record structure
|
||||
rec->ts = q->ts;
|
||||
//mPayload[iv->id].gotFragment = true;
|
||||
uint8_t multi_parts = 0;
|
||||
|
||||
/*
|
||||
Polling the device software and hardware version number command
|
||||
start byte Command word routing address target address User data check end byte
|
||||
byte[0] byte[1] byte[2] byte[3] byte[4] byte[5] byte[6] byte[7] byte[8] byte[9] byte[10] byte[11] byte[12]
|
||||
0x7e 0x0f xx xx xx xx YY YY YY YY 0x00 CRC 0x7f
|
||||
Command Receipt - First Frame
|
||||
start byte Command word target address routing address Multi-frame marking User data User data User data User data User data User data User data User data User data User data User data User data User data User data User data User data check end byte
|
||||
byte[0] byte[1] byte[2] byte[3] byte[4] byte[5] byte[6] byte[7] byte[8] byte[9] byte[10] byte[11] byte[12] byte[13] byte[14] byte[15] byte[16] byte[17] byte[18] byte[19] byte[20] byte[21] byte[22] byte[23] byte[24] byte[25] byte[26] byte[27] byte[28]
|
||||
0x7e 0x8f YY YY YY YY xx xx xx xx 0x00 USFWBuild_VER APPFWBuild_VER APPFWBuild_YYYY APPFWBuild_MMDD APPFWBuild_HHMM APPFW_PN HW_VER CRC 0x7f
|
||||
Command Receipt - Second Frame
|
||||
start byte Command word target address routing address Multi-frame marking User data User data User data User data User data User data User data User data User data User data User data User data User data User data User data User data check end byte
|
||||
byte[0] byte[1] byte[2] byte[3] byte[4] byte[5] byte[6] byte[7] byte[8] byte[9] byte[10] byte[11] byte[12] byte[13] byte[14] byte[15] byte[16] byte[17] byte[18] byte[19] byte[20] byte[21] byte[22] byte[23] byte[24] byte[25] byte[26] byte[27] byte[28]
|
||||
0x7e 0x8f YY YY YY YY xx xx xx xx 0x01 HW_PN HW_FB_TLmValue HW_FB_ReSPRT HW_GridSamp_ResValule HW_ECapValue Matching_APPFW_PN CRC 0x7f
|
||||
Command receipt - third frame
|
||||
start byte Command word target address routing address Multi-frame marking User data User data User data User data User data User data User data User data check end byte
|
||||
byte[0] byte[1] byte[2] byte[3] byte[4] byte[5] byte[6] byte[7] byte[8] byte[9] byte[10] byte[11] byte[12] byte[13] byte[14] byte[15] byte[16] byte[15] byte[16] byte[17] byte[18]
|
||||
0x7e 0x8f YY YY YY YY xx xx xx xx 0x12 APPFW_MINVER HWInfoAddr PNInfoCRC_gusv PNInfoCRC_gusv CRC 0x7f
|
||||
*/
|
||||
/*
|
||||
Polling the device software and hardware version number command
|
||||
start byte Command word routing address target address User data check end byte
|
||||
byte[0] byte[1] byte[2] byte[3] byte[4] byte[5] byte[6] byte[7] byte[8] byte[9] byte[10] byte[11] byte[12]
|
||||
0x7e 0x0f xx xx xx xx YY YY YY YY 0x00 CRC 0x7f
|
||||
Command Receipt - First Frame
|
||||
start byte Command word target address routing address Multi-frame marking User data User data User data User data User data User data User data User data User data User data User data User data User data User data User data User data check end byte
|
||||
byte[0] byte[1] byte[2] byte[3] byte[4] byte[5] byte[6] byte[7] byte[8] byte[9] byte[10] byte[11] byte[12] byte[13] byte[14] byte[15] byte[16] byte[17] byte[18] byte[19] byte[20] byte[21] byte[22] byte[23] byte[24] byte[25] byte[26] byte[27] byte[28]
|
||||
0x7e 0x8f YY YY YY YY xx xx xx xx 0x00 USFWBuild_VER APPFWBuild_VER APPFWBuild_YYYY APPFWBuild_MMDD APPFWBuild_HHMM APPFW_PN HW_VER CRC 0x7f
|
||||
Command Receipt - Second Frame
|
||||
start byte Command word target address routing address Multi-frame marking User data User data User data User data User data User data User data User data User data User data User data User data User data User data User data User data check end byte
|
||||
byte[0] byte[1] byte[2] byte[3] byte[4] byte[5] byte[6] byte[7] byte[8] byte[9] byte[10] byte[11] byte[12] byte[13] byte[14] byte[15] byte[16] byte[17] byte[18] byte[19] byte[20] byte[21] byte[22] byte[23] byte[24] byte[25] byte[26] byte[27] byte[28]
|
||||
0x7e 0x8f YY YY YY YY xx xx xx xx 0x01 HW_PN HW_FB_TLmValue HW_FB_ReSPRT HW_GridSamp_ResValule HW_ECapValue Matching_APPFW_PN CRC 0x7f
|
||||
Command receipt - third frame
|
||||
start byte Command word target address routing address Multi-frame marking User data User data User data User data User data User data User data User data check end byte
|
||||
byte[0] byte[1] byte[2] byte[3] byte[4] byte[5] byte[6] byte[7] byte[8] byte[9] byte[10] byte[11] byte[12] byte[13] byte[14] byte[15] byte[16] byte[15] byte[16] byte[17] byte[18]
|
||||
0x7e 0x8f YY YY YY YY xx xx xx xx 0x12 APPFW_MINVER HWInfoAddr PNInfoCRC_gusv PNInfoCRC_gusv CRC 0x7f
|
||||
*/
|
||||
|
||||
/*
|
||||
case InverterDevInform_All:
|
||||
/*
|
||||
case InverterDevInform_All:
|
||||
rec->length = (uint8_t)(HMINFO_LIST_LEN);
|
||||
rec->assign = (byteAssign_t *)InfoAssignment;
|
||||
rec->pyldLen = HMINFO_PAYLOAD_LEN;
|
||||
break;
|
||||
|
||||
const byteAssign_t InfoAssignment[] = {
|
||||
{ FLD_FW_VERSION, UNIT_NONE, CH0, 0, 2, 1 },
|
||||
{ FLD_FW_BUILD_YEAR, UNIT_NONE, CH0, 2, 2, 1 },
|
||||
{ FLD_FW_BUILD_MONTH_DAY, UNIT_NONE, CH0, 4, 2, 1 },
|
||||
{ FLD_FW_BUILD_HOUR_MINUTE, UNIT_NONE, CH0, 6, 2, 1 },
|
||||
{ FLD_BOOTLOADER_VER, UNIT_NONE, CH0, 8, 2, 1 }
|
||||
};
|
||||
*/
|
||||
|
||||
const byteAssign_t InfoAssignment[] = {
|
||||
{ FLD_FW_VERSION, UNIT_NONE, CH0, 0, 2, 1 },
|
||||
{ FLD_FW_BUILD_YEAR, UNIT_NONE, CH0, 2, 2, 1 },
|
||||
{ FLD_FW_BUILD_MONTH_DAY, UNIT_NONE, CH0, 4, 2, 1 },
|
||||
{ FLD_FW_BUILD_HOUR_MINUTE, UNIT_NONE, CH0, 6, 2, 1 },
|
||||
{ FLD_BOOTLOADER_VER, UNIT_NONE, CH0, 8, 2, 1 }
|
||||
};
|
||||
*/
|
||||
if ( p->packet[9] == 0x00 ) {//first frame
|
||||
//FLD_FW_VERSION
|
||||
for (uint8_t i = 0; i < 5; i++) {
|
||||
|
@ -413,9 +509,6 @@ const byteAssign_t InfoAssignment[] = {
|
|||
q->iv->radioStatistics.rxSuccess++;
|
||||
mState = States::RESET;
|
||||
|
||||
//mPayload[iv->id].gotFragment = true;
|
||||
//mPayload[iv->id].multi_parts += 4;
|
||||
|
||||
uint8_t datachan = ( p->packet[0] == (MI_REQ_CH1 + ALL_FRAMES) || p->packet[0] == (MI_REQ_4CH + ALL_FRAMES) ) ? CH1 :
|
||||
( p->packet[0] == (MI_REQ_CH2 + ALL_FRAMES) || p->packet[0] == (0x37 + ALL_FRAMES) ) ? CH2 :
|
||||
p->packet[0] == (0x38 + ALL_FRAMES) ? CH3 :
|
||||
|
@ -434,18 +527,13 @@ const byteAssign_t InfoAssignment[] = {
|
|||
|
||||
q->iv->setValue(q->iv->getPosByChFld(0, FLD_T, rec), rec, (float) ((int16_t)(p->packet[21] << 8) + p->packet[22])/10);
|
||||
q->iv->setValue(q->iv->getPosByChFld(0, FLD_IRR, rec), rec, (float) (calcIrradiation(q->iv, datachan)));
|
||||
//mPayload[q->iv->id].rssi[(datachan-1)] = p->rssi;
|
||||
|
||||
if (datachan == 1) //mPayload[q->iv->id].rssi[(datachan-1)] = p->rssi;
|
||||
q->iv->rssi = p->rssi;
|
||||
else if(q->iv->rssi > p->rssi)
|
||||
q->iv->rssi = p->rssi;
|
||||
|
||||
/*if ( datachan < 3 ) {
|
||||
mPayload[q->iv->id].dataAB[datachan] = true;
|
||||
}
|
||||
if ( !mPayload[iv->id].dataAB[CH0] && mPayload[iv->id].dataAB[CH1] && mPayload[iv->id].dataAB[CH2] ) {
|
||||
mPayload[iv->id].dataAB[CH0] = true;
|
||||
}*/
|
||||
|
||||
if (p->packet[0] >= (MI_REQ_4CH + ALL_FRAMES) ) {
|
||||
/*For MI1500:
|
||||
if (MI1500) {
|
||||
|
@ -456,11 +544,16 @@ const byteAssign_t InfoAssignment[] = {
|
|||
miStsConsolidate(q, datachan, rec, p->packet[23], p->packet[24]);
|
||||
|
||||
if (p->packet[0] < (0x39 + ALL_FRAMES) ) {
|
||||
addImportant(q->iv, (q->cmd + 1));
|
||||
//mPayload[iv->id].txCmd++;
|
||||
//mPayload[iv->id].retransmits = 0; // reserve retransmissions for each response
|
||||
//mPayload[iv->id].complete = false;
|
||||
miNextRequest((p->packet[0] - ALL_FRAMES + 1), q);
|
||||
} else {
|
||||
miComplete(q->iv);
|
||||
}
|
||||
} else if((p->packet[0] == (MI_REQ_CH1 + ALL_FRAMES)) && q->iv->type == INV_TYPE_2CH ) {
|
||||
} else if((p->packet[0] == (MI_REQ_CH1 + ALL_FRAMES)) && (q->iv->type == INV_TYPE_2CH)) {
|
||||
addImportant(q->iv, MI_REQ_CH2);
|
||||
miNextRequest(MI_REQ_CH2, q);
|
||||
} else { // first data msg for 1ch, 2nd for 2ch
|
||||
miComplete(q->iv);
|
||||
|
@ -488,17 +581,6 @@ const byteAssign_t InfoAssignment[] = {
|
|||
}
|
||||
}
|
||||
|
||||
/* inline void miStsDecode(Inverter<> *iv, packet_t *p, uint8_t stschan = CH1) {
|
||||
record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug); // choose the record structure
|
||||
rec->ts = mPayload[iv->id].ts;
|
||||
mPayload[iv->id].gotFragment = true;
|
||||
mPayload[iv->id].multi_parts += 3;
|
||||
mPayload[iv->id].txId = p->packet[0];
|
||||
miStsConsolidate(iv, stschan, rec, p->packet[10], p->packet[12], p->packet[9], p->packet[11]);
|
||||
mPayload[iv->id].stsAB[stschan] = true;
|
||||
if (mPayload[iv->id].stsAB[CH1] && mPayload[iv->id].stsAB[CH2])
|
||||
*/
|
||||
|
||||
inline void miStsConsolidate(const queue_s *q, 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 statusMi = 3; // regular status for MI, change to 1 later?
|
||||
|
@ -598,113 +680,6 @@ const byteAssign_t InfoAssignment[] = {
|
|||
iv->isProducing();
|
||||
}
|
||||
|
||||
|
||||
inline void parseDevCtrl(packet_t *p, const queue_s *q) {
|
||||
if((p->packet[12] != ActivePowerContr) || (p->packet[13] != 0x00))
|
||||
return;
|
||||
bool accepted = true;
|
||||
if((p->packet[10] == 0x00) && (p->packet[11] == 0x00))
|
||||
q->iv->powerLimitAck = true;
|
||||
else
|
||||
accepted = false;
|
||||
|
||||
DPRINT_IVID(DBG_INFO, q->iv->id);
|
||||
DBGPRINT(F("has "));
|
||||
if(!accepted) DBGPRINT(F("not "));
|
||||
DBGPRINT(F("accepted power limit set point "));
|
||||
DBGPRINT(String(q->iv->powerLimit[0]));
|
||||
DBGPRINT(F(" with PowerLimitControl "));
|
||||
DBGPRINTLN(String(q->iv->powerLimit[1]));
|
||||
q->iv->actPowerLimit = 0xffff; // unknown, readback current value
|
||||
}
|
||||
|
||||
inline void compilePayload(const queue_s *q) {
|
||||
uint16_t crc = 0xffff, crcRcv = 0x0000;
|
||||
for(uint8_t i = 0; i < mMaxFrameId; i++) {
|
||||
if(i == (mMaxFrameId - 1)) {
|
||||
crc = ah::crc16(mLocalBuf[i].buf, mLocalBuf[i].len - 2, crc);
|
||||
crcRcv = (mLocalBuf[i].buf[mLocalBuf[i].len-2] << 8);
|
||||
crcRcv |= mLocalBuf[i].buf[mLocalBuf[i].len-1];
|
||||
} else
|
||||
crc = ah::crc16(mLocalBuf[i].buf, mLocalBuf[i].len, crc);
|
||||
}
|
||||
|
||||
if(crc != crcRcv) {
|
||||
DPRINT_IVID(DBG_WARN, q->iv->id);
|
||||
DBGPRINT(F("CRC Error "));
|
||||
if(q->attempts == 0) {
|
||||
DBGPRINTLN(F("-> Fail"));
|
||||
q->iv->radioStatistics.rxFail++; // got fragments but not complete response
|
||||
cmdDone();
|
||||
} else
|
||||
DBGPRINTLN(F("-> complete retransmit"));
|
||||
mState = States::RESET;
|
||||
return;
|
||||
}
|
||||
|
||||
/*DPRINT_IVID(DBG_INFO, q->iv->id);
|
||||
DBGPRINT(F("procPyld: cmd: 0x"));
|
||||
DBGHEXLN(q->cmd);*/
|
||||
|
||||
memset(mPayload, 0, 150);
|
||||
int8_t rssi = -127;
|
||||
uint8_t len = 0;
|
||||
|
||||
for(uint8_t i = 0; i < mMaxFrameId; i++) {
|
||||
if(mLocalBuf[i].len + len > 150) {
|
||||
DPRINTLN(DBG_ERROR, F("payload buffer to small!"));
|
||||
return;
|
||||
}
|
||||
memcpy(&mPayload[len], mLocalBuf[i].buf, mLocalBuf[i].len);
|
||||
len += mLocalBuf[i].len;
|
||||
// get best RSSI
|
||||
if(mLocalBuf[i].rssi > rssi)
|
||||
rssi = mLocalBuf[i].rssi;
|
||||
}
|
||||
|
||||
len -= 2;
|
||||
|
||||
DPRINT_IVID(DBG_INFO, q->iv->id);
|
||||
DBGPRINT(F("Payload ("));
|
||||
DBGPRINT(String(len));
|
||||
DBGPRINT(F("): "));
|
||||
ah::dumpBuf(mPayload, len);
|
||||
|
||||
record_t<> *rec = q->iv->getRecordStruct(q->cmd);
|
||||
if(NULL == rec) {
|
||||
DPRINTLN(DBG_ERROR, F("record is NULL!"));
|
||||
return;
|
||||
}
|
||||
if((rec->pyldLen != len) && (0 != rec->pyldLen)) {
|
||||
DPRINT(DBG_ERROR, F("plausibility check failed, expected "));
|
||||
DBGPRINT(String(rec->pyldLen));
|
||||
DBGPRINTLN(F(" bytes"));
|
||||
q->iv->radioStatistics.rxFail++;
|
||||
return;
|
||||
}
|
||||
|
||||
q->iv->radioStatistics.rxSuccess++;
|
||||
|
||||
rec->ts = q->ts;
|
||||
for (uint8_t i = 0; i < rec->length; i++) {
|
||||
q->iv->addValue(i, mPayload, rec);
|
||||
}
|
||||
|
||||
q->iv->rssi = rssi;
|
||||
q->iv->doCalculations();
|
||||
|
||||
if(AlarmData == q->cmd) {
|
||||
uint8_t i = 0;
|
||||
while(1) {
|
||||
if(0 == q->iv->parseAlarmLog(i++, mPayload, len))
|
||||
break;
|
||||
if (NULL != mCbAlarm)
|
||||
(mCbAlarm)(q->iv);
|
||||
yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
enum class States : uint8_t {
|
||||
RESET, START, WAIT, CHECK_FRAMES, CHECK_PACKAGE
|
||||
|
@ -722,7 +697,7 @@ const byteAssign_t InfoAssignment[] = {
|
|||
uint32_t mWaitTimeout = 0;
|
||||
std::array<frame_t, MAX_PAYLOAD_ENTRIES> mLocalBuf;
|
||||
uint8_t mMaxFrameId;
|
||||
uint8_t mPayload[150];
|
||||
uint8_t mPayload[MAX_BUFFER];
|
||||
payloadListenerType mCbPayload = NULL;
|
||||
alarmListenerType mCbAlarm = NULL;
|
||||
};
|
||||
|
|
|
@ -197,14 +197,6 @@ class Inverter {
|
|||
else
|
||||
cb(RealTimeRunData_Debug, false); // get live data
|
||||
} else {
|
||||
/*if (cmd == 0x01) { //0x1 for HM-types
|
||||
cmd2 = 0x00;
|
||||
cmd = 0x0f; // for MI, these seem to make part of polling the device software and hardware version number command
|
||||
}
|
||||
if (cmd == SystemConfigPara ) { // 0x05 for HM-types
|
||||
cmd2 = 0x00;
|
||||
cmd = 0x10; // legacy GPF request
|
||||
*/
|
||||
if(mDevControlRequest) {
|
||||
cb(devControlCmd, true);
|
||||
mDevControlRequest = false;
|
||||
|
@ -215,7 +207,7 @@ class Inverter {
|
|||
if (getChannelFieldValue(CH0, FLD_PART_NUM, rec) == 0)
|
||||
cb(0x0f, false); // hard- and firmware version for missing HW part nr, delivered by frame 1
|
||||
else
|
||||
cb(type == INV_TYPE_4CH ? MI_REQ_4CH : MI_REQ_CH1, false);
|
||||
cb(((type == INV_TYPE_4CH) ? MI_REQ_4CH : MI_REQ_CH1), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -330,15 +330,15 @@ class HmPayload {
|
|||
mPayload[iv->id].requested = false;
|
||||
mPayload[iv->id].rxTmo = false;
|
||||
|
||||
uint8_t payload[150];
|
||||
uint8_t payload[MAX_BUFFER];
|
||||
uint8_t payloadLen = 0;
|
||||
|
||||
memset(payload, 0, 150);
|
||||
memset(payload, 0, MAX_BUFFER);
|
||||
|
||||
int8_t rssi = -127;
|
||||
|
||||
for (uint8_t i = 0; i < (mPayload[iv->id].maxPackId); i++) {
|
||||
if((mPayload[iv->id].len[i] + payloadLen) > 150) {
|
||||
if((mPayload[iv->id].len[i] + payloadLen) > MAX_BUFFER) {
|
||||
DPRINTLN(DBG_ERROR, F("payload buffer to small!"));
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue