diff --git a/tools/esp8266/hmDefines.h b/tools/esp8266/hmDefines.h index ac53b876..169a8d09 100644 --- a/tools/esp8266/hmDefines.h +++ b/tools/esp8266/hmDefines.h @@ -4,10 +4,18 @@ #include "debug.h" #include + +union serial_u { + uint64_t u64; + uint8_t b[8]; +}; + + // units enum {UNIT_V = 0, UNIT_A, UNIT_W, UNIT_WH, UNIT_KWH, UNIT_HZ, UNIT_C, UNIT_PCT}; const char* const units[] = {"V", "A", "W", "Wh", "kWh", "Hz", "°C", "%"}; + // field types enum {FLD_UDC = 0, FLD_IDC, FLD_PDC, FLD_YD, FLD_YW, FLD_YT, FLD_UAC, FLD_IAC, FLD_PAC, FLD_F, FLD_T, FLD_PCT}; @@ -15,10 +23,8 @@ const char* const fields[] = {"U_DC", "I_DC", "P_DC", "YieldDay", "YieldWeek", " "U_AC", "I_AC", "P_AC", "Freq", "Temp", "Pct"}; -union serial_u { - uint64_t u64; - uint8_t b[8]; -}; +// indices to calculation functions, defined in hmInverter.h +enum {CALC_YT_CH0 = 0, CALC_YD_CH0, CALC_UDC_CH}; // CH0 is default channel (freq, ac, temp) @@ -30,6 +36,7 @@ enum {INV_TYPE_HM600 = 0, INV_TYPE_HM1200, INV_TYPE_HM400, INV_TYPE_HM800}; const char* const invTypes[] = {"HM600", "HM1200 / HM1500", "HM400", "HM800"}; #define NUM_INVERTER_TYPES 4 + typedef struct { uint8_t fieldId; // field id uint8_t unitId; // uint id @@ -119,7 +126,7 @@ const byteAssign_t hm1200assignment[] = { { FLD_PDC, UNIT_W, CH1, CMD01, 9, 2, 10 }, { FLD_YD, UNIT_WH, CH1, CMD02, 5, 2, 1 }, { FLD_YT, UNIT_KWH, CH1, CMD01, 13, 4, 1000 }, - { FLD_UDC, UNIT_V, CH2, CMD02, 9, 2, 10 }, + { FLD_UDC, UNIT_V, CH3, CMD02, 9, 2, 10 }, { FLD_IDC, UNIT_A, CH2, CMD01, 7, 2, 100 }, { FLD_PDC, UNIT_W, CH2, CMD01, 11, 2, 10 }, { FLD_YD, UNIT_WH, CH2, CMD02, 7, 2, 1 }, @@ -137,10 +144,15 @@ const byteAssign_t hm1200assignment[] = { { FLD_PAC, UNIT_W, CH0, CMD84, 3, 2, 10 }, { FLD_F, UNIT_HZ, CH0, CMD84, 1, 2, 100 }, { FLD_PCT, UNIT_PCT, CH0, CMD84, 9, 2, 10 }, - { FLD_T, UNIT_C, CH0, CMD84, 11, 2, 10 } + { FLD_T, UNIT_C, CH0, CMD84, 11, 2, 10 }, + { FLD_YT, UNIT_KWH, CH0, CMDFF, CALC_YT_CH0, 0, 1000 }, + { FLD_YD, UNIT_KWH, CH0, CMDFF, CALC_YD_CH0, 0, 1 }, + { FLD_UDC, UNIT_KWH, CH2, CMDFF, CALC_UDC_CH, CH1, 1000 }, + { FLD_UDC, UNIT_KWH, CH4, CMDFF, CALC_UDC_CH, CH3, 1000 } }; #define HM1200_LIST_LEN (sizeof(hm1200assignment) / sizeof(byteAssign_t)) + #endif /*__HM_DEFINES_H__*/ diff --git a/tools/esp8266/hmInverter.h b/tools/esp8266/hmInverter.h index 999545bf..06a307e6 100644 --- a/tools/esp8266/hmInverter.h +++ b/tools/esp8266/hmInverter.h @@ -3,7 +3,45 @@ #include "hmDefines.h" +/** + * For values which are of interest and not transmitted by the inverter can be + * calculated automatically. + * A list of functions can be linked to the assignment and will be executed + * automatically. Their result does not differ from original read values. + * The special command 0xff (CMDFF) must be used. + */ + +// forward declaration of class template +class Inverter; + + +// prototypes +template +static T calcYieldTotalCh0(Inverter<> *iv, uint8_t arg0); + +template +static T calcYieldDayCh0(Inverter<> *iv, uint8_t arg0); + +template +using func_t = T (Inverter<> *, uint8_t); + +template +struct calcFunc_t { + uint8_t funcId; // unique id + func_t* func; // function pointer +} ; + + +// list of all available functions, mapped in hmDefines.h +template +const calcFunc_t calcFunctions[] = { + { CALC_YT_CH0, &calcYieldTotalCh0 }, + { CALC_YD_CH0, &calcYieldDayCh0 } +}; + + +template class Inverter { public: uint8_t id; // unique id @@ -91,7 +129,7 @@ class Inverter { assign = (byteAssign_t*)hm600assignment; channels = 2; } - else if(INV_TYPE_HM800 == p->type) { + else if(INV_TYPE_HM800 == type) { listLen = (uint8_t)(HM800_LIST_LEN); assign = (byteAssign_t*)hm800assignment; channels = 2; @@ -107,6 +145,14 @@ class Inverter { assign = NULL; } } + + void doCalculations(void) { + for(uint8_t i = 0; i < listLen; i++) { + if(CMDFF == assign[i].cmdId) { + calcFunctions[assign[i].start].func(this, assign[i].num); + } + } + } }; @@ -116,33 +162,43 @@ class Inverter { * The special command 0xff (CMDFF) must be used. */ -typedef float (*func_t)(Inverter<> *); -typedef struct { - uint8_t funcId; // unique id - func_t func; // function pointer -} calcFunc_t; - -static float calcYieldTotalCh0(Inverter<> *iv) { +template +static T calcYieldTotalCh0(Inverter<> *iv, uint8_t arg0) { if(NULL != iv) { - float yield[iv->channels]; + T yield = 0; for(uint8_t i = 1; i <= iv->channels; i++) { uint8_t pos = iv->getPosByChFld(i, FLD_YT); - //yield[i-1] = iv->getValue(iv) + yield += iv->getValue(pos); } + return yield; } - return 1.0; + return 0.0; } -static float calcYieldDayCh0(Inverter<> *iv) { - return 1.0; +template +static T calcYieldDayCh0(Inverter<> *iv, uint8_t arg0) { + if(NULL != iv) { + T yield = 0; + for(uint8_t i = 1; i <= iv->channels; i++) { + uint8_t pos = iv->getPosByChFld(i, FLD_YD); + yield += iv->getValue(pos); + } + return yield; + } + return 0.0; } -enum {CALC_YT_CH0 = 0, CALC_YD_CH0}; +template +static T calcUdcCh(Inverter<> *iv, uint8_t arg0) { + // 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); + } + } -const calcFunc_t calcFunctions[] = { - { CALC_YT_CH0, &calcYieldTotalCh0 }, - { CALC_YD_CH0, &calcYieldDayCh0 } -}; + return 0.0; +} #endif /*__HM_INVERTER_H__*/