Browse Source

Merge pull request #327 from DanielR92/daniel-dev03

patch and change to a switch case
pull/330/head
lumapu 2 years ago
committed by GitHub
parent
commit
ab70dda9a1
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      tools/esp8266/CircularBuffer.h
  2. 8
      tools/esp8266/User_Manual.md
  3. 2
      tools/esp8266/app.cpp
  4. 184
      tools/esp8266/hmDefines.h
  5. 8
      tools/esp8266/hmInverter.h
  6. 37
      tools/esp8266/hmRadio.h
  7. 38
      tools/esp8266/html/serial.html
  8. 2
      tools/esp8266/html/visualization.html
  9. 37
      tools/esp8266/platformio.ini
  10. 4
      tools/esp8266/web.cpp
  11. 77
      tools/esp8266/webApi.cpp

5
tools/esp8266/CircularBuffer.h

@ -21,10 +21,7 @@
#ifndef CircularBuffer_h #ifndef CircularBuffer_h
#define CircularBuffer_h #define CircularBuffer_h
#ifdef ESP8266 #if defined(ESP8266) || defined(ESP32)
#define DISABLE_IRQ noInterrupts()
#define RESTORE_IRQ interrupts()
#elif defined(ESP32)
#define DISABLE_IRQ noInterrupts() #define DISABLE_IRQ noInterrupts()
#define RESTORE_IRQ interrupts() #define RESTORE_IRQ interrupts()
#else #else

8
tools/esp8266/User_Manual.md

@ -18,11 +18,11 @@ The ahoy dtu will publish on the following topics
|U_AC | 233.300|actual AC Voltage in Volt| |U_AC | 233.300|actual AC Voltage in Volt|
|I_AC | 0.300 | actual AC Current in Ampere| |I_AC | 0.300 | actual AC Current in Ampere|
|P_AC | 71.000| actual AC Power in Watt| |P_AC | 71.000| actual AC Power in Watt|
|P_ACr | 21.200| actual AC reactive power in VAr| |Q_AC | 21.200| actual AC reactive power in var|
|Freq | 49.990|actual AC Frequency in 1/s| |F_AC | 49.990| actual AC Frequency in Hz|
|Pct | 95.800|actual AC Power factor in %| |PF_AC | 95.800| actual AC Power factor|
|Temp | 19.800|Temperature of inverter in Celsius| |Temp | 19.800|Temperature of inverter in Celsius|
|LARM_MES_ID | 9.000|Last Alarm Message Id| |EVT | 9.000|Last Event/Alarm Message Index|
|YieldDay | 51.000|Energy converted to AC per day in Watt hours (measured on DC)| |YieldDay | 51.000|Energy converted to AC per day in Watt hours (measured on DC)|
|YieldTotal | 465.294|Energy converted to AC since reset Watt hours (measured on DC)| |YieldTotal | 465.294|Energy converted to AC since reset Watt hours (measured on DC)|
|P_DC | 74.600|actual DC Power in Watt| |P_DC | 74.600|actual DC Power in Watt|

2
tools/esp8266/app.cpp

@ -250,7 +250,7 @@ void app::loop(void) {
DPRINTLN(DBG_DEBUG, F("app:loop WiFi WiFi.status ") + String(WiFi.status())); DPRINTLN(DBG_DEBUG, F("app:loop WiFi WiFi.status ") + String(WiFi.status()));
DPRINTLN(DBG_INFO, F("Requesting Inverter SN ") + String(iv->serial.u64, HEX)); DPRINTLN(DBG_INFO, F("Requesting Inverter SN ") + String(iv->serial.u64, HEX));
} }
if(iv->devControlRequest && (iv->powerLimit[0] > 0) && (NoPowerLimit != iv->powerLimit[1])) { // prevent to "switch off" if(iv->devControlRequest && ((iv->devControlCmd != ActivePowerContr) || ((iv->devControlCmd == ActivePowerContr) && (iv->powerLimit[0] > 0) && (iv->powerLimit[1] != NoPowerLimit)))) { // prevent to "switch off"
if(mConfig.serialDebug) if(mConfig.serialDebug)
DPRINTLN(DBG_INFO, F("Devcontrol request ") + String(iv->devControlCmd) + F(" power limit ") + String(iv->powerLimit[0])); DPRINTLN(DBG_INFO, F("Devcontrol request ") + String(iv->devControlCmd) + F(" power limit ") + String(iv->powerLimit[0]));
mSys->Radio.sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit); mSys->Radio.sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit);

184
tools/esp8266/hmDefines.h

@ -20,16 +20,17 @@ union serial_u {
enum {UNIT_V = 0, UNIT_A, UNIT_W, UNIT_WH, UNIT_KWH, UNIT_HZ, UNIT_C, UNIT_PCT, UNIT_VAR, UNIT_NONE}; enum {UNIT_V = 0, UNIT_A, UNIT_W, UNIT_WH, UNIT_KWH, UNIT_HZ, UNIT_C, UNIT_PCT, UNIT_VAR, UNIT_NONE};
const char* const units[] = {"V", "A", "W", "Wh", "kWh", "Hz", "°C", "%", "var", ""}; const char* const units[] = {"V", "A", "W", "Wh", "kWh", "Hz", "°C", "%", "var", ""};
// field types // field types
enum {FLD_UDC = 0, FLD_IDC, FLD_PDC, FLD_YD, FLD_YW, FLD_YT, 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_PF, FLD_EFF, FLD_UAC, FLD_IAC, FLD_PAC, FLD_F, FLD_T, FLD_PF, FLD_EFF,
FLD_IRR, FLD_Q,FLD_ALARM_MES_ID,FLD_FW_VERSION,FLD_FW_BUILD_YEAR, FLD_IRR, FLD_Q, FLD_EVT, FLD_FW_VERSION, FLD_FW_BUILD_YEAR,
FLD_FW_BUILD_MONTH_DAY,FLD_HW_ID,FLD_ACT_PWR_LIMIT,FLD_LAST_ALARM_CODE}; 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};
const char* const fields[] = {"U_DC", "I_DC", "P_DC", "YieldDay", "YieldWeek", "YieldTotal", const char* const fields[] = {"U_DC", "I_DC", "P_DC", "YieldDay", "YieldWeek", "YieldTotal",
"U_AC", "I_AC", "P_AC", "F_AC", "Temp", "PF_AC", "Efficiency", "Irradiation","Q_AC", "U_AC", "I_AC", "P_AC", "F_AC", "Temp", "PF_AC", "Efficiency", "Irradiation","Q_AC",
"ALARM_MES_ID","FWVersion","FWBuildYear","FWBuildMonthDay","HWPartId","PowerLimit","LastAlarmCode"}; "ALARM_MES_ID","FWVersion","FWBuildYear","FWBuildMonthDay","FWBuildHourMinute","HWPartId",
"active PowerLimit", /*"reactive PowerLimit","Powerfactor",*/ "LastAlarmCode"};
const char* const notAvail = "n/a"; const char* const notAvail = "n/a";
// mqtt discovery device classes // mqtt discovery device classes
@ -93,12 +94,15 @@ const byteAssign_t InfoAssignment[] = {
{ FLD_FW_VERSION, UNIT_NONE, CH0, 0, 2, 1 }, { FLD_FW_VERSION, UNIT_NONE, CH0, 0, 2, 1 },
{ FLD_FW_BUILD_YEAR, UNIT_NONE, CH0, 2, 2, 1 }, { FLD_FW_BUILD_YEAR, UNIT_NONE, CH0, 2, 2, 1 },
{ FLD_FW_BUILD_MONTH_DAY, UNIT_NONE, CH0, 4, 2, 1 }, { FLD_FW_BUILD_MONTH_DAY, UNIT_NONE, CH0, 4, 2, 1 },
{ FLD_FW_BUILD_HOUR_MINUTE, UNIT_NONE, CH0, 6, 2, 1 },
{ FLD_HW_ID, UNIT_NONE, CH0, 8, 2, 1 } { FLD_HW_ID, UNIT_NONE, CH0, 8, 2, 1 }
}; };
#define HMINFO_LIST_LEN (sizeof(InfoAssignment) / sizeof(byteAssign_t)) #define HMINFO_LIST_LEN (sizeof(InfoAssignment) / sizeof(byteAssign_t))
const byteAssign_t SystemConfigParaAssignment[] = { const byteAssign_t SystemConfigParaAssignment[] = {
{ FLD_ACT_PWR_LIMIT, UNIT_PCT, CH0, 2, 2, 10 } { FLD_ACT_ACTIVE_PWR_LIMIT, UNIT_PCT, CH0, 2, 2, 10 }/*,
{ FLD_ACT_REACTIVE_PWR_LIMIT, UNIT_PCT, CH0, 4, 2, 10 },
{ FLD_ACT_PF, UNIT_NONE, CH0, 6, 2, 1000 }*/
}; };
#define HMSYSTEM_LIST_LEN (sizeof(SystemConfigParaAssignment) / sizeof(byteAssign_t)) #define HMSYSTEM_LIST_LEN (sizeof(SystemConfigParaAssignment) / sizeof(byteAssign_t))
@ -113,25 +117,25 @@ const byteAssign_t AlarmDataAssignment[] = {
// HM300, HM350, HM400 // HM300, HM350, HM400
//------------------------------------- //-------------------------------------
const byteAssign_t hm1chAssignment[] = { const byteAssign_t hm1chAssignment[] = {
{ FLD_UDC, UNIT_V, CH1, 2, 2, 10 }, { FLD_UDC, UNIT_V, CH1, 2, 2, 10 },
{ FLD_IDC, UNIT_A, CH1, 4, 2, 100 }, { FLD_IDC, UNIT_A, CH1, 4, 2, 100 },
{ FLD_PDC, UNIT_W, CH1, 6, 2, 10 }, { FLD_PDC, UNIT_W, CH1, 6, 2, 10 },
{ FLD_YD, UNIT_WH, CH1, 12, 2, 1 }, { FLD_YD, UNIT_WH, CH1, 12, 2, 1 },
{ FLD_YT, UNIT_KWH, CH1, 8, 4, 1000 }, { FLD_YT, UNIT_KWH, CH1, 8, 4, 1000 },
{ FLD_IRR, UNIT_PCT, CH1, CALC_IRR_CH, CH1, CMD_CALC }, { FLD_IRR, UNIT_PCT, CH1, CALC_IRR_CH, CH1, CMD_CALC },
{ FLD_UAC, UNIT_V, CH0, 14, 2, 10 }, { FLD_UAC, UNIT_V, CH0, 14, 2, 10 },
{ FLD_IAC, UNIT_A, CH0, 22, 2, 100 }, { FLD_IAC, UNIT_A, CH0, 22, 2, 100 },
{ FLD_PAC, UNIT_W, CH0, 18, 2, 10 }, { FLD_PAC, UNIT_W, CH0, 18, 2, 10 },
{ FLD_Q, UNIT_VAR, CH0, 20, 2, 10 }, { FLD_Q, UNIT_VAR, CH0, 20, 2, 10 },
{ FLD_F, UNIT_HZ, CH0, 16, 2, 100 }, { FLD_F, UNIT_HZ, CH0, 16, 2, 100 },
{ FLD_PF, UNIT_NONE,CH0, 24, 2, 1000 }, { FLD_PF, UNIT_NONE, CH0, 24, 2, 1000 },
{ FLD_T, UNIT_C, CH0, 26, 2, 10 }, { FLD_T, UNIT_C, CH0, 26, 2, 10 },
{ FLD_ALARM_MES_ID, UNIT_NONE, CH0, 28, 2, 1 }, { FLD_EVT, UNIT_NONE, CH0, 28, 2, 1 },
{ FLD_YD, UNIT_WH, CH0, CALC_YD_CH0, 0, CMD_CALC }, { FLD_YD, UNIT_WH, CH0, CALC_YD_CH0, 0, CMD_CALC },
{ FLD_YT, UNIT_KWH, CH0, CALC_YT_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_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 }
}; };
#define HM1CH_LIST_LEN (sizeof(hm1chAssignment) / sizeof(byteAssign_t)) #define HM1CH_LIST_LEN (sizeof(hm1chAssignment) / sizeof(byteAssign_t))
@ -140,32 +144,32 @@ const byteAssign_t hm1chAssignment[] = {
// HM600, HM700, HM800 // HM600, HM700, HM800
//------------------------------------- //-------------------------------------
const byteAssign_t hm2chAssignment[] = { const byteAssign_t hm2chAssignment[] = {
{ FLD_UDC, UNIT_V, CH1, 2, 2, 10 }, { FLD_UDC, UNIT_V, CH1, 2, 2, 10 },
{ FLD_IDC, UNIT_A, CH1, 4, 2, 100 }, { FLD_IDC, UNIT_A, CH1, 4, 2, 100 },
{ FLD_PDC, UNIT_W, CH1, 6, 2, 10 }, { FLD_PDC, UNIT_W, CH1, 6, 2, 10 },
{ FLD_YD, UNIT_WH, CH1, 22, 2, 1 }, { FLD_YD, UNIT_WH, CH1, 22, 2, 1 },
{ FLD_YT, UNIT_KWH, CH1, 14, 4, 1000 }, { FLD_YT, UNIT_KWH, CH1, 14, 4, 1000 },
{ FLD_IRR, UNIT_PCT, CH1, CALC_IRR_CH, CH1, CMD_CALC }, { FLD_IRR, UNIT_PCT, CH1, CALC_IRR_CH, CH1, CMD_CALC },
{ FLD_UDC, UNIT_V, CH2, 8, 2, 10 }, { FLD_UDC, UNIT_V, CH2, 8, 2, 10 },
{ FLD_IDC, UNIT_A, CH2, 10, 2, 100 }, { FLD_IDC, UNIT_A, CH2, 10, 2, 100 },
{ FLD_PDC, UNIT_W, CH2, 12, 2, 10 }, { FLD_PDC, UNIT_W, CH2, 12, 2, 10 },
{ FLD_YD, UNIT_WH, CH2, 24, 2, 1 }, { FLD_YD, UNIT_WH, CH2, 24, 2, 1 },
{ FLD_YT, UNIT_KWH, CH2, 18, 4, 1000 }, { FLD_YT, UNIT_KWH, CH2, 18, 4, 1000 },
{ FLD_IRR, UNIT_PCT, CH2, CALC_IRR_CH, CH2, CMD_CALC }, { FLD_IRR, UNIT_PCT, CH2, CALC_IRR_CH, CH2, CMD_CALC },
{ FLD_UAC, UNIT_V, CH0, 26, 2, 10 }, { FLD_UAC, UNIT_V, CH0, 26, 2, 10 },
{ FLD_IAC, UNIT_A, CH0, 34, 2, 100 }, { FLD_IAC, UNIT_A, CH0, 34, 2, 100 },
{ FLD_PAC, UNIT_W, CH0, 30, 2, 10 }, { FLD_PAC, UNIT_W, CH0, 30, 2, 10 },
{ FLD_Q, UNIT_VAR, CH0, 32, 2, 10 }, { FLD_Q, UNIT_VAR, CH0, 32, 2, 10 },
{ FLD_F, UNIT_HZ, CH0, 28, 2, 100 }, { FLD_F, UNIT_HZ, CH0, 28, 2, 100 },
{ FLD_PF, UNIT_NONE,CH0, 36, 2, 1000 }, { FLD_PF, UNIT_NONE, CH0, 36, 2, 1000 },
{ FLD_T, UNIT_C, CH0, 38, 2, 10 }, { FLD_T, UNIT_C, CH0, 38, 2, 10 },
{ FLD_ALARM_MES_ID, UNIT_NONE, CH0, 40, 2, 1 }, { FLD_EVT, UNIT_NONE, CH0, 40, 2, 1 },
{ FLD_YD, UNIT_WH, CH0, CALC_YD_CH0, 0, CMD_CALC }, { FLD_YD, UNIT_WH, CH0, CALC_YD_CH0, 0, CMD_CALC },
{ FLD_YT, UNIT_KWH, CH0, CALC_YT_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_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 }
}; };
#define HM2CH_LIST_LEN (sizeof(hm2chAssignment) / sizeof(byteAssign_t)) #define HM2CH_LIST_LEN (sizeof(hm2chAssignment) / sizeof(byteAssign_t))
@ -175,46 +179,46 @@ const byteAssign_t hm2chAssignment[] = {
// HM1200, HM1500 // HM1200, HM1500
//------------------------------------- //-------------------------------------
const byteAssign_t hm4chAssignment[] = { const byteAssign_t hm4chAssignment[] = {
{ FLD_UDC, UNIT_V, CH1, 2, 2, 10 }, { FLD_UDC, UNIT_V, CH1, 2, 2, 10 },
{ FLD_IDC, UNIT_A, CH1, 4, 2, 100 }, { FLD_IDC, UNIT_A, CH1, 4, 2, 100 },
{ FLD_PDC, UNIT_W, CH1, 8, 2, 10 }, { FLD_PDC, UNIT_W, CH1, 8, 2, 10 },
{ FLD_YD, UNIT_WH, CH1, 20, 2, 1 }, { FLD_YD, UNIT_WH, CH1, 20, 2, 1 },
{ FLD_YT, UNIT_KWH, CH1, 12, 4, 1000 }, { FLD_YT, UNIT_KWH, CH1, 12, 4, 1000 },
{ FLD_IRR, UNIT_PCT, CH1, CALC_IRR_CH, CH1, CMD_CALC }, { FLD_IRR, UNIT_PCT, CH1, CALC_IRR_CH, CH1, CMD_CALC },
{ FLD_UDC, UNIT_V, CH2, CALC_UDC_CH, CH1, CMD_CALC }, { FLD_UDC, UNIT_V, CH2, CALC_UDC_CH, CH1, CMD_CALC },
{ FLD_IDC, UNIT_A, CH2, 6, 2, 100 }, { FLD_IDC, UNIT_A, CH2, 6, 2, 100 },
{ FLD_PDC, UNIT_W, CH2, 10, 2, 10 }, { FLD_PDC, UNIT_W, CH2, 10, 2, 10 },
{ FLD_YD, UNIT_WH, CH2, 22, 2, 1 }, { FLD_YD, UNIT_WH, CH2, 22, 2, 1 },
{ FLD_YT, UNIT_KWH, CH2, 16, 4, 1000 }, { FLD_YT, UNIT_KWH, CH2, 16, 4, 1000 },
{ FLD_IRR, UNIT_PCT, CH2, CALC_IRR_CH, CH2, CMD_CALC }, { FLD_IRR, UNIT_PCT, CH2, CALC_IRR_CH, CH2, CMD_CALC },
{ FLD_UDC, UNIT_V, CH3, 24, 2, 10 }, { FLD_UDC, UNIT_V, CH3, 24, 2, 10 },
{ FLD_IDC, UNIT_A, CH3, 26, 2, 100 }, { FLD_IDC, UNIT_A, CH3, 26, 2, 100 },
{ FLD_PDC, UNIT_W, CH3, 30, 2, 10 }, { FLD_PDC, UNIT_W, CH3, 30, 2, 10 },
{ FLD_YD, UNIT_WH, CH3, 42, 2, 1 }, { FLD_YD, UNIT_WH, CH3, 42, 2, 1 },
{ FLD_YT, UNIT_KWH, CH3, 34, 4, 1000 }, { FLD_YT, UNIT_KWH, CH3, 34, 4, 1000 },
{ FLD_IRR, UNIT_PCT, CH3, CALC_IRR_CH, CH3, CMD_CALC }, { FLD_IRR, UNIT_PCT, CH3, CALC_IRR_CH, CH3, CMD_CALC },
{ FLD_UDC, UNIT_V, CH4, CALC_UDC_CH, CH3, CMD_CALC }, { FLD_UDC, UNIT_V, CH4, CALC_UDC_CH, CH3, CMD_CALC },
{ FLD_IDC, UNIT_A, CH4, 28, 2, 100 }, { FLD_IDC, UNIT_A, CH4, 28, 2, 100 },
{ FLD_PDC, UNIT_W, CH4, 32, 2, 10 }, { FLD_PDC, UNIT_W, CH4, 32, 2, 10 },
{ FLD_YD, UNIT_WH, CH4, 44, 2, 1 }, { FLD_YD, UNIT_WH, CH4, 44, 2, 1 },
{ FLD_YT, UNIT_KWH, CH4, 38, 4, 1000 }, { FLD_YT, UNIT_KWH, CH4, 38, 4, 1000 },
{ FLD_IRR, UNIT_PCT, CH4, CALC_IRR_CH, CH4, CMD_CALC }, { FLD_IRR, UNIT_PCT, CH4, CALC_IRR_CH, CH4, CMD_CALC },
{ FLD_UAC, UNIT_V, CH0, 46, 2, 10 }, { FLD_UAC, UNIT_V, CH0, 46, 2, 10 },
{ FLD_IAC, UNIT_A, CH0, 54, 2, 100 }, { FLD_IAC, UNIT_A, CH0, 54, 2, 100 },
{ FLD_PAC, UNIT_W, CH0, 50, 2, 10 }, { FLD_PAC, UNIT_W, CH0, 50, 2, 10 },
{ FLD_Q, UNIT_VAR, CH0, 52, 2, 10 }, { FLD_Q, UNIT_VAR, CH0, 52, 2, 10 },
{ FLD_F, UNIT_HZ, CH0, 48, 2, 100 }, { FLD_F, UNIT_HZ, CH0, 48, 2, 100 },
{ FLD_PF, UNIT_NONE,CH0, 56, 2, 1000 }, { FLD_PF, UNIT_NONE, CH0, 56, 2, 1000 },
{ FLD_T, UNIT_C, CH0, 58, 2, 10 }, { FLD_T, UNIT_C, CH0, 58, 2, 10 },
{ FLD_ALARM_MES_ID, UNIT_NONE, CH0, 60, 2, 1 }, { FLD_EVT, UNIT_NONE, CH0, 60, 2, 1 },
{ FLD_YD, UNIT_WH, CH0, CALC_YD_CH0, 0, CMD_CALC }, { FLD_YD, UNIT_WH, CH0, CALC_YD_CH0, 0, CMD_CALC },
{ FLD_YT, UNIT_KWH, CH0, CALC_YT_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_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 }
}; };
#define HM4CH_LIST_LEN (sizeof(hm4chAssignment) / sizeof(byteAssign_t)) #define HM4CH_LIST_LEN (sizeof(hm4chAssignment) / sizeof(byteAssign_t))

8
tools/esp8266/hmInverter.h

@ -109,7 +109,7 @@ class Inverter {
uint16_t alarmMesIndex; // Last recorded Alarm Message Index uint16_t alarmMesIndex; // Last recorded Alarm Message Index
uint16_t fwVersion; // Firmware Version from Info Command Request uint16_t fwVersion; // Firmware Version from Info Command Request
uint16_t powerLimit[2]; // limit power output uint16_t powerLimit[2]; // limit power output
uint16_t actPowerLimit; // float actPowerLimit; // actual power limit
uint8_t devControlCmd; // carries the requested cmd uint8_t devControlCmd; // carries the requested cmd
bool devControlRequest; // true if change needed bool devControlRequest; // true if change needed
serial_u serial; // serial number as on barcode serial_u serial; // serial number as on barcode
@ -253,7 +253,7 @@ class Inverter {
DPRINTLN(DBG_VERBOSE, "add real time"); DPRINTLN(DBG_VERBOSE, "add real time");
// get last alarm message index and save it in the inverter object // get last alarm message index and save it in the inverter object
if (getPosByChFld(0, FLD_ALARM_MES_ID, rec) == pos){ if (getPosByChFld(0, FLD_EVT, rec) == pos){
if (alarmMesIndex < rec->record[pos]){ if (alarmMesIndex < rec->record[pos]){
alarmMesIndex = rec->record[pos]; alarmMesIndex = rec->record[pos];
//enqueCommand<InfoCommand>(AlarmUpdate); // What is the function of AlarmUpdate? //enqueCommand<InfoCommand>(AlarmUpdate); // What is the function of AlarmUpdate?
@ -275,9 +275,9 @@ class Inverter {
else if (rec->assign == SystemConfigParaAssignment) { else if (rec->assign == SystemConfigParaAssignment) {
DPRINTLN(DBG_DEBUG, "add config"); DPRINTLN(DBG_DEBUG, "add config");
// get at least the firmware version and save it to the inverter object // get at least the firmware version and save it to the inverter object
if (getPosByChFld(0, FLD_ACT_PWR_LIMIT, rec) == pos){ if (getPosByChFld(0, FLD_ACT_ACTIVE_PWR_LIMIT, rec) == pos){
actPowerLimit = rec->record[pos]; actPowerLimit = rec->record[pos];
DPRINT(DBG_DEBUG, F("Inverter actual power limit: ") + String(actPowerLimit)); DPRINT(DBG_DEBUG, F("Inverter actual power limit: ") + String(actPowerLimit, 1));
} }
} }
else if (rec->assign == AlarmDataAssignment) { else if (rec->assign == AlarmDataAssignment) {

37
tools/esp8266/hmRadio.h

@ -183,31 +183,26 @@ class HmRadio {
void sendControlPacket(uint64_t invId, uint8_t cmd, uint16_t *data) { void sendControlPacket(uint64_t invId, uint8_t cmd, uint16_t *data) {
DPRINTLN(DBG_INFO, F("sendControlPacket cmd: ") + String(cmd)); DPRINTLN(DBG_INFO, F("sendControlPacket cmd: ") + String(cmd));
sendCmdPacket(invId, TX_REQ_DEVCONTROL, SINGLE_FRAME, false); // SINGLE_FRAME 0x81 as original DTU code sendCmdPacket(invId, TX_REQ_DEVCONTROL, SINGLE_FRAME, false);
int cnt = 0; uint8_t cnt = 0;
mTxBuf[10] = cmd; // cmd --> 0x0b => Type_ActivePowerContr, 0 on, 1 off, 2 restart, 12 reactive power, 13 power factor, 20 CleanState_LockAndAlarm mTxBuf[10 + cnt++] = cmd; // cmd -> 0 on, 1 off, 2 restart, 11 active power, 12 reactive power, 13 power factor
if (cmd == CleanState_LockAndAlarm) { mTxBuf[10 + cnt++] = 0x00;
// skip user data, append only crc8 if(cmd >= ActivePowerContr && cmd <= PFSet) { // ActivePowerContr, ReactivePowerContr, PFSet
} else { mTxBuf[10 + cnt++] = ((data[0] * 10) >> 8) & 0xff; // power limit
// append user data and crc16 mTxBuf[10 + cnt++] = ((data[0] * 10) ) & 0xff; // power limit
mTxBuf[10 + (++cnt)] = 0x00; mTxBuf[10 + cnt++] = ((data[1] ) >> 8) & 0xff; // setting for persistens handlings
if (cmd >= ActivePowerContr && cmd <= PFSet){ mTxBuf[10 + cnt++] = ((data[1] ) ) & 0xff; // setting for persistens handling
mTxBuf[10 + (++cnt)] = ((data[0] * 10) >> 8) & 0xff; // power limit
mTxBuf[10 + (++cnt)] = ((data[0] * 10) ) & 0xff; // power limit
mTxBuf[10 + (++cnt)] = ((data[1] ) >> 8) & 0xff; // setting for persistens handlings
mTxBuf[10 + (++cnt)] = ((data[1] ) ) & 0xff; // setting for persistens handling
}
// crc16 control data
uint16_t crc = Ahoy::crc16(&mTxBuf[10], cnt+1);
mTxBuf[10 + (++cnt)] = (crc >> 8) & 0xff;
mTxBuf[10 + (++cnt)] = (crc ) & 0xff;
} }
// crc8 over all // crc control data
cnt++; uint16_t crc = Ahoy::crc16(&mTxBuf[10], cnt);
mTxBuf[10 + cnt++] = (crc >> 8) & 0xff;
mTxBuf[10 + cnt++] = (crc ) & 0xff;
// crc over all
mTxBuf[10 + cnt] = Ahoy::crc8(mTxBuf, 10 + cnt); mTxBuf[10 + cnt] = Ahoy::crc8(mTxBuf, 10 + cnt);
sendPacket(invId, mTxBuf, 10 + (++cnt), true); sendPacket(invId, mTxBuf, 10 + cnt + 1, true);
} }
void sendTimePacket(uint64_t invId, uint8_t cmd, uint32_t ts, uint16_t alarmMesId) { void sendTimePacket(uint64_t invId, uint8_t cmd, uint32_t ts, uint16_t alarmMesId) {

38
tools/esp8266/html/serial.html

@ -20,7 +20,7 @@
<hr> <hr>
<h3>handle next buttons with care - test / debug only!!</h3> <h3>handle next buttons with care - test / debug only!!</h3>
<br/> <br/>
<label for="iv">Choose your Inverter:</label> <label for="iv">Select Inverter:</label>
<select name="iv" id="iv"> <select name="iv" id="iv">
<option value="0">0</option> <option value="0">0</option>
<option value="1">1</option> <option value="1">1</option>
@ -30,9 +30,9 @@
<br/> <br/>
<input type="button" value="power limit 100%" class="btn" id="pwrlim2"/> <input type="button" value="power limit 100%" class="btn" id="pwrlim2"/>
<input type="button" value="power limit 10%" class="btn" id="pwrlim"/> <input type="button" value="power limit 10%" class="btn" id="pwrlim"/>
<input type="button" value="Restart" class="btn" id="restart"/>
<input type="button" value="Turn Off" class="btn" id="turnoff"/> <input type="button" value="Turn Off" class="btn" id="turnoff"/>
<input type="button" value="Turn On" class="btn" id="turnon"/> <input type="button" value="Turn On" class="btn" id="turnon"/>
<input type="button" value="Clean &amp; Reboot" class="btn" id="clnstate"/>
<br/> <br/>
Ctrl result: <span id="result">n/a</span> Ctrl result: <span id="result">n/a</span>
</div> </div>
@ -103,53 +103,53 @@
e.innerHTML = "Error: " + obj["error"]; e.innerHTML = "Error: " + obj["error"];
} }
function get_selected_iv()
{
var e = document.getElementById("iv");
return e.value;
}
document.getElementById("turnon").addEventListener("click", function() { document.getElementById("turnon").addEventListener("click", function() {
var obj = new Object(); var obj = new Object();
obj.inverter = get_selected_iv();
obj.cmd = 0; obj.cmd = 0;
obj.tx_request = 81; obj.tx_request = 81;
obj.inverter = get_selected_iv();
getAjax("/api/ctrl", ctrlCb, "POST", JSON.stringify(obj)); getAjax("/api/ctrl", ctrlCb, "POST", JSON.stringify(obj));
}); });
document.getElementById("turnoff").addEventListener("click", function() { document.getElementById("turnoff").addEventListener("click", function() {
var obj = new Object(); var obj = new Object();
obj.inverter = get_selected_iv();
obj.cmd = 1; obj.cmd = 1;
obj.tx_request = 81; obj.tx_request = 81;
getAjax("/api/ctrl", ctrlCb, "POST", JSON.stringify(obj));
});
document.getElementById("restart").addEventListener("click", function() {
var obj = new Object();
obj.inverter = get_selected_iv(); obj.inverter = get_selected_iv();
obj.cmd = 2;
obj.tx_request = 81;
getAjax("/api/ctrl", ctrlCb, "POST", JSON.stringify(obj)); getAjax("/api/ctrl", ctrlCb, "POST", JSON.stringify(obj));
}); });
document.getElementById("pwrlim").addEventListener("click", function() { document.getElementById("pwrlim").addEventListener("click", function() {
var obj = new Object(); var obj = new Object();
obj.inverter = get_selected_iv();
obj.cmd = 11; obj.cmd = 11;
obj.tx_request = 81; obj.tx_request = 81;
obj.payload = [10, 1]; obj.payload = [10, 1];
obj.inverter = get_selected_iv();
getAjax("/api/ctrl", ctrlCb, "POST", JSON.stringify(obj)); getAjax("/api/ctrl", ctrlCb, "POST", JSON.stringify(obj));
}); });
document.getElementById("pwrlim2").addEventListener("click", function() { document.getElementById("pwrlim2").addEventListener("click", function() {
var obj = new Object(); var obj = new Object();
obj.inverter = get_selected_iv();
obj.cmd = 11; obj.cmd = 11;
obj.tx_request = 81; obj.tx_request = 81;
obj.payload = [2000, 1]; obj.payload = [2000, 1];
obj.inverter = get_selected_iv();
getAjax("/api/ctrl", ctrlCb, "POST", JSON.stringify(obj)); getAjax("/api/ctrl", ctrlCb, "POST", JSON.stringify(obj));
}); });
document.getElementById("clnstate").addEventListener("click", function() {
var obj = new Object();
obj.cmd = 20;
obj.tx_request = 81;
obj.inverter = get_selected_iv();
getAjax("/api/ctrl", ctrlCb, "POST", JSON.stringify(obj));
});
function get_selected_iv()
{
var e = document.getElementById("iv");
return e.value;
}
</script> </script>
</body> </body>
</html> </html>

2
tools/esp8266/html/visualization.html

@ -55,7 +55,7 @@
case 6: total[j] += val; break; // YieldTotal case 6: total[j] += val; break; // YieldTotal
case 7: total[j] += val; break; // YieldDay case 7: total[j] += val; break; // YieldDay
case 8: total[j] += val; break; // P_DC case 8: total[j] += val; break; // P_DC
case 10: total[j] += val; break; // P_ACr case 10: total[j] += val; break; // Q_AC
} }
} }
} }

37
tools/esp8266/platformio.ini

@ -32,24 +32,22 @@ extra_scripts =
pre:html/convert.py pre:html/convert.py
lib_deps = lib_deps =
nrf24/RF24@1.4.5 https://github.com/yubox-node-org/ESPAsyncWebServer
paulstoffregen/Time@^1.6.1 nrf24/RF24
knolleary/PubSubClient@^2.8 paulstoffregen/Time
bblanchon/ArduinoJson@^6.19.4 knolleary/PubSubClient
;esp8266/DNSServer@1.1.0 bblanchon/ArduinoJson
;esp8266/EEPROM@^1.0 ;esp8266/DNSServer
;esp8266/ESP8266WiFi@^1.0 ;esp8266/EEPROM
;esp8266/SPI@1.0 ;esp8266/ESP8266WiFi
;esp8266/Ticker@^1.0 ;esp8266/SPI
;esp8266/Ticker
[env:esp8266-release] [env:esp8266-release]
platform = espressif8266 platform = espressif8266
board = esp12e board = esp12e
board_build.f_cpu = 80000000L board_build.f_cpu = 80000000L
build_flags = -D RELEASE build_flags = -D RELEASE
lib_deps = ${env.lib_deps}
me-no-dev/ESP Async WebServer@^1.2.3
me-no-dev/ESPAsyncTCP@^1.2.2
monitor_filters = monitor_filters =
;default ; Remove typical terminal control codes from input ;default ; Remove typical terminal control codes from input
time ; Add timestamp with milliseconds for each new line time ; Add timestamp with milliseconds for each new line
@ -61,9 +59,6 @@ board = esp12e
board_build.f_cpu = 80000000L board_build.f_cpu = 80000000L
build_flags = -DDEBUG_LEVEL=DBG_DEBUG -DDEBUG_ESP_CORE -DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_SERVER -DDEBUG_ESP_OOM -DDEBUG_ESP_PORT=Serial build_flags = -DDEBUG_LEVEL=DBG_DEBUG -DDEBUG_ESP_CORE -DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_SERVER -DDEBUG_ESP_OOM -DDEBUG_ESP_PORT=Serial
build_type = debug build_type = debug
lib_deps = ${env.lib_deps}
me-no-dev/ESP Async WebServer@^1.2.3
me-no-dev/ESPAsyncTCP@^1.2.2
monitor_filters = monitor_filters =
;default ; Remove typical terminal control codes from input ;default ; Remove typical terminal control codes from input
time ; Add timestamp with milliseconds for each new line time ; Add timestamp with milliseconds for each new line
@ -72,10 +67,8 @@ monitor_filters =
[env:esp32-wroom32-release] [env:esp32-wroom32-release]
platform = espressif32 platform = espressif32
board = lolin_d32 board = lolin_d32
build_flags = -D RELEASE build_flags = -D RELEASE -std=gnu++14
lib_deps = ${env.lib_deps} build_unflags = -std=gnu++11
https://github.com/me-no-dev/ESPAsyncWebServer.git
me-no-dev/AsyncTCP@^1.1.1
upload_port = /dev/cu.SLAB_USBtoUART upload_port = /dev/cu.SLAB_USBtoUART
monitor_filters = monitor_filters =
;default ; Remove typical terminal control codes from input ;default ; Remove typical terminal control codes from input
@ -85,11 +78,9 @@ monitor_filters =
[env:esp32-wroom32-debug] [env:esp32-wroom32-debug]
platform = espressif32 platform = espressif32
board = lolin_d32 board = lolin_d32
build_flags = -DDEBUG_LEVEL=DBG_DEBUG -DDEBUG_ESP_CORE -DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_SERVER -DDEBUG_ESP_OOM -DDEBUG_ESP_PORT=Serial build_flags = -DDEBUG_LEVEL=DBG_DEBUG -DDEBUG_ESP_CORE -DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_SERVER -DDEBUG_ESP_OOM -DDEBUG_ESP_PORT=Serial -std=gnu++14
build_unflags = -std=gnu++11
build_type = debug build_type = debug
lib_deps = ${env.lib_deps}
https://github.com/me-no-dev/ESPAsyncWebServer.git
me-no-dev/AsyncTCP@^1.1.1
upload_port = /dev/cu.SLAB_USBtoUART upload_port = /dev/cu.SLAB_USBtoUART
monitor_filters = monitor_filters =
;default ; Remove typical terminal control codes from input ;default ; Remove typical terminal control codes from input

4
tools/esp8266/web.cpp

@ -396,6 +396,10 @@ void web::showWebApi(AsyncWebServerRequest *request) {
iv->devControlCmd = CleanState_LockAndAlarm; iv->devControlCmd = CleanState_LockAndAlarm;
iv->devControlRequest = true; // queue it in the request loop iv->devControlRequest = true; // queue it in the request loop
} }
if (response["cmd"] == (uint8_t)Restart) {
iv->devControlCmd = Restart;
iv->devControlRequest = true; // queue it in the request loop
}
} }
} }
request->send(200, "text/json", "{success:true}"); request->send(200, "text/json", "{success:true}");

77
tools/esp8266/webApi.cpp

@ -261,7 +261,7 @@ void webApi::getLive(JsonObject obj) {
JsonArray invArr = obj.createNestedArray(F("inverter")); JsonArray invArr = obj.createNestedArray(F("inverter"));
obj["refresh_interval"] = SEND_INTERVAL; obj["refresh_interval"] = SEND_INTERVAL;
uint8_t list[] = {FLD_UAC, FLD_IAC, FLD_PAC, FLD_F, FLD_PF, FLD_T, FLD_YT, FLD_YD, FLD_PDC, FLD_EFF, FLD_Q, FLD_ALARM_MES_ID}; uint8_t list[] = {FLD_UAC, FLD_IAC, FLD_PAC, FLD_F, FLD_PF, FLD_T, FLD_YT, FLD_YD, FLD_PDC, FLD_EFF, FLD_Q};
Inverter<> *iv; Inverter<> *iv;
uint8_t pos; uint8_t pos;
@ -272,7 +272,7 @@ void webApi::getLive(JsonObject obj) {
JsonObject obj2 = invArr.createNestedObject(); JsonObject obj2 = invArr.createNestedObject();
obj2[F("name")] = String(iv->name); obj2[F("name")] = String(iv->name);
obj2[F("channels")] = iv->channels; obj2[F("channels")] = iv->channels;
obj2[F("power_limit_read")] = iv->actPowerLimit; obj2[F("power_limit_read")] = round3(iv->actPowerLimit);
obj2[F("power_limit_active")] = NoPowerLimit != iv->powerLimit[1]; obj2[F("power_limit_active")] = NoPowerLimit != iv->powerLimit[1];
obj2[F("last_alarm")] = String(iv->lastAlarmMsg); obj2[F("last_alarm")] = String(iv->lastAlarmMsg);
obj2[F("ts_last_success")] = rec->ts; obj2[F("ts_last_success")] = rec->ts;
@ -340,45 +340,42 @@ bool webApi::setCtrl(DynamicJsonDocument jsonIn, JsonObject jsonOut) {
// Todo: num is the inverter number 0-3. For better display in DPRINTLN // Todo: num is the inverter number 0-3. For better display in DPRINTLN
uint8_t num = jsonIn[F("inverter")]; uint8_t num = jsonIn[F("inverter")];
if(TX_REQ_DEVCONTROL == jsonIn[F("tx_request")]) { if(TX_REQ_DEVCONTROL == jsonIn[F("tx_request")])
{
DPRINTLN(DBG_INFO, F("devcontrol [") + String(num) + F("], cmd: 0x") + String(cmd, HEX)); DPRINTLN(DBG_INFO, F("devcontrol [") + String(num) + F("], cmd: 0x") + String(cmd, HEX));
if(ActivePowerContr == cmd) {
Inverter<> *iv = getInverter(jsonIn, jsonOut); Inverter<> *iv = getInverter(jsonIn, jsonOut);
if(NULL != iv) { JsonArray payload = jsonIn[F("payload")].as<JsonArray>();
JsonArray payload = jsonIn[F("payload")].as<JsonArray>();
iv->powerLimit[0] = payload[0]; if(NULL != iv)
iv->powerLimit[1] = payload[1]; {
} switch (cmd)
} {
else if(TurnOn == cmd) { case TurnOn:
Inverter<> *iv = getInverter(jsonIn, jsonOut); iv->devControlCmd = TurnOn;
if(NULL != iv) { iv->devControlRequest = true;
iv->devControlCmd = TurnOn; break;
iv->devControlRequest = true; case TurnOff:
} iv->devControlCmd = TurnOff;
else iv->devControlRequest = true;
return false; break;
} case CleanState_LockAndAlarm:
else if(TurnOff == cmd) { iv->devControlCmd = CleanState_LockAndAlarm;
Inverter<> *iv = getInverter(jsonIn, jsonOut); iv->devControlRequest = true;
if(NULL != iv) { break;
iv->devControlCmd = TurnOff; case Restart:
iv->devControlRequest = true; iv->devControlCmd = Restart;
} iv->devControlRequest = true;
else break;
return false; case ActivePowerContr:
} iv->powerLimit[0] = payload[0];
else if(CleanState_LockAndAlarm == cmd) { iv->powerLimit[1] = payload[1];
Inverter<> *iv = getInverter(jsonIn, jsonOut); break;
if(NULL != iv) { default:
iv->devControlCmd = CleanState_LockAndAlarm; jsonOut["error"] = "unknown 'cmd' = " + String(cmd);
iv->devControlRequest = true; return false;
} }
else } else {
return false;
}
else {
jsonOut["error"] = "unknown 'cmd' = " + String(cmd);
return false; return false;
} }
} }

Loading…
Cancel
Save