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); } }