Browse Source

0.8.81

* fixed authentication with empty token #1415
* added new setting for future function to send log via MqTT
* combined firmware and hardware version to JSON topics (MqTT) #1212
pull/1431/head
lumapu 11 months ago
parent
commit
bd532805a6
  1. 5
      src/CHANGES.md
  2. 9
      src/config/settings.h
  3. 2
      src/defines.h
  4. 59
      src/publisher/pubMqttIvData.h
  5. 2
      src/web/Protection.h
  6. 1
      src/web/RestApi.h
  7. 73
      src/web/html/setup.html
  8. 5
      src/web/lang.json
  9. 1
      src/web/web.h

5
src/CHANGES.md

@ -1,5 +1,10 @@
# Development Changes
## 0.8.81 - 2024-02-13
* fixed authentication with empty token #1415
* added new setting for future function to send log via MqTT
* combined firmware and hardware version to JSON topics (MqTT) #1212
## 0.8.80 - 2024-02-12
* optimize API authentication, Error-Codes #1415
* breaking change: authentication API command changed #1415

9
src/config/settings.h

@ -31,7 +31,7 @@
* https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html#flash-layout
* */
#define CONFIG_VERSION 10
#define CONFIG_VERSION 11
#define PROT_MASK_INDEX 0x0001
@ -120,6 +120,7 @@ typedef struct {
bool debug;
bool privacyLog;
bool printWholeTrace;
bool log2mqtt;
} cfgSerial_t;
typedef struct {
@ -436,6 +437,7 @@ class settings {
mCfg.serial.debug = false;
mCfg.serial.privacyLog = true;
mCfg.serial.printWholeTrace = false;
mCfg.serial.log2mqtt = false;
mCfg.mqtt.port = DEF_MQTT_PORT;
snprintf(mCfg.mqtt.broker, MQTT_ADDR_LEN, "%s", DEF_MQTT_BROKER);
@ -509,6 +511,9 @@ class settings {
mCfg.sys.region = 0; // Europe
mCfg.sys.timezone = 1;
}
if(mCfg.configVersion < 11) {
mCfg.serial.log2mqtt = false;
}
}
}
@ -658,11 +663,13 @@ class settings {
obj[F("debug")] = mCfg.serial.debug;
obj[F("prv")] = (bool) mCfg.serial.privacyLog;
obj[F("trc")] = (bool) mCfg.serial.printWholeTrace;
obj[F("mqtt")] = (bool) mCfg.serial.log2mqtt;
} else {
getVal<bool>(obj, F("show"), &mCfg.serial.showIv);
getVal<bool>(obj, F("debug"), &mCfg.serial.debug);
getVal<bool>(obj, F("prv"), &mCfg.serial.privacyLog);
getVal<bool>(obj, F("trc"), &mCfg.serial.printWholeTrace);
getVal<bool>(obj, F("mqtt"), &mCfg.serial.log2mqtt);
}
}

2
src/defines.h

@ -13,7 +13,7 @@
//-------------------------------------
#define VERSION_MAJOR 0
#define VERSION_MINOR 8
#define VERSION_PATCH 80
#define VERSION_PATCH 81
//-------------------------------------
typedef struct {

59
src/publisher/pubMqttIvData.h

@ -6,6 +6,7 @@
#ifndef __PUB_MQTT_IV_DATA_H__
#define __PUB_MQTT_IV_DATA_H__
#include <array>
#include "../utils/dbg.h"
#include "../hm/hmSystem.h"
#include "pubMqttDefs.h"
@ -107,14 +108,14 @@ class PubMqttIvData {
if(found) {
record_t<> *rec = mIv->getRecordStruct(mCmd);
if(MqttSentStatus::NEW_DATA == rec->mqttSentStatus) {
snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "%s/last_success", mIv->config->name);
snprintf(mVal, 40, "%d", mIv->getLastTs(rec));
mPublish(mSubTopic, mVal, true, QOS_0);
snprintf(mSubTopic.data(), mSubTopic.size(), "%s/last_success", mIv->config->name);
snprintf(mVal.data(), mVal.size(), "%d", mIv->getLastTs(rec));
mPublish(mSubTopic.data(), mVal.data(), true, QOS_0);
if((mIv->ivGen == IV_HMS) || (mIv->ivGen == IV_HMT)) {
snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "%s/ch0/rssi", mIv->config->name);
snprintf(mVal, 40, "%d", mIv->rssi);
mPublish(mSubTopic, mVal, false, QOS_0);
snprintf(mSubTopic.data(), mSubTopic.size(), "%s/ch0/rssi", mIv->config->name);
snprintf(mVal.data(), mVal.size(), "%d", mIv->rssi);
mPublish(mSubTopic.data(), mVal.data(), false, QOS_0);
}
rec->mqttSentStatus = MqttSentStatus::LAST_SUCCESS_SENT;
}
@ -144,7 +145,7 @@ class PubMqttIvData {
if(mPos < rec->length) {
bool retained = false;
if (mCmd == RealTimeRunData_Debug) {
if (RealTimeRunData_Debug == mCmd) {
if((FLD_YT == rec->assign[mPos].fieldId) || (FLD_YD == rec->assign[mPos].fieldId))
retained = true;
@ -176,10 +177,32 @@ class PubMqttIvData {
}
if (MqttSentStatus::LAST_SUCCESS_SENT == rec->mqttSentStatus) {
if(InverterDevInform_All == mCmd) {
snprintf(mSubTopic.data(), mSubTopic.size(), "%s/firmware", mIv->config->name);
snprintf(mVal.data(), mVal.size(), "{\"version\":%d,\"build_year\":\"%s\",\"build_month_day\":%d,\"build_hour_min\":%d,\"bootloader\":%d}",
mIv->getChannelFieldValue(CH0, FLD_FW_VERSION, rec),
mIv->getChannelFieldValue(CH0, FLD_FW_BUILD_YEAR, rec),
mIv->getChannelFieldValue(CH0, FLD_FW_BUILD_MONTH_DAY, rec),
mIv->getChannelFieldValue(CH0, FLD_FW_BUILD_HOUR_MINUTE, rec),
mIv->getChannelFieldValue(CH0, FLD_BOOTLOADER_VER, rec));
retained = true;
} else if(InverterDevInform_Simple == mCmd) {
snprintf(mSubTopic.data(), mSubTopic.size(), "%s/hardware", mIv->config->name);
snprintf(mVal.data(), mVal.size(), "{\"part\":%d,\"version\":\"%s\",\"grid_profile_code\":%d,\"grid_profile_version\":%d}",
mIv->getChannelFieldValue(CH0, FLD_PART_NUM, rec),
mIv->getChannelFieldValue(CH0, FLD_HW_VERSION, rec),
mIv->getChannelFieldValue(CH0, FLD_GRID_PROFILE_CODE, rec),
mIv->getChannelFieldValue(CH0, FLD_GRID_PROFILE_VERSION, rec));
retained = true;
} else {
snprintf(mSubTopic.data(), mSubTopic.size(), "%s/ch%d/%s", mIv->config->name, rec->assign[mPos].ch, fields[rec->assign[mPos].fieldId]);
snprintf(mVal.data(), mVal.size(), "%g", ah::round3(mIv->getValue(mPos, rec)));
}
uint8_t qos = (FLD_ACT_ACTIVE_PWR_LIMIT == rec->assign[mPos].fieldId) ? QOS_2 : QOS_0;
snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "%s/ch%d/%s", mIv->config->name, rec->assign[mPos].ch, fields[rec->assign[mPos].fieldId]);
snprintf(mVal, 40, "%g", ah::round3(mIv->getValue(mPos, rec)));
mPublish(mSubTopic, mVal, retained, qos);
if((FLD_EVT != rec->assign[mPos].fieldId)
&& (FLD_LAST_ALARM_CODE != rec->assign[mPos].fieldId))
mPublish(mSubTopic.data(), mVal.data(), retained, qos);
}
mPos++;
} else {
@ -192,8 +215,8 @@ class PubMqttIvData {
}
inline void sendRadioStat(uint8_t start) {
snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "%s/radio_stat", mIv->config->name);
snprintf(mVal, 140, "{\"tx\":%d,\"success\":%d,\"fail\":%d,\"no_answer\":%d,\"retransmits\":%d,\"lossIvRx\":%d,\"lossIvTx\":%d,\"lossDtuRx\":%d,\"lossDtuTx\":%d}",
snprintf(mSubTopic.data(), mSubTopic.size(), "%s/radio_stat", mIv->config->name);
snprintf(mVal.data(), mVal.size(), "{\"tx\":%d,\"success\":%d,\"fail\":%d,\"no_answer\":%d,\"retransmits\":%d,\"lossIvRx\":%d,\"lossIvTx\":%d,\"lossDtuRx\":%d,\"lossDtuTx\":%d}",
mIv->radioStatistics.txCnt,
mIv->radioStatistics.rxSuccess,
mIv->radioStatistics.rxFail,
@ -203,7 +226,7 @@ class PubMqttIvData {
mIv->radioStatistics.ivSent,
mIv->radioStatistics.dtuLoss,
mIv->radioStatistics.dtuSent);
mPublish(mSubTopic, mVal, false, QOS_0);
mPublish(mSubTopic.data(), mVal.data(), false, QOS_0);
}
void stateSendTotals() {
@ -240,9 +263,9 @@ class PubMqttIvData {
retained = false;
break;
}
snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "total/%s", fields[fieldId]);
snprintf(mVal, 40, "%g", ah::round3(mTotal[mPos]));
mPublish(mSubTopic, mVal, retained, QOS_0);
snprintf(mSubTopic.data(), mSubTopic.size(), "total/%s", fields[fieldId]);
snprintf(mVal.data(), mVal.size(), "%g", ah::round3(mTotal[mPos]));
mPublish(mSubTopic.data(), mVal.data(), retained, QOS_0);
mPos++;
} else {
mSendList->pop();
@ -266,8 +289,8 @@ class PubMqttIvData {
uint8_t mPos = 0;
bool mRTRDataHasBeenSent = false;
char mSubTopic[32 + MAX_NAME_LENGTH + 1];
char mVal[140];
std::array<char, (32 + MAX_NAME_LENGTH + 1)> mSubTopic;
std::array<char, 140> mVal;
std::queue<sendListCmdIv> *mSendList = nullptr;
};

2
src/web/Protection.h

@ -85,7 +85,7 @@ class Protection {
if(isIdentical(clientIp, mApiIp))
return (0 != strncmp(token, mToken.data(), 16));
return false;
return true;
}
private:

1
src/web/RestApi.h

@ -680,6 +680,7 @@ class RestApi {
obj[F("debug")] = mConfig->serial.debug;
obj[F("priv")] = mConfig->serial.privacyLog;
obj[F("wholeTrace")] = mConfig->serial.printWholeTrace;
obj[F("log2mqtt")] = mConfig->serial.log2mqtt;
}
void getStaticIp(JsonObject obj) {

73
src/web/html/setup.html

@ -43,24 +43,8 @@
<div class="col-4 col-sm-9"><input type="text" name="cstLnkTxt"/></div>
</div>
</fieldset>
<fieldset class="mb-4">
<fieldset class="mb-4" id="serialCb">
<legend class="des">{#SERIAL_CONSOLE}</legend>
<div class="row mb-3">
<div class="col-8 col-sm-3">{#LOG_PRINT_INVERTER_DATA}</div>
<div class="col-4 col-sm-9"><input type="checkbox" name="serEn"/></div>
</div>
<div class="row mb-3">
<div class="col-8 col-sm-3">{#LOG_SERIAL_DEBUG}</div>
<div class="col-4 col-sm-9"><input type="checkbox" name="serDbg"/></div>
</div>
<div class="row mb-3">
<div class="col-8 col-sm-3">{#LOG_PRIVACY_MODE}</div>
<div class="col-4 col-sm-9"><input type="checkbox" name="priv"/></div>
</div>
<div class="row mb-3">
<div class="col-8 col-sm-3">{#LOG_PRINT_TRACES}</div>
<div class="col-4 col-sm-9"><input type="checkbox" name="wholeTrace"/></div>
</div>
</fieldset>
</div>
@ -716,6 +700,13 @@
ivGlob(obj);
}
function divRow(item0, item1) {
return ml("div", {class: "row mb-3"}, [
ml("div", {class: "col-3 mt-2"}, item0),
ml("div", {class: "col-9"}, item1)
])
}
function ivModal(obj) {
var lines = [];
lines.push(ml("tr", {}, [
@ -743,43 +734,23 @@
var html = ml("div", {}, [
tabs(["{#TAB_GENERAL}", "{#TAB_INPUTS}", "{#TAB_RADIO}", "{#TAB_ADVANCED}"]),
ml("div", {id: "div{#TAB_GENERAL}", class: "tab-content"}, [
ml("div", {class: "row mb-3"}, [
ml("div", {class: "col-2"}, "{#INV_ENABLE}"),
ml("div", {class: "col-10"}, cbEn)
]),
ml("div", {class: "row mb-3"}, [
ml("div", {class: "col-2 mt-2"}, "{#INV_SERIAL}"),
ml("div", {class: "col-10"}, ser)
]),
ml("div", {class: "row mb-3"}, [
ml("div", {class: "col-2 mt-2"}, "Name"),
ml("div", {class: "col-10"}, ml("input", {name: "name", class: "text", type: "text", value: obj.name}, null))
])
divRow("{#INV_ENABLE}", cbEn),
divRow("{#INV_SERIAL}", ser),
divRow("Name", ml("input", {name: "name", class: "text", type: "text", value: obj.name}, null))
]),
ml("div", {id: "div{#TAB_INPUTS}", class: "tab-content hide"}, [
ml("div", {class: "row mb-3"},
ml("table", {class: "table"},
ml("tbody", {}, lines)
)
ml("table", {class: "table"}, ml("tbody", {}, lines))
)
]),
ml("div", {id: "div{#TAB_RADIO}", class: "tab-content hide"}, [
ml("input", {type: "hidden", name: "isnrf"}, null),
ml("div", {id: "setcmt"}, [
ml("div", {class: "row mb-3"}, [
ml("div", {class: "col-3 mt-2"}, "{#INV_FREQUENCY}"),
ml("div", {class: "col-9"}, sel("freq", esp32cmtFreq, obj.freq))
]),
ml("div", {class: "row mb-3"}, [
ml("div", {class: "col-3 mt-2"}, "{#INV_POWER_LEVEL}"),
ml("div", {class: "col-9"}, sel("cmtpa", esp32cmtPa, obj.pa))
]),
divRow("{#INV_FREQUENCY}", sel("freq", esp32cmtFreq, obj.freq)),
divRow("{#INV_POWER_LEVEL}", sel("cmtpa", esp32cmtPa, obj.pa))
]),
ml("div", {id: "setnrf"},
ml("div", {class: "row mb-3"}, [
ml("div", {class: "col-3 mt-2"}, "{#INV_POWER_LEVEL}"),
ml("div", {class: "col-9"}, sel("nrfpa", nrfPa, obj.pa))
]),
divRow("{#INV_POWER_LEVEL}", sel("nrfpa", nrfPa, obj.pa))
),
]),
ml("div", {id: "div{#TAB_ADVANCED}", class: "tab-content hide"}, [
@ -1026,8 +997,18 @@
/*ENDIF_ESP32*/
function parseSerial(obj) {
for(var i of [["serEn", "show_live_data"], ["serDbg", "debug"], ["priv", "priv"], ["wholeTrace", "wholeTrace"]])
document.getElementsByName(i[0])[0].checked = obj[i[1]];
var e = document.getElementById("serialCb")
var l = [["serEn", "show_live_data", "{#LOG_PRINT_INVERTER_DATA}"], ["serDbg", "debug", "{#LOG_SERIAL_DEBUG}"], ["priv", "priv", "{#LOG_PRIVACY_MODE}"], ["wholeTrace", "wholeTrace", "{#LOG_PRINT_TRACES}"], ["log2mqtt", "log2mqtt", "{#LOG_TO_MQTT}"]]
for(var i of l) {
var cb = ml("input", {name: i[0], type: "checkbox"}, null)
cb.checked = obj[i[1]]
e.appendChild(
ml("div", {class: "row mb-3"}, [
ml("div", {class: "col-8 col-sm-3"}, i[2]),
ml("div", {class: "col-4 col-sm-9"}, cb)
])
)
}
}
function parseDisplay(obj, type, system) {

5
src/web/lang.json

@ -203,6 +203,11 @@
"en": "Print whole traces in Log",
"de": "alle Informationen in Log schreiben"
},
{
"token": "LOG_TO_MQTT",
"en": "Send Serial debug over MqTT",
"de": "sende serielles Log &uuml;ber MqTT"
},
{
"token": "NETWORK",
"en": "Network",

1
src/web/web.h

@ -552,6 +552,7 @@ class Web {
mConfig->serial.privacyLog = (request->arg("priv") == "on");
mConfig->serial.printWholeTrace = (request->arg("wholeTrace") == "on");
mConfig->serial.showIv = (request->arg("serEn") == "on");
mConfig->serial.log2mqtt = (request->arg("log2mqtt") == "on");
// display
mConfig->plugin.display.pwrSaveAtIvOffline = (request->arg("disp_pwr") == "on");

Loading…
Cancel
Save