Consolidate firmware UI; server learns board from the device, not a picker
Build and push server image / build-and-push (push) Successful in 37s
Build and push server image / build-and-push (push) Successful in 37s
All firmware-related controls (manual upload, Gitea repo URL, auto-update checkbox, detected board, Update frame button) now live in one "Firmware update" card instead of being split across the main Settings form and a separate card. The board variant used to pick a Gitea release asset was a dropdown the user had to set by hand and could get wrong. The device now reports it itself via a new X-Frame-Board header (CONFIG_FRAME_BOARD_NAME, "devkit" by default, "xiao" in sdkconfig.xiao) on every /frame/config poll, stored as device_board_variant -- the server learns it instead. Update checks/applies are gated on the board being known, since there's nothing to fetch until a device has checked in at least once.
This commit is contained in:
@@ -75,25 +75,6 @@
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
<label>Firmware Gitea repo URL
|
||||
<input type="text" id="firmware_update_repo_url" placeholder="https://git.example.com/owner/repo"
|
||||
value="{{ cfg.firmware_update_repo_url }}">
|
||||
</label>
|
||||
<label>Frame's board
|
||||
<select id="firmware_board_variant">
|
||||
<option value="xiao" {% if cfg.firmware_board_variant == "xiao" %}selected{% endif %}>Seeed XIAO ESP32-C6</option>
|
||||
<option value="devkit" {% if cfg.firmware_board_variant == "devkit" %}selected{% endif %}>ESP32-C6-DevKitC-1</option>
|
||||
</select>
|
||||
</label>
|
||||
<div class="checkbox-row">
|
||||
<input type="checkbox" id="firmware_auto_update" {% if cfg.firmware_auto_update %}checked{% endif %}>
|
||||
<label for="firmware_auto_update">Automatically apply updates</label>
|
||||
</div>
|
||||
<p class="sub" style="margin-top: 8px;">When a Gitea repo URL is set, the
|
||||
server periodically checks its releases for a newer build for the
|
||||
board above. With auto-apply off, an "Update frame" button appears
|
||||
below when one's found; with it on, the server stages the new
|
||||
build itself -- the frame still only updates on its own next wake.</p>
|
||||
<button type="button" class="secondary" id="load-albums">Load Albums</button>
|
||||
<button type="submit">Save</button>
|
||||
</form>
|
||||
@@ -124,12 +105,30 @@
|
||||
|
||||
<section class="card">
|
||||
<h2 class="card-title">Firmware update</h2>
|
||||
<p class="sub" id="firmware-board">
|
||||
{% if cfg.device_board_variant %}Detected board: {{ cfg.device_board_variant }}
|
||||
{% else %}Board not detected yet -- the frame reports it on its next check-in.{% endif %}
|
||||
</p>
|
||||
<p class="sub" id="firmware-available">
|
||||
{% if cfg.firmware_available_version %}Uploaded: v{{ cfg.firmware_available_version }} -- the frame
|
||||
updates itself on its next wake if it's running something else.{% else %}No firmware uploaded yet.{% endif %}
|
||||
</p>
|
||||
<input type="file" id="firmware-file" accept=".bin">
|
||||
<button type="button" class="secondary" id="firmware-upload">Upload firmware</button>
|
||||
|
||||
<p class="sub" style="margin-top: 16px;">Or check a Gitea repo's releases
|
||||
automatically -- built by <code>.gitea/workflows/firmware-release-build.yml</code>,
|
||||
one binary per board. The board above is learned from the frame
|
||||
itself, never picked by hand.</p>
|
||||
<label>Gitea repo URL
|
||||
<input type="text" id="firmware_update_repo_url" placeholder="https://git.example.com/owner/repo"
|
||||
value="{{ cfg.firmware_update_repo_url }}">
|
||||
</label>
|
||||
<div class="checkbox-row">
|
||||
<input type="checkbox" id="firmware_auto_update" {% if cfg.firmware_auto_update %}checked{% endif %}>
|
||||
<label for="firmware_auto_update">Automatically apply updates</label>
|
||||
</div>
|
||||
<button type="button" class="secondary" id="firmware-settings-save">Save</button>
|
||||
<p class="sub" id="firmware-gitea-status" style="display: none; margin-top: 10px;"></p>
|
||||
<button type="button" id="firmware-update-btn" style="display: none;">Update frame</button>
|
||||
</section>
|
||||
@@ -167,7 +166,6 @@
|
||||
quiet_hours_end: document.getElementById('quiet_hours_end').value || '07:00',
|
||||
timezone: document.getElementById('timezone').value || 'UTC',
|
||||
firmware_update_repo_url: document.getElementById('firmware_update_repo_url').value || '',
|
||||
firmware_board_variant: document.getElementById('firmware_board_variant').value,
|
||||
firmware_auto_update: String(document.getElementById('firmware_auto_update').checked),
|
||||
});
|
||||
const resp = await fetch('/api/config', {
|
||||
@@ -215,6 +213,16 @@
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('firmware-settings-save').addEventListener('click', async () => {
|
||||
try {
|
||||
await saveConfig();
|
||||
showStatus(true, 'Saved.');
|
||||
loadFirmwareCheck();
|
||||
} catch (e) {
|
||||
showStatus(false, e.message);
|
||||
}
|
||||
});
|
||||
|
||||
let upcomingItems = [];
|
||||
|
||||
// Pointer Events (not the native HTML5 Drag-and-Drop API) so the same
|
||||
@@ -522,19 +530,26 @@
|
||||
async function loadFirmwareCheck() {
|
||||
const statusEl = document.getElementById('firmware-gitea-status');
|
||||
const btn = document.getElementById('firmware-update-btn');
|
||||
const boardEl = document.getElementById('firmware-board');
|
||||
try {
|
||||
const resp = await fetch('/api/firmware/check');
|
||||
if (!resp.ok) {
|
||||
return;
|
||||
}
|
||||
const data = await resp.json();
|
||||
if (data.board) {
|
||||
boardEl.textContent = `Detected board: ${data.board}`;
|
||||
}
|
||||
if (!data.enabled) {
|
||||
statusEl.style.display = 'none';
|
||||
btn.style.display = 'none';
|
||||
return;
|
||||
}
|
||||
statusEl.style.display = 'block';
|
||||
if (data.update_available) {
|
||||
if (!data.board) {
|
||||
statusEl.textContent = "Waiting for the frame to check in before it can look up the right build.";
|
||||
btn.style.display = 'none';
|
||||
} else if (data.update_available) {
|
||||
statusEl.textContent = `Update available: v${data.latest_version}.`;
|
||||
btn.style.display = 'inline-block';
|
||||
} else if (data.latest_version) {
|
||||
|
||||
Reference in New Issue
Block a user