[OTA] Resolve the offered version per build environment (#2350)

checkForUpdates() reads an optional "envs" map from the update manifest and,
when it holds an entry for this build's ENV_NAME, offers that version instead
of the global latest_version. Boards with no entry are unaffected.

This lets the OTA server hold a specific product at an older release while the
rest of the fleet advances, with no per-board build flags. The resolved value
is republished as latest_version so the Home Assistant update entity compares
against it, and the map itself is dropped from the retained state topic to
keep it small.

Backward compatible both ways: old firmware ignores "envs", and a manifest
without "envs" behaves exactly as before.

OTA_JSON_URL is also guarded with #ifndef so a build environment can point the
update check at another OTA server. It was defined unconditionally, so a -D
build flag could not retarget it (the header definition always won). This is
needed to exercise the check against a test manifest, and is useful for
self-hosted OTA servers. No behaviour change without an override.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
FlorianandClaude Opus 5 authored and GitHub committed 2026-08-10 06:33:13 -05:00
1 parent b9e8821b17
commit 65d0998278
2 files changed
+25 -6

No files matched your search

+6 -4
View File
@@ -251,10 +251,12 @@
# ifndef MQTT_HTTPS_FW_UPDATE_USE_PASSWORD
# define MQTT_HTTPS_FW_UPDATE_USE_PASSWORD 1 // Set this to 0 if not using TLS connection to MQTT broker to prevent clear text passwords being sent.
# endif
# if DEVELOPMENTOTA
# define OTA_JSON_URL "https://ota.openmqttgateway.com/binaries/dev/latest_version_dev.json" //OTA url used to discover new versions of the firmware from development nightly builds
# else
# define OTA_JSON_URL "https://ota.openmqttgateway.com/binaries/latest_version.json" //OTA url used to discover new versions of the firmware
# ifndef OTA_JSON_URL // may be overridden by a build flag to use another OTA server
# if DEVELOPMENTOTA
# define OTA_JSON_URL "https://ota.openmqttgateway.com/binaries/dev/latest_version_dev.json" //OTA url used to discover new versions of the firmware from development nightly builds
# else
# define OTA_JSON_URL "https://ota.openmqttgateway.com/binaries/latest_version.json" //OTA url used to discover new versions of the firmware
# endif
# endif
# define ENTITY_PICTURE "https://github.com/1technophile/OpenMQTTGateway/raw/development/docs/img/Openmqttgateway_logo_mini_margins.png"
# define RELEASE_LINK_DEV "https://ota.openmqttgateway.com/binaries/dev/"
+19 -2
View File
@@ -3224,12 +3224,29 @@ bool checkForUpdates() {
jsondata["entity_picture"] = ENTITY_PICTURE;
if (!jsondata.containsKey("release_summary"))
jsondata["release_summary"] = "";
latestVersion = jsondata["latest_version"].as<String>();
// Per-environment version pinning: if the manifest carries an "envs" map with
// an entry for this build's ENV_NAME, that entry caps the version offered to
// this board; boards without an entry fall back to the global latest_version.
// This lets the OTA server hold e.g. theengs-plug at an older release while the
// rest of the fleet advances, with no board-specific firmware build flags.
// The "envs" map is expected to list only pinned exceptions so the manifest
// stays within JSON_MSG_BUFFER (1024 B on ESP32).
JsonVariant envVersion = jsondata["envs"][ENV_NAME];
if (!envVersion.isNull()) {
latestVersion = envVersion.as<String>();
} else {
latestVersion = jsondata["latest_version"].as<String>();
}
// Publish the resolved value as latest_version so the Home Assistant update
// entity compares against the (possibly pinned) version, and drop the map so
// it is not carried in the retained state topic.
jsondata["latest_version"] = latestVersion;
jsondata.remove("envs");
jsondata["origin"] = subjectRLStoMQTT;
jsondata["retain"] = true;
enqueueJsonObject(jsondata);
THEENGS_LOG_TRACE(F("Update file found on server" CR));
THEENGS_LOG_TRACE(F("Update file found on server, offering version %s" CR), latestVersion.c_str());
return true;
} else {
THEENGS_LOG_TRACE(F("No update file found on server" CR));