diff --git a/doc/Notes.md b/doc/Notes.md
index e38f294..10a0cd8 100644
--- a/doc/Notes.md
+++ b/doc/Notes.md
@@ -26,14 +26,49 @@ Was haben wir bereits am iTender Projekt gemacht?
#### Neues 3D-Modell
-Folgt.
+
+
+
-## Umsetzung
-
-#### Webseiten-Skizzen
-
+## Das Programm
+#### Aufbau
+- Das Programm ist aufgebaut in eine Client-Seite und eine Server-Seite
+- Diese sind zur Sicherheit des Geräts voneinander getrennt
+- Server und Client kommunizieren über einen WebSocket, welchen man sich als eine Art Chat-Kanal vorstellen kann
+- Client und Server haben bestimmte Status, ein Status ist beispielsweise READY oder FILLING
+- Die Oberfläche ist sowohl über das Display, aber auch über ein Tablet steuerbar
+- Oberfläche sendet Befehle an den Server → Server verarbeitet und gibt ggfs. eine Antwort
+
+#### Fotos des Webinterfaces (Stand 21.11)
+
+Main
+
+Die Main Pane ist der Hauptteil und direkt die Einstiegsseite des iTenders
+Hier können Getränke ausgewählt werden, welche dann "gemacht" werden
+
+
+Menu
+Das Menü ist das Navigationsherz, von hier aus können alle anderen Panels erreicht werden
+
+
+Containers
+Hier können die Behälter inhalte aktualisiert werden
+Man wählt die "Zutat" aus und danach wie voll der Behälter nun ist
+In der Regel kann das auch automatisch eingemessen werden, wenn alle Sensoren eingestellt sind
+
Trotzdem sollte das hier eingestellt werden
+
+
+Fill
+Einfach ein "Popup" welches anzeigt dass das Getränk gefüllt wird
+
+
+Setup
+Das Setup ist das erste menü was nach dem ersten einrichten erscheint
+es dient zur Grundkonfiguration
+
+
diff --git a/doc/Screenshot_Model1.2_Back.png b/doc/Screenshot_Model1.2_Back.png
new file mode 100644
index 0000000..474a7c3
Binary files /dev/null and b/doc/Screenshot_Model1.2_Back.png differ
diff --git a/doc/Screenshot_Model1.2_Front.png b/doc/Screenshot_Model1.2_Front.png
new file mode 100644
index 0000000..b172f31
Binary files /dev/null and b/doc/Screenshot_Model1.2_Front.png differ
diff --git a/doc/autostart.config b/doc/autostart.config
new file mode 100644
index 0000000..a89b477
--- /dev/null
+++ b/doc/autostart.config
@@ -0,0 +1,33 @@
+#
+# These things are run when an Openbox X Session is started.
+# You may place a similar script in $HOME/.config/openbox/autostart
+# to run user-specific things.
+#
+
+# If you want to use GNOME config tools...
+#
+#if test -x /usr/lib/aarch64-linux-gnu/gnome-settings-daemon >/dev/null; then
+# /usr/lib/aarch64-linux-gnu/gnome-settings-daemon &
+#elif which gnome-settings-daemon >/dev/null 2>&1; then
+# gnome-settings-daemon &
+#fi
+
+# If you want to use XFCE config tools...
+#
+#xfce-mcs-manager &
+
+xset s off
+xset s noblank
+xset -dpms
+
+setxkbmap -option terminate:ctrl_alt_bksp
+
+# Start Chromium in kiosk mode
+sed -i 's/"exited_cleanly":false/"exited_cleanly":true/' ~/.config/chromium/'Local State'
+sed -i 's/"exited_cleanly":false/"exited_cleanly":true/; s/"exit_type":"[^"]\+"/"exit_type":"Normal"/' ~/.config/chromium/Default/Preferences
+
+/usr/bin/chromium-browser --disable-infobars --kiosk --incognito --disable-pinch --overscroll-history-navigation=0 http://192.168.1.186:3000/
+
+
+
+
diff --git a/doc/installPi.sh b/doc/installPi.sh
new file mode 100644
index 0000000..ffeda76
--- /dev/null
+++ b/doc/installPi.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+apt update
+apt install
+
+apt install --no-install-recommends xserver-xorg x11-xserver-utils xinit openbox -y
+apt purge nodejs npm -y
+curl -fsSL https://deb.nodesource.com/setup_19.x | sudo bash -
+apt install -y nodejs
+apt install gcc g++ make -y
+curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | sudo tee /usr/share/keyrings/yarnkey.gpg >/dev/null
+echo "deb [signed-by=/usr/share/keyrings/yarnkey.gpg] https://dl.yarnpkg.com/debian stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
+apt update
+apt install yarn git cmake make chromium-browser unclutter -y
+apt upgrade -y
+echo "allowed_users=anybody" >/etc/X11/Xwrapper.config
+cp autostart.config /etc/xdg/openbox/autostart
+
+reboot now
diff --git a/doc/start.sh b/doc/start.sh
new file mode 100644
index 0000000..e0c0f49
--- /dev/null
+++ b/doc/start.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+/usr/bin/startx /usr/bin/chromium-browser --kiosk --incognito --disable-pinch --overscroll-history-navigation=0 http://192.168.1.186:3000/
\ No newline at end of file
diff --git a/doc/v1Containers.png b/doc/v1Containers.png
new file mode 100644
index 0000000..e5b01af
Binary files /dev/null and b/doc/v1Containers.png differ
diff --git a/doc/v1Fill.png b/doc/v1Fill.png
new file mode 100644
index 0000000..a020c88
Binary files /dev/null and b/doc/v1Fill.png differ
diff --git a/doc/v1Main.png b/doc/v1Main.png
new file mode 100644
index 0000000..cc6ac5e
Binary files /dev/null and b/doc/v1Main.png differ
diff --git a/doc/v1Menu.png b/doc/v1Menu.png
new file mode 100644
index 0000000..67682a0
Binary files /dev/null and b/doc/v1Menu.png differ
diff --git a/doc/v1Setup.png b/doc/v1Setup.png
new file mode 100644
index 0000000..f77b6e0
Binary files /dev/null and b/doc/v1Setup.png differ
diff --git a/doc/v1Stats.png b/doc/v1Stats.png
new file mode 100644
index 0000000..be90735
Binary files /dev/null and b/doc/v1Stats.png differ
diff --git a/public/images/waza_6918742036110288.gif b/public/images/Making_Drink.gif
similarity index 100%
rename from public/images/waza_6918742036110288.gif
rename to public/images/Making_Drink.gif
diff --git a/public/stylesheets/inputs.css b/public/stylesheets/inputs.css
index 69e86f0..1aa0ce3 100644
--- a/public/stylesheets/inputs.css
+++ b/public/stylesheets/inputs.css
@@ -6,7 +6,8 @@
border-radius: 2px;
cursor: none !important;
font-weight: 500;
- margin-right: 2%;
+ margin-right: 1%;
+ margin-left: 1%;
transition: 0.2s all;
}
diff --git a/public/stylesheets/main.css b/public/stylesheets/main.css
index 6e27e47..74fa2ca 100644
--- a/public/stylesheets/main.css
+++ b/public/stylesheets/main.css
@@ -23,7 +23,7 @@
grid-row-gap: 4%;
text-align: center;
border-radius: 30px 10px 30px;
- color: black;
+ color: white;
/*box-shadow: 3px 3px 3px;*/
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.3), 0 6px 20px 0 rgba(0, 0, 0, 0.29);
transition: 0.4s;
@@ -55,4 +55,78 @@
grid-column: span 1;
grid-row: span 1;
font-size: 150%;
+}
+
+
+
+
+/* Water animation */
+body {
+ margin: 50px;
+}
+
+.water {
+ position: relative;
+ width: 130px;
+ height: 150px;
+ background-color: #23417B;
+ box-shadow: inset 0 0 80px #18566D;
+ clip-path: polygon(0 0, 100% 0, 85% 100%, 15% 100%);
+
+ background-repeat: no-repeat;
+ background-position: center;
+ background-size: auto 83%;
+ margin: auto auto 3%;
+}
+
+.water::before {
+ content: "";
+ width: 200%;
+ height: 200%;
+ background-color: #ececec;
+ position: absolute;
+ top: -90%;
+ left: -50%;
+ border-radius: 40%;
+ animation: animWater 10s linear infinite, animFillIn 15s linear forwards;
+}
+
+.water::after {
+ content: "";
+ width: 204%;
+ height: 204%;
+ background-color: #ececec80;
+ position: absolute;
+ top: -90%;
+ left: -52%;
+ border-radius: 40%;
+ animation: animWater 10s linear infinite, animFillIn 15s linear forwards;
+ animation-delay: 0.4s;
+}
+
+.waterCancel {
+ background-color: red;
+ transition: background-color 1s;
+}
+
+@keyframes animFillIn {
+ 0% {
+ top: -90%;
+ }
+ 100% {
+ top: -190%;
+ }
+}
+
+@keyframes animWater {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+
+#main_fillTxt {
+ margin-bottom: 3%;
}
\ No newline at end of file
diff --git a/public/stylesheets/menu.css b/public/stylesheets/menu.css
index 3cffcbf..1329218 100644
--- a/public/stylesheets/menu.css
+++ b/public/stylesheets/menu.css
@@ -1,9 +1,8 @@
#menu {
padding-left: 5%;
- padding-right: 5%;
padding-top: 10%;
display: grid;
- grid-template-columns: repeat(2, calc(100% / 2));
+ grid-template-columns: repeat(2, calc(95% / 2));
grid-template-rows: repeat(2, calc(95% / 2));
grid-gap: 2% 2%;
color: white;
diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css
index 1c08446..bcb24b7 100644
--- a/public/stylesheets/style.css
+++ b/public/stylesheets/style.css
@@ -12,15 +12,23 @@
/*cursor: none !important;*/
}
+
ul {
list-style: circle;
}
+
html * {
/*cursor: none !important*/
-webkit-user-select: none; /* Safari */
-ms-user-select: none; /* IE 10 and IE 11 */
user-select: none; /* Standard syntax */
+ cursor: none;
+}
+
+
+html *::-webkit-scrollbar {
+ display: none;
}
@@ -39,6 +47,7 @@ body {
user-select: none; /* Standard syntax */
}
+
h1 {
font-size: 1.74em;
font-weight: 500;
@@ -63,7 +72,9 @@ h1 {
font-size: 2em;
padding-right: 3px;
padding-left: 3px;
- background-color: #167fcc;
+ background-color: #167FCC;
+ box-shadow: inset 11px 45px 50px 3px rgba(181, 15, 15, 0.66);
+
}
@@ -102,14 +113,15 @@ h1 {
left: 0;
right: 0;
height: 9%;
- background-color: #167fcc;
+ background-color: #167FCC;
+ box-shadow: inset 11px -45px 50px 3px rgba(223, 12, 42, 0.66);
}
#overlay #bottom #menuBtn {
height: 100%;
width: 10%;
- background-color: #21212d;
+ background-color: #21212D;
padding: 1px;
font-size: 1.5em;
border: 0;
@@ -117,13 +129,17 @@ h1 {
color: white;
float: left;
transition: all 0.4s;
+ margin-left: 0;
}
+
+
#menuBtn:hover {
background-color: #313147 !important;
}
+
#menuBtn:disabled {
- background-color: #777 !important;
+ background-color: #777777 !important;
color: #C1C1C1 !important;
}
@@ -143,9 +159,10 @@ h1 {
right: 0;
height: 82%;
color: white;
- background-color: #0e1f31;
+ background-color: #0E1F31;
}
+
.pane {
height: 100%;
padding: 1% 2%;
@@ -155,9 +172,15 @@ h1 {
scroll-behavior: smooth;
color: white;
/*animation: showPane 0.3s forwards;*/
-
+ -ms-overflow-style: none; /* IE and Edge */
}
+
+.pane::-webkit-scrollbar {
+ display: none;
+}
+
+
@keyframes showPane {
0% {
display: none;
@@ -171,11 +194,14 @@ h1 {
}
}
+
.hiddenPane {
transition: 0.4s;
display: none !important;
/*animation: hidePane 0.4s forwards;*/
}
+
+
@keyframes hidePane {
0% {
opacity: 1;
@@ -190,6 +216,7 @@ h1 {
}
}
+
#settings {
display: none;
background-color: red;
diff --git a/src/RequestType.ts b/src/RequestType.ts
index fe959a6..151d7e7 100644
--- a/src/RequestType.ts
+++ b/src/RequestType.ts
@@ -2,4 +2,5 @@ export enum RequestType {
CONTAINERS = "CONTAINERS",
INGREDIENTS = "INGREDIENTS",
STATS = "STATS",
+ JOB = "JOB",
}
\ No newline at end of file
diff --git a/src/WebSocketEvent.ts b/src/WebSocketEvent.ts
index 03bbe46..502dc66 100644
--- a/src/WebSocketEvent.ts
+++ b/src/WebSocketEvent.ts
@@ -7,5 +7,7 @@ export enum WebSocketEvent {
TARE = "TARE",
SETUP = "SETUP",
REQUEST = "REQUEST",
- RESPONSE = "RESPONSE"
+ RESPONSE = "RESPONSE",
+ FILL = "FILL",
+ CANCEL = "CANCEL"
}
\ No newline at end of file
diff --git a/src/routes/ws/websocketRoute.ts b/src/routes/ws/websocketRoute.ts
index 8b88620..8d9e92c 100644
--- a/src/routes/ws/websocketRoute.ts
+++ b/src/routes/ws/websocketRoute.ts
@@ -43,6 +43,11 @@ router.ws('/', async (ws, req, next) => {
log(msg);
switch (msg.event) {
+ case WebSocketEvent.FILL : {
+ iTender.setStatus(iTenderStatus.FILLING);
+ break;
+ }
+
case WebSocketEvent.TARE: {
if (msg.data["state"] == true) {
iTender.toggleTare(true);
diff --git a/src/web/WebHandler.ts b/src/web/WebHandler.ts
index 692efd0..9ed8446 100644
--- a/src/web/WebHandler.ts
+++ b/src/web/WebHandler.ts
@@ -2,6 +2,9 @@ import {WebSocketPayload} from "../WebSocketPayload";
import {IDrink} from "../database/IDrink";
import {Pane} from "./Pane";
import {Setup} from "./Setup";
+import {Modal} from "./Modal";
+import {WebSocketEvent} from "../WebSocketEvent";
+import {WebWebSocketHandler} from "./WebWebSocketHandler";
export class WebHandler {
static get currentPane(): Pane {
@@ -38,6 +41,13 @@ export class WebHandler {
drinkImg.src = "/images/" + drink.name + ".png";
drinkName.innerText = drink.name;
+
+
+ drinkEle.onclick = () => {
+ let payload = new WebSocketPayload(WebSocketEvent.FILL, false, {drink: drink._id });
+ WebWebSocketHandler.send(payload);
+ }
+
/*
let ingredients = "";
for (let i of drink.ingredients) {
diff --git a/src/web/WebWebSocketHandler.ts b/src/web/WebWebSocketHandler.ts
index c1c32b8..6c1b108 100644
--- a/src/web/WebWebSocketHandler.ts
+++ b/src/web/WebWebSocketHandler.ts
@@ -7,6 +7,7 @@ import {WebHandler} from "./WebHandler";
import {Setup} from "./Setup";
import {Pane} from "./Pane";
import {RequestType} from "../RequestType";
+import {IDrink} from "../database/IDrink";
export class WebWebSocketHandler {
private static socket: WebSocket;
@@ -61,8 +62,8 @@ export class WebWebSocketHandler {
switch (status) {
case iTenderStatus.READY: {
Modal.close("start");
- Modal.close("refreshing");
Modal.close("setup");
+ Modal.close("fill");
WebHandler.openPane(Pane.MAIN);
(document.getElementById("menuBtn") as HTMLButtonElement).disabled = false;
break;
@@ -88,7 +89,52 @@ export class WebWebSocketHandler {
case iTenderStatus.SETUP: {
Modal.close("start");
Setup.openSetup();
+ break;
}
+ case iTenderStatus.FILLING: {
+
+ let modal = new Modal("fill", "Getränk wird ausgegeben");
+ let header = document.createElement("h2");
+ header.innerText = "";
+
+ modal.addContent(header);
+
+ let txt = document.createElement("p");
+ txt.innerHTML = `Dein Cocktail wird gerade zubereitet`;
+ txt.id = "main_fillTxt";
+
+ let waterAnimDiv = document.createElement("div");
+ waterAnimDiv.classList.add("water");
+ modal.addContent(txt);
+
+ modal.addContent(waterAnimDiv);
+
+ let cancelBtn = document.createElement("button");
+ cancelBtn.classList.add("btn", "btn-danger");
+ cancelBtn.innerText = "Abbrechen";
+ cancelBtn.disabled = true;
+ setTimeout(() => {
+ cancelBtn.disabled = false;
+ }, 1000);
+ cancelBtn.onclick = () => {
+ cancelBtn.disabled = true;
+ txt.innerHTML = "Der Vorgang wird abgebrochen...";
+ waterAnimDiv.classList.add("waterCancel");
+
+ WebWebSocketHandler.send(new WebSocketPayload(WebSocketEvent.CANCEL));
+ };
+ modal.addContent(cancelBtn);
+
+ WebWebSocketHandler.request(RequestType.JOB).then((payload) => {
+ let drink = payload.data as IDrink;
+ waterAnimDiv.style.backgroundImage = "/images/" + drink.name + ".png";
+ header.innerText = drink.name;
+ });
+
+ modal.open();
+ break;
+ }
+
}
break;
}