|
@ -15,16 +15,17 @@ |
|
|
typedef struct { |
|
|
typedef struct { |
|
|
uint32_t ts; |
|
|
uint32_t ts; |
|
|
bool requested; |
|
|
bool requested; |
|
|
|
|
|
bool limitrequested; |
|
|
uint8_t txCmd; |
|
|
uint8_t txCmd; |
|
|
uint8_t len[MAX_PAYLOAD_ENTRIES]; |
|
|
uint8_t len[MAX_PAYLOAD_ENTRIES]; |
|
|
bool complete; |
|
|
bool complete; |
|
|
bool dataAB[3]; |
|
|
bool dataAB[3]; |
|
|
bool stsAB[3]; |
|
|
bool stsAB[3]; |
|
|
uint8_t sts[5]; |
|
|
uint16_t sts[6]; |
|
|
uint8_t txId; |
|
|
uint8_t txId; |
|
|
uint8_t invId; |
|
|
uint8_t invId; |
|
|
uint8_t retransmits; |
|
|
uint8_t retransmits; |
|
|
uint8_t skipfirstrepeat; |
|
|
//uint8_t skipfirstrepeat;
|
|
|
bool gotFragment; |
|
|
bool gotFragment; |
|
|
/*
|
|
|
/*
|
|
|
uint8_t data[MAX_PAYLOAD_ENTRIES][MAX_RF_PAYLOAD_SIZE]; |
|
|
uint8_t data[MAX_PAYLOAD_ENTRIES][MAX_RF_PAYLOAD_SIZE]; |
|
@ -48,7 +49,8 @@ class MiPayload { |
|
|
mMaxRetrans = maxRetransmits; |
|
|
mMaxRetrans = maxRetransmits; |
|
|
mTimestamp = timestamp; |
|
|
mTimestamp = timestamp; |
|
|
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) { |
|
|
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) { |
|
|
reset(i); |
|
|
reset(i, true); |
|
|
|
|
|
mPayload[i].limitrequested = true; |
|
|
} |
|
|
} |
|
|
mSerialDebug = false; |
|
|
mSerialDebug = false; |
|
|
mHighPrioIv = NULL; |
|
|
mHighPrioIv = NULL; |
|
@ -68,7 +70,7 @@ class MiPayload { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void loop() { |
|
|
void loop() { |
|
|
if(NULL != mHighPrioIv) { |
|
|
if(NULL != mHighPrioIv) { // && mHighPrioIv->ivGen == IV_MI) {
|
|
|
ivSend(mHighPrioIv, true); // for devcontrol commands?
|
|
|
ivSend(mHighPrioIv, true); // for devcontrol commands?
|
|
|
mHighPrioIv = NULL; |
|
|
mHighPrioIv = NULL; |
|
|
} |
|
|
} |
|
@ -118,23 +120,34 @@ class MiPayload { |
|
|
if (mSerialDebug) { |
|
|
if (mSerialDebug) { |
|
|
DPRINTHEAD(DBG_INFO, iv->id); |
|
|
DPRINTHEAD(DBG_INFO, iv->id); |
|
|
DBGPRINT(F("Devcontrol request 0x")); |
|
|
DBGPRINT(F("Devcontrol request 0x")); |
|
|
DBGPRINT(String(iv->devControlCmd, HEX)); |
|
|
DHEX(iv->devControlCmd); |
|
|
DBGPRINT(F(" power limit ")); |
|
|
DBGPRINT(F(" power limit ")); |
|
|
DBGPRINTLN(String(iv->powerLimit[0])); |
|
|
DBGPRINTLN(String(iv->powerLimit[0])); |
|
|
} |
|
|
} |
|
|
mRadio->sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, false); |
|
|
mRadio->sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, false, false); |
|
|
mPayload[iv->id].txCmd = iv->devControlCmd; |
|
|
mPayload[iv->id].txCmd = iv->devControlCmd; |
|
|
//iv->clearCmdQueue();
|
|
|
mPayload[iv->id].limitrequested = true; |
|
|
//iv->enqueCommand<InfoCommand>(SystemConfigPara); // read back power limit
|
|
|
|
|
|
|
|
|
iv->clearCmdQueue(); |
|
|
|
|
|
iv->enqueCommand<InfoCommand>(SystemConfigPara); // try to read back power limit
|
|
|
} else { |
|
|
} else { |
|
|
uint8_t cmd = iv->getQueuedCmd(); |
|
|
uint8_t cmd = iv->getQueuedCmd(); |
|
|
DPRINTHEAD(DBG_INFO, iv->id); |
|
|
DPRINTHEAD(DBG_INFO, iv->id); |
|
|
DBGPRINT(F("prepareDevInformCmd 0x")); |
|
|
DBGPRINT(F("prepareDevInformCmd 0x")); |
|
|
DBGPRINTLN(String(cmd, HEX)); |
|
|
DHEXLN(cmd); |
|
|
uint8_t cmd2 = cmd; |
|
|
uint8_t cmd2 = cmd; |
|
|
if (cmd == 0x1 ) { //0x1
|
|
|
if ( cmd == SystemConfigPara ) { //0x05 for HM-types
|
|
|
cmd = 0x0f; |
|
|
if (!mPayload[iv->id].limitrequested) { // only do once at startup
|
|
|
cmd2 = 0x00; |
|
|
iv->setQueuedCmdFinished(); |
|
|
|
|
|
cmd = iv->getQueuedCmd(); |
|
|
|
|
|
} else { |
|
|
|
|
|
mPayload[iv->id].limitrequested = false; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (cmd == 0x01 || cmd == SystemConfigPara ) { //0x1 and 0x05 for HM-types
|
|
|
|
|
|
cmd = 0x0f; // for MI, these seem to make part of the Polling the device software and hardware version number command
|
|
|
|
|
|
cmd2 = cmd == SystemConfigPara ? 0x01 : 0x00; //perhaps we can only try to get second frame?
|
|
|
mRadio->sendCmdPacket(iv->radioId.u64, cmd, cmd2, false); |
|
|
mRadio->sendCmdPacket(iv->radioId.u64, cmd, cmd2, false); |
|
|
} else { |
|
|
} else { |
|
|
mRadio->prepareDevInformCmd(iv->radioId.u64, cmd2, mPayload[iv->id].ts, iv->alarmMesIndex, false, cmd); |
|
|
mRadio->prepareDevInformCmd(iv->radioId.u64, cmd2, mPayload[iv->id].ts, iv->alarmMesIndex, false, cmd); |
|
@ -157,7 +170,6 @@ class MiPayload { |
|
|
|
|
|
|
|
|
void add(Inverter<> *iv, packet_t *p) { |
|
|
void add(Inverter<> *iv, packet_t *p) { |
|
|
//DPRINTLN(DBG_INFO, F("MI got data [0]=") + String(p->packet[0], HEX));
|
|
|
//DPRINTLN(DBG_INFO, F("MI got data [0]=") + String(p->packet[0], HEX));
|
|
|
|
|
|
|
|
|
if (p->packet[0] == (0x08 + ALL_FRAMES)) { // 0x88; MI status response to 0x09
|
|
|
if (p->packet[0] == (0x08 + ALL_FRAMES)) { // 0x88; MI status response to 0x09
|
|
|
miStsDecode(iv, p); |
|
|
miStsDecode(iv, p); |
|
|
} |
|
|
} |
|
@ -218,13 +230,34 @@ const byteAssign_t InfoAssignment[] = { |
|
|
for (uint8_t i = 0; i < 5; i++) { |
|
|
for (uint8_t i = 0; i < 5; i++) { |
|
|
iv->setValue(i, rec, (float) ((p->packet[(12+2*i)] << 8) + p->packet[(13+2*i)])/1); |
|
|
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])); |
|
|
/*iv->setQueuedCmdFinished();
|
|
|
/*iv->setQueuedCmdFinished();
|
|
|
mStat->rxSuccess++; |
|
|
|
|
|
mSys->Radio.sendCmdPacket(iv->radioId.u64, 0x0f, 0x01, false);*/ |
|
|
mSys->Radio.sendCmdPacket(iv->radioId.u64, 0x0f, 0x01, false);*/ |
|
|
} else if ( p->packet[9] == 0x01 ) {//second frame
|
|
|
} else if ( p->packet[9] == 0x01 || p->packet[9] == 0x10 ) {//second frame for MI, 3rd gen. answers in 0x10
|
|
|
DPRINTHEAD(DBG_INFO, iv->id); |
|
|
DPRINTHEAD(DBG_INFO, iv->id); |
|
|
DBGPRINTLN(F("got 2nd frame (hw info)")); |
|
|
if ( p->packet[9] == 0x01 ) { |
|
|
//mSys->Radio.sendCmdPacket(iv->radioId.u64, 0x0f, 0x12, false);
|
|
|
DBGPRINTLN(F("got 2nd frame (hw info)")); |
|
|
|
|
|
} else { |
|
|
|
|
|
DBGPRINTLN(F("3rd gen. inverter!")); // see table in OpenDTU code, DevInfoParser.cpp devInfo[]
|
|
|
|
|
|
} |
|
|
|
|
|
// xlsx: HW_ECapValue is total energy?!? (data coll. inst. #154)
|
|
|
|
|
|
DPRINT(DBG_INFO,F("HW_PartNo ")); |
|
|
|
|
|
DBGPRINTLN(String((uint32_t) (((p->packet[10] << 8) | p->packet[11]) << 8 | p->packet[12]) << 8 | p->packet[13])); |
|
|
|
|
|
//DBGPRINTLN(String((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])); |
|
|
|
|
|
} |
|
|
} else if ( p->packet[9] == 0x12 ) {//3rd frame
|
|
|
} else if ( p->packet[9] == 0x12 ) {//3rd frame
|
|
|
DPRINTHEAD(DBG_INFO, iv->id); |
|
|
DPRINTHEAD(DBG_INFO, iv->id); |
|
|
DBGPRINTLN(F("got 3rd frame (hw info)")); |
|
|
DBGPRINTLN(F("got 3rd frame (hw info)")); |
|
@ -232,20 +265,26 @@ const byteAssign_t InfoAssignment[] = { |
|
|
mStat->rxSuccess++; |
|
|
mStat->rxSuccess++; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
} else if (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES)) { // response from get information command
|
|
|
} else if ( p->packet[0] == (TX_REQ_INFO + ALL_FRAMES) // response from get information command
|
|
|
// atm, we just do nothing else than print out what we got...
|
|
|
|| (p->packet[0] == 0xB6 && mPayload[iv->id].txCmd != 0x36)) { // strange short response from MI-1500 3rd gen; might be missleading!
|
|
|
// for decoding see xls- Data collection instructions - #147ff
|
|
|
// atm, we just do nothing else than print out what we got...
|
|
|
mPayload[iv->id].txId = p->packet[0]; |
|
|
// for decoding see xls- Data collection instructions - #147ff
|
|
|
|
|
|
//mPayload[iv->id].txId = p->packet[0];
|
|
|
DPRINTLN(DBG_DEBUG, F("Response from info request received")); |
|
|
DPRINTLN(DBG_DEBUG, F("Response from info request received")); |
|
|
uint8_t *pid = &p->packet[9]; |
|
|
uint8_t *pid = &p->packet[9]; |
|
|
if (*pid == 0x00) { |
|
|
if (*pid == 0x00) { |
|
|
DPRINT(DBG_DEBUG, F("fragment number zero received")); |
|
|
DPRINT(DBG_DEBUG, F("fragment number zero received")); |
|
|
|
|
|
|
|
|
iv->setQueuedCmdFinished(); |
|
|
iv->setQueuedCmdFinished(); |
|
|
} //else {
|
|
|
} else if (p->packet[9] == 0x81) { // might need some additional check, as this is only ment for short answers!
|
|
|
DPRINTLN(DBG_DEBUG, "PID: 0x" + String(*pid, HEX)); |
|
|
DPRINT(DBG_WARN, F("(#")); |
|
|
/*
|
|
|
DBGPRINT(String(iv->id)); |
|
|
if ((*pid & 0x7F) < MAX_PAYLOAD_ENTRIES) { |
|
|
DBGPRINTLN(F(") seems to use 3rd gen. protocol - switching ivGen!")); |
|
|
|
|
|
iv->ivGen = IV_HM; |
|
|
|
|
|
iv->setQueuedCmdFinished(); |
|
|
|
|
|
iv->clearCmdQueue(); |
|
|
|
|
|
//DPRINTLN(DBG_DEBUG, "PID: 0x" + String(*pid, HEX));
|
|
|
|
|
|
/* (old else-tree)
|
|
|
|
|
|
if ((*pid & 0x7F) < MAX_PAYLOAD_ENTRIES) {^ |
|
|
memcpy(mPayload[iv->id].data[(*pid & 0x7F) - 1], &p->packet[10], p->len - 11); |
|
|
memcpy(mPayload[iv->id].data[(*pid & 0x7F) - 1], &p->packet[10], p->len - 11); |
|
|
mPayload[iv->id].len[(*pid & 0x7F) - 1] = p->len - 11; |
|
|
mPayload[iv->id].len[(*pid & 0x7F) - 1] = p->len - 11; |
|
|
mPayload[iv->id].gotFragment = true; |
|
|
mPayload[iv->id].gotFragment = true; |
|
@ -257,34 +296,36 @@ const byteAssign_t InfoAssignment[] = { |
|
|
if (*pid > 0x81) |
|
|
if (*pid > 0x81) |
|
|
mPayload[iv->id].lastFound = true; |
|
|
mPayload[iv->id].lastFound = true; |
|
|
} |
|
|
} |
|
|
} |
|
|
}*/ |
|
|
} |
|
|
} |
|
|
} */ |
|
|
//}
|
|
|
} else if (p->packet[0] == (TX_REQ_DEVCONTROL + ALL_FRAMES)) { // response from dev control command
|
|
|
} 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); |
|
|
DPRINTHEAD(DBG_DEBUG, iv->id); |
|
|
DBGPRINTLN(F("Response from devcontrol request received")); |
|
|
DBGPRINTLN(F("Response from devcontrol request received")); |
|
|
|
|
|
|
|
|
mPayload[iv->id].txId = p->packet[0]; |
|
|
mPayload[iv->id].txId = p->packet[0]; |
|
|
iv->clearDevControlRequest(); |
|
|
iv->clearDevControlRequest(); |
|
|
|
|
|
|
|
|
if ((p->packet[12] == ActivePowerContr) && (p->packet[13] == 0x00)) { |
|
|
if ((p->packet[9] == 0x5a) && (p->packet[10] == 0x5a)) { |
|
|
String msg = ""; |
|
|
mApp->setMqttPowerLimitAck(iv); |
|
|
if((p->packet[10] == 0x00) && (p->packet[11] == 0x00)) |
|
|
|
|
|
mApp->setMqttPowerLimitAck(iv); |
|
|
|
|
|
else |
|
|
|
|
|
msg = "NOT "; |
|
|
|
|
|
//DPRINTLN(DBG_INFO, F("Inverter ") + String(iv->id) + F(" has ") + msg + F("accepted power limit set point ") + String(iv->powerLimit[0]) + F(" with PowerLimitControl ") + String(iv->powerLimit[1]));
|
|
|
|
|
|
DPRINTHEAD(DBG_INFO, iv->id); |
|
|
DPRINTHEAD(DBG_INFO, iv->id); |
|
|
DBGPRINTLN(F("has ") + msg + F("accepted power limit set point ") + String(iv->powerLimit[0]) + F(" with PowerLimitControl ") + String(iv->powerLimit[1])); |
|
|
DBGPRINT(F("has accepted power limit set point ")); |
|
|
|
|
|
DBGPRINT(String(iv->powerLimit[0])); |
|
|
|
|
|
DBGPRINT(F(" with PowerLimitControl ")); |
|
|
|
|
|
DBGPRINTLN(String(iv->powerLimit[1])); |
|
|
|
|
|
|
|
|
iv->clearCmdQueue(); |
|
|
iv->clearCmdQueue(); |
|
|
iv->enqueCommand<InfoCommand>(SystemConfigPara); // read back power limit
|
|
|
iv->enqueCommand<InfoCommand>(SystemConfigPara); // read back power limit
|
|
|
} |
|
|
} |
|
|
iv->devControlCmd = Init; |
|
|
iv->devControlCmd = Init; |
|
|
} else { // some other response; copied from hmPayload:process; might not be correct to do that here!!!
|
|
|
} 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)); |
|
|
DPRINT(DBG_INFO, F("procPyld: cmd: 0x")); |
|
|
DPRINTLN(DBG_INFO, F("procPyld: txid: 0x") + String(mPayload[iv->id].txId, HEX)); |
|
|
DHEXLN(mPayload[iv->id].txCmd); |
|
|
//DPRINTLN(DBG_DEBUG, F("procPyld: max: ") + String(mPayload[iv->id].maxPackId));
|
|
|
DPRINT(DBG_INFO, F("procPyld: txid: 0x")); |
|
|
|
|
|
DHEXLN(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
|
|
|
record_t<> *rec = iv->getRecordStruct(mPayload[iv->id].txCmd); // choose the parser
|
|
|
mPayload[iv->id].complete = true; |
|
|
mPayload[iv->id].complete = true; |
|
|
|
|
|
|
|
@ -366,10 +407,10 @@ const byteAssign_t InfoAssignment[] = { |
|
|
|
|
|
|
|
|
//delayed next message?
|
|
|
//delayed next message?
|
|
|
//mPayload[iv->id].skipfirstrepeat++;
|
|
|
//mPayload[iv->id].skipfirstrepeat++;
|
|
|
if (mPayload[iv->id].skipfirstrepeat) { |
|
|
/*if (mPayload[iv->id].skipfirstrepeat) {
|
|
|
mPayload[iv->id].skipfirstrepeat = 0; //reset counter*/
|
|
|
mPayload[iv->id].skipfirstrepeat = 0; //reset counter
|
|
|
continue; // skip to next inverter
|
|
|
continue; // skip to next inverter
|
|
|
} |
|
|
}*/ |
|
|
|
|
|
|
|
|
if (!mPayload[iv->id].complete) { |
|
|
if (!mPayload[iv->id].complete) { |
|
|
//DPRINTLN(DBG_INFO, F("Pyld incompl code")); //info for testing only
|
|
|
//DPRINTLN(DBG_INFO, F("Pyld incompl code")); //info for testing only
|
|
@ -385,7 +426,7 @@ const byteAssign_t InfoAssignment[] = { |
|
|
} else if(iv->devControlCmd == ActivePowerContr) { |
|
|
} else if(iv->devControlCmd == ActivePowerContr) { |
|
|
DPRINTHEAD(DBG_INFO, iv->id); |
|
|
DPRINTHEAD(DBG_INFO, iv->id); |
|
|
DBGPRINTLN(F("retransmit power limit")); |
|
|
DBGPRINTLN(F("retransmit power limit")); |
|
|
mRadio->sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, true); |
|
|
mRadio->sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, true, false); |
|
|
} else { |
|
|
} else { |
|
|
uint8_t cmd = mPayload[iv->id].txCmd; |
|
|
uint8_t cmd = mPayload[iv->id].txCmd; |
|
|
if (mPayload[iv->id].retransmits < mMaxRetrans) { |
|
|
if (mPayload[iv->id].retransmits < mMaxRetrans) { |
|
@ -424,11 +465,14 @@ const byteAssign_t InfoAssignment[] = { |
|
|
} |
|
|
} |
|
|
DPRINTHEAD(DBG_INFO, iv->id); |
|
|
DPRINTHEAD(DBG_INFO, iv->id); |
|
|
if (change) { |
|
|
if (change) { |
|
|
DBGPRINT(F("next request is 0x")); |
|
|
DBGPRINT(F("next request is")); |
|
|
|
|
|
//mPayload[iv->id].skipfirstrepeat = 0;
|
|
|
} else { |
|
|
} else { |
|
|
DBGPRINT(F("not complete: Request Retransmit 0x")); |
|
|
DBGPRINT(F("sth.")); |
|
|
|
|
|
DBGPRINT(F(" missing: Request Retransmit")); |
|
|
} |
|
|
} |
|
|
DBGPRINTLN(String(cmd, HEX)); |
|
|
DBGPRINT(F(" 0x")); |
|
|
|
|
|
DHEXLN(cmd); |
|
|
//mSys->Radio.sendCmdPacket(iv->radioId.u64, cmd, cmd, true);
|
|
|
//mSys->Radio.sendCmdPacket(iv->radioId.u64, cmd, cmd, true);
|
|
|
mRadio->prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmMesIndex, true, cmd); |
|
|
mRadio->prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmMesIndex, true, cmd); |
|
|
mPayload[iv->id].txCmd = cmd; |
|
|
mPayload[iv->id].txCmd = cmd; |
|
@ -445,7 +489,8 @@ const byteAssign_t InfoAssignment[] = { |
|
|
mPayload[iv->id].txCmd = iv->getQueuedCmd(); |
|
|
mPayload[iv->id].txCmd = iv->getQueuedCmd(); |
|
|
DPRINTHEAD(DBG_INFO, iv->id); |
|
|
DPRINTHEAD(DBG_INFO, iv->id); |
|
|
|
|
|
|
|
|
DBGPRINTLN(F("prepareDevInformCmd 0x") + String(mPayload[iv->id].txCmd, HEX)); |
|
|
DBGPRINT(F("prepareDevInformCmd 0x")); |
|
|
|
|
|
DHEXLN(mPayload[iv->id].txCmd); |
|
|
mRadio->prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true); |
|
|
mRadio->prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -455,16 +500,6 @@ const byteAssign_t InfoAssignment[] = { |
|
|
DPRINTLN(DBG_INFO, F("procPyld: txid: 0x") + String(mPayload[iv->id].txId, 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));
|
|
|
//DPRINTLN(DBG_DEBUG, F("procPyld: max: ") + String(mPayload[iv->id].maxPackId));
|
|
|
//record_t<> *rec = iv->getRecordStruct(mPayload[iv->id].txCmd); // choose the parser
|
|
|
//record_t<> *rec = iv->getRecordStruct(mPayload[iv->id].txCmd); // choose the parser
|
|
|
mPayload[iv->id].complete = true; |
|
|
|
|
|
uint8_t ac_pow = 0; |
|
|
|
|
|
//if (mPayload[iv->id].sts[0] == 3) {
|
|
|
|
|
|
ac_pow = calcPowerDcCh0(iv, 0)*9.5; |
|
|
|
|
|
//}
|
|
|
|
|
|
record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug); // choose the parser
|
|
|
|
|
|
iv->setValue(iv->getPosByChFld(0, FLD_PAC, rec), rec, (float) (ac_pow/10)); |
|
|
|
|
|
DPRINTLN(DBG_INFO, F("process: compl. set of msgs detected")); |
|
|
|
|
|
iv->setValue(iv->getPosByChFld(0, FLD_YD, rec), rec, calcYieldDayCh0(iv,0)); |
|
|
|
|
|
iv->doCalculations(); |
|
|
|
|
|
//uint8_t payload[128];
|
|
|
//uint8_t payload[128];
|
|
|
//uint8_t payloadLen = 0;
|
|
|
//uint8_t payloadLen = 0;
|
|
|
//memset(payload, 0, 128);
|
|
|
//memset(payload, 0, 128);
|
|
@ -526,30 +561,67 @@ const byteAssign_t InfoAssignment[] = { |
|
|
rec->ts = mPayload[iv->id].ts; |
|
|
rec->ts = mPayload[iv->id].ts; |
|
|
mPayload[iv->id].gotFragment = true; |
|
|
mPayload[iv->id].gotFragment = true; |
|
|
mPayload[iv->id].txId = p->packet[0]; |
|
|
mPayload[iv->id].txId = p->packet[0]; |
|
|
|
|
|
miStsConsolidate(iv, stschan, rec, p->packet[10], p->packet[12], p->packet[9], p->packet[11]); |
|
|
//uint8_t status = (p->packet[11] << 8) + p->packet[12];
|
|
|
|
|
|
uint8_t status = (p->packet[9] << 8) + p->packet[10]; |
|
|
|
|
|
//uint8_t stschan = p->packet[0] == 0x88 ? CH1 : CH2;
|
|
|
|
|
|
mPayload[iv->id].sts[stschan] = status; |
|
|
|
|
|
mPayload[iv->id].stsAB[stschan] = true; |
|
|
mPayload[iv->id].stsAB[stschan] = true; |
|
|
if (mPayload[iv->id].stsAB[CH1] && mPayload[iv->id].stsAB[CH2]) |
|
|
if (mPayload[iv->id].stsAB[CH1] && mPayload[iv->id].stsAB[CH2]) |
|
|
mPayload[iv->id].stsAB[CH0] = true; |
|
|
mPayload[iv->id].stsAB[CH0] = true; |
|
|
if ( !mPayload[iv->id].sts[0] || status < mPayload[iv->id].sts[0]) { |
|
|
//mPayload[iv->id].skipfirstrepeat = 1;
|
|
|
mPayload[iv->id].sts[0] = status; |
|
|
if (mPayload[iv->id].stsAB[CH0] && mPayload[iv->id].dataAB[CH0] && !mPayload[iv->id].complete) { |
|
|
iv->setValue(iv->getPosByChFld(0, FLD_EVT, rec), rec, status); |
|
|
miComplete(iv); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
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 (lState) |
|
|
|
|
|
status += lState*10; |
|
|
|
|
|
} else if ( uState > 3 ) { |
|
|
|
|
|
status = uState*1000 + uEnum*10; |
|
|
|
|
|
if (lState) |
|
|
|
|
|
status += lState*100; //needs review, esp. for 4ch-8310 state!
|
|
|
|
|
|
//if (lEnum)
|
|
|
|
|
|
status += lEnum; |
|
|
|
|
|
if (uEnum < 6) { |
|
|
|
|
|
status += stschan; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
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(": ")); |
|
|
|
|
|
DBGPRINTLN(iv->getAlarmStr(prntsts)); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if ( !mPayload[iv->id].sts[0] || prntsts < mPayload[iv->id].sts[0] ) { |
|
|
|
|
|
mPayload[iv->id].sts[0] = prntsts; |
|
|
|
|
|
iv->setValue(iv->getPosByChFld(0, FLD_EVT, rec), rec, prntsts); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (iv->alarmMesIndex < rec->record[iv->getPosByChFld(0, FLD_EVT, rec)]){ |
|
|
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?!?
|
|
|
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); |
|
|
DPRINTHEAD(DBG_INFO, iv->id); |
|
|
DBGPRINTLN(F("alarm ID incremented to ") + String(iv->alarmMesIndex)); |
|
|
DBGPRINT(F("alarm ID incremented to ")); |
|
|
iv->enqueCommand<InfoCommand>(AlarmData); |
|
|
DBGPRINTLN(String(iv->alarmMesIndex)); |
|
|
} |
|
|
|
|
|
//mPayload[iv->id].skipfirstrepeat = 1;
|
|
|
|
|
|
if (mPayload[iv->id].stsAB[CH0] && mPayload[iv->id].dataAB[CH0] && !mPayload[iv->id].complete) { |
|
|
|
|
|
miComplete(iv); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
/*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 != mCbAlarm) |
|
|
|
|
|
(mCbAlarm)(code, start, end); |
|
|
|
|
|
yield(); |
|
|
|
|
|
} |
|
|
|
|
|
}*/ |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void miDataDecode(Inverter<> *iv, packet_t *p) { |
|
|
void miDataDecode(Inverter<> *iv, packet_t *p) { |
|
@ -594,12 +666,14 @@ const byteAssign_t InfoAssignment[] = { |
|
|
FCODE = (uint8_t)(p->packet[27]); |
|
|
FCODE = (uint8_t)(p->packet[27]); |
|
|
}*/ |
|
|
}*/ |
|
|
|
|
|
|
|
|
uint8_t status = (uint8_t)(p->packet[23]); |
|
|
/*uint16_t status = (uint8_t)(p->packet[23]);
|
|
|
mPayload[iv->id].sts[datachan] = status; |
|
|
mPayload[iv->id].sts[datachan] = status; |
|
|
if ( !mPayload[iv->id].sts[0] || status < mPayload[iv->id].sts[0]) { |
|
|
if ( !mPayload[iv->id].sts[0] || status < mPayload[iv->id].sts[0]) { |
|
|
mPayload[iv->id].sts[0] = status; |
|
|
mPayload[iv->id].sts[0] = status; |
|
|
iv->setValue(iv->getPosByChFld(0, FLD_EVT, rec), rec, status); |
|
|
iv->setValue(iv->getPosByChFld(0, FLD_EVT, rec), rec, status); |
|
|
} |
|
|
}*/ |
|
|
|
|
|
miStsConsolidate(iv, datachan, rec, p->packet[23], p->packet[24]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (p->packet[0] < (0x39 + ALL_FRAMES) ) { |
|
|
if (p->packet[0] < (0x39 + ALL_FRAMES) ) { |
|
|
/*uint8_t cmd = p->packet[0] - ALL_FRAMES + 1;
|
|
|
/*uint8_t cmd = p->packet[0] - ALL_FRAMES + 1;
|
|
@ -615,18 +689,17 @@ const byteAssign_t InfoAssignment[] = { |
|
|
mPayload[iv->id].complete = true; |
|
|
mPayload[iv->id].complete = true; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
//iv->setValue(iv->getPosByChFld(0, FLD_EVT, rec), rec, calcMiSts(iv));yield();
|
|
|
/*if (iv->alarmMesIndex < rec->record[iv->getPosByChFld(0, FLD_EVT, rec)]){
|
|
|
if (iv->alarmMesIndex < rec->record[iv->getPosByChFld(0, FLD_EVT, rec)]){ |
|
|
|
|
|
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); |
|
|
DPRINTHEAD(DBG_INFO, iv->id); |
|
|
DBGPRINTLN(F("alarm ID incremented to ") + String(iv->alarmMesIndex)); |
|
|
DBGPRINT_TXT(TXT_INCRALM); |
|
|
//iv->enqueCommand<InfoCommand>(AlarmData);
|
|
|
DBGPRINTLN(String(iv->alarmMesIndex)); |
|
|
} |
|
|
}*/ |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if ( mPayload[iv->id].complete || //4ch device
|
|
|
if ( mPayload[iv->id].complete || //4ch device
|
|
|
(iv->type != INV_TYPE_4CH //other devices
|
|
|
(iv->type != INV_TYPE_4CH //other devices
|
|
|
&& mPayload[iv->id].dataAB[CH0] |
|
|
&& mPayload[iv->id].dataAB[CH0] |
|
|
&& mPayload[iv->id].stsAB[CH0])) { |
|
|
&& mPayload[iv->id].stsAB[CH0])) { |
|
@ -652,8 +725,11 @@ const byteAssign_t InfoAssignment[] = { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void miComplete(Inverter<> *iv) { |
|
|
void miComplete(Inverter<> *iv) { |
|
|
|
|
|
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...
|
|
|
mPayload[iv->id].complete = true; // For 2 CH devices, this might be too short...
|
|
|
DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") got all msgs")); |
|
|
DPRINTHEAD(DBG_INFO, iv->id); |
|
|
|
|
|
DBGPRINTLN(F("got all msgs")); |
|
|
record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug); |
|
|
record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug); |
|
|
iv->setValue(iv->getPosByChFld(0, FLD_YD, rec), rec, calcYieldDayCh0(iv,0)); |
|
|
iv->setValue(iv->getPosByChFld(0, FLD_YD, rec), rec, calcYieldDayCh0(iv,0)); |
|
|
|
|
|
|
|
@ -677,6 +753,7 @@ const byteAssign_t InfoAssignment[] = { |
|
|
|
|
|
|
|
|
bool build(uint8_t id, bool *complete) { |
|
|
bool build(uint8_t id, bool *complete) { |
|
|
DPRINTLN(DBG_VERBOSE, F("build")); |
|
|
DPRINTLN(DBG_VERBOSE, F("build")); |
|
|
|
|
|
//DPRINTLN_TXT(DBG_VERBOSE, TXT_BUILD);
|
|
|
/*uint16_t crc = 0xffff, crcRcv = 0x0000;
|
|
|
/*uint16_t crc = 0xffff, crcRcv = 0x0000;
|
|
|
if (mPayload[id].maxPackId > MAX_PAYLOAD_ENTRIES) |
|
|
if (mPayload[id].maxPackId > MAX_PAYLOAD_ENTRIES) |
|
|
mPayload[id].maxPackId = MAX_PAYLOAD_ENTRIES; |
|
|
mPayload[id].maxPackId = MAX_PAYLOAD_ENTRIES; |
|
@ -706,14 +783,7 @@ const byteAssign_t InfoAssignment[] = { |
|
|
return true; |
|
|
return true; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* void miDPRINTHead(uint8_t lvl, uint8_t id) {
|
|
|
void reset(uint8_t id, bool clrSts = false) { |
|
|
DPRINT(lvl, F("(#")); |
|
|
|
|
|
DBGPRINT(String(id)); |
|
|
|
|
|
DBGPRINT(F(") ")); |
|
|
|
|
|
}*/ |
|
|
|
|
|
|
|
|
|
|
|
void reset(uint8_t id) { |
|
|
|
|
|
//DPRINTLN(DBG_INFO, F("resetPayload: id: ") + String(id));
|
|
|
|
|
|
DPRINTHEAD(DBG_INFO, id); |
|
|
DPRINTHEAD(DBG_INFO, id); |
|
|
DBGPRINTLN(F("resetPayload")); |
|
|
DBGPRINTLN(F("resetPayload")); |
|
|
memset(mPayload[id].len, 0, MAX_PAYLOAD_ENTRIES); |
|
|
memset(mPayload[id].len, 0, MAX_PAYLOAD_ENTRIES); |
|
@ -729,14 +799,17 @@ const byteAssign_t InfoAssignment[] = { |
|
|
mPayload[id].stsAB[CH1] = true; //required for 1CH and 2CH devices
|
|
|
mPayload[id].stsAB[CH1] = true; //required for 1CH and 2CH devices
|
|
|
mPayload[id].stsAB[CH2] = true; //only required for 2CH devices
|
|
|
mPayload[id].stsAB[CH2] = true; //only required for 2CH devices
|
|
|
mPayload[id].txCmd = 0; |
|
|
mPayload[id].txCmd = 0; |
|
|
mPayload[id].skipfirstrepeat = 0; |
|
|
//mPayload[id].skipfirstrepeat = 0;
|
|
|
mPayload[id].requested = false; |
|
|
mPayload[id].requested = false; |
|
|
mPayload[id].ts = *mTimestamp; |
|
|
mPayload[id].ts = *mTimestamp; |
|
|
mPayload[id].sts[0] = 0; |
|
|
mPayload[id].sts[0] = 0; |
|
|
mPayload[id].sts[CH1] = 0; |
|
|
if (clrSts) { // only clear channel states at startup
|
|
|
mPayload[id].sts[CH2] = 0; |
|
|
mPayload[id].sts[CH1] = 0; |
|
|
mPayload[id].sts[CH3] = 0; |
|
|
mPayload[id].sts[CH2] = 0; |
|
|
mPayload[id].sts[CH4] = 0; |
|
|
mPayload[id].sts[CH3] = 0; |
|
|
|
|
|
mPayload[id].sts[CH4] = 0; |
|
|
|
|
|
mPayload[id].sts[5] = 0; //remember last summarized state
|
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|