Browse Source

merged SH1106 1.3" Display, thx @dAjaY85

added SH1106 to automatic build
added IP address to MQTT (version, device and IP are retained and only transmitted once after boot) #556
added `set_power_limit` acknowledge MQTT publish #553
changed: version, device name are only published via MQTT once after boot
added `Login` to menu if admin password is set #554
added `development` to second changelog link in `index.html` #543
added interval for MQTT (as option). With this settings MQTT live data is published in a fixed timing (only if inverter is available) #542, #523
added MQTT `comm_disabled` #529
pull/566/head
lumapu 2 years ago
parent
commit
712b5af9b9
  1. 2
      .github/workflows/compile_development.yml
  2. 2
      .github/workflows/compile_release.yml
  3. 2
      User_Manual.md
  4. 11
      src/CHANGES.md
  5. 9
      src/app.cpp
  6. 4
      src/app.h
  7. 1
      src/appInterface.h
  8. 6
      src/config/settings.h
  9. 2
      src/defines.h
  10. 10
      src/hm/payload.h
  11. 53
      src/publisher/pubMqtt.h
  12. 24
      src/web/RestApi.h
  13. 2
      src/web/html/index.html
  14. 9
      src/web/html/setup.html
  15. 1
      src/web/web.h

2
.github/workflows/compile_development.yml

@ -47,7 +47,7 @@ jobs:
run: python convert.py run: python convert.py
- name: Run PlatformIO - name: Run PlatformIO
run: pio run -d src --environment esp8266-release --environment esp8285-release --environment esp8266-nokia5110 --environment esp8266-ssd1306 --environment esp32-wroom32-release --environment esp32-wroom32-nokia5110 --environment esp32-wroom32-ssd1306 run: pio run -d src --environment esp8266-release --environment esp8285-release --environment esp8266-nokia5110 --environment esp8266-ssd1306 --environment esp8266-sh1106 --environment esp32-wroom32-release --environment esp32-wroom32-nokia5110 --environment esp32-wroom32-ssd1306 --environment esp32-wroom32-sh1106
- name: Rename Binary files - name: Rename Binary files
id: rename-binary-files id: rename-binary-files

2
.github/workflows/compile_release.yml

@ -51,7 +51,7 @@ jobs:
run: python convert.py run: python convert.py
- name: Run PlatformIO - name: Run PlatformIO
run: pio run -d src --environment esp8266-release --environment esp8285-release --environment esp8266-nokia5110 --environment esp8266-ssd1306 --environment esp32-wroom32-release --environment esp32-wroom32-nokia5110 --environment esp32-wroom32-ssd1306 run: pio run -d src --environment esp8266-release --environment esp8285-release --environment esp8266-nokia5110 --environment esp8266-ssd1306 --environment esp8266-sh1106 --environment esp32-wroom32-release --environment esp32-wroom32-nokia5110 --environment esp32-wroom32-ssd1306 --environment esp32-wroom32-sh1106
- name: Rename Binary files - name: Rename Binary files
id: rename-binary-files id: rename-binary-files

2
User_Manual.md

@ -29,6 +29,7 @@ The AhoyDTU will publish on the following topics
| `uptime` | 73630 | uptime in seconds | false | | `uptime` | 73630 | uptime in seconds | false |
| `version` | 0.5.61 | current installed verison of AhoyDTU | true | | `version` | 0.5.61 | current installed verison of AhoyDTU | true |
| `wifi_rssi` | -75 | WiFi signal strength | false | | `wifi_rssi` | -75 | WiFi signal strength | false |
| `ip_addr` | 192.168.178.25 | WiFi Station IP Address | true |
| status code | Remarks | | status code | Remarks |
|---|---| |---|---|
@ -43,6 +44,7 @@ The AhoyDTU will publish on the following topics
|---|---|---|---| |---|---|---|---|
| `available` | 2 | see table below | true | | `available` | 2 | see table below | true |
| `last_success` | 1672155690 | UTC Timestamp | true | | `last_success` | 1672155690 | UTC Timestamp | true |
| `ack_pwr_limit` | true | fast information if inverter has accepted power limit | false |
| status code | Remarks | | status code | Remarks |
|---|---| |---|---|

11
src/CHANGES.md

