Blame view

gpio_trigger.py 4.88 KB
Frederik Lindenaar authored
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#! /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