Merge branch 'development03' into zero-export

This commit is contained in:
lumapu 2024-03-02 01:32:51 +01:00
commit 053a2e0079
22 changed files with 190 additions and 121 deletions

View file

@ -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<const char*>(mTmpBuf), mTmpSize);
JsonObject obj = json.as<JsonObject>();
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<const char*>(mTmpBuf), mTmpSize);
if(!json.is<JsonObject>())
root[F("error")] = F(DESER_FAILED);
else {
JsonObject obj = json.as<JsonObject>();
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;
};

View file

@ -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

View file

@ -10,15 +10,15 @@
<a id="nav11" class="acitve" href="/history?v={#VERSION}">{#NAV_HISTORY}</a>
<a id="nav4" class="hide" href="/serial?v={#VERSION}">{#NAV_WEBSERIAL}</a>
<a id="nav5" class="hide" href="/setup?v={#VERSION}">{#NAV_SETTINGS}</a>
<span class="seperator"></span>
<span class="separator"></span>
<a id="nav6" class="hide" href="/update?v={#VERSION}">Update</a>
<a id="nav7" class="hide" href="/system?v={#VERSION}">System</a>
<span class="seperator"></span>
<span class="separator"></span>
<a id="nav8" href="/api" target="_blank">REST API</a>
<a id="nav9" href="https://ahoydtu.de" target="_blank">{#NAV_DOCUMENTATION}</a>
<a id="nav10" href="/about?v={#VERSION}">{#NAV_ABOUT}</a>
<a id="nav12" href="#" class="hide" target="_blank">Custom Link</a>
<span class="seperator"></span>
<span class="separator"></span>
<a id="nav0" class="hide" href="/login">Login</a>
<a id="nav1" class="hide" href="/logout">Logout</a>
</div>

View file

@ -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);

View file

@ -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}");
}
}
});

View file

@ -157,10 +157,6 @@
<div class="col-8">{#INV_READ_GRID_PROFILE}</div>
<div class="col-4"><input type="checkbox" name="rdGrid"/></div>
</div>
<div class="row mb-3">
<div class="col-8">{#INV_YIELD_EFF}</div>
<div class="col-4"><input type="number" name="yldEff" step="any"/></div>
</div>
</fieldset>
</div>
@ -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;

View file

@ -139,7 +139,7 @@ svg.icon {
background-color: var(--nav-active);
}
span.seperator {
span.separator {
width: 100%;
height: 1px;
margin: 5px 0 5px;

View file

@ -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&uuml;cksetzen ('Kommunikation w&auml;hrend der Nacht pausieren' muss gesetzt sein)"
"en": "Reset values and YieldDay at midnight",
"de": "Werte und Gesamtertrag um Mitternacht zur&uuml;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",

View file

@ -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;} },