@ -2,6 +2,17 @@
(starting from release version `0.5.66`) (starting from release version `0.5.66`)
## 0.5.69
* merged SH1106 1.3" Display, thx @dAjaY85
* added SH1106 to automatic build
* added IP address to MQTT (version, device and IP are retained and only transmitted once after boot) #556
* added `set_power_limit` acknowledge MQTT publish #553
* changed: version, device name are only published via MQTT once after boot
* added `Login` to menu if admin password is set #554
* added `development` to second changelog link in `index.html` #543
* added interval for MQTT (as option). With this settings MQTT live data is published in a fixed timing (only if inverter is available) #542, #523
* added MQTT `comm_disabled` #529
## 0.5.68 ## 0.5.68
* repaired receive payload * repaired receive payload
* Powerlimit is transfered immediately to inverter * Powerlimit is transfered immediately to inverter

9
src/app.cpp

@ -51,7 +51,7 @@ void app::setup() {
#endif #endif
mSys->addInverters(&mConfig->inst); mSys->addInverters(&mConfig->inst);
mPayload.setup(mSys, &mStat, mConfig->nrf.maxRetransPerPyld, &mTimestamp); mPayload.setup(this, mSys, &mStat, mConfig->nrf.maxRetransPerPyld, &mTimestamp);
mPayload.enableSerialDebug(mConfig->serial.debug); mPayload.enableSerialDebug(mConfig->serial.debug);
if(!mSys->Radio.isChipConnected()) if(!mSys->Radio.isChipConnected())
@ -162,14 +162,17 @@ void app::tickIVCommunication(void) {
nxtTrig = mSunrise - mConfig->sun.offsetSec; nxtTrig = mSunrise - mConfig->sun.offsetSec;
} else { } else {
if (mTimestamp > (mSunset + mConfig->sun.offsetSec)) { // current time is past communication stop, nothing to do. Next update will be done at midnight by tickCalcSunrise if (mTimestamp > (mSunset + mConfig->sun.offsetSec)) { // current time is past communication stop, nothing to do. Next update will be done at midnight by tickCalcSunrise
return; nxtTrig = 0;
} else { // current time lies within communication start/stop time, set next trigger to communication stop } else { // current time lies within communication start/stop time, set next trigger to communication stop
mIVCommunicationOn = true; mIVCommunicationOn = true;
nxtTrig = mSunset + mConfig->sun.offsetSec; nxtTrig = mSunset + mConfig->sun.offsetSec;
} }
} }
onceAt(std::bind(&app::tickIVCommunication, this), nxtTrig); if (nxtTrig != 0)
onceAt(std::bind(&app::tickIVCommunication, this), nxtTrig);
} }
if (mConfig->mqtt.broker[0] > 0)
mMqtt.tickerComm(mIVCommunicationOn);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

4
src/app.h

@ -122,6 +122,10 @@ class app : public IApp, public ah::Scheduler {
once(std::bind(&PubMqttType::sendDiscoveryConfig, &mMqtt), 1); once(std::bind(&PubMqttType::sendDiscoveryConfig, &mMqtt), 1);
} }
void setMqttPowerLimitAck(Inverter<> *iv) {
mMqtt.setPowerLimitAck(iv);
}
void ivSendHighPrio(Inverter<> *iv) { void ivSendHighPrio(Inverter<> *iv) {
mPayload.ivSendHighPrio(iv); mPayload.ivSendHighPrio(iv);
} }

1
src/appInterface.h

