diff --git a/.github/workflows/compile_development.yml b/.github/workflows/compile_development.yml index c15bd883..7f539871 100644 --- a/.github/workflows/compile_development.yml +++ b/.github/workflows/compile_development.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v4 build-en: - name: Build Environments (English) + name: Build (EN) needs: check runs-on: ubuntu-latest continue-on-error: true @@ -77,7 +77,7 @@ jobs: path: firmware/* build-de: - name: Build Environments (German) + name: Build (DE) needs: check runs-on: ubuntu-latest continue-on-error: true @@ -138,7 +138,7 @@ jobs: path: firmware/* deploy: - name: Deploy Environments + name: Update Artifacts / Deploy needs: [build-en, build-de] runs-on: ubuntu-latest continue-on-error: false @@ -164,9 +164,35 @@ jobs: env: VERSION: ${{ steps.version_name.outputs.name }} + + - name: Create ESP Web Tools Manifest + working-directory: src + run: python ../scripts/buildManifest.py + + - name: Copy install html + run: mv scripts/gh-action-dev-build-flash.html firmware/install.html + + - name: Copy Changes.md + run: mv src/CHANGES.md firmware/CHANGES.md + + - name: Rename firmware directory run: mv firmware ${{ steps.version_name.outputs.name }} + - name: delete environment Artifacts + uses: geekyeggo/delete-artifact@v4 + with: + name: dev-* + + - name: Create Artifact + uses: actions/upload-artifact@v4 + with: + name: dev-${{ steps.version_name.outputs.name }} + path: | + ${{ steps.version_name.outputs.name }}/* + manual/User_Manual.md + manual/Getting_Started.md + - name: Deploy uses: nogsantos/scp-deploy@master with: diff --git a/scripts/buildManifest.py b/scripts/buildManifest.py index 2664a39f..b91145cd 100644 --- a/scripts/buildManifest.py +++ b/scripts/buildManifest.py @@ -36,9 +36,27 @@ def buildManifest(path, infile, outfile): esp32["parts"].append({"path": "ESP32/bootloader.bin", "offset": 4096}) esp32["parts"].append({"path": "ESP32/partitions.bin", "offset": 32768}) esp32["parts"].append({"path": "ESP32/ota.bin", "offset": 57344}) - esp32["parts"].append({"path": "ESP32/" + version[1] + "_" + sha + "_esp32.bin", "offset": 65536}) + esp32["parts"].append({"path": "ESP32/" + version[1] + "_" + sha + "_esp32-wroom32.bin", "offset": 65536}) data["builds"].append(esp32) + esp32s2 = {} + esp32s2["chipFamily"] = "ESP32-S2" + esp32s2["parts"] = [] + esp32s2["parts"].append({"path": "ESP32-S2/bootloader.bin", "offset": 4096}) + esp32s2["parts"].append({"path": "ESP32-S2/partitions.bin", "offset": 32768}) + esp32s2["parts"].append({"path": "ESP32-S2/ota.bin", "offset": 57344}) + esp32s2["parts"].append({"path": "ESP32-S2/" + version[1] + "_" + sha + "_esp32-s2-mini.bin", "offset": 65536}) + data["builds"].append(esp32s2) + + esp32s3 = {} + esp32s3["chipFamily"] = "ESP32-S3" + esp32s3["parts"] = [] + esp32s3["parts"].append({"path": "ESP32/bootloader.bin", "offset": 4096}) + esp32s3["parts"].append({"path": "ESP32/partitions.bin", "offset": 32768}) + esp32s3["parts"].append({"path": "ESP32/ota.bin", "offset": 57344}) + esp32s3["parts"].append({"path": "ESP32-S3/" + version[1] + "_" + sha + "_opendtufusion.bin", "offset": 65536}) + data["builds"].append(esp32s3) + esp8266 = {} esp8266["chipFamily"] = "ESP8266" esp8266["parts"] = [] @@ -47,7 +65,7 @@ def buildManifest(path, infile, outfile): jsonString = json.dumps(data, indent=2) - fp = open(path + "firmware/" + outfile, "w") + fp = open(path + "../firmware/" + outfile, "w") fp.write(jsonString) fp.close() diff --git a/src/CHANGES.md b/src/CHANGES.md index 003c8cef..f5aa9cd9 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,24 @@ # Development Changes +## 0.8.89 - 2024-03-02 +* merge PR: Collection of small fixes #1465 +* fix: show esp type on `/history` #1463 +* improved HMS-400-1T support (serial number 1125...) #1460 + +## 0.8.88 - 2024-02-28 +* fix MqTT statistic data overflow #1458 +* add HMS-400-1T support (serial number 1125...) #1460 +* removed `yield efficiency` because the inverter already calculates correct #1243 +* merge PR: Remove hint to INV_RESET_MIDNIGHT resp. INV_PAUSE_DURING_NIGHT #1431 + +## 0.8.87 - 2024-02-25 +* fix translations #1455 #1442 + +## 0.8.86 - 2024-02-23 +* RestAPI check for parent element to be JsonObject #1449 +* fix translation #1448 #1442 +* fix reset values when inverter status is 'not available' #1035 #1437 + ## 0.8.85 - 2024-02-22 * possible fix of MqTT fix "total values are sent to often" #1421 * fix translation #1442 @@ -251,7 +270,7 @@ ## 0.8.39 - 2024-01-01 * fix MqTT dis_night_comm in the morning #1309 #1286 -* seperated offset for sunrise and sunset #1308 +* separated offset for sunrise and sunset #1308 * powerlimit (active power control) now has one decimal place (MqTT / API) #1199 * merge Prometheus metrics fix #1310 * merge MI grid profile request #1306 @@ -464,7 +483,7 @@ ## 0.7.61 - 2023-10-01 * merged `hmPayload` and `hmsPayload` into single class * merged generic radio functions into new parent class `radio.h` -* moved radio statistics into the inverter - each inverter has now seperate statistics which can be accessed by click on the footer in `/live` +* moved radio statistics into the inverter - each inverter has now separate statistics which can be accessed by click on the footer in `/live` * fix compiler warnings #1191 * fix ePaper logo during night time #1151 diff --git a/src/app.cpp b/src/app.cpp index d60c62e5..a3d93bb1 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -484,7 +484,7 @@ void app:: zeroIvValues(bool checkAvail, bool skipYieldDay) { continue; // skip to next inverter if (checkAvail) { - if (!iv->isAvailable()) + if (iv->isAvailable()) continue; } diff --git a/src/config/settings.h b/src/config/settings.h index f4618603..55d7031b 100644 --- a/src/config/settings.h +++ b/src/config/settings.h @@ -170,7 +170,7 @@ typedef struct { } cfgIv_t; typedef struct { - bool enabled; +// bool enabled; cfgIv_t iv[MAX_NUM_INVERTERS]; uint16_t sendInterval; @@ -179,7 +179,6 @@ typedef struct { bool rstValsCommStop; bool rstMaxValsMidNight; bool startWithoutTime; - float yieldEffiency; bool readGrid; } cfgInst_t; @@ -495,7 +494,6 @@ class settings { mCfg.inst.rstValsCommStop = false; mCfg.inst.startWithoutTime = false; mCfg.inst.rstMaxValsMidNight = false; - mCfg.inst.yieldEffiency = 1.0f; mCfg.inst.readGrid = true; for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) { @@ -840,30 +838,23 @@ class settings { void jsonInst(JsonObject obj, bool set = false) { if(set) { obj[F("intvl")] = mCfg.inst.sendInterval; - obj[F("en")] = (bool)mCfg.inst.enabled; +// obj[F("en")] = (bool)mCfg.inst.enabled; obj[F("rstMidNight")] = (bool)mCfg.inst.rstYieldMidNight; obj[F("rstNotAvail")] = (bool)mCfg.inst.rstValsNotAvail; obj[F("rstComStop")] = (bool)mCfg.inst.rstValsCommStop; obj[F("strtWthtTime")] = (bool)mCfg.inst.startWithoutTime; obj[F("rstMaxMidNight")] = (bool)mCfg.inst.rstMaxValsMidNight; - obj[F("yldEff")] = mCfg.inst.yieldEffiency; obj[F("rdGrid")] = (bool)mCfg.inst.readGrid; } else { getVal(obj, F("intvl"), &mCfg.inst.sendInterval); - getVal(obj, F("en"), &mCfg.inst.enabled); +// getVal(obj, F("en"), &mCfg.inst.enabled); getVal(obj, F("rstMidNight"), &mCfg.inst.rstYieldMidNight); getVal(obj, F("rstNotAvail"), &mCfg.inst.rstValsNotAvail); getVal(obj, F("rstComStop"), &mCfg.inst.rstValsCommStop); getVal(obj, F("strtWthtTime"), &mCfg.inst.startWithoutTime); getVal(obj, F("rstMaxMidNight"), &mCfg.inst.rstMaxValsMidNight); - getVal(obj, F("yldEff"), &mCfg.inst.yieldEffiency); getVal(obj, F("rdGrid"), &mCfg.inst.readGrid); - - if(mCfg.inst.yieldEffiency < 0.5) - mCfg.inst.yieldEffiency = 1.0f; - else if(mCfg.inst.yieldEffiency > 1.0f) - mCfg.inst.yieldEffiency = 1.0f; } JsonArray ivArr; diff --git a/src/defines.h b/src/defines.h index 0eb203f5..48b2daba 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 85 +#define VERSION_PATCH 89 //------------------------------------- typedef struct { @@ -112,7 +112,7 @@ enum { typedef struct { uint32_t rxFail; - uint32_t rxFailNoAnser; + uint32_t rxFailNoAnswer; uint32_t rxSuccess; uint32_t frmCnt; uint32_t txCnt; diff --git a/src/hm/Communication.h b/src/hm/Communication.h index 8c7fbe6d..5fd3b487 100644 --- a/src/hm/Communication.h +++ b/src/hm/Communication.h @@ -117,7 +117,7 @@ class Communication : public CommQueue<> { //q->iv->radioStatistics.txCnt++; q->iv->radio->mRadioWaitTime.startTimeMonitor(mTimeout); - if(!mIsRetransmit && (q->cmd == AlarmData) || (q->cmd == GridOnProFilePara)) + if((!mIsRetransmit && (q->cmd == AlarmData)) || (q->cmd == GridOnProFilePara)) incrAttempt((q->cmd == AlarmData)? MORE_ATTEMPS_ALARMDATA : MORE_ATTEMPS_GRIDONPROFILEPARA); mIsRetransmit = false; @@ -622,7 +622,7 @@ class Communication : public CommQueue<> { else if(q->iv->mGotFragment || mCompleteRetry) q->iv->radioStatistics.rxFail++; // got no complete payload else - q->iv->radioStatistics.rxFailNoAnser++; // got nothing + q->iv->radioStatistics.rxFailNoAnswer++; // got nothing mWaitTime.startTimeMonitor(1); // maybe remove, side effects unknown bool keep = false; diff --git a/src/hm/Heuristic.h b/src/hm/Heuristic.h index cc42df4f..1220692e 100644 --- a/src/hm/Heuristic.h +++ b/src/hm/Heuristic.h @@ -153,7 +153,7 @@ class Heuristic { DBGPRINT(F(", f: ")); DBGPRINT(String(iv->radioStatistics.rxFail)); DBGPRINT(F(", n: ")); - DBGPRINT(String(iv->radioStatistics.rxFailNoAnser)); + DBGPRINT(String(iv->radioStatistics.rxFailNoAnswer)); DBGPRINT(F(" | p: ")); // better debugging for helpers... if((IV_HMS == iv->ivGen) || (IV_HMT == iv->ivGen)) DBGPRINTLN(String(iv->config->powerLevel-10)); @@ -217,15 +217,12 @@ class Heuristic { } inline uint8_t id2Ch(uint8_t id) { - switch(id) { - case 0: return 3; - case 1: return 23; - case 2: return 40; - case 3: return 61; - case 4: return 75; - } - return 3; // standard + if (id < RF_MAX_CHANNEL_ID) + return mChList[id]; + else + return 3; // standard } + uint8_t mChList[RF_MAX_CHANNEL_ID] = {03, 23, 40, 61, 75}; }; diff --git a/src/hm/hmInverter.h b/src/hm/hmInverter.h index b7fb00a1..4252800d 100644 --- a/src/hm/hmInverter.h +++ b/src/hm/hmInverter.h @@ -288,32 +288,30 @@ class Inverter { uint8_t end = ptr + rec->assign[pos].num; uint16_t div = rec->assign[pos].div; - if(NULL != rec) { - if(CMD_CALC != div) { - uint32_t val = 0; - do { - val <<= 8; - val |= buf[ptr]; - } while(++ptr != end); - - if ((FLD_T == rec->assign[pos].fieldId) || (FLD_Q == rec->assign[pos].fieldId) || (FLD_PF == rec->assign[pos].fieldId)) { - // temperature, Qvar, and power factor are a signed values - rec->record[pos] = ((REC_TYP)((int16_t)val)) / (REC_TYP)(div); - } else if (FLD_YT == rec->assign[pos].fieldId) { - rec->record[pos] = ((REC_TYP)(val) / (REC_TYP)(div) * generalConfig->yieldEffiency) + ((REC_TYP)config->yieldCor[rec->assign[pos].ch-1]); - } else if (FLD_YD == rec->assign[pos].fieldId) { - float actYD = (REC_TYP)(val) / (REC_TYP)(div) * generalConfig->yieldEffiency; - uint8_t idx = rec->assign[pos].ch - 1; - if (mLastYD[idx] > actYD) - mOffYD[idx] += mLastYD[idx]; - mLastYD[idx] = actYD; - rec->record[pos] = mOffYD[idx] + actYD; - } else { - if ((REC_TYP)(div) > 1) - rec->record[pos] = (REC_TYP)(val) / (REC_TYP)(div); - else - rec->record[pos] = (REC_TYP)(val); - } + if(CMD_CALC != div) { + uint32_t val = 0; + do { + val <<= 8; + val |= buf[ptr]; + } while(++ptr != end); + + if ((FLD_T == rec->assign[pos].fieldId) || (FLD_Q == rec->assign[pos].fieldId) || (FLD_PF == rec->assign[pos].fieldId)) { + // temperature, Qvar, and power factor are a signed values + rec->record[pos] = ((REC_TYP)((int16_t)val)) / (REC_TYP)(div); + } else if (FLD_YT == rec->assign[pos].fieldId) { + rec->record[pos] = ((REC_TYP)(val) / (REC_TYP)(div)) + ((REC_TYP)config->yieldCor[rec->assign[pos].ch-1]); + } else if (FLD_YD == rec->assign[pos].fieldId) { + float actYD = (REC_TYP)(val) / (REC_TYP)(div); + uint8_t idx = rec->assign[pos].ch - 1; + if (mLastYD[idx] > actYD) + mOffYD[idx] += mLastYD[idx]; + mLastYD[idx] = actYD; + rec->record[pos] = mOffYD[idx] + actYD; + } else { + if ((REC_TYP)(div) > 1) + rec->record[pos] = (REC_TYP)(val) / (REC_TYP)(div); + else + rec->record[pos] = (REC_TYP)(val); } } diff --git a/src/hm/hmSystem.h b/src/hm/hmSystem.h index 7e79f30a..3b43b9f0 100644 --- a/src/hm/hmSystem.h +++ b/src/hm/hmSystem.h @@ -16,8 +16,8 @@ class HmSystem { HmSystem() {} void setup(uint32_t *timestamp, cfgInst_t *config, IApp *app) { - mInverter[0].timestamp = timestamp; - mInverter[0].generalConfig = config; + INVERTERTYPE::timestamp = timestamp; + INVERTERTYPE::generalConfig = config; //mInverter[0].app = app; } @@ -35,6 +35,8 @@ class HmSystem { case 0x21: iv->type = INV_TYPE_1CH; break; + case 0x25: // HMS-400 - 1 channel but payload like 2ch + case 0x44: // HMS-1000 case 0x42: case 0x41: iv->type = INV_TYPE_2CH; @@ -51,15 +53,14 @@ class HmSystem { } if(iv->config->serial.b[5] == 0x11) { - if((iv->config->serial.b[4] & 0x0f) == 0x04) { + if(((iv->config->serial.b[4] & 0x0f) == 0x04) || ((iv->config->serial.b[4] & 0x0f) == 0x05)) { iv->ivGen = IV_HMS; iv->ivRadioType = INV_RADIO_TYPE_CMT; } else { iv->ivGen = IV_HM; iv->ivRadioType = INV_RADIO_TYPE_NRF; } - } - else if((iv->config->serial.b[4] & 0x03) == 0x02) { // MI 3rd Gen -> same as HM + } else if((iv->config->serial.b[4] & 0x03) == 0x02) { // MI 3rd Gen -> same as HM iv->ivGen = IV_HM; iv->ivRadioType = INV_RADIO_TYPE_NRF; } else { // MI 2nd Gen @@ -82,7 +83,7 @@ class HmSystem { DPRINT(DBG_INFO, "added inverter "); if(iv->config->serial.b[5] == 0x11) { - if((iv->config->serial.b[4] & 0x0f) == 0x04) + if(((iv->config->serial.b[4] & 0x0f) == 0x04) || ((iv->config->serial.b[4] & 0x0f) == 0x05)) DBGPRINT("HMS"); else DBGPRINT("HM"); diff --git a/src/publisher/pubMqtt.h b/src/publisher/pubMqtt.h index ea6f331e..4b09b649 100644 --- a/src/publisher/pubMqtt.h +++ b/src/publisher/pubMqtt.h @@ -423,7 +423,7 @@ class PubMqtt { } DynamicJsonDocument doc2(512); - constexpr static char* unitTotal[] = {"W", "kWh", "Wh", "W"}; + constexpr static const char* unitTotal[] = {"W", "kWh", "Wh", "W"}; doc2[F("name")] = String(name.data()); doc2[F("stat_t")] = String(mCfgMqtt->topic) + "/" + ((!total) ? String(iv->config->name) : "total" ) + String(topic.data()); doc2[F("unit_of_meas")] = ((!total) ? (iv->getUnit(mDiscovery.sub, rec)) : (unitTotal[mDiscovery.sub])); diff --git a/src/publisher/pubMqttIvData.h b/src/publisher/pubMqttIvData.h index c15c9799..6ddd63a9 100644 --- a/src/publisher/pubMqttIvData.h +++ b/src/publisher/pubMqttIvData.h @@ -222,7 +222,7 @@ class PubMqttIvData { mIv->radioStatistics.txCnt, mIv->radioStatistics.rxSuccess, mIv->radioStatistics.rxFail, - mIv->radioStatistics.rxFailNoAnser, + mIv->radioStatistics.rxFailNoAnswer, mIv->radioStatistics.retransmits, mIv->radioStatistics.ivLoss, mIv->radioStatistics.ivSent, @@ -293,7 +293,7 @@ class PubMqttIvData { bool mRTRDataHasBeenSent = false; std::array mSubTopic; - std::array mVal; + std::array mVal; std::queue *mSendList = nullptr; }; diff --git a/src/utils/scheduler.h b/src/utils/scheduler.h index 16009778..0f7cea7b 100644 --- a/src/utils/scheduler.h +++ b/src/utils/scheduler.h @@ -125,8 +125,8 @@ namespace ah { mTicker[i].timeout = timeout; mTicker[i].reload = reload; mTicker[i].isTimestamp = isTimestamp; - memset(mTicker[i].name, 0, 6); - strncpy(mTicker[i].name, name, (strlen(name) < 6) ? strlen(name) : 5); + strncpy(mTicker[i].name, name, 5); + mTicker[i].name[5]=0; if(mMax == i) mMax = i + 1; return i; diff --git a/src/web/RestApi.h b/src/web/RestApi.h index 12fe6d70..36a7ec61 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -141,7 +141,7 @@ class RestApi { DPRINTLN(DBG_VERBOSE, "onApiPostBody"); if(0 == index) { - if(NULL != mTmpBuf) + if(nullptr != mTmpBuf) delete[] mTmpBuf; mTmpBuf = new uint8_t[total+1]; mTmpSize = total; @@ -154,36 +154,40 @@ class RestApi { DynamicJsonDocument json(1000); - DeserializationError err = deserializeJson(json, reinterpret_cast(mTmpBuf), mTmpSize); - JsonObject obj = json.as(); - AsyncJsonResponse* response = new AsyncJsonResponse(false, 200); JsonObject root = response->getRoot(); - root[F("success")] = (err) ? false : true; - if(!err) { - String path = request->url().substring(5); - if(path == "ctrl") - root[F("success")] = setCtrl(obj, root, request->client()->remoteIP().toString().c_str()); - else if(path == "setup") - root[F("success")] = setSetup(obj, root, request->client()->remoteIP().toString().c_str()); - else { - root[F("success")] = false; - root[F("error")] = F(PATH_NOT_FOUND) + path; - } - } else { - switch (err.code()) { - case DeserializationError::Ok: break; - case DeserializationError::IncompleteInput: root[F("error")] = F(INCOMPLETE_INPUT); break; - case DeserializationError::InvalidInput: root[F("error")] = F(INVALID_INPUT); break; - case DeserializationError::NoMemory: root[F("error")] = F(NOT_ENOUGH_MEM); break; - default: root[F("error")] = F(DESER_FAILED); break; + DeserializationError err = deserializeJson(json, reinterpret_cast(mTmpBuf), mTmpSize); + if(!json.is()) + root[F("error")] = F(DESER_FAILED); + else { + JsonObject obj = json.as(); + + root[F("success")] = (err) ? false : true; + if(!err) { + String path = request->url().substring(5); + if(path == "ctrl") + root[F("success")] = setCtrl(obj, root, request->client()->remoteIP().toString().c_str()); + else if(path == "setup") + root[F("success")] = setSetup(obj, root, request->client()->remoteIP().toString().c_str()); + else { + root[F("success")] = false; + root[F("error")] = F(PATH_NOT_FOUND) + path; + } + } else { + switch (err.code()) { + case DeserializationError::Ok: break; + case DeserializationError::IncompleteInput: root[F("error")] = F(INCOMPLETE_INPUT); break; + case DeserializationError::InvalidInput: root[F("error")] = F(INVALID_INPUT); break; + case DeserializationError::NoMemory: root[F("error")] = F(NOT_ENOUGH_MEM); break; + default: root[F("error")] = F(DESER_FAILED); break; + } } } response->setLength(); request->send(response); delete[] mTmpBuf; - mTmpBuf = NULL; + mTmpBuf = nullptr; } void getNotFound(JsonObject obj, String url) { @@ -422,7 +426,7 @@ class RestApi { obj[F("name")] = String(iv->config->name); obj[F("rx_success")] = iv->radioStatistics.rxSuccess; obj[F("rx_fail")] = iv->radioStatistics.rxFail; - obj[F("rx_fail_answer")] = iv->radioStatistics.rxFailNoAnser; + obj[F("rx_fail_answer")] = iv->radioStatistics.rxFailNoAnswer; obj[F("frame_cnt")] = iv->radioStatistics.frmCnt; obj[F("tx_cnt")] = iv->radioStatistics.txCnt; obj[F("retransmits")] = iv->radioStatistics.retransmits; @@ -480,7 +484,6 @@ class RestApi { obj[F("strtWthtTm")] = (bool)mConfig->inst.startWithoutTime; obj[F("rdGrid")] = (bool)mConfig->inst.readGrid; obj[F("rstMaxMid")] = (bool)mConfig->inst.rstMaxValsMidNight; - obj[F("yldEff")] = mConfig->inst.yieldEffiency; } void getInverter(JsonObject obj, uint8_t id) { @@ -998,7 +1001,7 @@ class RestApi { uint32_t mTimezoneOffset = 0; uint32_t mHeapFree = 0, mHeapFreeBlk = 0; uint8_t mHeapFrag = 0; - uint8_t *mTmpBuf = NULL; + uint8_t *mTmpBuf = nullptr; uint32_t mTmpSize = 0; }; diff --git a/src/web/html/history.html b/src/web/html/history.html index 7e317b59..6372ab82 100644 --- a/src/web/html/history.html +++ b/src/web/html/history.html @@ -80,6 +80,7 @@ function parsePowerHistory(obj){ if (null != obj) { parseNav(obj.generic); + parseESP(obj.generic); parseHistory(obj,"pwr", pwrExeOnce) document.getElementById("pwrLast").innerHTML = mLastValue document.getElementById("pwrMaxDay").innerHTML = obj.maxDay diff --git a/src/web/html/includes/nav.html b/src/web/html/includes/nav.html index 447bf411..bab64829 100644 --- a/src/web/html/includes/nav.html +++ b/src/web/html/includes/nav.html @@ -10,15 +10,15 @@ {#NAV_HISTORY} {#NAV_WEBSERIAL} {#NAV_SETTINGS} - + Update System - + REST API {#NAV_DOCUMENTATION} {#NAV_ABOUT} Custom Link - + Login Logout diff --git a/src/web/html/index.html b/src/web/html/index.html index 2611db5b..954ee012 100644 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -70,9 +70,9 @@ var min = parseInt(up / 60) % 60; var sec = up % 60; var e = document.getElementById("uptime"); - e.innerHTML = days + " Day"; + e.innerHTML = days + " {#DAY}"; if(1 != days) - e.innerHTML += "s"; + e.innerHTML += "{#S}"; e.innerHTML += ", " + ("0"+hrs).substr(-2) + ":" + ("0"+min).substr(-2) + ":" + ("0"+sec).substr(-2); diff --git a/src/web/html/serial.html b/src/web/html/serial.html index ff63772c..835f1766 100644 --- a/src/web/html/serial.html +++ b/src/web/html/serial.html @@ -65,7 +65,7 @@ }); document.getElementById("scroll").addEventListener("click", function() { mAutoScroll = !mAutoScroll; - this.value = (mAutoScroll) ? "autoscroll" : "manual scroll"; + this.value = (mAutoScroll) ? "{#BTN_AUTOSCROLL}" : "{#BTN_MANUALSCROLL}"; }); document.getElementById("copy").addEventListener("click", function() { con.value = version + " - " + build + "\n---------------\n" + con.value; @@ -80,10 +80,10 @@ try { return document.execCommand("copy"); // Security exception may be thrown by some browsers. } catch (ex) { - alert("Copy to clipboard failed" + ex); + alert("{#CLIPBOARD_FAILED} " + ex); } finally { document.body.removeChild(ta); - alert("Copied to clipboard"); + alert("{#COPIED_TO_CLIPBOARD}"); } } }); diff --git a/src/web/html/setup.html b/src/web/html/setup.html index 864e2ff4..18500cf7 100644 --- a/src/web/html/setup.html +++ b/src/web/html/setup.html @@ -157,10 +157,6 @@
{#INV_READ_GRID_PROFILE}
-
-
{#INV_YIELD_EFF}
-
-
@@ -652,7 +648,7 @@ } function ivGlob(obj) { - for(var i of [["invInterval", "interval"], ["yldEff", "yldEff"]]) + for(var i of [["invInterval", "interval"]]) document.getElementsByName(i[0])[0].value = obj[i[1]]; for(var i of ["Mid", "ComStop", "NotAvail", "MaxMid"]) document.getElementsByName("invRst"+i)[0].checked = obj["rst" + i]; @@ -833,7 +829,8 @@ case 0x1000: nrf = true; break; case 0x1100: switch(sn & 0x000f) { - case 0x0004: nrf = false; break; + case 0x0004: + case 0x0005: nrf = false; break; default: nrf = true; break; } break; diff --git a/src/web/html/style.css b/src/web/html/style.css index 880ce759..18f9aeaa 100644 --- a/src/web/html/style.css +++ b/src/web/html/style.css @@ -139,7 +139,7 @@ svg.icon { background-color: var(--nav-active); } -span.seperator { +span.separator { width: 100%; height: 1px; margin: 5px 0 5px; diff --git a/src/web/lang.json b/src/web/lang.json index 727eadcd..67b08b75 100644 --- a/src/web/lang.json +++ b/src/web/lang.json @@ -295,8 +295,8 @@ }, { "token": "INV_RESET_MIDNIGHT", - "en": "Reset values and YieldDay at midnight. ('Pause communication during night' need to be set)", - "de": "Werte und Gesamtertrag um Mitternacht zurücksetzen ('Kommunikation während der Nacht pausieren' muss gesetzt sein)" + "en": "Reset values and YieldDay at midnight", + "de": "Werte und Gesamtertrag um Mitternacht zurücksetzen" }, { "token": "INV_PAUSE_SUNSET", @@ -323,11 +323,6 @@ "en": "Read Grid Profile", "de": "Grid-Profil auslesen" }, - { - "token": "INV_YIELD_EFF", - "en": "Yield Efficiency (default 1.0)", - "de": "Ertragseffizienz (Standard 1.0)" - }, { "token": "NTP_INTERVAL", "en": "NTP Interval (in minutes, min. 5 minutes)", @@ -883,6 +878,11 @@ "en": "autoscroll", "de": "automatisch scrollen" }, + { + "token": "BTN_MANUALSCROLL", + "en": "manual scroll", + "de": "manuell scrollen" + }, { "token": "BTN_COPY", "en": "copy", @@ -897,12 +897,21 @@ "token": "UPTIME", "en": "uptime", "de": "Laufzeit" - } -, + }, { "token": "DAYS", "en": "days", "de": "Tage" + }, + { + "token": "COPIED_TO_CLIPBOARD", + "en": "Copied to clipboard", + "de": "in die Zwischenablage kopiert" + }, + { + "token": "CLIPBOARD_FAILED", + "en": "Copy failed", + "de": "kopieren fehlgeschlagen" } ] }, @@ -979,6 +988,16 @@ "en": "Error", "de": "Fehler" }, + { + "token": "DAY", + "en": "day", + "de": "Tag" + }, + { + "token": "S", + "en": "s", + "de": "e" + }, { "token": "NTP_UNREACH", "en": "NTP timeserver unreachable", diff --git a/src/web/web.h b/src/web/web.h index 2764e219..0425ff53 100644 --- a/src/web/web.h +++ b/src/web/web.h @@ -486,7 +486,6 @@ class Web { mConfig->inst.startWithoutTime = (request->arg("strtWthtTm") == "on"); mConfig->inst.readGrid = (request->arg("rdGrid") == "on"); mConfig->inst.rstMaxValsMidNight = (request->arg("invRstMaxMid") == "on"); - mConfig->inst.yieldEffiency = (request->arg("yldEff")).toFloat(); // pinout @@ -701,7 +700,7 @@ class Web { { "max_power", "gauge", metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->getMaxPower();} }, { "radio_rx_success", "counter" ,metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->radioStatistics.rxSuccess;} }, { "radio_rx_fail", "counter" ,metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->radioStatistics.rxFail;} }, - { "radio_rx_fail_answer", "counter" ,metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->radioStatistics.rxFailNoAnser;} }, + { "radio_rx_fail_answer", "counter" ,metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->radioStatistics.rxFailNoAnswer;} }, { "radio_frame_cnt", "counter" ,metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->radioStatistics.frmCnt;} }, { "radio_tx_cnt", "counter" ,metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->radioStatistics.txCnt;} }, { "radio_retransmits", "counter" ,metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->radioStatistics.retransmits;} },