#! /usr/bin/env python # # gpio_trigger.py - execute a command when a GPIO pin is triggered (up or down) # # Version 1.0, latest version, documentation and bugtracker available at: # https://gitlab.lindenaar.net/scripts/raspberrypi # # Copyright (c) 2019 Frederik Lindenaar # # This script is free software: you can redistribute and/or modify it under the # terms of version 3 of the GNU General Public License as published by the Free # Software Foundation, or (at your option) any later version of the license. # # This script is distributed in the hope that it will be useful but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along with # this program. If not, visit <http://www.gnu.org/licenses/> to download it. # from os import fork, system from argparse import ArgumentParser from RPi import GPIO parser = ArgumentParser(description='Run command when a Raspberry Pi pin is' ' high or low (e.g. a button is pressed)') pgroup = parser.add_mutually_exclusive_group(required=False) pgroup.add_argument('-P', '--pcb', action='store_const', dest='mode', const=GPIO.BOARD, default=GPIO.BOARD, help='GPIO header/board (PCB) pin numbers (default)') pgroup.add_argument('-S', '--bcm', help='GPIO BCM mode (Broadcom SOC pins)', action='store_const', dest='mode', const=GPIO.BCM) parser.add_argument('-p', '--pin', type=int, required=False, default=40, help='GPIO pin number to use (default: 40)') pgroup = parser.add_mutually_exclusive_group(required=False) pgroup.add_argument('-u', '--pull-up', action='store_const', dest='pull', default=GPIO.PUD_UP, const=GPIO.PUD_UP, help='internally pull pin up (default)') pgroup.add_argument('-d', '--pull-down', action='store_const', dest='pull', const=GPIO.PUD_DOWN, help='internally pull pin down') pgroup.add_argument('-n', '--no-pull', action='store_const', const=GPIO.PUD_OFF, dest='pull', help='don\'t pull pin up or down internally') pgroup = parser.add_mutually_exclusive_group(required=False) pgroup.add_argument('-f', '--edge-falling', action='store_const', const=GPIO.FALLING, dest='edge', default=GPIO.FALLING, help='respond to pin going down (default)') pgroup.add_argument('-r', '--edge-rising', action='store_const', dest='edge', const=GPIO.RISING, help='respond to pin going up') pgroup.add_argument('-a', '--edge-any', action='store_const', const=GPIO.BOTH, dest='edge', help='respond to any pin change') parser.add_argument('-i', '--ignore-result', action='store_true', default=False, help='ignore command result code (default: exit if <> 0)') parser.add_argument('-b', '--debounce', type=int, default=200, help='debounce period (in milliseconds, default=200)') parser.add_argument('-t', '--timeout', type=int, default=-1, help='optional timeout (in milliseconds) to wait') pgroup = parser.add_mutually_exclusive_group(required=False) pgroup.add_argument('-c', '--continuous', default=False, action='store_true', help='continously monitor GPIO pin and run cmd upon change') pgroup.add_argument('-o', '--once', action='store_false', dest='continuous', help='monitor pin and run cmd once, then exit (default)') parser.add_argument('-D', '--daemon', action='store_true', help='run in background (as daemon)') parser.add_argument('cmd', help='command to execute when pin goes low') parser.add_argument('arg', nargs='*', help='argument(s) for the command, use --' ' before first argument to stop parsing parameters') args = parser.parse_args() # parse command line GPIO.setmode(args.mode) # set GPIO number mode GPIO.setup(args.pin, GPIO.IN, pull_up_down=args.pull) # setup pin as input if args.daemon and fork() != 0: # Fork for daemon mode exit(0) # exit parent process ret = 0 while args.ignore_result or ret == 0: if GPIO.wait_for_edge(args.pin, args.edge, bouncetime=args.debounce, timeout=args.timeout): ret = system(' '.join([ args.cmd ] + args.arg)) # run the command if not args.continuous: # exit if running once break else: # exit if timeout break GPIO.cleanup(args.pin) # cleanup GPIO exit(ret) # and return the result