mirror of
https://github.com/lumapu/ahoy.git
synced 2025-05-13 00:46:38 +02:00
improved records in hmInverter.h
This commit is contained in:
parent
6bd7e01f1a
commit
56b747709a
9 changed files with 316 additions and 290 deletions
|
@ -23,7 +23,7 @@
|
|||
*/
|
||||
|
||||
// forward declaration of class
|
||||
template <class RECORDTYPE=float>
|
||||
template <class REC_TYP=float>
|
||||
class Inverter;
|
||||
|
||||
|
||||
|
@ -55,17 +55,23 @@ struct calcFunc_t {
|
|||
func_t<T>* func; // function pointer
|
||||
};
|
||||
|
||||
template<class T=float>
|
||||
struct record_t {
|
||||
byteAssign_t* assign; // assigment of bytes in payload
|
||||
uint8_t length; // length of the assignment list
|
||||
T *record; // data pointer
|
||||
uint32_t ts; // timestamp of last received payload
|
||||
};
|
||||
|
||||
class CommandAbstract {
|
||||
public:
|
||||
CommandAbstract(uint8_t txType = 0, uint8_t cmd = 0){
|
||||
CommandAbstract(uint8_t txType = 0, uint8_t cmd = 0) {
|
||||
_TxType = txType;
|
||||
_Cmd = cmd;
|
||||
};
|
||||
virtual ~CommandAbstract() {};
|
||||
|
||||
const uint8_t getCmd()
|
||||
{
|
||||
const uint8_t getCmd() {
|
||||
return _Cmd;
|
||||
}
|
||||
|
||||
|
@ -75,11 +81,11 @@ class CommandAbstract {
|
|||
};
|
||||
|
||||
class InfoCommand : public CommandAbstract {
|
||||
public:
|
||||
InfoCommand(uint8_t cmd){
|
||||
_TxType = 0x15;
|
||||
_Cmd = cmd;
|
||||
}
|
||||
public:
|
||||
InfoCommand(uint8_t cmd){
|
||||
_TxType = 0x15;
|
||||
_Cmd = cmd;
|
||||
}
|
||||
};
|
||||
|
||||
// list of all available functions, mapped in hmDefines.h
|
||||
|
@ -94,35 +100,34 @@ const calcFunc_t<T> calcFunctions[] = {
|
|||
};
|
||||
|
||||
|
||||
template <class RECORDTYPE>
|
||||
template <class REC_TYP>
|
||||
class Inverter {
|
||||
public:
|
||||
uint8_t id; // unique id
|
||||
uint8_t id; // unique id
|
||||
char name[MAX_NAME_LENGTH]; // human readable name, eg. "HM-600.1"
|
||||
uint8_t type; // integer which refers to inverter type
|
||||
byteAssign_t* assign; // type of inverter
|
||||
uint8_t listLen; // length of assignments
|
||||
uint16_t alarmMesIndex; // Last recorded Alarm Message Index
|
||||
uint16_t fwVersion; // Firmware Version from Info Command Request
|
||||
uint16_t powerLimit[2]; // limit power output
|
||||
uint16_t actPowerLimit; //
|
||||
uint8_t devControlCmd; // carries the requested cmd
|
||||
bool devControlRequest; // true if change needed
|
||||
serial_u serial; // serial number as on barcode
|
||||
serial_u radioId; // id converted to modbus
|
||||
uint8_t channels; // number of PV channels (1-4)
|
||||
uint32_t ts; // timestamp of last received payload
|
||||
RECORDTYPE *record; // pointer for values
|
||||
uint16_t chMaxPwr[4]; // maximum power of the modules (Wp)
|
||||
char chName[4][MAX_NAME_LENGTH]; // human readable name for channel
|
||||
uint8_t type; // integer which refers to inverter type
|
||||
uint16_t alarmMesIndex; // Last recorded Alarm Message Index
|
||||
uint16_t fwVersion; // Firmware Version from Info Command Request
|
||||
uint16_t powerLimit[2]; // limit power output
|
||||
uint16_t actPowerLimit; //
|
||||
uint8_t devControlCmd; // carries the requested cmd
|
||||
bool devControlRequest; // true if change needed
|
||||
serial_u serial; // serial number as on barcode
|
||||
serial_u radioId; // id converted to modbus
|
||||
uint8_t channels; // number of PV channels (1-4)
|
||||
record_t<REC_TYP> recordMeas; // structure for measured values
|
||||
record_t<REC_TYP> recordInfo; // structure for info values
|
||||
record_t<REC_TYP> recordConfig; // structure for system config values
|
||||
record_t<REC_TYP> recordAlarm; // structure for alarm values
|
||||
uint16_t chMaxPwr[4]; // maximum power of the modules (Wp)
|
||||
char chName[4][MAX_NAME_LENGTH]; // human readable name for channels
|
||||
String lastAlarmMsg;
|
||||
bool initialized; // needed to check if the inverter was correctly added (ESP32 specific - union types are never null)
|
||||
bool initialized; // needed to check if the inverter was correctly added (ESP32 specific - union types are never null)
|
||||
|
||||
Inverter() {
|
||||
ts = 0;
|
||||
powerLimit[0] = 0xffff; // 65535 W Limit -> unlimited
|
||||
powerLimit[1] = NoPowerLimit; //
|
||||
actPowerLimit = 0xffff; // init feedback from inverter to -1
|
||||
powerLimit[0] = 0xffff; // 65535 W Limit -> unlimited
|
||||
powerLimit[1] = NoPowerLimit; // default power limit setting
|
||||
actPowerLimit = 0xffff; // init feedback from inverter to -1
|
||||
devControlRequest = false;
|
||||
devControlCmd = InitDataState;
|
||||
initialized = false;
|
||||
|
@ -174,187 +179,201 @@ class Inverter {
|
|||
|
||||
void init(void) {
|
||||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:init"));
|
||||
getAssignment();
|
||||
initAssignment(&recordMeas, RealTimeRunData_Debug);
|
||||
initAssignment(&recordInfo, InverterDevInform_All);
|
||||
initAssignment(&recordConfig, SystemConfigPara);
|
||||
initAssignment(&recordAlarm, AlarmData);
|
||||
toRadioId();
|
||||
record = new RECORDTYPE[listLen];
|
||||
memset(name, 0, MAX_NAME_LENGTH);
|
||||
memset(chName, 0, MAX_NAME_LENGTH * 4);
|
||||
memset(record, 0, sizeof(RECORDTYPE) * listLen);
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
uint8_t getPosByChFld(uint8_t channel, uint8_t fieldId) {
|
||||
uint8_t getPosByChFld(uint8_t channel, uint8_t fieldId, record_t<> *rec) {
|
||||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:getPosByChFld"));
|
||||
uint8_t pos = 0;
|
||||
for(; pos < listLen; pos++) {
|
||||
if((assign[pos].ch == channel) && (assign[pos].fieldId == fieldId))
|
||||
break;
|
||||
if(NULL != rec) {
|
||||
for(; pos < rec->length; pos++) {
|
||||
if((rec->assign[pos].ch == channel) && (rec->assign[pos].fieldId == fieldId))
|
||||
break;
|
||||
}
|
||||
return (pos >= rec->length) ? 0xff : pos;
|
||||
}
|
||||
return (pos >= listLen) ? 0xff : pos;
|
||||
else
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
const char *getFieldName(uint8_t pos) {
|
||||
const char *getFieldName(uint8_t pos, record_t<> *rec) {
|
||||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:getFieldName"));
|
||||
return fields[assign[pos].fieldId];
|
||||
if(NULL != rec)
|
||||
return fields[rec->assign[pos].fieldId];
|
||||
return notAvail;
|
||||
}
|
||||
|
||||
const char *getUnit(uint8_t pos) {
|
||||
const char *getUnit(uint8_t pos, record_t<> *rec) {
|
||||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:getUnit"));
|
||||
return units[assign[pos].unitId];
|
||||
if(NULL != rec)
|
||||
return units[rec->assign[pos].unitId];
|
||||
return notAvail;
|
||||
}
|
||||
|
||||
uint8_t getChannel(uint8_t pos) {
|
||||
uint8_t getChannel(uint8_t pos, record_t<> *rec) {
|
||||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:getChannel"));
|
||||
return assign[pos].ch;
|
||||
if(NULL != rec)
|
||||
return rec->assign[pos].ch;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void addValue(uint8_t pos, uint8_t buf[]) {
|
||||
void addValue(uint8_t pos, uint8_t buf[], record_t<> *rec) {
|
||||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:addValue"));
|
||||
uint8_t cmd = getQueuedCmd();
|
||||
uint8_t ptr = assign[pos].start;
|
||||
uint8_t end = ptr + assign[pos].num;
|
||||
uint16_t div = assign[pos].div;
|
||||
if(CMD_CALC != div) {
|
||||
uint32_t val = 0;
|
||||
do {
|
||||
val <<= 8;
|
||||
val |= buf[ptr];
|
||||
} while(++ptr != end);
|
||||
if ((RECORDTYPE)(div) > 1){
|
||||
record[pos] = (RECORDTYPE)(val) / (RECORDTYPE)(div);
|
||||
}
|
||||
else {
|
||||
record[pos] = (RECORDTYPE)(val);
|
||||
}
|
||||
|
||||
}
|
||||
if (cmd == RealTimeRunData_Debug) {
|
||||
// get last alarm message index and save it in the inverter object
|
||||
if (getPosByChFld(0, FLD_ALARM_MES_ID) == pos){
|
||||
if (alarmMesIndex < record[pos]){
|
||||
alarmMesIndex = record[pos];
|
||||
//enqueCommand<InfoCommand>(AlarmUpdate); // What is the function of AlarmUpdate?
|
||||
enqueCommand<InfoCommand>(AlarmData);
|
||||
if(NULL != rec) {
|
||||
uint8_t ptr = rec->assign[pos].start;
|
||||
uint8_t end = ptr + rec->assign[pos].num;
|
||||
uint16_t div = rec->assign[pos].div;
|
||||
if(rec == &recordMeas) {
|
||||
if(CMD_CALC != div) {
|
||||
uint32_t val = 0;
|
||||
do {
|
||||
val <<= 8;
|
||||
val |= buf[ptr];
|
||||
} while(++ptr != end);
|
||||
if ((REC_TYP)(div) > 1)
|
||||
rec->record[pos] = (REC_TYP)(val) / (REC_TYP)(div);
|
||||
else
|
||||
rec->record[pos] = (REC_TYP)(val);
|
||||
}
|
||||
else {
|
||||
alarmMesIndex = record[pos]; // no change
|
||||
// get last alarm message index and save it in the inverter object
|
||||
if (getPosByChFld(0, FLD_ALARM_MES_ID, rec) == pos){
|
||||
if (alarmMesIndex < rec->record[pos]){
|
||||
alarmMesIndex = rec->record[pos];
|
||||
//enqueCommand<InfoCommand>(AlarmUpdate); // What is the function of AlarmUpdate?
|
||||
enqueCommand<InfoCommand>(AlarmData);
|
||||
}
|
||||
else {
|
||||
alarmMesIndex = rec->record[pos]; // no change
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rec == &recordInfo) {
|
||||
// get at least the firmware version and save it to the inverter object
|
||||
if (getPosByChFld(0, FLD_FW_VERSION, rec) == pos){
|
||||
fwVersion = rec->record[pos];
|
||||
DPRINT(DBG_DEBUG, F("Inverter FW-Version: ") + String(fwVersion));
|
||||
}
|
||||
}
|
||||
if (rec == &recordConfig) {
|
||||
// get at least the firmware version and save it to the inverter object
|
||||
if (getPosByChFld(0, FLD_ACT_PWR_LIMIT, rec) == pos){
|
||||
actPowerLimit = rec->record[pos];
|
||||
DPRINT(DBG_DEBUG, F("Inverter actual power limit: ") + String(actPowerLimit));
|
||||
}
|
||||
}
|
||||
if (rec == &recordAlarm){
|
||||
if (getPosByChFld(0, FLD_LAST_ALARM_CODE, rec) == pos){
|
||||
lastAlarmMsg = getAlarmStr(rec->record[pos]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cmd == InverterDevInform_All) {
|
||||
// get at least the firmware version and save it to the inverter object
|
||||
if (getPosByChFld(0, FLD_FW_VERSION) == pos){
|
||||
fwVersion = record[pos];
|
||||
DPRINT(DBG_DEBUG, F("Inverter FW-Version: ") + String(fwVersion));
|
||||
}
|
||||
}
|
||||
if (cmd == SystemConfigPara) {
|
||||
// get at least the firmware version and save it to the inverter object
|
||||
if (getPosByChFld(0, FLD_ACT_PWR_LIMIT) == pos){
|
||||
actPowerLimit = record[pos];
|
||||
DPRINT(DBG_DEBUG, F("Inverter actual power limit: ") + String(actPowerLimit));
|
||||
}
|
||||
}
|
||||
if (cmd == AlarmData){
|
||||
if (getPosByChFld(0, FLD_LAST_ALARM_CODE) == pos){
|
||||
lastAlarmMsg = getAlarmStr(record[pos]);
|
||||
}
|
||||
}
|
||||
else
|
||||
DPRINTLN(DBG_ERROR, F("addValue: assignment not found with cmd 0x"));
|
||||
}
|
||||
|
||||
RECORDTYPE getValue(uint8_t pos) {
|
||||
REC_TYP getValue(uint8_t pos, record_t<> *rec) {
|
||||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:getValue"));
|
||||
return record[pos];
|
||||
if(NULL == rec)
|
||||
return 0;
|
||||
return rec->record[pos];
|
||||
}
|
||||
|
||||
void doCalculations() {
|
||||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:doCalculations"));
|
||||
uint8_t cmd = getQueuedCmd();
|
||||
getAssignment();
|
||||
if (cmd == RealTimeRunData_Debug){
|
||||
for(uint8_t i = 0; i < listLen; i++) {
|
||||
if(CMD_CALC == assign[i].div) {
|
||||
record[i] = calcFunctions<RECORDTYPE>[assign[i].start].func(this, assign[i].num);
|
||||
}
|
||||
yield();
|
||||
record_t<> *rec = getRecordStruct(RealTimeRunData_Debug);
|
||||
for(uint8_t i = 0; i < rec->length; i++) {
|
||||
if(CMD_CALC == rec->assign[i].div) {
|
||||
rec->record[i] = calcFunctions<REC_TYP>[rec->assign[i].start].func(this, rec->assign[i].num);
|
||||
}
|
||||
yield();
|
||||
}
|
||||
}
|
||||
|
||||
bool isAvailable(uint32_t timestamp) {
|
||||
bool isAvailable(uint32_t timestamp, record_t<> *rec) {
|
||||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:isAvailable"));
|
||||
return ((timestamp - ts) < INACT_THRES_SEC);
|
||||
return ((timestamp - rec->ts) < INACT_THRES_SEC);
|
||||
}
|
||||
|
||||
bool isProducing(uint32_t timestamp) {
|
||||
bool isProducing(uint32_t timestamp, record_t<> *rec) {
|
||||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:isProducing"));
|
||||
if(isAvailable(timestamp)) {
|
||||
uint8_t pos = getPosByChFld(CH0, FLD_PAC);
|
||||
return (getValue(pos) > INACT_PWR_THRESH);
|
||||
if(isAvailable(timestamp, rec)) {
|
||||
uint8_t pos = getPosByChFld(CH0, FLD_PAC, rec);
|
||||
return (getValue(pos, rec) > INACT_PWR_THRESH);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t getLastTs(void) {
|
||||
uint32_t getLastTs(record_t<> *rec) {
|
||||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:getLastTs"));
|
||||
return ts;
|
||||
return rec->ts;
|
||||
}
|
||||
|
||||
void getAssignment() {
|
||||
DPRINTLN(DBG_DEBUG, F("hmInverter.h:getAssignment"));
|
||||
// Default assignment;
|
||||
if (INV_TYPE_1CH == type) {
|
||||
listLen = (uint8_t)(HM1CH_LIST_LEN);
|
||||
assign = (byteAssign_t *)hm1chAssignment;
|
||||
channels = 1;
|
||||
}
|
||||
else if (INV_TYPE_2CH == type) {
|
||||
listLen = (uint8_t)(HM2CH_LIST_LEN);
|
||||
assign = (byteAssign_t *)hm2chAssignment;
|
||||
channels = 2;
|
||||
}
|
||||
else if (INV_TYPE_4CH == type) {
|
||||
listLen = (uint8_t)(HM4CH_LIST_LEN);
|
||||
assign = (byteAssign_t *)hm4chAssignment;
|
||||
channels = 4;
|
||||
}
|
||||
else {
|
||||
listLen = 0;
|
||||
channels = 0;
|
||||
assign = NULL;
|
||||
record_t<> *getRecordStruct(uint8_t cmd) {
|
||||
switch (cmd) {
|
||||
case RealTimeRunData_Debug: return &recordMeas;
|
||||
case InverterDevInform_All: return &recordInfo;
|
||||
case SystemConfigPara: return &recordConfig;
|
||||
case AlarmData: return &recordAlarm;
|
||||
default: break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (getQueuedCmd()) {
|
||||
void initAssignment(record_t<> *rec, uint8_t cmd) {
|
||||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:initAssignment"));
|
||||
rec->ts = 0;
|
||||
rec->length = 0;
|
||||
switch (cmd) {
|
||||
case RealTimeRunData_Debug:
|
||||
// Do nothing will use default
|
||||
if (INV_TYPE_1CH == type) {
|
||||
rec->length = (uint8_t)(HM1CH_LIST_LEN);
|
||||
rec->assign = (byteAssign_t *)hm1chAssignment;
|
||||
channels = 1;
|
||||
}
|
||||
else if (INV_TYPE_2CH == type) {
|
||||
rec->length = (uint8_t)(HM2CH_LIST_LEN);
|
||||
rec->assign = (byteAssign_t *)hm2chAssignment;
|
||||
channels = 2;
|
||||
}
|
||||
else if (INV_TYPE_4CH == type) {
|
||||
rec->length = (uint8_t)(HM4CH_LIST_LEN);
|
||||
rec->assign = (byteAssign_t *)hm4chAssignment;
|
||||
channels = 4;
|
||||
}
|
||||
else {
|
||||
rec->length = 0;
|
||||
rec->assign = NULL;
|
||||
channels = 0;
|
||||
}
|
||||
break;
|
||||
case InverterDevInform_All:
|
||||
listLen = (uint8_t)(HMINFO_LIST_LEN);
|
||||
assign = (byteAssign_t *)InfoAssignment;
|
||||
rec->length = (uint8_t)(HMINFO_LIST_LEN);
|
||||
rec->assign = (byteAssign_t *)InfoAssignment;
|
||||
break;
|
||||
case SystemConfigPara:
|
||||
listLen = (uint8_t)(HMSYSTEM_LIST_LEN);
|
||||
assign = (byteAssign_t *)SystemConfigParaAssignment;
|
||||
rec->length = (uint8_t)(HMSYSTEM_LIST_LEN);
|
||||
rec->assign = (byteAssign_t *)SystemConfigParaAssignment;
|
||||
break;
|
||||
case AlarmData:
|
||||
listLen = (uint8_t)(HMALARMDATA_LIST_LEN);
|
||||
assign = (byteAssign_t *)AlarmDataAssignment;
|
||||
rec->length = (uint8_t)(HMALARMDATA_LIST_LEN);
|
||||
rec->assign = (byteAssign_t *)AlarmDataAssignment;
|
||||
break;
|
||||
default:
|
||||
DPRINTLN(DBG_INFO, "Parser not implemented");
|
||||
DPRINTLN(DBG_INFO, F("initAssignment: Parser not implemented"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool isLiveDataAssignment(void) {
|
||||
if(assign == (byteAssign_t *)hm1chAssignment)
|
||||
return true;
|
||||
else if(assign == (byteAssign_t *)hm2chAssignment)
|
||||
return true;
|
||||
else if(assign == (byteAssign_t *)hm4chAssignment)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
if(0 != rec->length) {
|
||||
rec->record = new REC_TYP[rec->length];
|
||||
memset(rec->record, 0, sizeof(REC_TYP) * rec->length);
|
||||
}
|
||||
}
|
||||
|
||||
String getAlarmStr(u_int16_t alarmCode) {
|
||||
|
@ -455,10 +474,11 @@ template<class T=float>
|
|||
static T calcYieldTotalCh0(Inverter<> *iv, uint8_t arg0) {
|
||||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:calcYieldTotalCh0"));
|
||||
if(NULL != iv) {
|
||||
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);
|
||||
yield += iv->getValue(pos);
|
||||
uint8_t pos = iv->getPosByChFld(i, FLD_YT, rec);
|
||||
yield += iv->getValue(pos, rec);
|
||||
}
|
||||
return yield;
|
||||
}
|
||||
|
@ -469,10 +489,11 @@ template<class T=float>
|
|||
static T calcYieldDayCh0(Inverter<> *iv, uint8_t arg0) {
|
||||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:calcYieldDayCh0"));
|
||||
if(NULL != iv) {
|
||||
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);
|
||||
yield += iv->getValue(pos);
|
||||
uint8_t pos = iv->getPosByChFld(i, FLD_YD, rec);
|
||||
yield += iv->getValue(pos, rec);
|
||||
}
|
||||
return yield;
|
||||
}
|
||||
|
@ -483,9 +504,10 @@ template<class T=float>
|
|||
static T calcUdcCh(Inverter<> *iv, uint8_t arg0) {
|
||||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:calcUdcCh"));
|
||||
// arg0 = channel of source
|
||||
for(uint8_t i = 0; i < iv->listLen; i++) {
|
||||
if((FLD_UDC == iv->assign[i].fieldId) && (arg0 == iv->assign[i].ch)) {
|
||||
return iv->getValue(i);
|
||||
record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
||||
for(uint8_t i = 0; i < rec->length; i++) {
|
||||
if((FLD_UDC == rec->assign[i].fieldId) && (arg0 == rec->assign[i].ch)) {
|
||||
return iv->getValue(i, rec);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -496,10 +518,11 @@ template<class T=float>
|
|||
static T calcPowerDcCh0(Inverter<> *iv, uint8_t arg0) {
|
||||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:calcPowerDcCh0"));
|
||||
if(NULL != iv) {
|
||||
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);
|
||||
dcPower += iv->getValue(pos);
|
||||
uint8_t pos = iv->getPosByChFld(i, FLD_PDC, rec);
|
||||
dcPower += iv->getValue(pos, rec);
|
||||
}
|
||||
return dcPower;
|
||||
}
|
||||
|
@ -510,12 +533,13 @@ template<class T=float>
|
|||
static T calcEffiencyCh0(Inverter<> *iv, uint8_t arg0) {
|
||||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:calcEfficiencyCh0"));
|
||||
if(NULL != iv) {
|
||||
uint8_t pos = iv->getPosByChFld(CH0, FLD_PAC);
|
||||
T acPower = iv->getValue(pos);
|
||||
record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
||||
uint8_t pos = iv->getPosByChFld(CH0, FLD_PAC, rec);
|
||||
T acPower = iv->getValue(pos, rec);
|
||||
T dcPower = 0;
|
||||
for(uint8_t i = 1; i <= iv->channels; i++) {
|
||||
pos = iv->getPosByChFld(i, FLD_PDC);
|
||||
dcPower += iv->getValue(pos);
|
||||
pos = iv->getPosByChFld(i, FLD_PDC, rec);
|
||||
dcPower += iv->getValue(pos, rec);
|
||||
}
|
||||
if(dcPower > 0)
|
||||
return acPower / dcPower * 100.0f;
|
||||
|
@ -528,9 +552,10 @@ static T calcIrradiation(Inverter<> *iv, uint8_t arg0) {
|
|||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:calcIrradiation"));
|
||||
// arg0 = channel
|
||||
if(NULL != iv) {
|
||||
uint8_t pos = iv->getPosByChFld(arg0, FLD_PDC);
|
||||
record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
||||
uint8_t pos = iv->getPosByChFld(arg0, FLD_PDC, rec);
|
||||
if(iv->chMaxPwr[arg0-1] > 0)
|
||||
return iv->getValue(pos) / iv->chMaxPwr[arg0-1] * 100.0f;
|
||||
return iv->getValue(pos, rec) / iv->chMaxPwr[arg0-1] * 100.0f;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue