first commit

This commit is contained in:
2025-05-23 08:04:13 +02:00
commit 488305c252
4 changed files with 1789 additions and 0 deletions

419
templates/dil5.html Normal file
View File

@ -0,0 +1,419 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pump Control</title>
<style>
body, html {
height: 100%;
margin: 0;
padding: 0;
background-color: lightgrey;
display: flex;
}
.svg-container {
flex: 2;
height: 100%;
position: relative;
display: flex;
}
#pump-svg {
width: 100%;
height: 100%;
display: block;
border-radius: 12px;
}
.control-panel {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
padding: 10px;
background-color: #B8EBE5;
border-radius: 12px;
}
.control-panel p {
font-size: 20px;
font-family:verdana;
}
.control-panel h {
font-size: 32px;
font-family:verdana;
}
.button-container {
display: flex;
flex-direction: rows;
gap: 10px;
margin-bottom: 20px;
font-size: 20px;
font-family:verdana;
}
.control-button {
padding: 10px;
background-color: #AFB0B1;
color: black;
border: none;
border-radius: 5px;
cursor: pointer;
width: 100px;
font-weight: bold;
}
.control-button:hover {
background-color: #DADBDC;
}
#outputtext {
width: 100%;
height: 200px;
resize: none;
border-radius: 12px;
}
.content-container {
display: flex;
flex-direction: row;
gap: 10px;
margin-bottom: 20px;
}
</style>
</head>
<body>
<div class="content-container">
<object id="pump-svg" type="image/svg+xml" data="/static/UI5.svg"></object>
<div class="control-panel">
<h1> DIL5 Control </h1>
<p> States </p>
<div class="button-container">
<button id = "test-btn" class="control-button" onclick="handleStateClick('TEST')">Test</button>
<button id = "condense-btn" class="control-button" onclick="handleStateClick('CONDENSE')">Condense</button>
<button id = "circulate-btn" class="control-button" onclick="handleStateClick('CIRCULATE')">Circulate</button>
<button id = "remove-btn" class="control-button" onclick="handleStateClick('REMOVE')">Remove</button>
<button id = "manual-btn" class="control-button" onclick="handleStateClick('MANUAL')">Manual</button>
</div>
<p> Status messages </p>
<textarea name="outputtext" id="outputtext" rows="10" cols="30" readonly></textarea>
</div>
</div>
</body>
<script>
var ctr_ids = ["MV9", "turbopumpfill", "MV10", "MV11", "MV12", "MV13", "MV8", "MVB", "MV2", "MV1", "MV3a", "MV3b", "GV1", "GV2", "MV14", "V1fill", "V2fill", "V9fill", "V5fill", "V4fill", "forepumpfill", "compressorfill"];
var ctr_mod = ["MV9", "turbopump", "MV10", "MV11", "MV12", "MV13", "MV8", "MVB", "MV2", "MV1", "MV3a", "MV3b", "GV1", "GV2", "MV14", "V1", "V2", "V9", "V5", "V4", "pump", "compressor"];
var ctr_state = new Array(ctr_mod.length).fill("init");
const svgElements = {};
let updateQueue = [];
var state_ids = ["Airpressure"];
var state_mod = ["Druckluft"];
var param_ids = ["P1txt", "P2txt", "P3txt", "P4txt", "P5txt", "speedtxt", "currenttxt"];
var param_unit = [" mbar", " mbar", " mbar", " mbar", " mbar", " Hz", " %"];
var param_mod = ["p1", "p2", "p3", "p4", "p5", "turbopumpspeed", "turbopumpcurrent"];
var controlpanelObject = document.getElementById("pump-svg");
let active_state = "MANUAL";
let pollTimer;
const POLL_INTERVAL = 500;
function handleStateClick(state) {
changeState("stateMachine", state);
document.getElementById(state.toLowerCase() + "-btn").style.backgroundColor = "white";
document.getElementById(active_state.toLowerCase() + "-btn").style.backgroundColor = "rgb(175, 176, 177)";
active_state = state;
}
function updateState(state) {
document.getElementById(state.toLowerCase() + "-btn").style.backgroundColor = "white";
document.getElementById(active_state.toLowerCase() + "-btn").style.backgroundColor = "rgb(175, 176, 177)";
active_state = state;
}
function changeControlledValve(mod, state) {
const index = ctr_mod.indexOf(mod);
if (index !== -1 && String(state) !== String(ctr_state[index])) {
ctr_state[index] = state;
const el = svgElements[ctr_ids[index]];
if (el) {
el.style.fill = state === "true" ? "#66ffbaff" :
state === "false" ? "#ff3067ff" : "#eaeaea";
}
}
}
function changeControlledValve(mod, state) {
index = ctr_mod.indexOf(mod)
if (index != -1) {
//if (String(state) !== String(ctr_state[index])){
ctr_state[index] = state;
if (state == "true"){
svgElements[ctr_ids[index]].style.fill = "#66ffbaff";
} else if (state == "false"){
svgElements[ctr_ids[index]].style.fill = "#ff3067ff";
} else {
svgElements[ctr_ids[index]].style.fill = "#eaeaea" ;
}
//}
}
}
function fillstateID(mod, state) {
const index = state_mod.indexOf(mod);
const element = svgDoc.querySelector("#" + state_ids[index]);
if (index !== -1 && element) {
element.style.fill = state === "true" ? "#66ffbaff" :
state === "false" ? "#ff3067ff" : "#eaeaea";
}
}
function editText(mod, text) {
const index = param_mod.indexOf(mod);
if (index !== -1) {
const textElement = svgDoc.querySelector("#" + param_ids[index]);
if (textElement) {
textElement.textContent = text + param_unit[index];
textElement.style.fill = "#d5d5d5";
}
}
}
function writeToScreen(message) {
const output = document.getElementById("outputtext");
output.value += message;
output.scrollTop = output.scrollHeight;
}
function doConnect() {
websocket = new WebSocket("ws://linse-dil5:8010/");
websocket.onopen = evt => onOpen(evt);
websocket.onclose = evt => onClose(evt);
websocket.onmessage = evt => updateQueue.push(evt.data);
websocket.onerror = evt => onError(evt);
}
function onOpen(evt) {
writeToScreen("Connected to DIL5\n");
//doSend("activate");
ctr_ids.forEach((id, index) => readTarget(ctr_mod[index]));
startPolling();
}
function changeTarget(mod, value) {
doSend(`change ${mod}:target ${value}`);
}
function changeState(mod, value) {
doSend(`change ${mod}:target "${value}"`);
//writeToScreen(`change ${mod}:target "${value}"\n`);
}
function readTarget(mod) {
doSend("read " + mod + ":target");
}
function onClose(evt) {
writeToScreen("disconnected\n");
stopPolling();
}
function onError(evt) {
if (evt.data === undefined) {
writeToScreen("Unable to connect to DIL5 as websocket is not connectable\n");
} else {
writeToScreen("error: " + evt.data + '\n');
stopPolling();
websocket.close();
}
}
function doSend(message) {
websocket.send(message);
}
function handleUpdate(msg) {
const teile = msg.split(":");
const mod = teile[0].split(" ")[1];
const param = teile[1].split(" ")[0];
const value = teile[1].split(",")[0].split('[')[1];
if (["status", "pollinterval"].includes(param)) return;
if (param === "value") {
if (param_mod.includes(mod)) {
editText(mod, value);
} else if (ctr_mod.includes(mod)) {
changeControlledValve(mod, value);
} else if (state_mod.includes(mod)) {
fillstateID(mod, value);
} else if (mod == "stateMachine"){
console.log("StateMaschine")
}
} else if (param === "_speed") {
editText("turbopumpspeed", value);
} else if (param === "_current") {
editText("turbopumpcurrent", value);
}
}
function handleChange(msg) {
const teile = msg.split(":");
const mod = teile[0].split(" ")[1];
const value = teile[1].split(",")[0].split('[')[1];
changeControlledValve(mod, value);
}
function handleReply(msg) {
const teile = msg.split(":");
const mod = teile[0].split(" ")[1];
const param = teile[1].split(" ")[0];
const value = teile[1].split(",")[0].split('[')[1];
if (param === "target") {
if (ctr_mod.includes(mod)) {
changeControlledValve(mod, value);
}
} else if (param === "value") {
if (param_mod.includes(mod)) {
editText(mod, value);
} else if (state_mod.includes(mod)) {
fillstateID(mod, value);
} else if (mod == "stateMachine"){
if (value == "5"){
if (active_state != "TEST"){
updateState("TEST")
}
} else if (value == "4"){
if (active_state != "MANUAL"){
updateState("MANUAL")
}
}
}
} else if (param === "_speed") {
editText("turbopumpspeed", value);
} else if (param === "_current") {
editText("turbopumpcurrent", value);
} else if (param === "stateMachine") {
console.log(msg)
updateState(value)
}
}
function handleMSG(msg) {
if (msg.startsWith("changed")) {
handleChange(msg);
} else if (msg.startsWith("update")) {
handleUpdate(msg);
} else if (msg.startsWith("reply")) {
handleReply(msg);
} else if (msg.startsWith("error_update")) {
writeToScreen("Error in update: " + msg + '\n');
}
}
function processUpdateQueue() {
if (updateQueue.length > 0) {
const queueCopy = updateQueue.slice();
updateQueue = [];
queueCopy.forEach(msg => handleMSG(msg));
}
requestAnimationFrame(processUpdateQueue);
}
function addClickListener(type, id, svgDoc) {
const element = svgDoc.querySelector("#" + id);
element.addEventListener('click', () => {
console.log("click");
const index = ctr_ids.indexOf(id);
const state = ctr_state[index];
if (state !== -1) {
const newState = state === "true" ? false : true;
changeTarget(ctr_mod[index], newState);
}
});
}
function loadSVG() {
svgDoc = controlpanelObject.contentDocument;
}
function startPolling() {
pollTimer = setInterval(() => {
pollAllStates();
}, POLL_INTERVAL);
}
function stopPolling() {
clearInterval(pollTimer);
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function pollAllStates() {
for (const mod of ctr_mod) {
doSend(`read ${mod}:target`);
await sleep(50);
}
await sleep(50);
doSend('read turbopump:_speed');
await sleep(50);
doSend('read turbopump:_current');
await sleep(50);
doSend('read stateMachine:value');
for (const mod of state_mod) {
doSend(`read ${mod}:value`);
await sleep(50);
}
for (const mod of param_mod) {
doSend(`read ${mod}:value`);
await sleep(50);
}
}
function pollSingle(mod) {
doSend(`read ${mod}:value`);
}
window.onload = function() {
loadSVG();
doConnect();
ctr_ids.forEach(id => {
addClickListener("controls", id, svgDoc);
svgElements[id] = svgDoc.querySelector("#" + id);
});
requestAnimationFrame(processUpdateQueue);
};
</script>
</body>
</html>