Adds Qskid
This commit is contained in:
parent
2c50795388
commit
f5a7b3c8d7
|
|
@ -31,10 +31,11 @@ class CANBackend:
|
||||||
# Simulate getting the latest data with random values
|
# Simulate getting the latest data with random values
|
||||||
if pu_number ==1:
|
if pu_number ==1:
|
||||||
return {
|
return {
|
||||||
"FM2": 1080,
|
"FM2": 630.0,
|
||||||
"FM3": 1080,
|
"FM2": 1080.0,
|
||||||
"FM4": 1080,
|
"FM3": 1080.0,
|
||||||
"FM5": 1080,
|
"FM4": 1080.0,
|
||||||
|
"FM5": 1080.0,
|
||||||
"PS1": 6.2,
|
"PS1": 6.2,
|
||||||
"PS2": 6.2,
|
"PS2": 6.2,
|
||||||
"PS3": 6.2,
|
"PS3": 6.2,
|
||||||
|
|
|
||||||
43
main.py
43
main.py
|
|
@ -43,7 +43,7 @@ app.mount("/static", StaticFiles(directory="static"), name="static")
|
||||||
|
|
||||||
## BUFFER CREATION AND HELPER
|
## BUFFER CREATION AND HELPER
|
||||||
# Global object to store the latest data
|
# 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
|
# RECORDER
|
||||||
recording_flag = False
|
recording_flag = False
|
||||||
|
|
@ -54,6 +54,22 @@ write_buffer = deque()
|
||||||
flush_interval = 1.0 # flush every 1 second
|
flush_interval = 1.0 # flush every 1 second
|
||||||
last_flush_time = datetime.datetime.now()
|
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):
|
def format_data(data):
|
||||||
return {
|
return {
|
||||||
"timestamp": datetime.datetime.now().isoformat(),
|
"timestamp": datetime.datetime.now().isoformat(),
|
||||||
|
|
@ -81,21 +97,6 @@ def format_data(data):
|
||||||
"MV08_sp": np.round(data.get("MV08_sp", 0.0), 1),
|
"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
|
# CREDENTIALS
|
||||||
|
|
||||||
# Load users from JSON file at startup
|
# Load users from JSON file at startup
|
||||||
|
|
@ -111,8 +112,6 @@ PASSWORD = CREDENTIALS["password"]
|
||||||
|
|
||||||
|
|
||||||
# ======== LOGIN & SESSION HANDLING ========
|
# ======== LOGIN & SESSION HANDLING ========
|
||||||
|
|
||||||
|
|
||||||
def require_login(request: Request):
|
def require_login(request: Request):
|
||||||
user = request.session.get("user")
|
user = request.session.get("user")
|
||||||
if user != USERNAME:
|
if user != USERNAME:
|
||||||
|
|
@ -226,17 +225,17 @@ def get_pu_status():
|
||||||
|
|
||||||
async def update_latest_data():
|
async def update_latest_data():
|
||||||
while True:
|
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)
|
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}"] = 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)
|
await asyncio.sleep(0.2)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/monitor")
|
@app.get("/monitor")
|
||||||
async def get_monitor_data(pu_number: Optional[int] = Query(None)):
|
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:
|
if pu_number is not None:
|
||||||
return latest_data.get(f"PU_{pu_number}", {})
|
return latest_data.get(f"PU_{pu_number}", {})
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -59,12 +59,12 @@
|
||||||
<div id="pressure-plot-1" class="large-plot"></div>
|
<div id="pressure-plot-1" class="large-plot"></div>
|
||||||
<div id="flow-plot-2" class="large-plot"></div>
|
<div id="flow-plot-2" class="large-plot"></div>
|
||||||
<div id="pressure-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="MV02_sp-plot" class="small-plot"></div>
|
||||||
<div id="mv03-plot" class="small-plot"></div>
|
<div id="MV03_sp-plot" class="small-plot"></div>
|
||||||
<div id="mv04-05-plot" class="small-plot"></div>
|
<div id="MV04_sp-05-plot" class="small-plot"></div>
|
||||||
<div id="mv06-plot" class="small-plot"></div>
|
<div id="MV06_sp-plot" class="small-plot"></div>
|
||||||
<div id="mv07-plot" class="small-plot"></div>
|
<div id="MV07_sp-plot" class="small-plot"></div>
|
||||||
<div id="mv08-plot" class="small-plot"></div>
|
<div id="MV08_sp-plot" class="small-plot"></div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
// Extract PU number from URL
|
// Extract PU number from URL
|
||||||
|
|
@ -103,6 +103,7 @@
|
||||||
}
|
}
|
||||||
const allData = await response.json();
|
const allData = await response.json();
|
||||||
const puData = allData[`PU_${puNumber}`];
|
const puData = allData[`PU_${puNumber}`];
|
||||||
|
const SkidData = allData[`PatientSkid`];
|
||||||
recordedData.push({
|
recordedData.push({
|
||||||
timestamp: new Date().toISOString(),
|
timestamp: new Date().toISOString(),
|
||||||
Qperm: puData.Qperm,
|
Qperm: puData.Qperm,
|
||||||
|
|
@ -112,13 +113,14 @@
|
||||||
Pro: puData.Pro,
|
Pro: puData.Pro,
|
||||||
Pdilute: puData.Pdilute,
|
Pdilute: puData.Pdilute,
|
||||||
Prentate: puData.Prentate,
|
Prentate: puData.Prentate,
|
||||||
MV02: puData.MV02,
|
MV02_sp: puData.MV02_sp,
|
||||||
MV03: puData.MV03,
|
MV03_sp: puData.MV03_sp,
|
||||||
MV04: puData.MV04,
|
MV04_sp: puData.MV04_sp,
|
||||||
MV05: puData.MV05,
|
MV05_sp: puData.MV05_sp,
|
||||||
MV06: puData.MV06,
|
MV06_sp: puData.MV06_sp,
|
||||||
MV07: puData.MV07,
|
MV07_sp: puData.MV07_sp,
|
||||||
MV08: puData.MV08
|
MV08_sp: puData.MV08_sp,
|
||||||
|
QSkid: SkidData.QSkid,
|
||||||
});
|
});
|
||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
|
|
@ -127,9 +129,9 @@
|
||||||
clearInterval(recordingInterval);
|
clearInterval(recordingInterval);
|
||||||
if (recordedData.length > 0) {
|
if (recordedData.length > 0) {
|
||||||
const csvContent = "data:text/csv;charset=utf-8," +
|
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 =>
|
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");
|
).join("\n");
|
||||||
const encodedUri = encodeURI(csvContent);
|
const encodedUri = encodeURI(csvContent);
|
||||||
const link = document.createElement("a");
|
const link = document.createElement("a");
|
||||||
|
|
@ -160,6 +162,8 @@
|
||||||
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
|
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
const allData = await response.json();
|
const allData = await response.json();
|
||||||
const puData = allData[`PU_${puNumber}`];
|
const puData = allData[`PU_${puNumber}`];
|
||||||
|
const SkidData = allData[`PatientSkid`];
|
||||||
|
|
||||||
const timestamp = new Date(puData.timestamp);
|
const timestamp = new Date(puData.timestamp);
|
||||||
Plotly.extendTraces('flow-plot-1', {
|
Plotly.extendTraces('flow-plot-1', {
|
||||||
x: [[timestamp], [timestamp]],
|
x: [[timestamp], [timestamp]],
|
||||||
|
|
@ -167,9 +171,9 @@
|
||||||
}, [0, 1], maxPoints);
|
}, [0, 1], maxPoints);
|
||||||
|
|
||||||
Plotly.extendTraces('flow-plot-2', {
|
Plotly.extendTraces('flow-plot-2', {
|
||||||
x: [[timestamp], [timestamp]],
|
x: [[timestamp], [timestamp], [timestamp]],
|
||||||
y: [[puData.Qdrain], [puData.Qrecirc]]
|
y: [[puData.Qdrain], [puData.Qdrain], [SkidData.QSkid]]
|
||||||
}, [0, 1], maxPoints);
|
}, [0, 1, 2], maxPoints);
|
||||||
|
|
||||||
Plotly.extendTraces('pressure-plot-1', {
|
Plotly.extendTraces('pressure-plot-1', {
|
||||||
x: [[timestamp], [timestamp]],
|
x: [[timestamp], [timestamp]],
|
||||||
|
|
@ -181,18 +185,18 @@
|
||||||
y: [[puData.Pdilute]]
|
y: [[puData.Pdilute]]
|
||||||
}, [0], maxPoints);
|
}, [0], maxPoints);
|
||||||
|
|
||||||
Plotly.extendTraces('mv02-plot', { x: [[timestamp]], y: [[puData.MV02]] }, [0], maxPoints);
|
Plotly.extendTraces('MV02_sp-plot', { x: [[timestamp]], y: [[puData.MV02_sp]] }, [0], maxPoints);
|
||||||
Plotly.extendTraces('mv03-plot', { x: [[timestamp]], y: [[puData.MV03]] }, [0], maxPoints);
|
Plotly.extendTraces('MV03_sp-plot', { x: [[timestamp]], y: [[puData.MV03_sp]] }, [0], maxPoints);
|
||||||
Plotly.extendTraces('mv04-05-plot', {
|
Plotly.extendTraces('MV04_sp-05-plot', {
|
||||||
x: [[timestamp], [timestamp]],
|
x: [[timestamp], [timestamp]],
|
||||||
y: [[puData.MV04], [puData.MV05]]
|
y: [[puData.MV04_sp], [puData.MV05_sp]]
|
||||||
}, [0, 1], maxPoints);
|
}, [0, 1], maxPoints);
|
||||||
Plotly.extendTraces('mv06-plot', { x: [[timestamp]], y: [[puData.MV06]] }, [0], maxPoints);
|
Plotly.extendTraces('MV06_sp-plot', { x: [[timestamp]], y: [[puData.MV06_sp]] }, [0], maxPoints);
|
||||||
Plotly.extendTraces('mv07-plot', { x: [[timestamp]], y: [[puData.MV07]] }, [0], maxPoints);
|
Plotly.extendTraces('MV07_sp-plot', { x: [[timestamp]], y: [[puData.MV07_sp]] }, [0], maxPoints);
|
||||||
Plotly.extendTraces('mv08-plot', { x: [[timestamp]], y: [[puData.MV08]] }, [0], maxPoints);
|
Plotly.extendTraces('MV08_sp-plot', { x: [[timestamp]], y: [[puData.MV08_sp]] }, [0], maxPoints);
|
||||||
|
|
||||||
const range = getLastMinuteRange();
|
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 => {
|
// plotIds.forEach(id => {
|
||||||
// Plotly.relayout(id, { 'xaxis.range': range });
|
// Plotly.relayout(id, { 'xaxis.range': range });
|
||||||
// });
|
// });
|
||||||
|
|
@ -228,9 +232,10 @@
|
||||||
|
|
||||||
Plotly.newPlot('flow-plot-2', [
|
Plotly.newPlot('flow-plot-2', [
|
||||||
{ x: time0, y: [0], name: 'Qdrain', mode: 'lines', line: { color: 'red' } },
|
{ 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' },
|
xaxis: { title: 'Time', type: 'date' },
|
||||||
yaxis: { title: 'Flow (L/h)' }
|
yaxis: { title: 'Flow (L/h)' }
|
||||||
});
|
});
|
||||||
|
|
@ -252,41 +257,41 @@
|
||||||
yaxis: { title: 'Pressure (bar)' }
|
yaxis: { title: 'Pressure (bar)' }
|
||||||
});
|
});
|
||||||
|
|
||||||
Plotly.newPlot('mv02-plot', [{
|
Plotly.newPlot('MV02_sp-plot', [{
|
||||||
x: time0, y: [0], name: 'MV02', mode: 'lines'
|
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', [{
|
Plotly.newPlot('MV03_sp-plot', [{
|
||||||
x: time0, y: [0], name: 'MV03', mode: 'lines'
|
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', [
|
Plotly.newPlot('MV04_sp-05-plot', [
|
||||||
{ x: time0, y: [0], name: 'MV04', mode: 'lines' },
|
{ x: time0, y: [0], name: 'MV04_sp', mode: 'lines' },
|
||||||
{ x: time0, y: [0], name: 'MV05', 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', [{
|
Plotly.newPlot('MV06_sp-plot', [{
|
||||||
x: time0, y: [0], name: 'MV06', mode: 'lines'
|
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', [{
|
Plotly.newPlot('MV07_sp-plot', [{
|
||||||
x: time0, y: [0], name: 'MV07', mode: 'lines'
|
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', [{
|
Plotly.newPlot('MV08_sp-plot', [{
|
||||||
x: time0, y: [0], name: 'MV08', mode: 'lines'
|
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);
|
setInterval(updatePlots, 500);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user