Compare commits
2 Commits
4769323230
...
edc3a45194
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
edc3a45194 | ||
|
|
c74264545b |
79
main.py
79
main.py
|
|
@ -25,10 +25,12 @@ import aiohttp
|
||||||
|
|
||||||
if platform.system() in ["Darwin"]: # macOS or Windows
|
if platform.system() in ["Darwin"]: # macOS or Windows
|
||||||
from MockCAN import CANBackend
|
from MockCAN import CANBackend
|
||||||
|
|
||||||
logging.basicConfig(level=logging.INFO)
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
from classCAN import CANBackend # Your real backend
|
from classCAN import CANBackend # Your real backend
|
||||||
|
|
||||||
logging.basicConfig(level=logging.ERROR)
|
logging.basicConfig(level=logging.ERROR)
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
|
|
@ -36,14 +38,21 @@ app.add_middleware(SessionMiddleware, secret_key="your_super_secret_key")
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
templates = Jinja2Templates(directory="templates")
|
templates = Jinja2Templates(directory="templates")
|
||||||
can_backend = CANBackend()
|
can_backend = CANBackend()
|
||||||
valve_backend = ValveBackend(eds_file="/home/hmi/Desktop/HMI/eds_file/inletvalveboard.eds")
|
valve_backend = ValveBackend(
|
||||||
|
eds_file="/home/hmi/Desktop/HMI/eds_file/inletvalveboard.eds"
|
||||||
|
)
|
||||||
|
|
||||||
# Serve static files (HTML, JS, CSS)
|
# Serve static files (HTML, JS, CSS)
|
||||||
app.mount("/static", StaticFiles(directory="static"), name="static")
|
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, "PatientSkid" : {"QSkid":0.0}}
|
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 +63,7 @@ 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
|
## LOGGING QSkid
|
||||||
async def update_latest_flow():
|
async def update_latest_flow():
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
|
@ -73,30 +83,31 @@ async def update_latest_flow():
|
||||||
def format_data(data):
|
def format_data(data):
|
||||||
return {
|
return {
|
||||||
"timestamp": datetime.datetime.now().isoformat(),
|
"timestamp": datetime.datetime.now().isoformat(),
|
||||||
"Qperm": data.get("FM2", 0.0),
|
"Qperm": np.round(data.get("FM2", 0.0), 1),
|
||||||
"Qdilute": data.get("FM1", 0.0),
|
"Qdilute": np.round(data.get("FM1", 0.0), 1),
|
||||||
"Qdrain": data.get("FM4", 0.0),
|
"Qdrain": np.round(data.get("FM4", 0.0), 1),
|
||||||
"Qrecirc": data.get("FM3", 0.0),
|
"Qrecirc": np.round(data.get("FM3", 0.0), 1),
|
||||||
"Pro": data.get("PS1", 0.0),
|
"Pro": np.round(data.get("PS1", 0.0), 1),
|
||||||
"Pdilute": data.get("PS3", 0.0),
|
"Pdilute": np.round(data.get("PS3", 0.0), 1),
|
||||||
"Prentate": data.get("PS2", 0.0),
|
"Prentate": np.round(data.get("PS2", 0.0), 1),
|
||||||
"Conductivity": data.get("Cond", 0.0),
|
"Conductivity": np.round(data.get("Cond", 0.0), 1),
|
||||||
"MV02": data.get("MV02", 0.0),
|
"MV02": np.round(data.get("MV02", 0.0), 1),
|
||||||
"MV02_sp": data.get("MV02_sp", 0.0),
|
"MV02_sp": np.round(data.get("MV02_sp", 0.0), 1),
|
||||||
"MV03": data.get("MV03", 0.0),
|
"MV03": np.round(data.get("MV03", 0.0), 1),
|
||||||
"MV03_sp": data.get("MV03_sp", 0.0),
|
"MV03_sp": np.round(data.get("MV03_sp", 0.0), 1),
|
||||||
"MV04": data.get("MV05", 0.0),
|
"MV04": np.round(data.get("MV05", 0.0), 1),
|
||||||
"MV04_sp": data.get("MV05_sp", 0.0),
|
"MV04_sp": np.round(data.get("MV05_sp", 0.0), 1),
|
||||||
"MV05": data.get("MV05", 0.0),
|
"MV05": np.round(data.get("MV05", 0.0), 1),
|
||||||
"MV05_sp": data.get("MV05_sp", 0.0),
|
"MV05_sp": np.round(data.get("MV05_sp", 0.0), 1),
|
||||||
"MV06": data.get("MV06", 0.0),
|
"MV06": np.round(data.get("MV06", 0.0), 1),
|
||||||
"MV06_sp": data.get("MV06_sp", 0.0),
|
"MV06_sp": np.round(data.get("MV06_sp", 0.0), 1),
|
||||||
"MV07": data.get("MV07", 0.0),
|
"MV07": np.round(data.get("MV07", 0.0), 1),
|
||||||
"MV07_sp": data.get("MV07_sp", 0.0),
|
"MV07_sp": np.round(data.get("MV07_sp", 0.0), 1),
|
||||||
"MV08": data.get("MV08", 0.0),
|
"MV08": np.round(data.get("MV08", 0.0), 1),
|
||||||
"MV08_sp": data.get("MV08_sp", 0.0),
|
"MV08_sp": np.round(data.get("MV08_sp", 0.0), 1),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# CREDENTIALS
|
# CREDENTIALS
|
||||||
|
|
||||||
# Load users from JSON file at startup
|
# Load users from JSON file at startup
|
||||||
|
|
@ -169,14 +180,14 @@ def connect_toggle():
|
||||||
else:
|
else:
|
||||||
success = can_backend.connect()
|
success = can_backend.connect()
|
||||||
try:
|
try:
|
||||||
valve_backend.connect()
|
valve_backend.connect()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Connection error : {e}")
|
print(f"Connection error : {e}")
|
||||||
|
|
||||||
if not success:
|
if not success:
|
||||||
raise HTTPException(status_code=500, detail="Connection failed.")
|
raise HTTPException(status_code=500, detail="Connection failed.")
|
||||||
return {"connected": True}
|
return {"connected": True}
|
||||||
|
|
||||||
|
|
||||||
@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(...)):
|
||||||
|
|
@ -225,7 +236,10 @@ def get_pu_status():
|
||||||
|
|
||||||
async def update_latest_data():
|
async def update_latest_data():
|
||||||
while True:
|
while True:
|
||||||
for pu in [1, 2]: # TODO: REPLACE THIS WITH CONNECTED PUs, IS GET PU STATUS SLOW?
|
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)
|
||||||
latest_data[f"PU_{pu}"] = format_data(data)
|
latest_data[f"PU_{pu}"] = format_data(data)
|
||||||
current_data = latest_data[f"PU_{pu}"]
|
current_data = latest_data[f"PU_{pu}"]
|
||||||
|
|
@ -263,7 +277,8 @@ def feedvalve_control(MV01_opening: int = Query(...)):
|
||||||
logging.info(f"Feed valve opening to {MV01_opening}")
|
logging.info(f"Feed valve opening to {MV01_opening}")
|
||||||
return {"status": "ok"}
|
return {"status": "ok"}
|
||||||
|
|
||||||
#LOCAL RECORDER
|
|
||||||
|
# LOCAL RECORDER
|
||||||
@app.post("/start_recording")
|
@app.post("/start_recording")
|
||||||
async def start_recording():
|
async def start_recording():
|
||||||
global recording_flag, recording_task, recording_file, recording_writer
|
global recording_flag, recording_task, recording_file, recording_writer
|
||||||
|
|
@ -307,7 +322,6 @@ async def stop_recording():
|
||||||
return {"status": "recording stopped"}
|
return {"status": "recording stopped"}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def record_data_loop():
|
async def record_data_loop():
|
||||||
global recording_writer, recording_file, write_buffer, last_flush_time
|
global recording_writer, recording_file, write_buffer, last_flush_time
|
||||||
|
|
||||||
|
|
@ -315,6 +329,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 = {"timestamp": timestamp, "pu": pu, **data}
|
||||||
print("record_data",data)
|
print("record_data",data)
|
||||||
row = {
|
row = {
|
||||||
"timestamp": timestamp,
|
"timestamp": timestamp,
|
||||||
|
|
@ -324,11 +339,15 @@ async def record_data_loop():
|
||||||
recording_writer.writerow(row)
|
recording_writer.writerow(row)
|
||||||
|
|
||||||
# Flush every flush_interval seconds
|
# Flush every flush_interval seconds
|
||||||
if (datetime.datetime.now() - last_flush_time).total_seconds() >= flush_interval:
|
if (
|
||||||
|
datetime.datetime.now() - last_flush_time
|
||||||
|
).total_seconds() >= flush_interval:
|
||||||
recording_file.flush()
|
recording_file.flush()
|
||||||
last_flush_time = datetime.datetime.now()
|
last_flush_time = datetime.datetime.now()
|
||||||
|
|
||||||
await asyncio.sleep(0.1) # 10 Hz
|
await asyncio.sleep(0.1) # 10 Hz
|
||||||
|
|
||||||
|
|
||||||
app.include_router(router)
|
app.include_router(router)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
||||||
|
|
@ -260,13 +260,13 @@
|
||||||
Plotly.newPlot('MV02_sp-plot', [{
|
Plotly.newPlot('MV02_sp-plot', [{
|
||||||
x: time0, y: [0], name: 'MV02_sp', mode: 'lines'
|
x: time0, y: [0], name: 'MV02_sp', mode: 'lines'
|
||||||
}], {
|
}], {
|
||||||
title: 'MV02_sp (%)', yaxis: { range: [0, 100] }, xaxis: { type: 'date' }
|
title: 'MV02_sp (%)', yaxis: { }, xaxis: { type: 'date' }
|
||||||
});
|
});
|
||||||
|
|
||||||
Plotly.newPlot('MV03_sp-plot', [{
|
Plotly.newPlot('MV03_sp-plot', [{
|
||||||
x: time0, y: [0], name: 'MV03_sp', mode: 'lines'
|
x: time0, y: [0], name: 'MV03_sp', mode: 'lines'
|
||||||
}], {
|
}], {
|
||||||
title: 'MV03_sp (%)', yaxis: { range: [0, 100] }, xaxis: { type: 'date' }
|
title: 'MV03_sp (%)', yaxis: { }, xaxis: { type: 'date' }
|
||||||
});
|
});
|
||||||
|
|
||||||
Plotly.newPlot('MV04_sp-05-plot', [
|
Plotly.newPlot('MV04_sp-05-plot', [
|
||||||
|
|
@ -279,13 +279,13 @@
|
||||||
Plotly.newPlot('MV06_sp-plot', [{
|
Plotly.newPlot('MV06_sp-plot', [{
|
||||||
x: time0, y: [0], name: 'MV06_sp', mode: 'lines'
|
x: time0, y: [0], name: 'MV06_sp', mode: 'lines'
|
||||||
}], {
|
}], {
|
||||||
title: 'MV06_sp (%)', yaxis: { range: [0, 100] }, xaxis: { type: 'date' }
|
title: 'MV06_sp (%)', yaxis: { }, xaxis: { type: 'date' }
|
||||||
});
|
});
|
||||||
|
|
||||||
Plotly.newPlot('MV07_sp-plot', [{
|
Plotly.newPlot('MV07_sp-plot', [{
|
||||||
x: time0, y: [0], name: 'MV07_sp', mode: 'lines'
|
x: time0, y: [0], name: 'MV07_sp', mode: 'lines'
|
||||||
}], {
|
}], {
|
||||||
title: 'MV07_sp (%)', yaxis: { range: [0, 100] }, xaxis: { type: 'date' }
|
title: 'MV07_sp (%)', yaxis: { }, xaxis: { type: 'date' }
|
||||||
});
|
});
|
||||||
|
|
||||||
Plotly.newPlot('MV08_sp-plot', [{
|
Plotly.newPlot('MV08_sp-plot', [{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user