diff --git a/tools/esp8266/User_Manual.md b/tools/esp8266/User_Manual.md index dcdd5cb4..5667aa3e 100644 --- a/tools/esp8266/User_Manual.md +++ b/tools/esp8266/User_Manual.md @@ -1,30 +1,30 @@ # User Manual Ahoy DTU (on ESP8266) -15.08.2022 +16.08.2022 ## Introduction -see the repository [here](https://github.com/grindylow/ahoy/blob/main/tools/esp8266/README.md) +See the repository [here](https://github.com/grindylow/ahoy/blob/main/tools/esp8266/README.md) ## Setup -Assuming you have a running ahoy-dtu and you can access te setup page. -In the initial case or after click "erease settings" the fields for the inverter setup are empty. +Assuming you have a running ahoy-dtu and you can access the setup page. +In the initial case or after click "erase settings" the fields for the inverter setup are empty. Set at least the serial number and a name for each inverter, check the "reboot after save" and click the "Save" button. ## Active Power Limit via Setup Page I you leave the field "Active Power Limit" empty during the setup and reboot the ahoy-dtu a value of 65535 will be filled in. -That is the value you have to fill in case you want to operate the inverter without a active power limit. -If the value is 65535 or -1 after another reboot the value will be seted automatically to "100" and in the drop-down menu "relativ in percent persistent" will be seted. Of course you can do this also by your self. +That is the value you have to fill in case you want to operate the inverter without a active power limit. +If the value is 65535 or -1 after another reboot the value will be set automatically to "100" and in the drop-down menu "relative in percent persistent" will be set. Of course you can do this also by your self. You can change the setting in the following manner. Decide if you want to set -- an absolut value in Watt -- an relativ value in percent based on the maximum Power cababilities of the inverter +- an absolute value in Watt +- an relative value in percent based on the maximum Power capabilities of the inverter and if this settings shall be - persistent - not persistent -after a power cylce of the inverter (P_DC=0 and P_AC=0 for at least 10 seconds) +after a power cycle of the inverter (P_DC=0 and P_AC=0 for at least 10 seconds) -The user has to ensure sensfule settings. Remember that for the inverters of 3rd generation the relative active power limit is in the range of 2% up to 100%. -Also an absolut active power limit below approx. 30Watt is not senseful because of the control capabilities and reactive power load. +The user has to ensure correct settings. Remember that for the inverters of 3rd generation the relative active power limit is in the range of 2% up to 100%. +Also an absolute active power limit below approx. 30Watt is not correct because of the control capabilities and reactive power load. ## Active Power Limit via MQTT The ahoy-dtu subscribes on the topic /devcontrol/# if the mqtt broker is set-up correctly. The default topic is inverter/devcontrol/#. @@ -58,10 +58,10 @@ The implementation allows to set any of the available Commands: Init = 0xff } DevControlCmdType; ``` -The MQTT payload will be seted on first to bytes and DATA2 will be seted on the second two bytes if the corresponding DevControlCmdType supports 4 byte data. +The MQTT payload will be set on first to bytes and DATA2 will be set on the second two bytes if the corresponding DevControlCmdType supports 4 byte data. So as example sending any payload on inverter/devcontrol/0/1 will switch off the inverter. - + ## Active Power Limit via REST API It is also implemented to set the power limit via REST API call. Therefore send a POST request to the endpoint /api. The response will always be a json with {success:true} @@ -76,7 +76,7 @@ The payload shall be a json formated string in the following manner } ``` With the following value ranges - + | Value | range | note | | --------------------------- | ----------- | ------------------------------- | @@ -84,7 +84,7 @@ With the following value ranges | | [0...255] | integer uint8, subcmds eg. 0x0b | | | [0...65535] | uint16 | | | [0...3] | integer uint8 | - + Example to set the active power limit non persistent to 10% ```json { @@ -105,23 +105,23 @@ Example to set the active power limit persistent to 600Watt "payload2": 256 } ``` - + ### Developer Information REST API -In the same approach as for MQTT any other SubCmd can be applied and the respsine payload can be observed in the serial logs. Eg. request the Alarm Data. +In the same approach as for MQTT any other SubCmd can be applied and the response payload can be observed in the serial logs. Eg. request the Alarm Data. + - ## Issues and Debuging for active power limit settings -Turn on the serial debuging in the setup. Try to have find out if the behavior is deterministic. That means can you reproduce the behavior. Be patient and wait on inverter reactions at least some minutes and beware that the DC-Power is sufficient. +Turn on the serial debugging in the setup. Try to have find out if the behavior is deterministic. That means can you reproduce the behavior. Be patient and wait on inverter reactions at least some minutes and beware that the DC-Power is sufficient. In case of issues please report: 1. Version of firmware 2. The output of the serial debug esp. the TX messages starting with "0x51" and the RX messages starting with "0xD1" or "0xF1" 3. Which case you have tried: Setup-Page, MQTT, REST API and at what was shown on the "Visualization Page" at the Location "Limit" -4. The setting means payload, relativ, absolut, persisten, not persisten (see tables above) +4. The setting means payload, relative, absolute, persistent, not persistent (see tables above) + - **Developer Information General for Active Power Limit** ⚡To be verified by field tests and feedback -Internally this values will be seted for the second two bytes for MainCmd: 0x51 SubCmd: 0x0b --> DevControl set ActivePowerLimit +Internally this values will be set for the second two bytes for MainCmd: 0x51 SubCmd: 0x0b --> DevControl set ActivePowerLimit ```C typedef enum { // ToDo: to be verified by field tests AbsolutNonPersistent = 0x0000, // 0 @@ -129,4 +129,4 @@ typedef enum { // ToDo: to be verified by field tests AbsolutPersistent = 0x0100, // 256 RelativPersistent = 0x0101 // 257 } PowerLimitControlType; -``` \ No newline at end of file +``` diff --git a/tools/esp8266/app.cpp b/tools/esp8266/app.cpp index 7127b7c1..a657f875 100644 --- a/tools/esp8266/app.cpp +++ b/tools/esp8266/app.cpp @@ -84,6 +84,29 @@ void app::loop(void) { Inverter<> *iv = mSys->findInverter(&p->packet[1]); if(NULL != iv && p->packet[0] == (TX_REQ_INFO + 0x80)) { // response from get information command DPRINTLN(DBG_DEBUG, F("Response from info request received")); + uint8_t *pid = &p->packet[9]; + if (*pid == 0x00) + { + DPRINT(DBG_DEBUG, "fragment number zero received and ignored"); + } + else + { + if ((*pid & 0x7F) < 5) + { + memcpy(mPayload[iv->id].data[(*pid & 0x7F) - 1], &p->packet[10], len - 11); + mPayload[iv->id].len[(*pid & 0x7F) - 1] = len - 11; + } + + if ((*pid & 0x80) == 0x80) + { // Last packet + if ((*pid & 0x7f) > mPayload[iv->id].maxPackId) + { + mPayload[iv->id].maxPackId = (*pid & 0x7f); + if (*pid > 0x81) + mLastPacketId = *pid; + } + } + } switch (mSys->InfoCmd){ case InverterDevInform_Simple: { @@ -94,7 +117,6 @@ void app::loop(void) { case InverterDevInform_All: { DPRINT(DBG_INFO, "Response from inform all\n"); - mSys->InfoCmd = RealTimeRunData_Debug; // Set back to default break; } case GetLossRate: @@ -117,23 +139,6 @@ void app::loop(void) { } case RealTimeRunData_Debug: { - uint8_t *pid = &p->packet[9]; - if (*pid == 0x00) { - DPRINT(DBG_DEBUG, "fragment number zero received and ignored"); - } else { - if((*pid & 0x7F) < 5) { - memcpy(mPayload[iv->id].data[(*pid & 0x7F) - 1], &p->packet[10], len-11); - mPayload[iv->id].len[(*pid & 0x7F) - 1] = len-11; - } - - if((*pid & 0x80) == 0x80) { // Last packet - if((*pid & 0x7f) > mPayload[iv->id].maxPackId) { - mPayload[iv->id].maxPackId = (*pid & 0x7f); - if(*pid > 0x81) - mLastPacketId = *pid; - } - } - } break; } } @@ -175,7 +180,7 @@ void app::loop(void) { if(rxRdy) { - processPayload(true); + processPayload(true,mSys->InfoCmd); } } @@ -261,7 +266,7 @@ void app::loop(void) { if(NULL != iv) { if(!mPayload[iv->id].complete) - processPayload(false); + processPayload(false,mSys->InfoCmd); if(!mPayload[iv->id].complete) { mRxFailed++; @@ -271,13 +276,7 @@ void app::loop(void) { } } - // reset payload data - memset(mPayload[iv->id].len, 0, MAX_PAYLOAD_ENTRIES); - mPayload[iv->id].retransmits = 0; - mPayload[iv->id].maxPackId = 0; - mPayload[iv->id].complete = false; - mPayload[iv->id].requested = true; - mPayload[iv->id].ts = mTimestamp; + resetPayload(iv); yield(); if(mConfig.serialDebug) @@ -335,6 +334,9 @@ bool app::buildPayload(uint8_t id) { //----------------------------------------------------------------------------- void app::processPayload(bool retransmit) { + processPayload(retransmit, RealTimeRunData_Debug); +} +void app::processPayload(bool retransmit, uint8_t cmd = RealTimeRunData_Debug) { // cmd value decides which parser is used to decode payload #ifdef __MQTT_AFTER_RX__ boolean doMQTT = false; @@ -390,12 +392,14 @@ void app::processPayload(bool retransmit) { mSys->Radio.dumpBuf(NULL, payload, offs); } mRxSuccess++; + mSys->InfoCmd = RealTimeRunData_Debug; // On success set back to default + iv->getAssignment(cmd); // choose the parser for(uint8_t i = 0; i < iv->listLen; i++) { - iv->addValue(i, payload); + iv->addValue(i, payload,cmd); // cmd value decides which parser is used to decode payload yield(); } - iv->doCalculations(); + iv->doCalculations(cmd); // cmd value decides which parser is used to decode payload #ifdef __MQTT_AFTER_RX__ doMQTT = true; @@ -432,7 +436,6 @@ void app::cbMqtt(char* topic, byte* payload, unsigned int length) { if (std::strcmp(token,"devcontrol")==0){ token = strtok(NULL, "/"); uint8_t iv_id = std::stoi(token); - uint8_t powerLimitControl = 0; if (iv_id >= 0 && iv_id <= MAX_NUM_INVERTERS){ Inverter<> *iv = this->mSys->getInverterByPos(iv_id); if(NULL != iv) { @@ -442,24 +445,22 @@ void app::cbMqtt(char* topic, byte* payload, unsigned int length) { case ActivePowerContr: // Active Power Control token = strtok(NULL, "/"); // get ControlMode aka "PowerPF.Desc" in DTU-Pro Code from topic string if (token == NULL) // default via mqtt ommit the LimitControlMode - powerLimitControl = AbsolutNonPersistent; + iv->powerLimit[1] = AbsolutNonPersistent; else - powerLimitControl = std::stoi(token); - // 0x0001 -> relativ limit in percent - // 0x0000 -> absolut limit in Watt - // 0x0101 -> persisten limit in percent (?) - // ... - if (true){ // if (std::stoi((char*)payload) > 0) error handling powerlimit needed? - iv->devControlCmd = ActivePowerContr; - iv->powerLimit[0] = std::stoi((char*)payload); - if (powerLimitControl >= AbsolutNonPersistent && powerLimitControl <= RelativNonPersistent) - iv->powerLimit[1] = powerLimitControl; - if (iv->powerLimit[1] & 0x0001) - DPRINTLN(DBG_INFO, F("Power limit for inverter ") + String(iv->id) + F(" set to ") + String(iv->powerLimit[0]) + F("%") ); - else - DPRINTLN(DBG_INFO, F("Power limit for inverter ") + String(iv->id) + F(" set to ") + String(iv->powerLimit[0]) + F("W") ); + iv->powerLimit[1] = std::stoi(token); + if (length<=5){ // if (std::stoi((char*)payload) > 0) more error handling powerlimit needed? + if (iv->powerLimit[1] >= AbsolutNonPersistent && iv->powerLimit[1] <= RelativPersistent){ + iv->devControlCmd = ActivePowerContr; + iv->powerLimit[0] = std::stoi(std::string((char*)payload, (unsigned int)length)); // THX to @silversurfer + if (iv->powerLimit[1] & 0x0001) + DPRINTLN(DBG_INFO, F("Power limit for inverter ") + String(iv->id) + F(" set to ") + String(iv->powerLimit[0]) + F("%") ); + else + DPRINTLN(DBG_INFO, F("Power limit for inverter ") + String(iv->id) + F(" set to ") + String(iv->powerLimit[0]) + F("W") ); + } + iv->devControlRequest = true; + } else { + DPRINTLN(DBG_INFO, F("Invalid mqtt payload recevied: ") + String((char*)payload)); } - iv->devControlRequest = true; break; case TurnOn: // Turn On iv->devControlCmd = TurnOn; @@ -518,7 +519,7 @@ String app::getStatistics(void) { iv = mSys->getInverterByPos(i); if(NULL != iv) { bool avail = true; - content += F("Inverter '") + String(iv->name) + F("' is "); + content += F("Inverter '") + String(iv->name) + F(" (FW-Version: ") + String(iv->fwVersion) +F(")") + F("' is "); if(!iv->isAvailable(mTimestamp)) { content += F("not "); avail = false; @@ -937,3 +938,15 @@ void app::setupMqtt(void) { } } } + +//----------------------------------------------------------------------------- +void app::resetPayload(Inverter<>* iv) +{ + // reset payload data + memset(mPayload[iv->id].len, 0, MAX_PAYLOAD_ENTRIES); + mPayload[iv->id].retransmits = 0; + mPayload[iv->id].maxPackId = 0; + mPayload[iv->id].complete = false; + mPayload[iv->id].requested = true; + mPayload[iv->id].ts = mTimestamp; +} \ No newline at end of file diff --git a/tools/esp8266/app.h b/tools/esp8266/app.h index 25ee205c..00967f76 100644 --- a/tools/esp8266/app.h +++ b/tools/esp8266/app.h @@ -69,6 +69,7 @@ class app { void handleIntr(void); void cbMqtt(char* topic, byte* payload, unsigned int length); void saveValues(void); + void resetPayload(Inverter<>* iv); String getStatistics(void); String getLiveData(void); String getJson(void); @@ -147,9 +148,10 @@ class app { void loadDefaultConfig(void); void loadEEpconfig(void); void setupMqtt(void); - + bool buildPayload(uint8_t id); void processPayload(bool retransmit); + void processPayload(bool retransmit, uint8_t cmd); void sendMqttDiscoveryConfig(void); const char* getFieldDeviceClass(uint8_t fieldId); diff --git a/tools/esp8266/defines.h b/tools/esp8266/defines.h index 59a67c59..339ef89e 100644 --- a/tools/esp8266/defines.h +++ b/tools/esp8266/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 5 -#define VERSION_PATCH 12 +#define VERSION_PATCH 14 //------------------------------------- @@ -58,10 +58,10 @@ typedef enum { } DevControlCmdType; typedef enum { // ToDo: to be verified by field tests - AbsolutNonPersistent = 0x0000, // 0 - RelativNonPersistent = 0x0001, // 1 - AbsolutPersistent = 0x0100, // 256 - RelativPersistent = 0x0101 // 257 + AbsolutNonPersistent = 0UL, // 0x0000 + RelativNonPersistent = 1UL, // 0x0001 + AbsolutPersistent = 256UL, // 0x0100 + RelativPersistent = 257UL // 0x0101 } PowerLimitControlType; // minimum serial interval diff --git a/tools/esp8266/hmDefines.h b/tools/esp8266/hmDefines.h index 1450379b..e69bc071 100644 --- a/tools/esp8266/hmDefines.h +++ b/tools/esp8266/hmDefines.h @@ -17,15 +17,15 @@ union serial_u { // units -enum {UNIT_V = 0, UNIT_A, UNIT_W, UNIT_WH, UNIT_KWH, UNIT_HZ, UNIT_C, UNIT_PCT, UNIT_VA, UNIT_ALARM_MES_ID}; +enum {UNIT_V = 0, UNIT_A, UNIT_W, UNIT_WH, UNIT_KWH, UNIT_HZ, UNIT_C, UNIT_PCT, UNIT_VA, UNIT_NONE}; const char* const units[] = {"V", "A", "W", "Wh", "kWh", "Hz", "°C", "%","VAr",""}; // 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, FLD_EFF, FLD_IRR, FLD_PRA,FLD_ALARM_MES_ID}; + FLD_UAC, FLD_IAC, FLD_PAC, FLD_F, FLD_T, FLD_PCT, FLD_EFF, FLD_IRR, FLD_PRA,FLD_ALARM_MES_ID,FLD_FW_VERSION,FLD_FW_BUILD_YEAR,FLD_FW_BUILD_MONTH_DAY,FLD_HW_ID}; const char* const fields[] = {"U_DC", "I_DC", "P_DC", "YieldDay", "YieldWeek", "YieldTotal", - "U_AC", "I_AC", "P_AC", "Freq", "Temp", "Pct", "Efficiency", "Irradiation","P_ACr","ALARM_MES_ID"}; + "U_AC", "I_AC", "P_AC", "Freq", "Temp", "Pct", "Efficiency", "Irradiation","P_ACr","ALARM_MES_ID","FWVersion","FWBuildYear","FWBuildMonthDay","HWPartId"}; // 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}; @@ -81,6 +81,19 @@ typedef struct { * (complete payload in buffer) * */ +//------------------------------------- +// HM-Series +//------------------------------------- +const byteAssign_t InfoAssignment[] = { + { FLD_FW_VERSION, UNIT_NONE, CH0, 0, 2, 1 }, + { FLD_FW_BUILD_YEAR, UNIT_NONE, CH0, 2, 2, 1 }, + { FLD_FW_BUILD_MONTH_DAY, UNIT_NONE, CH0, 4, 2, 1 }, + { FLD_HW_ID, UNIT_NONE, CH0, 8, 2, 1 } +}; +#define HMINFO_LIST_LEN (sizeof(InfoAssignment) / sizeof(byteAssign_t)) + + + //------------------------------------- // HM300, HM350, HM400 //------------------------------------- @@ -98,7 +111,7 @@ const byteAssign_t hm1chAssignment[] = { { FLD_PRA, UNIT_VA, CH0, 20, 2, 10 }, { FLD_F, UNIT_HZ, CH0, 16, 2, 100 }, { FLD_T, UNIT_C, CH0, 26, 2, 10 }, - { FLD_ALARM_MES_ID, UNIT_ALARM_MES_ID, CH0, 28, 2, 1 }, + { FLD_ALARM_MES_ID, UNIT_NONE, CH0, 28, 2, 1 }, { FLD_PDC, UNIT_W, CH0, CALC_PDC_CH0, 0, CMD_CALC }, { FLD_EFF, UNIT_PCT, CH0, CALC_EFF_CH0, 0, CMD_CALC } }; @@ -129,7 +142,7 @@ const byteAssign_t hm2chAssignment[] = { { FLD_PRA, UNIT_VA, CH0, 32, 2, 10 }, { FLD_F, UNIT_HZ, CH0, 28, 2, 100 }, { FLD_T, UNIT_C, CH0, 38, 2, 10 }, - { FLD_ALARM_MES_ID, UNIT_ALARM_MES_ID, CH0, 40, 2, 1 }, + { FLD_ALARM_MES_ID, UNIT_NONE, CH0, 40, 2, 1 }, { 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 }, @@ -178,7 +191,7 @@ const byteAssign_t hm4chAssignment[] = { { FLD_F, UNIT_HZ, CH0, 48, 2, 100 }, { FLD_PCT, UNIT_PCT, CH0, 56, 2, 10 }, { FLD_T, UNIT_C, CH0, 58, 2, 10 }, - { FLD_ALARM_MES_ID, UNIT_ALARM_MES_ID, CH0, 60, 2, 1 }, + { FLD_ALARM_MES_ID, UNIT_NONE, CH0, 60, 2, 1 }, { 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 }, diff --git a/tools/esp8266/hmInverter.h b/tools/esp8266/hmInverter.h index 321dec50..3b443873 100644 --- a/tools/esp8266/hmInverter.h +++ b/tools/esp8266/hmInverter.h @@ -70,6 +70,7 @@ class Inverter { 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 uint8_t devControlCmd; // carries the requested cmd bool devControlRequest; // true if change needed @@ -89,6 +90,7 @@ class Inverter { devControlRequest = false; devControlCmd = 0xff; initialized = false; + fwVersion = 0; } ~Inverter() { @@ -131,7 +133,7 @@ class Inverter { return assign[pos].ch; } - void addValue(uint8_t pos, uint8_t buf[]) { + void addValue(uint8_t pos, uint8_t buf[],uint8_t cmd) { DPRINTLN(DBG_VERBOSE, F("hmInverter.h:addValue")); uint8_t ptr = assign[pos].start; uint8_t end = ptr + assign[pos].num; @@ -145,9 +147,18 @@ class Inverter { record[pos] = (RECORDTYPE)(val) / (RECORDTYPE)(div); } - // get last alarm message index and save it in the inverter instance - if (getPosByChFld(0, FLD_ALARM_MES_ID) == pos){ - alarmMesIndex = record[pos]; + if (cmd == RealTimeRunData_Debug) { + // get last alarm message index and save it in the inverter object + if (getPosByChFld(0, FLD_ALARM_MES_ID) == pos){ + alarmMesIndex = 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)); + } } } @@ -156,13 +167,16 @@ class Inverter { return record[pos]; } - void doCalculations(void) { + void doCalculations(uint8_t cmd=RealTimeRunData_Debug) { DPRINTLN(DBG_VERBOSE, F("hmInverter.h:doCalculations")); - for(uint8_t i = 0; i < listLen; i++) { - if(CMD_CALC == assign[i].div) { - record[i] = calcFunctions[assign[i].start].func(this, assign[i].num); + getAssignment(cmd); + if (cmd == RealTimeRunData_Debug){ + for(uint8_t i = 0; i < listLen; i++) { + if(CMD_CALC == assign[i].div) { + record[i] = calcFunctions[assign[i].start].func(this, assign[i].num); + } + yield(); } - yield(); } } @@ -185,6 +199,36 @@ class Inverter { return ts; } + void getAssignment(uint8_t cmd=RealTimeRunData_Debug) { + DPRINTLN(DBG_VERBOSE, F("hmInverter.h:getAssignment")); + if(cmd == RealTimeRunData_Debug){ + 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; + } + } + if(cmd == InverterDevInform_All){ + listLen = (uint8_t)(HMINFO_LIST_LEN); + assign = (byteAssign_t*)InfoAssignment; + } + } + private: void toRadioId(void) { DPRINTLN(DBG_VERBOSE, F("hmInverter.h:toRadioId")); @@ -195,30 +239,6 @@ class Inverter { radioId.b[1] = serial.b[3]; radioId.b[0] = 0x01; } - - void getAssignment(void) { - DPRINTLN(DBG_VERBOSE, F("hmInverter.h:getAssignment")); - 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; - } - } }; diff --git a/tools/esp8266/hmRadio.h b/tools/esp8266/hmRadio.h index 872590b5..7decd2c2 100644 --- a/tools/esp8266/hmRadio.h +++ b/tools/esp8266/hmRadio.h @@ -170,20 +170,10 @@ class HmRadio { mTxBuf[10] = cmd; // cmd --> 0x0b => Type_ActivePowerContr, 0 on, 1 off, 2 restart, 12 reactive power, 13 power factor mTxBuf[10 + (++cnt)] = 0x00; if (cmd >= ActivePowerContr && cmd <= PFSet){ - // 4 bytes control data - // Power Limit fix point 10 eg. 30 W --> 0d300 = 0x012c - // -1 = 0xffff --> no limit - uint16_t powerLimit = data[0]; - uint16_t powerLimitSetting = data[1]; - if (powerLimit == 0xffff){ - powerLimit &= 0xffff; // ToDo: unlimit value is needed and is inverter specific! --> get it via RF from inverter or via user interface - } else { - powerLimit *= 10; // will overwrite the data bc it is a pointer - } - mTxBuf[10 + (++cnt)] = (powerLimit >> 8) & 0xff; // power limit - mTxBuf[10 + (++cnt)] = (powerLimit ) & 0xff; // power limit - mTxBuf[10 + (++cnt)] = (powerLimitSetting >> 8) & 0xff; // setting for persistens handling - mTxBuf[10 + (++cnt)] = (powerLimitSetting ) & 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 } // crc control data uint16_t crc = Hoymiles::crc16(&mTxBuf[10], cnt+1); diff --git a/tools/esp8266/html/h/setup_html.h b/tools/esp8266/html/h/setup_html.h index 69dbcd96..c114fdfc 100644 --- a/tools/esp8266/html/h/setup_html.h +++ b/tools/esp8266/html/h/setup_html.h @@ -1,4 +1,4 @@ #ifndef __SETUP_HTML_H__ #define __SETUP_HTML_H__ -const char setup_html[] PROGMEM = "Setup - {DEVICE}

