fix: blank Heater/Stirrer status on browser disconnect instead of stale text

updateDeviceStatus() gains a tri-state: true/false once the server has
actually reported it, or null for "unknown" - rendered as a blank
'---' badge with both Connect/Disconnect buttons disabled.
setConnected() now resets Heater/Stirrer to null whenever the browser's
own websocket connection drops, so a stale Connected/Disconnected badge
from before the disconnect doesn't keep misleadingly showing as current.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YaPLuRPpyjWcwhMvCvpHCL
This commit is contained in:
2026-07-03 21:59:15 +02:00
co-authored by Claude Sonnet 5
parent 4b9a144b62
commit b526711595
+28 -2
View File
@@ -538,16 +538,28 @@ function updateSudActions() {
// and Connect/Disconnect buttons for one device. Simulated devices are
// always connected and have nothing to connect/disconnect, so their
// buttons are hidden entirely rather than just disabled.
//
// isConnected is a tri-state: true/false once the server has actually
// reported it, or null for "unknown" - shown as a blank '---' badge with
// both buttons disabled, used while the browser itself has no connection
// to the server at all (see setConnected()) since a stale Connected/
// Disconnected from before that disconnect would otherwise misleadingly
// look current.
function updateDeviceStatus(prefix, isConnected, simulated) {
const statusEl = document.getElementById(`${prefix}-status`);
if (isConnected === null) {
statusEl.textContent = '---';
statusEl.className = 'panel-status status-disconnected';
} else {
statusEl.textContent = isConnected ? 'Connected' : 'Disconnected';
statusEl.className = `panel-status ${isConnected ? 'status-connected' : 'status-disconnected'}`;
}
const connectBtn = document.getElementById(`btn-${prefix}-connect`);
const disconnectBtn = document.getElementById(`btn-${prefix}-disconnect`);
connectBtn.classList.toggle('hidden', !!simulated);
disconnectBtn.classList.toggle('hidden', !!simulated);
connectBtn.disabled = isConnected;
disconnectBtn.disabled = !isConnected;
connectBtn.disabled = isConnected !== false;
disconnectBtn.disabled = isConnected !== true;
}
// Reflects closedLoop (the Controller panel's Enable toggle) in the
@@ -867,6 +879,20 @@ function setConnected(isConnected) {
document.getElementById('lcd-pot-row').style.visibility = isConnected ? 'visible' : 'hidden';
document.getElementById('sud-status-line').style.visibility = isConnected ? 'visible' : 'hidden';
document.getElementById('env-status-line').style.visibility = isConnected ? 'visible' : 'hidden';
if (!isConnected) {
// The browser's own link to the server is gone, so whatever
// Heater/Stirrer connection state was last reported is now stale -
// blank it out rather than leave a misleading Connected/
// Disconnected badge showing. Simulated stays unknown too (null,
// not false) since updateDeviceStatus() only hides the buttons
// once the server says so again.
heaterConnected = null;
heaterSimulated = null;
stirrerConnected = null;
stirrerSimulated = null;
updateDeviceStatus('heater', heaterConnected, heaterSimulated);
updateDeviceStatus('stirrer', stirrerConnected, stirrerSimulated);
}
updateSudActions();
}