Adds Qskid

This commit is contained in:
Etienne Chassaing 2025-07-17 09:46:13 +02:00
parent 2c50795388
commit f5a7b3c8d7
3 changed files with 78 additions and 73 deletions

View File

@ -31,10 +31,11 @@ class CANBackend:
# Simulate getting the latest data with random values
if pu_number ==1:
return {
"FM2": 1080,
"FM3": 1080,
"FM4": 1080,
"FM5": 1080,
"FM2": 630.0,
"FM2": 1080.0,
"FM3": 1080.0,
"FM4": 1080.0,
"FM5": 1080.0,
"PS1": 6.2,
"PS2": 6.2,
"PS3": 6.2,

43
main.py
View File

@ -43,7 +43,7 @@ app.mount("/static", StaticFiles(directory="static"), name="static")
## BUFFER CREATION AND HELPER
# Global object to store the latest data
latest_data: Dict[str, Any] = {"PU_1": None, "PU_2": None, "PU_3": None}
latest_data: Dict[str, Any] = {"PU_1": None, "PU_2": None, "PU_3": None, "PatientSkid" : {"QSkid":0.0}}
# RECORDER
recording_flag = False
@ -54,6 +54,22 @@ write_buffer = deque()
flush_interval = 1.0 # flush every 1 second
last_flush_time = datetime.datetime.now()
## LOGGING QSkid
async def update_latest_flow():
async with aiohttp.ClientSession() as session:
while True:
try:
async with session.get("http://192.168.1.28:8000/instant_flow") as resp:
data = await resp.json()
latest_flow = int(data["log"]["flow"])
logging.debug(f"Updated flow: {latest_flow}")
latest_data["PatientSkid"]["QSkid"] = latest_flow
except Exception as e:
logging.error(f"Error fetching flow: {e}")
await asyncio.sleep(1)
def format_data(data):
return {
"timestamp": datetime.datetime.now().isoformat(),
@ -81,21 +97,6 @@ def format_data(data):
"MV08_sp": np.round(data.get("MV08_sp", 0.0), 1),
}
## LOGGING QCONSO
latest_flow = 0
async def update_latest_flow():
async with aiohttp.ClientSession() as session:
while True:
try:
async with session.get("http://192.168.1.28:8000/instant_flow") as resp:
data = await resp.json()
latest_flow = int(data["log"]["flow"])
logging.info(f"Updated flow: {latest_flow}")
except Exception as e:
logging.error(f"Error fetching flow: {e}")
await asyncio.sleep(1)
# CREDENTIALS
# Load users from JSON file at startup
@ -111,8 +112,6 @@ PASSWORD = CREDENTIALS["password"]
# ======== LOGIN & SESSION HANDLING ========
def require_login(request: Request):
user = request.session.get("user")
if user != USERNAME:
@ -226,17 +225,17 @@ def get_pu_status():
async def update_latest_data():
while True:
for pu in [1, 2, 3]:
for pu in [1, 2]: # TODO: REPLACE THIS WITH CONNECTED PUs, IS GET PU STATUS SLOW?
data = can_backend.get_latest_data(pu_number=pu)
# logging.info(f"[MONITOR BUFFER] PU{pu}: ") # {data}
latest_data[f"PU_{pu}"] = format_data(data)
latest_data[f"PU_{pu}"]["Qconso"] = latest_flow
current_data = latest_data[f"PU_{pu}"]
logging.debug(f"[MONITOR BUFFER] PU{pu}: {current_data}")
# logging.info(f"[MONITOR BUFFER] latest_data: {latest_data}")
await asyncio.sleep(0.2)
@app.get("/monitor")
async def get_monitor_data(pu_number: Optional[int] = Query(None)):
logging.info(f"[MONITOR DATA QUERY] {pu_number}")
if pu_number is not None:
return latest_data.get(f"PU_{pu_number}", {})
else:

View File

@ -59,12 +59,12 @@
<div id="pressure-plot-1" class="large-plot"></div>
<div id="flow-plot-2" class="large-plot"></div>
<div id="pressure-plot-2" class="large-plot"></div>
<div id="mv02-plot" class="small-plot"></div>
<div id="mv03-plot" class="small-plot"></div>
<div id="mv04-05-plot" class="small-plot"></div>
<div id="mv06-plot" class="small-plot"></div>
<div id="mv07-plot" class="small-plot"></div>
<div id="mv08-plot" class="small-plot"></div>
<div id="MV02_sp-plot" class="small-plot"></div>
<div id="MV03_sp-plot" class="small-plot"></div>
<div id="MV04_sp-05-plot" class="small-plot"></div>
<div id="MV06_sp-plot" class="small-plot"></div>
<div id="MV07_sp-plot" class="small-plot"></div>
<div id="MV08_sp-plot" class="small-plot"></div>
</div>
<script>
// Extract PU number from URL
@ -103,6 +103,7 @@
}
const allData = await response.json();
const puData = allData[`PU_${puNumber}`];
const SkidData = allData[`PatientSkid`];
recordedData.push({
timestamp: new Date().toISOString(),
Qperm: puData.Qperm,
@ -112,13 +113,14 @@
Pro: puData.Pro,
Pdilute: puData.Pdilute,
Prentate: puData.Prentate,
MV02: puData.MV02,
MV03: puData.MV03,
MV04: puData.MV04,
MV05: puData.MV05,
MV06: puData.MV06,
MV07: puData.MV07,
MV08: puData.MV08
MV02_sp: puData.MV02_sp,
MV03_sp: puData.MV03_sp,
MV04_sp: puData.MV04_sp,
MV05_sp: puData.MV05_sp,
MV06_sp: puData.MV06_sp,
MV07_sp: puData.MV07_sp,
MV08_sp: puData.MV08_sp,
QSkid: SkidData.QSkid,
});
}, 100);
}
@ -127,9 +129,9 @@
clearInterval(recordingInterval);
if (recordedData.length > 0) {
const csvContent = "data:text/csv;charset=utf-8," +
"Timestamp,Qperm,Qdilute,Qdrain,Qrecirc,Pro,Pdilute,Prentate,MV02,MV03,MV04,MV05,MV06,MV07,MV08\n" +
"Timestamp,Qperm,Qdilute,Qdrain,Qrecirc,Pro,Pdilute,Prentate,MV02_sp,MV03_sp,MV04_sp,MV05_sp,MV06_sp,MV07_sp,MV08_sp,QSkid\n" +
recordedData.map(row =>
`${row.timestamp},${row.Qperm},${row.Qdilute},${row.Qdrain},${row.Qrecirc},${row.Pro},${row.Pdilute},${row.Prentate},${row.MV02},${row.MV03},${row.MV04},${row.MV05},${row.MV06},${row.MV07},${row.MV08}`
`${row.timestamp},${row.Qperm},${row.Qdilute},${row.Qdrain},${row.Qrecirc},${row.Pro},${row.Pdilute},${row.Prentate},${row.MV02_sp},${row.MV03_sp},${row.MV04_sp},${row.MV05_sp},${row.MV06_sp},${row.MV07_sp},${row.MV08_sp},${row.QSkid}`
).join("\n");
const encodedUri = encodeURI(csvContent);
const link = document.createElement("a");
@ -160,6 +162,8 @@
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
const allData = await response.json();
const puData = allData[`PU_${puNumber}`];
const SkidData = allData[`PatientSkid`];
const timestamp = new Date(puData.timestamp);
Plotly.extendTraces('flow-plot-1', {
x: [[timestamp], [timestamp]],
@ -167,9 +171,9 @@
}, [0, 1], maxPoints);
Plotly.extendTraces('flow-plot-2', {
x: [[timestamp], [timestamp]],
y: [[puData.Qdrain], [puData.Qrecirc]]
}, [0, 1], maxPoints);
x: [[timestamp], [timestamp], [timestamp]],
y: [[puData.Qdrain], [puData.Qdrain], [SkidData.QSkid]]
}, [0, 1, 2], maxPoints);
Plotly.extendTraces('pressure-plot-1', {
x: [[timestamp], [timestamp]],
@ -181,18 +185,18 @@
y: [[puData.Pdilute]]
}, [0], maxPoints);
Plotly.extendTraces('mv02-plot', { x: [[timestamp]], y: [[puData.MV02]] }, [0], maxPoints);
Plotly.extendTraces('mv03-plot', { x: [[timestamp]], y: [[puData.MV03]] }, [0], maxPoints);
Plotly.extendTraces('mv04-05-plot', {
Plotly.extendTraces('MV02_sp-plot', { x: [[timestamp]], y: [[puData.MV02_sp]] }, [0], maxPoints);
Plotly.extendTraces('MV03_sp-plot', { x: [[timestamp]], y: [[puData.MV03_sp]] }, [0], maxPoints);
Plotly.extendTraces('MV04_sp-05-plot', {
x: [[timestamp], [timestamp]],
y: [[puData.MV04], [puData.MV05]]
y: [[puData.MV04_sp], [puData.MV05_sp]]
}, [0, 1], maxPoints);
Plotly.extendTraces('mv06-plot', { x: [[timestamp]], y: [[puData.MV06]] }, [0], maxPoints);
Plotly.extendTraces('mv07-plot', { x: [[timestamp]], y: [[puData.MV07]] }, [0], maxPoints);
Plotly.extendTraces('mv08-plot', { x: [[timestamp]], y: [[puData.MV08]] }, [0], maxPoints);
Plotly.extendTraces('MV06_sp-plot', { x: [[timestamp]], y: [[puData.MV06_sp]] }, [0], maxPoints);
Plotly.extendTraces('MV07_sp-plot', { x: [[timestamp]], y: [[puData.MV07_sp]] }, [0], maxPoints);
Plotly.extendTraces('MV08_sp-plot', { x: [[timestamp]], y: [[puData.MV08_sp]] }, [0], maxPoints);
const range = getLastMinuteRange();
const plotIds = ['flow-plot-1', 'flow-plot-2', 'pressure-plot-1', 'pressure-plot-2', 'mv02-plot', 'mv03-plot', 'mv04-05-plot', 'mv06-plot', 'mv07-plot', 'mv08-plot'];
const plotIds = ['flow-plot-1', 'flow-plot-2', 'pressure-plot-1', 'pressure-plot-2', 'MV02_sp-plot', 'MV03_sp-plot', 'MV04_sp-05-plot', 'MV06_sp-plot', 'MV07_sp-plot', 'MV08_sp-plot'];
// plotIds.forEach(id => {
// Plotly.relayout(id, { 'xaxis.range': range });
// });
@ -228,9 +232,10 @@
Plotly.newPlot('flow-plot-2', [
{ x: time0, y: [0], name: 'Qdrain', mode: 'lines', line: { color: 'red' } },
{ x: time0, y: [0], name: 'Qrecirc', mode: 'lines', line: { color: 'orange' } }
{ x: time0, y: [0], name: 'Qrecirc', mode: 'lines', line: { color: 'orange' } },
{ x: time0, y: [0], name: 'QSkid', mode: 'lines', line: { color: 'green' } }
], {
title: 'Qdrain and Qrecirc Flow Rates Over Time',
title: 'Qdrain, Qrecirc and Qskid Flow Rates Over Time',
xaxis: { title: 'Time', type: 'date' },
yaxis: { title: 'Flow (L/h)' }
});
@ -252,41 +257,41 @@
yaxis: { title: 'Pressure (bar)' }
});
Plotly.newPlot('mv02-plot', [{
x: time0, y: [0], name: 'MV02', mode: 'lines'
Plotly.newPlot('MV02_sp-plot', [{
x: time0, y: [0], name: 'MV02_sp', mode: 'lines'
}], {
title: 'MV02 (%)', yaxis: { range: [0, 100] }, xaxis: { type: 'date' }
title: 'MV02_sp (%)', yaxis: { range: [0, 100] }, xaxis: { type: 'date' }
});
Plotly.newPlot('mv03-plot', [{
x: time0, y: [0], name: 'MV03', mode: 'lines'
Plotly.newPlot('MV03_sp-plot', [{
x: time0, y: [0], name: 'MV03_sp', mode: 'lines'
}], {
title: 'MV03 (%)', yaxis: { range: [0, 100] }, xaxis: { type: 'date' }
title: 'MV03_sp (%)', yaxis: { range: [0, 100] }, xaxis: { type: 'date' }
});
Plotly.newPlot('mv04-05-plot', [
{ x: time0, y: [0], name: 'MV04', mode: 'lines' },
{ x: time0, y: [0], name: 'MV05', mode: 'lines' }
Plotly.newPlot('MV04_sp-05-plot', [
{ x: time0, y: [0], name: 'MV04_sp', mode: 'lines' },
{ x: time0, y: [0], name: 'MV05_sp', mode: 'lines' }
], {
title: 'MV04 + MV05 (%)', yaxis: { range: [0, 100] }, xaxis: { type: 'date' }
title: 'MV04_sp + MV05_sp (%)', yaxis: { range: [0, 100] }, xaxis: { type: 'date' }
});
Plotly.newPlot('mv06-plot', [{
x: time0, y: [0], name: 'MV06', mode: 'lines'
Plotly.newPlot('MV06_sp-plot', [{
x: time0, y: [0], name: 'MV06_sp', mode: 'lines'
}], {
title: 'MV06 (%)', yaxis: { range: [0, 100] }, xaxis: { type: 'date' }
title: 'MV06_sp (%)', yaxis: { range: [0, 100] }, xaxis: { type: 'date' }
});
Plotly.newPlot('mv07-plot', [{
x: time0, y: [0], name: 'MV07', mode: 'lines'
Plotly.newPlot('MV07_sp-plot', [{
x: time0, y: [0], name: 'MV07_sp', mode: 'lines'
}], {
title: 'MV07 (%)', yaxis: { range: [0, 100] }, xaxis: { type: 'date' }
title: 'MV07_sp (%)', yaxis: { range: [0, 100] }, xaxis: { type: 'date' }
});
Plotly.newPlot('mv08-plot', [{
x: time0, y: [0], name: 'MV08', mode: 'lines'
Plotly.newPlot('MV08_sp-plot', [{
x: time0, y: [0], name: 'MV08_sp', mode: 'lines'
}], {
title: 'MV08 (%)', yaxis: { range: [0, 100] }, xaxis: { type: 'date' }
title: 'MV08_sp (%)', yaxis: { range: [0, 100] }, xaxis: { type: 'date' }
});
setInterval(updatePlots, 500);