Setup

ERASE SETTINGS (not WiFi)

Device Host Name

WiFi

Enter the credentials to your prefered WiFi station. After rebooting the device tries to connect with this information.

Inverter{INVERTERS}

General

NTP Server
MQTT
System Config

Pinout (Wemos)

{PINOUT}

Radio (NRF24L01+)

Serial Console



 

"; +const char setup_html[] PROGMEM = "Setup - {DEVICE}

Setup

ERASE SETTINGS (not WiFi)

Device Host Name

WiFi

Enter the credentials to your prefered WiFi station. After rebooting the device tries to connect with this information.

Inverter{INVERTERS}

General

NTP Server
MQTT
System Config

Pinout (Wemos)

{PINOUT}

Radio (NRF24L01+)

Serial Console



 

"; #endif /*__SETUP_HTML_H__*/ diff --git a/tools/esp8266/html/setup.html b/tools/esp8266/html/setup.html index 72bf2f00..3a970d5e 100644 --- a/tools/esp8266/html/setup.html +++ b/tools/esp8266/html/setup.html @@ -109,8 +109,6 @@ - - diff --git a/tools/esp8266/web.cpp b/tools/esp8266/web.cpp index da229f3f..77339653 100644 --- a/tools/esp8266/web.cpp +++ b/tools/esp8266/web.cpp @@ -189,7 +189,7 @@ void web::showSetup(void) { inv += F(""); inv += F("