From 7afc662ba70b5fdbd1a12c7d284c4cbda13bddf8 Mon Sep 17 00:00:00 2001 From: Skylar Grant Date: Sun, 18 Aug 2024 13:46:10 -0400 Subject: [PATCH] Move timeout to a promise --- src/custom_modules/VoidGPIO.js | 85 +++++++++++++++++++++++++--------- src/python/gpio_interface.py | 42 +++++++++++++---- 2 files changed, 95 insertions(+), 32 deletions(-) diff --git a/src/custom_modules/VoidGPIO.js b/src/custom_modules/VoidGPIO.js index c8b2b19..5e132d8 100644 --- a/src/custom_modules/VoidGPIO.js +++ b/src/custom_modules/VoidGPIO.js @@ -1,20 +1,49 @@ const { exec } = require('child_process'); const pins = [ - { key: 'igniter', board: 13, bcm: 27, mode: 'OUT' }, - { key: 'exhaust', board: 15, bcm: 22, mode: 'OUT' }, - { key: 'auger', board: 7, bcm: 4, mode: 'OUT' }, - { key: 'pof', board: 16, bcm: 23, mode: 'IN' }, - { key: 'vacuum', board: 22, bcm: 25, mode: 'IN' } + { + key: 'igniter', + board: 13, + bcm: 27, + mode: 'OUT', + defaultState: 0 + }, + { + key: 'exhaust', + board: 15, + bcm: 22, + mode: 'OUT', + defaultState: 1 + }, + { + key: 'auger', + board: 7, + bcm: 4, + mode: 'OUT', + defaultState: 0 + }, + { + key: 'pof', + board: 16, + bcm: 23, + mode: 'IN' + }, + { + key: 'vacuum', + board: 22, + bcm: 25, + mode: 'IN' } ]; +const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); + pins.forEach(pin => { console.log(`Key: ${pin.key}, Board: ${pin.board}, BCM: ${pin.bcm}, Mode: ${pin.mode}`); }); module.exports = { - // Function to toggle a pin on-then-off + // Calls the GPIO Interface script to toggle a pin's state opposite of its current state togglePin(pin, callback) { exec(`python3 src/python/gpio_interface.py toggle ${pin}`, (error, stdout, stderr) => { if (error) { @@ -23,26 +52,39 @@ module.exports = { if (stderr) { return callback(new Error(stderr)); } - console.log(`Successfully toggled pin ${pin}`); }); }, - // Function to sense a pin state - sensePin(pin, callback) { - exec(`python3 src/python/gpio_interface.py sense ${pin}`, (error, stdout, stderr) => { + // Calls the GPIO Interface script to read a pin's state + readPin(pin, callback) { + exec(`python3 src/python/gpio_interface.py read ${pin}`, (error, stdout, stderr) => { + if (error) return callback(error); + if (stderr) return callback(new Error(stderr)); + callback(null, stdout.trim()); + }); + }, + // Calls the GPIO Interface script to set a pin's state regardless of its current state + setPin(pin, state, callback) { + exec(`python 3 src/python/gpio_interface.py set ${pin} ${state}`, (error, stdout, stderr) => { if (error) { - console.error(`Error sensing pin ${pin}: ${error.message}`); return callback(error); } if (stderr) { - console.error(`Stderr while sensing pin ${pin}: ${stderr}`); return callback(new Error(stderr)); } - console.log(`Pin ${pin} state: ${stdout.trim()}`); - callback(stdout.trim(), null); - }); + callback(null); + }) }, - // Toggle pins sequentially and then sense pin states + // Boot up sanity check during debug mode debugInit() { + console.log('Resetting all output pins.'); + pins.forEach(async (pin) => { + if (pin.mode === 'OUT') { + this.setPin(pin.board, pin.defaultState, err => { + if (err) throw err; + console.log(`Set ${pin.key} pin to ${pin.defaultState}.`); + }); + }; + }); pins.forEach(async (pin) => { switch (pin.mode) { case 'OUT': @@ -50,14 +92,13 @@ module.exports = { if (err) throw err; }); // Wait 1000ms before toggling again. - await setTimeout(() => { - this.togglePin(pin.board, err => { - if (err) throw err; - }); - }, 1000); + await sleep(1000); + this.togglePin(pin.board, err => { + if (err) throw err; + }); break; case 'IN': - this.sensePin(pin.board, (state, err) => { + this.readPin(pin.board, (err, state) => { if (err) throw err; console.log(`${pin.key} state: ${state}`); }); diff --git a/src/python/gpio_interface.py b/src/python/gpio_interface.py index 01703d3..9fb34c4 100644 --- a/src/python/gpio_interface.py +++ b/src/python/gpio_interface.py @@ -1,6 +1,5 @@ import RPi.GPIO as GPIO import sys -import time # Initialize GPIO using Board mode for pin numbering GPIO.setmode(GPIO.BOARD) @@ -27,22 +26,35 @@ def toggle_pin(pin): # Exit with 1 for failure return 1 -def sense_pin(pin): +def read_pin(pin): setup_pin(pin, 'IN') try: - # Sense pin state + # Read pin state state = GPIO.input(pin) # Return 1 if pin is HIGH, 0 if LOW return 1 if state == GPIO.HIGH else 0 except Exception as e: # Handle errors - print(f"Error sensing pin {pin}: {e}") + print(f"Error reading pin {pin}: {e}") # Return -1 on error return -1 +def set_pin_state(pin, state): + setup_pin(pin, 'OUT') + try: + # Set the pin state to either HIGH (1) or LOW (0) + GPIO.output(pin, GPIO.HIGH if state == 1 else GPIO.LOW) + # Exit with 0 for success + return 0 + except Exception as e: + # Handle errors + print(f"Error setting pin {pin} to state {state}: {e}") + # Exit with 1 for failure + return 1 + def main(): - if len(sys.argv) < 2: - print("Usage: python3 gpio_interface.py ") + if len(sys.argv) < 3: + print("Usage: python3 gpio_interface.py []") sys.exit(1) command = sys.argv[1].lower() @@ -51,13 +63,23 @@ def main(): if command == "toggle": result = toggle_pin(pin) sys.exit(result) - elif command == "sense": - result = sense_pin(pin) + elif command == "read": + result = read_pin(pin) print(result) sys.exit(0 if result >= 0 else 1) + elif command == "set": + if len(sys.argv) < 4: + print("Usage: python3 gpio_interface.py set ") + sys.exit(1) + state = int(sys.argv[3]) + if state not in [0, 1]: + print("Invalid state. Use 0 for LOW or 1 for HIGH.") + sys.exit(1) + result = set_pin_state(pin, state) + sys.exit(result) else: - print("Invalid command. Use 'toggle' or 'sense'.") + print("Invalid command. Use 'toggle', 'read', or 'set'.") sys.exit(1) if __name__ == "__main__": - main() \ No newline at end of file + main()