fotobox/src/gpio.ts
2023-05-24 00:23:46 +02:00

129 lines
3.2 KiB
TypeScript

import * as fs from "fs";
export class GPIO {
private static openPorts: GPIO[] = [];
private readonly gpioPath: string;
private readonly gpioPin: number;
public constructor(pin: number, direction: 'in' | 'out') {
const gpioPath = `/sys/class/gpio/gpio${pin}`;
this.gpioPath = gpioPath;
this.gpioPin = pin;
try {
fs.accessSync(gpioPath);
} catch( e )
{
throw new GPIOError("GPIO not accessible");
}
// Überprüfe, ob der GPIO-Pin bereits exportiert ist
if (!fs.existsSync(gpioPath)) {
this.export();
}
// Setze den Richtungsmodus auf Ausgang
fs.writeFileSync(`${gpioPath}/direction`, direction);
GPIO.openPorts.push(this);
}
public static getPin(pin: number, direction: 'in' | 'out'): GPIO {
let port = new GPIO(pin, direction);
this.openPorts.push(port);
return port;
}
public static watchForButton(pin: number, onPress: (pin: number) => void) {
const button = new GPIO(pin, 'in');
this.openPorts.push(button);
button.watch((err) => {
if (err) {
console.error(err);
return;
}
onPress(pin);
}, 100, 500);
}
public static unexportAll() {
for (let p of this.openPorts) {
try {
p.unexport();
} catch (e) {
}
}
}
public getValue(): number {
// Überprüfe, ob der GPIO-Pin bereits exportiert ist
if (!fs.existsSync(this.gpioPath)) {
throw new GPIOError('Pin not exported');
}
// Lese den Wert des GPIO-Pins
const value = fs.readFileSync(`${this.gpioPath}/value`, 'utf8');
return Number.parseInt(value.trim());
}
public setValue(value: number) {
// Setze den Wert auf X
fs.writeFileSync(`${(this.gpioPath)}/value`, String(value));
}
public setHigh() {
this.setValue(1);
}
public setLow() {
this.setValue(0);
}
public changeDirection(direction: 'in' | 'out') {
// Setze den Richtungsmodus auf Ausgang
fs.writeFileSync(`${this.gpioPath}/direction`, direction);
}
public watch(callback: (value: number) => void, interval: number = 100, bounceWait = 500) {
let lastState = this.getValue();
let lastBounce = Date.now();
setInterval(() => {
if (lastBounce + bounceWait > Date.now())
return;
let val = this.getValue();
if (lastState != val) {
callback(val);
lastState = val;
}
}, interval);
}
private export() {
// Exportiere den GPIO-Pin
fs.writeFileSync('/sys/class/gpio/export', this.gpioPin.toString());
}
private unexport() {
// Exportiere den GPIO-Pin
fs.writeFileSync('/sys/class/gpio/unexport', this.gpioPin.toString());
}
}
export class GPIOError extends Error {
constructor(msg: string) {
super(msg);
// Set the prototype explicitly.
Object.setPrototypeOf(this, GPIOError.prototype);
}
}