mirror of
https://github.com/lumapu/ahoy.git
synced 2025-05-25 23:06:11 +02:00
0.7.31
* fixed docu #1085 * changed active power limit MqTT messages to QOS2 #1072 * improved alarm messages, added alarm-id to log #1089 * trigger power limit read on next day (if inverter was offline meanwhile) * disabled improv implementation to check if it is related to 'Schwuppdizitaet' * changed live view to gray once inverter isn't available * added inverter status to API * changed sum of totals on WebGui depending on inverter status #1084 * merge maximum power (AC and DC) from PR #1080
This commit is contained in:
parent
995c7ea5fb
commit
55764102ce
20 changed files with 223 additions and 112 deletions
|
@ -168,7 +168,7 @@ This feature was removed. The persisten limit should not be modified cyclic by a
|
|||
|
||||
### Generic Information
|
||||
|
||||
The rest API works with *JSON* POST requests. All the following instructions must be sent to the `/api` endpoint of the AhoyDTU.
|
||||
The rest API works with *JSON* POST requests. All the following instructions must be sent to the `/api/ctrl` endpoint of the AhoyDTU.
|
||||
|
||||
👆 `<INVERTER_ID>` is the number of the specific inverter in the setup page.
|
||||
|
||||
|
|
|
@ -1,5 +1,16 @@
|
|||
# Development Changes
|
||||
|
||||
## 0.7.31 - 2023-08-13
|
||||
* fixed docu #1085
|
||||
* changed active power limit MqTT messages to QOS2 #1072
|
||||
* improved alarm messages, added alarm-id to log #1089
|
||||
* trigger power limit read on next day (if inverter was offline meanwhile)
|
||||
* disabled improv implementation to check if it is related to 'Schwuppdizitaet'
|
||||
* changed live view to gray once inverter isn't available
|
||||
* added inverter status to API
|
||||
* changed sum of totals on WebGui depending on inverter status #1084
|
||||
* merge maximum power (AC and DC) from PR #1080
|
||||
|
||||
## 0.7.30 - 2023-08-10
|
||||
* attempt to improve speed / repsonse times (Schwuppdizitaet) #1075
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ void app::setup() {
|
|||
mPubSerial.setup(mConfig, &mSys, &mTimestamp);
|
||||
|
||||
#if !defined(ETHERNET)
|
||||
mImprov.setup(this, mConfig->sys.deviceName, mVersion);
|
||||
//mImprov.setup(this, mConfig->sys.deviceName, mVersion);
|
||||
#endif
|
||||
|
||||
regularTickers();
|
||||
|
@ -248,7 +248,7 @@ void app::regularTickers(void) {
|
|||
everySec(std::bind(&DisplayType::tickerSecond, &mDisplay), "disp");
|
||||
every(std::bind(&PubSerialType::tick, &mPubSerial), mConfig->serial.interval, "uart");
|
||||
#if !defined(ETHERNET)
|
||||
everySec([this]() { mImprov.tickSerial(); }, "impro");
|
||||
//everySec([this]() { mImprov.tickSerial(); }, "impro");
|
||||
#endif
|
||||
// every([this]() { mPayload.simulation();}, 15, "simul");
|
||||
}
|
||||
|
|
|
@ -332,7 +332,7 @@ class app : public IApp, public ah::Scheduler {
|
|||
MiPayloadType mMiPayload;
|
||||
PubSerialType mPubSerial;
|
||||
#if !defined(ETHERNET)
|
||||
Improv mImprov;
|
||||
//Improv mImprov;
|
||||
#endif
|
||||
#ifdef ESP32
|
||||
CmtRadioType mCmtRadio;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
//-------------------------------------
|
||||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 7
|
||||
#define VERSION_PATCH 30
|
||||
#define VERSION_PATCH 31
|
||||
|
||||
//-------------------------------------
|
||||
typedef struct {
|
||||
|
|
|
@ -22,19 +22,19 @@ enum {FLD_UDC = 0, FLD_IDC, FLD_PDC, FLD_YD, FLD_YW, FLD_YT,
|
|||
FLD_IAC_1, FLD_IAC_2, FLD_IAC_3, FLD_PAC, FLD_F, FLD_T, FLD_PF, FLD_EFF,
|
||||
FLD_IRR, FLD_Q, FLD_EVT, FLD_FW_VERSION, FLD_FW_BUILD_YEAR,
|
||||
FLD_FW_BUILD_MONTH_DAY, FLD_FW_BUILD_HOUR_MINUTE, FLD_HW_ID,
|
||||
FLD_ACT_ACTIVE_PWR_LIMIT, /*FLD_ACT_REACTIVE_PWR_LIMIT, FLD_ACT_PF,*/ FLD_LAST_ALARM_CODE};
|
||||
FLD_ACT_ACTIVE_PWR_LIMIT, /*FLD_ACT_REACTIVE_PWR_LIMIT, FLD_ACT_PF,*/ FLD_LAST_ALARM_CODE, FLD_MP};
|
||||
|
||||
const char* const fields[] = {"U_DC", "I_DC", "P_DC", "YieldDay", "YieldWeek", "YieldTotal",
|
||||
"U_AC", "U_AC_1N", "U_AC_2N", "U_AC_3N", "UAC_12", "UAC_23", "UAC_31", "I_AC",
|
||||
"IAC_1", "I_AC_2", "I_AC_3", "P_AC", "F_AC", "Temp", "PF_AC", "Efficiency", "Irradiation","Q_AC",
|
||||
"ALARM_MES_ID","FWVersion","FWBuildYear","FWBuildMonthDay","FWBuildHourMinute","HWPartId",
|
||||
"active_PowerLimit", /*"reactivePowerLimit","Powerfactor",*/ "LastAlarmCode"};
|
||||
"active_PowerLimit", /*"reactivePowerLimit","Powerfactor",*/ "LastAlarmCode", "MaxPower"};
|
||||
const char* const notAvail = "n/a";
|
||||
|
||||
const uint8_t fieldUnits[] = {UNIT_V, UNIT_A, UNIT_W, UNIT_WH, UNIT_KWH, UNIT_KWH,
|
||||
UNIT_V, UNIT_V, UNIT_V, UNIT_V, UNIT_V, UNIT_V, UNIT_V, UNIT_A, UNIT_A, UNIT_A, UNIT_A,
|
||||
UNIT_W, UNIT_HZ, UNIT_C, UNIT_NONE, UNIT_PCT, UNIT_PCT, UNIT_VAR,
|
||||
UNIT_NONE, UNIT_NONE, UNIT_NONE, UNIT_NONE, UNIT_NONE, UNIT_NONE, UNIT_PCT, UNIT_NONE};
|
||||
UNIT_NONE, UNIT_NONE, UNIT_NONE, UNIT_NONE, UNIT_NONE, UNIT_NONE, UNIT_PCT, UNIT_NONE, UNIT_W};
|
||||
|
||||
// mqtt discovery device classes
|
||||
enum {DEVICE_CLS_NONE = 0, DEVICE_CLS_CURRENT, DEVICE_CLS_ENERGY, DEVICE_CLS_PWR, DEVICE_CLS_VOLTAGE, DEVICE_CLS_FREQ, DEVICE_CLS_TEMP};
|
||||
|
@ -65,7 +65,7 @@ const byteAssign_fieldDeviceClass deviceFieldAssignment[] = {
|
|||
#define DEVICE_CLS_ASSIGN_LIST_LEN (sizeof(deviceFieldAssignment) / sizeof(byteAssign_fieldDeviceClass))
|
||||
|
||||
// indices to calculation functions, defined in hmInverter.h
|
||||
enum {CALC_YT_CH0 = 0, CALC_YD_CH0, CALC_UDC_CH, CALC_PDC_CH0, CALC_EFF_CH0, CALC_IRR_CH};
|
||||
enum {CALC_YT_CH0 = 0, CALC_YD_CH0, CALC_UDC_CH, CALC_PDC_CH0, CALC_EFF_CH0, CALC_IRR_CH, CALC_MPAC_CH0, CALC_MPDC_CH};
|
||||
enum {CMD_CALC = 0xffff};
|
||||
|
||||
|
||||
|
@ -129,6 +129,7 @@ const byteAssign_t hm1chAssignment[] = {
|
|||
{ FLD_YD, UNIT_WH, CH1, 12, 2, 1 },
|
||||
{ FLD_YT, UNIT_KWH, CH1, 8, 4, 1000 },
|
||||
{ FLD_IRR, UNIT_PCT, CH1, CALC_IRR_CH, CH1, CMD_CALC },
|
||||
{ FLD_MP, UNIT_W, CH1, CALC_MPDC_CH, CH1, CMD_CALC },
|
||||
|
||||
{ FLD_UAC, UNIT_V, CH0, 14, 2, 10 },
|
||||
{ FLD_IAC, UNIT_A, CH0, 22, 2, 100 },
|
||||
|
@ -141,7 +142,8 @@ const byteAssign_t hm1chAssignment[] = {
|
|||
{ FLD_YD, UNIT_WH, CH0, CALC_YD_CH0, 0, CMD_CALC },
|
||||
{ FLD_YT, UNIT_KWH, CH0, CALC_YT_CH0, 0, CMD_CALC },
|
||||
{ FLD_PDC, UNIT_W, CH0, CALC_PDC_CH0, 0, CMD_CALC },
|
||||
{ FLD_EFF, UNIT_PCT, CH0, CALC_EFF_CH0, 0, CMD_CALC }
|
||||
{ FLD_EFF, UNIT_PCT, CH0, CALC_EFF_CH0, 0, CMD_CALC },
|
||||
{ FLD_MP, UNIT_W, CH0, CALC_MPAC_CH0, 0, CMD_CALC }
|
||||
};
|
||||
#define HM1CH_LIST_LEN (sizeof(hm1chAssignment) / sizeof(byteAssign_t))
|
||||
#define HM1CH_PAYLOAD_LEN 30
|
||||
|
@ -157,6 +159,7 @@ const byteAssign_t hm2chAssignment[] = {
|
|||
{ FLD_YD, UNIT_WH, CH1, 22, 2, 1 },
|
||||
{ FLD_YT, UNIT_KWH, CH1, 14, 4, 1000 },
|
||||
{ FLD_IRR, UNIT_PCT, CH1, CALC_IRR_CH, CH1, CMD_CALC },
|
||||
{ FLD_MP, UNIT_W, CH1, CALC_MPDC_CH, CH1, CMD_CALC },
|
||||
|
||||
{ FLD_UDC, UNIT_V, CH2, 8, 2, 10 },
|
||||
{ FLD_IDC, UNIT_A, CH2, 10, 2, 100 },
|
||||
|
@ -164,6 +167,7 @@ const byteAssign_t hm2chAssignment[] = {
|
|||
{ FLD_YD, UNIT_WH, CH2, 24, 2, 1 },
|
||||
{ FLD_YT, UNIT_KWH, CH2, 18, 4, 1000 },
|
||||
{ FLD_IRR, UNIT_PCT, CH2, CALC_IRR_CH, CH2, CMD_CALC },
|
||||
{ FLD_MP, UNIT_W, CH2, CALC_MPDC_CH, CH2, CMD_CALC },
|
||||
|
||||
{ FLD_UAC, UNIT_V, CH0, 26, 2, 10 },
|
||||
{ FLD_IAC, UNIT_A, CH0, 34, 2, 100 },
|
||||
|
@ -176,7 +180,8 @@ const byteAssign_t hm2chAssignment[] = {
|
|||
{ FLD_YD, UNIT_WH, CH0, CALC_YD_CH0, 0, CMD_CALC },
|
||||
{ FLD_YT, UNIT_KWH, CH0, CALC_YT_CH0, 0, CMD_CALC },
|
||||
{ FLD_PDC, UNIT_W, CH0, CALC_PDC_CH0, 0, CMD_CALC },
|
||||
{ FLD_EFF, UNIT_PCT, CH0, CALC_EFF_CH0, 0, CMD_CALC }
|
||||
{ FLD_EFF, UNIT_PCT, CH0, CALC_EFF_CH0, 0, CMD_CALC },
|
||||
{ FLD_MP, UNIT_W, CH0, CALC_MPAC_CH0, 0, CMD_CALC }
|
||||
|
||||
};
|
||||
#define HM2CH_LIST_LEN (sizeof(hm2chAssignment) / sizeof(byteAssign_t))
|
||||
|
@ -193,6 +198,7 @@ const byteAssign_t hm4chAssignment[] = {
|
|||
{ FLD_YD, UNIT_WH, CH1, 20, 2, 1 },
|
||||
{ FLD_YT, UNIT_KWH, CH1, 12, 4, 1000 },
|
||||
{ FLD_IRR, UNIT_PCT, CH1, CALC_IRR_CH, CH1, CMD_CALC },
|
||||
{ FLD_MP, UNIT_W, CH1, CALC_MPDC_CH, CH1, CMD_CALC },
|
||||
|
||||
{ FLD_UDC, UNIT_V, CH2, CALC_UDC_CH, CH1, CMD_CALC },
|
||||
{ FLD_IDC, UNIT_A, CH2, 6, 2, 100 },
|
||||
|
@ -200,6 +206,7 @@ const byteAssign_t hm4chAssignment[] = {
|
|||
{ FLD_YD, UNIT_WH, CH2, 22, 2, 1 },
|
||||
{ FLD_YT, UNIT_KWH, CH2, 16, 4, 1000 },
|
||||
{ FLD_IRR, UNIT_PCT, CH2, CALC_IRR_CH, CH2, CMD_CALC },
|
||||
{ FLD_MP, UNIT_W, CH2, CALC_MPDC_CH, CH2, CMD_CALC },
|
||||
|
||||
{ FLD_UDC, UNIT_V, CH3, 24, 2, 10 },
|
||||
{ FLD_IDC, UNIT_A, CH3, 26, 2, 100 },
|
||||
|
@ -207,6 +214,7 @@ const byteAssign_t hm4chAssignment[] = {
|
|||
{ FLD_YD, UNIT_WH, CH3, 42, 2, 1 },
|
||||
{ FLD_YT, UNIT_KWH, CH3, 34, 4, 1000 },
|
||||
{ FLD_IRR, UNIT_PCT, CH3, CALC_IRR_CH, CH3, CMD_CALC },
|
||||
{ FLD_MP, UNIT_W, CH3, CALC_MPDC_CH, CH3, CMD_CALC },
|
||||
|
||||
{ FLD_UDC, UNIT_V, CH4, CALC_UDC_CH, CH3, CMD_CALC },
|
||||
{ FLD_IDC, UNIT_A, CH4, 28, 2, 100 },
|
||||
|
@ -214,6 +222,7 @@ const byteAssign_t hm4chAssignment[] = {
|
|||
{ FLD_YD, UNIT_WH, CH4, 44, 2, 1 },
|
||||
{ FLD_YT, UNIT_KWH, CH4, 38, 4, 1000 },
|
||||
{ FLD_IRR, UNIT_PCT, CH4, CALC_IRR_CH, CH4, CMD_CALC },
|
||||
{ FLD_MP, UNIT_W, CH4, CALC_MPDC_CH, CH4, CMD_CALC },
|
||||
|
||||
{ FLD_UAC, UNIT_V, CH0, 46, 2, 10 },
|
||||
{ FLD_IAC, UNIT_A, CH0, 54, 2, 100 },
|
||||
|
@ -226,7 +235,8 @@ const byteAssign_t hm4chAssignment[] = {
|
|||
{ FLD_YD, UNIT_WH, CH0, CALC_YD_CH0, 0, CMD_CALC },
|
||||
{ FLD_YT, UNIT_KWH, CH0, CALC_YT_CH0, 0, CMD_CALC },
|
||||
{ FLD_PDC, UNIT_W, CH0, CALC_PDC_CH0, 0, CMD_CALC },
|
||||
{ FLD_EFF, UNIT_PCT, CH0, CALC_EFF_CH0, 0, CMD_CALC }
|
||||
{ FLD_EFF, UNIT_PCT, CH0, CALC_EFF_CH0, 0, CMD_CALC },
|
||||
{ FLD_MP, UNIT_W, CH0, CALC_MPAC_CH0, 0, CMD_CALC }
|
||||
};
|
||||
#define HM4CH_LIST_LEN (sizeof(hm4chAssignment) / sizeof(byteAssign_t))
|
||||
#define HM4CH_PAYLOAD_LEN 62
|
||||
|
|
|
@ -48,6 +48,12 @@ static T calcEffiencyCh0(Inverter<> *iv, uint8_t arg0);
|
|||
template<class T=float>
|
||||
static T calcIrradiation(Inverter<> *iv, uint8_t arg0);
|
||||
|
||||
template<class T=float>
|
||||
static T calcMaxPowerAcCh0(Inverter<> *iv, uint8_t arg0);
|
||||
|
||||
template<class T=float>
|
||||
static T calcMaxPowerDc(Inverter<> *iv, uint8_t arg0);
|
||||
|
||||
template<class T=float>
|
||||
using func_t = T (Inverter<> *, uint8_t);
|
||||
|
||||
|
@ -107,7 +113,9 @@ const calcFunc_t<T> calcFunctions[] = {
|
|||
{ CALC_UDC_CH, &calcUdcCh },
|
||||
{ CALC_PDC_CH0, &calcPowerDcCh0 },
|
||||
{ CALC_EFF_CH0, &calcEffiencyCh0 },
|
||||
{ CALC_IRR_CH, &calcIrradiation }
|
||||
{ CALC_IRR_CH, &calcIrradiation },
|
||||
{ CALC_MPAC_CH0, &calcMaxPowerAcCh0 },
|
||||
{ CALC_MPDC_CH, &calcMaxPowerDc }
|
||||
};
|
||||
|
||||
enum class InverterStatus : uint8_t {
|
||||
|
@ -314,8 +322,8 @@ class Inverter {
|
|||
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]){
|
||||
if (getPosByChFld(0, FLD_EVT, rec) == pos) {
|
||||
if (alarmMesIndex < rec->record[pos]) {
|
||||
alarmMesIndex = rec->record[pos];
|
||||
//enqueCommand<InfoCommand>(AlarmUpdate); // What is the function of AlarmUpdate?
|
||||
|
||||
|
@ -415,8 +423,10 @@ class Inverter {
|
|||
if(status < InverterStatus::PRODUCING)
|
||||
status = InverterStatus::STARTING;
|
||||
} else {
|
||||
if((*timestamp - recordMeas.ts) > INVERTER_OFF_THRES_SEC)
|
||||
if((*timestamp - recordMeas.ts) > INVERTER_OFF_THRES_SEC) {
|
||||
status = InverterStatus::OFF;
|
||||
actPowerLimit = 0xffff; // power limit will be read once inverter becomes available
|
||||
}
|
||||
else
|
||||
status = InverterStatus::WAS_ON;
|
||||
}
|
||||
|
@ -680,8 +690,7 @@ static T calcYieldTotalCh0(Inverter<> *iv, uint8_t arg0) {
|
|||
record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
||||
T yield = 0;
|
||||
for(uint8_t i = 1; i <= iv->channels; i++) {
|
||||
uint8_t pos = iv->getPosByChFld(i, FLD_YT, rec);
|
||||
yield += iv->getValue(pos, rec);
|
||||
yield += iv->getChannelFieldValue(i, FLD_YT, rec);
|
||||
}
|
||||
return yield;
|
||||
}
|
||||
|
@ -695,8 +704,7 @@ static T calcYieldDayCh0(Inverter<> *iv, uint8_t arg0) {
|
|||
record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
||||
T yield = 0;
|
||||
for(uint8_t i = 1; i <= iv->channels; i++) {
|
||||
uint8_t pos = iv->getPosByChFld(i, FLD_YD, rec);
|
||||
yield += iv->getValue(pos, rec);
|
||||
yield += iv->getChannelFieldValue(i, FLD_YD, rec);
|
||||
}
|
||||
return yield;
|
||||
}
|
||||
|
@ -724,8 +732,7 @@ static T calcPowerDcCh0(Inverter<> *iv, uint8_t arg0) {
|
|||
record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
||||
T dcPower = 0;
|
||||
for(uint8_t i = 1; i <= iv->channels; i++) {
|
||||
uint8_t pos = iv->getPosByChFld(i, FLD_PDC, rec);
|
||||
dcPower += iv->getValue(pos, rec);
|
||||
dcPower += iv->getChannelFieldValue(i, FLD_PDC, rec);
|
||||
}
|
||||
return dcPower;
|
||||
}
|
||||
|
@ -737,12 +744,10 @@ static T calcEffiencyCh0(Inverter<> *iv, uint8_t arg0) {
|
|||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:calcEfficiencyCh0"));
|
||||
if(NULL != iv) {
|
||||
record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
||||
uint8_t pos = iv->getPosByChFld(CH0, FLD_PAC, rec);
|
||||
T acPower = iv->getValue(pos, rec);
|
||||
T acPower = iv->getChannelFieldValue(CH0, FLD_PAC, rec);
|
||||
T dcPower = 0;
|
||||
for(uint8_t i = 1; i <= iv->channels; i++) {
|
||||
pos = iv->getPosByChFld(i, FLD_PDC, rec);
|
||||
dcPower += iv->getValue(pos, rec);
|
||||
dcPower += iv->getChannelFieldValue(i, FLD_PDC, rec);
|
||||
}
|
||||
if(dcPower > 0)
|
||||
return acPower / dcPower * 100.0f;
|
||||
|
@ -756,11 +761,49 @@ static T calcIrradiation(Inverter<> *iv, uint8_t arg0) {
|
|||
// arg0 = channel
|
||||
if(NULL != iv) {
|
||||
record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
||||
uint8_t pos = iv->getPosByChFld(arg0, FLD_PDC, rec);
|
||||
if(iv->config->chMaxPwr[arg0-1] > 0)
|
||||
return iv->getValue(pos, rec) / iv->config->chMaxPwr[arg0-1] * 100.0f;
|
||||
return iv->getChannelFieldValue(arg0, FLD_PDC, rec) / iv->config->chMaxPwr[arg0-1] * 100.0f;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
template<class T=float>
|
||||
static T calcMaxPowerAcCh0(Inverter<> *iv, uint8_t arg0) {
|
||||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:calcMaxPowerAcCh0"));
|
||||
T acMaxPower = 0.0;
|
||||
if(NULL != iv) {
|
||||
record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
||||
T acPower = iv->getChannelFieldValue(arg0, FLD_PAC, rec);
|
||||
|
||||
for(uint8_t i = 0; i < rec->length; i++) {
|
||||
if((FLD_MP == rec->assign[i].fieldId) && (0 == rec->assign[i].ch)) {
|
||||
acMaxPower = iv->getValue(i, rec);
|
||||
}
|
||||
}
|
||||
if(acPower > acMaxPower)
|
||||
return acPower;
|
||||
}
|
||||
return acMaxPower;
|
||||
}
|
||||
|
||||
template<class T=float>
|
||||
static T calcMaxPowerDc(Inverter<> *iv, uint8_t arg0) {
|
||||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:calcMaxPowerDc"));
|
||||
// arg0 = channel
|
||||
T dcMaxPower = 0.0;
|
||||
if(NULL != iv) {
|
||||
record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
||||
T dcPower = iv->getChannelFieldValue(arg0, FLD_PDC, rec);
|
||||
|
||||
for(uint8_t i = 0; i < rec->length; i++) {
|
||||
if((FLD_MP == rec->assign[i].fieldId) && (arg0 == rec->assign[i].ch)) {
|
||||
dcMaxPower = iv->getValue(i, rec);
|
||||
}
|
||||
}
|
||||
if(dcPower > dcMaxPower)
|
||||
return dcPower;
|
||||
}
|
||||
return dcMaxPower;
|
||||
}
|
||||
|
||||
#endif /*__HM_INVERTER_H__*/
|
||||
|
|
|
@ -326,7 +326,6 @@ class HmPayload {
|
|||
|
||||
if(AlarmData == mPayload[iv->id].txCmd) {
|
||||
uint8_t i = 0;
|
||||
uint32_t start, end;
|
||||
while(1) {
|
||||
if(0 == iv->parseAlarmLog(i++, payload, payloadLen))
|
||||
break;
|
||||
|
|
|
@ -217,7 +217,7 @@ class HmRadio {
|
|||
mTxBuf[10] = cmd; // cid
|
||||
mTxBuf[11] = 0x00;
|
||||
CP_U32_LittleEndian(&mTxBuf[12], ts);
|
||||
if (cmd == RealTimeRunData_Debug || cmd == AlarmData ) {
|
||||
if (cmd == AlarmData ) { //cmd == RealTimeRunData_Debug ||
|
||||
mTxBuf[18] = (alarmMesId >> 8) & 0xff;
|
||||
mTxBuf[19] = (alarmMesId ) & 0xff;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ const byteAssign_t hms1chAssignment[] = {
|
|||
{ FLD_YT, UNIT_KWH, CH1, 8, 4, 1000 },
|
||||
{ FLD_YD, UNIT_WH, CH1, 12, 2, 1 },
|
||||
{ FLD_IRR, UNIT_PCT, CH1, CALC_IRR_CH, CH1, CMD_CALC },
|
||||
{ FLD_MP, UNIT_W, CH1, CALC_MPDC_CH, CH1, CMD_CALC },
|
||||
|
||||
{ FLD_UAC, UNIT_V, CH0, 14, 2, 10 },
|
||||
{ FLD_F, UNIT_HZ, CH0, 16, 2, 100 },
|
||||
|
@ -31,7 +32,8 @@ const byteAssign_t hms1chAssignment[] = {
|
|||
{ FLD_YD, UNIT_WH, CH0, CALC_YD_CH0, 0, CMD_CALC },
|
||||
{ FLD_YT, UNIT_KWH, CH0, CALC_YT_CH0, 0, CMD_CALC },
|
||||
{ FLD_PDC, UNIT_W, CH0, CALC_PDC_CH0, 0, CMD_CALC },
|
||||
{ FLD_EFF, UNIT_PCT, CH0, CALC_EFF_CH0, 0, CMD_CALC }
|
||||
{ FLD_EFF, UNIT_PCT, CH0, CALC_EFF_CH0, 0, CMD_CALC },
|
||||
{ FLD_MP, UNIT_W, CH0, CALC_MPAC_CH0, 0, CMD_CALC }
|
||||
};
|
||||
#define HMS1CH_LIST_LEN (sizeof(hms1chAssignment) / sizeof(byteAssign_t))
|
||||
#define HMS1CH_PAYLOAD_LEN 30
|
||||
|
@ -46,6 +48,7 @@ const byteAssign_t hms2chAssignment[] = {
|
|||
{ FLD_YT, UNIT_KWH, CH1, 14, 4, 1000 },
|
||||
{ FLD_YD, UNIT_WH, CH1, 22, 2, 1 },
|
||||
{ FLD_IRR, UNIT_PCT, CH1, CALC_IRR_CH, CH1, CMD_CALC },
|
||||
{ FLD_MP, UNIT_W, CH1, CALC_MPDC_CH, CH1, CMD_CALC },
|
||||
|
||||
{ FLD_UDC, UNIT_V, CH2, 4, 2, 10 },
|
||||
{ FLD_IDC, UNIT_A, CH2, 8, 2, 100 },
|
||||
|
@ -53,6 +56,7 @@ const byteAssign_t hms2chAssignment[] = {
|
|||
{ FLD_YT, UNIT_KWH, CH2, 18, 4, 1000 },
|
||||
{ FLD_YD, UNIT_WH, CH2, 24, 2, 1 },
|
||||
{ FLD_IRR, UNIT_PCT, CH2, CALC_IRR_CH, CH2, CMD_CALC },
|
||||
{ FLD_MP, UNIT_W, CH2, CALC_MPDC_CH, CH2, CMD_CALC },
|
||||
|
||||
{ FLD_UAC, UNIT_V, CH0, 26, 2, 10 },
|
||||
{ FLD_F, UNIT_HZ, CH0, 28, 2, 100 },
|
||||
|
@ -65,7 +69,8 @@ const byteAssign_t hms2chAssignment[] = {
|
|||
{ FLD_YD, UNIT_WH, CH0, CALC_YD_CH0, 0, CMD_CALC },
|
||||
{ FLD_YT, UNIT_KWH, CH0, CALC_YT_CH0, 0, CMD_CALC },
|
||||
{ FLD_PDC, UNIT_W, CH0, CALC_PDC_CH0, 0, CMD_CALC },
|
||||
{ FLD_EFF, UNIT_PCT, CH0, CALC_EFF_CH0, 0, CMD_CALC }
|
||||
{ FLD_EFF, UNIT_PCT, CH0, CALC_EFF_CH0, 0, CMD_CALC },
|
||||
{ FLD_MP, UNIT_W, CH0, CALC_MPAC_CH0, 0, CMD_CALC }
|
||||
};
|
||||
#define HMS2CH_LIST_LEN (sizeof(hms2chAssignment) / sizeof(byteAssign_t))
|
||||
#define HMS2CH_PAYLOAD_LEN 42
|
||||
|
@ -80,6 +85,7 @@ const byteAssign_t hms4chAssignment[] = {
|
|||
{ FLD_YT, UNIT_KWH, CH1, 14, 4, 1000 },
|
||||
{ FLD_YD, UNIT_WH, CH1, 22, 2, 1 },
|
||||
{ FLD_IRR, UNIT_PCT, CH1, CALC_IRR_CH, CH1, CMD_CALC },
|
||||
{ FLD_MP, UNIT_W, CH1, CALC_MPDC_CH, CH1, CMD_CALC },
|
||||
|
||||
{ FLD_UDC, UNIT_V, CH2, 4, 2, 10 },
|
||||
{ FLD_IDC, UNIT_A, CH2, 8, 2, 100 },
|
||||
|
@ -87,6 +93,7 @@ const byteAssign_t hms4chAssignment[] = {
|
|||
{ FLD_YT, UNIT_KWH, CH2, 18, 4, 1000 },
|
||||
{ FLD_YD, UNIT_WH, CH2, 24, 2, 1 },
|
||||
{ FLD_IRR, UNIT_PCT, CH2, CALC_IRR_CH, CH2, CMD_CALC },
|
||||
{ FLD_MP, UNIT_W, CH2, CALC_MPDC_CH, CH2, CMD_CALC },
|
||||
|
||||
{ FLD_UDC, UNIT_V, CH3, 26, 2, 10 },
|
||||
{ FLD_IDC, UNIT_A, CH3, 30, 2, 100 },
|
||||
|
@ -94,6 +101,7 @@ const byteAssign_t hms4chAssignment[] = {
|
|||
{ FLD_YT, UNIT_KWH, CH3, 38, 4, 1000 },
|
||||
{ FLD_YD, UNIT_WH, CH3, 46, 2, 1 },
|
||||
{ FLD_IRR, UNIT_PCT, CH3, CALC_IRR_CH, CH3, CMD_CALC },
|
||||
{ FLD_MP, UNIT_W, CH3, CALC_MPDC_CH, CH3, CMD_CALC },
|
||||
|
||||
{ FLD_UDC, UNIT_V, CH4, 28, 2, 10 },
|
||||
{ FLD_IDC, UNIT_A, CH4, 32, 2, 100 },
|
||||
|
@ -101,6 +109,7 @@ const byteAssign_t hms4chAssignment[] = {
|
|||
{ FLD_YT, UNIT_KWH, CH4, 42, 4, 1000 },
|
||||
{ FLD_YD, UNIT_WH, CH4, 48, 2, 1 },
|
||||
{ FLD_IRR, UNIT_PCT, CH4, CALC_IRR_CH, CH4, CMD_CALC },
|
||||
{ FLD_MP, UNIT_W, CH4, CALC_MPDC_CH, CH4, CMD_CALC },
|
||||
|
||||
{ FLD_UAC, UNIT_V, CH0, 50, 2, 10 },
|
||||
{ FLD_F, UNIT_HZ, CH0, 52, 2, 100 },
|
||||
|
@ -113,7 +122,8 @@ const byteAssign_t hms4chAssignment[] = {
|
|||
{ FLD_YD, UNIT_WH, CH0, CALC_YD_CH0, 0, CMD_CALC },
|
||||
{ FLD_YT, UNIT_KWH, CH0, CALC_YT_CH0, 0, CMD_CALC },
|
||||
{ FLD_PDC, UNIT_W, CH0, CALC_PDC_CH0, 0, CMD_CALC },
|
||||
{ FLD_EFF, UNIT_PCT, CH0, CALC_EFF_CH0, 0, CMD_CALC }
|
||||
{ FLD_EFF, UNIT_PCT, CH0, CALC_EFF_CH0, 0, CMD_CALC },
|
||||
{ FLD_MP, UNIT_W, CH0, CALC_MPAC_CH0, 0, CMD_CALC }
|
||||
};
|
||||
#define HMS4CH_LIST_LEN (sizeof(hms4chAssignment) / sizeof(byteAssign_t))
|
||||
#define HMS4CH_PAYLOAD_LEN 66
|
||||
|
@ -128,6 +138,7 @@ const byteAssign_t hmt6chAssignment[] = {
|
|||
{ FLD_YT, UNIT_KWH, CH1, 12, 4, 1000 },
|
||||
{ FLD_YD, UNIT_WH, CH1, 20, 2, 1 },
|
||||
{ FLD_IRR, UNIT_PCT, CH1, CALC_IRR_CH, CH1, CMD_CALC },
|
||||
{ FLD_MP, UNIT_W, CH1, CALC_MPDC_CH, CH1, CMD_CALC },
|
||||
|
||||
{ FLD_UDC, UNIT_V, CH2, CALC_UDC_CH, CH1, CMD_CALC },
|
||||
{ FLD_IDC, UNIT_A, CH2, 6, 2, 100 },
|
||||
|
@ -135,6 +146,7 @@ const byteAssign_t hmt6chAssignment[] = {
|
|||
{ FLD_YT, UNIT_KWH, CH2, 16, 4, 1000 },
|
||||
{ FLD_YD, UNIT_WH, CH2, 22, 2, 1 },
|
||||
{ FLD_IRR, UNIT_PCT, CH2, CALC_IRR_CH, CH2, CMD_CALC },
|
||||
{ FLD_MP, UNIT_W, CH2, CALC_MPDC_CH, CH2, CMD_CALC },
|
||||
|
||||
{ FLD_UDC, UNIT_V, CH3, 24, 2, 10 },
|
||||
{ FLD_IDC, UNIT_A, CH3, 26, 2, 100 },
|
||||
|
@ -142,6 +154,7 @@ const byteAssign_t hmt6chAssignment[] = {
|
|||
{ FLD_YT, UNIT_KWH, CH3, 34, 4, 1000 },
|
||||
{ FLD_YD, UNIT_WH, CH3, 42, 2, 1 },
|
||||
{ FLD_IRR, UNIT_PCT, CH3, CALC_IRR_CH, CH3, CMD_CALC },
|
||||
{ FLD_MP, UNIT_W, CH3, CALC_MPDC_CH, CH3, CMD_CALC },
|
||||
|
||||
{ FLD_UDC, UNIT_V, CH4, CALC_UDC_CH, CH3, CMD_CALC },
|
||||
{ FLD_IDC, UNIT_A, CH4, 28, 2, 100 },
|
||||
|
@ -149,6 +162,7 @@ const byteAssign_t hmt6chAssignment[] = {
|
|||
{ FLD_YT, UNIT_KWH, CH4, 38, 4, 1000 },
|
||||
{ FLD_YD, UNIT_WH, CH4, 44, 2, 1 },
|
||||
{ FLD_IRR, UNIT_PCT, CH4, CALC_IRR_CH, CH4, CMD_CALC },
|
||||
{ FLD_MP, UNIT_W, CH4, CALC_MPDC_CH, CH4, CMD_CALC },
|
||||
|
||||
{ FLD_UDC, UNIT_V, CH5, 46, 2, 10 },
|
||||
{ FLD_IDC, UNIT_A, CH5, 48, 2, 100 },
|
||||
|
@ -156,6 +170,7 @@ const byteAssign_t hmt6chAssignment[] = {
|
|||
{ FLD_YT, UNIT_KWH, CH5, 56, 4, 1000 },
|
||||
{ FLD_YD, UNIT_WH, CH5, 64, 2, 1 },
|
||||
{ FLD_IRR, UNIT_PCT, CH5, CALC_IRR_CH, CH5, CMD_CALC },
|
||||
{ FLD_MP, UNIT_W, CH5, CALC_MPDC_CH, CH5, CMD_CALC },
|
||||
|
||||
{ FLD_UDC, UNIT_V, CH6, CALC_UDC_CH, CH5, CMD_CALC },
|
||||
{ FLD_IDC, UNIT_A, CH6, 50, 2, 100 },
|
||||
|
@ -163,6 +178,7 @@ const byteAssign_t hmt6chAssignment[] = {
|
|||
{ FLD_YT, UNIT_KWH, CH6, 60, 4, 1000 },
|
||||
{ FLD_YD, UNIT_WH, CH6, 66, 2, 1 },
|
||||
{ FLD_IRR, UNIT_PCT, CH6, CALC_IRR_CH, CH6, CMD_CALC },
|
||||
{ FLD_MP, UNIT_W, CH6, CALC_MPDC_CH, CH6, CMD_CALC },
|
||||
|
||||
{ FLD_UAC_1N, UNIT_V, CH0, 68, 2, 10 },
|
||||
{ FLD_UAC_2N, UNIT_V, CH0, 70, 2, 10 },
|
||||
|
@ -182,7 +198,8 @@ const byteAssign_t hmt6chAssignment[] = {
|
|||
{ FLD_YD, UNIT_WH, CH0, CALC_YD_CH0, 0, CMD_CALC },
|
||||
{ FLD_YT, UNIT_KWH, CH0, CALC_YT_CH0, 0, CMD_CALC },
|
||||
{ FLD_PDC, UNIT_W, CH0, CALC_PDC_CH0, 0, CMD_CALC },
|
||||
{ FLD_EFF, UNIT_PCT, CH0, CALC_EFF_CH0, 0, CMD_CALC }
|
||||
{ FLD_EFF, UNIT_PCT, CH0, CALC_EFF_CH0, 0, CMD_CALC },
|
||||
{ FLD_MP, UNIT_W, CH0, CALC_MPAC_CH0, 0, CMD_CALC }
|
||||
};
|
||||
#define HMT6CH_LIST_LEN (sizeof(hmt6chAssignment) / sizeof(byteAssign_t))
|
||||
#define HMT6CH_PAYLOAD_LEN 98
|
||||
|
|
|
@ -98,10 +98,10 @@ class CmtRadio {
|
|||
initPacket(ivId, reqfld, ALL_FRAMES);
|
||||
mTxBuf[10] = cmd;
|
||||
CP_U32_LittleEndian(&mTxBuf[12], ts);
|
||||
/*if (cmd == RealTimeRunData_Debug || cmd == AlarmData ) {
|
||||
if (cmd == AlarmData ) { //cmd == RealTimeRunData_Debug ||
|
||||
mTxBuf[18] = (alarmMesId >> 8) & 0xff;
|
||||
mTxBuf[19] = (alarmMesId ) & 0xff;
|
||||
}*/
|
||||
}
|
||||
sendPacket(24, isRetransmit);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,8 +24,6 @@
|
|||
#include "pubMqttDefs.h"
|
||||
#include "pubMqttIvData.h"
|
||||
|
||||
#define QOS_0 0
|
||||
|
||||
typedef std::function<void(JsonObject)> subscriptionCb;
|
||||
|
||||
typedef struct {
|
||||
|
@ -60,8 +58,8 @@ class PubMqtt {
|
|||
mIntervalTimeout = 1;
|
||||
|
||||
mSendIvData.setup(sys, utcTs, &mSendList);
|
||||
mSendIvData.setPublishFunc([this](const char *subTopic, const char *payload, bool retained) {
|
||||
publish(subTopic, payload, retained);
|
||||
mSendIvData.setPublishFunc([this](const char *subTopic, const char *payload, bool retained, uint8_t qos) {
|
||||
publish(subTopic, payload, retained, true, qos);
|
||||
});
|
||||
mDiscovery.running = false;
|
||||
|
||||
|
@ -177,7 +175,7 @@ class PubMqtt {
|
|||
mSendAlarm[iv->id] = true;
|
||||
}
|
||||
|
||||
void publish(const char *subTopic, const char *payload, bool retained = false, bool addTopic = true) {
|
||||
void publish(const char *subTopic, const char *payload, bool retained = false, bool addTopic = true, uint8_t qos = QOS_0) {
|
||||
if(!mClient.connected())
|
||||
return;
|
||||
|
||||
|
@ -186,15 +184,15 @@ class PubMqtt {
|
|||
else
|
||||
snprintf(mTopic, MQTT_TOPIC_LEN + 32 + MAX_NAME_LENGTH + 1, "%s", subTopic);
|
||||
|
||||
mClient.publish(mTopic, QOS_0, retained, payload);
|
||||
mClient.publish(mTopic, qos, retained, payload);
|
||||
yield();
|
||||
mTxCnt++;
|
||||
}
|
||||
|
||||
void subscribe(const char *subTopic) {
|
||||
void subscribe(const char *subTopic, uint8_t qos = QOS_0) {
|
||||
char topic[MQTT_TOPIC_LEN + 20];
|
||||
snprintf(topic, (MQTT_TOPIC_LEN + 20), "%s/%s", mCfgMqtt->topic, subTopic);
|
||||
mClient.subscribe(topic, QOS_0);
|
||||
mClient.subscribe(topic, qos);
|
||||
}
|
||||
|
||||
void setSubscriptionCb(subscriptionCb cb) {
|
||||
|
@ -224,7 +222,7 @@ class PubMqtt {
|
|||
void setPowerLimitAck(Inverter<> *iv) {
|
||||
if (NULL != iv) {
|
||||
snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "%s/%s", iv->config->name, subtopics[MQTT_ACK_PWR_LMT]);
|
||||
publish(mSubTopic, "true", true);
|
||||
publish(mSubTopic, "true", true, true, QOS_2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -244,7 +242,7 @@ class PubMqtt {
|
|||
|
||||
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) {
|
||||
snprintf(mVal, 20, "ctrl/limit/%d", i);
|
||||
subscribe(mVal);
|
||||
subscribe(mVal, QOS_2);
|
||||
snprintf(mVal, 20, "ctrl/restart/%d", i);
|
||||
subscribe(mVal);
|
||||
snprintf(mVal, 20, "ctrl/power/%d", i);
|
||||
|
@ -525,7 +523,7 @@ class PubMqtt {
|
|||
publish(mSubTopic, mVal, true);
|
||||
|
||||
snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "%s/alarm/%d/str", iv->config->name, j);
|
||||
snprintf(mVal, 40, "%s", iv->getAlarmStr(iv->lastAlarm[j].code));
|
||||
snprintf(mVal, 40, "%s", iv->getAlarmStr(iv->lastAlarm[j].code).c_str());
|
||||
publish(mSubTopic, mVal, true);
|
||||
|
||||
snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "%s/alarm/%d/start", iv->config->name, j);
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#include <Arduino.h>
|
||||
|
||||
enum { QOS_0 = 0, QOS_1, QOS_2 };
|
||||
|
||||
enum {
|
||||
STR_TRUE,
|
||||
STR_FALSE
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include "../hm/hmSystem.h"
|
||||
#include "pubMqttDefs.h"
|
||||
|
||||
typedef std::function<void(const char *subTopic, const char *payload, bool retained)> pubMqttPublisherType;
|
||||
typedef std::function<void(const char *subTopic, const char *payload, bool retained, uint8_t qos)> pubMqttPublisherType;
|
||||
|
||||
struct sendListCmdIv {
|
||||
uint8_t cmd;
|
||||
|
@ -104,7 +104,7 @@ class PubMqttIvData {
|
|||
record_t<> *rec = mIv->getRecordStruct(mCmd);
|
||||
snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "%s/last_success", mIv->config->name);
|
||||
snprintf(mVal, 40, "%d", mIv->getLastTs(rec));
|
||||
mPublish(mSubTopic, mVal, true);
|
||||
mPublish(mSubTopic, mVal, true, QOS_0);
|
||||
|
||||
mIv->isProducing(); // recalculate status
|
||||
mState = SEND_DATA;
|
||||
|
@ -160,10 +160,14 @@ class PubMqttIvData {
|
|||
} else
|
||||
mIvLastRTRpub[mIv->id] = lastTs;
|
||||
|
||||
uint8_t qos = QOS_0;
|
||||
if(FLD_ACT_ACTIVE_PWR_LIMIT == rec->assign[mPos].fieldId)
|
||||
qos = QOS_2;
|
||||
|
||||
if((mIvSend == mIv) || (NULL == mIvSend)) { // send only updated values, or all if the inverter is NULL
|
||||
snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "%s/ch%d/%s", mIv->config->name, rec->assign[mPos].ch, fields[rec->assign[mPos].fieldId]);
|
||||
snprintf(mVal, 40, "%g", ah::round3(mIv->getValue(mPos, rec)));
|
||||
mPublish(mSubTopic, mVal, retained);
|
||||
mPublish(mSubTopic, mVal, retained, qos);
|
||||
}
|
||||
mPos++;
|
||||
} else
|
||||
|
@ -204,7 +208,7 @@ class PubMqttIvData {
|
|||
}
|
||||
snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "total/%s", fields[fieldId]);
|
||||
snprintf(mVal, 40, "%g", ah::round3(mTotal[mPos]));
|
||||
mPublish(mSubTopic, mVal, retained);
|
||||
mPublish(mSubTopic, mVal, retained, QOS_0);
|
||||
mPos++;
|
||||
} else {
|
||||
mSendList->pop();
|
||||
|
|
|
@ -27,9 +27,9 @@
|
|||
#define F(sl) (sl)
|
||||
#endif
|
||||
|
||||
const uint8_t acList[] = {FLD_UAC, FLD_IAC, FLD_PAC, FLD_F, FLD_PF, FLD_T, FLD_YT, FLD_YD, FLD_PDC, FLD_EFF, FLD_Q};
|
||||
const uint8_t acListHmt[] = {FLD_UAC_1N, FLD_IAC_1, FLD_PAC, FLD_F, FLD_PF, FLD_T, FLD_YT, FLD_YD, FLD_PDC, FLD_EFF, FLD_Q};
|
||||
const uint8_t dcList[] = {FLD_UDC, FLD_IDC, FLD_PDC, FLD_YD, FLD_YT, FLD_IRR};
|
||||
const uint8_t acList[] = {FLD_UAC, FLD_IAC, FLD_PAC, FLD_F, FLD_PF, FLD_T, FLD_YT, FLD_YD, FLD_PDC, FLD_EFF, FLD_Q, FLD_MP};
|
||||
const uint8_t acListHmt[] = {FLD_UAC_1N, FLD_IAC_1, FLD_PAC, FLD_F, FLD_PF, FLD_T, FLD_YT, FLD_YD, FLD_PDC, FLD_EFF, FLD_Q, FLD_MP};
|
||||
const uint8_t dcList[] = {FLD_UDC, FLD_IDC, FLD_PDC, FLD_YD, FLD_YT, FLD_IRR, FLD_MP};
|
||||
|
||||
template<class HMSYSTEM, class HMRADIO>
|
||||
class RestApi {
|
||||
|
@ -365,6 +365,7 @@ class RestApi {
|
|||
obj[F("power_limit_ack")] = iv->powerLimitAck;
|
||||
obj[F("ts_last_success")] = rec->ts;
|
||||
obj[F("generation")] = iv->ivGen;
|
||||
obj[F("status")] = (uint8_t)iv->status;
|
||||
|
||||
JsonArray ch = obj.createNestedArray("ch");
|
||||
|
||||
|
@ -403,7 +404,10 @@ class RestApi {
|
|||
return;
|
||||
}
|
||||
|
||||
record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
||||
|
||||
obj["cnt"] = iv->alarmCnt;
|
||||
obj["last_id"] = iv->getChannelFieldValue(CH0, FLD_EVT, rec);
|
||||
|
||||
JsonArray alarm = obj.createNestedArray(F("alarm"));
|
||||
for(uint8_t i = 0; i < 10; i++) {
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
--total-bg: #b06e04;
|
||||
--iv-head-title: #1c6800;
|
||||
--iv-head-bg: #32b004;
|
||||
--iv-dis-title: #888;
|
||||
--iv-dis: #999;
|
||||
--ch-head-title: #003c80;
|
||||
--ch-head-bg: #006ec0;
|
||||
--ts-head: #333;
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
--total-bg: #666622;
|
||||
--iv-head-title: #115511;
|
||||
--iv-head-bg: #226622;
|
||||
--iv-dis-title: #333;
|
||||
--iv-dis: #444;
|
||||
--ch-head-title: #112255;
|
||||
--ch-head-bg: #223366;
|
||||
--ts-head: #333;
|
||||
|
|
|
@ -217,6 +217,7 @@
|
|||
|
||||
function parseRelease(obj) {
|
||||
release = obj["name"].substring(6);
|
||||
getAjax("/api/index", parse);
|
||||
}
|
||||
|
||||
getAjax("/api/index", parse);
|
||||
|
|
|
@ -141,6 +141,16 @@ span.seperator {
|
|||
color: var(--fg2);
|
||||
}
|
||||
|
||||
.iv-h-dis {
|
||||
background-color: var(--iv-dis-title);
|
||||
color: var(--fg2);
|
||||
}
|
||||
|
||||
.iv-bg-dis {
|
||||
background-color: var(--iv-dis);
|
||||
color: var(--fg2);
|
||||
}
|
||||
|
||||
.ch-h {
|
||||
background-color: var(--ch-head-title);
|
||||
color: var(--fg2);
|
||||
|
|
|
@ -87,22 +87,26 @@
|
|||
);
|
||||
}
|
||||
function ivHead(obj) {
|
||||
if(0 != obj.status) { // only add totals if inverter is online
|
||||
total[0] += obj.ch[0][2]; // P_AC
|
||||
total[1] += obj.ch[0][7]; // YieldDay
|
||||
total[2] += obj.ch[0][6]; // YieldTotal
|
||||
total[3] += obj.ch[0][8]; // P_DC
|
||||
total[4] += obj.ch[0][10]; // Q_AC
|
||||
}
|
||||
var t = span(" °C");
|
||||
var clh = (0 == obj.status) ? "iv-h-dis" : "iv-h";
|
||||
var clbg = (0 == obj.status) ? "iv-bg-dis" : "iv-bg";
|
||||
return ml("div", {class: "row mt-2"},
|
||||
ml("div", {class: "col"}, [
|
||||
ml("div", {class: "p-2 iv-h"},
|
||||
ml("div", {class: "p-2 " + clh},
|
||||
ml("div", {class: "row"}, [
|
||||
ml("div", {class: "col mx-2 mx-md-1"}, obj.name),
|
||||
ml("div", {class: "col a-c"}, "Power limit " + ((obj.power_limit_read == 65535) ? "n/a" : (obj.power_limit_read + " %"))),
|
||||
ml("div", {class: "col a-r mx-2 mx-md-1"}, String(obj.ch[0][5]) + t.innerText)
|
||||
])
|
||||
),
|
||||
ml("div", {class: "p-2 iv-bg"}, [
|
||||
ml("div", {class: "p-2 " + clbg}, [
|
||||
ml("div", {class: "row"},[
|
||||
numBig(obj.ch[0][2], "W", "AC Power"),
|
||||
numBig(obj.ch[0][7], "Wh", "Yield Day"),
|
||||
|
@ -110,6 +114,7 @@
|
|||
]),
|
||||
ml("div", {class: "hr"}),
|
||||
ml("div", {class: "row mt-2"},[
|
||||
numMid(obj.ch[0][11], "W", "Max AC Power"),
|
||||
numMid(obj.ch[0][8], "W", "DC Power"),
|
||||
numMid(obj.ch[0][0], "V", "Voltage"),
|
||||
numMid(obj.ch[0][1], "A", "Current"),
|
||||
|
@ -138,12 +143,15 @@
|
|||
]);
|
||||
}
|
||||
|
||||
function ch(name, vals) {
|
||||
function ch(status, name, vals) {
|
||||
var clh = (0 == status) ? "iv-h-dis" : "iv-h";
|
||||
var clbg = (0 == status) ? "iv-bg-dis" : "iv-bg";
|
||||
return ml("div", {class: "col-6 col-md-3 mt-2"}, [
|
||||
ml("div", {class: "ch-h p-2 a-c"}, name),
|
||||
ml("div", {class: "p-2 ch-bg"}, [
|
||||
ml("div", {class: "p-2 a-c " + clh}, name),
|
||||
ml("div", {class: "p-2 " + clbg}, [
|
||||
ml("div", {class: "row"}, [
|
||||
numCh(vals[2], units[2], "Power"),
|
||||
numCh(vals[6], units[2], "Max Power"),
|
||||
numCh(vals[5], units[5], "Irradiation"),
|
||||
numCh(vals[3], units[3], "Yield Day"),
|
||||
numCh(vals[4], units[4], "Yield Total"),
|
||||
|
@ -182,7 +190,7 @@
|
|||
if(name.length == 0)
|
||||
name = "CHANNEL " + i;
|
||||
if(obj.ch_max_pwr[i] > 0) // show channel only if max mod pwr
|
||||
chn.push(ch(name, obj.ch[i]));
|
||||
chn.push(ch(obj.status, name, obj.ch[i]));
|
||||
}
|
||||
mIvHtml.push(
|
||||
ml("div", {}, [
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue