Took 1 hour 17 minutes
This commit is contained in:
Tobias Hopp 2023-01-30 11:40:11 +01:00
parent 8f3e62f70e
commit 3e1d88a0e5
13 changed files with 92 additions and 41 deletions

View File

@ -28,4 +28,5 @@
- [ ] Bei Container erstellung kann optional "Arduino Proxy" angewählt werden
- Danach werden die Daten dieses Containers über den Arduino bezogen
- [ ] Behälter Menü neu designen
- [ ] In den ganzen messfn checken ob überhaupt eingestellt ist, den proxy zu nutzen
- [ ] In den ganzen messFn checken ob überhaupt eingestellt ist, den proxy zu nutzen
- [ ] Slot mit in Container senden nehmen

View File

@ -95,4 +95,4 @@
#setupContainers .setupContainer select {
margin-bottom: 2%;
}
}

View File

@ -37,7 +37,7 @@ export class ArduinoProxy {
return ele.manufacturer == "Arduino";
});
if (!arduino) {
return reject("No arduino found");
return reject("No arduino found. Is it plugged in?");
}
// @ts-ignore
@ -51,7 +51,7 @@ export class ArduinoProxy {
if (err) {
log("Error whilst connecting to proxy (open serial-connection)");
log(err.name + "\n" + err.message + "\n" + err.stack);
return reject(err.name);
return reject("Could not open serial connection to arduino");
}
// @ts-ignore

View File

@ -28,6 +28,7 @@ export class WebSocketHandler {
try {
if (this.ws && this.ws.readyState == 1) {
log("Sending " + payload.event);
await this.ws.send(payload.toString());
resolve();
}
@ -38,7 +39,8 @@ export class WebSocketHandler {
}
public static answerRequest(type: RequestType, content: any) {
WebSocketHandler.send(new WebSocketPayload(WebSocketEvent.RESPONSE, {type: type, content: content}));
WebSocketHandler.send(new WebSocketPayload(WebSocketEvent.RESPONSE, {type: type, data: content}));
log("Answered " + type + " request");
}

View File

@ -3,6 +3,7 @@ import debug from "debug";
import Ingredient from "./Ingredient";
import Drink from "./Drink";
import Container from "./Container";
import mongoose from "mongoose";
// create a namespace for logging
const log = debug("itender:server");
@ -13,6 +14,7 @@ export class Database {
return new Promise(async (resolve, reject) => {
try {
//connect to mongodb using mongoose
mongoose.set("strictQuery", false);
await Mongoose.connect("mongodb://127.0.0.1:27017/iTender?retryWrites=true");
log("Connected to Database");
// Preload the schema for Ingredient, Drink and Container

View File

@ -13,6 +13,7 @@ import {IJob} from "../../database/IJob";
import {SensorHelper} from "../../SensorHelper";
import {IContainer} from "../../database/IContainer";
import {Mixer} from "../../Mixer";
import {ArduinoProxy} from "../../ArduinoProxy";
const express = require('express');
const router = express.Router();
@ -168,32 +169,44 @@ router.ws('/', async (ws, req, next) => {
"ambient_color": string
}
await SensorHelper.clearAllRawMeasurements();
let content: { error: boolean, msg: string } = {
error: false,
msg: ""
let content: { success: boolean, msg: string } = {
success: true,
msg: "Prüfung erfolgreich."
};
// Check config
/// Check Proxy
if (Settings.get("arduino_proxy_enabled") == true) {
if (conf["arduino_proxy_enabled"]) {
try {
await ArduinoProxy.connect();
} catch (e) {
content.success = false;
content.msg = "Bei der Kommunikation mit dem Arduino Proxy ist ein Fehler aufgetreten.<br>Technische Details: " + e;
return WebSocketHandler.answerRequest(msg.data["type"] as RequestType, content);
}
}
// Check measurements
await SensorHelper.measureAllRaw();
try {
await SensorHelper.measureAllRaw();
} catch (e) {
content.success = false;
content.msg = e + "<br>Überprüfe die Einstellungen der Sensoren-Pins.";
return WebSocketHandler.answerRequest(msg.data["type"] as RequestType, content);
}
for (let c of await Container.find()) {
if (c.sensorType != SensorType.NONE && c.rawData == -1) {
content.error = true;
content.success = false;
content.msg = "Container " + (c.slot + 1) + " weist Fehler im Sensor auf.<br>Überprüfe die Einstellungen der Sensoren-Pins.";
return WebSocketHandler.answerRequest(msg.data["type"] as RequestType, content);
}
}
return WebSocketHandler.answerRequest(msg.data["type"] as RequestType, content);
break;
}
case RequestType.TARE: {
@ -208,6 +221,8 @@ router.ws('/', async (ws, req, next) => {
}
}
let timeouts: NodeJS.Timer[] = [];
async function measureAndSafe() {
try {
await SensorHelper.measureAllRaw();
@ -220,13 +235,15 @@ router.ws('/', async (ws, req, next) => {
// { success: boolean, msg: string }
WebSocketHandler.answerRequest(type, {success: false, msg: e});
success = false;
for (let t of timeouts)
clearTimeout(t);
}
}
setTimeout(measureAndSafe, 500);
setTimeout(measureAndSafe, 1000);
setTimeout(measureAndSafe, 2000);
setTimeout(measureAndSafe, 3000);
timeouts.push(setTimeout(measureAndSafe, 500));
timeouts.push(setTimeout(measureAndSafe, 1000));
timeouts.push(setTimeout(measureAndSafe, 2000));
timeouts.push(setTimeout(measureAndSafe, 3000));
setTimeout(async () => {
if (success) {

View File

@ -111,7 +111,7 @@ export class Containers {
WebWebSocketHandler.request(RequestType.CONTAINERS).then((payload) => {
for (let container of (payload.data["content"] as IContainer[])) {
for (let container of (payload.data as IContainer[])) {
containerVolumes[container._id] = container.volume;
let option = document.createElement("option");
option.value = container._id;
@ -119,10 +119,10 @@ export class Containers {
selectContainer.append(option);
containers[container._id] = container;
}
//containers = payload.data["content"] as IContainer[];
//containers = payload.data as IContainer[];
});
WebWebSocketHandler.request(RequestType.INGREDIENTS).then((payload) => {
for (let ingredient of (payload.data["content"] as IIngredient[])) {
for (let ingredient of (payload.data as IIngredient[])) {
let option = document.createElement("option");
option.value = ingredient._id;
option.innerText = ingredient.name;

View File

@ -64,7 +64,7 @@ export class Fill {
modal.open().then(() => {
WebWebSocketHandler.request(RequestType.JOB).then((payload) => {
let minus = 0;
let job = payload.data.content as IJob;
let job = payload.data as IJob;
ml.innerText = Math.floor((job.completeAmount / job.estimatedTime) * minus) + "ml";
waterAnimDiv.style.setProperty("--fillTime", job.estimatedTime + "s");
waterAnimDiv.style.backgroundImage = `url("/images/${job.drink._id}.png")`;

View File

@ -29,6 +29,22 @@ export class Setup {
const proxyCheckbox = document.getElementById("proxyCheckbox") as HTMLInputElement;
proxyCheckbox.checked = !!payload.data["arduino_proxy_enabled"];
this.usingProxy = proxyCheckbox.checked;
proxyCheckbox.onchange = () => {
this.usingProxy = proxyCheckbox.checked;
for (let checkbox of this.arduinoProxyCheckboxes) {
checkbox.disabled = !proxyCheckbox.checked;
if( !proxyCheckbox.checked )
{
checkbox.checked = false;
let event = new Event('change', {bubbles: true});
checkbox.dispatchEvent(event); // Trigger virtual onChange event
}
console.log(checkbox.disabled ? "Disabled" : "Enabled", checkbox);
}
}
ledCheckbox.checked = !!payload.data["led_enabled"];
allowRemoteCheckbox.checked = !!payload.data["remote_enabled"];
hotspotCheckbox.checked = !!payload.data["hotspot_enabled"];
@ -80,6 +96,7 @@ Dort werden die Behälter definiert, welche in den iTender gestellt werden.<br>D
const cancelBtn = document.getElementById("setup_cancelBtn") as HTMLButtonElement;
cancelBtn.onclick = () => {
let payload = new WebSocketPayload(WebSocketEvent.SETUP, false);
menuBtn.disabled = false;
WebWebSocketHandler.send(payload);
}
@ -147,8 +164,6 @@ Dort werden die Behälter definiert, welche in den iTender gestellt werden.<br>D
setupSaveBtn.disabled = true;
const ledCheckbox = document.getElementById("ledCheckbox") as HTMLInputElement;
const ledGPIO = document.getElementById("ledGPIO") as HTMLInputElement;
const ambientColor = document.getElementById("ambientColor") as HTMLInputElement;
@ -188,8 +203,8 @@ Dort werden die Behälter definiert, welche in den iTender gestellt werden.<br>D
// Check
let answer = await WebWebSocketHandler.request(RequestType.CHECK, newConf);
if( !(answer.data["success"] as boolean) )
{
if (!(answer.data as boolean)) {
ele.innerHTML = `Die Konfiguration weist Fehler auf!<br>${answer.data["msg"]}`;
await errorModal.open();
return;
@ -214,6 +229,7 @@ Dort werden die Behälter definiert, welche in den iTender gestellt werden.<br>D
setTimeout(() => {
saveModal.close();
this.startTare();
}, 1000);
@ -223,8 +239,6 @@ Dort werden die Behälter definiert, welche in den iTender gestellt werden.<br>D
});
menuBtn.disabled = false;
}
}
@ -236,6 +250,12 @@ Dort werden die Behälter definiert, welche in den iTender gestellt werden.<br>D
tareModal.addButton(ButtonType.PRIMARY, "Nein", () => {
tareModal.close();
// Needs to be after selectPin.append because noSel-Pin should always be at pos 0
let event = new Event('click', {bubbles: true});
let btn = document.getElementById("setup_cancelBtn");
if(btn )
btn.dispatchEvent(event);
});
let ul;
@ -275,6 +295,10 @@ Alle Sensoren wurden erfolgreich kalibriert.<br>`;
btn.onclick = () => {
modal.close();
clearInterval(tareInterval);
let event = new Event('click', {bubbles: true});
let btn = document.getElementById("setup_cancelBtn");
if(btn )
btn.dispatchEvent(event);
};
} else {
btn.innerText = "Erneut versuchen";
@ -321,19 +345,24 @@ Mindestens ein Sensor konnte nicht kalibriert werden.<br>${data.msg}<br>`;
// Proxy Label
let proxyLabel = document.createElement("label");
proxyLabel.innerText = "Pumpen Pin";
proxyLabel.innerText = "Arduino als Proxy";
proxyLabel.style.display = "block";
proxyLabel.style.marginBottom = "1%";
containerDiv.append(proxyLabel);
// Proxy checkbox
let proxyCheckbox = document.createElement("input");
proxyCheckbox.type = "checkbox";
proxyCheckbox.classList.add("input");
proxyCheckbox.style.marginLeft = "3%";
proxyCheckbox.checked = !!(Setup.usingProxy && container?.useProxy); // Auto Check
proxyCheckbox.disabled = !(Setup.usingProxy);
this.arduinoProxyCheckboxes.push(proxyCheckbox);
containerDiv.append(proxyCheckbox);
proxyLabel.append(proxyCheckbox);
containerDiv.append(document.createElement("br"));
// Pump Pin Selector
let pumpPinSelect;
@ -343,7 +372,7 @@ Mindestens ein Sensor konnte nicht kalibriert werden.<br>${data.msg}<br>`;
pumpPinSelect = selectPin.cloneNode(true);
pumpPinSelect.onchange = () => Setup.checkContainers();
pumpPinSelect.selectedIndex = 0;
containerDiv.append(pumpPinSelect);
pumpLabel.append(pumpPinSelect);
containerDiv.append(document.createElement("br"));
@ -369,7 +398,7 @@ Mindestens ein Sensor konnte nicht kalibriert werden.<br>${data.msg}<br>`;
sensorTypeScale.innerText = "Wägezelle";
sensorTypeScale.value = "1";
sensorType.append(sensorTypeScale);
containerDiv.append(sensorType);
sensorTypeLabel.append(sensorType);
containerDiv.append(document.createElement("br"));
@ -429,7 +458,7 @@ Mindestens ein Sensor konnte nicht kalibriert werden.<br>${data.msg}<br>`;
pumpPinSelect.append(noSel.cloneNode(true));
sensor1Select.append(noSel.cloneNode(true));
sensor2Select.append(noSel.cloneNode(true));
selectPin.selectedIndex = 0;
pumpPinSelect.selectedIndex = 0;
sensor1Select.selectedIndex = 0;
sensor2Select.selectedIndex = 0;
// Add pins
@ -483,7 +512,7 @@ Mindestens ein Sensor konnte nicht kalibriert werden.<br>${data.msg}<br>`;
let containerDiv = document.getElementById("setupContainers") as HTMLDivElement;
containerDiv.innerHTML = "";
let containers = payload.data["content"] as IContainer[];
let containers = payload.data as IContainer[];
for (let c of containers) {
Setup.addSetupContainer(c);
}

View File

@ -46,7 +46,7 @@ export class WebHandler {
drinkEle.onclick = () => {
WebWebSocketHandler.request(RequestType.STARTFILL, {drink: drink}).then((payload) => {
let data = payload.data.content as { success: boolean, job?: IJob };
let data = payload.data as { success: boolean, job?: IJob };
if (!data.success) {
let modal = new Modal("fill", "Oh nein!");

View File

@ -219,7 +219,7 @@ export class WebWebSocketHandler {
return new Promise(resolve => {
WebWebSocketHandler.registerForEvent(WebSocketEvent.RESPONSE, (payload) => {
if ((payload.data["type"] as RequestType) == type) {
resolve(payload);
resolve(payload.data);
}
});
WebWebSocketHandler.send(new WebSocketPayload(WebSocketEvent.REQUEST, {

View File

@ -77,19 +77,19 @@ function setupOnClickEvents() {
WebWebSocketHandler.request(RequestType.STATS).then((payload) => {
let li = document.createElement("li");
li.innerText = "Cocktails ausgegeben: " + payload.data["content"]["drinks_finished"];
li.innerText = "Cocktails ausgegeben: " + payload.data["drinks_finished"];
list.append(li);
li = document.createElement("li");
li.innerText = "Häufigster Cocktail: " + payload.data["content"]["drink_most"];
li.innerText = "Häufigster Cocktail: " + payload.data["drink_most"];
list.append(li);
li = document.createElement("li");
li.innerText = "Anzahl Ingredients: " + payload.data["content"]["count_ingredients"];
li.innerText = "Anzahl Ingredients: " + payload.data["count_ingredients"];
list.append(li);
li = document.createElement("li");
li.innerText = "Anzahl Cocktails: " + payload.data["content"]["count_cocktails"];
li.innerText = "Anzahl Cocktails: " + payload.data["count_cocktails"];
list.append(li);
});

View File

@ -22,7 +22,7 @@ block setup
label(onclick="document.getElementById('hotspotCheckbox').checked = !document.getElementById('hotspotCheckbox').checked;") Ohne WiFi Hotspot aktivieren
input#hotspotCheckbox.input(type="checkbox")
div.inputGroup
label(onclick="document.getElementById('proxyCheckbox').checked = !document.getElementById('proxyCheckbox').checked;") Arduino Mega als Proxy erlauben
label() Arduino Mega als Proxy erlauben
input#proxyCheckbox.input(type="checkbox")