Adds Qperm setpoint

This commit is contained in:
Etienne Chassaing 2025-08-18 10:30:41 +02:00
parent 4ee303f854
commit 9dabcc81d0
4 changed files with 43 additions and 21 deletions

View File

@ -302,7 +302,7 @@ class CANBackend:
} }
return state_map.get(state_val, f"UNKNOWN({state_val})") return state_map.get(state_val, f"UNKNOWN({state_val})")
def send_state_command(self, state: str, pu_number: int, ploop_setpoint: float): def send_state_command(self, state: str, pu_number: int, ploop_setpoint: float, qperm_setpoint : float): # TODO : use qperm_setpoint
""" """
Send the PU state and pressure loop setpoint to the master node. Send the PU state and pressure loop setpoint to the master node.

29
main.py
View File

@ -55,8 +55,6 @@ latest_data: Dict[str, Any] = {
active_PUs: list[int] = [] active_PUs: list[int] = []
DEFAULT_FEED_VALVE = 0.0
# RECORDER # RECORDER
recording_flag = False recording_flag = False
recording_task = None recording_task = None
@ -100,7 +98,7 @@ def format_PU_data(data):
"MV07_sp": np.round(data.get("MV07_sp", 0.0), 1), "MV07_sp": np.round(data.get("MV07_sp", 0.0), 1),
"MV08": np.round(data.get("MV08", 0.0), 1), "MV08": np.round(data.get("MV08", 0.0), 1),
"MV08_sp": np.round(data.get("MV08_sp", 0.0), 1), "MV08_sp": np.round(data.get("MV08_sp", 0.0), 1),
"Qdrain_sp" : np.round(data.get("Qdrain_sp", 0.0), 1), "Qdrain_sp" : 60*np.round(data.get("Qdrain_sp", 0.0), 2),
} }
def format_DS_data(data): def format_DS_data(data):
@ -240,8 +238,7 @@ def is_connected():
# PU CONTROL # 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(...), qperm_setpoint: float = Query(...)):
global DEFAULT_FEED_VALVE
VALID_STATES = { VALID_STATES = {
"IDLE", "IDLE",
"PRE-PRODUCTION", "PRE-PRODUCTION",
@ -259,6 +256,8 @@ def send_command(state: str, pu_number: int, ploop_setpoint: float = Query(...))
logging.info(f"Sending state '{state}' to PU {pu_number}") logging.info(f"Sending state '{state}' to PU {pu_number}")
pu_number = [pu_number] if pu_number !=3 else [1,2] # Temporary way of starting two pus
print("pu_number", pu_number)
if state == "IDLE": if state == "IDLE":
set_patient_skid_users(0) set_patient_skid_users(0)
url = f"http://192.168.1.28:8000/stop_test" url = f"http://192.168.1.28:8000/stop_test"
@ -270,15 +269,17 @@ def send_command(state: str, pu_number: int, ploop_setpoint: float = Query(...))
logging.info(f"Closing valves on Patient Skid: {response.status_code}") logging.info(f"Closing valves on Patient Skid: {response.status_code}")
try: try:
can_backend.send_state_command(state, pu_number, ploop_setpoint) for pu in pu_number:
current_state = can_backend.read_current_state(pu_number) can_backend.send_state_command(state, pu, ploop_setpoint, qperm_setpoint)
return { current_state = can_backend.read_current_state(pu)
"status": "success", return {
"command": state, "status": "success",
"pu": pu_number, "command": state,
"ploop_setpoint": ploop_setpoint, "pu": pu,
"current_state": current_state, "ploop_setpoint": ploop_setpoint,
} "qperm_setpoint": qperm_setpoint,
"current_state": current_state,
}
except Exception as e: except Exception as e:
raise HTTPException(status_code=500, detail=str(e)) raise HTTPException(status_code=500, detail=str(e))

View File

@ -271,21 +271,21 @@
<div class="pu-buttons"> <div class="pu-buttons">
<button onclick="sendCommand('IDLE', 1, this)" data-action="IDLE" data-pu="1"><i class="fas fa-power-off"></i> IDLE PU 1</button> <button onclick="sendCommand('IDLE', 1, this)" data-action="IDLE" data-pu="1"><i class="fas fa-power-off"></i> IDLE PU 1</button>
<button onclick="sendCommand('IDLE', 2, this)" data-action="IDLE" data-pu="2"><i class="fas fa-power-off"></i> IDLE PU 2</button> <button onclick="sendCommand('IDLE', 2, this)" data-action="IDLE" data-pu="2"><i class="fas fa-power-off"></i> IDLE PU 2</button>
<button onclick="sendCommand('IDLE', 3, this)" data-action="IDLE" data-pu="3"><i class="fas fa-power-off"></i> IDLE PU 3</button> <button onclick="sendCommand('IDLE', 3, this)" data-action="IDLE" data-pu="3"><i class="fas fa-power-off"></i> IDLE BOTH</button>
</div> </div>
</div> </div>
<div class="mode-block"> <div class="mode-block">
<div class="pu-buttons"> <div class="pu-buttons">
<button onclick="sendCommand('PRE-PRODUCTION', 1, this)" data-action="PRE-PRODUCTION" data-pu="1"><i class="fas fa-play"></i> PRE-PROD PU 1</button> <button onclick="sendCommand('PRE-PRODUCTION', 1, this)" data-action="PRE-PRODUCTION" data-pu="1"><i class="fas fa-play"></i> PRE-PROD PU 1</button>
<button onclick="sendCommand('PRE-PRODUCTION', 2, this)" data-action="PRE-PRODUCTION" data-pu="2"><i class="fas fa-play"></i> PRE-PROD PU 2</button> <button onclick="sendCommand('PRE-PRODUCTION', 2, this)" data-action="PRE-PRODUCTION" data-pu="2"><i class="fas fa-play"></i> PRE-PROD PU 2</button>
<button onclick="sendCommand('PRE-PRODUCTION', 3, this)" data-action="PRE-PRODUCTION" data-pu="3"><i class="fas fa-play"></i> PRE-PROD PU 3</button> <button onclick="sendCommand('PRE-PRODUCTION', 3, this)" data-action="PRE-PRODUCTION" data-pu="3"><i class="fas fa-play"></i> PRE-PROD BOTH</button>
</div> </div>
</div> </div>
<div class="mode-block"> <div class="mode-block">
<div class="pu-buttons"> <div class="pu-buttons">
<button onclick="sendCommand('FIRST_START', 1, this)" data-action="FIRST_START" data-pu="1"><i class="fas fa-power-off"></i> FIRST START PU 1</button> <button onclick="sendCommand('FIRST_START', 1, this)" data-action="FIRST_START" data-pu="1"><i class="fas fa-power-off"></i> FIRST START PU 1</button>
<button onclick="sendCommand('FIRST_START', 2, this)" data-action="FIRST_START" data-pu="2"><i class="fas fa-power-off"></i> FIRST START PU 2</button> <button onclick="sendCommand('FIRST_START', 2, this)" data-action="FIRST_START" data-pu="2"><i class="fas fa-power-off"></i> FIRST START PU 2</button>
<button onclick="sendCommand('FIRST_START', 3, this)" data-action="FIRST_START" data-pu="3"><i class="fas fa-power-off"></i> FIRST START PU 3</button> <button onclick="sendCommand('FIRST_START', 3, this)" data-action="FIRST_START" data-pu="3"><i class="fas fa-power-off"></i> FIRST START BOTH</button>
</div> </div>
</div> </div>
<div class="slider-container"> <div class="slider-container">
@ -297,6 +297,20 @@
</div> </div>
<input type="range" min="0.5" max="3.5" step="0.1" value="2.5" id="ploopSetpoint" class="slider" oninput="updatePloopSetpoint(this.value)"> <input type="range" min="0.5" max="3.5" step="0.1" value="2.5" id="ploopSetpoint" class="slider" oninput="updatePloopSetpoint(this.value)">
</div> </div>
<div class="slider-container">
<label for="qpermSetpoint">Qperm Setpoint (L/h):</label>
<div class="slider-values">
<span id="qpermMin">1200</span>
<span id="qpermCurrent">1200</span>
<span id="qpermMax">1600</span>
</div>
<input type="range" min="1200" max="1600" step="100" value="1200"
id="qpermSetpoint" class="slider"
oninput="updateQpermSetpoint(this.value)">
</div>
<div class="mode-block"> <div class="mode-block">
<button onclick="sendCommand('ThermalLoopCleaning', 0, this)"><i class="fas fa-fire"></i> Thermal Loop Cleaning</button> <button onclick="sendCommand('ThermalLoopCleaning', 0, this)"><i class="fas fa-fire"></i> Thermal Loop Cleaning</button>
</div> </div>
@ -363,6 +377,11 @@
document.getElementById('currentValue').textContent = value; document.getElementById('currentValue').textContent = value;
} }
function updateQpermSetpoint(value) {
document.getElementById('qpermCurrent').textContent = value;
}
async function getConnectionStatus() { async function getConnectionStatus() {
const response = await fetch('/is_connected', { method: 'GET' }); const response = await fetch('/is_connected', { method: 'GET' });
const data = await response.json(); const data = await response.json();
@ -404,7 +423,9 @@
async function sendCommand(state, puNumber, buttonEl) { async function sendCommand(state, puNumber, buttonEl) {
const ploopSetpoint = document.getElementById('ploopSetpoint').value; const ploopSetpoint = document.getElementById('ploopSetpoint').value;
await fetch(`/command/${state}/pu/${puNumber}?ploop_setpoint=${ploopSetpoint}`, { method: 'POST' }); const qpermSetpoint = document.getElementById('qpermSetpoint').value;
await fetch(`/command/${state}/pu/${puNumber}?ploop_setpoint=${ploopSetpoint}&qperm_setpoint=${qpermSetpoint}`, { method: 'POST' });
document.querySelectorAll('button').forEach(btn => { document.querySelectorAll('button').forEach(btn => {
btn.classList.remove('in-progress', 'ready', 'production'); btn.classList.remove('in-progress', 'ready', 'production');
}); });
@ -554,7 +575,7 @@
console.error('Element with selector "#Qconso .monitor-value" not found.'); console.error('Element with selector "#Qconso .monitor-value" not found.');
} }
} }
} catch (error) { } catch (error) {
console.error('Error fetching monitor data:', error); console.error('Error fetching monitor data:', error);
} }

View File

@ -4,7 +4,7 @@
PI_USER="hmi" PI_USER="hmi"
PI_HOST="192.168.1.46" PI_HOST="192.168.1.46"
REMOTE_FOLDER="/home/hmi/Desktop/HMI/recordings" REMOTE_FOLDER="/home/hmi/Desktop/HMI/recordings"
LOCAL_FOLDER="/Users/Etienne/GitHub/NorthStar-HMI" LOCAL_FOLDER="/Users/Etienne/Library/CloudStorage/OneDrive-nehemis/nehemis - 04 Records/HMI_data"
echo "Starting folder download from Raspberry Pi" echo "Starting folder download from Raspberry Pi"