[OTA] Enable 2 clicks OTA update / one simple MQTT command (#1485)
* [OTA] Add automatic OTA updates This feature will enable to update the gateway with one button or a simple MQTT command. * [CI] Enable automatic OTA for nightly development builds And integrate the latest_version file creation into the CI Enable to specify a particular version and switch between dev and production builds
This commit is contained in:
1 parent
e83bfb0e4d
commit
454a062b3b
15 files changed
+186
-54
No files matched your search
+78
-18
@@ -596,9 +596,6 @@ void connectMQTT() {
|
||||
#endif
|
||||
#ifdef ZgatewayIR
|
||||
client.subscribe(subjectMultiGTWIR); // subject on which other OMG will publish, this OMG will store these msg and by the way don't republish them if they have been already published
|
||||
#endif
|
||||
#ifdef MQTT_HTTPS_FW_UPDATE
|
||||
client.subscribe(subjectFWUpdate);
|
||||
#endif
|
||||
Log.trace(F("Subscription OK to the subjects %s" CR), topic2);
|
||||
}
|
||||
@@ -653,7 +650,7 @@ void callback(char* topic, byte* payload, unsigned int length) {
|
||||
//launch the function to treat received data if this data concern OpenMQTTGateway
|
||||
if ((strstr(topic, subjectMultiGTWKey) != NULL) ||
|
||||
(strstr(topic, subjectGTWSendKey) != NULL) ||
|
||||
(strstr(topic, subjectFWUpdate) != NULL))
|
||||
(strstr(topic, subjectMQTTtoSYSupdate) != NULL))
|
||||
receivingMQTT(topic, (char*)p);
|
||||
|
||||
// Free the memory
|
||||
@@ -1509,6 +1506,10 @@ void loop() {
|
||||
connected = true;
|
||||
#if defined(ESP8266) || defined(ESP32) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__)
|
||||
if (now > (timer_sys_measures + (TimeBetweenReadingSYS * 1000)) || !timer_sys_measures) {
|
||||
# if defined(ESP32) && defined(MQTT_HTTPS_FW_UPDATE)
|
||||
if (!timer_sys_measures) // Only check for updates at start for ESP32
|
||||
checkForUpdates();
|
||||
# endif
|
||||
timer_sys_measures = millis();
|
||||
stateMeasures();
|
||||
# ifdef ZgatewayBT
|
||||
@@ -1691,6 +1692,7 @@ void stateMeasures() {
|
||||
SYSdata["uptime"] = uptime();
|
||||
SYSdata["version"] = OMG_VERSION;
|
||||
# if defined(ESP8266) || defined(ESP32)
|
||||
SYSdata["env"] = ENV_NAME;
|
||||
uint32_t freeMem;
|
||||
freeMem = ESP.getFreeHeap();
|
||||
SYSdata["freemem"] = freeMem;
|
||||
@@ -1940,39 +1942,97 @@ void receivingMQTT(char* topicOri, char* datacallback) {
|
||||
}
|
||||
|
||||
#ifdef MQTT_HTTPS_FW_UPDATE
|
||||
String latestVersion;
|
||||
# ifdef ESP32
|
||||
# include <HTTPClient.h>
|
||||
|
||||
# include "zzHTTPUpdate.h"
|
||||
|
||||
/**
|
||||
* Check on a server the latest version information to build a releaseLink
|
||||
* The release link will be used when the user trigger an OTA update command
|
||||
* Only available for ESP32
|
||||
*/
|
||||
bool checkForUpdates() {
|
||||
HTTPClient http;
|
||||
http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
|
||||
http.begin(OTA_JSON_URL, OTAserver_cert);
|
||||
int httpCode = http.GET();
|
||||
StaticJsonDocument<JSON_MSG_BUFFER> jsonBuffer;
|
||||
JsonObject jsondata = jsonBuffer.to<JsonObject>();
|
||||
|
||||
if (httpCode > 0) { //Check for the returning code
|
||||
String payload = http.getString();
|
||||
auto error = deserializeJson(jsonBuffer, payload);
|
||||
if (error) {
|
||||
Log.error(F("Deserialize MQTT data failed: %s" CR), error.c_str());
|
||||
}
|
||||
Log.trace(F("HttpCode %d" CR), httpCode);
|
||||
Log.trace(F("Payload %s" CR), payload.c_str());
|
||||
} else {
|
||||
Log.error(F("Error on HTTP request"));
|
||||
}
|
||||
http.end(); //Free the resources
|
||||
if (jsondata.containsKey("latest_version")) {
|
||||
jsondata["installed_version"] = OMG_VERSION;
|
||||
jsondata["entity_picture"] = ENTITY_PICTURE;
|
||||
latestVersion = jsondata["latest_version"].as<String>();
|
||||
pub(subjectSYStoMQTT, jsondata);
|
||||
Log.trace(F("Update file found on server" CR));
|
||||
return true;
|
||||
} else {
|
||||
Log.trace(F("No update file found on server" CR));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
# elif ESP8266
|
||||
# include <ESP8266httpUpdate.h>
|
||||
# endif
|
||||
|
||||
void MQTTHttpsFWUpdate(char* topicOri, JsonObject& HttpsFwUpdateData) {
|
||||
if (strstr(topicOri, subjectFWUpdate) != NULL) {
|
||||
if (strstr(topicOri, subjectMQTTtoSYSupdate) != NULL) {
|
||||
const char* version = HttpsFwUpdateData["version"];
|
||||
if (version && ((strlen(version) != strlen(OMG_VERSION)) || strcmp(version, OMG_VERSION) != 0)) {
|
||||
const char* url = HttpsFwUpdateData["url"];
|
||||
String systemUrl;
|
||||
if (url) {
|
||||
if (!strstr((url + (strlen(url) - 5)), ".bin")) {
|
||||
Log.error(F("Invalid firmware extension" CR));
|
||||
return;
|
||||
}
|
||||
# if MQTT_HTTPS_FW_UPDATE_USE_PASSWORD > 0
|
||||
const char* pwd = HttpsFwUpdateData["password"];
|
||||
if (pwd) {
|
||||
if (strcmp(pwd, ota_pass) != 0) {
|
||||
Log.error(F("Invalid OTA password" CR));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
Log.error(F("No password sent" CR));
|
||||
return;
|
||||
}
|
||||
# endif
|
||||
# ifdef ESP32
|
||||
} else if (strcmp(version, "latest") == 0) {
|
||||
if (!checkForUpdates())
|
||||
return;
|
||||
systemUrl = RELEASE_LINK + latestVersion + "/" + ENV_NAME + "-firmware.bin";
|
||||
url = systemUrl.c_str();
|
||||
Log.notice(F("Using system OTA url with latest version %s" CR), url);
|
||||
} else if (strcmp(version, "dev") == 0) {
|
||||
systemUrl = String(RELEASE_LINK_DEV) + ENV_NAME + "-firmware.bin";
|
||||
url = systemUrl.c_str();
|
||||
Log.notice(F("Using system OTA url with dev version %s" CR), url);
|
||||
} else if (version[0] == 'v') {
|
||||
systemUrl = String(RELEASE_LINK) + version + "/" + ENV_NAME + "-firmware.bin";
|
||||
url = systemUrl.c_str();
|
||||
Log.notice(F("Using system OTA url with defined version %s" CR), url);
|
||||
# endif
|
||||
} else {
|
||||
Log.error(F("Invalid URL" CR));
|
||||
return;
|
||||
}
|
||||
|
||||
# if MQTT_HTTPS_FW_UPDATE_USE_PASSWORD > 0
|
||||
const char* pwd = HttpsFwUpdateData["password"];
|
||||
if (pwd) {
|
||||
if (strcmp(pwd, ota_pass) != 0) {
|
||||
Log.error(F("Invalid OTA password" CR));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
Log.error(F("No password sent" CR));
|
||||
return;
|
||||
}
|
||||
# endif
|
||||
|
||||
Log.warning(F("Starting firmware update" CR));
|
||||
SendReceiveIndicatorON();
|
||||
ErrorIndicatorON();
|
||||
|
||||
Reference in new issue
Block a user