Timestamp synchro
This commit is contained in:
parent
656ae95f19
commit
1ddf8276ef
87
main.py
87
main.py
|
|
@ -13,8 +13,10 @@ from starlette.exceptions import HTTPException as StarletteHTTPException
|
||||||
from starlette.status import HTTP_302_FOUND
|
from starlette.status import HTTP_302_FOUND
|
||||||
import json
|
import json
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Optional
|
from typing import Optional, Dict, Any
|
||||||
from fastapi import Query
|
from fastapi import Query
|
||||||
|
import asyncio
|
||||||
|
import datetime
|
||||||
|
|
||||||
if platform.system() in ["Darwin"]: # macOS or Windows
|
if platform.system() in ["Darwin"]: # macOS or Windows
|
||||||
from MockCAN import CANBackend
|
from MockCAN import CANBackend
|
||||||
|
|
@ -30,6 +32,37 @@ can_backend = CANBackend()
|
||||||
# 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
|
||||||
|
# Global object to store the latest data
|
||||||
|
latest_data: Dict[str, Any] = {"PU_1": None, "PU_2": None, "PU_3": None}
|
||||||
|
|
||||||
|
|
||||||
|
def format_data(data):
|
||||||
|
return {
|
||||||
|
"timestamp": datetime.datetime.now().isoformat(),
|
||||||
|
"Qperm": data.get("FM2", 0.0),
|
||||||
|
"Qdilute": data.get("FM1", 0.0),
|
||||||
|
"Qdrain": data.get("FM4", 0.0),
|
||||||
|
"Qrecirc": data.get("FM3", 0.0),
|
||||||
|
"Pro": data.get("PS1", 0.0),
|
||||||
|
"Pdilute": data.get("PS3", 0.0),
|
||||||
|
"Prentate": data.get("PS2", 0.0),
|
||||||
|
"Conductivity": data.get("Cond", 0.0),
|
||||||
|
"MV02": data.get("MV02", 0.0),
|
||||||
|
"MV02_sp": data.get("MV02_sp", 0.0),
|
||||||
|
"MV03": data.get("MV03", 0.0),
|
||||||
|
"MV03_sp": data.get("MV03_sp", 0.0),
|
||||||
|
"MV05": data.get("MV05", 0.0),
|
||||||
|
"MV05_sp": data.get("MV05_sp", 0.0),
|
||||||
|
"MV06": data.get("MV06", 0.0),
|
||||||
|
"MV06_sp": data.get("MV06_sp", 0.0),
|
||||||
|
"MV07": data.get("MV07", 0.0),
|
||||||
|
"MV07_sp": data.get("MV07_sp", 0.0),
|
||||||
|
"MV08": data.get("MV08", 0.0),
|
||||||
|
"MV08_sp": data.get("MV08_sp", 0.0),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# CREDENTIALS
|
# CREDENTIALS
|
||||||
|
|
||||||
# Load users from JSON file at startup
|
# Load users from JSON file at startup
|
||||||
|
|
@ -152,41 +185,27 @@ def get_pu_status():
|
||||||
return JSONResponse(content=states)
|
return JSONResponse(content=states)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/monitor")
|
async def update_latest_data():
|
||||||
def get_monitor_data(pu_number: Optional[int] = Query(None)):
|
while True:
|
||||||
logging.info(f"[MONITOR DATA] {pu_number}")
|
|
||||||
def format_data(data):
|
|
||||||
return {
|
|
||||||
"Qperm": data.get("FM2", 0.0),
|
|
||||||
"Qdilute": data.get("FM1", 0.0),
|
|
||||||
"Qdrain": data.get("FM4", 0.0),
|
|
||||||
"Qrecirc": data.get("FM3", 0.0),
|
|
||||||
|
|
||||||
"Pro": data.get("PS1", 0.0),
|
|
||||||
"Pdilute": data.get("PS3", 0.0),
|
|
||||||
"Prentate": data.get("PS2", 0.0),
|
|
||||||
|
|
||||||
"Conductivity": data.get("Cond", 0.0),
|
|
||||||
|
|
||||||
"MV02": data.get("MV02", 0.0),
|
|
||||||
"MV02_sp": data.get("MV02_sp", 0.0),
|
|
||||||
"MV03": data.get("MV03", 0.0),
|
|
||||||
"MV03_sp": data.get("MV03_sp", 0.0),
|
|
||||||
"MV05": data.get("MV05", 0.0),
|
|
||||||
"MV05_sp": data.get("MV05_sp", 0.0),
|
|
||||||
"MV06": data.get("MV06", 0.0),
|
|
||||||
"MV06_sp": data.get("MV06_sp", 0.0),
|
|
||||||
"MV07": data.get("MV07", 0.0),
|
|
||||||
"MV07_sp": data.get("MV07_sp", 0.0),
|
|
||||||
"MV08": data.get("MV08", 0.0),
|
|
||||||
"MV08_sp": data.get("MV08_sp", 0.0),
|
|
||||||
}
|
|
||||||
all_data = {}
|
|
||||||
for pu in [1, 2, 3]:
|
for pu in [1, 2, 3]:
|
||||||
data = can_backend.get_latest_data(pu_number=pu)
|
data = can_backend.get_latest_data(pu_number=pu)
|
||||||
logging.info(f"[MONITOR] PU{pu}: {data}")
|
logging.info(f"[MONITOR BUFFER] PU{pu}: {data}")
|
||||||
all_data[f"PU_{pu}"] = format_data(data)
|
latest_data[f"PU_{pu}"] = format_data(data)
|
||||||
return all_data
|
await asyncio.sleep(0.1) # Update every 100ms
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/monitor")
|
||||||
|
async def get_monitor_data(pu_number: Optional[int] = Query(None)):
|
||||||
|
logging.info(f"[MONITOR DATA QUERY] {pu_number}")
|
||||||
|
if pu_number:
|
||||||
|
return latest_data.get(f"PU_{pu_number}", {})
|
||||||
|
else:
|
||||||
|
return latest_data
|
||||||
|
|
||||||
|
|
||||||
|
@app.on_event("startup")
|
||||||
|
async def startup_event():
|
||||||
|
asyncio.create_task(update_latest_data())
|
||||||
|
|
||||||
|
|
||||||
@app.get("/can_status")
|
@app.get("/can_status")
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,6 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
const maxPoints = 100;
|
const maxPoints = 100;
|
||||||
const time = () => new Date();
|
|
||||||
|
|
||||||
function getLastMinuteRange() {
|
function getLastMinuteRange() {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
|
|
@ -148,30 +147,22 @@
|
||||||
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 t = time();
|
|
||||||
|
// Convert timestamp string to Date object
|
||||||
|
const timestamp = new Date(puData.timestamp);
|
||||||
|
|
||||||
Plotly.extendTraces('flow-plot', {
|
Plotly.extendTraces('flow-plot', {
|
||||||
x: [[t], [t], [t], [t]],
|
x: [[timestamp], [timestamp], [timestamp], [timestamp]],
|
||||||
y: [[puData.Qperm], [puData.Qdilute], [puData.Qdrain], [puData.Qrecirc]]
|
y: [[puData.Qperm], [puData.Qdilute], [puData.Qdrain], [puData.Qrecirc]]
|
||||||
}, [0, 1, 2, 3], maxPoints);
|
}, [0, 1, 2, 3], maxPoints);
|
||||||
|
|
||||||
Plotly.extendTraces('pressure-plot', {
|
Plotly.extendTraces('pressure-plot', {
|
||||||
x: [[t], [t], [t]],
|
x: [[timestamp], [timestamp], [timestamp]],
|
||||||
y: [[puData.Pro], [puData.Pdilute], [puData.Prentate]]
|
y: [[puData.Pro], [puData.Pdilute], [puData.Prentate]]
|
||||||
}, [0, 1, 2], maxPoints);
|
}, [0, 1, 2], maxPoints);
|
||||||
// Plotly.extendTraces('mv02-plot', { x: [[t]], y: [[puData.MV02]] }, [0]);
|
|
||||||
// Plotly.extendTraces('mv03-plot', { x: [[t]], y: [[puData.MV03]] }, [0]);
|
|
||||||
// Plotly.extendTraces('mv04-05-plot', {
|
|
||||||
// x: [[t], [t]],
|
|
||||||
// y: [[puData.MV04], [puData.MV05]]
|
|
||||||
// }, [0, 1]);
|
|
||||||
// Plotly.extendTraces('mv06-plot', { x: [[t]], y: [[puData.MV06]] }, [0]);
|
|
||||||
// Plotly.extendTraces('mv07-plot', { x: [[t]], y: [[puData.MV07]] }, [0]);
|
|
||||||
// Plotly.extendTraces('mv08-plot', { x: [[t]], y: [[puData.MV08]] }, [0]);
|
|
||||||
|
|
||||||
const range = getLastMinuteRange();
|
const range = getLastMinuteRange();
|
||||||
const plotIds = [
|
const plotIds = ['flow-plot', 'pressure-plot'];
|
||||||
'flow-plot', 'pressure-plot', 'mv02-plot', 'mv03-plot',
|
|
||||||
'mv04-05-plot', 'mv06-plot', 'mv07-plot', 'mv08-plot'
|
|
||||||
];
|
|
||||||
plotIds.forEach(id => {
|
plotIds.forEach(id => {
|
||||||
Plotly.relayout(id, { 'xaxis.range': range });
|
Plotly.relayout(id, { 'xaxis.range': range });
|
||||||
});
|
});
|
||||||
|
|
@ -181,7 +172,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function initPlots() {
|
function initPlots() {
|
||||||
const time0 = [time()];
|
const time0 = [new Date()]; // Use current time for initialization
|
||||||
Plotly.newPlot('flow-plot', [
|
Plotly.newPlot('flow-plot', [
|
||||||
{ x: time0, y: [0], name: 'Qperm', mode: 'lines', line: { color: 'blue' } },
|
{ x: time0, y: [0], name: 'Qperm', mode: 'lines', line: { color: 'blue' } },
|
||||||
{ x: time0, y: [0], name: 'Qdilute', mode: 'lines', line: { color: 'green' } },
|
{ x: time0, y: [0], name: 'Qdilute', mode: 'lines', line: { color: 'green' } },
|
||||||
|
|
@ -192,6 +183,7 @@
|
||||||
xaxis: { title: 'Time', type: 'date' },
|
xaxis: { title: 'Time', type: 'date' },
|
||||||
yaxis: { title: 'Flow (L/h)', range: [0, 2000] }
|
yaxis: { title: 'Flow (L/h)', range: [0, 2000] }
|
||||||
});
|
});
|
||||||
|
|
||||||
Plotly.newPlot('pressure-plot', [
|
Plotly.newPlot('pressure-plot', [
|
||||||
{ x: time0, y: [0], name: 'Pro', mode: 'lines', line: { color: 'purple' } },
|
{ x: time0, y: [0], name: 'Pro', mode: 'lines', line: { color: 'purple' } },
|
||||||
{ x: time0, y: [0], name: 'Pdilute', mode: 'lines', line: { color: 'teal' } },
|
{ x: time0, y: [0], name: 'Pdilute', mode: 'lines', line: { color: 'teal' } },
|
||||||
|
|
@ -201,37 +193,7 @@
|
||||||
xaxis: { title: 'Time', type: 'date' },
|
xaxis: { title: 'Time', type: 'date' },
|
||||||
yaxis: { title: 'Pressure (bar)', range: [0, 15] }
|
yaxis: { title: 'Pressure (bar)', range: [0, 15] }
|
||||||
});
|
});
|
||||||
// Plotly.newPlot('mv02-plot', [{
|
|
||||||
// x: time0, y: [0], name: 'MV02', mode: 'lines'
|
|
||||||
// }], {
|
|
||||||
// title: 'MV02 (%)', yaxis: { range: [0, 100] }, xaxis: { type: 'date' }
|
|
||||||
// });
|
|
||||||
// Plotly.newPlot('mv03-plot', [{
|
|
||||||
// x: time0, y: [0], name: 'MV03', mode: 'lines'
|
|
||||||
// }], {
|
|
||||||
// title: 'MV03 (%)', yaxis: { range: [0, 100] }, xaxis: { type: 'date' }
|
|
||||||
// });
|
|
||||||
// Plotly.newPlot('mv04-05-plot', [
|
|
||||||
// { x: time0, y: [0], name: 'MV04', mode: 'lines' },
|
|
||||||
// { x: time0, y: [0], name: 'MV05', mode: 'lines' }
|
|
||||||
// ], {
|
|
||||||
// title: 'MV04 + MV05 (%)', yaxis: { range: [0, 100] }, xaxis: { type: 'date' }
|
|
||||||
// });
|
|
||||||
// Plotly.newPlot('mv06-plot', [{
|
|
||||||
// x: time0, y: [0], name: 'MV06', mode: 'lines'
|
|
||||||
// }], {
|
|
||||||
// title: 'MV06 (%)', yaxis: { range: [0, 100] }, xaxis: { type: 'date' }
|
|
||||||
// });
|
|
||||||
// Plotly.newPlot('mv07-plot', [{
|
|
||||||
// x: time0, y: [0], name: 'MV07', mode: 'lines'
|
|
||||||
// }], {
|
|
||||||
// title: 'MV07 (%)', yaxis: { range: [0, 100] }, xaxis: { type: 'date' }
|
|
||||||
// });
|
|
||||||
// Plotly.newPlot('mv08-plot', [{
|
|
||||||
// x: time0, y: [0], name: 'MV08', mode: 'lines'
|
|
||||||
// }], {
|
|
||||||
// title: 'MV08 (%)', yaxis: { range: [0, 100] }, xaxis: { type: 'date' }
|
|
||||||
// });
|
|
||||||
setInterval(updatePlots, 250);
|
setInterval(updatePlots, 250);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user