mirror of
https://github.com/rstrouse/ESPSomfy-RTS.git
synced 2026-10-31 13:52:15 +01:00
feat: remove the GitHub update
The release check, release list, download, cancel and /recoverFilesystem go, with the GitHub button and the Auto Check for Updates setting in the web UI (docs/adr/0007-no-github-update.md). The HTTPS session it needed failed for want of a 35-40 KB block (#76), it checked no certificate, and the web UI's buttons had been getting 404. Updates are uploads only (/updateFirmware, /updateApplication). The old socket still sends fwStatus with the installed versions, which the web UI and Home Assistant read. checkForUpdate stays in NVS and the backup file so their formats don't change. The release image shrinks by 126.5 KB: 142 KB of the OTA slot is free. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
539a49eb77
commit
83c946dd5f
14 changed files with 25 additions and 1009 deletions
|
|
@ -579,9 +579,6 @@ async function initSockets() {
|
|||
case 'memStatus':
|
||||
firmware.procMemoryStatus(msg);
|
||||
break;
|
||||
case 'updateProgress':
|
||||
firmware.procUpdateProgress(msg);
|
||||
break;
|
||||
case 'fwStatus':
|
||||
firmware.procFwStatus(msg);
|
||||
break;
|
||||
|
|
@ -4569,268 +4566,11 @@ class Firmware {
|
|||
}
|
||||
|
||||
procFwStatus(rel) {
|
||||
console.log(rel);
|
||||
let div = document.getElementById('divFirmwareUpdate');
|
||||
if (rel.available && rel.status === 0 && rel.checkForUpdate !== false) {
|
||||
div.style.color = 'black';
|
||||
div.innerHTML = `<span>Firmware ${rel.fwVersion.name} Installed<span><span style="color:red"> ${rel.latest.name} Available</span>`;
|
||||
}
|
||||
else {
|
||||
switch (rel.status) {
|
||||
case 2: // Awaiting update.
|
||||
div.style.color = 'red';
|
||||
div.innerHTML = `Preparing firmware update`;
|
||||
break;
|
||||
case 3: // Updating -- this will be set by the update progress.
|
||||
break;
|
||||
case 4: // Complete
|
||||
if (rel.error !== 0) {
|
||||
div.style.color = 'red';
|
||||
let e = errors.find(x => x.code === rel.error) || { code: rel.error, desc: 'Unspecified error' };
|
||||
let inst = document.getElementById('divGitInstall');
|
||||
if (inst) {
|
||||
inst.remove();
|
||||
ui.errorMessage(e.desc);
|
||||
}
|
||||
div.innerHTML = e.desc;
|
||||
}
|
||||
else {
|
||||
div.innerHTML = `Firmware update complete`;
|
||||
// Throw up a wait message this will be cleared on the reload.
|
||||
ui.waitMessage(document.getElementById('divContainer'));
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
div.style.color = 'red';
|
||||
div.innerHTML = `Cancelling firmware update`;
|
||||
break;
|
||||
case 6:
|
||||
div.style.color = 'red';
|
||||
div.innerHTML = `Firmware update cancelled`;
|
||||
break;
|
||||
|
||||
default:
|
||||
div.style.color = 'black';
|
||||
div.innerHTML = `Firmware ${rel.fwVersion.name} Installed`;
|
||||
break;
|
||||
}
|
||||
}
|
||||
div.style.color = 'black';
|
||||
div.innerHTML = `Firmware ${rel.fwVersion.name} Installed`;
|
||||
div.style.display = '';
|
||||
}
|
||||
procUpdateProgress(prog) {
|
||||
let pct = Math.round((prog.loaded / prog.total) * 100);
|
||||
let file = prog.part === 100 ? 'Application' : 'Firmware';
|
||||
let div = document.getElementById('divFirmwareUpdate');
|
||||
if (div) {
|
||||
div.style.color = 'red';
|
||||
div.innerHTML = `Updating ${file} to ${prog.ver} ${pct}%`;
|
||||
}
|
||||
general.reloadApp = true;
|
||||
let git = document.getElementById('divGitInstall');
|
||||
if (git) {
|
||||
// Update the status on the client that started the install.
|
||||
if (pct >= 100 && prog.part === 100) git.remove();
|
||||
else {
|
||||
if (prog.part === 100) {
|
||||
document.getElementById('btnCancelUpdate').style.display = 'none';
|
||||
}
|
||||
let p = prog.part === 100 ? document.getElementById('progApplicationDownload') : document.getElementById('progFirmwareDownload');
|
||||
if (p) {
|
||||
p.style.setProperty('--progress', `${pct}%`);
|
||||
p.setAttribute('data-progress', `${pct}%`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
async installGitRelease(div) {
|
||||
if (!this.isMobile()) {
|
||||
console.log('Starting backup');
|
||||
try {
|
||||
await firmware.backup();
|
||||
console.log('Backup Complete');
|
||||
}
|
||||
catch (err) {
|
||||
ui.serviceError(el, err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let obj = ui.fromElement(div);
|
||||
console.log(obj);
|
||||
putJSONSync(`/downloadFirmware?ver=${obj.version}`, {}, (err, ver) => {
|
||||
if (err) ui.serviceError(err);
|
||||
else {
|
||||
general.reloadApp = true;
|
||||
// Change the display and allow the percentage to be shown when the socket emits the progress.
|
||||
let html = `<div>Installing ${ver.name}</div><div style="font-size:.7em;margin-top:4px;">Please wait as the files are downloaded and installed. Once the application update process starts you may no longer cancel the update as this will corrupt the downloaded files.</div>`;
|
||||
html += `<div class="progress-bar" id="progFirmwareDownload" style="--progress:0%;margin-top:10px;text-align:center;"></div>`;
|
||||
html += `<label for="progFirmwareDownload" style="font-size:10pt;">Firmware Install Progress</label>`;
|
||||
html += `<div class="progress-bar" id="progApplicationDownload" style="--progress:0%;margin-top:10px;text-align:center;"></div>`;
|
||||
html += `<label for="progFirmwareDownload" style="font-size:10pt;">Application Install Progress</label>`;
|
||||
html += `<hr></hr><div class="button-container" style="text-align:center;">`;
|
||||
html += `<button id="btnCancelUpdate" type="button" style="width:40%;padding-left:20px;padding-right:20px;display:inline-block;" onclick="firmware.cancelInstallGit(document.getElementById('divGitInstall'));">Cancel</button>`;
|
||||
html += `</div>`;
|
||||
div.innerHTML = html;
|
||||
}
|
||||
});
|
||||
}
|
||||
cancelInstallGit(div) {
|
||||
putJSONSync(`/cancelFirmware`, {}, (err, ver) => {
|
||||
if (err) ui.serviceError(err);
|
||||
else console.log(ver);
|
||||
div.remove();
|
||||
});
|
||||
}
|
||||
updateGithub() {
|
||||
getJSONSync('/getReleases', (err, rel) => {
|
||||
if (err) ui.serviceError(err);
|
||||
else {
|
||||
console.log(rel);
|
||||
let div = document.createElement('div');
|
||||
let chip = document.getElementById('divContainer').getAttribute('data-chipmodel');
|
||||
div.setAttribute('id', 'divGitInstall')
|
||||
div.setAttribute('class', 'inst-overlay');
|
||||
div.style.width = '100%';
|
||||
div.style.alignContent = 'center';
|
||||
// Sort the releases so that the pre-releases are at the bottom.
|
||||
rel.releases.sort((a, b) => a.preRelease === b.preRelease && b.draft === a.draft ? 0 : a.preRelease ? 1 : -1);
|
||||
|
||||
let html = `<div>Select a version from the repository to install using the dropdown below. Then press the update button to install that version.</div><div style="font-size:.7em;margin-top:4px;">Select Main to install the most recent alpha version from the repository.</div>`;
|
||||
html += `<div id="divPrereleaseWarning" style="display:none;width:100%;color:red;text-align:center;font-weight:bold;"><span style="margin-top:7px;width:100%;padding:3px;display:inline-block;border-radius:5px;background:white;">WARNING<span><hr style="margin:0px" /><div style="font-size:.7em;padding-left:1em;padding-right:1em;color:black;font-weight:normal;">You have selected a pre-released beta version that has not been fully tested or published for general use.</div></div>`;
|
||||
html += `<div class="field-group" style="text-align:center;">`;
|
||||
html += `<select id="selVersion" data-bind="version" style="width:70%;font-size:2em;color:white;text-align-last:center;" onchange="firmware.gitReleaseSelected(document.getElementById('divGitInstall'));">`
|
||||
for (let i = 0; i < rel.releases.length; i++) {
|
||||
if (rel.releases[i].hwVersions.length === 0 || rel.releases[i].hwVersions.indexOf(chip) >= 0)
|
||||
html += `<option style="text-align:left;font-size:.5em;color:black;" data-prerelease="${rel.releases[i].preRelease}" value="${rel.releases[i].version.name}">${rel.releases[i].name}${rel.releases[i].preRelease ? ' - Pre' : ''}</option>`
|
||||
}
|
||||
html += `</select><label for="selVersion">Select a version</label></div>`;
|
||||
html += `<div class="button-container" id="divReleaseNotes" style="text-align:center;margin-top:-20px;display:none;"><button type="button" onclick="firmware.showReleaseNotes(document.getElementById('selVersion').value);" style="display:inline-block;width:auto;padding-left:20px;padding-right:20px;">Release Notes</button></div>`;
|
||||
if (this.isMobile()) {
|
||||
html += `<div style="width:100%;color:red;text-align:center;font-weight:bold;"><span style="margin-top:7px;width:100%;background:yellow;padding:3px;display:inline-block;border-radius:5px;background:white;">WARNING<span></div>`;
|
||||
html += '<hr/><div style="font-size:14px;margin-bottom:10px;">This browser does not support automatic backups. It is highly recommended that you back up your configuration using the backup button before proceeding.</div>';
|
||||
}
|
||||
else {
|
||||
html += '<hr/><div style="font-size:14px;margin-bottom:10px;">A backup file for your configuration will be downloaded to your browser. If the firmware update process fails please restore this file using the restore button after going through the onboarding process.</div>'
|
||||
}
|
||||
html += `<hr></hr><div class="button-container" style="text-align:center;">`;
|
||||
if (this.isMobile()) {
|
||||
html += `<button id="btnBackupCfg" type="button" style="display:inline-block;width:calc(80% + 7px);padding-left:20px;padding-right:20px;margin-right:4px;" onclick="firmware.backup();">Backup</button>`;
|
||||
}
|
||||
html += `<button id="btnUpdate" type="button" style="width:40%;padding-left:20px;padding-right:20px;display:inline-block;margin-right:7px;" onclick="firmware.installGitRelease(document.getElementById('divGitInstall'));">Update</button>`;
|
||||
html += `<button id="btnClose" type="button" style="width:40%;padding-left:20px;padding-right:20px;display:inline-block;" onclick="document.getElementById('divGitInstall').remove();">Cancel</button>`;
|
||||
|
||||
html += `</div></div>`;
|
||||
|
||||
div.innerHTML = html;
|
||||
document.getElementById('divContainer').appendChild(div);
|
||||
this.gitReleaseSelected(div);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
gitReleaseSelected(div) {
|
||||
let obj = ui.fromElement(div);
|
||||
let divNotes = div.querySelector('#divReleaseNotes');
|
||||
let divPre = div.querySelector('#divPrereleaseWarning');
|
||||
|
||||
let sel = div.querySelector('#selVersion');
|
||||
if (sel && sel.selectedIndex !== -1 && makeBool(sel.options[sel.selectedIndex].getAttribute('data-prerelease'))) {
|
||||
if (divPre) divPre.style.display = '';
|
||||
}
|
||||
else
|
||||
if (divPre) divPre.style.display = 'none';
|
||||
|
||||
if (divNotes) {
|
||||
if (!obj.version || obj.version === 'main' || obj.version === '') divNotes.style.display = 'none';
|
||||
else divNotes.style.display = '';
|
||||
}
|
||||
}
|
||||
async getReleaseInfo(tag) {
|
||||
let overlay = ui.waitMessage(document.getElementById('divContainer'));
|
||||
try {
|
||||
let ret = {};
|
||||
ret.resp = await fetch(`https://api.github.com/repos/cjkas/espsomfy-rts/releases/tags/${tag}`);
|
||||
if (ret.resp.ok)
|
||||
ret.info = await ret.resp.json();
|
||||
return ret;
|
||||
}
|
||||
catch (err) {
|
||||
return { err: err };
|
||||
}
|
||||
finally { overlay.remove(); }
|
||||
}
|
||||
async showReleaseNotes(tagName) {
|
||||
console.log(tagName);
|
||||
let r = await this.getReleaseInfo(tagName);
|
||||
console.log(r);
|
||||
let fnToItem = (txt, tag) => { }
|
||||
if (r.resp.ok) {
|
||||
// Convert this to html.
|
||||
let lines = r.info.body.split('\r\n');
|
||||
let ctx = { html: '', llvl: 0, lines: r.info.body.split('\r\n'), ndx: 0 };
|
||||
ctx.toHead = function (txt) {
|
||||
let num = txt.indexOf(' ');
|
||||
return `<h${num}>${txt.substring(num).trim()}</h${num}>`;
|
||||
};
|
||||
ctx.toUL = function () {
|
||||
let txt = this.lines[this.ndx++];
|
||||
let tok = this.token(txt);
|
||||
this.html += `<ul>${this.toLI(tok.txt)}`;
|
||||
while (this.ndx < this.lines.length) {
|
||||
txt = this.lines[this.ndx];
|
||||
let t = this.token(txt);
|
||||
if (t.ch === '*') {
|
||||
if (t.indent !== tok.indent) this.toUL();
|
||||
else {
|
||||
this.html += this.toLI(t.txt);
|
||||
this.ndx++;
|
||||
}
|
||||
}
|
||||
else break;
|
||||
}
|
||||
this.html += '</ul>';
|
||||
};
|
||||
ctx.toLI = function (txt) { return `<li>${txt.trim()}</li>`; }
|
||||
ctx.token = function (txt) {
|
||||
let tok = { ch: '', indent: 0, txt:'' }
|
||||
for (let i = 0; i < txt.length; i++) {
|
||||
if (txt[i] === ' ') tok.indent++;
|
||||
else {
|
||||
tok.ch = txt[i];
|
||||
let tmp = txt.substring(tok.indent);
|
||||
tok.txt = tmp.substring(tmp.indexOf(' '));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return tok;
|
||||
};
|
||||
ctx.next = function () {
|
||||
if (this.ndx >= this.lines.length) return false;
|
||||
let tok = this.token(this.lines[this.ndx]);
|
||||
switch (tok.ch) {
|
||||
case '#':
|
||||
this.html += this.toHead(this.lines[this.ndx]);
|
||||
this.ndx++;
|
||||
break;
|
||||
case '*':
|
||||
this.toUL();
|
||||
break;
|
||||
case '':
|
||||
this.ndx++;
|
||||
this.html += `<br/><div>${tok.txt}</div>`;
|
||||
break;
|
||||
default:
|
||||
this.ndx++;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
while (ctx.next());
|
||||
console.log(ctx);
|
||||
ui.infoMessage(ctx.html);
|
||||
}
|
||||
}
|
||||
updateFirmware() {
|
||||
let div = this.createFileUploader('/updateFirmware');
|
||||
let inst = div.querySelector('div[id=divInstText]');
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue