Skip to content

Commit

Permalink
Merge pull request #14 from jtuinman/master
Browse files Browse the repository at this point in the history
Changed it so it runs on a Raspberry Pi. CHIP support branched off.
  • Loading branch information
b0tting authored Jul 27, 2017
2 parents 2553950 + f96b71f commit c1c5aa3
Show file tree
Hide file tree
Showing 10 changed files with 58 additions and 49 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# escapemachine
A python script for supporting Escape Room puzzles with a c.h.i.p. (getchip.com)
A python script for supporting Escape Room puzzles with a Raspberry Pi (https://www.raspberrypi.org/)

# Features
The CHIP runs the following functions:
The Pi runs the following functions:
- Allow the game master to play spoken hints and sound effects, from a previously placed set of sound files
- Play the background music for the escape room, with fading over to other tracks on scene changes
- Follow scene progression from a phone, allow for direct intervention by enabling or disabling individual relays
Expand All @@ -12,4 +12,4 @@ The CHIP runs the following functions:
The interface was built using materializecss and is aimed at phone and tablet use.

# Technically..
..you could easily convert this script for use on a raspberry pi or any other SBC with IO pins. However, the CHIP is such a cool thing, I'd go for that if you can find one. The scene setup is extremely simple python code and easy to convert for other rooms, the UI is dynamic and should follow the python config. Also, someday, one day, I will enable configuration using XML or JSON.
..this script was converted from Mark Ottings orginal version which ran on a C.H.I.P.
27 changes: 14 additions & 13 deletions escape.conf.example → escape.conf
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,27 @@ logfile = ./escape.log
debug = False

## Define which pin links to which item or button. Find these at
bookbutton1pin = XIO-P2
bookbutton2pin = XIO-P4
keybuttonpin = XIO-P6
lamppin = CSID1
spotpin = CSID3
magnetpin = CSID5
bookbuttonpin1 = 23
bookbuttonpin2 = 24
keybuttonpin = 25
lamppin = 17
spotpin = 27
magnetpin = 22

## Music backgrounds for the different stages
music_state_entree = ambience_1.mp3
music_state_bathroom = ambience_2.mp3
music_state_endgame = ambience_3.mp3
music_state_entree = state1.mp3
music_state_bathroom = state2.mp3
music_state_endgame = state3.mp3

## Sound effects at start of the different stages
## Are optional, ie. I check if a sound_effect_<scene_name> exists
sound_effect_bathroom = ding_effect.ogg
sound_effect_bathroom = krakende_deur.ogg

## Webserver port
port = 8000
port = 3000

## Default volumes. "Sound volume" is for hints. Values go from 0 to 100.
music_volume = 85
sound_volume = 85
music_volume = 70
sound_volume = 70


64 changes: 37 additions & 27 deletions escape.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import logging
import os
import pygame
from threading import Thread

from flask import Flask, render_template, jsonify
import time
Expand All @@ -13,11 +12,13 @@

chip_complete_mode = False
try:
import CHIP_IO.GPIO as GPIO
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
chip_complete_mode = True
except Exception:
GPIO = False


## Prereqs: python 2.7 (PYTHON 3 MAG NAAR DE HEL)
## apt-get install git build-essential python-dev python-pip flex bison python-pygame -y
## pip install flask
Expand Down Expand Up @@ -51,12 +52,13 @@ def clean():
## Given time, the state machine should be migrated to it's own class and use
## external XML or sorts to define states. Seeing the clear purpose of the current
## version I'm not investing time in that yet.
def run_state_machine():
def run_state_machine(self):
## Measuring buttons states before investigating current state
book1pushed = not GPIO.input(bookbutton1pin)
book2pushed = not GPIO.input(bookbutton2pin)
keypushed = not GPIO.input(keybuttonpin)
logger.info("Buttons push, now in: pin1 " + str(book1pushed) + ", pin2 " + str(book2pushed) + ", pin3 " + str(keypushed))
time.sleep(0.3)
book1pushed = GPIO.input(bookbuttonpin1)
book2pushed = GPIO.input(bookbuttonpin2)
keypushed = GPIO.input(keybuttonpin)
logger.info("Buttons push, now in: book1 " + str(book1pushed) + ", book2 " + str(book2pushed) + ", key " + str(keypushed))

## Nobody said it had to be hard!
if not book1pushed and not book2pushed and state == STATE_NORMAL:
Expand All @@ -68,7 +70,7 @@ def run_state_machine():

def state_machine_start():
global state
state = STATE_START
state = STATE_START ## standby
logger.info("Now going into state " + readeable_states[state])
spot.turn_off()
lamp.turn_off()
Expand Down Expand Up @@ -106,21 +108,25 @@ def state_machine_endgame():
play_scene_sound("sound_effect_endgame")

def button_listener_thread(pin):
logger.info(pin + " listener up for reading")
logger.info(str(pin) + " listener up for reading")
while True:
logger.info(str(pin))
GPIO.wait_for_edge(pin, GPIO.BOTH)
logger.info(pin + " got edge!")
logger.info(str(pin) + " got edge!")
run_state_machine()
time.sleep(1)

def setup_pin(pin, input=True):
if input and GPIO:
GPIO.setup(pin, GPIO.IN)
button_thread = Thread(target = button_listener_thread, args = (pin,))
button_thread.daemon = True
button_thread.start()

## button_thread = Thread(target = button_listener_thread, args = (pin,))
## button_thread.daemon = True
## button_thread.start()
return pin



def play_scene_sound(scene_sound):
if config.has_option('Escape', scene_sound):
play_sound(sounddir + config.get("Escape", scene_sound))
Expand Down Expand Up @@ -302,14 +308,23 @@ def hello_world():

## Init all pins
logger.info("Initalizing pins")
bookbutton1pin = setup_pin(config.get("Escape", "bookbutton1pin"))
bookbutton2pin = setup_pin(config.get("Escape", "bookbutton2pin"))
keybuttonpin = setup_pin(config.get("Escape", "keybuttonpin"))
lamp = OutputPin(config.get("Escape", "lamppin"), "Lamp")
bookbuttonpin1 = config.getint("Escape", "bookbuttonpin1")
GPIO.setup(bookbuttonpin1, GPIO.IN)
GPIO.add_event_detect(bookbuttonpin1, GPIO.BOTH, callback=run_state_machine, bouncetime=200)

bookbuttonpin2 = config.getint("Escape", "bookbuttonpin2")
GPIO.setup(bookbuttonpin2, GPIO.IN)
GPIO.add_event_detect(bookbuttonpin2, GPIO.BOTH, callback=run_state_machine, bouncetime=200)

keybuttonpin = config.getint("Escape", "keybuttonpin")
GPIO.setup(keybuttonpin, GPIO.IN)
GPIO.add_event_detect(keybuttonpin, GPIO.BOTH, callback=run_state_machine, bouncetime=200)

lamp = OutputPin(config.getint("Escape", "lamppin"), "Lamp")
time.sleep(0.5)
spot = OutputPin(config.get("Escape", "spotpin"), "Spot")
spot = OutputPin(config.getint("Escape", "spotpin"), "Spot")
time.sleep(0.5)
magnet = OutputPin(config.get("Escape", "magnetpin"), "Magnet")
magnet = OutputPin(config.getint("Escape", "magnetpin"), "Magnet")
outputpins = {lamp.name:lamp, spot.name:spot,magnet.name:magnet}
sounddir = config.get("Escape", "sounddir") + "/"
music_volume = config.getfloat("Escape", "music_volume")
Expand All @@ -322,22 +337,17 @@ def hello_world():
state = STATE_START

if chip_complete_mode:
logger.error("CHIP_IO found, running on CHIP mode")
logger.error("RPi found, running on Pi mode")
else:
logger.error("CHIP_IO NOT found. Running in fake mode")
logger.error("RPi NOT found. Running in fake mode")

debug = config.getboolean("Escape", "debug")
if debug:
logger.error("Running in debug mode, app will restart.")
if chip_complete_mode:
logger.error("This might cause weird behaviour on the CHIP, so please don't do that")
logger.error("This might cause weird behaviour on the Pi, so please don't do that")

logger.error("Starting app complete")


app.run(debug=config.getboolean("Escape", "debug"),host="0.0.0.0",port=config.getint("Escape", "port"),threaded=True)





3 changes: 0 additions & 3 deletions escape.sh

This file was deleted.

3 changes: 2 additions & 1 deletion escape_library.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
import logging
import imp
try:
import CHIP_IO.GPIO as GPIO
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
except Exception:
GPIO = False
import datetime
Expand Down
4 changes: 2 additions & 2 deletions escapemachine.service
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ After=network-online.target

[Service]
PIDFile=/var/run/escapemachine.pid
WorkingDirectory=/usr/local/escapemachine
ExecStart=/bin/bash escape.sh
WorkingDirectory=/home/pi/escapemachine
ExecStart=/usr/bin/python escape.py

[Install]
WantedBy=multi-user.target
Binary file removed static/sounds/ambience_1.mp3
Binary file not shown.
Binary file removed static/sounds/ambience_2.mp3
Binary file not shown.
Binary file removed static/sounds/ambience_3.mp3
Binary file not shown.
Binary file removed static/sounds/ding_effect.ogg
Binary file not shown.

0 comments on commit c1c5aa3

Please sign in to comment.