This commit is contained in:
2022-11-14 15:41:11 +01:00
parent 1380575845
commit a7fac21442
17 changed files with 236 additions and 63 deletions

33
src/WebSocketHandler.ts Normal file
View File

@ -0,0 +1,33 @@
import {WebSocketPayload} from "./WebSocketPayload";
export class WebSocketHandler {
private static _ws: WebSocket;
static get ws(): WebSocket {
return this._ws;
}
static set ws(value: WebSocket) {
this._ws = value;
}
public static send(payload: WebSocketPayload): Promise<void> {
return new Promise(async (resolve, reject) => {
try {
if( this.ws && this.ws.readyState == 1 )
{
await this.ws.send(payload.toString());
resolve();
}
else
{
reject("Websocket is not connected!");
}
} catch (e) {
reject(e);
}
});
}
}

View File

@ -45,8 +45,17 @@ export class WebSocketPayload {
return null;
}
let wsEvent = WebSocketEvent[<keyof typeof WebSocketEvent> rawPayload.event];
let wsEvent = WebSocketEvent[<keyof typeof WebSocketEvent>rawPayload.event];
return new WebSocketPayload(wsEvent, rawPayload.status, rawPayload.data);
}
/**
* Returns the payload as base64 encoded json string
*/
public toString(): string {
let json = JSON.stringify({"event": this._event, status: this._status, data: this._data});
json = (window) ? btoa(json) : Buffer.from(json).toString("base64");
return json;
}
}

View File

@ -1,26 +0,0 @@
import {IContainer} from "./IContainer";
import {IIngredient} from "./IIngredient";
import {HCSR04} from "hc-sr04";
export abstract class AbstractContainer implements IContainer {
slot: number = 1;
content: IIngredient | undefined;
sensorEcho: number = 26;
sensorFilledMax: number = 0;
sensorFilledMin: number = 0;
sensorTrigger: number = 27;
volume: number = 1000;
sensor: HCSR04;
protected constructor() {
this.sensor = new HCSR04(this.sensorTrigger, this.sensorEcho);
}
public measure() : Number {
let dist = this.sensor.distance();
return dist * 100 / (this.sensorFilledMax + this.sensorFilledMin);
}
}

View File

@ -1,17 +1,18 @@
import * as Mongoose from "mongoose";
import {AbstractContainer} from "./AbstractContainer";
import mongoose from "mongoose";
import {IContainer} from "./IContainer";
export const ContainerSchema = new Mongoose.Schema<AbstractContainer>({
export const ContainerSchema = new Mongoose.Schema<IContainer>({
slot: {type: Number},
volume: {type: Number, required: true, default: 1000},
sensorEcho: Number,
sensorTrigger: Number,
content: {type: String},
content: {type: mongoose.Types.ObjectId},
sensorFilledMax: Number,
sensorFilledMin: Number
sensorFilledMin: Number,
filled: Number,
});
const Container = mongoose.model<AbstractContainer>('Container', ContainerSchema);
const Container = mongoose.model<IContainer>('Container', ContainerSchema);
export default Container;

View File

@ -4,7 +4,8 @@ import * as mongoose from "mongoose";
export const DrinkSchema = new mongoose.Schema<IDrink>({
name: {type: String, required: true},
ingredients: [{type: {type: mongoose.Types.ObjectId, ref: "Ingredient", required: true}, amount: { type: Number } }],
category: String
category: String,
recommendedQuantity: {type: Number, default: 200 }
});
const Drink = mongoose.model<IDrink>('Drink', DrinkSchema);

View File

@ -1,7 +1,7 @@
import {IIngredient} from "./IIngredient";
import * as mongoose from "mongoose";
export interface IContainer {
export interface IContainer extends mongoose.Document{
slot: number;
content: IIngredient|undefined;
volume: number;
@ -9,4 +9,5 @@ export interface IContainer {
sensorFilledMax: number;
sensorTrigger: number;
sensorEcho: number;
filled: Number;
}

View File

@ -12,4 +12,7 @@ export interface IDrink extends mongoose.Document {
// Category of the drink
category: Category;
// Recommended amount in milliliters
recommendedQuantity: number;
}

View File

@ -1,10 +1,15 @@
import {iTenderStatus} from "./iTenderStatus";
import {AbstractContainer} from "./database/AbstractContainer";
import Container from "./database/Container";
import {HCSR04} from "hc-sr04";
import {IContainer} from "./database/IContainer";
import Drink from "./database/Drink";
import {IDrink} from "./database/IDrink";
export class iTender {
private static _status: iTenderStatus;
private static containers: AbstractContainer[];
private static containers: { container: IContainer, sensor: HCSR04, pump: null }[];
private static drinks: IDrink[];
static set status(value: iTenderStatus) {
this._status = value;
@ -22,15 +27,65 @@ export class iTender {
// todo Stop fill method
}
static measureContainers() {
for( let container of this.containers )
{
container.measure();
}
static measureContainers(): Promise<void> {
return new Promise(async resolve => {
let containers = await Container.find();
/*
public measure() : Number {
let dist = this.sensor.distance();
return dist * 100 / (this.sensorFilledMax + this.sensorFilledMin);
}
*/
})
}
static loadContainers() {
static refreshDrinks(): Promise<void> {
return new Promise(async resolve => {
this.drinks = [];
for (let d of (await Drink.find().populate("ingredients.type"))) {
let drinkAccept = true;
for (let i of d.ingredients) {
let c = await Container.findOne({content: i["type"]});
if (!c) {
drinkAccept = false;
break;
}
}
if (drinkAccept)
this.drinks.push(d);
}
});
}
static refreshContainers(): Promise<void> {
return new Promise(async resolve => {
let containers = await Container.find();
for (let c of containers) {
let i = 0;
let found = false;
for (let c2 of this.containers) {
if (c2.container._id == c._id) {
this.containers[i] = {
container: c,
sensor: new HCSR04(c.sensorTrigger, c.sensorEcho),
pump: null
};
found = true;
break;
}
i++;
}
if (!found)
this.containers.push({container: c, sensor: new HCSR04(c.sensorTrigger, c.sensorEcho), pump: null});
}
})
}
}

View File

@ -1,7 +1,14 @@
export enum iTenderStatus {
// Machine is going to start
STARTING,
// Machine is ready
READY,
// Machine is filling your drink and destroying your leberwurst
FILLING,
// Drinks will be refreshed from global database (the internet neuland :O)
REFRESHING,
// Drinks will be calculated (check containers and which drinks can be done)
CALCULATING,
// An error happened; Oh no :(
ERROR
}

View File

@ -4,7 +4,8 @@ import {WebsocketApp} from "./WebsocketApp";
import {Database} from "./database/Database";
import Drink from "./database/Drink";
import Ingredient from "./database/Ingredient";
import {Category} from "./Category";
import Container from "./database/Container";
import {iTender} from "./iTender";
const log = debug("itender:server");
@ -12,31 +13,64 @@ const app = new App();
const wsApp = new WebsocketApp();
(async( ) => {
(async () => {
try {
log("Starting...");
await Database.connect();
await app.listen();
await wsApp.listen();
await test();
} catch( e )
{
await init();
} catch (e) {
console.error("---- ERROR ----")
console.error(e);
process.exit(-1);
}
})();
function init() : Promise<void> {
log("Initializing...");
return new Promise(async resolve => {
await iTender.refreshContainers();
await iTender.refreshDrinks();
resolve();
});
}
async function test() {
console.log("Testing fn");
let ingredient = await Ingredient.findOne({name: "Cola"});
if (!ingredient)
return;
/*let drink = new Drink();
drink.name = "Cola";
drink.ingredients = [{type: ingredient, amount: 200}];
await drink.save();*/
let drink = await Drink.findOne({name: "Cola"}).populate("ingredients.type");
if (!drink) return;
console.log(drink);
/*let container = new Container();
container.slot = 1;
container.volume = 750;
container.sensorEcho = 26;
container.sensorTrigger = 27;
container.content = ingredient;
container.sensorFilledMax = 2;
container.sensorFilledMin = 15;
await container.save();*/
let container = await Container.findOne({slot: 1});
if (!container) return;
console.log(container);
let drink = await Drink.findOne( { name: "Mezzo Mix" } ).populate("ingredients.type");
if(!drink)return;
console.log(drink.ingredients);
//console.log(drink.ingredients)
/*let ingredient = new Ingredient();
ingredient.name = "Cola";

View File

@ -1,10 +1,10 @@
import {WebSocketPayload} from "../../WebSocketPayload";
import debug from "debug";
import {WebSocketHandler} from "../../WebSocketHandler";
const express = require('express');
const router = express.Router();
let currentWS: WebSocket;
const log = debug("itender:websocket");
@ -24,9 +24,9 @@ router.ws('/', (ws, req, next) => {
});
ws.on('open', (listener) => {
if (currentWS)
currentWS.close(1001);
currentWS = ws;
if (WebSocketHandler.ws)
WebSocketHandler.ws.close(1001);
WebSocketHandler.ws = ws;
});
});

View File

@ -1,6 +1,6 @@
import {Modal} from "./Modal";
export class WebSocketHandler {
export class WebWebSocketHandler {
private socket : WebSocket;
constructor() {

View File

@ -1,4 +1,4 @@
import {WebSocketHandler} from "./WebSocketHandler";
import {WebWebSocketHandler} from "./WebWebSocketHandler";
import {Modal} from "./Modal";
const main = document.getElementById("main");
@ -54,6 +54,6 @@ function load()
let wsHandler;
function connect()
{
wsHandler = new WebSocketHandler();
wsHandler = new WebWebSocketHandler();
}