Reformatting
This commit is contained in:
parent
400fe40bcd
commit
9ad18a17c8
98
main.py
98
main.py
|
|
@ -50,11 +50,11 @@ latest_data: Dict[str, Any] = {
|
|||
"PU_1": None,
|
||||
"PU_2": None,
|
||||
"PU_3": None,
|
||||
"DS" : None,
|
||||
"DS": None,
|
||||
"PatientSkid": {"QSkid": 0.0},
|
||||
}
|
||||
|
||||
active_PUs : list[int] = []
|
||||
active_PUs: list[int] = []
|
||||
|
||||
DEFAULT_FEED_VALVE = 0.0
|
||||
|
||||
|
|
@ -78,7 +78,8 @@ def format_PU_data(data):
|
|||
"Qdilute": np.round(data.get("FM1", 0.0), 1),
|
||||
"Qdrain": np.round(data.get("FM4", 0.0), 1),
|
||||
"Qrecirc": np.round(data.get("FM3", 0.0), 1),
|
||||
"QdrainEDI": np.round(data.get("FM2", 0.0), 1)- np.round(data.get("FM1", 0.0), 1),
|
||||
"QdrainEDI": np.round(data.get("FM2", 0.0), 1)
|
||||
- np.round(data.get("FM1", 0.0), 1),
|
||||
"Pro": np.round(data.get("PS2", 0.0), 2),
|
||||
"Pdilute": np.round(data.get("PS3", 0.0), 2),
|
||||
"Pretentate": np.round(data.get("PS1", 0.0), 2),
|
||||
|
|
@ -109,11 +110,9 @@ def format_DS_data(data):
|
|||
"TankLevel": np.round(data.get("TankLevel", 0.0), 2),
|
||||
"Qinlet": np.round(data.get("Inlet_flow", 0.0), 1),
|
||||
"Qoutlet": np.round(data.get("Outlet_flow", 0.0), 1),
|
||||
|
||||
"Q_conso_filt": np.round(data.get("Qdrain_sp", 0.0), 1),
|
||||
"Q_conso_filt": np.round(data.get("Qdrain_sp", 0.0), 1),
|
||||
"Q_conso_filt": np.round(data.get("Qdrain_sp", 0.0), 1),
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -164,6 +163,12 @@ def logout(request: Request):
|
|||
# ======== PROTECTED INTERFACE ========
|
||||
|
||||
|
||||
@app.on_event("startup")
|
||||
async def startup_event():
|
||||
asyncio.create_task(update_latest_data())
|
||||
asyncio.create_task(update_latest_flow())
|
||||
|
||||
|
||||
@app.get("/control", response_class=HTMLResponse)
|
||||
def control_page(request: Request):
|
||||
can_backend.connect()
|
||||
|
|
@ -177,12 +182,14 @@ def monitor_page(request: Request):
|
|||
with open("static/monitor_DS.html") as f:
|
||||
return HTMLResponse(f.read())
|
||||
|
||||
@app.get("/monitor-page", response_class=HTMLResponse)
|
||||
|
||||
@app.get("/monitor-PU", response_class=HTMLResponse)
|
||||
def monitor_page(request: Request):
|
||||
with open("static/monitor_PU.html") as f:
|
||||
return HTMLResponse(f.read())
|
||||
|
||||
@app.get("/multi-monitor-page", response_class=HTMLResponse)
|
||||
|
||||
@app.get("/multi-monitor-PU", response_class=HTMLResponse)
|
||||
def monitor_page(request: Request):
|
||||
with open("static/multi_pu_dashboard.html") as f:
|
||||
return HTMLResponse(f.read())
|
||||
|
|
@ -190,6 +197,7 @@ def monitor_page(request: Request):
|
|||
|
||||
# ======== CAN + BACKEND ROUTES ========
|
||||
|
||||
|
||||
@app.post("/connect_toggle")
|
||||
def connect_toggle():
|
||||
logging.info(f"Toggling CAN connection, CAN is {can_backend.connected}")
|
||||
|
|
@ -204,11 +212,15 @@ def connect_toggle():
|
|||
raise HTTPException(status_code=500, detail="Connection failed.")
|
||||
return {"connected": can_backend.connected}
|
||||
|
||||
|
||||
@app.get("/is_connected")
|
||||
def is_connected():
|
||||
return {"connected": can_backend.connected}
|
||||
|
||||
|
||||
# PU CONTROL
|
||||
|
||||
|
||||
@app.post("/command/{state}/pu/{pu_number}")
|
||||
def send_command(state: str, pu_number: int, ploop_setpoint: float = Query(...)):
|
||||
global DEFAULT_FEED_VALVE
|
||||
|
|
@ -243,6 +255,9 @@ def send_command(state: str, pu_number: int, ploop_setpoint: float = Query(...))
|
|||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
|
||||
## MONITORING
|
||||
|
||||
|
||||
@app.get("/api/pu_status")
|
||||
def get_pu_status():
|
||||
global active_PUs
|
||||
|
|
@ -253,7 +268,11 @@ def get_pu_status():
|
|||
}
|
||||
logging.info(f"[PU STATUS] {states}")
|
||||
|
||||
active_PUs = [index + 1 for index, (pu, status) in enumerate(states.items()) if status != 'Offline']
|
||||
active_PUs = [
|
||||
index + 1
|
||||
for index, (pu, status) in enumerate(states.items())
|
||||
if status != "Offline"
|
||||
]
|
||||
logging.info(f"[ACTIVE PU] {active_PUs}")
|
||||
|
||||
return JSONResponse(content=states)
|
||||
|
|
@ -262,7 +281,7 @@ def get_pu_status():
|
|||
async def update_latest_data():
|
||||
global active_PUs
|
||||
while True:
|
||||
#DS
|
||||
# DS
|
||||
data = can_backend.get_latest_data(pu_number=0)
|
||||
latest_data[f"DS"] = format_DS_data(data)
|
||||
|
||||
|
|
@ -271,7 +290,6 @@ async def update_latest_data():
|
|||
data = can_backend.get_latest_data(pu_number=pu)
|
||||
latest_data[f"PU_{pu}"] = format_PU_data(data)
|
||||
|
||||
|
||||
logging.debug(f"[MONITOR DS BUFFER] latest_data: {latest_data}")
|
||||
await asyncio.sleep(0.05)
|
||||
|
||||
|
|
@ -281,18 +299,6 @@ async def get_monitor_data():
|
|||
return JSONResponse(content=latest_data)
|
||||
|
||||
|
||||
@app.on_event("startup")
|
||||
async def startup_event():
|
||||
asyncio.create_task(update_latest_data())
|
||||
asyncio.create_task(update_latest_flow())
|
||||
|
||||
|
||||
@app.get("/can_status")
|
||||
def can_status():
|
||||
"""Return current CAN connection status."""
|
||||
return {"connected": can_backend.connected}
|
||||
|
||||
|
||||
# LOCAL RECORDER
|
||||
@app.post("/start_recording")
|
||||
async def start_recording():
|
||||
|
|
@ -344,11 +350,7 @@ async def record_data_loop():
|
|||
timestamp = datetime.datetime.now().isoformat()
|
||||
for pu, data in latest_data.items():
|
||||
if data:
|
||||
row = {
|
||||
"timestamp": timestamp,
|
||||
"pu": pu,
|
||||
**data
|
||||
}
|
||||
row = {"timestamp": timestamp, "pu": pu, **data}
|
||||
recording_writer.writerow(row)
|
||||
|
||||
# Flush every flush_interval seconds
|
||||
|
|
@ -360,18 +362,26 @@ async def record_data_loop():
|
|||
|
||||
await asyncio.sleep(0.05) # 10 Hz
|
||||
|
||||
|
||||
## AUTOMATIC TESTING
|
||||
|
||||
async def send_command_with_delay(state: str, pu: int, delay_s: int = 0, ploop_setpoint: float = 0.0):
|
||||
|
||||
async def send_command_with_delay(
|
||||
state: str, pu: int, delay_s: int = 0, ploop_setpoint: float = 0.0
|
||||
):
|
||||
await asyncio.sleep(delay_s)
|
||||
logging.info(f"[AUTO TEST] Sending {state} to PU{pu} after {delay_s}s")
|
||||
can_backend.send_state_command(state, pu, ploop_setpoint)
|
||||
|
||||
|
||||
async def set_patients_with_delay(count: int, delay_s: int):
|
||||
await asyncio.sleep(delay_s)
|
||||
logging.info(f"[AUTO TEST] Sending {count} patients to patient skid after {delay_s}s")
|
||||
logging.info(
|
||||
f"[AUTO TEST] Sending {count} patients to patient skid after {delay_s}s"
|
||||
)
|
||||
set_patient_skid_users(count)
|
||||
|
||||
|
||||
@router.post("/test/auto/1")
|
||||
async def auto_test_pu1(ploop_setpoint: float = Query(0.0)):
|
||||
pu = 1
|
||||
|
|
@ -379,39 +389,52 @@ async def auto_test_pu1(ploop_setpoint: float = Query(0.0)):
|
|||
asyncio.create_task(run_auto_test_pu1(pu, ploop_setpoint))
|
||||
return {"status": "started", "pu": pu}
|
||||
|
||||
|
||||
@router.post("/test/auto/2")
|
||||
async def auto_test_pu2(ploop_setpoint: float = Query(0.0)):
|
||||
logging.info("[AUTO TEST] Starting automatic test for 2 PUs")
|
||||
asyncio.create_task(run_auto_test_pu2(ploop_setpoint))
|
||||
return {"status": "started", "pu": [1, 2]}
|
||||
|
||||
|
||||
async def run_auto_test_pu1(pu: int, ploop_setpoint: float):
|
||||
await send_command_with_delay("PRE-PRODUCTION", pu, delay_s=0, ploop_setpoint=ploop_setpoint)
|
||||
await send_command_with_delay("PRODUCTION", pu, delay_s=180, ploop_setpoint=ploop_setpoint)
|
||||
await send_command_with_delay(
|
||||
"PRE-PRODUCTION", pu, delay_s=0, ploop_setpoint=ploop_setpoint
|
||||
)
|
||||
await send_command_with_delay(
|
||||
"PRODUCTION", pu, delay_s=180, ploop_setpoint=ploop_setpoint
|
||||
)
|
||||
await set_patients_with_delay(5, delay_s=60)
|
||||
await set_patients_with_delay(10, delay_s=60)
|
||||
await send_command_with_delay("IDLE", pu, delay_s=60, ploop_setpoint=ploop_setpoint)
|
||||
logging.info("[AUTO TEST] Finished PU1 test")
|
||||
|
||||
|
||||
async def run_auto_test_pu2(ploop_setpoint: float):
|
||||
# Step 1: Run PU1 test
|
||||
await run_auto_test_pu1(1, ploop_setpoint)
|
||||
|
||||
# Step 2: PU2 sequence
|
||||
await send_command_with_delay("PRE-PRODUCTION", 2, delay_s=0, ploop_setpoint=ploop_setpoint)
|
||||
await send_command_with_delay("PRODUCTION", 2, delay_s=180, ploop_setpoint=ploop_setpoint)
|
||||
await send_command_with_delay(
|
||||
"PRE-PRODUCTION", 2, delay_s=0, ploop_setpoint=ploop_setpoint
|
||||
)
|
||||
await send_command_with_delay(
|
||||
"PRODUCTION", 2, delay_s=180, ploop_setpoint=ploop_setpoint
|
||||
)
|
||||
await set_patients_with_delay(15, delay_s=60)
|
||||
await set_patients_with_delay(0, delay_s=60)
|
||||
await send_command_with_delay("IDLE", 2, delay_s=60, ploop_setpoint=ploop_setpoint)
|
||||
await send_command_with_delay("IDLE", 1, delay_s=60, ploop_setpoint=ploop_setpoint)
|
||||
logging.info("[AUTO TEST] Finished PU1 + PU2 test")
|
||||
|
||||
|
||||
@router.post("/test/auto/3")
|
||||
async def auto_test_pu3():
|
||||
# Call the function for PU3 auto test
|
||||
logging.info("Start auto test of 3 PU")
|
||||
return {"status": "started", "pu": 3}
|
||||
|
||||
|
||||
# PATIENT SKID HELPERS
|
||||
async def update_latest_flow():
|
||||
global active_PUs
|
||||
|
|
@ -431,6 +454,7 @@ async def update_latest_flow():
|
|||
logging.error(f"Error fetching flow: {e}")
|
||||
await asyncio.sleep(1.0)
|
||||
|
||||
|
||||
def set_patient_skid_users(count: int = 1):
|
||||
try:
|
||||
url = f"http://192.168.1.28:8000/set_users/{count}"
|
||||
|
|
@ -439,9 +463,13 @@ def set_patient_skid_users(count: int = 1):
|
|||
if response.status_code == 200:
|
||||
return {"status": "success", "detail": response.json()}
|
||||
else:
|
||||
raise HTTPException(status_code=502, detail=f"Remote server error: {response.text}")
|
||||
raise HTTPException(
|
||||
status_code=502, detail=f"Remote server error: {response.text}"
|
||||
)
|
||||
except httpx.RequestError as e:
|
||||
raise HTTPException(status_code=500, detail=f"Request to external server failed: {str(e)}")
|
||||
raise HTTPException(
|
||||
status_code=500, detail=f"Request to external server failed: {str(e)}"
|
||||
)
|
||||
|
||||
|
||||
app.include_router(router)
|
||||
|
|
|
|||
|
|
@ -241,16 +241,16 @@
|
|||
<h1>Hydraulic Machine Control</h1>
|
||||
<div class="monitor-pu-buttons">
|
||||
<!-- New multi-monitor button -->
|
||||
<a href="/multi-monitor-page" target="_blank" class="monitor-link">
|
||||
<a href="/multi-monitor-PU" 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">
|
||||
<a href="/monitor-PU?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">
|
||||
<a href="/monitor-PU?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">
|
||||
<a href="/monitor-PU?pu_number=3" target="_blank" class="monitor-link">
|
||||
<i class="fas fa-chart-line"></i> Monitor PU 3
|
||||
</a>
|
||||
<a href="/monitor-DS" target="_blank" class="monitor-link">
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user