mirror of
https://github.com/lumapu/ahoy.git
synced 2025-08-06 09:58:23 +02:00
Merge branch 'development03' of https://github.com/geronet1/ahoy into development03
This commit is contained in:
commit
c1cdb1b06c
16 changed files with 74 additions and 13 deletions
|
@ -1,5 +1,12 @@
|
||||||
# Development Changes
|
# Development Changes
|
||||||
|
|
||||||
|
## 0.8.110 - 2024-04-11
|
||||||
|
* revert CMT2300A changes #1553
|
||||||
|
* merged PR: fix closing tag #1584
|
||||||
|
* add disable retain flag #1582
|
||||||
|
* fix German translation #1569
|
||||||
|
* improved `Wizard`
|
||||||
|
|
||||||
## 0.8.109 - 2024-04-09
|
## 0.8.109 - 2024-04-09
|
||||||
* fix hal patch
|
* fix hal patch
|
||||||
|
|
||||||
|
|
|
@ -168,7 +168,7 @@ class app : public IApp, public ah::Scheduler {
|
||||||
|
|
||||||
#if !defined(ETHERNET)
|
#if !defined(ETHERNET)
|
||||||
bool getAvailNetworks(JsonObject obj) override {
|
bool getAvailNetworks(JsonObject obj) override {
|
||||||
return mNetwork->getAvailNetworks(obj);
|
return mNetwork->getAvailNetworks(obj, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupStation(void) override {
|
void setupStation(void) override {
|
||||||
|
@ -204,6 +204,10 @@ class app : public IApp, public ah::Scheduler {
|
||||||
return mVersionModules;
|
return mVersionModules;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addOnce(ah::scdCb c, uint32_t timeout, const char *name) override {
|
||||||
|
once(c, timeout, name);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t getSunrise() override {
|
uint32_t getSunrise() override {
|
||||||
return mSunrise;
|
return mSunrise;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "ESPAsyncWebServer.h"
|
#include "ESPAsyncWebServer.h"
|
||||||
|
#include "utils/scheduler.h"
|
||||||
|
|
||||||
// abstract interface to App. Make members of App accessible from child class
|
// abstract interface to App. Make members of App accessible from child class
|
||||||
// like web or API without forward declaration
|
// like web or API without forward declaration
|
||||||
|
@ -25,6 +26,8 @@ class IApp {
|
||||||
virtual const char *getVersion() = 0;
|
virtual const char *getVersion() = 0;
|
||||||
virtual const char *getVersionModules() = 0;
|
virtual const char *getVersionModules() = 0;
|
||||||
|
|
||||||
|
virtual void addOnce(ah::scdCb c, uint32_t timeout, const char *name) = 0;
|
||||||
|
|
||||||
#if !defined(ETHERNET)
|
#if !defined(ETHERNET)
|
||||||
virtual bool getAvailNetworks(JsonObject obj) = 0;
|
virtual bool getAvailNetworks(JsonObject obj) = 0;
|
||||||
virtual void setupStation(void) = 0;
|
virtual void setupStation(void) = 0;
|
||||||
|
|
|
@ -166,6 +166,7 @@ typedef struct {
|
||||||
char topic[MQTT_TOPIC_LEN];
|
char topic[MQTT_TOPIC_LEN];
|
||||||
bool json;
|
bool json;
|
||||||
uint16_t interval;
|
uint16_t interval;
|
||||||
|
bool enableRetain;
|
||||||
} cfgMqtt_t;
|
} cfgMqtt_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -492,6 +493,7 @@ class settings {
|
||||||
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.mqtt.interval = 0; // off
|
||||||
mCfg.mqtt.json = 0; // off
|
mCfg.mqtt.json = 0; // off
|
||||||
|
mCfg.mqtt.enableRetain = true;
|
||||||
|
|
||||||
mCfg.inst.sendInterval = SEND_INTERVAL;
|
mCfg.inst.sendInterval = SEND_INTERVAL;
|
||||||
mCfg.inst.rstYieldMidNight = false;
|
mCfg.inst.rstYieldMidNight = false;
|
||||||
|
@ -749,6 +751,7 @@ class settings {
|
||||||
obj[F("topic")] = mCfg.mqtt.topic;
|
obj[F("topic")] = mCfg.mqtt.topic;
|
||||||
obj[F("json")] = mCfg.mqtt.json;
|
obj[F("json")] = mCfg.mqtt.json;
|
||||||
obj[F("intvl")] = mCfg.mqtt.interval;
|
obj[F("intvl")] = mCfg.mqtt.interval;
|
||||||
|
obj[F("retain")] = mCfg.mqtt.enableRetain;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
getVal<uint16_t>(obj, F("port"), &mCfg.mqtt.port);
|
getVal<uint16_t>(obj, F("port"), &mCfg.mqtt.port);
|
||||||
|
@ -759,6 +762,7 @@ class settings {
|
||||||
getChar(obj, F("clientId"), mCfg.mqtt.clientId, MQTT_CLIENTID_LEN);
|
getChar(obj, F("clientId"), mCfg.mqtt.clientId, MQTT_CLIENTID_LEN);
|
||||||
getChar(obj, F("pwd"), mCfg.mqtt.pwd, MQTT_PWD_LEN);
|
getChar(obj, F("pwd"), mCfg.mqtt.pwd, MQTT_PWD_LEN);
|
||||||
getChar(obj, F("topic"), mCfg.mqtt.topic, MQTT_TOPIC_LEN);
|
getChar(obj, F("topic"), mCfg.mqtt.topic, MQTT_TOPIC_LEN);
|
||||||
|
getVal<bool>(obj, F("retain"), &mCfg.mqtt.enableRetain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
#define VERSION_MAJOR 0
|
#define VERSION_MAJOR 0
|
||||||
#define VERSION_MINOR 8
|
#define VERSION_MINOR 8
|
||||||
#define VERSION_PATCH 108
|
#define VERSION_PATCH 110
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t ch;
|
uint8_t ch;
|
||||||
|
|
|
@ -248,12 +248,14 @@ class Cmt2300a {
|
||||||
}
|
}
|
||||||
|
|
||||||
CmtStatus tx(uint8_t buf[], uint8_t len) {
|
CmtStatus tx(uint8_t buf[], uint8_t len) {
|
||||||
|
if(mTxPending)
|
||||||
|
return CmtStatus::ERR_TX_PENDING;
|
||||||
|
|
||||||
if(mInRxMode) {
|
if(mInRxMode) {
|
||||||
mInRxMode = false;
|
mInRxMode = false;
|
||||||
if(!cmtSwitchStatus(CMT2300A_GO_STBY, CMT2300A_STA_STBY))
|
if(!cmtSwitchStatus(CMT2300A_GO_STBY, CMT2300A_STA_STBY))
|
||||||
return CmtStatus::ERR_SWITCH_STATE;
|
return CmtStatus::ERR_SWITCH_STATE;
|
||||||
}
|
}
|
||||||
mTxPending = false; // safety
|
|
||||||
|
|
||||||
mSpi.writeReg(CMT2300A_CUS_INT1_CTL, CMT2300A_INT_SEL_TX_DONE);
|
mSpi.writeReg(CMT2300A_CUS_INT1_CTL, CMT2300A_INT_SEL_TX_DONE);
|
||||||
|
|
||||||
|
|
|
@ -90,12 +90,9 @@ class AhoyNetwork {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(ETHERNET)
|
#if !defined(ETHERNET)
|
||||||
bool getAvailNetworks(JsonObject obj) {
|
bool getAvailNetworks(JsonObject obj, IApp *app) {
|
||||||
if(!mScanActive) {
|
if(!mScanActive) {
|
||||||
mScanActive = true;
|
app->addOnce([this]() {scan();}, 1, "scan");
|
||||||
if(NetworkState::GOT_IP != mStatus)
|
|
||||||
WiFi.disconnect();
|
|
||||||
WiFi.scanNetworks(true, true);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,6 +114,13 @@ class AhoyNetwork {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void scan(void) {
|
||||||
|
mScanActive = true;
|
||||||
|
if(NetworkState::GOT_IP != mStatus)
|
||||||
|
WiFi.disconnect();
|
||||||
|
WiFi.scanNetworks(true, true);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -63,6 +63,7 @@ class AhoyWifiAp {
|
||||||
#if defined(ETHERNET)
|
#if defined(ETHERNET)
|
||||||
WiFi.mode(WIFI_OFF);
|
WiFi.mode(WIFI_OFF);
|
||||||
#else
|
#else
|
||||||
|
WiFi.scanDelete();
|
||||||
WiFi.mode(WIFI_STA);
|
WiFi.mode(WIFI_STA);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ class AhoyWifi : public AhoyNetwork {
|
||||||
|
|
||||||
DBGPRINT(F("connect to network '"));
|
DBGPRINT(F("connect to network '"));
|
||||||
DBGPRINT(mConfig->sys.stationSsid);
|
DBGPRINT(mConfig->sys.stationSsid);
|
||||||
|
DBGPRINTLN(F("'"));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -205,6 +205,9 @@ class PubMqtt {
|
||||||
else
|
else
|
||||||
snprintf(mTopic.data(), mTopic.size(), "%s", subTopic);
|
snprintf(mTopic.data(), mTopic.size(), "%s", subTopic);
|
||||||
|
|
||||||
|
if(!mCfgMqtt->enableRetain)
|
||||||
|
retained = false;
|
||||||
|
|
||||||
mClient.publish(mTopic.data(), qos, retained, payload);
|
mClient.publish(mTopic.data(), qos, retained, payload);
|
||||||
yield();
|
yield();
|
||||||
mTxCnt++;
|
mTxCnt++;
|
||||||
|
|
|
@ -489,7 +489,9 @@ class RestApi {
|
||||||
|
|
||||||
void getHtmlFactory(AsyncWebServerRequest *request, JsonObject obj) {
|
void getHtmlFactory(AsyncWebServerRequest *request, JsonObject obj) {
|
||||||
getGeneric(request, obj.createNestedObject(F("generic")));
|
getGeneric(request, obj.createNestedObject(F("generic")));
|
||||||
obj[F("html")] = F("Factory reset? <a class=\"btn\" href=\"/factorytrue\">yes</a> <a class=\"btn\" href=\"/\">no</a>");
|
char tmp[200];
|
||||||
|
snprintf(tmp, 200, "%s <a class=\"btn\" href=\"/factorytrue\">%s</a> <a class=\"btn\" href=\"/\">%s</a>", FACTORY_RESET, BTN_YES, BTN_NO);
|
||||||
|
obj[F("html")] = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void getHtmlFactoryTrue(AsyncWebServerRequest *request, JsonObject obj) {
|
void getHtmlFactoryTrue(AsyncWebServerRequest *request, JsonObject obj) {
|
||||||
|
@ -712,6 +714,7 @@ class RestApi {
|
||||||
obj[F("topic")] = String(mConfig->mqtt.topic);
|
obj[F("topic")] = String(mConfig->mqtt.topic);
|
||||||
obj[F("json")] = (bool) mConfig->mqtt.json;
|
obj[F("json")] = (bool) mConfig->mqtt.json;
|
||||||
obj[F("interval")] = String(mConfig->mqtt.interval);
|
obj[F("interval")] = String(mConfig->mqtt.interval);
|
||||||
|
obj[F("retain")] = (bool)mConfig->mqtt.enableRetain;
|
||||||
}
|
}
|
||||||
|
|
||||||
void getNtp(JsonObject obj) {
|
void getNtp(JsonObject obj) {
|
||||||
|
|
|
@ -250,6 +250,10 @@
|
||||||
<span id="apiResultMqtt"></span>
|
<span id="apiResultMqtt"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-8 col-sm-3">{#RETAIN}</div>
|
||||||
|
<div class="col-4 col-sm-9"><input type="checkbox" name="retain"/></div>
|
||||||
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -286,7 +290,7 @@
|
||||||
<div id="screenSaver"></div>
|
<div id="screenSaver"></div>
|
||||||
<div class="row mb-3" id="luminanceOption">
|
<div class="row mb-3" id="luminanceOption">
|
||||||
<div class="col-12 col-sm-3 my-2">{#DISP_LUMINANCE}</div>
|
<div class="col-12 col-sm-3 my-2">{#DISP_LUMINANCE}</div>
|
||||||
<div class="col-12 col-sm-9"><input type="number" name="disp_cont" min="0" max="255"></select></div>
|
<div class="col-12 col-sm-9"><input type="number" name="disp_cont" min="0" max="255"></div>
|
||||||
</div>
|
</div>
|
||||||
<p class="des">{#DISP_PINOUT}</p>
|
<p class="des">{#DISP_PINOUT}</p>
|
||||||
<div id="dispPins"></div>
|
<div id="dispPins"></div>
|
||||||
|
@ -295,7 +299,7 @@
|
||||||
<p class="des">{#GRAPH_OPTIONS}</p>
|
<p class="des">{#GRAPH_OPTIONS}</p>
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<div class="col-12 col-sm-3 my-2">{#GRAPH_SHOW_RATIO}</div>
|
<div class="col-12 col-sm-3 my-2">{#GRAPH_SHOW_RATIO}</div>
|
||||||
<div class="col-12 col-sm-9"><input type="number" name="disp_graph_ratio" min="0" max="100"></select></div>
|
<div class="col-12 col-sm-9"><input type="number" name="disp_graph_ratio" min="0" max="100"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="graphSize"></div>
|
<div id="graphSize"></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -927,6 +931,7 @@
|
||||||
for(var i of [["Addr", "broker"], ["Port", "port"], ["ClientId", "clientId"], ["User", "user"], ["Pwd", "pwd"], ["Topic", "topic"], ["Interval", "interval"]])
|
for(var i of [["Addr", "broker"], ["Port", "port"], ["ClientId", "clientId"], ["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]];
|
||||||
document.getElementsByName("mqttJson")[0].checked = obj["json"];
|
document.getElementsByName("mqttJson")[0].checked = obj["json"];
|
||||||
|
document.getElementsByName("retain")[0].checked = obj.retain
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseNtp(obj) {
|
function parseNtp(obj) {
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
</form>
|
</form>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<div class="row mt-4">
|
<div class="row mt-4">
|
||||||
<a href="https://fw.ahoydtu.de" target="_blank">{#DOWNLOADS}<a/>
|
<a href="https://fw.ahoydtu.de" target="_blank">{#DOWNLOADS}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -72,4 +72,22 @@
|
||||||
#define BTN_REBOOT "Reboot"
|
#define BTN_REBOOT "Reboot"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef LANG_DE
|
||||||
|
#define BTN_REBOOT "Ahoy neustarten"
|
||||||
|
#else /*LANG_EN*/
|
||||||
|
#define BTN_REBOOT "Reboot"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LANG_DE
|
||||||
|
#define BTN_YES "ja"
|
||||||
|
#else /*LANG_EN*/
|
||||||
|
#define BTN_YES "yes"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LANG_DE
|
||||||
|
#define BTN_NO "nein"
|
||||||
|
#else /*LANG_EN*/
|
||||||
|
#define BTN_NO "no"
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /*__LANG_H__*/
|
#endif /*__LANG_H__*/
|
||||||
|
|
|
@ -106,7 +106,7 @@
|
||||||
{
|
{
|
||||||
"token": "NETWORK_SUCCESS",
|
"token": "NETWORK_SUCCESS",
|
||||||
"en": "success, got following IP in your network: ",
|
"en": "success, got following IP in your network: ",
|
||||||
"de": "Verindung erfolgreich. AhoyDTU hat die folgende IP bekommen: "
|
"de": "Verbindung erfolgreich. AhoyDTU hat die folgende IP bekommen: "
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"token": "BTN_FINISH",
|
"token": "BTN_FINISH",
|
||||||
|
@ -418,6 +418,11 @@
|
||||||
"en": "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)",
|
"en": "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)",
|
||||||
"de": "Wechselrichterdaten in fixem Intervall schicken, auch wenn es keine Änderung gab. Ein Wert von '0' deaktiviert das fixe Intervall, die Wechselrichterdaten werden übertragen, sobald neue zur Verfügung stehen. (Standard: 0)"
|
"de": "Wechselrichterdaten in fixem Intervall schicken, auch wenn es keine Änderung gab. Ein Wert von '0' deaktiviert das fixe Intervall, die Wechselrichterdaten werden übertragen, sobald neue zur Verfügung stehen. (Standard: 0)"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"token": "RETAIN",
|
||||||
|
"en": "enable retain flag",
|
||||||
|
"de": "'Retain Flag' aktivieren"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"token": "DISPLAY_CONFIG",
|
"token": "DISPLAY_CONFIG",
|
||||||
"en": "Display Config",
|
"en": "Display Config",
|
||||||
|
|
|
@ -584,6 +584,7 @@ class Web {
|
||||||
mConfig->mqtt.json = (request->arg("mqttJson") == "on");
|
mConfig->mqtt.json = (request->arg("mqttJson") == "on");
|
||||||
mConfig->mqtt.port = request->arg("mqttPort").toInt();
|
mConfig->mqtt.port = request->arg("mqttPort").toInt();
|
||||||
mConfig->mqtt.interval = request->arg("mqttInterval").toInt();
|
mConfig->mqtt.interval = request->arg("mqttInterval").toInt();
|
||||||
|
mConfig->mqtt.enableRetain = (request->arg("retain") == "on");
|
||||||
|
|
||||||
// serial console
|
// serial console
|
||||||
mConfig->serial.debug = (request->arg("serDbg") == "on");
|
mConfig->serial.debug = (request->arg("serDbg") == "on");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue