Update measure and tare
Took 4 hours 19 minutes
This commit is contained in:
parent
c509fb2bf7
commit
9626cb43c9
@ -86,7 +86,6 @@ export class iTender {
|
|||||||
|
|
||||||
const job = new Job();
|
const job = new Job();
|
||||||
|
|
||||||
|
|
||||||
let amounts: { ingredient: IIngredient, amount: number, container?: IContainer }[] = [];
|
let amounts: { ingredient: IIngredient, amount: number, container?: IContainer }[] = [];
|
||||||
job.completeAmount = 0;
|
job.completeAmount = 0;
|
||||||
if (data.amounts) {
|
if (data.amounts) {
|
||||||
@ -227,6 +226,7 @@ export class iTender {
|
|||||||
clearInterval(iTender._jobCheckInterval);
|
clearInterval(iTender._jobCheckInterval);
|
||||||
job.endAt = new Date();
|
job.endAt = new Date();
|
||||||
job.successful = true;
|
job.successful = true;
|
||||||
|
|
||||||
await job.save();
|
await job.save();
|
||||||
mixLog("Job successful");
|
mixLog("Job successful");
|
||||||
setTimeout(() => iTender.setStatus(iTenderStatus.READY), 3000)
|
setTimeout(() => iTender.setStatus(iTenderStatus.READY), 3000)
|
||||||
@ -263,12 +263,13 @@ export class iTender {
|
|||||||
// ToDo
|
// ToDo
|
||||||
let container: IContainer = jobIngredient.container;
|
let container: IContainer = jobIngredient.container;
|
||||||
let deltaStartStop = (this._currentJob.endAt.getTime() - this._currentJob.startedAt.getTime()) / 1000;
|
let deltaStartStop = (this._currentJob.endAt.getTime() - this._currentJob.startedAt.getTime()) / 1000;
|
||||||
container.filled = container.filled - ( jobIngredient.amount * (deltaStartStop / ((jobIngredient.amount / 100) * iTender.secondsPer100ml)) ); // V2: Near the current fill value based on time values from delta start stop // todo fixme
|
|
||||||
|
// füllmenge - ( ( (stopp-start) / 1000 ) * ( sekunden100ml / 100 ) )
|
||||||
|
container.filled = container.filled - (deltaStartStop * (iTender.secondsPer100ml / 100)) // V2: Near the current fill value based on time values from delta start stop
|
||||||
container.save().then();
|
container.save().then();
|
||||||
}
|
}
|
||||||
|
|
||||||
iTender.setStatus(iTenderStatus.READY);
|
iTender.setStatus(iTenderStatus.READY);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -288,7 +289,15 @@ export class iTender {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// V2: New calculation method
|
// V2: New calculation method
|
||||||
c.filled = weight - c.sensorDelta; // V2: Testing
|
let newFilled = weight - c.sensorDelta;
|
||||||
|
|
||||||
|
if (newFilled <= 3 && c.filled != -1) {
|
||||||
|
c.filled = -1;
|
||||||
|
// Container is empty!
|
||||||
|
} else {
|
||||||
|
// Container > 2
|
||||||
|
c.filled = newFilled;
|
||||||
|
}
|
||||||
|
|
||||||
await c.save();
|
await c.save();
|
||||||
}
|
}
|
||||||
@ -386,10 +395,8 @@ export class iTender {
|
|||||||
c.save();
|
c.save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (let remote of serverIngredients) {
|
for (let remote of serverIngredients) {
|
||||||
let ingredient = await Ingredient.findById(remote._id);
|
let ingredient = await Ingredient.findById(remote._id);
|
||||||
if (!ingredient)
|
if (!ingredient)
|
||||||
@ -463,13 +470,21 @@ export class iTender {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static interval;
|
|
||||||
|
|
||||||
public static toggleTare(state: boolean) {
|
public static measureAllRaw() {
|
||||||
clearInterval(iTender.interval);
|
return new Promise<void>(async (resolve, reject) => {
|
||||||
if (state)
|
for (let c of (await Container.find({}))) {
|
||||||
this.interval = setInterval(async () => {
|
if (c.sensorType != SensorType.NONE) {
|
||||||
await this.measureContainers();
|
let weight = SensorHelper.measure(c);
|
||||||
}, 500);
|
if (weight == null) {
|
||||||
|
// Problem erkannt!
|
||||||
|
return reject("Fehler Sensor (" + c.sensorPin1 + ", " + c.sensorPin2 + ") - Container " + c.slot + 1);
|
||||||
|
}
|
||||||
|
c.rawData = weight;
|
||||||
|
await c.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resolve();
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -23,7 +23,6 @@ router.ws('/', async (ws, req, next) => {
|
|||||||
log("Incoming websocket connection...");
|
log("Incoming websocket connection...");
|
||||||
|
|
||||||
if (WebSocketHandler.ws) {
|
if (WebSocketHandler.ws) {
|
||||||
iTender.toggleTare(false);
|
|
||||||
WebSocketHandler.ws.close(1001);
|
WebSocketHandler.ws.close(1001);
|
||||||
}
|
}
|
||||||
WebSocketHandler.ws = ws;
|
WebSocketHandler.ws = ws;
|
||||||
@ -44,14 +43,6 @@ router.ws('/', async (ws, req, next) => {
|
|||||||
|
|
||||||
|
|
||||||
switch (msg.event) {
|
switch (msg.event) {
|
||||||
case WebSocketEvent.TARE: {
|
|
||||||
if (msg.data["state"] == true) {
|
|
||||||
iTender.toggleTare(true);
|
|
||||||
} else {
|
|
||||||
iTender.toggleTare(false);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case WebSocketEvent.CONTAINERS: {
|
case WebSocketEvent.CONTAINERS: {
|
||||||
let data = msg.data as { pumpPin: number; sensorType: SensorType; sensor1: number; sensor2: number; }[];
|
let data = msg.data as { pumpPin: number; sensorType: SensorType; sensor1: number; sensor2: number; }[];
|
||||||
await Container.deleteMany({}); // V2: Remove this and check every container based on id if changes occurs
|
await Container.deleteMany({}); // V2: Remove this and check every container based on id if changes occurs
|
||||||
@ -73,7 +64,7 @@ router.ws('/', async (ws, req, next) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case WebSocketEvent.CONTAINER_UPDATE: {
|
case WebSocketEvent.CONTAINER_UPDATE: {
|
||||||
let container : IContainer | null = await Container.findById(msg.data["container"]);
|
let container: IContainer | null = await Container.findById(msg.data["container"]);
|
||||||
if (!container) break;
|
if (!container) break;
|
||||||
|
|
||||||
let ingredient;
|
let ingredient;
|
||||||
@ -83,20 +74,16 @@ router.ws('/', async (ws, req, next) => {
|
|||||||
ingredient = undefined;
|
ingredient = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
let filled : number = parseInt(msg.data["filled"]);
|
let filled: number = parseInt(msg.data["filled"]);
|
||||||
|
|
||||||
container.filled = filled;
|
container.filled = filled;
|
||||||
container.volume = filled; // V2: Volume is now being updated after change of ingredient
|
container.volume = filled; // V2: Volume is now being updated after change of ingredient
|
||||||
|
|
||||||
if( container.sensorType != SensorType.NONE )
|
if (container.sensorType != SensorType.NONE) {
|
||||||
{
|
|
||||||
let raw = SensorHelper.measure(container);
|
let raw = SensorHelper.measure(container);
|
||||||
if( !raw )
|
if (!raw) {
|
||||||
{
|
await WebSocketHandler.send(new WebSocketPayload(WebSocketEvent.ERROR, "Der Sensor hat beim Austarieren einen ungültigen Wert zurückgegeben.<br>Dies weist auf eine Fehlkonfiguration oder kaputten Sensor hin.<br>Aus Sicherheitsgründen wurde der Sensor für diesen Behälter deaktiviert."));
|
||||||
await WebSocketHandler.send(new WebSocketPayload(WebSocketEvent.ERROR, "Der Sensor hat beim Austarieren einen ungültigen Wert zurückgegeben.<br>Dies weist auf eine Fehlkonfiguration oder kaputten Sensor hin.<br>Aus Sicherheitsgründen wurde der Sensor für diesen Behälter deaktiviert." ));
|
} else {
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
container.sensorDelta = raw - filled; // V2: Kalkuliere differenz zwischen Gewicht und gefülltem Inhalt // Todo Möglicherweise ist der "raw"-Wert nicht Gewicht
|
container.sensorDelta = raw - filled; // V2: Kalkuliere differenz zwischen Gewicht und gefülltem Inhalt // Todo Möglicherweise ist der "raw"-Wert nicht Gewicht
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -170,6 +157,51 @@ router.ws('/', async (ws, req, next) => {
|
|||||||
WebSocketHandler.answerRequest(msg.data["type"] as RequestType, "ok");
|
WebSocketHandler.answerRequest(msg.data["type"] as RequestType, "ok");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case RequestType.TARE: {
|
||||||
|
let type = msg.data["type"];
|
||||||
|
// Start TARE
|
||||||
|
let success = true;
|
||||||
|
|
||||||
|
for (let c of await Container.find({})) {
|
||||||
|
if (c.sensorType != SensorType.NONE) {
|
||||||
|
c.sensorTare = 0;
|
||||||
|
await c.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function measureAndSafe() {
|
||||||
|
try {
|
||||||
|
await iTender.measureAllRaw();
|
||||||
|
for (let c of await Container.find({})) {
|
||||||
|
if (c.sensorType != SensorType.NONE) {
|
||||||
|
c.sensorTare += c.rawData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// { success: boolean, msg: string }
|
||||||
|
WebSocketHandler.answerRequest(type, {success: false, msg: e});
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(measureAndSafe, 500);
|
||||||
|
setTimeout(measureAndSafe, 1000);
|
||||||
|
setTimeout(measureAndSafe, 2000);
|
||||||
|
setTimeout(measureAndSafe, 3000);
|
||||||
|
|
||||||
|
setTimeout(async () => {
|
||||||
|
if (success) {
|
||||||
|
for (let c of await Container.find({})) {
|
||||||
|
if (c.sensorType != SensorType.NONE) {
|
||||||
|
c.sensorTare = c.sensorTare / 4;
|
||||||
|
await c.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WebSocketHandler.answerRequest(type, {success: true, msg: "OK"});
|
||||||
|
}
|
||||||
|
}, 4000);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -44,9 +44,9 @@ export class Setup {
|
|||||||
<strong>LED-Modul</strong><br>
|
<strong>LED-Modul</strong><br>
|
||||||
In diesem Modul kann die Ambiente-Farbe sowie der LED-Streifen aktiviert werden.<br><br>
|
In diesem Modul kann die Ambiente-Farbe sowie der LED-Streifen aktiviert werden.<br><br>
|
||||||
<strong>Erweiterte Einstellungen</strong><br>
|
<strong>Erweiterte Einstellungen</strong><br>
|
||||||
Hier lässt sich konfigurieren, ob die Nutzung der Remote-Bedienung erlaubt ist, oder ein Hotspot aktiviert werden soll, falls keine WiFI-Verbindung vorliegt.<br><br>
|
Hier lässt sich konfigurieren, ob die Nutzung der Remote-Bedienung erlaubt ist, oder ein Hotspot aktiviert werden soll, falls keine WiFI-Verbindung vorliegt.<br>Außerdem lässt sich hier optional die Nutzung eines Arduino Mega als Proxy aktivieren. Pro Container kann dann der Proxy aktiviert werden, welcher anstatt dem Raspberry Pi die PINs steuert.<br><br>
|
||||||
<strong>Behälter-Modul</strong><br>
|
<strong>Behälter-Modul</strong><br>
|
||||||
Dort werden die Behälter definiert, welche in den iTender gestellt werden.<br>Dort müssen GPIO-Pins der Pumpe, etwaige Sensoren-Typen und Pins definiert werden.<br>Außerdem wird das Volumen eingestellt.<br><br>`;
|
Dort werden die Behälter definiert, welche in den iTender gestellt werden.<br>Dort müssen GPIO-Pins der Pumpe, etwaige Sensoren-Typen und Pins definiert werden.<br>Ggf. steht hier auch die Proxy-Option.<br><br>`;
|
||||||
btn.innerText = "Einrichtung starten";
|
btn.innerText = "Einrichtung starten";
|
||||||
btn.onclick = () => {
|
btn.onclick = () => {
|
||||||
modal.close();
|
modal.close();
|
||||||
@ -105,6 +105,12 @@ Dort werden die Behälter definiert, welche in den iTender gestellt werden.<br>D
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (selects[1].value == "0") {
|
||||||
|
ele.innerHTML += `Die Sensorart Ultraschall wird nicht mehr unterstützt.<br>Sollten Sie diesen Support wünschen wenden Sie sich an den Kundensupport.`;
|
||||||
|
errorModal.open();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (selects[1].value != "-1" && (selects[2].value == "-1" || selects[3].value == "-1")) {
|
if (selects[1].value != "-1" && (selects[2].value == "-1" || selects[3].value == "-1")) {
|
||||||
ele.innerHTML += `Wenn ein Sensor-Typ definiert ist, müssen alle Sensor-Pins gesetzt sein.`;
|
ele.innerHTML += `Wenn ein Sensor-Typ definiert ist, müssen alle Sensor-Pins gesetzt sein.`;
|
||||||
errorModal.open();
|
errorModal.open();
|
||||||
@ -137,6 +143,7 @@ Dort werden die Behälter definiert, welche in den iTender gestellt werden.<br>D
|
|||||||
const ambientColor = document.getElementById("ambientColor") as HTMLInputElement;
|
const ambientColor = document.getElementById("ambientColor") as HTMLInputElement;
|
||||||
const allowRemoteCheckbox = document.getElementById("allowRemoteCheckbox") as HTMLInputElement;
|
const allowRemoteCheckbox = document.getElementById("allowRemoteCheckbox") as HTMLInputElement;
|
||||||
const hotspotCheckbox = document.getElementById("hotspotCheckbox") as HTMLInputElement;
|
const hotspotCheckbox = document.getElementById("hotspotCheckbox") as HTMLInputElement;
|
||||||
|
const proxyCheckbox = document.getElementById("proxyCheckbox") as HTMLInputElement;
|
||||||
|
|
||||||
|
|
||||||
let cons: { pumpPin: number; sensorType: SensorType; sensor1: number; sensor2: number; volume: number; }[] = [];
|
let cons: { pumpPin: number; sensorType: SensorType; sensor1: number; sensor2: number; volume: number; }[] = [];
|
||||||
@ -166,6 +173,7 @@ Dort werden die Behälter definiert, welche in den iTender gestellt werden.<br>D
|
|||||||
"led_enabled": ledCheckbox.checked,
|
"led_enabled": ledCheckbox.checked,
|
||||||
"remote_enabled": allowRemoteCheckbox.checked,
|
"remote_enabled": allowRemoteCheckbox.checked,
|
||||||
"hotspot_enabled": hotspotCheckbox.checked,
|
"hotspot_enabled": hotspotCheckbox.checked,
|
||||||
|
"arduino_proxy_enabled": proxyCheckbox.checked,
|
||||||
"led_gpio": parseInt(ledGPIO.value),
|
"led_gpio": parseInt(ledGPIO.value),
|
||||||
"ambient_color": ambientColor.value
|
"ambient_color": ambientColor.value
|
||||||
});
|
});
|
||||||
@ -189,25 +197,24 @@ Dort werden die Behälter definiert, welche in den iTender gestellt werden.<br>D
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static startTare() {
|
public static startTare() {
|
||||||
let tareModal = new Modal("tare", "Einmessung Sensoren");
|
let tareModal = new Modal("tare", "Sensoren kalibrieren?");
|
||||||
let txt = document.createElement("p");
|
let txt = document.createElement("p");
|
||||||
txt.innerHTML = `Damit alle Sensoren korrekte Werte liefern, sollte eine Einmessung durchgeführt werden.<br>
|
txt.innerHTML = `Damit alle Sensoren korrekte Werte liefern sollte möglichst oft eine Kalibrierung vorgenommen werden.<br>Grundsätzlich muss diese beim Einrichten neuer Sensoren ausgeführt werden und kann danach übersprungen werden.<br><br>Soll das Kalibrieren aller Sensoren gestartet werden?<br>Dieser Vorgang nimmt circa eine Minute in Anspruch.<br><br>`;
|
||||||
Während der Einmessung müssen die Behälter einmal geleert und gefüllt werden.<br><br>`;
|
|
||||||
tareModal.addContent(txt);
|
tareModal.addContent(txt);
|
||||||
|
|
||||||
tareModal.addButton(ButtonType.PRIMARY, "Später", () => {
|
tareModal.addButton(ButtonType.PRIMARY, "Nein", () => {
|
||||||
tareModal.close();
|
tareModal.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
let ul;
|
let ul;
|
||||||
tareModal.addButton(ButtonType.PRIMARY, "Starten", async () => {
|
tareModal.addButton(ButtonType.PRIMARY, "Ja", async () => {
|
||||||
tareModal.close();
|
tareModal.close();
|
||||||
|
|
||||||
let modal = new Modal("tare", "Einmessung");
|
let modal = new Modal("tare", "Kalibrierung");
|
||||||
|
|
||||||
let txt = document.createElement("p");
|
let txt = document.createElement("p");
|
||||||
txt.innerHTML = `Messung Teil 1<br>
|
txt.innerHTML = `Kalibrierung<br>
|
||||||
Bitte den <strong>Inhalt der Behälter entfernen</strong><br>
|
Bitte den <strong>alle</strong> Behälter von den Sensoren entfernen.<br>
|
||||||
Die Gewichtssensoren werden beim Bestätigen austariert<br><br>Zum fortfahren Tarieren drücken.<br>`;
|
Die Gewichtssensoren werden beim Bestätigen austariert<br><br>Zum fortfahren Tarieren drücken.<br>`;
|
||||||
modal.addContent(txt);
|
modal.addContent(txt);
|
||||||
|
|
||||||
@ -221,40 +228,33 @@ Die Gewichtssensoren werden beim Bestätigen austariert<br><br>Zum fortfahren Ta
|
|||||||
btn.innerText = "Tarieren";
|
btn.innerText = "Tarieren";
|
||||||
btn.style.marginTop = "3%";
|
btn.style.marginTop = "3%";
|
||||||
btn.onclick = () => {
|
btn.onclick = () => {
|
||||||
let payload = new WebSocketPayload(WebSocketEvent.TARE, {tare: 0});
|
txt.innerHTML = `Kalibriere...<br>
|
||||||
WebWebSocketHandler.send(payload);
|
<strong>Bitte warten!</strong> - Keine Behälter oder sonstige Gegenstände auf die Sensoren stellen!<br>
|
||||||
|
Die Gewichtssensoren werden gerade austariert...<br>`;
|
||||||
|
btn.disabled = true;
|
||||||
|
btn.innerText = "Abschließen"
|
||||||
|
|
||||||
txt.innerHTML = `Messung Teil 2<br>
|
WebWebSocketHandler.request(RequestType.TARE, true).then((result) => {
|
||||||
Bitte nun alle <strong>Behälter mit Inhalt füllen</strong> und wieder einsetzen.<br>
|
let data: { success: boolean, msg: string } = result.data;
|
||||||
Die Gewichtssensoren werden beim Bestätigen austariert.<br><br>Zum fortfahren Tarieren drücken.<br>`;
|
btn.disabled = false;
|
||||||
btn.onclick = () => {
|
if (data.success) {
|
||||||
let payload = new WebSocketPayload(WebSocketEvent.TARE, {tare: 1});
|
txt.innerHTML = `Kalibrierung abgeschlossen!<br>
|
||||||
WebWebSocketHandler.send(payload);
|
Alle Sensoren wurden erfolgreich kalibriert.<br>`;
|
||||||
|
btn.onclick = () => {
|
||||||
btn.onclick = () => {
|
modal.close();
|
||||||
modal.close();
|
clearInterval(tareInterval);
|
||||||
clearInterval(tareInterval);
|
};
|
||||||
};
|
} else {
|
||||||
};
|
btn.innerText = "Erneut versuchen";
|
||||||
|
txt.innerHTML = `Kalibrierung fehlgeschlagen!<br>
|
||||||
|
Mindestens ein Sensor konnte nicht kalibriert werden.<br>${data.msg}<br>`;
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
modal.addContent(btn);
|
modal.addContent(btn);
|
||||||
await modal.open();
|
await modal.open();
|
||||||
|
|
||||||
tareInterval = setInterval(() => WebWebSocketHandler.request(RequestType.CONTAINERS).then((payload) => {
|
|
||||||
if (!ul) return;
|
|
||||||
|
|
||||||
ul.innerHTML = "";
|
|
||||||
let containers = payload.data as IContainer[];
|
|
||||||
for (let c of containers) {
|
|
||||||
if (c.sensorType == SensorType.NONE) continue;
|
|
||||||
|
|
||||||
let li = document.createElement("li");
|
|
||||||
li.innerText = `Behälter ${c.slot}: ${c.rawData.toFixed(3)} [${c.sensorType}]`;
|
|
||||||
ul.append(li);
|
|
||||||
}
|
|
||||||
}), 250);
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
tareModal.open();
|
tareModal.open();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user