Skip to content

Instantly share code, notes, and snippets.

@roguesherlock
Last active April 1, 2017 07:30
Show Gist options
  • Save roguesherlock/b18d7d30efddc2e412f0bfdcbc625a3a to your computer and use it in GitHub Desktop.
Save roguesherlock/b18d7d30efddc2e412f0bfdcbc625a3a to your computer and use it in GitHub Desktop.
GPIO-Input-Listener: A simple python script that listens for gpio input events (more specifically button clicks) and calls appropriate methods. It has a very basic bouncing mechanism.It has logging capabilities and restarts itself on any exception.Basically, It's trying to imitate a daemon.I hope it might be useful to someone.
#!/usr/bin/env python
#########################################################################
# GPIO-Input-Listener: A simple python script that listens for #
# gpio input events (more specifically button clicks) and calls #
# appropriate methods. It has a very basic bouncing mechanism. #
# It has logging capabilities and restarts itself on any exception. #
# Basically, It's trying to imitate a daemon. #
# I hope it might be useful to someone. #
# Copyright (c) 2017 0xelectron #
#########################################################################
import sys
from subprocess import call, check_output, STDOUT
import time
import logging
import logging.handlers
# logger config
LOG_FILENAME = "/var/log/gpio_input_listner.log"
LOG_FORMAT = logging.Formatter('%(levelname)s | %(asctime)-15s | %(message)s')
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
handler = logging.handlers.RotatingFileHandler(
LOG_FILENAME, maxBytes=10*1024*1024, backupCount=5)
handler.setFormatter(LOG_FORMAT)
logger.addHandler(handler)
import RPi.GPIO as GPIO
logger.info("GPIO Version: {}".format(GPIO.VERSION))
logger.info("Initializing...")
# start playlist audio pin
spa_pin = 2
# start playlist video pin
spv_pin = 3
# stop falcon plyaer pin
sfp_pin = 4
# pins setup
GPIO.setmode(GPIO.BCM)
GPIO.setup(spa_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(spv_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(sfp_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# def start_playlist(pin, value):
# if not fppd_status():
# logger.warning("fpp daemon was stoped. Restarting now!")
# fppd_restart()
# if (playlist_status() and pin != sfp_pin):
# logger.info(""" Got pin {0} with value {1}.
# Ignoring as playlist is already running.""".format(pin, value))
# return
# else:
# if pin == spa_pin:
# logger.info("""Got pin {0} with value {1}.
# Starting audio playlist in fpp player""".format(pin, value))
# call(["/opt/fpp/bin.pi/fpp", "-P", "audio"])
# elif pin == spv_pin:
# logger.info("""Got pin {0} with value {1}.
# Starting video playlist in fpp player""".format(pin, value))
# call(["/opt/fpp/bin.pi/fpp", "-P", "video"])
# elif pin == sfp_pin:
# logger.info("""Got pin {0} with value {1}.
# Stoping playlist in fpp player""".format(pin, value))
# fppd_stop()
# else:
# logger.warning("""Something is really wrong here.
# Got pin {0} with value {1}""".format(pin, value))
# return
# return
def playlist_start(playlist):
if not fppd_status():
logger.warning("fpp daemon was stoped. Restarting now!")
fppd_restart()
if playlist_status():
logger.info("Ignoring input as playlist is already playling")
return
else:
if playlist == "audio" or playlist == "video":
logger.info("Starting {} playlist in fpp player".format(playlist))
call(["/opt/fpp/bin.pi/fpp", "-P", playlist])
else:
logger.warning("Got wrong playlist name, Ignoring it.")
return
return
# playlist_status: Checks if any playlists are plyaing
# returns True if there are, else False
def playlist_status():
# get status from fpp cli
status = str(check_output("/opt/fpp/bin.pi/fpp -s", stderr=STDOUT, shell=True)).lower()
# This is kind of an hack, really!
if (len(status) > 30 and "fseq" in status and
"playlist" in status):
return True
return False
# fppd_restart: Restarts fpp daemon
def fppd_restart():
logger.info("Restarting fpp daemon.")
call(["/opt/fpp/scripts/fppd_stop"])
call(["/opt/fpp/scripts/fppd_start"])
# fppd_status: checks status of fpp daemon
# returns True if fppd is on else False
def fppd_status():
status = check_output("/opt/fpp/bin.pi/fpp -s", stderr=STDOUT, shell=True)
if ("false" in str(status)):
logger.info("fpp daemon was stoped.")
return False
return True
# fppd_stop: stops the currently playling
# playlist immediately and restarts daemon
def fppd_stop():
call(["/opt/fpp/bin.pi/fpp", "-d"])
logger.info("playlist in fpp player stoped. Now restarting fpp daemon.")
fppd_restart()
# def main():
# look for button presses
try:
# logger.info("")
# GPIO.add_event_detect(sfp_pin, GPIO.BOTH, callback=start_playlist,
# bouncetime=300)
# GPIO.add_interrupt_callback(spv_pin, start_playlist, threaded_callback=True,
# debounce_timeout_ms=100)
# GPIO.wait_for_interrupts(threaded=True)
# old input states of three pins
ois1 = ois2 = ois3 = True
logger.info("All done! Waiting for input...")
while True:
# new input states of three pins
nis1 = GPIO.input(sfp_pin)
nis2 = GPIO.input(spa_pin)
nis3 = GPIO.input(spv_pin)
# if states have changed
if not nis1 and ois1:
fppd_stop()
elif not nis2 and ois2:
playlist_start("audio")
elif not nis3 and ois3:
playlist_start("video")
# update the old states
ois1 = nis1
ois2 = nis2
ois3 = nis3
# sleep
time.sleep(0.2)
except KeyboardInterrupt:
logger.info("Got Keyboard Interrupt. Closing Now!")
sys.exit(0)
except Exception as e:
logger.error("Caught Exception:", exc_info=True)
logger.info("Restarting the script!")
os.execv(__file__, sys.argv)
finally:
logger.info("Cleaning up gpio setup")
GPIO.cleanup()
logger.info("Cleaned up!")
logger.info("bye!")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment