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