ui: show water level and status line before any sud is loaded

Pot config (water_mass, volumen) sent in System message at startup.
app.js stores potConfig and uses it in updatePotVisualization/
updateStatusLine when sudEmpty, showing startup fill level and
"No schedule – N L water" without requiring a sud to be loaded first.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-30 19:53:54 +02:00
co-authored by Claude Sonnet 4.6
parent d0a137e39e
commit e7824dc297
4 changed files with 29 additions and 8 deletions
+3 -1
View File
@@ -48,6 +48,8 @@
"mass": 5.96,
"material": "Edelstahl 18/10",
"L": 0.2,
"Td": 17
"Td": 17,
"water_mass": 22,
"volumen": 30
}
}
+3 -1
View File
@@ -47,6 +47,8 @@
"mass": 5.96,
"material": "Edelstahl 18/10",
"L": 0.2,
"Td": 17
"Td": 17,
"water_mass": 22,
"volumen": 30
}
}
+2 -1
View File
@@ -164,7 +164,8 @@ if __name__ == '__main__':
msg_system = dispatcher.msgio_get("System")
async def send_system_info():
await msg_system.send({'AmbientTemp': theta_amb, 'WarpFactor': DT / DT_TASK, 'PlantSim': plant_sim})
await msg_system.send({'AmbientTemp': theta_amb, 'WarpFactor': DT / DT_TASK, 'PlantSim': plant_sim,
'Pot': config.get('Pot', {})})
asyncio.ensure_future(send_system_info())
async def on_system_recv(data):
+21 -5
View File
@@ -41,6 +41,10 @@ let heaterMaxPower = 100;
// Only switchable when not running; auto-reset to true on play.
let closedLoop = true;
// Pot hardware config from server's Pot section - used for display before
// any sud is loaded (startup water level, status line).
let potConfig = {};
// Sud state - mirrors the sud_* fields on client/brewpi_gui.py's Window.
let sudSchedule = [];
let sudName = '';
@@ -420,7 +424,11 @@ function updatePotVisualization() {
const levelTickEl = document.getElementById('level-tick');
const levelLabelEl = document.getElementById('level-label');
if (sudEmpty || sudVolumen <= 0) {
const volumen = sudEmpty ? (potConfig.volumen || 0) : sudVolumen;
const grainMass = sudEmpty ? 0 : currentStepGrainMass();
const waterMass = sudEmpty ? (potConfig.water_mass || 0) : currentStepWaterMass();
if (volumen <= 0) {
waterFillEl.setAttribute('height', '0');
waterWaveEl.setAttribute('d', '');
if (waterClipRect) waterClipRect.setAttribute('height', '0');
@@ -430,9 +438,8 @@ function updatePotVisualization() {
return;
}
const grainMass = currentStepGrainMass();
const utilizedVolume = currentStepWaterMass() + grainMass * 0.7;
const fillFraction = Math.min(1, Math.max(0, utilizedVolume / sudVolumen));
const utilizedVolume = waterMass + grainMass * 0.7;
const fillFraction = Math.min(1, Math.max(0, utilizedVolume / volumen));
const waterH = fillFraction * potInnerH;
const waterTop = potInnerBottom - waterH;
waterFillEl.setAttribute('y', waterTop.toFixed(1));
@@ -462,7 +469,8 @@ function updatePotVisualization() {
function updateStatusLine() {
const el = document.getElementById('sud-status-line');
if (sudSchedule.length === 0) {
el.textContent = '';
const w = potConfig.water_mass || 0;
el.textContent = w > 0 ? `No schedule ${w} L water` : '';
return;
}
let text = '';
@@ -776,6 +784,13 @@ function onSystemChanged(msg) {
if ('PlantSim' in msg) {
document.getElementById('pot-reset-row').classList.toggle('hidden', !msg.PlantSim);
}
if ('Pot' in msg) {
potConfig = msg.Pot;
if (sudEmpty) {
updatePotVisualization();
updateStatusLine();
}
}
}
const HANDLERS = {
@@ -820,6 +835,7 @@ function connect() {
initialTempSollSync = true;
initialPotTempSync = true;
closedLoop = true;
potConfig = {};
setConnected(true);
for (const channel of CHANNELS) {
ws.send(JSON.stringify({'+': channel}));