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