mirror of
https://github.com/lumapu/ahoy.git
synced 2025-06-12 23:51:39 +02:00
improved mqtt
removed wrong "inverter type can't be detected!" messages repaired NTP and static IP #459 MQTT status about availability and produce are retain messages now
This commit is contained in:
parent
f4c3aea964
commit
0a5833e6ec
11 changed files with 96 additions and 87 deletions
|
@ -10,6 +10,7 @@
|
||||||
#include <LittleFS.h>
|
#include <LittleFS.h>
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
#include "../utils/dbg.h"
|
#include "../utils/dbg.h"
|
||||||
|
#include "../utils/helper.h"
|
||||||
#include "../defines.h"
|
#include "../defines.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -223,25 +224,6 @@ class settings {
|
||||||
return saveSettings();
|
return saveSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
String ip2Str(uint8_t ip[]) {
|
|
||||||
return String(ip[0]) + F(".")
|
|
||||||
+ String(ip[1]) + F(".")
|
|
||||||
+ String(ip[2]) + F(".")
|
|
||||||
+ String(ip[3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ip2Arr(uint8_t ip[], const char *ipStr) {
|
|
||||||
char *tmp = new char[strlen(ipStr)];
|
|
||||||
strncpy(tmp, ipStr, strlen(ipStr));
|
|
||||||
char *p = strtok(tmp, ".");
|
|
||||||
uint8_t i = 0;
|
|
||||||
while(NULL != p) {
|
|
||||||
ip[i++] = atoi(p);
|
|
||||||
p = strtok(NULL, ".");
|
|
||||||
}
|
|
||||||
delete[] tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loadDefaults(bool wifi = true) {
|
void loadDefaults(bool wifi = true) {
|
||||||
DPRINTLN(DBG_INFO, F("loadDefaults"));
|
DPRINTLN(DBG_INFO, F("loadDefaults"));
|
||||||
|
@ -288,25 +270,26 @@ class settings {
|
||||||
|
|
||||||
void jsonWifi(JsonObject obj, bool set = false) {
|
void jsonWifi(JsonObject obj, bool set = false) {
|
||||||
if(set) {
|
if(set) {
|
||||||
|
char buf[16];
|
||||||
obj[F("ssid")] = mCfg.sys.stationSsid;
|
obj[F("ssid")] = mCfg.sys.stationSsid;
|
||||||
obj[F("pwd")] = mCfg.sys.stationPwd;
|
obj[F("pwd")] = mCfg.sys.stationPwd;
|
||||||
obj[F("dev")] = mCfg.sys.deviceName;
|
obj[F("dev")] = mCfg.sys.deviceName;
|
||||||
obj[F("adm")] = mCfg.sys.adminPwd;
|
obj[F("adm")] = mCfg.sys.adminPwd;
|
||||||
obj[F("ip")] = ip2Str(mCfg.sys.ip.ip);
|
ah::ip2Char(mCfg.sys.ip.ip, buf); obj[F("ip")] = String(buf);
|
||||||
obj[F("mask")] = ip2Str(mCfg.sys.ip.mask);
|
ah::ip2Char(mCfg.sys.ip.mask, buf); obj[F("mask")] = String(buf);
|
||||||
obj[F("dns1")] = ip2Str(mCfg.sys.ip.dns1);
|
ah::ip2Char(mCfg.sys.ip.dns1, buf); obj[F("dns1")] = String(buf);
|
||||||
obj[F("dns2")] = ip2Str(mCfg.sys.ip.dns2);
|
ah::ip2Char(mCfg.sys.ip.dns2, buf); obj[F("dns2")] = String(buf);
|
||||||
obj[F("gtwy")] = ip2Str(mCfg.sys.ip.gateway);
|
ah::ip2Char(mCfg.sys.ip.gateway, buf); obj[F("gtwy")] = String(buf);
|
||||||
} else {
|
} else {
|
||||||
snprintf(mCfg.sys.stationSsid, SSID_LEN, "%s", obj[F("ssid")].as<const char*>());
|
snprintf(mCfg.sys.stationSsid, SSID_LEN, "%s", obj[F("ssid")].as<const char*>());
|
||||||
snprintf(mCfg.sys.stationPwd, PWD_LEN, "%s", obj[F("pwd")].as<const char*>());
|
snprintf(mCfg.sys.stationPwd, PWD_LEN, "%s", obj[F("pwd")].as<const char*>());
|
||||||
snprintf(mCfg.sys.deviceName, DEVNAME_LEN, "%s", obj[F("dev")].as<const char*>());
|
snprintf(mCfg.sys.deviceName, DEVNAME_LEN, "%s", obj[F("dev")].as<const char*>());
|
||||||
snprintf(mCfg.sys.adminPwd, PWD_LEN, "%s", obj[F("adm")].as<const char*>());
|
snprintf(mCfg.sys.adminPwd, PWD_LEN, "%s", obj[F("adm")].as<const char*>());
|
||||||
ip2Arr(mCfg.sys.ip.ip, obj[F("ip")]);
|
ah::ip2Arr(mCfg.sys.ip.ip, obj[F("ip")].as<const char*>());
|
||||||
ip2Arr(mCfg.sys.ip.mask, obj[F("mask")]);
|
ah::ip2Arr(mCfg.sys.ip.mask, obj[F("mask")].as<const char*>());
|
||||||
ip2Arr(mCfg.sys.ip.dns1, obj[F("dns1")]);
|
ah::ip2Arr(mCfg.sys.ip.dns1, obj[F("dns1")].as<const char*>());
|
||||||
ip2Arr(mCfg.sys.ip.dns2, obj[F("dns2")]);
|
ah::ip2Arr(mCfg.sys.ip.dns2, obj[F("dns2")].as<const char*>());
|
||||||
ip2Arr(mCfg.sys.ip.gateway, obj[F("gtwy")]);
|
ah::ip2Arr(mCfg.sys.ip.gateway, obj[F("gtwy")].as<const char*>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
#define VERSION_MAJOR 0
|
#define VERSION_MAJOR 0
|
||||||
#define VERSION_MINOR 5
|
#define VERSION_MINOR 5
|
||||||
#define VERSION_PATCH 43
|
#define VERSION_PATCH 44
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -70,7 +70,7 @@ class HmSystem {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if(p->config->serial.u64 != 0ULL)
|
||||||
DPRINTLN(DBG_ERROR, F("inverter type can't be detected!"));
|
DPRINTLN(DBG_ERROR, F("inverter type can't be detected!"));
|
||||||
|
|
||||||
p->init();
|
p->init();
|
||||||
|
|
|
@ -111,7 +111,8 @@ class PubMqtt {
|
||||||
}
|
}
|
||||||
|
|
||||||
void payloadEventListener(uint8_t cmd) {
|
void payloadEventListener(uint8_t cmd) {
|
||||||
mSendList.push(cmd);
|
if(mClient.connected()) // prevent overflow if MQTT broker is not reachable but set
|
||||||
|
mSendList.push(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSubscriptionCb(subscriptionCb cb) {
|
void setSubscriptionCb(subscriptionCb cb) {
|
||||||
|
@ -185,6 +186,7 @@ class PubMqtt {
|
||||||
void onWifiConnect(const WiFiEventStationModeGotIP& event) {
|
void onWifiConnect(const WiFiEventStationModeGotIP& event) {
|
||||||
DPRINTLN(DBG_VERBOSE, F("MQTT connecting"));
|
DPRINTLN(DBG_VERBOSE, F("MQTT connecting"));
|
||||||
mClient.connect();
|
mClient.connect();
|
||||||
|
mEnReconnect = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void onWifiDisconnect(const WiFiEventStationModeDisconnected& event) {
|
void onWifiDisconnect(const WiFiEventStationModeDisconnected& event) {
|
||||||
|
@ -197,6 +199,7 @@ class PubMqtt {
|
||||||
case SYSTEM_EVENT_STA_GOT_IP:
|
case SYSTEM_EVENT_STA_GOT_IP:
|
||||||
DPRINTLN(DBG_VERBOSE, F("MQTT connecting"));
|
DPRINTLN(DBG_VERBOSE, F("MQTT connecting"));
|
||||||
mClient.connect();
|
mClient.connect();
|
||||||
|
mEnReconnect = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SYSTEM_EVENT_STA_DISCONNECTED:
|
case SYSTEM_EVENT_STA_DISCONNECTED:
|
||||||
|
@ -360,15 +363,15 @@ class PubMqtt {
|
||||||
(status == MQTT_STATUS_AVAIL_NOT_PROD) ? "not " : "",
|
(status == MQTT_STATUS_AVAIL_NOT_PROD) ? "not " : "",
|
||||||
(status == MQTT_STATUS_NOT_AVAIL_NOT_PROD) ? "" : "producing"
|
(status == MQTT_STATUS_NOT_AVAIL_NOT_PROD) ? "" : "producing"
|
||||||
);
|
);
|
||||||
publish(topic, val);
|
publish(topic, val, true);
|
||||||
|
|
||||||
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/available", iv->config->name);
|
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/available", iv->config->name);
|
||||||
snprintf(val, 40, "%d", status);
|
snprintf(val, 40, "%d", status);
|
||||||
publish(topic, val);
|
publish(topic, val, true);
|
||||||
|
|
||||||
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/last_success", iv->config->name);
|
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/last_success", iv->config->name);
|
||||||
snprintf(val, 40, "%i", iv->getLastTs(rec) * 1000);
|
snprintf(val, 40, "%i", iv->getLastTs(rec) * 1000);
|
||||||
publish(topic, val);
|
publish(topic, val, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// data
|
// data
|
||||||
|
|
29
src/utils/helper.cpp
Normal file
29
src/utils/helper.cpp
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// 2022 Ahoy, https://github.com/lumpapu/ahoy
|
||||||
|
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "helper.h"
|
||||||
|
|
||||||
|
namespace ah {
|
||||||
|
void ip2Arr(uint8_t ip[], const char *ipStr) {
|
||||||
|
memset(ip, 0, 4);
|
||||||
|
char *tmp = new char[strlen(ipStr)+1];
|
||||||
|
strncpy(tmp, ipStr, strlen(ipStr)+1);
|
||||||
|
char *p = strtok(tmp, ".");
|
||||||
|
uint8_t i = 0;
|
||||||
|
while(NULL != p) {
|
||||||
|
ip[i++] = atoi(p);
|
||||||
|
p = strtok(NULL, ".");
|
||||||
|
}
|
||||||
|
delete[] tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// note: char *str needs to be at least 16 bytes long
|
||||||
|
void ip2Char(uint8_t ip[], char *str) {
|
||||||
|
if(0 == ip[0])
|
||||||
|
str[0] = '\0';
|
||||||
|
else
|
||||||
|
snprintf(str, 16, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
|
||||||
|
}
|
||||||
|
}
|
19
src/utils/helper.h
Normal file
19
src/utils/helper.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// 2022 Ahoy, https://ahoydtu.de
|
||||||
|
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef __HELPER_H__
|
||||||
|
#define __HELPER_H__
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstring>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
namespace ah {
|
||||||
|
void ip2Arr(uint8_t ip[], const char *ipStr);
|
||||||
|
void ip2Char(uint8_t ip[], char *str);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /*__HELPER_H__*/
|
|
@ -196,9 +196,9 @@
|
||||||
parseStat(obj["statistics"]);
|
parseStat(obj["statistics"]);
|
||||||
parseIv(obj["inverter"]);
|
parseIv(obj["inverter"]);
|
||||||
parseWarnInfo(obj["warnings"], obj["infos"]);
|
parseWarnInfo(obj["warnings"], obj["infos"]);
|
||||||
document.getElementById("refresh").innerHTML = obj["refresh_interval"];
|
document.getElementById("refresh").innerHTML = 10;
|
||||||
if(exeOnce) {
|
if(exeOnce) {
|
||||||
window.setInterval("getAjax('/api/index', parse)", obj["refresh_interval"] * 1000);
|
window.setInterval("getAjax('/api/index', parse)", 10000);
|
||||||
exeOnce = false;
|
exeOnce = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "web.h"
|
#include "web.h"
|
||||||
|
|
||||||
#include "../utils/ahoyTimer.h"
|
#include "../utils/ahoyTimer.h"
|
||||||
|
#include "../utils/helper.h"
|
||||||
|
|
||||||
#include "html/h/index_html.h"
|
#include "html/h/index_html.h"
|
||||||
#include "html/h/login_html.h"
|
#include "html/h/login_html.h"
|
||||||
|
@ -343,28 +344,16 @@ void web::showSave(AsyncWebServerRequest *request) {
|
||||||
|
|
||||||
|
|
||||||
// static ip
|
// static ip
|
||||||
if(request->arg("ipAddr") != "") {
|
request->arg("ipAddr").toCharArray(buf, 20);
|
||||||
request->arg("ipAddr").toCharArray(buf, SSID_LEN);
|
ah::ip2Arr(mConfig->sys.ip.ip, buf);
|
||||||
ip2Arr(mConfig->sys.ip.ip, buf);
|
request->arg("ipMask").toCharArray(buf, 20);
|
||||||
if(request->arg("ipMask") != "") {
|
ah::ip2Arr(mConfig->sys.ip.mask, buf);
|
||||||
request->arg("ipMask").toCharArray(buf, SSID_LEN);
|
request->arg("ipDns1").toCharArray(buf, 20);
|
||||||
ip2Arr(mConfig->sys.ip.mask, buf);
|
ah::ip2Arr(mConfig->sys.ip.dns1, buf);
|
||||||
}
|
request->arg("ipDns2").toCharArray(buf, 20);
|
||||||
if(request->arg("ipDns1") != "") {
|
ah::ip2Arr(mConfig->sys.ip.dns2, buf);
|
||||||
request->arg("ipDns1").toCharArray(buf, SSID_LEN);
|
request->arg("ipGateway").toCharArray(buf, 20);
|
||||||
ip2Arr(mConfig->sys.ip.dns1, buf);
|
ah::ip2Arr(mConfig->sys.ip.gateway, buf);
|
||||||
}
|
|
||||||
if(request->arg("ipDns2") != "") {
|
|
||||||
request->arg("ipDns2").toCharArray(buf, SSID_LEN);
|
|
||||||
ip2Arr(mConfig->sys.ip.dns2, buf);
|
|
||||||
}
|
|
||||||
if(request->arg("ipGateway") != "") {
|
|
||||||
request->arg("ipGateway").toCharArray(buf, SSID_LEN);
|
|
||||||
ip2Arr(mConfig->sys.ip.gateway, buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
memset(&mConfig->sys.ip.ip, 0, 4);
|
|
||||||
|
|
||||||
|
|
||||||
// inverter
|
// inverter
|
||||||
|
@ -437,12 +426,14 @@ void web::showSave(AsyncWebServerRequest *request) {
|
||||||
String addr = request->arg("mqttAddr");
|
String addr = request->arg("mqttAddr");
|
||||||
addr.trim();
|
addr.trim();
|
||||||
addr.toCharArray(mConfig->mqtt.broker, MQTT_ADDR_LEN);
|
addr.toCharArray(mConfig->mqtt.broker, MQTT_ADDR_LEN);
|
||||||
request->arg("mqttUser").toCharArray(mConfig->mqtt.user, MQTT_USER_LEN);
|
|
||||||
if(request->arg("mqttPwd") != "{PWD}")
|
|
||||||
request->arg("mqttPwd").toCharArray(mConfig->mqtt.pwd, MQTT_PWD_LEN);
|
|
||||||
request->arg("mqttTopic").toCharArray(mConfig->mqtt.topic, MQTT_TOPIC_LEN);
|
|
||||||
mConfig->mqtt.port = request->arg("mqttPort").toInt();
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
mConfig->mqtt.broker[0] = '\0';
|
||||||
|
request->arg("mqttUser").toCharArray(mConfig->mqtt.user, MQTT_USER_LEN);
|
||||||
|
if(request->arg("mqttPwd") != "{PWD}")
|
||||||
|
request->arg("mqttPwd").toCharArray(mConfig->mqtt.pwd, MQTT_PWD_LEN);
|
||||||
|
request->arg("mqttTopic").toCharArray(mConfig->mqtt.topic, MQTT_TOPIC_LEN);
|
||||||
|
mConfig->mqtt.port = request->arg("mqttPort").toInt();
|
||||||
|
|
||||||
// serial console
|
// serial console
|
||||||
if(request->arg("serIntvl") != "") {
|
if(request->arg("serIntvl") != "") {
|
||||||
|
|
|
@ -64,15 +64,6 @@ class web {
|
||||||
void onSerial(AsyncWebServerRequest *request);
|
void onSerial(AsyncWebServerRequest *request);
|
||||||
void onSystem(AsyncWebServerRequest *request);
|
void onSystem(AsyncWebServerRequest *request);
|
||||||
|
|
||||||
void ip2Arr(uint8_t ip[], char *ipStr) {
|
|
||||||
char *p = strtok(ipStr, ".");
|
|
||||||
uint8_t i = 0;
|
|
||||||
while(NULL != p) {
|
|
||||||
ip[i++] = atoi(p);
|
|
||||||
p = strtok(NULL, ".");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ENABLE_JSON_EP
|
#ifdef ENABLE_JSON_EP
|
||||||
void showJson(void);
|
void showJson(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -332,13 +332,12 @@ void webApi::getSerial(JsonObject obj) {
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void webApi::getStaticIp(JsonObject obj) {
|
void webApi::getStaticIp(JsonObject obj) {
|
||||||
if(mConfig->sys.ip.ip[0] != 0) {
|
char buf[16];
|
||||||
obj[F("ip")] = ip2String(mConfig->sys.ip.ip);
|
ah::ip2Char(mConfig->sys.ip.ip, buf); obj[F("ip")] = String(buf);
|
||||||
obj[F("mask")] = ip2String(mConfig->sys.ip.mask);
|
ah::ip2Char(mConfig->sys.ip.mask, buf); obj[F("mask")] = String(buf);
|
||||||
obj[F("dns1")] = ip2String(mConfig->sys.ip.dns1);
|
ah::ip2Char(mConfig->sys.ip.dns1, buf); obj[F("dns1")] = String(buf);
|
||||||
obj[F("dns2")] = ip2String(mConfig->sys.ip.dns2);
|
ah::ip2Char(mConfig->sys.ip.dns2, buf); obj[F("dns2")] = String(buf);
|
||||||
obj[F("gateway")] = ip2String(mConfig->sys.ip.gateway);
|
ah::ip2Char(mConfig->sys.ip.gateway, buf); obj[F("gateway")] = String(buf);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -397,7 +396,7 @@ void webApi::getIndex(JsonObject obj) {
|
||||||
JsonArray warn = obj.createNestedArray(F("warnings"));
|
JsonArray warn = obj.createNestedArray(F("warnings"));
|
||||||
if(!mApp->mSys->Radio.isChipConnected())
|
if(!mApp->mSys->Radio.isChipConnected())
|
||||||
warn.add(F("your NRF24 module can't be reached, check the wiring and pinout"));
|
warn.add(F("your NRF24 module can't be reached, check the wiring and pinout"));
|
||||||
if(!mApp->mqttIsConnected())
|
if((!mApp->mqttIsConnected()) && (String(mConfig->mqtt.broker).length() > 0))
|
||||||
warn.add(F("MQTT is not connected"));
|
warn.add(F("MQTT is not connected"));
|
||||||
|
|
||||||
JsonArray info = obj.createNestedArray(F("infos"));
|
JsonArray info = obj.createNestedArray(F("infos"));
|
||||||
|
|
|
@ -63,12 +63,6 @@ class webApi {
|
||||||
return (int)(value * 1000 + 0.5) / 1000.0;
|
return (int)(value * 1000 + 0.5) / 1000.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
String ip2String(uint8_t ip[]) {
|
|
||||||
char str[16];
|
|
||||||
snprintf(str, 16, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
|
|
||||||
return String(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
AsyncWebServer *mSrv;
|
AsyncWebServer *mSrv;
|
||||||
app *mApp;
|
app *mApp;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue