mirror of
https://github.com/mikecarper/MeshCore.git
synced 2026-10-23 07:32:27 +00:00
feat(webconfig): trim the displayed version to base, build and channel
The full embedded string is v1.16.0.5-observer-beta-dev-a1b2c3d. The -observer tag is on every observer build and the commit is for machines, so neither tells a person anything at a glance. Both the page header and the console banner now show base + published build number + channel, paired with the build date the way `ver` pairs them: v1.16.0.5-dev (6 Jun 2026) v1.16.0.5 (6 Jun 2026) `ver` still prints the whole string, commit included, for when that is what you need. The channel suffix follows the release filenames rather than the embedded tag — build.sh writes FILENAME_CHANNEL_TAG "-dev" for the same builds it tags "-observer-beta-dev" internally, so "-dev" is the name these already carry. Carrying the build date meant /api/status had to report it; WebConfigServer now takes FIRMWARE_BUILD_DATE alongside FIRMWARE_VERSION, from the same defines `ver` reads. A local build has neither build number nor channel to show, so the fact worth knowing about it moves to the second line: "local build, OTA not configured". build.sh deliberately leaves OTA_MANIFEST_BASE undefined there, and a bare version number gives no hint that the node cannot update itself.
This commit is contained in:
1 parent
cac91c91d8
commit
20826dcccf
5 files changed
+27
-22
No files matched your search
@@ -1438,7 +1438,7 @@ bool MyMesh::startWebConfig(bool force_ap, char* reply) {
|
||||
}
|
||||
if (!_webconfig) {
|
||||
_webconfig = new WebConfigServer(&_prefs, _cli.getObserverPrefs(), this,
|
||||
self_id.pub_key, getFirmwareVer(), getRole(),
|
||||
self_id.pub_key, getFirmwareVer(), getBuildDate(), getRole(),
|
||||
_cli.getBoard()->getManufacturerName());
|
||||
}
|
||||
if (force_ap) {
|
||||
|
||||
@@ -187,7 +187,8 @@ class State:
|
||||
# Shaped like build.sh's EMBEDDED_VERSION_STRING
|
||||
# (base[.build][-observer][-channel]-hash) so the console's channel
|
||||
# labelling is exercised against a real version, not "v1.x-mock".
|
||||
"fw": FW_VERSION, "role": "Repeater", "board": "Heltec V3 (mock)",
|
||||
"fw": FW_VERSION, "build_date": "6 Jun 2026",
|
||||
"role": "Repeater", "board": "Heltec V3 (mock)",
|
||||
"uptime_s": int(time.time() - self.start),
|
||||
"runtime_slots": 6, "max_slots": 6, "active_slots": self.active_slots,
|
||||
"max_cmds": CLI_MAX_CMDS,
|
||||
|
||||
@@ -112,9 +112,10 @@ static portMUX_TYPE s_wc_route_mux = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
WebConfigServer::WebConfigServer(NodePrefs* prefs, MQTTPrefs* obs, Callbacks* callbacks,
|
||||
const uint8_t* pub_key, const char* fw_ver,
|
||||
const char* build_date,
|
||||
const char* role, const char* board_name)
|
||||
: _prefs(prefs), _obs(obs), _cb(callbacks), _pub_key(pub_key),
|
||||
_fw_ver(fw_ver), _role(role), _board_name(board_name) {
|
||||
_fw_ver(fw_ver), _build_date(build_date), _role(role), _board_name(board_name) {
|
||||
_mux = xSemaphoreCreateMutex();
|
||||
}
|
||||
|
||||
@@ -571,6 +572,9 @@ void WebConfigServer::handleStatus(AsyncWebServerRequest* req) {
|
||||
for (int i = 0; i < 8; i++) sprintf(&node_id[i * 2], "%02x", _pub_key[i]);
|
||||
doc["node_id"] = node_id;
|
||||
doc["fw"] = _fw_ver;
|
||||
// The page shows a trimmed version — base + build number + channel — and
|
||||
// pairs it with this, the way `ver` does. Both come from the same defines.
|
||||
doc["build_date"] = _build_date;
|
||||
doc["role"] = _role;
|
||||
doc["board"] = _board_name;
|
||||
doc["uptime_s"] = millis() / 1000;
|
||||
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
};
|
||||
|
||||
WebConfigServer(NodePrefs* prefs, MQTTPrefs* obs, Callbacks* callbacks,
|
||||
const uint8_t* pub_key, const char* fw_ver,
|
||||
const uint8_t* pub_key, const char* fw_ver, const char* build_date,
|
||||
const char* role, const char* board_name);
|
||||
~WebConfigServer();
|
||||
|
||||
@@ -125,6 +125,7 @@ private:
|
||||
Callbacks* _cb;
|
||||
const uint8_t* _pub_key;
|
||||
const char* _fw_ver;
|
||||
const char* _build_date;
|
||||
const char* _role;
|
||||
const char* _board_name;
|
||||
|
||||
|
||||
+17
-18
@@ -582,6 +582,18 @@ function $(s){return document.querySelector(s)}
|
||||
function $$(s){return Array.prototype.slice.call(document.querySelectorAll(s))}
|
||||
function toast(m){var t=$("#toast");t.textContent=m;t.classList.add("show");clearTimeout(t._h);t._h=setTimeout(function(){t.classList.remove("show")},2600)}
|
||||
function esc(s){return String(s).replace(/[&<>"]/g,function(c){return{"&":"&","<":"<",">":">",'"':"""}[c]})}
|
||||
// build.sh embeds base[.build][-observer][-channel]-hash, e.g.
|
||||
// v1.16.0.5-observer-beta-dev-a1b2c3d. What identifies a build to a person is
|
||||
// the base, the published build number and the channel — the -observer variant
|
||||
// tag is the same on every observer build and the commit is for machines. `ver`
|
||||
// still prints the whole string when you want it.
|
||||
function shortVer(){
|
||||
var fw=st.fw||"",m=/^(v?\d+\.\d+\.\d+(?:\.\d+)?)/.exec(fw);
|
||||
var s=m?m[1]:(fw||"unknown version");
|
||||
if(/-dev(-|$)/.test(fw))s+="-dev"; // OTA_CHANNEL_TAG=beta-dev
|
||||
else if(/-beta(-|$)/.test(fw))s+="-beta"; // a beta-only channel, if ever
|
||||
return st.build?s+" ("+st.build+")":s;
|
||||
}
|
||||
|
||||
function api(path,opts){
|
||||
opts=opts||{};
|
||||
@@ -629,9 +641,9 @@ function boot(){
|
||||
// size for older firmware that doesn't report it.
|
||||
st.mode=s.mode;st.authed=s.auth;st.needsSetup=!!s.needs_setup;st.nslots=s.active_slots||s.runtime_slots||6;
|
||||
if(s.max_cmds>0)CLI_MAX=s.max_cmds;
|
||||
st.fw=s.fw||"";st.role=s.role||"";st.board=s.board||"";
|
||||
st.fw=s.fw||"";st.build=s.build_date||"";st.role=s.role||"";st.board=s.board||"";
|
||||
$("#h-name").textContent=s.name||"MeshCore";
|
||||
$("#h-sub").textContent=s.role+" · "+s.fw+" · "+s.board;
|
||||
$("#h-sub").textContent=s.role+" · "+shortVer()+" · "+s.board;
|
||||
var b=$("#h-badge");b.classList.remove("hide");
|
||||
if(s.mode==="setup"){b.textContent="SETUP";b.classList.add("setup")}else{b.textContent="LAN"}
|
||||
// Only in setup mode: in LAN mode the console is a tab, and the header is
|
||||
@@ -1637,23 +1649,10 @@ function cliEcho(cls,text){
|
||||
}
|
||||
function cliGap(){var d=cliEcho("gap","");return d}
|
||||
function cliClear(){$("#term-out").innerHTML="";cliBanner();$("#term-in").focus()}
|
||||
// build.sh composes FIRMWARE_VERSION as base[.build][-observer][-channel]-hash,
|
||||
// e.g. v1.16.0.5-observer-beta-dev-a1b2c3d. A plain `pio run` never goes through
|
||||
// build.sh, so it keeps the header default (v1.16.0) with no build number, no
|
||||
// hash, and — deliberately — no OTA_MANIFEST_BASE, so such a node cannot update
|
||||
// itself. Worth saying out loud: the version alone does not make that obvious.
|
||||
function cliChannel(fw){
|
||||
if(/-dev(-|$)/.test(fw))return"dev channel"; // OTA_CHANNEL_TAG=beta-dev
|
||||
if(/-beta(-|$)/.test(fw))return"beta channel";
|
||||
if(/^v?\d+\.\d+\.\d+$/.test(fw))return"local build — not from CI, OTA not configured";
|
||||
return"release channel";
|
||||
}
|
||||
function cliBanner(){
|
||||
// Full string, unabbreviated: the 4th component is the published build number
|
||||
// and the trailing token is the commit, which is what identifies a build.
|
||||
var ch=cliChannel(st.fw||"");
|
||||
cliEcho("sys","MeshCore "+(st.fw||"unknown version")+(ch?" ("+ch+")":""));
|
||||
cliEcho("sys",(st.role||"")+" · "+(st.board||""));
|
||||
cliEcho("sys","MeshCore "+shortVer());
|
||||
cliEcho("sys",(st.role||"")+" · "+(st.board||"")+
|
||||
(/^v?\d+\.\d+\.\d+$/.test(st.fw||"")?" · local build, OTA not configured":""));
|
||||
if(st.mode==="setup"){
|
||||
// The wizard refuses to finish without an admin password; nothing stops a
|
||||
// console-driven setup from rebooting on the factory one, so say so here
|
||||
|
||||
Reference in new issue
Block a user