add and close #12

Took 1 hour 46 minutes
This commit is contained in:
Tobias Hopp 2023-02-02 14:28:09 +01:00
parent a021d25332
commit 937f825e82
13 changed files with 135 additions and 89 deletions

View File

@ -1,6 +1,6 @@
{
"name": "itender",
"version": "1.0.2",
"version": "2.2.8",
"private": true,
"author": "Tobias Hopp <tobi@gaminggeneration.de>",
"license": "UNLICENSED",

View File

@ -63,12 +63,12 @@
.modalBlendIn {
animation: modalBlendIn 0.5s forwards;
animation: modalBlendIn 0.4s forwards;
}
.modalBlendOut {
animation: modalBlendOut 0.8s forwards;
animation: modalBlendOut 0.4s forwards;
}

View File

@ -30,10 +30,10 @@ export class Settings {
}
public static saveSettings() {
fs.writeFileSync(path.join(__dirname, "../config.json"), JSON.stringify(this._json));
fs.writeFileSync(path.join(__dirname, "../config.json"), JSON.stringify(this._json, null, 1));
}
public static get(key: string): any {
public static get(key: "setupDone"|"secondsPer100ml"|"arduino_proxy_enabled"|"led_enabled"|"remote_enabled"|"hotspot_enabled"|"led_gpio"|"ambient_color"): any {
return this._json[key];
}

View File

@ -33,7 +33,7 @@ export class iTender {
* How many seconds it takes to fill 100ml
* @private
*/
static secondsPer100ml: number = 35.3335;
static secondsPer100ml: number = 19.3335; // 35.3335
/**
* Sensitivity-Factor of the hx711 scales

View File

@ -10,6 +10,7 @@ import Drink from "./database/Drink";
import {MyGPIO} from "./MyGPIO";
import {ContainerHelper} from "./ContainerHelper";
import {Mixer} from "./Mixer";
import {ArduinoProxy} from "./ArduinoProxy";
const log = debug("itender:server");
@ -20,11 +21,25 @@ const wsApp = new WebsocketApp();
(async () => {
try {
log("Starting...");
Settings.loadSettings();
await Database.connect();
if( Settings.get("arduino_proxy_enabled") as boolean )
{
try {
await ArduinoProxy.connect();
} catch( e )
{
Settings.set("arduino_proxy_enabled",false);
Settings.setupDone = false;
log("Force iTender to setup, because proxy not connected!");
}
}
//await test();
await app.listen();
await wsApp.listen();
Settings.loadSettings();
iTender.setStatus(iTenderStatus.STARTING);
await Utils.sleep(2000);

View File

@ -77,6 +77,17 @@ router.ws('/', async (ws, req, next) => {
await container.save();
i++;
}
let containers : IContainer[] = await Container.find();
for( let c of containers )
{
let find = data.find( (e) => {
return c._id == e.id;
} );
if( !find )
await Container.deleteOne({_id: c._id });
}
break;
}
@ -211,7 +222,7 @@ router.ws('/', async (ws, req, next) => {
} catch (e) {
log("Checkup failed");
content.success = false;
content.msg = "Bei der Kommunikation mit dem Arduino Proxy ist ein Fehler aufgetreten.<br>Technische Details: " + e;
content.msg = "Bei der Kommunikation mit dem Arduino Proxy ist ein Fehler aufgetreten.<br><br><em>Technische Details: " + e + "</em>";
return WebSocketHandler.answerRequest(msg.data["type"] as RequestType, content);
}
}
@ -288,13 +299,20 @@ router.ws('/', async (ws, req, next) => {
}
case RequestType.UPDATE: {
/*
- git pull
- yarn install
- yarn run compile
- (arduino update?)
- reboot
*/
if( !iTender.internetConnection )
return WebSocketHandler.answerRequest(msg.data["type"] as RequestType, false);
WebSocketHandler.answerRequest(msg.data["type"] as RequestType, true);
try {
let result = await exec("/home/itender/itender/update.sh");
if( result.stderr )
await WebSocketHandler.send(new WebSocketPayload(WebSocketEvent.ERROR, "Der iTender konnte das Update nicht installieren.<br>Möglicherweise ist die Internetverbindung nicht ausreichend oder das Update enthält Fehler.<br>"));
} catch( e )
{
await WebSocketHandler.send(new WebSocketPayload(WebSocketEvent.ERROR, "Der iTender konnte das Update nicht installieren.<br>Möglicherweise ist die Internetverbindung nicht ausreichend oder das Update enthält Fehler.<br>"));
}
break;
}
@ -321,7 +339,9 @@ router.ws('/', async (ws, req, next) => {
"ip": ipAddr,
"network": wifi.substring(wifi.indexOf('"')+1,wifi.length-2),
"uptime": (await exec("uptime -p")).stdout.substring(3),
"version": packageJson.version
"version": packageJson.version,
"author": "Tobias Hopp",
"contact": "tobi@gaminggeneration.de"
}
return WebSocketHandler.answerRequest(msg.data["type"] as RequestType, data);

View File

@ -82,7 +82,7 @@ export class Containers {
let selectIngredient = document.createElement("select");
selectIngredient.classList.add("hidden");
selectIngredient.classList.add("input");
selectIngredient.style.width = "50%"
selectIngredient.style.width = "35%"
// When ingredient is changed
selectIngredient.onchange = () => {
@ -189,6 +189,7 @@ export class Containers {
selectContainer.dispatchEvent(event);
selectIngredient.dispatchEvent(event);
});
modal.close();
};
modal.open();

View File

@ -177,7 +177,7 @@ export class Modal {
modalContent.classList.remove("modalBlendOut");
modal.classList.remove("modalBlendOut");
this.modalInClose = false;
}, 800);
}, 402);
this.currentModalId = undefined;
}

View File

@ -13,6 +13,9 @@ export class Settings {
const reload = document.getElementById("settings_reload") as HTMLButtonElement;
reload.onclick = () => window.location.reload();
const update = document.getElementById("settings_update") as HTMLButtonElement;
update.onclick = () => this.update();
}
private static onClickRefreshDrinks() {
@ -41,21 +44,17 @@ export class Settings {
th.append(tdTh1, tdTh2);
let x = [["internet","Internet-Konnektivität"], ["ip","IP-Adresse"], ["network","WiFi-Netzwerk"], ["uptime","Gerät aktiv seit"], ["version", "Version"]];
for( let y of x )
{
let x = [["internet", "Internet-Konnektivität"], ["ip", "IP-Adresse"], ["network", "WiFi-Netzwerk"], ["uptime", "Gerät aktiv seit"], ["version", "Version"], ["author", "Entwickler"], ["contact", "Support-Adresse"]];
for (let y of x) {
let tr = document.createElement("tr");
let td1 = document.createElement("td");
let td2 = document.createElement("td");
td1.innerText = y[1];
td1.style.fontWeight = "bold";
if( payload.data[y[0]] === true || payload.data[y[0]] === false )
{
if (payload.data[y[0]] === true || payload.data[y[0]] === false) {
td2.innerText = payload.data[y[0]] == true ? "Verbunden" : "Getrennt";
}
else
{
} else {
td2.innerText = payload.data[y[0]];
}
@ -70,4 +69,23 @@ export class Settings {
modal.open();
});
}
private static update() {
WebWebSocketHandler.request(RequestType.UPDATE, null).then((payload) => {
let modal = new Modal("info", "System-Update");
let txt = document.createElement("p");
if (payload.data as boolean) {
txt.innerHTML = `Der iTender wird nun aktualisiert!<br><br>
Sobald das Update installiert ist, wird das System neu gestartet.<br>Die dadurch hergehende Verbindungswarnung kann ignoriert werden.<br>Der iTender stellt die Verbindung automatisch wieder her.<br><br><span style="color:red;font-weight: bold">Schalten Sie das System nicht aus und entfernen Sie nicht das Netzkabel!</span>`;
modal.addContent(txt);
modal.loader = true;
} else {
txt.innerHTML = `Das System kann nicht aktualisiert werden.<br>iTender hat keine Internet-Konnektivität fest gestellt.<br>Versuchen Sie es zu einem späteren Zeitpunkt erneut.`;
modal.addButton(ButtonType.PRIMARY, "Schließen", () => modal.close());
}
modal.open();
});
}
}

View File

@ -199,9 +199,9 @@ Dort werden die Behälter definiert, welche in den iTender gestellt werden.<br>D
// Check
let answer = await WebWebSocketHandler.request(RequestType.CHECK, newConf);
console.log(answer);
if (!(answer.data["success"] as boolean)) {
ele.innerHTML = `Die Konfiguration weist Fehler auf!<br>${answer.data["msg"]}`;
ele.innerHTML = `Die Überprüfung schlug fehl!<br>${answer.data["msg"]}`;
await errorModal.open();
return;
}
@ -552,8 +552,11 @@ Mindestens ein Sensor konnte nicht kalibriert werden.<br>${data.msg}<br>`;
setTimeout(() => {
c.classList.remove("error");
c2.classList.remove("error");
setTimeout( () => {
sel.classList.remove("error");
sel2.classList.remove("error");
}, 1500 );
}, 2200);
returner = false;
}

View File

@ -42,8 +42,7 @@ document.addEventListener("DOMContentLoaded", async () => {
let container: IContainer;
let bottomContainers = document.getElementById("menuContainers") as HTMLDivElement;
bottomContainers.innerHTML = "";
for( container of payload.data )
{
for (container of payload.data) {
let containerDiv = document.createElement("div") as HTMLDivElement;
containerDiv.classList.add("container");
@ -59,9 +58,9 @@ document.addEventListener("DOMContentLoaded", async () => {
if (pcnt < 5)
containerDiv.style.backgroundColor = "red";
else if (pcnt < 15)
containerDiv.style.backgroundColor = "#ef4f00";
containerDiv.style.backgroundColor = "#EF4F00";
else if (pcnt < 30)
containerDiv.style.backgroundColor = "#ff5400";
containerDiv.style.backgroundColor = "#FF5400";
containerDiv.append(span);
@ -75,18 +74,6 @@ function setupOnClickEvents() {
const menuBtn = document.getElementById("menuBtn") as HTMLButtonElement;
menuBtn.disabled = true;
let timer = 0;
function mouseDown() {
timer = Date.now();
}
function mouseUp() {
if( ( Date.now() - timer ) / 1000 > 5 )
window.location.reload();
}
menuBtn.onmousedown = mouseDown;
menuBtn.ontouchstart = mouseDown;
menuBtn.onmouseup = mouseUp;
menuBtn.ontouchend = mouseUp;
function doMenu() {
if (WebHandler.currentPane != Pane.MENU) {
@ -107,43 +94,43 @@ function setupOnClickEvents() {
menuStatsBtn.onclick = async () => {
let statsModal = new Modal("stats", "Statistiken");
let modal = new Modal("stats", "Statistiken");
let txt = document.createElement("p");
txt.innerHTML = `Folgende Statistiken wurden erfasst.`;
statsModal.addContent(txt);
let table = document.createElement("table");
table.style.marginLeft = "auto";
table.style.marginRight = "auto";
let div = document.createElement("div");
div.style.textAlign = "left";
statsModal.addContent(div);
let th = document.createElement("th");
table.append(th);
let list = document.createElement("ul");
div.append(list);
let tdTh1 = document.createElement("td");
tdTh1.innerText = "";
let tdTh2 = document.createElement("td");
tdTh2.innerText = "";
statsModal.addContent(document.createElement("br"));
statsModal.addButton(ButtonType.PRIMARY, "Schließen", () => statsModal.close());
th.append(tdTh1, tdTh2);
WebWebSocketHandler.request(RequestType.STATS).then((payload) => {
let li = document.createElement("li");
console.log(payload);
li.innerText = "Cocktails ausgegeben: " + payload.data["drinks_finished"];
list.append(li);
let x = [["drinks_finished", "Ausgegebene Cocktails"], ["drink_most", "Beliebtester Cocktail"], ["count_cocktails", "Anzahl an Cocktails"], ["count_ingredients", "Anzahl an Zutaten"]];
for (let y of x) {
let tr = document.createElement("tr");
let td1 = document.createElement("td");
let td2 = document.createElement("td");
li = document.createElement("li");
li.innerText = "Häufigster Cocktail: " + payload.data["drink_most"];
list.append(li);
td1.innerText = y[1];
td1.style.fontWeight = "bold";
td2.innerText = payload.data[y[0]];
tr.append(td1, td2);
li = document.createElement("li");
li.innerText = "Anzahl Ingredients: " + payload.data["count_ingredients"];
list.append(li);
li = document.createElement("li");
li.innerText = "Anzahl Cocktails: " + payload.data["count_cocktails"];
list.append(li);
table.append(tr);
}
modal.addContent(table);
modal.addContent(document.createElement("br"));
modal.addButton(ButtonType.PRIMARY, "Schließen", () => modal.close());
modal.open();
});
await statsModal.open();
};
const menuSettingsBtn = document.getElementById("menu_settings") as HTMLButtonElement;
@ -159,8 +146,6 @@ function setupOnClickEvents() {
Settings.addListeners();
}
let wsHandler;

View File

@ -1,5 +1,7 @@
#!/bin/bash
cd /home/itender/itender || exit -1
git pull "https://tobiash:!IwedwrimmVeudiweN!@git.gaminggeneration.de/tobiash/itender.git" --quiet
yarn
yarn run compile
sudo systemctl restart itender
exit 0

View File

@ -11,7 +11,7 @@ block setup
input#ledGPIO.input(type="number" value="40" style="width:15%" disabled="disabled")
div.inputGroup
label Ambiente Farbe
input#ambientColor.input(type="color" value="#05445E" style="width:15%" disabled="disabled")
input#ambientColor.input(type="color" value="#05445E" style="width:15%")
div#setupExtraDiv
h1 Erweiterte Einstellungen
@ -54,11 +54,13 @@ block menu
block settings
// Settings
button.btn.btn-primary#settings_refreshDrinks Getränke herunterladen
button.btn.btn-primary#settings_update System aktualisieren
button.btn.btn-primary#settings_getInfo Systeminformationen
button.btn.btn-primary#settings_refreshDrinks Getränke aktualisieren
button.btn.btn-primary#settings_deleteDrinks(disabled="disabled") Getränke-DB löschen
button.btn.btn-primary#settings_reload Oberfläche neu starten
button.btn.btn-primary#settings_getInfo Systeminformationen
button.btn.btn-primary#settings_update System aktualisieren
button.btn.btn-primary#settings_restart(disabled="disabled") iTender neu starten
button.btn.btn-primary#settings_shutdown(disabled="disabled") iTender herunterfahren
block main