V2: Add proxy for pumps and sensors
Took 30 minutes
This commit is contained in:
parent
c9a0ac68c4
commit
243715dab7
12
DOCME.md
Normal file
12
DOCME.md
Normal file
@ -0,0 +1,12 @@
|
||||
# Willkommen!
|
||||
|
||||
Willkommen im iTender Projekt von Tobias Hopp und Nick Thiele.
|
||||
|
||||
Sie befinden sich in der internen Code-Dokumentation von iTender.
|
||||
|
||||
Hier befinden sich Methoden und Klassen vom iTender, von Web-Client, über die WebSocket-App bis hin zum Server.
|
||||
|
||||
Die Bedienung dieser Dokumentation erscheint anfangs vielleicht holprig, allerdings ist sie leichter als gedacht.
|
||||
|
||||
Du willst vermutlich hier hin ->
|
||||
[iTender Klasse](classes/iTender.iTender.html)
|
18
README.md
18
README.md
@ -1 +1,19 @@
|
||||
# iTender
|
||||
|
||||
Willkommen im iTender Projekt von Tobias Hopp und Nick Thiele.
|
||||
|
||||
Das Projekt ist entstanden in einer Unterrichtseinheit zum Thema Abschlussprojekt.
|
||||
Wir (Nick und Tobias) dachten zuerst an eine KI gesteuertes Auto, welches allerdings relativ schnell durch den iTender verworfen wurde.
|
||||
|
||||
Der iTender ist längst über dem Niveau eines Schul-Projektes und befindet sich in stetigem Wachstum.
|
||||
Bereits über 100 Stunden an Programmierarbeit, mehr als 20 Stunden Design sowie 50+ Stunden Dokumentationsaufwand sind in das Projekt geflossen.
|
||||
Wie man leicht heraus lesen kann, nutzen wir auch viel unserer Freizeit für unser außergewöhnliches Projekt.
|
||||
|
||||
|
||||
Das Projekt war anfangs nur sehr einfach geplant, mit einer Möglichkeit aus einer kleinen Liste Drinks zu wählen, welche dann zubereitet werden.
|
||||
Die Idee lag bei einem kleinen 2-Zeiligem LCD-Display, welches mit einem Drehsensor verbunden ist und dann die Drinks mischt.
|
||||
|
||||
Nun ja, wie man unschwer am Produkt erkennen kann, ist unsere Idee etwas expandiert.
|
||||
Nicht nur, dass wir kein LCD-Display, sondern ein hochauflösendes Farbdisplay nutzen, viel mehr noch, dass wir eine Cloud, eine vollwertige Benutzeroberfläche, Handy Unterstützung und vieles mehr anbieten.
|
||||
Die Liste hört grundlegend nicht mehr auf, wird sich aber im Benutzer-Handbuch vom iTender unter Features wiederfinden.
|
||||
|
||||
|
@ -10,7 +10,8 @@
|
||||
"compile": "tsc && webpack",
|
||||
"compileStart": "yarn run compile && yarn start",
|
||||
"watchTS": "tsc --watch",
|
||||
"watchWP": "webpack --watch"
|
||||
"watchWP": "webpack --watch",
|
||||
"doc": "typedoc"
|
||||
},
|
||||
"dependencies": {
|
||||
"@serialport/parser-readline": "^10.5.0",
|
||||
@ -37,6 +38,7 @@
|
||||
"morgan": "^1.10.0",
|
||||
"net-ping": "^1.2.3",
|
||||
"onoff": "^6.0.3",
|
||||
"pi-hx711": "^1.2.0",
|
||||
"pug": "^3.0.2",
|
||||
"rpi-gpio": "^2.1.7",
|
||||
"rpi-ws281x-native": "^1.0.4",
|
||||
|
14
src/HX711.ts
14
src/HX711.ts
@ -1,14 +0,0 @@
|
||||
export class HX711 {
|
||||
private clockPin: number;
|
||||
private dataPin: number;
|
||||
|
||||
|
||||
constructor(dataPin: number, clockPin: number) {
|
||||
this.clockPin = clockPin;
|
||||
this.dataPin = dataPin;
|
||||
}
|
||||
|
||||
public measure(): number {
|
||||
return 0;
|
||||
}
|
||||
}
|
41
src/Mixer.ts
41
src/Mixer.ts
@ -7,6 +7,9 @@ import {clearInterval} from "timers";
|
||||
import {IContainer} from "./database/IContainer";
|
||||
import {iTender} from "./iTender";
|
||||
import debug from "debug";
|
||||
import {ArduinoProxyPayload} from "./ArduinoProxyPayload";
|
||||
import {ArduinoProxyPayloadType} from "./ArduinoProxyPayloadType";
|
||||
import {ArduinoProxy} from "./ArduinoProxy";
|
||||
|
||||
const isPI = require("detect-rpi");
|
||||
|
||||
@ -54,9 +57,18 @@ export class Mixer {
|
||||
|
||||
// Start pump here
|
||||
try {
|
||||
await MyGPIO.setup(x.container.pumpPin, GPIO.DIR_OUT)
|
||||
if (x.container.pumpProxy) {
|
||||
let payload = new ArduinoProxyPayload(ArduinoProxyPayloadType.SET_PIN, {
|
||||
pin: x.container.pumpPin,
|
||||
mode: "DIGITAL",
|
||||
value: 255
|
||||
});
|
||||
await ArduinoProxy.sendRequest(payload);
|
||||
} else {
|
||||
await MyGPIO.setup(x.container.pumpPin, GPIO.DIR_OUT)
|
||||
await MyGPIO.write(x.container.pumpPin, true);
|
||||
}
|
||||
|
||||
await MyGPIO.write(x.container.pumpPin, true);
|
||||
} catch (e) {
|
||||
if (isPI()) {
|
||||
log("[ERROR] GPIO I/O Error " + e);
|
||||
@ -83,7 +95,17 @@ export class Mixer {
|
||||
log(`Stopping output of pump ${x.container.pumpPin}`);
|
||||
// Stop pump here
|
||||
try {
|
||||
await MyGPIO.write(x.container.pumpPin, false);
|
||||
if (x.container.pumpProxy) {
|
||||
let payload = new ArduinoProxyPayload(ArduinoProxyPayloadType.SET_PIN, {
|
||||
pin: x.container.pumpPin,
|
||||
mode: "DIGITAL",
|
||||
"value": 0
|
||||
});
|
||||
await ArduinoProxy.sendRequest(payload);
|
||||
} else {
|
||||
await MyGPIO.write(x.container.pumpPin, false);
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
if (isPI()) {
|
||||
log("[ERROR] GPIO I/O Error " + e);
|
||||
@ -143,12 +165,21 @@ export class Mixer {
|
||||
for (let jobIngredient of this._currentJob.amounts) {
|
||||
// stop pump pin
|
||||
try {
|
||||
await MyGPIO.write(jobIngredient.container.pumpPin, false);
|
||||
if (jobIngredient.container.pumpProxy) {
|
||||
let payload = new ArduinoProxyPayload(ArduinoProxyPayloadType.SET_PIN, {
|
||||
pin: jobIngredient.container.pumpPin,
|
||||
mode: "DIGITAL",
|
||||
"value": 0
|
||||
});
|
||||
await ArduinoProxy.sendRequest(payload);
|
||||
} else {
|
||||
await MyGPIO.write(jobIngredient.container.pumpPin, false);
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
|
||||
// ToDo
|
||||
// ToDo v2 calc
|
||||
let container: IContainer = jobIngredient.container;
|
||||
let deltaStartStop = (this._currentJob.endAt.getTime() - this._currentJob.startedAt.getTime()) / 1000;
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import GPIO from "rpi-gpio";
|
||||
import Container from "./database/Container";
|
||||
import debug from "debug";
|
||||
import {IContainer} from "./database/IContainer";
|
||||
|
||||
const log = debug("itender:gpio");
|
||||
|
||||
@ -45,12 +46,15 @@ export class MyGPIO {
|
||||
let containers = await Container.find({});
|
||||
for (let c of containers) {
|
||||
try {
|
||||
if (c.sensorType) {
|
||||
if (c.sensorType && !c.sensorProxy) {
|
||||
await MyGPIO.setup(c.sensorPin1, GPIO.DIR_IN);
|
||||
await MyGPIO.setup(c.sensorPin2, GPIO.DIR_IN);
|
||||
}
|
||||
await MyGPIO.setup(c.pumpPin, GPIO.DIR_OUT);
|
||||
await MyGPIO.write(c.pumpPin, false);
|
||||
if( c.pumpPin && !c.pumpProxy )
|
||||
{
|
||||
await MyGPIO.setup(c.pumpPin, GPIO.DIR_OUT);
|
||||
await MyGPIO.write(c.pumpPin, false);
|
||||
}
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,13 @@
|
||||
import {IContainer} from "./database/IContainer";
|
||||
import {SensorType} from "./SensorType";
|
||||
import {HX711} from "./HX711";
|
||||
|
||||
import debug from "debug";
|
||||
import {ArduinoProxyPayload} from "./ArduinoProxyPayload";
|
||||
import {ArduinoProxyPayloadType} from "./ArduinoProxyPayloadType";
|
||||
import {ArduinoProxy} from "./ArduinoProxy";
|
||||
import Container from "./database/Container";
|
||||
import {HCSR04} from "hc-sr04";
|
||||
const HX711 = require("pi-hx711");
|
||||
|
||||
const log = debug("itender:sensor");
|
||||
|
||||
@ -31,7 +33,7 @@ export class SensorHelper {
|
||||
container.rawData = val.data.value;
|
||||
} else {
|
||||
let sensor = new HX711(container.sensorPin1, container.sensorPin2);
|
||||
container.rawData = sensor.measure();
|
||||
container.rawData = await sensor.readRaw();
|
||||
}
|
||||
} catch (e) {
|
||||
log("Sensor (Weight cell) of container " + container._id + " is broken or has malfunction - Removing it!");
|
||||
@ -42,9 +44,9 @@ export class SensorHelper {
|
||||
} else if (container.sensorType == SensorType.ULTRASOUND) {
|
||||
try {
|
||||
// V2: Measure weight
|
||||
let sensor = new HX711(container.sensorPin1, container.sensorPin2);
|
||||
let sensor = new HCSR04(container.sensorPin1, container.sensorPin2);
|
||||
|
||||
container.rawData = sensor.measure();
|
||||
// container.rawData = sensor.measure(); ToDo
|
||||
|
||||
} catch (e) {
|
||||
log("Sensor (Ultrasound) of container " + container._id + " is broken or has malfunction - Removing it!");
|
||||
|
@ -14,6 +14,7 @@ export const ContainerSchema = new Mongoose.Schema<IContainer>({
|
||||
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},
|
||||
pumpProxy: { type: Boolean, default: false },
|
||||
filled: Number,
|
||||
enabled: {type: Boolean, default: false},
|
||||
});
|
||||
|
@ -19,9 +19,18 @@ export interface IContainer extends mongoose.Document {
|
||||
* HX711 CLOCK-Pin
|
||||
*/
|
||||
sensorPin2: number;
|
||||
|
||||
/**
|
||||
* Is the arduino used as proxy for the sensor?
|
||||
*/
|
||||
sensorProxy: boolean
|
||||
rawData: number;
|
||||
pumpPin: number;
|
||||
|
||||
/**
|
||||
* Is the arduino used as proxy for the pump?
|
||||
*/
|
||||
pumpProxy: boolean
|
||||
filled: number;
|
||||
enabled: boolean;
|
||||
}
|
@ -2,13 +2,15 @@
|
||||
"entryPoints": [
|
||||
"src/main.ts",
|
||||
"src/iTender.ts",
|
||||
"src/Mixer.ts",
|
||||
"src/ArduinoProxy.ts",
|
||||
"src/web/main.ts",
|
||||
"src/WebsocketApp.ts",
|
||||
"src/App.ts",
|
||||
"src/routes/ws/websocketRoute.ts"
|
||||
],
|
||||
"out": "docs/",
|
||||
"readme": "README.md",
|
||||
"name": "iTender Documentation",
|
||||
"readme": "DOCME.md",
|
||||
"name": "iTender internal Code Docs",
|
||||
"tsconfig": "./tsconfig.json"
|
||||
}
|
||||
|
15
yarn.lock
15
yarn.lock
@ -2466,6 +2466,13 @@ path-to-regexp@0.1.7:
|
||||
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
|
||||
integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==
|
||||
|
||||
pi-hx711@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/pi-hx711/-/pi-hx711-1.2.0.tgz#804f954f8c397c4442304118a95dda679fa94d24"
|
||||
integrity sha512-HuoMIVo+T1wf8jig/VODiE9XYCEBgSfavxLrtG9SF6l8fQQPr618ri3mSQB8oCAoYrNiYA1hEXoH+GdtlKN3Ow==
|
||||
dependencies:
|
||||
pigpio "^3.3.1"
|
||||
|
||||
picocolors@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
|
||||
@ -2476,6 +2483,14 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1:
|
||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
|
||||
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
|
||||
|
||||
pigpio@^3.3.1:
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/pigpio/-/pigpio-3.3.1.tgz#fc31885ea2bfb335cccb80b9d78b443fcfe56b90"
|
||||
integrity sha512-z7J55K14IwWkA+oW5JHzWcgwThFAuJ7IzV3A2//yRm4jJ2DTU0DHIy91DB0siOi12rvvlrIhRetEuAo0ztF/vQ==
|
||||
dependencies:
|
||||
bindings "^1.5.0"
|
||||
nan "^2.14.2"
|
||||
|
||||
pkg-dir@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3"
|
||||
|
Loading…
x
Reference in New Issue
Block a user