mirror of
https://github.com/lumapu/ahoy.git
synced 2025-07-25 20:27:18 +02:00
added MI additions / corrections from @rejoe2
This commit is contained in:
parent
96f181c662
commit
1b965d67a8
6 changed files with 141 additions and 27 deletions
|
@ -71,7 +71,8 @@ class Communication : public CommQueue<> {
|
|||
case States::CHECK_FRAMES: {
|
||||
if(!q->iv->radio->get()) { // radio buffer empty
|
||||
cmdDone();
|
||||
DPRINT(DBG_INFO, F("request timeout: "));
|
||||
DPRINT_IVID(DBG_INFO, q->iv->id);
|
||||
DBGPRINT(F("request timeout: "));
|
||||
DBGPRINT(String(millis() - mWaitTimeout + 500));
|
||||
DBGPRINTLN(F("ms"));
|
||||
|
||||
|
@ -90,11 +91,15 @@ class Communication : public CommQueue<> {
|
|||
|
||||
DPRINT_IVID(DBG_INFO, q->iv->id);
|
||||
DBGPRINT(F("RX "));
|
||||
if(p->millis < 100)
|
||||
DBGPRINT(F("0"));
|
||||
DBGPRINT(String(p->millis));
|
||||
DBGPRINT(F("ms "));
|
||||
DBGPRINT(String(p->len));
|
||||
if(IV_HM == q->iv->ivGen) {
|
||||
if((IV_HM == q->iv->ivGen) || (IV_MI == q->iv->ivGen)) {
|
||||
DBGPRINT(F(" CH"));
|
||||
if(3 == p->ch)
|
||||
DBGPRINT(F("0"));
|
||||
DBGPRINT(String(p->ch));
|
||||
}
|
||||
DBGPRINT(F(", "));
|
||||
|
@ -111,6 +116,8 @@ class Communication : public CommQueue<> {
|
|||
} else if (p->packet[0] == (TX_REQ_DEVCONTROL + ALL_FRAMES)) { // response from dev control command
|
||||
parseDevCtrl(p, q);
|
||||
cmdDone(true); // remove done request
|
||||
} else if(IV_MI == q->iv->ivGen) {
|
||||
parseMiFrame(p, q);
|
||||
}
|
||||
} else
|
||||
DPRINTLN(DBG_WARN, F("Inverter serial does not match"));
|
||||
|
@ -227,6 +234,74 @@ class Communication : public CommQueue<> {
|
|||
f->rssi = p->rssi;
|
||||
}
|
||||
|
||||
inline void parseMiFrame(packet_t *p, const queue_s *q) {
|
||||
if ((p->packet[0] == MI_REQ_CH1 + ALL_FRAMES)
|
||||
|| (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))) {
|
||||
// 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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
inline void miDataDecode(packet_t *p, const queue_s *q) {
|
||||
record_t<> *rec = q->iv->getRecordStruct(RealTimeRunData_Debug); // choose the parser
|
||||
//rec->ts = mPayload[iv->id].ts;
|
||||
//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 :
|
||||
CH4;
|
||||
// count in RF_communication_protocol.xlsx is with offset = -1
|
||||
q->iv->setValue(q->iv->getPosByChFld(datachan, FLD_UDC, rec), rec, (float)((p->packet[9] << 8) + p->packet[10])/10);
|
||||
|
||||
q->iv->setValue(q->iv->getPosByChFld(datachan, FLD_IDC, rec), rec, (float)((p->packet[11] << 8) + p->packet[12])/10);
|
||||
|
||||
q->iv->setValue(q->iv->getPosByChFld(0, FLD_UAC, rec), rec, (float)((p->packet[13] << 8) + p->packet[14])/10);
|
||||
|
||||
q->iv->setValue(q->iv->getPosByChFld(0, FLD_F, rec), rec, (float) ((p->packet[15] << 8) + p->packet[16])/100);
|
||||
q->iv->setValue(q->iv->getPosByChFld(datachan, FLD_PDC, rec), rec, (float)((p->packet[17] << 8) + p->packet[18])/10);
|
||||
|
||||
q->iv->setValue(q->iv->getPosByChFld(datachan, FLD_YD, rec), rec, (float)((p->packet[19] << 8) + p->packet[20])/1);
|
||||
|
||||
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 < 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) {
|
||||
STAT = (uint8_t)(p->packet[25] );
|
||||
FCNT = (uint8_t)(p->packet[26]);
|
||||
FCODE = (uint8_t)(p->packet[27]);
|
||||
}*/
|
||||
//miStsConsolidate(iv, 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;
|
||||
} else {
|
||||
//miComplete(iv);
|
||||
}
|
||||
} else if((p->packet[0] == (MI_REQ_CH1 + ALL_FRAMES)) && q->iv->type == INV_TYPE_2CH ) {
|
||||
addImportant(q->iv, MI_REQ_CH2);
|
||||
}
|
||||
}
|
||||
|
||||
inline void parseDevCtrl(packet_t *p, const queue_s *q) {
|
||||
if((p->packet[12] != ActivePowerContr) || (p->packet[13] != 0x00))
|
||||
return;
|
||||
|
|
|
@ -346,4 +346,8 @@ const devInfo_t devInfo[] = {
|
|||
{ 0x103331, 2250 }
|
||||
};
|
||||
|
||||
#define MI_REQ_CH1 0x09
|
||||
#define MI_REQ_CH2 0x11
|
||||
#define MI_REQ_4CH 0x36
|
||||
|
||||
#endif /*__HM_DEFINES_H__*/
|
||||
|
|
|
@ -182,6 +182,7 @@ class Inverter {
|
|||
}
|
||||
|
||||
void tickSend(std::function<void(uint8_t cmd, bool isDevControl)> cb) {
|
||||
if (IV_MI != ivGen) {
|
||||
if(mDevControlRequest) {
|
||||
cb(devControlCmd, true);
|
||||
mDevControlRequest = false;
|
||||
|
@ -195,6 +196,21 @@ class Inverter {
|
|||
cb(SystemConfigPara, false); // power limit info
|
||||
else
|
||||
cb(RealTimeRunData_Debug, false); // get live data
|
||||
} else {
|
||||
if(mDevControlRequest) {
|
||||
cb(devControlCmd, true);
|
||||
mDevControlRequest = false;
|
||||
} else if(0 == getFwVersion())
|
||||
cb(MI_REQ_CH1, false); // get firmware version
|
||||
//cb(InverterDevInform_All, false); // get firmware version
|
||||
else {
|
||||
record_t<> *rec = getRecordStruct(InverterDevInform_Simple);
|
||||
if (getChannelFieldValue(CH0, FLD_PART_NUM, rec) == 0)
|
||||
cb(InverterDevInform_All, 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*template <typename T>
|
||||
|
|
|
@ -117,24 +117,24 @@ class HmRadio : public Radio {
|
|||
mNrf24.setChannel(mRfChLst[mRxChIdx]);
|
||||
mNrf24.startListening();
|
||||
|
||||
uint32_t startMicros = micros();
|
||||
uint32_t startMicros = micros() + 5110;
|
||||
uint32_t loopMillis = millis() + 400;
|
||||
while (millis() < loopMillis) {
|
||||
while (micros()-startMicros < 5110) { // listen (4088us or?) 5110us to each channel
|
||||
while (micros() < startMicros) { // listen (4088us or?) 5110us to each channel
|
||||
if (mIrqRcvd) {
|
||||
mIrqRcvd = false;
|
||||
if (getReceived()) { // everything received
|
||||
|
||||
if (getReceived()) // everything received
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
yield();
|
||||
}
|
||||
// switch to next RX channel
|
||||
startMicros = micros();
|
||||
if(++mRxChIdx >= RF_CHANNELS)
|
||||
mRxChIdx = 0;
|
||||
mNrf24.setChannel(mRfChLst[mRxChIdx]);
|
||||
yield();
|
||||
startMicros = micros() + 5000;
|
||||
}
|
||||
// not finished but time is over
|
||||
return;
|
||||
|
@ -145,12 +145,13 @@ class HmRadio : public Radio {
|
|||
return mNrf24.isChipConnected();
|
||||
}
|
||||
|
||||
void sendControlPacket(Inverter<> *iv, uint8_t cmd, uint16_t *data, bool isRetransmit, bool isNoMI = true, uint16_t powerMax = 0) {
|
||||
DPRINT(DBG_INFO, F("sendControlPacket cmd: 0x"));
|
||||
void sendControlPacket(Inverter<> *iv, uint8_t cmd, uint16_t *data, bool isRetransmit) {
|
||||
DPRINT_IVID(DBG_INFO, iv->id);
|
||||
DBGPRINT(F("sendControlPacket cmd: 0x"));
|
||||
DBGHEXLN(cmd);
|
||||
initPacket(iv->radioId.u64, TX_REQ_DEVCONTROL, SINGLE_FRAME);
|
||||
uint8_t cnt = 10;
|
||||
if (isNoMI) {
|
||||
if (IV_MI != iv->ivGen) {
|
||||
mTxBuf[cnt++] = cmd; // cmd -> 0 on, 1 off, 2 restart, 11 active power, 12 reactive power, 13 power factor
|
||||
mTxBuf[cnt++] = 0x00;
|
||||
if(cmd >= ActivePowerContr && cmd <= PFSet) { // ActivePowerContr, ReactivePowerContr, PFSet
|
||||
|
@ -160,6 +161,7 @@ class HmRadio : public Radio {
|
|||
mTxBuf[cnt++] = ((data[1] ) ) & 0xff; // setting for persistens handling
|
||||
}
|
||||
} else { //MI 2nd gen. specific
|
||||
uint16_t powerMax = ((iv->powerLimit[1] == RelativNonPersistent) ? 0 : iv->getMaxPower());
|
||||
switch (cmd) {
|
||||
case Restart:
|
||||
case TurnOn:
|
||||
|
@ -225,7 +227,7 @@ class HmRadio : public Radio {
|
|||
}
|
||||
cnt++;
|
||||
}
|
||||
sendPacket(iv, cnt, isRetransmit, isNoMI);
|
||||
sendPacket(iv, cnt, isRetransmit, (IV_MI != iv->ivGen));
|
||||
}
|
||||
|
||||
uint8_t getDataRate(void) {
|
||||
|
@ -297,6 +299,10 @@ class HmRadio : public Radio {
|
|||
return iv->radioId.u64;
|
||||
}
|
||||
|
||||
uint8_t getIvGen(Inverter<> *iv) {
|
||||
return iv->ivGen;
|
||||
}
|
||||
|
||||
uint64_t DTU_RADIO_ID;
|
||||
uint8_t mRfChLst[RF_CHANNELS];
|
||||
uint8_t mTxChIdx;
|
||||
|
|
|
@ -21,7 +21,7 @@ class Inverter;
|
|||
// abstract radio interface
|
||||
class Radio {
|
||||
public:
|
||||
virtual void sendControlPacket(Inverter<> *iv, uint8_t cmd, uint16_t *data, bool isRetransmit, bool isNoMI = true, uint16_t powerMax = 0) = 0;
|
||||
virtual void sendControlPacket(Inverter<> *iv, uint8_t cmd, uint16_t *data, bool isRetransmit) = 0;
|
||||
virtual bool switchFrequency(Inverter<> *iv, uint32_t fromkHz, uint32_t tokHz) { return true; }
|
||||
virtual void loop(void) {};
|
||||
|
||||
|
@ -43,6 +43,14 @@ class Radio {
|
|||
}
|
||||
|
||||
void prepareDevInformCmd(Inverter<> *iv, 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.
|
||||
if(IV_MI == getIvGen(iv)) {
|
||||
DPRINT_IVID(DBG_INFO, getIvId(iv));
|
||||
DBGPRINT(F("legacy cmd 0x"));
|
||||
DBGHEXLN(cmd);
|
||||
sendCmdPacket(iv, cmd, cmd, false, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if(mSerialDebug) {
|
||||
DPRINT(DBG_DEBUG, F("prepareDevInformCmd 0x"));
|
||||
DPRINTLN(DBG_DEBUG,String(cmd, HEX));
|
||||
|
@ -63,6 +71,7 @@ class Radio {
|
|||
protected:
|
||||
virtual void sendPacket(Inverter<> *iv, uint8_t len, bool isRetransmit, bool appendCrc16=true) = 0;
|
||||
virtual uint64_t getIvId(Inverter<> *iv) = 0;
|
||||
virtual uint8_t getIvGen(Inverter<> *iv) = 0;
|
||||
|
||||
void initPacket(uint64_t ivId, uint8_t mid, uint8_t pid) {
|
||||
mTxBuf[0] = mid;
|
||||
|
|
|
@ -44,7 +44,7 @@ class CmtRadio : public Radio {
|
|||
return mCmtAvail;
|
||||
}
|
||||
|
||||
void sendControlPacket(Inverter<> *iv, uint8_t cmd, uint16_t *data, bool isRetransmit, bool isNoMI = true, uint16_t powerMax = 0) {
|
||||
void sendControlPacket(Inverter<> *iv, uint8_t cmd, uint16_t *data, bool isRetransmit) {
|
||||
DPRINT(DBG_INFO, F("sendControlPacket cmd: 0x"));
|
||||
DBGHEXLN(cmd);
|
||||
initPacket(iv->radioId.u64, TX_REQ_DEVCONTROL, SINGLE_FRAME);
|
||||
|
@ -101,6 +101,10 @@ class CmtRadio : public Radio {
|
|||
return iv->radioId.u64;
|
||||
}
|
||||
|
||||
uint8_t getIvGen(Inverter<> *iv) {
|
||||
return iv->ivGen;
|
||||
}
|
||||
|
||||
inline void reset(bool genDtuSn) {
|
||||
if(genDtuSn)
|
||||
generateDtuSn();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue