Update many stuff, see toDo
Took 9 seconds
This commit is contained in:
93
src/ArduinoProxy.ts
Normal file
93
src/ArduinoProxy.ts
Normal file
@ -0,0 +1,93 @@
|
||||
import SerialPort from "serialport";
|
||||
import debug from "debug";
|
||||
import {ArduinoProxyPayload} from "./ArduinoProxyPayload";
|
||||
import {Utils} from "./Utils";
|
||||
import {ReadlineParser} from "@serialport/parser-readline";
|
||||
|
||||
const log = debug("itender:arduinoProxy");
|
||||
|
||||
export class ArduinoProxy {
|
||||
|
||||
private static serialPort;
|
||||
private static callbacks: Record<string, { resolve: Function, reject: Function }> = {};
|
||||
private static encoding: string = "utf-8";
|
||||
|
||||
private static onData(data) {
|
||||
data = data.toString().trim();
|
||||
try {
|
||||
let json = JSON.parse(data) as ArduinoProxyPayload;
|
||||
if (this.callbacks[json.id]) {
|
||||
this.callbacks[json.id].resolve(json);
|
||||
delete this.callbacks[json.id];
|
||||
log("Answered request " + json.id);
|
||||
} else {
|
||||
log("ERROR - Got an response from arduino but we are not waiting for it?");
|
||||
}
|
||||
} catch (e) {
|
||||
log("ERROR - Got an invalid response from arduino?");
|
||||
}
|
||||
}
|
||||
|
||||
public static connect() {
|
||||
return new Promise<void>(async (resolve, reject) => {
|
||||
// @ts-ignore
|
||||
let list = await SerialPort.list()
|
||||
|
||||
let arduino = list.find((ele) => {
|
||||
return ele.manufacturer == "Arduino";
|
||||
});
|
||||
if (!arduino) {
|
||||
return reject("No arduino found");
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
this.serialPort = new SerialPort({
|
||||
path: arduino.path,
|
||||
baudRate: 9600,
|
||||
autoOpen: false,
|
||||
});
|
||||
|
||||
this.serialPort.open((err: Error | null | undefined) => {
|
||||
if (err) {
|
||||
log("Error whilst connecting to proxy (open serial-connection)");
|
||||
log(err.name + "\n" + err.message + "\n" + err.stack);
|
||||
return reject(err.name);
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
const parser = this.serialPort.pipe(new ReadlineParser({delimiter: '\r'}));
|
||||
|
||||
parser.on('data', (data) => this.onData(data));
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public static disconnect() {
|
||||
if (this.serialPort.isOpen) {
|
||||
this.serialPort.close((err) => {
|
||||
this.serialPort = null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static sendRequest(request: ArduinoProxyPayload, timeout: number = 1000) {
|
||||
return new Promise<ArduinoProxyPayload>((resolve, reject) => {
|
||||
let id = Utils.generateRandomString(8);
|
||||
request.id = id;
|
||||
this.callbacks[id] = {resolve: resolve, reject: reject};
|
||||
|
||||
this.serialPort.write(JSON.stringify(request), ArduinoProxy.encoding, (err: Error | null | undefined) => {
|
||||
if (err) {
|
||||
reject("I/O error on request " + id);
|
||||
}
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
reject("Timeout on request " + id);
|
||||
delete this.callbacks[id];
|
||||
}, timeout);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
35
src/ArduinoProxyPayload.ts
Normal file
35
src/ArduinoProxyPayload.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import {ArduinoProxyPayloadType} from "./ArduinoProxyPayloadType";
|
||||
import {ArduinoProxy} from "./ArduinoProxy";
|
||||
|
||||
export class ArduinoProxyPayload {
|
||||
set id(value: string) {
|
||||
this._id = value;
|
||||
}
|
||||
|
||||
private readonly _type: ArduinoProxyPayloadType;
|
||||
private readonly _data: any;
|
||||
|
||||
private _id: string ="";
|
||||
|
||||
|
||||
constructor(type: ArduinoProxyPayloadType, data: any) {
|
||||
this._type = type;
|
||||
this._data = data;
|
||||
}
|
||||
|
||||
get type(): ArduinoProxyPayloadType {
|
||||
return this._type;
|
||||
}
|
||||
|
||||
get data(): any {
|
||||
return this._data;
|
||||
}
|
||||
|
||||
get id(): string {
|
||||
return this._id;
|
||||
}
|
||||
|
||||
public send() {
|
||||
return ArduinoProxy.sendRequest(this);
|
||||
}
|
||||
}
|
7
src/ArduinoProxyPayloadType.ts
Normal file
7
src/ArduinoProxyPayloadType.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export enum ArduinoProxyPayloadType {
|
||||
ACK="ACK",
|
||||
SET_PIN="SET_PIN",
|
||||
GET_VAL="GET_VAL",
|
||||
GET_SENSOR="GET_SENSOR",
|
||||
RESTART="RESTART",
|
||||
}
|
0
src/ArduinoProxyUpdater.ts
Normal file
0
src/ArduinoProxyUpdater.ts
Normal file
@ -5,5 +5,7 @@ export enum RequestType {
|
||||
JOB = "JOB",
|
||||
STARTFILL = "STARTFILL",
|
||||
STOPFILL = "STOPFILL",
|
||||
DOWNLOAD_DRINKS = "DOWNLOAD_DRINKS"
|
||||
DOWNLOAD_DRINKS = "DOWNLOAD_DRINKS",
|
||||
TARE = "TARE",
|
||||
CHECK = "CHECK",
|
||||
}
|
10
src/Utils.ts
10
src/Utils.ts
@ -84,4 +84,14 @@ export class Utils {
|
||||
|
||||
|
||||
}
|
||||
|
||||
static generateRandomString(number: number) {
|
||||
let result = '';
|
||||
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
const charactersLength = characters.length;
|
||||
for (let i = 0; i < length; i++) {
|
||||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@ -13,6 +13,7 @@ export const ContainerSchema = new Mongoose.Schema<IContainer>({
|
||||
content: {type: mongoose.Types.ObjectId, ref: "Ingredient"},
|
||||
sensorDelta: Number, // V2: Now sensorDelta - Differenz, welche beim Einstellen der Zutat aus Gewicht(Sensor) - Volumen errechnet wird
|
||||
sensorTare: Number, // V2: Now sensorTare
|
||||
sensorProxy: {type: Boolean, default: false},
|
||||
filled: Number,
|
||||
enabled: {type: Boolean, default: false},
|
||||
});
|
||||
|
@ -12,6 +12,7 @@ export interface IContainer extends mongoose.Document {
|
||||
sensorType: SensorType;
|
||||
sensorPin1: number;
|
||||
sensorPin2: number;
|
||||
sensorProxy: boolean
|
||||
rawData: number;
|
||||
pumpPin: number;
|
||||
filled: number;
|
||||
|
@ -470,13 +470,31 @@ export class iTender {
|
||||
});
|
||||
}
|
||||
|
||||
public static clearAllRawMeasurements()
|
||||
{
|
||||
return new Promise<void>(async (resolve, reject) => {
|
||||
for (let c of (await Container.find({}))) {
|
||||
if (c.sensorType != SensorType.NONE) {
|
||||
c.rawData = -1;
|
||||
await c.save();
|
||||
}
|
||||
}
|
||||
resolve();
|
||||
})
|
||||
}
|
||||
|
||||
public static measureAllRaw() {
|
||||
return new Promise<void>(async (resolve, reject) => {
|
||||
for (let c of (await Container.find({}))) {
|
||||
if (c.sensorType != SensorType.NONE) {
|
||||
let weight = SensorHelper.measure(c);
|
||||
if (weight == null) {
|
||||
let weight : number | null = c.rawData;
|
||||
if( !c.sensorProxy )
|
||||
{
|
||||
// Check values
|
||||
weight = SensorHelper.measure(c);
|
||||
}
|
||||
|
||||
if (weight == null || weight > 1000 || weight < 0 ) { //fixme werte
|
||||
// Problem erkannt!
|
||||
return reject("Fehler Sensor (" + c.sensorPin1 + ", " + c.sensorPin2 + ") - Container " + c.slot + 1);
|
||||
}
|
||||
|
@ -157,6 +157,37 @@ router.ws('/', async (ws, req, next) => {
|
||||
WebSocketHandler.answerRequest(msg.data["type"] as RequestType, "ok");
|
||||
break;
|
||||
}
|
||||
case RequestType.CHECK: {
|
||||
await iTender.clearAllRawMeasurements();
|
||||
|
||||
|
||||
let content : {error: boolean, msg: string} = {
|
||||
error: false,
|
||||
msg: ""
|
||||
};
|
||||
|
||||
// Check config
|
||||
/// Check Proxy
|
||||
if( Settings.get("arduino_proxy_enabled") == true )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Check measurements
|
||||
await iTender.measureAllRaw();
|
||||
for( let c of await Container.find() )
|
||||
{
|
||||
if( c.sensorType != SensorType.NONE && c.rawData == -1 )
|
||||
{
|
||||
content.error = true;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
case RequestType.TARE: {
|
||||
let type = msg.data["type"];
|
||||
// Start TARE
|
||||
|
Reference in New Issue
Block a user