mirror of
https://github.com/lumapu/ahoy.git
synced 2025-04-29 10:16:21 +02:00
fix #338, needs verifcation from homeassistant users
added download link for settings on setup.html and update.html
This commit is contained in:
parent
38bb3fd7e2
commit
a595950d7d
6 changed files with 77 additions and 29 deletions
|
@ -71,6 +71,11 @@ void app::loop(void) {
|
||||||
DPRINTLN(DBG_INFO, "[NTP]: " + getDateTimeStr(mTimestamp));
|
DPRINTLN(DBG_INFO, "[NTP]: " + getDateTimeStr(mTimestamp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(mFlagSendDiscoveryConfig) {
|
||||||
|
mFlagSendDiscoveryConfig = false;
|
||||||
|
sendMqttDiscoveryConfig();
|
||||||
|
}
|
||||||
|
|
||||||
if(mShouldReboot) {
|
if(mShouldReboot) {
|
||||||
DPRINTLN(DBG_INFO, F("Rebooting..."));
|
DPRINTLN(DBG_INFO, F("Rebooting..."));
|
||||||
ESP.restart();
|
ESP.restart();
|
||||||
|
@ -155,10 +160,6 @@ void app::loop(void) {
|
||||||
char val[10];
|
char val[10];
|
||||||
snprintf(val, 10, "%ld", millis()/1000);
|
snprintf(val, 10, "%ld", millis()/1000);
|
||||||
|
|
||||||
#ifndef __MQTT_NO_DISCOVERCONFIG__
|
|
||||||
// MQTTDiscoveryConfig nur wenn nicht abgeschaltet.
|
|
||||||
sendMqttDiscoveryConfig();
|
|
||||||
#endif
|
|
||||||
mMqtt.sendMsg("uptime", val);
|
mMqtt.sendMsg("uptime", val);
|
||||||
|
|
||||||
#ifdef __MQTT_TEST__
|
#ifdef __MQTT_TEST__
|
||||||
|
@ -598,13 +599,14 @@ void app::sendMqttDiscoveryConfig(void) {
|
||||||
Inverter<> *iv = mSys->getInverterByPos(id);
|
Inverter<> *iv = mSys->getInverterByPos(id);
|
||||||
if(NULL != iv) {
|
if(NULL != iv) {
|
||||||
record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
||||||
if(iv->isAvailable(mTimestamp, rec) && mMqttConfigSendState[id] != true) {
|
// TODO: next line makes no sense if discovery config is send manually by button
|
||||||
|
//if(iv->isAvailable(mTimestamp, rec) && mMqttConfigSendState[id] != true) {
|
||||||
DynamicJsonDocument deviceDoc(128);
|
DynamicJsonDocument deviceDoc(128);
|
||||||
deviceDoc["name"] = iv->name;
|
deviceDoc["name"] = iv->name;
|
||||||
deviceDoc["ids"] = String(iv->serial.u64, HEX);
|
deviceDoc["ids"] = String(iv->serial.u64, HEX);
|
||||||
deviceDoc["cu"] = F("http://") + String(WiFi.localIP().toString());
|
deviceDoc["cu"] = F("http://") + String(WiFi.localIP().toString());
|
||||||
deviceDoc["mf"] = "Hoymiles";
|
deviceDoc["mf"] = "Hoymiles";
|
||||||
deviceDoc["mdl"] = iv->name;
|
deviceDoc["mdl"] = iv->name;
|
||||||
JsonObject deviceObj = deviceDoc.as<JsonObject>();
|
JsonObject deviceObj = deviceDoc.as<JsonObject>();
|
||||||
DynamicJsonDocument doc(384);
|
DynamicJsonDocument doc(384);
|
||||||
|
|
||||||
|
@ -620,28 +622,28 @@ void app::sendMqttDiscoveryConfig(void) {
|
||||||
const char* devCls = getFieldDeviceClass(rec->assign[i].fieldId);
|
const char* devCls = getFieldDeviceClass(rec->assign[i].fieldId);
|
||||||
const char* stateCls = getFieldStateClass(rec->assign[i].fieldId);
|
const char* stateCls = getFieldStateClass(rec->assign[i].fieldId);
|
||||||
|
|
||||||
doc["name"] = name;
|
doc["name"] = name;
|
||||||
doc["stat_t"] = stateTopic;
|
doc["stat_t"] = stateTopic;
|
||||||
doc["unit_of_meas"] = iv->getUnit(i, rec);
|
doc["unit_of_meas"] = iv->getUnit(i, rec);
|
||||||
doc["uniq_id"] = String(iv->serial.u64, HEX) + "_" + uniq_id;
|
doc["uniq_id"] = String(iv->serial.u64, HEX) + "_" + uniq_id;
|
||||||
doc["dev"] = deviceObj;
|
doc["dev"] = deviceObj;
|
||||||
doc["exp_aft"] = mMqttInterval + 5; // add 5 sec if connection is bad or ESP too slow
|
doc["exp_aft"] = mMqttInterval + 5; // add 5 sec if connection is bad or ESP too slow
|
||||||
if (devCls != NULL) {
|
if (devCls != NULL)
|
||||||
doc["dev_cla"] = devCls;
|
doc["dev_cla"] = devCls;
|
||||||
}
|
if (stateCls != NULL)
|
||||||
if (stateCls != NULL) {
|
|
||||||
doc["stat_cla"] = stateCls;
|
doc["stat_cla"] = stateCls;
|
||||||
}
|
|
||||||
|
|
||||||
serializeJson(doc, buffer);
|
serializeJson(doc, buffer);
|
||||||
mMqtt.sendMsg2(discoveryTopic, buffer, true);
|
mMqtt.sendMsg2(discoveryTopic, buffer, true);
|
||||||
|
//DPRINTLN(DBG_INFO, F("mqtt sent"));
|
||||||
doc.clear();
|
doc.clear();
|
||||||
|
|
||||||
yield();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: remove this field, obsolete?
|
||||||
mMqttConfigSendState[id] = true;
|
mMqttConfigSendState[id] = true;
|
||||||
}
|
|
||||||
|
yield();
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -674,6 +676,7 @@ void app::resetSystem(void) {
|
||||||
mUptimeSecs = 0;
|
mUptimeSecs = 0;
|
||||||
mPrevMillis = 0;
|
mPrevMillis = 0;
|
||||||
mUpdateNtp = false;
|
mUpdateNtp = false;
|
||||||
|
mFlagSendDiscoveryConfig = false;
|
||||||
|
|
||||||
mNtpRefreshTicker = 0;
|
mNtpRefreshTicker = 0;
|
||||||
mNtpRefreshInterval = NTP_REFRESH_INTERVAL; // [ms]
|
mNtpRefreshInterval = NTP_REFRESH_INTERVAL; // [ms]
|
||||||
|
|
|
@ -156,20 +156,23 @@ class app {
|
||||||
inline bool getSettingsValid(void) { return mSettingsValid; }
|
inline bool getSettingsValid(void) { return mSettingsValid; }
|
||||||
inline bool getRebootRequestState(void) { return mShowRebootRequest; }
|
inline bool getRebootRequestState(void) { return mShowRebootRequest; }
|
||||||
|
|
||||||
|
|
||||||
HmSystemType *mSys;
|
HmSystemType *mSys;
|
||||||
bool mShouldReboot;
|
bool mShouldReboot;
|
||||||
|
bool mFlagSendDiscoveryConfig;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void resetSystem(void);
|
void resetSystem(void);
|
||||||
void loadDefaultConfig(void);
|
void loadDefaultConfig(void);
|
||||||
void loadEEpconfig(void);
|
void loadEEpconfig(void);
|
||||||
void setupMqtt(void);
|
void setupMqtt(void);
|
||||||
|
|
||||||
|
void sendMqttDiscoveryConfig(void);
|
||||||
|
|
||||||
bool buildPayload(uint8_t id);
|
bool buildPayload(uint8_t id);
|
||||||
void processPayload(bool retransmit);
|
void processPayload(bool retransmit);
|
||||||
void processPayload(bool retransmit, uint8_t cmd);
|
void processPayload(bool retransmit, uint8_t cmd);
|
||||||
|
|
||||||
void sendMqttDiscoveryConfig(void);
|
|
||||||
const char* getFieldDeviceClass(uint8_t fieldId);
|
const char* getFieldDeviceClass(uint8_t fieldId);
|
||||||
const char* getFieldStateClass(uint8_t fieldId);
|
const char* getFieldStateClass(uint8_t fieldId);
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@
|
||||||
<label for="ntpBtn">set system time</label>
|
<label for="ntpBtn">set system time</label>
|
||||||
<input type="button" name="ntpBtn" id="ntpBtn" class="btn" value="from browser" onclick="setTime()"/>
|
<input type="button" name="ntpBtn" id="ntpBtn" class="btn" value="from browser" onclick="setTime()"/>
|
||||||
<input type="button" name="ntpSync" id="ntpSync" class="btn" value="sync NTP" onclick="syncTime()"/>
|
<input type="button" name="ntpSync" id="ntpSync" class="btn" value="sync NTP" onclick="syncTime()"/>
|
||||||
<span id="apiResult">n/a</span>
|
<span id="apiResultNtp"></span>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -85,6 +85,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"/>
|
<input type="text" class="text" name="mqttTopic"/>
|
||||||
|
<label for="mqttBtn">Discovery Config (homeassistant)</label>
|
||||||
|
<input type="button" name="mqttDiscovery" id="mqttDiscovery" class="btn" value="send" onclick="sendDiscoveryConfig()"/>
|
||||||
|
<span id="apiResultMqtt"></span>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -110,7 +113,9 @@
|
||||||
|
|
||||||
<label for="reboot">Reboot device after successful save</label>
|
<label for="reboot">Reboot device after successful save</label>
|
||||||
<input type="checkbox" class="cb" name="reboot"/>
|
<input type="checkbox" class="cb" name="reboot"/>
|
||||||
<input type="submit" value="save" class="btn right"/>
|
<input type="submit" value="save" class="btn right"/><br/>
|
||||||
|
<br/>
|
||||||
|
<a href="/get_setup" target="_blank">Download your settings (JSON file)</a> (only saved values)
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -132,8 +137,16 @@
|
||||||
ivHtml(JSON.parse('{"name":"","serial":"","channels":4,"ch_max_power":[0,0,0,0],"ch_name":["","","",""]}'), highestId + 1);
|
ivHtml(JSON.parse('{"name":"","serial":"","channels":4,"ch_max_power":[0,0,0,0],"ch_name":["","","",""]}'), highestId + 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
function apiCb(obj) {
|
function apiCbNtp(obj) {
|
||||||
var e = document.getElementById("apiResult");
|
var e = document.getElementById("apiResultNtp");
|
||||||
|
if(obj["success"])
|
||||||
|
e.innerHTML = "command excuted";
|
||||||
|
else
|
||||||
|
e.innerHTML = "Error: " + obj["error"];
|
||||||
|
}
|
||||||
|
|
||||||
|
function apiCbMqtt(obj) {
|
||||||
|
var e = document.getElementById("apiResultMqtt");
|
||||||
if(obj["success"])
|
if(obj["success"])
|
||||||
e.innerHTML = "command excuted";
|
e.innerHTML = "command excuted";
|
||||||
else
|
else
|
||||||
|
@ -146,13 +159,19 @@
|
||||||
var obj = new Object();
|
var obj = new Object();
|
||||||
obj.cmd = "set_time";
|
obj.cmd = "set_time";
|
||||||
obj.ts = parseInt(offset + (date.getTime() / 1000));
|
obj.ts = parseInt(offset + (date.getTime() / 1000));
|
||||||
getAjax("/api/setup", apiCb, "POST", JSON.stringify(obj));
|
getAjax("/api/setup", apiCbNtp, "POST", JSON.stringify(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
function syncTime() {
|
function syncTime() {
|
||||||
var obj = new Object();
|
var obj = new Object();
|
||||||
obj.cmd = "sync_ntp";
|
obj.cmd = "sync_ntp";
|
||||||
getAjax("/api/setup", apiCb, "POST", JSON.stringify(obj));
|
getAjax("/api/setup", apiCbNtp, "POST", JSON.stringify(obj));
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendDiscoveryConfig() {
|
||||||
|
var obj = new Object();
|
||||||
|
obj.cmd = "discovery_cfg";
|
||||||
|
getAjax("/api/setup", apiCbMqtt, "POST", JSON.stringify(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
function ivHtml(obj, id) {
|
function ivHtml(obj, id) {
|
||||||
|
|
|
@ -10,7 +10,9 @@
|
||||||
<h1>Update</h1>
|
<h1>Update</h1>
|
||||||
<div id="content" class="content">
|
<div id="content" class="content">
|
||||||
<div>
|
<div>
|
||||||
Make sure that you have noted all your settings before starting an update. New versions may have changed their memory layout which can break your existing settings.
|
Make sure that you have noted all your settings before starting an update. New versions may have changed their memory layout which can break your existing settings.<br/>
|
||||||
|
<br/>
|
||||||
|
<a href="/get_setup" target="_blank">Download your settings (JSON file)</a>
|
||||||
</div>
|
</div>
|
||||||
<br/><br/>
|
<br/><br/>
|
||||||
<form method="POST" action="/update" enctype="multipart/form-data" accept-charset="utf-8">
|
<form method="POST" action="/update" enctype="multipart/form-data" accept-charset="utf-8">
|
||||||
|
|
|
@ -26,6 +26,8 @@ void webApi::setup(void) {
|
||||||
mSrv->on("/api", HTTP_GET, std::bind(&webApi::onApi, this, std::placeholders::_1));
|
mSrv->on("/api", HTTP_GET, std::bind(&webApi::onApi, this, std::placeholders::_1));
|
||||||
mSrv->on("/api", HTTP_POST, std::bind(&webApi::onApiPost, this, std::placeholders::_1)).onBody(
|
mSrv->on("/api", HTTP_POST, std::bind(&webApi::onApiPost, this, std::placeholders::_1)).onBody(
|
||||||
std::bind(&webApi::onApiPostBody, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
|
std::bind(&webApi::onApiPostBody, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
|
||||||
|
|
||||||
|
mSrv->on("/get_setup", HTTP_GET, std::bind(&webApi::onDwnldSetup, this, std::placeholders::_1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -117,6 +119,21 @@ void webApi::getNotFound(JsonObject obj, String url) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void webApi::onDwnldSetup(AsyncWebServerRequest *request) {
|
||||||
|
AsyncJsonResponse* response = new AsyncJsonResponse(false, 8192);
|
||||||
|
JsonObject root = response->getRoot();
|
||||||
|
|
||||||
|
getSetup(root);
|
||||||
|
|
||||||
|
response->setLength();
|
||||||
|
response->addHeader("Content-Type", "application/octet-stream");
|
||||||
|
response->addHeader("Content-Description", "File Transfer");
|
||||||
|
response->addHeader("Content-Disposition", "attachment; filename=ahoy_setup.json");
|
||||||
|
request->send(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void webApi::getSystem(JsonObject obj) {
|
void webApi::getSystem(JsonObject obj) {
|
||||||
obj[F("ssid")] = mSysCfg->stationSsid;
|
obj[F("ssid")] = mSysCfg->stationSsid;
|
||||||
|
@ -396,6 +413,8 @@ bool webApi::setSetup(DynamicJsonDocument jsonIn, JsonObject jsonOut) {
|
||||||
mApp->setTimestamp(jsonIn[F("ts")]);
|
mApp->setTimestamp(jsonIn[F("ts")]);
|
||||||
else if(F("sync_ntp") == jsonIn[F("cmd")])
|
else if(F("sync_ntp") == jsonIn[F("cmd")])
|
||||||
mApp->setTimestamp(0); // 0: update ntp flag
|
mApp->setTimestamp(0); // 0: update ntp flag
|
||||||
|
else if(F("discovery_cfg") == jsonIn[F("cmd")])
|
||||||
|
mApp->mFlagSendDiscoveryConfig = true; // for homeassistant
|
||||||
else {
|
else {
|
||||||
jsonOut[F("error")] = F("unknown cmd");
|
jsonOut[F("error")] = F("unknown cmd");
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -26,6 +26,7 @@ class webApi {
|
||||||
void onApiPost(AsyncWebServerRequest *request);
|
void onApiPost(AsyncWebServerRequest *request);
|
||||||
void onApiPostBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total);
|
void onApiPostBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total);
|
||||||
void getNotFound(JsonObject obj, String url);
|
void getNotFound(JsonObject obj, String url);
|
||||||
|
void onDwnldSetup(AsyncWebServerRequest *request);
|
||||||
|
|
||||||
void getSystem(JsonObject obj);
|
void getSystem(JsonObject obj);
|
||||||
void getStatistics(JsonObject obj);
|
void getStatistics(JsonObject obj);
|
||||||
|
@ -36,6 +37,7 @@ class webApi {
|
||||||
void getRadio(JsonObject obj);
|
void getRadio(JsonObject obj);
|
||||||
void getSerial(JsonObject obj);
|
void getSerial(JsonObject obj);
|
||||||
|
|
||||||
|
|
||||||
void getIndex(JsonObject obj);
|
void getIndex(JsonObject obj);
|
||||||
void getSetup(JsonObject obj);
|
void getSetup(JsonObject obj);
|
||||||
void getLive(JsonObject obj);
|
void getLive(JsonObject obj);
|
||||||
|
|
Loading…
Add table
Reference in a new issue