@ -34,6 +34,7 @@ class IApp {
virtual bool getRebootRequestState() = 0; virtual bool getRebootRequestState() = 0;
virtual bool getSettingsValid() = 0; virtual bool getSettingsValid() = 0;
virtual void setMqttDiscoveryFlag() = 0; virtual void setMqttDiscoveryFlag() = 0;
virtual void setMqttPowerLimitAck(Inverter<> *iv) = 0;
virtual void ivSendHighPrio(Inverter<> *iv) = 0; virtual void ivSendHighPrio(Inverter<> *iv) = 0;

6
src/config/settings.h

@ -96,6 +96,7 @@ typedef struct {
char user[MQTT_USER_LEN]; char user[MQTT_USER_LEN];
char pwd[MQTT_PWD_LEN]; char pwd[MQTT_PWD_LEN];
char topic[MQTT_TOPIC_LEN]; char topic[MQTT_TOPIC_LEN];
uint16_t interval;
} cfgMqtt_t; } cfgMqtt_t;
typedef struct { typedef struct {
@ -297,6 +298,7 @@ class settings {
snprintf(mCfg.mqtt.user, MQTT_USER_LEN, "%s", DEF_MQTT_USER); snprintf(mCfg.mqtt.user, MQTT_USER_LEN, "%s", DEF_MQTT_USER);
snprintf(mCfg.mqtt.pwd, MQTT_PWD_LEN, "%s", DEF_MQTT_PWD); snprintf(mCfg.mqtt.pwd, MQTT_PWD_LEN, "%s", DEF_MQTT_PWD);
snprintf(mCfg.mqtt.topic, MQTT_TOPIC_LEN, "%s", DEF_MQTT_TOPIC); snprintf(mCfg.mqtt.topic, MQTT_TOPIC_LEN, "%s", DEF_MQTT_TOPIC);
mCfg.mqtt.interval = 0; // off
mCfg.led.led0 = DEF_LED0_PIN; mCfg.led.led0 = DEF_LED0_PIN;
mCfg.led.led1 = DEF_LED1_PIN; mCfg.led.led1 = DEF_LED1_PIN;
@ -396,8 +398,10 @@ class settings {
obj[F("user")] = mCfg.mqtt.user; obj[F("user")] = mCfg.mqtt.user;
obj[F("pwd")] = mCfg.mqtt.pwd; obj[F("pwd")] = mCfg.mqtt.pwd;
obj[F("topic")] = mCfg.mqtt.topic; obj[F("topic")] = mCfg.mqtt.topic;
obj[F("intvl")] = mCfg.mqtt.interval;
} else { } else {
mCfg.mqtt.port = obj[F("port")]; mCfg.mqtt.port = obj[F("port")];
mCfg.mqtt.interval = obj[F("intvl")];
snprintf(mCfg.mqtt.broker, MQTT_ADDR_LEN, "%s", obj[F("broker")].as<const char*>()); snprintf(mCfg.mqtt.broker, MQTT_ADDR_LEN, "%s", obj[F("broker")].as<const char*>());
snprintf(mCfg.mqtt.user, MQTT_USER_LEN, "%s", obj[F("user")].as<const char*>()); snprintf(mCfg.mqtt.user, MQTT_USER_LEN, "%s", obj[F("user")].as<const char*>());
snprintf(mCfg.mqtt.pwd, MQTT_PWD_LEN, "%s", obj[F("pwd")].as<const char*>()); snprintf(mCfg.mqtt.pwd, MQTT_PWD_LEN, "%s", obj[F("pwd")].as<const char*>());

2
src/defines.h

@ -13,7 +13,7 @@
//------------------------------------- //-------------------------------------
#define VERSION_MAJOR 0 #define VERSION_MAJOR 0
#define VERSION_MINOR 5 #define VERSION_MINOR 5
#define VERSION_PATCH 68 #define VERSION_PATCH 69
//------------------------------------- //-------------------------------------
typedef struct { typedef struct {

10
src/hm/payload.h

@ -35,7 +35,8 @@ class Payload : public Handler<payloadListenerType> {
public: public:
Payload() : Handler() {} Payload() : Handler() {}
void setup(HMSYSTEM *sys, statistics_t *stat, uint8_t maxRetransmits, uint32_t *timestamp) { void setup(IApp *app, HMSYSTEM *sys, statistics_t *stat, uint8_t maxRetransmits, uint32_t *timestamp) {
mApp = app;
mSys = sys; mSys = sys;
mStat = stat; mStat = stat;
mMaxRetrans = maxRetransmits; mMaxRetrans = maxRetransmits;
@ -141,7 +142,11 @@ class Payload : public Handler<payloadListenerType> {
iv->devControlRequest = false; iv->devControlRequest = false;
if ((p->packet[12] == ActivePowerContr) && (p->packet[13] == 0x00)) { if ((p->packet[12] == ActivePowerContr) && (p->packet[13] == 0x00)) {
String msg = (p->packet[10] == 0x00 && p->packet[11] == 0x00) ? "" : "NOT "; String msg = "";
if((p->packet[10] == 0x00) && (p->packet[11] == 0x00)) {
msg = "NOT ";
mApp->setMqttPowerLimitAck(iv);
}
DPRINTLN(DBG_INFO, F("Inverter ") + String(iv->id) + F(" has ") + msg + F("accepted power limit set point ") + String(iv->powerLimit[0]) + F(" with PowerLimitControl ") + String(iv->powerLimit[1])); DPRINTLN(DBG_INFO, F("Inverter ") + String(iv->id) + F(" has ") + msg + F("accepted power limit set point ") + String(iv->powerLimit[0]) + F(" with PowerLimitControl ") + String(iv->powerLimit[1]));
} }
iv->devControlCmd = Init; iv->devControlCmd = Init;
@ -272,6 +277,7 @@ class Payload : public Handler<payloadListenerType> {
} }
private: private:
IApp *mApp;
HMSYSTEM *mSys; HMSYSTEM *mSys;
statistics_t *mStat; statistics_t *mStat;
uint8_t mMaxRetrans; uint8_t mMaxRetrans;

53
src/publisher/pubMqtt.h

@ -41,11 +41,13 @@ class PubMqtt {
~PubMqtt() { } ~PubMqtt() { }
void setup(cfgMqtt_t *cfg_mqtt, const char *devName, const char *version, HMSYSTEM *sys, uint32_t *utcTs) { void setup(cfgMqtt_t *cfg_mqtt, const char *devName, const char *version, HMSYSTEM *sys, uint32_t *utcTs) {
mCfgMqtt = cfg_mqtt; mCfgMqtt = cfg_mqtt;
mDevName = devName; mDevName = devName;
mVersion = version; mVersion = version;
mSys = sys; mSys = sys;
mUtcTimestamp = utcTs; mUtcTimestamp = utcTs;
mExeOnce = true;
mIntervalTimeout = 1;
snprintf(mLwtTopic, MQTT_TOPIC_LEN + 5, "%s/mqtt", mCfgMqtt->topic); snprintf(mLwtTopic, MQTT_TOPIC_LEN + 5, "%s/mqtt", mCfgMqtt->topic);
@ -73,7 +75,16 @@ class PubMqtt {
} }
void tickerSecond() { void tickerSecond() {
sendIvData(); if(0 == mCfgMqtt->interval) // no fixed interval, publish once new data were received (from inverter)
sendIvData();
else { // send mqtt data in a fixed interval
if(--mIntervalTimeout == 0) {
mIntervalTimeout = mCfgMqtt->interval;
mSendList.push(RealTimeRunData_Debug);
sendIvData();
}
}
} }
void tickerMinute() { void tickerMinute() {
@ -98,9 +109,16 @@ class PubMqtt {
publish("dis_night_comm", ((disNightCom) ? "true" : "false"), true); publish("dis_night_comm", ((disNightCom) ? "true" : "false"), true);
} }
void tickerComm(bool disabled) {
publish("comm_disabled", ((disabled) ? "true" : "false"), true);
publish("comm_dis_ts", String(*mUtcTimestamp).c_str(), true);
}
void payloadEventListener(uint8_t cmd) { void payloadEventListener(uint8_t cmd) {
if(mClient.connected()) // prevent overflow if MQTT broker is not reachable but set if(mClient.connected()) { // prevent overflow if MQTT broker is not reachable but set
mSendList.push(cmd); if((0 == mCfgMqtt->interval) || (RealTimeRunData_Debug != cmd)) // no interval or no live data
mSendList.push(cmd);
}
} }
void publish(const char *subTopic, const char *payload, bool retained = false, bool addTopic = true) { void publish(const char *subTopic, const char *payload, bool retained = false, bool addTopic = true) {
@ -188,6 +206,15 @@ class PubMqtt {
} }
} }
void setPowerLimitAck(Inverter<> *iv) {
if (NULL != iv) {
char topic[7 + MQTT_TOPIC_LEN];
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/ack_pwr_limit", iv->config->name);
publish(topic, "true", true);
}
}
private: private:
#if defined(ESP8266) #if defined(ESP8266)
void onWifiConnect(const WiFiEventStationModeGotIP& event) { void onWifiConnect(const WiFiEventStationModeGotIP& event) {
@ -223,8 +250,12 @@ class PubMqtt {
DPRINTLN(DBG_INFO, F("MQTT connected")); DPRINTLN(DBG_INFO, F("MQTT connected"));
mEnReconnect = true; mEnReconnect = true;
publish("version", mVersion, true); if(mExeOnce) {
publish("device", mDevName, true); publish("version", mVersion, true);
publish("device", mDevName, true);
publish("ip_addr", WiFi.localIP().toString().c_str(), true);
mExeOnce = false;
}
tickerMinute(); tickerMinute();
publish(mLwtTopic, mLwtOnline, true, false); publish(mLwtTopic, mLwtOnline, true, false);
@ -494,6 +525,8 @@ class PubMqtt {
subscriptionCb mSubscriptionCb; subscriptionCb mSubscriptionCb;
bool mIvAvail; // shows if at least one inverter is available bool mIvAvail; // shows if at least one inverter is available
uint8_t mLastIvState[MAX_NUM_INVERTERS]; uint8_t mLastIvState[MAX_NUM_INVERTERS];
bool mExeOnce;
uint16_t mIntervalTimeout;
// last will topic and payload must be available trough lifetime of 'espMqttClient' // last will topic and payload must be available trough lifetime of 'espMqttClient'
char mLwtTopic[MQTT_TOPIC_LEN+5]; char mLwtTopic[MQTT_TOPIC_LEN+5];

24
src/web/RestApi.h

@ -276,11 +276,12 @@ class RestApi {
} }
void getMqtt(JsonObject obj) { void getMqtt(JsonObject obj) {
obj[F("broker")] = String(mConfig->mqtt.broker); obj[F("broker")] = String(mConfig->mqtt.broker);
obj[F("port")] = String(mConfig->mqtt.port); obj[F("port")] = String(mConfig->mqtt.port);
obj[F("user")] = String(mConfig->mqtt.user); obj[F("user")] = String(mConfig->mqtt.user);
obj[F("pwd")] = (strlen(mConfig->mqtt.pwd) > 0) ? F("{PWD}") : String(""); obj[F("pwd")] = (strlen(mConfig->mqtt.pwd) > 0) ? F("{PWD}") : String("");
obj[F("topic")] = String(mConfig->mqtt.topic); obj[F("topic")] = String(mConfig->mqtt.topic);
obj[F("interval")] = String(mConfig->mqtt.interval);
} }
void getNtp(JsonObject obj) { void getNtp(JsonObject obj) {
@ -357,10 +358,15 @@ class RestApi {
obj[F("name")][i] = "Documentation"; obj[F("name")][i] = "Documentation";
obj[F("link")][i] = "https://ahoydtu.de"; obj[F("link")][i] = "https://ahoydtu.de";
obj[F("trgt")][i++] = "_blank"; obj[F("trgt")][i++] = "_blank";
if((strlen(mConfig->sys.adminPwd) > 0) && !mApp->getProtection()) { if(strlen(mConfig->sys.adminPwd) > 0) {
obj[F("name")][i++] = "-"; obj[F("name")][i++] = "-";
obj[F("name")][i] = "Logout"; if(mApp->getProtection()) {
obj[F("link")][i++] = "/logout"; obj[F("name")][i] = "Login";
obj[F("link")][i++] = "/login";
} else {
obj[F("name")][i] = "Logout";
obj[F("link")][i++] = "/logout";
}
} }
} }
@ -411,6 +417,8 @@ class RestApi {
JsonArray info = obj.createNestedArray(F("infos")); JsonArray info = obj.createNestedArray(F("infos"));
if(mApp->getMqttIsConnected()) if(mApp->getMqttIsConnected())
info.add(F("MQTT is connected, ") + String(mApp->getMqttTxCnt()) + F(" packets sent, ") + String(mApp->getMqttRxCnt()) + F(" packets received")); info.add(F("MQTT is connected, ") + String(mApp->getMqttTxCnt()) + F(" packets sent, ") + String(mApp->getMqttRxCnt()) + F(" packets received"));
if(mConfig->mqtt.interval > 0)
info.add(F("MQTT publishes in a fixed interval of ") + String(mConfig->mqtt.interval) + F(" seconds"));
} }
void getSetup(JsonObject obj) { void getSetup(JsonObject obj) {

2
src/web/html/index.html

@ -51,7 +51,7 @@
<li>Discuss with us on <a href="https://discord.gg/WzhxEY62mB">Discord</a></li> <li>Discuss with us on <a href="https://discord.gg/WzhxEY62mB">Discord</a></li>
<li>Report <a href="https://github.com/lumapu/ahoy/issues" target="_blank">issues</a></li> <li>Report <a href="https://github.com/lumapu/ahoy/issues" target="_blank">issues</a></li>
<li>Contribute to <a href="https://github.com/lumapu/ahoy/blob/main/User_Manual.md" target="_blank">documentation</a></li> <li>Contribute to <a href="https://github.com/lumapu/ahoy/blob/main/User_Manual.md" target="_blank">documentation</a></li>
<li><a href="https://nightly.link/lumapu/ahoy/workflows/compile_development/development03/ahoydtu_dev.zip" target="_blank">Download</a> & Test development firmware, <a href="https://github.com/lumapu/ahoy/blob/development03/src/CHANGES.md" target="_blank">Changelog</a></li> <li><a href="https://nightly.link/lumapu/ahoy/workflows/compile_development/development03/ahoydtu_dev.zip" target="_blank">Download</a> & Test development firmware, <a href="https://github.com/lumapu/ahoy/blob/development03/src/CHANGES.md" target="_blank">Development Changelog</a></li>
<li>make a <a href="https://paypal.me/lupusch" target="_blank">donation</a></li> <li>make a <a href="https://paypal.me/lupusch" target="_blank">donation</a></li>
</ul> </ul>
<p class="lic"> <p class="lic">

9
src/web/html/setup.html

@ -94,7 +94,7 @@
<input type="button" id="btnAdd" class="btn" value="Add Inverter"/> <input type="button" id="btnAdd" class="btn" value="Add Inverter"/>
<p class="subdes">General</p> <p class="subdes">General</p>
<label for="invInterval">Interval [s]</label> <label for="invInterval">Interval [s]</label>
<input type="text" class="text" name="invInterval"/> <input type="text" class="text" name="invInterval" pattern="[0-9]+" title="Invalid input"/>
<label for="invRetry">Max retries per Payload</label> <label for="invRetry">Max retries per Payload</label>
<input type="text" class="text" name="invRetry"/> <input type="text" class="text" name="invRetry"/>
</fieldset> </fieldset>
@ -148,6 +148,9 @@
<input type="password" class="text" name="mqttPwd"/> <input type="password" class="text" name="mqttPwd"/>
<label for="mqttTopic">Topic</label> <label for="mqttTopic">Topic</label>
<input type="text" class="text" name="mqttTopic" pattern="[A-Za-z0-9.\-_\+\/]+" title="Invalid input" /> <input type="text" class="text" name="mqttTopic" pattern="[A-Za-z0-9.\-_\+\/]+" title="Invalid input" />
<p class="des">Send Inverter data in a fixed interval, even if there is no change. A value of '0' disables the fixed interval. The data is published once it was successfully received from inverter. (default: 0)</p>
<label for="mqttIntvl">Interval [s]</label>
<input type="text" class="text" name="mqttInterval" pattern="[0-9]+" title="Invalid input" />
<label for="mqttBtn">Discovery Config (homeassistant)</label> <label for="mqttBtn">Discovery Config (homeassistant)</label>
<input type="button" name="mqttDiscovery" id="mqttDiscovery" class="btn" value="send" onclick="sendDiscoveryConfig()"/> <input type="button" name="mqttDiscovery" id="mqttDiscovery" class="btn" value="send" onclick="sendDiscoveryConfig()"/>
<span id="apiResultMqtt"></span> <span id="apiResultMqtt"></span>
@ -170,7 +173,7 @@
<label for="serDbg">Serial Debug</label> <label for="serDbg">Serial Debug</label>
<input type="checkbox" class="cb" name="serDbg"/><br/> <input type="checkbox" class="cb" name="serDbg"/><br/>
<label for="serIntvl">Interval [s]</label> <label for="serIntvl">Interval [s]</label>
<input type="text" class="text" name="serIntvl"/> <input type="text" class="text" name="serIntvl" pattern="[0-9]+" title="Invalid input"/>
</fieldset> </fieldset>
</div> </div>
@ -389,7 +392,7 @@
} }
function parseMqtt(obj) { function parseMqtt(obj) {
for(var i of [["Addr", "broker"], ["Port", "port"], ["User", "user"], ["Pwd", "pwd"], ["Topic", "topic"]]) for(var i of [["Addr", "broker"], ["Port", "port"], ["User", "user"], ["Pwd", "pwd"], ["Topic", "topic"], ["Interval", "interval"]])
document.getElementsByName("mqtt"+i[0])[0].value = obj[i[1]]; document.getElementsByName("mqtt"+i[0])[0].value = obj[i[1]];
} }

1
src/web/web.h

@ -494,6 +494,7 @@ class Web {
request->arg("mqttPwd").toCharArray(mConfig->mqtt.pwd, MQTT_PWD_LEN); request->arg("mqttPwd").toCharArray(mConfig->mqtt.pwd, MQTT_PWD_LEN);
request->arg("mqttTopic").toCharArray(mConfig->mqtt.topic, MQTT_TOPIC_LEN); request->arg("mqttTopic").toCharArray(mConfig->mqtt.topic, MQTT_TOPIC_LEN);
mConfig->mqtt.port = request->arg("mqttPort").toInt(); mConfig->mqtt.port = request->arg("mqttPort").toInt();
mConfig->mqtt.interval = request->arg("mqttInterval").toInt();
// serial console // serial console
if(request->arg("serIntvl") != "") { if(request->arg("serIntvl") != "") {

Loading…
Cancel
Save