Adds multi_pu_dashboard.html
This commit is contained in:
parent
df12b633fd
commit
5e99fd392e
124
static/multi_pu_dashboard.html
Normal file
124
static/multi_pu_dashboard.html
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>Multi-PU Dashboard</title>
|
||||
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
}
|
||||
h1 {
|
||||
text-align: center;
|
||||
}
|
||||
.plot-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 40px;
|
||||
align-items: center;
|
||||
}
|
||||
.plot {
|
||||
width: 90%;
|
||||
height: 300px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Multi-PU Monitoring Dashboard</h1>
|
||||
<div class="plot-container">
|
||||
<div id="Qperm-plot" class="plot"></div>
|
||||
<div id="Pdilute-plot" class="plot"></div>
|
||||
<div id="Pro-plot" class="plot"></div>
|
||||
<div id="Qdilute-plot" class="plot"></div>
|
||||
<div id="Qdrain-plot" class="plot"></div>
|
||||
</div>
|
||||
<script>
|
||||
const time0 = [new Date()];
|
||||
const zero = [0];
|
||||
const maxPoints = 200;
|
||||
const puList = ['PU_1', 'PU_2', 'PU_3'];
|
||||
|
||||
const plots = [
|
||||
{ id: 'Qperm-plot', quantity: 'Qperm', title: 'Qperm per PU', ref: 1200 },
|
||||
{ id: 'Qdilute-plot', quantity: 'Qdilute', title: 'Qdilute per PU' },
|
||||
{ id: 'Qdrain-plot', quantity: 'Qdrain', title: 'Qdrain per PU' },
|
||||
{ id: 'Pro-plot', quantity: 'Pro', title: 'Pro per PU' },
|
||||
{ id: 'Pdilute-plot', quantity: 'Pdilute', title: 'Pdilute per PU', ref: 2.5 },
|
||||
];
|
||||
|
||||
function makeTraces(quantity) {
|
||||
return puList.map((pu, i) => ({
|
||||
x: time0.slice(),
|
||||
y: zero.slice(),
|
||||
name: pu,
|
||||
mode: 'lines',
|
||||
line: { width: 2 },
|
||||
legendgroup: pu
|
||||
}));
|
||||
}
|
||||
function initAllPlots() {
|
||||
plots.forEach(plot => {
|
||||
const data = makeTraces(plot.quantity);
|
||||
const layout = {
|
||||
title: plot.title,
|
||||
xaxis: { title: 'Time', type: 'date' },
|
||||
yaxis: { title: plot.id.includes('P') ? 'Pressure (bar)' : 'Flow (L/h)' },
|
||||
};
|
||||
if (plot.ref !== undefined) {
|
||||
data.push({
|
||||
x: [time0[0], time0[0]],
|
||||
y: [plot.ref, plot.ref],
|
||||
mode: 'lines',
|
||||
line: { dash: 'dash', color: 'red' },
|
||||
name: `Ref ${plot.ref}`,
|
||||
showlegend: true
|
||||
});
|
||||
}
|
||||
Plotly.newPlot(plot.id, data, layout);
|
||||
});
|
||||
}
|
||||
async function updateAllPlots() {
|
||||
try {
|
||||
const res = await fetch('/monitor');
|
||||
if (!res.ok) throw new Error(`HTTP error! status: ${res.status}`);
|
||||
const allData = await res.json();
|
||||
const timestamp = new Date();
|
||||
|
||||
// SkidData is only fetched once
|
||||
const SkidData = allData["PatientSkid"] || {};
|
||||
|
||||
|
||||
plots.forEach(plot => {
|
||||
const xUpdates = [];
|
||||
const yUpdates = [];
|
||||
|
||||
puList.forEach(pu => {
|
||||
const puData = allData[pu] || {};
|
||||
const value = puData[plot.quantity];
|
||||
xUpdates.push([timestamp]);
|
||||
yUpdates.push([value !== undefined ? value : null]);
|
||||
});
|
||||
|
||||
Plotly.extendTraces(plot.id, { x: xUpdates, y: yUpdates }, puList.map((_, i) => i), maxPoints);
|
||||
|
||||
if (plot.ref !== undefined) {
|
||||
Plotly.extendTraces(plot.id, {
|
||||
x: [[timestamp]],
|
||||
y: [[plot.ref]]
|
||||
}, [puList.length], maxPoints); // the ref line is always the last trace
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
console.error("Failed to update plots:", err);
|
||||
}
|
||||
}
|
||||
|
||||
initAllPlots();
|
||||
setInterval(updateAllPlots, 1000);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -231,19 +231,25 @@
|
|||
<div class="header">
|
||||
<h1>Hydraulic Machine Control</h1>
|
||||
<div class="monitor-pu-buttons">
|
||||
<a href="/monitor-page?pu_number=1" target="_blank" class="monitor-link">
|
||||
<i class="fas fa-chart-line"></i> Monitor PU 1
|
||||
</a>
|
||||
<a href="/monitor-page?pu_number=2" target="_blank" class="monitor-link">
|
||||
<i class="fas fa-chart-line"></i> Monitor PU 2
|
||||
</a>
|
||||
<a href="/monitor-page?pu_number=3" target="_blank" class="monitor-link">
|
||||
<i class="fas fa-chart-line"></i> Monitor PU 3
|
||||
</a>
|
||||
<!-- New Record Button -->
|
||||
<button id="recordButton" class="connect-button" onclick="toggleRecording()">
|
||||
<i class="fas fa-circle"></i> Start Recording
|
||||
</button>
|
||||
<!-- New multi-monitor button -->
|
||||
<a href="/multi-monitor-page" target="_blank" class="monitor-link">
|
||||
<i class="fas fa-chart-bar"></i> Monitor All PUs
|
||||
</a>
|
||||
|
||||
<a href="/monitor-page?pu_number=1" target="_blank" class="monitor-link">
|
||||
<i class="fas fa-chart-line"></i> Monitor PU 1
|
||||
</a>
|
||||
<a href="/monitor-page?pu_number=2" target="_blank" class="monitor-link">
|
||||
<i class="fas fa-chart-line"></i> Monitor PU 2
|
||||
</a>
|
||||
<a href="/monitor-page?pu_number=3" target="_blank" class="monitor-link">
|
||||
<i class="fas fa-chart-line"></i> Monitor PU 3
|
||||
</a>
|
||||
|
||||
<!-- New Record Button -->
|
||||
<button id="recordButton" class="connect-button" onclick="toggleRecording()">
|
||||
<i class="fas fa-circle"></i> Start Recording
|
||||
</button>
|
||||
</div>
|
||||
<button id="connectButton" class="connect-button" onclick="toggleConnection()">
|
||||
<i class="fas fa-power-off"></i> Connect
|
||||
|
|
@ -459,14 +465,8 @@
|
|||
<div class="monitor-value">Q_recirc<br>${puData.Qrecirc.toFixed(1)} L/h</div>
|
||||
<div class="monitor-value">P_ro<br>${puData.Pro.toFixed(1)} bar</div>
|
||||
<div class="monitor-value">P_dilute<br>${puData.Pdilute.toFixed(1)} bar</div>
|
||||
<div class="monitor-value">P_rentate<br>${puData.Prentate.toFixed(1)} bar</div>
|
||||
<div class="monitor-value">P_retentate<br>${puData.Pretentate.toFixed(1)} bar</div>
|
||||
<div class="monitor-value">Conductivity<br>${puData.Conductivity.toFixed(1)} µS/cm</div>
|
||||
<div class="monitor-value">MV02<br>${puData.MV02.toFixed(1)} % (sp: ${puData.MV02_sp.toFixed(1)})</div>
|
||||
<div class="monitor-value">MV03<br>${puData.MV03.toFixed(1)} % (sp: ${puData.MV03_sp.toFixed(1)})</div>
|
||||
<div class="monitor-value">MV05<br>${puData.MV05.toFixed(1)} % (sp: ${puData.MV05_sp.toFixed(1)})</div>
|
||||
<div class="monitor-value">MV06<br>${puData.MV06.toFixed(1)} % (sp: ${puData.MV06_sp.toFixed(1)})</div>
|
||||
<div class="monitor-value">MV07<br>${puData.MV07.toFixed(1)} % (sp: ${puData.MV07_sp.toFixed(1)})</div>
|
||||
<div class="monitor-value">MV08<br>${puData.MV08.toFixed(1)} % (sp: ${puData.MV08_sp.toFixed(1)})</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user