initial commit, forking from 2020 codebase

This commit is contained in:
jpunkt 2021-10-19 12:10:04 +02:00
commit f8b21a75d7
26 changed files with 1952 additions and 0 deletions

132
.gitignore vendored Normal file
View file

@ -0,0 +1,132 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# Pycharm settings
.idea

1
MANIFEST.in Normal file
View file

@ -0,0 +1 @@
recursive-include pizzactrl/sounds *.wav

2
README.md Normal file
View file

@ -0,0 +1,2 @@
# pizzabox-mc
Python software for controlling a mobile interactive artwork for "Invisible Cities"

5
pizzactrl/__init__.py Normal file
View file

@ -0,0 +1,5 @@
from pkg_resources import resource_filename
__version__ = '0.0.2'
SOUNDS_PATH = resource_filename(__name__, 'sounds/')

100
pizzactrl/fs_names.py Normal file
View file

@ -0,0 +1,100 @@
import os
import logging
from enum import Enum
from uuid import uuid4
from pizzactrl import SOUNDS_PATH
logger = logging.getLogger(__name__)
"""
Paths to files
"""
# Base paths
_STORY_SOUNDS = '/home/pi/sounds/'
_SFX_SOUNDS = 'sounds/'
_REC_FILES = '/home/pi/pizzafiles/'
USB_STICK = _REC_FILES + '.stick'
class FileType(Enum):
REC = 'r'
STORY = 's'
SFX = 'f'
class FileHandle:
"""
Base class for handles on context-specific paths
"""
uuid = None
def __init__(self, name: str, filetype: FileType):
self.name = name
self.filetype = filetype
# Create a uuid and fitting folder if not present
# All RecFiles for this session will be added to this foldere
if FileHandle.uuid is None:
FileHandle.uuid = str(uuid4())
logger.info(f'generated uuid for session: {FileHandle.uuid}')
try:
os.mkdir(_REC_FILES + FileHandle.uuid)
FileHandle.uuid += '/'
except OSError:
FileHandle.uuid = ''
def __str__(self):
"""
Return the file path as a string
"""
return {
FileType.STORY: lambda: (_STORY_SOUNDS + self.name + '.wav'),
FileType.SFX: lambda: (SOUNDS_PATH + self.name
+ '.wav'),
FileType.REC: lambda: (_REC_FILES + FileHandle.uuid + self.name)
}[self.filetype]()
class SfxFile(FileHandle):
"""
Returns the path to a sound-effect file
"""
def __init__(self, name: str):
FileHandle.__init__(self, name, FileType.SFX)
class RecFile(FileHandle):
"""
Returns the path to a recordable file
"""
def __init__(self, name: str):
FileHandle.__init__(self, name, FileType.REC)
class StoryFile(FileHandle):
"""
Returns the path to a storyboard file
"""
def __init__(self, name: str):
FileHandle.__init__(self, name, FileType.STORY)
REC_NAME = RecFile('name.wav')
REC_MY_IBK = RecFile('my_ibk.wav')
REC_PORTRAIT = RecFile('portrait.jpg')
REC_CITY_NAME = RecFile('city_name.wav')
REC_CITY_DESC = RecFile('city_description.wav')
REC_CITY_SOUND = RecFile('city_sound.wav')
REC_DRAW_CITY = RecFile('city_video.h264')
REC_CITY_PHOTO = RecFile('city_drawing.jpg')
SFX_ERROR = SfxFile('error')
SFX_ERROR_DE = SfxFile('error-de')
SFX_ERROR_EN = SfxFile('error-en')
SFX_POST_OK = SfxFile('done')
SFX_SHUTTER = SfxFile('done')
SFX_REC_AUDIO = SfxFile('countdown')
SFX_STOP_REC = SfxFile('done')
SND_SELECT_LANG = StoryFile(name='01')

21
pizzactrl/gpio_pins.py Normal file
View file

@ -0,0 +1,21 @@
# GPIO pin definitions
BTN_BACK_GPIO = 14 # "Back" button (user input)
BTN_FORWARD_GPIO = 18 # "Forward" button (user input)
LED_BACK_BTN = 15 # LED in back-button
LED_FWD_BTN = 23 # LED in forward-button
# LID_SWITCH = 18 # "Lid open" detector switch on front
LED_LAYER = 12 # LED-strip for top layer
LED_BACKLIGHT = 13 # LED-strip for backlight
MOTOR_CTRL_LR = (8, 7, 10) # Motor controller 1 (in1, in2, enable)
MOTOR_CTRL_UPDOWN = (9, 11, 25) # Motor controller 2 (in1, in2, enable)
SCROLL_UPDOWN_SENSORS = (22, 27) # Feed/Direction sensors
SCROLL_UPDOWN_ENDSTOP = 20 # End of Tape
SCROLL_LR_SENSORS = (6, 5) # Feed/Direction sensors
SCROLL_LR_ENDSTOP = 16 # End of Tape

409
pizzactrl/hal.py Normal file
View file

@ -0,0 +1,409 @@
import logging
import functools
from time import sleep
from typing import Any, List
from scipy.io.wavfile import write as writewav
import sounddevice as sd
import soundfile as sf
import numpy as np
from . import gpio_pins
from picamera import PiCamera
from gpiozero import Button, OutputDevice, PWMOutputDevice, PWMLED
logger = logging.getLogger(__name__)
# Constants
VIDEO_RES = (1920, 1080) # Video Resolution
PHOTO_RES = (2592, 1944) # Photo Resolution
AUDIO_REC_SR = 44100 # Audio Recording Samplerate
class Motor:
def __init__(self, in1, in2, enable):
self._in1 = OutputDevice(in1)
self._in2 = OutputDevice(in2)
self._en = PWMOutputDevice(enable)
@property
def direction(self):
return self._in1.value > self._in2.value
@direction.setter
def direction(self, cw=True):
if cw is None:
self._in1.value = self._in2.value = 0
if cw:
self._in1.value = 1
self._in2.value = 0
else:
self._in1.value = 0
self._in2.value = 1
@property
def speed(self):
return self._en.value * (1.0 if self.direction else -1.0)
@speed.setter
def speed(self, speed: float):
"""
Turn on motor. Negative speed = CCW direction
:param speed: float [-1.0 .. 1.0]
"""
if self.speed == speed:
return
if speed == 0:
self.off()
return
if abs(speed) > 1.:
speed = 1. if speed > 0 else -1.
self.direction = speed > 0
self._en.value = abs(speed)
def off(self):
"""
Stop motor
"""
logger.debug(f'motor{self}.off()')
self._en.off()
self.direction = None
class ScrollSensor:
def __init__(self, low_bit: int, high_bit: int, endstop: int):
self._low = Button(low_bit, pull_up=False)
self._high = Button(high_bit, pull_up=False)
self._end = Button(endstop, pull_up=False)
# self._low.when_released = self._callback
# self.direction = 0
# self.count = 0
@property
def is_home(self):
"""
:return: `True` if the endstops are active
"""
return self._high.value and self._end.value
@property
def eot_callback(self):
return self._high.when_pressed
@eot_callback.setter
def eot_callback(self, callback):
logger.debug(f'setting eot_callback={callback}')
self._high.when_pressed = callback
@property
def stop_callback(self):
return self._end.when_pressed
@stop_callback.setter
def stop_callback(self, callback):
logger.debug(f'setting stop_callback={callback}')
self._end.when_pressed = callback
class PizzaHAL:
"""
This class holds a represenation of the pizza box hardware and provides
methods to interact with it.
- lights upper/lower on/off
- motor up-down/left-right speed distance
- scroll up-down/left-right positions
- lid open/closed detectors
- user interface buttons
"""
def __init__(self):
self.btn_forward = Button(gpio_pins.BTN_FORWARD_GPIO)
self.btn_back = Button(gpio_pins.BTN_BACK_GPIO)
self.led_btn_fwd = PWMLED(gpio_pins.LED_FWD_BTN)
self.led_btn_back = PWMLED(gpio_pins.LED_BACK_BTN)
# self.lid_sensor = Button(gpio_pins.LID_SWITCH)
self.ud_sensor = ScrollSensor(*gpio_pins.SCROLL_UPDOWN_SENSORS,
gpio_pins.SCROLL_UPDOWN_ENDSTOP)
self.lr_sensor = ScrollSensor(*gpio_pins.SCROLL_LR_SENSORS,
gpio_pins.SCROLL_LR_ENDSTOP)
self.motor_lr = Motor(*gpio_pins.MOTOR_CTRL_LR)
self.motor_ud = Motor(*gpio_pins.MOTOR_CTRL_UPDOWN)
self.led_layer = PWMOutputDevice(gpio_pins.LED_LAYER)
self.led_backlight = PWMOutputDevice(gpio_pins.LED_BACKLIGHT)
self.camera = None
self.soundcache = {}
self.blocked = False
def blocking(func):
@functools.wraps(func)
def _wrapper(*args, **kwargs):
hal = kwargs.get('hal', None)
if hal is not None:
logger.debug('blocking...')
while hal.blocked:
pass
hal.blocked = True
func(*args, **kwargs)
if hal is not None:
logger.debug('unblocking')
hal.blocked = False
sleep(0.1)
return _wrapper
@blocking
def advance(motor: Motor, sensor: ScrollSensor, speed: float=0.3,
direction: bool=True):
"""
Move the motor controlling the up-down scroll a given distance at a
given speed.
"""
logger.debug(f'advance(motor={motor}, sensor={sensor}, speed={speed},'
f'direction={direction})')
if sensor.is_home and not direction:
logger.debug('home reached, not advancing.')
return
sensor.stop_callback = motor.off
sensor.eot_callback = motor.off
motor.speed = speed if direction else -speed
# Safety catch
sleeptime = abs(5 / (speed * 10))
sleep(sleeptime)
motor.off()
sensor.stop_callback = None
sensor.eot_callback = None
@blocking
def rewind(motor: Motor, sensor: ScrollSensor, direction: bool=True,
max_time: float=13.2):
if sensor.is_home:
return
sensor.eot_callback = motor.off
sensor.stop_callback = None
motor.speed = -0.3 if direction else 0.3
# Safety catch
sleep(max_time)
motor.off()
def turn_off(hal: PizzaHAL):
"""
Rewind the scrolls to starting position
:param hal: The hardware abstraction object
"""
hal.led_btn_back.off()
hal.led_btn_fwd.off()
hal.led_layer.off()
hal.led_backlight.off()
hal.btn_back.when_pressed = None
hal.btn_back.when_held = None
hal.btn_forward.when_pressed = None
hal.btn_forward.when_held = None
hal.motor_ud.off()
hal.motor_lr.off()
def wait_for_input(hal: PizzaHAL=None, go_callback: Any=None,
back_callback: Any=None, **kwargs):
"""
Blink leds on buttons. Wait until the user presses a button, then execute
the appropriate callback
:param hal: The hardware abstraction object
:param go_callback: called when button 'go' is pressed
:param back_callback: called whan button 'back' is pressed
"""
hal.led_btn_fwd.blink(0.3, 0.3, 0.15, 0.15)
hal.led_btn_back.blink(0.3, 0.3, 0.15, 0.15)
hal.blocked = True
hal.btn_forward.when_pressed = \
_wrap_wait_btn(hal=hal, callback=go_callback, **kwargs)
hal.btn_back.when_pressed = \
_wrap_wait_btn(hal=hal, callback=back_callback, **kwargs)
sleep(0.5)
while hal.blocked:
pass
def _wrap_wait_btn(hal: PizzaHAL=None, callback: Any=None, **kwargs):
@functools.wraps(callback)
def wrapper():
hal.blocked = True
if callback is not None:
callback(hal=hal, **kwargs)
hal.btn_forward.when_pressed = None
hal.btn_back.when_pressed = None
hal.led_btn_back.off()
hal.led_btn_fwd.off()
hal.blocked = False
return wrapper
def _fade_led(led_pin: PWMOutputDevice, intensity: float, fade: float = 1.0,
steps: int = 100):
brightness = led_pin.value
step = (intensity - brightness) / float(steps)
wait = fade / float(steps)
if step != 0.:
for i in np.arange(brightness, intensity, step):
led_pin.value = i
sleep(wait)
led_pin.value = intensity
@blocking
def light_layer(hal: PizzaHAL, intensity: float, fade: float = 0.0,
steps: int = 100, **kwargs):
"""
Turn on the light to illuminate the upper scroll
:param hal: The hardware abstraction object
:param fade: float
Default 0, time in seconds to fade in or out
:param intensity: float
Intensity of the light in percent
:param steps: int
How many steps for the fade (default: 10)
"""
if fade > 0.:
_fade_led(hal.led_layer, intensity, fade, steps)
else:
hal.led_layer.value = intensity
@blocking
def backlight(hal: PizzaHAL, intensity: float, fade: float = 0.0,
steps: int = 100, **kwargs):
"""
Turn on the backlight
:param hal: The hardware abstraction object
:param fade: float
Default 0, time in seconds to fade in or out
:param intensity: float
Intensity of the light in percent
:param steps: int
How many steps for the fade (default: 10)
"""
if fade > 0.:
_fade_led(hal.led_backlight, intensity, fade, steps)
else:
hal.led_backlight.value = intensity
@blocking
def play_sound(hal: PizzaHAL, sound: Any, **kwargs):
"""
Play a sound.
:param hal: The hardware abstraction object
:param sound: The sound to be played
"""
# Extract data and sampling rate from file
try:
data, fs = hal.soundcache.get(str(sound), sf.read(str(sound), dtype='float32'))
sd.play(data, fs)
sd.wait() # Wait until file is done playing
except KeyboardInterrupt:
logger.debug('skipped playback')
# sd.stop()
@blocking
def record_sound(hal: PizzaHAL, filename: Any, duration: int,
cache: bool = False, **kwargs):
"""
Record sound using the microphone
:param hal: The hardware abstraction object
:param filename: The path of the file to record to
:param duration: The time to record in seconds
:param cache: `True` to save recording to cache. Default is `False`
"""
myrecording = sd.rec(int(duration * AUDIO_REC_SR),
samplerate=AUDIO_REC_SR,
channels=2)
sd.wait() # Wait until recording is finished
writewav(str(filename), AUDIO_REC_SR, myrecording)
if cache:
hal.soundcache[str(filename)] = (myrecording, AUDIO_REC_SR)
@blocking
def record_video(hal: PizzaHAL, filename: Any, duration: float, **kwargs):
"""
Record video using the camera
:param hal: The hardware abstraction object
:param filename: The path of the file to record to
:param duration: The time to record in seconds
"""
hal.camera.resolution = VIDEO_RES
hal.camera.start_recording(str(filename))
hal.camera.wait_recording(duration)
hal.camera.stop_recording()
@blocking
def take_photo(hal: PizzaHAL, filename: Any, **kwargs):
"""
Take a foto with the camera
:param hal: The hardware abstraction object
:param filename: The path of the filename for the foto
"""
hal.camera.resolution = PHOTO_RES
hal.camera.capture(str(filename))
@blocking
def init_sounds(hal: PizzaHAL, sounds: List):
"""
Load prerecorded Sounds into memory
:param hal:
:param sounds: A list of sound files
"""
if hal.soundcache is None:
hal.soundcache = {}
for sound in sounds:
# Extract data and sampling rate from file
data, fs = sf.read(str(sound), dtype='float32')
hal.soundcache[str(sound)] = (data, fs)
@blocking
def init_camera(hal: PizzaHAL):
if hal.camera is None:
hal.camera = PiCamera()

52
pizzactrl/main.py Normal file
View file

@ -0,0 +1,52 @@
import sys
import click
import logging
from .statemachine import Statemachine, State
from . import sb_de, sb_en
logger = logging.getLogger('pizzactrl.main')
@click.command()
@click.option('--move', is_flag=True)
@click.option('--test', is_flag=True, default=False)
@click.option('--debug', is_flag=True, default=False)
def main(move: bool=False, test: bool=False, debug: bool=False):
if debug or test:
logging.basicConfig(level=logging.DEBUG, stream=sys.stdout)
else:
logging.basicConfig(level=logging.INFO, stream=sys.stdout)
sm = Statemachine(story_de=sb_de.STORYBOARD,
story_en=sb_en.STORYBOARD,
move=move)
sm.test = test
exitcode = 0
try:
sm.run()
except Exception:
logger.exception('An Error occurred while running the statemachine')
exitcode = 1
finally:
if sm.state is State.ERROR:
exitcode = 2
del sm
sys.exit(exitcode)
@click.command()
@click.option('--time', help='Safety deactivation time', type=float,
default=13.2)
def rewind(time: float):
from . import hal
pizza = hal.PizzaHAL()
hal.rewind(pizza.motor_ud, pizza.ud_sensor, max_time=time)
hal.turn_off(pizza)
del pizza
if __name__ == '__main__':
main()

255
pizzactrl/sb_de.py Normal file
View file

@ -0,0 +1,255 @@
from pizzactrl import storyboard, fs_names
STORYBOARD = [
storyboard.Chapter( # X1
# storyboard.Do(storyboard.Activity.ADVANCE_UP),
storyboard.Do(storyboard.Activity.LIGHT_BACK, # Bild 1
intensity=1.0, fade=1.0)
),
storyboard.Chapter( # X2
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('03de')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 2
),
storyboard.Chapter( # X3
storyboard.Do(storyboard.Activity.LIGHT_BACK, # Bild 1
intensity=1.0, fade=1.0),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('04de')),
storyboard.Do(storyboard.Activity.ADVANCE_UP), # Bild 3
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('05de')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('06de')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('07de')),
storyboard.Do(storyboard.Activity.ADVANCE_UP), # Bild 4
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('08de')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('09de')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0.0),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.ADVANCE_UP), # Bild 5
),
storyboard.Chapter( # X4
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1.0),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('10de')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('11de')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_REC_AUDIO),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('12de')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_REC_AUDIO),
storyboard.Do(storyboard.Activity.RECORD_SOUND,
filename=fs_names.REC_NAME,
duration=7.0,
cache=True),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_STOP_REC),
),
storyboard.Chapter( # X5
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('13de')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.REC_NAME),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('14de')),
storyboard.Do(storyboard.Activity.ADVANCE_UP), # Bild 6
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('15de')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_REC_AUDIO),
storyboard.Do(storyboard.Activity.RECORD_SOUND,
filename=fs_names.REC_MY_IBK,
duration=60.0),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_STOP_REC),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 7
),
storyboard.Chapter( # X6
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('16de')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0.0),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_REC_AUDIO),
storyboard.Do(storyboard.Activity.TAKE_PHOTO,
filename=fs_names.REC_PORTRAIT),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_SHUTTER)
),
storyboard.Chapter( # X7
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('17de')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.ADVANCE_UP)
),
storyboard.Chapter( # X8
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('18de')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1.0, fade=2.0),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('19de')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('20de')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0., fade=2.0),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('21de')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 9
),
storyboard.Chapter( # X9
storyboard.Do(storyboard.Activity.LIGHT_LAYER,
intensity=1., fade=0.5),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1., fade=0.5),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('22de')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('23de')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('24de')),
storyboard.Do(storyboard.Activity.LIGHT_LAYER,
intensity=0., fade=1.),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0., fade=1.),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('25de')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 10
),
storyboard.Chapter( # X10
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1., fade=1.),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('26de')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('27de')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('28de')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0., fade=1.),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('29de')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 11
),
storyboard.Chapter( # X11
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1., fade=1.),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('30de')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('31de')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0., fade=1.),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('32de')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 12
),
storyboard.Chapter( # X12
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1., fade=.5),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('33de')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 13
),
storyboard.Chapter( # X13
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('34de')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0., fade=1.),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_REC_AUDIO),
storyboard.Do(storyboard.Activity.RECORD_SOUND,
filename=fs_names.REC_CITY_NAME,
duration=7.0),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_STOP_REC),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 14
),
storyboard.Chapter( # X14
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1., fade=1.),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('35de')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_REC_AUDIO),
storyboard.Do(storyboard.Activity.RECORD_SOUND,
filename=fs_names.REC_CITY_DESC,
duration=60.0),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_STOP_REC),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 15
),
storyboard.Chapter( # X15
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('36de')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_REC_AUDIO),
storyboard.Do(storyboard.Activity.RECORD_SOUND,
filename=fs_names.REC_CITY_SOUND,
duration=60.0),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_STOP_REC),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0., fade=1.),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 16
),
storyboard.Chapter( # X16
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('37de')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1., fade=1.),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('38de')),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 17
),
storyboard.Chapter( # X17
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('39de')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0., fade=1.),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_REC_AUDIO),
storyboard.Do(storyboard.Activity.RECORD_VIDEO,
filename=fs_names.REC_DRAW_CITY,
duration=60.0),
storyboard.Do(storyboard.Activity.TAKE_PHOTO,
filename=fs_names.REC_CITY_PHOTO),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_STOP_REC),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 18
),
storyboard.Chapter( # X18
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1., fade=1.),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('40de')),
storyboard.Do(storyboard.Activity.ADVANCE_UP), # Bild 19
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('41de')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0., fade=2.)
)
]

119
pizzactrl/sb_de_alt.py Normal file
View file

@ -0,0 +1,119 @@
from pizzactrl import storyboard, fs_names
STORYBOARD = [
storyboard.Chapter( # X2
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 2
),
storyboard.Chapter( # X3
storyboard.Do(storyboard.Activity.ADVANCE_UP), # Bild 3
storyboard.Do(storyboard.Activity.ADVANCE_UP), # Bild 4
storyboard.Do(storyboard.Activity.ADVANCE_UP), # Bild 5
),
storyboard.Chapter( # X4
storyboard.Do(storyboard.Activity.ADVANCE_UP), # Bild 6
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 7
),
storyboard.Chapter( # X6
storyboard.Do(storyboard.Activity.ADVANCE_UP),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 9
),
storyboard.Chapter( # X9
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 10
),
storyboard.Chapter( # X10
storyboard.Do(storyboard.Activity.ADVANCE_UP), # Bild 11
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 12
),
storyboard.Chapter( # X12
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1., fade=.5),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('33de')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 13
),
storyboard.Chapter( # X13
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('34de')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0., fade=1.),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_REC_AUDIO),
storyboard.Do(storyboard.Activity.RECORD_SOUND,
filename=fs_names.REC_CITY_NAME,
duration=7.0),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_STOP_REC),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 14
),
storyboard.Chapter( # X14
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1., fade=1.),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('35de')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_REC_AUDIO),
storyboard.Do(storyboard.Activity.RECORD_SOUND,
filename=fs_names.REC_CITY_DESC,
duration=60.0),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_STOP_REC),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 15
),
storyboard.Chapter( # X15
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('36de')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_REC_AUDIO),
storyboard.Do(storyboard.Activity.RECORD_SOUND,
filename=fs_names.REC_CITY_SOUND,
duration=60.0),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_STOP_REC),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0., fade=1.),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 16
),
storyboard.Chapter( # X16
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('37de')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1., fade=1.),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('38de')),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 17
),
storyboard.Chapter( # X17
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('39de')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0., fade=1.),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_REC_AUDIO),
storyboard.Do(storyboard.Activity.RECORD_VIDEO,
filename=fs_names.REC_DRAW_CITY,
duration=60.0),
storyboard.Do(storyboard.Activity.TAKE_PHOTO,
filename=fs_names.REC_CITY_PHOTO),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_STOP_REC),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 18
),
storyboard.Chapter( # X18
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1., fade=1.),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('40de')),
storyboard.Do(storyboard.Activity.ADVANCE_UP), # Bild 19
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('41de')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0., fade=2.)
)
]

248
pizzactrl/sb_dummy.py Normal file
View file

@ -0,0 +1,248 @@
from pizzactrl import storyboard, fs_names
STORYBOARD = [
storyboard.Chapter(
# storyboard.Do(storyboard.Activity.ADVANCE_UP),
storyboard.Do(storyboard.Activity.LIGHT_BACK, # Bild 1
intensity=1.0, fade=1.0)
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 2
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.ADVANCE_UP), # Bild 3
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.ADVANCE_UP), # Bild 4
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0.0),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.ADVANCE_UP), # Bild 5
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1.0),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_REC_AUDIO),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_REC_AUDIO),
storyboard.Do(storyboard.Activity.RECORD_SOUND,
filename=fs_names.REC_NAME,
duration=7.0,
cache=True),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_STOP_REC),
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.REC_NAME),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.ADVANCE_UP), # Bild 6
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_REC_AUDIO),
storyboard.Do(storyboard.Activity.RECORD_SOUND,
filename=fs_names.REC_CITY_DESC,
duration=60.0),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_STOP_REC),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 7
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0.0),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.TAKE_PHOTO,
filename=fs_names.REC_PORTRAIT),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_SHUTTER)
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.ADVANCE_UP)
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1.0),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0., fade=2.0),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 9
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.LIGHT_LAYER,
intensity=1., fade=0.5),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1., fade=0.5),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.LIGHT_LAYER,
intensity=0., fade=1.),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0., fade=1.),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 10
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1., fade=1.),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0., fade=1.),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 11
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1., fade=1.),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0., fade=1.),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 12
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1., fade=.5),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 13
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0., fade=1.),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_REC_AUDIO),
storyboard.Do(storyboard.Activity.RECORD_SOUND,
filename=fs_names.REC_CITY_NAME,
duration=7.0),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_STOP_REC),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 14
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1., fade=1.),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_REC_AUDIO),
storyboard.Do(storyboard.Activity.RECORD_SOUND,
filename=fs_names.REC_CITY_DESC,
duration=60.0),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_STOP_REC),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 15
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_REC_AUDIO),
storyboard.Do(storyboard.Activity.RECORD_SOUND,
filename=fs_names.REC_CITY_DESC,
duration=60.0),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_STOP_REC),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0., fade=1.),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 16
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1., fade=1.),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 17
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0., fade=1.),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_REC_AUDIO),
storyboard.Do(storyboard.Activity.RECORD_VIDEO,
filename=fs_names.REC_DRAW_CITY,
duration=60.0),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_STOP_REC),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 18
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1., fade=1.),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.ADVANCE_UP), # Bild 19
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('01dummy')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0., fade=2.)
)
]

254
pizzactrl/sb_en.py Normal file
View file

@ -0,0 +1,254 @@
from pizzactrl import storyboard, fs_names
STORYBOARD = [
storyboard.Chapter(
# storyboard.Do(storyboard.Activity.ADVANCE_UP),
storyboard.Do(storyboard.Activity.LIGHT_BACK, # Bild 1
intensity=1.0, fade=1.0)
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('03en')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 2
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.LIGHT_BACK, # Bild 1
intensity=1.0, fade=1.0),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('04en')),
storyboard.Do(storyboard.Activity.ADVANCE_UP), # Bild 3
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('05en')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('06en')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('07en')),
storyboard.Do(storyboard.Activity.ADVANCE_UP), # Bild 4
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('08en')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('09en')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0.0),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.ADVANCE_UP), # Bild 5
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1.0),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('10en')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('11en')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_REC_AUDIO),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('12en')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_REC_AUDIO),
storyboard.Do(storyboard.Activity.RECORD_SOUND,
filename=fs_names.REC_NAME,
duration=7.0,
cache=True),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_STOP_REC),
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('13en')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.REC_NAME),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('14en')),
storyboard.Do(storyboard.Activity.ADVANCE_UP), # Bild 6
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('15en')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_REC_AUDIO),
storyboard.Do(storyboard.Activity.RECORD_SOUND,
filename=fs_names.REC_MY_IBK,
duration=60.0),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_STOP_REC),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 7
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('16en')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0.0),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_REC_AUDIO),
storyboard.Do(storyboard.Activity.TAKE_PHOTO,
filename=fs_names.REC_PORTRAIT),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_SHUTTER)
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('17en')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.ADVANCE_UP)
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('18en')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1.0, fade=2.0),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('19en')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('20en')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0., fade=2.0),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('21en')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 9
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.LIGHT_LAYER,
intensity=1., fade=0.5),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1., fade=0.5),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('22en')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('23en')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('24en')),
storyboard.Do(storyboard.Activity.LIGHT_LAYER,
intensity=0., fade=1.),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0., fade=1.),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('25en')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 10
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1., fade=1.),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('26en')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('27en')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('28en')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0., fade=1.),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('29en')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 11
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1., fade=1.),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('30en')),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('31en')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0., fade=1.),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('32en')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 12
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1., fade=.5),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('33en')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 13
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('34en')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0., fade=1.),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_REC_AUDIO),
storyboard.Do(storyboard.Activity.RECORD_SOUND,
filename=fs_names.REC_CITY_NAME,
duration=7.0),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_STOP_REC),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 14
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1., fade=1.),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('35en')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_REC_AUDIO),
storyboard.Do(storyboard.Activity.RECORD_SOUND,
filename=fs_names.REC_CITY_DESC,
duration=60.0),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_STOP_REC),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 15
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('36en')),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_REC_AUDIO),
storyboard.Do(storyboard.Activity.RECORD_SOUND,
filename=fs_names.REC_CITY_SOUND,
duration=60.0),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_STOP_REC),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0., fade=1.),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 16
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('37en')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1., fade=1.),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('38en')),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 17
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('39en')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0., fade=1.),
storyboard.Do(storyboard.Activity.WAIT_FOR_INPUT),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_REC_AUDIO),
storyboard.Do(storyboard.Activity.RECORD_VIDEO,
filename=fs_names.REC_DRAW_CITY,
duration=60.0),
storyboard.Do(storyboard.Activity.TAKE_PHOTO,
filename=fs_names.REC_CITY_PHOTO),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.SFX_STOP_REC),
storyboard.Do(storyboard.Activity.ADVANCE_UP) # Bild 18
),
storyboard.Chapter(
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=1., fade=1.),
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('40en')),
storyboard.Do(storyboard.Activity.ADVANCE_UP), # Bild 19
storyboard.Do(storyboard.Activity.PLAY_SOUND,
sound=fs_names.StoryFile('41en')),
storyboard.Do(storyboard.Activity.LIGHT_BACK,
intensity=0., fade=2.)
)
]

View file

Binary file not shown.

BIN
pizzactrl/sounds/done.wav Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
pizzactrl/sounds/error.wav Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
pizzactrl/sounds/stop.wav Normal file

Binary file not shown.

234
pizzactrl/statemachine.py Normal file
View file

@ -0,0 +1,234 @@
import logging
import os.path
import threading
from typing import Any
from time import sleep
from enum import Enum, auto
from pizzactrl import fs_names, sb_dummy, sb_de_alt
from .storyboard import Activity
from .hal import play_sound, take_photo, record_video, record_sound, turn_off, \
PizzaHAL, init_camera, init_sounds, wait_for_input, \
light_layer, backlight, advance, rewind
logger = logging.getLogger(__name__)
class State(Enum):
POWER_ON = auto()
POST = auto()
IDLE_START = auto()
PLAY = auto()
PAUSE = auto()
IDLE_END = auto()
SHUTDOWN = auto()
ERROR = -1
class Language(Enum):
NOT_SET = auto()
DE = auto()
EN = auto()
def load_sounds():
"""
Load all prerecorded Sounds from the cache
:returns a list of sound file names
"""
soundcache = [
fs_names.SFX_SHUTTER,
fs_names.SFX_ERROR,
fs_names.SFX_POST_OK,
fs_names.SND_SELECT_LANG
]
return soundcache
class Statemachine:
def __init__(self,
story_de: Any=None,
story_en: Any=None,
move: bool = False):
self.state = State.POWER_ON
self.hal = PizzaHAL()
self.story = None
self.story_de = story_de
self.story_en = story_en
self.alt = False
self.lang = Language.NOT_SET
self.move = move
self.test = False
def run(self):
logger.debug(f'Run(state={self.state})')
choice = {
State.POWER_ON: self._power_on,
State.POST: self._post,
State.IDLE_START: self._idle_start,
State.PLAY: self._play,
State.IDLE_END: self._idle_end
}
while (self.state is not State.ERROR) and \
(self.state is not State.SHUTDOWN):
choice[self.state]()
if self.state is State.ERROR:
logger.debug('An error occurred. Trying to notify user...')
if self.lang is Language.DE:
play_sound(self.hal, fs_names.SFX_ERROR_DE)
elif self.lang is Language.EN:
play_sound(self.hal, fs_names.SFX_ERROR_EN)
else:
play_sound(self.hal, fs_names.SFX_ERROR)
self._shutdown()
def _lang_de(self, **kwargs):
logger.info(f'select language german')
self.lang = Language.DE
self.story = self.story_de
def _lang_en(self, **kwargs):
logger.info(f'select language english')
self.lang = Language.EN
self.story = self.story_en
def _power_on(self):
"""
Initialize hal callbacks, load sounds
"""
logger.debug(f'power on')
# self.hal.lid_sensor.when_pressed = self._lid_open
# self.hal.lid_sensor.when_released = self._lid_closed
init_sounds(self.hal, load_sounds())
init_camera(self.hal)
self.state = State.POST
def _post(self):
"""
Power on self test.
"""
logger.debug(f'post')
# check scroll positions and rewind if necessary
turn_off(self.hal)
rewind(self.hal.motor_ud, self.hal.ud_sensor)
if not os.path.exists(fs_names.USB_STICK):
logger.warning('USB-Stick not found.')
self.state = State.ERROR
return
# play a sound if everything is alright
play_sound(self.hal, fs_names.SFX_POST_OK)
# Callback for start when blue button is held
self.hal.btn_forward.when_deactivated = self._start
self.state = State.IDLE_START
def _idle_start(self):
"""
Device is armed. Wait for user to hold blue button to start
"""
pass
def _start(self):
"""
Start playback when blue button is held for 3s
"""
t = 0.
while (self.hal.btn_forward.inactive_time < 3.0) and \
not self.hal.btn_forward.is_active:
t = self.hal.btn_forward.inactive_time
if t > 3.0:
self.hal.btn_forward.when_deactivated = None
if not self.hal.btn_back.is_active:
self.alt = True
self.state = State.PLAY
def _play(self):
"""
Run the storyboard
"""
logger.debug(f'play')
if not self.alt:
play_sound(self.hal, fs_names.SND_SELECT_LANG)
wait_for_input(self.hal,
self._lang_de,
self._lang_en)
sleep(0.5)
else:
self.story = sb_de_alt.STORYBOARD
try:
if self.story is None:
self.story = sb_dummy.STORYBOARD
except AttributeError:
pass
finally:
if self.test:
self.story = sb_dummy.STORYBOARD
for chapter in iter(self.story):
logger.debug(f'playing chapter {chapter}')
while chapter.hasnext():
act = next(chapter)
logger.debug(f'next activity {act.activity}')
if act.activity is Activity.WAIT_FOR_INPUT:
wait_for_input(hal=self.hal,
go_callback=chapter.mobilize,
back_callback=chapter.rewind)
elif act.activity is Activity.ADVANCE_UP:
if chapter.move and self.move:
logger.debug(
f'advance{advance}({self.hal.motor_ud}, '
f'{self.hal.ud_sensor})')
advance(motor=self.hal.motor_ud,
sensor=self.hal.ud_sensor)
elif not self.move:
play_sound(self.hal, fs_names.StoryFile('stop'))
else:
try:
{
Activity.PLAY_SOUND: play_sound,
Activity.RECORD_SOUND: record_sound,
Activity.RECORD_VIDEO: record_video,
Activity.TAKE_PHOTO: take_photo,
Activity.LIGHT_LAYER: light_layer,
Activity.LIGHT_BACK: backlight,
# Activity.ADVANCE_UP: noop
}[act.activity](self.hal, **act.values)
except KeyError:
logger.exception('Caught KeyError, ignoring...')
pass
self.state = State.IDLE_END
def _idle_end(self):
"""
Initialize shutdown
"""
if self.move:
rewind(self.hal.motor_ud, self.hal.ud_sensor)
self.state = State.SHUTDOWN
def _shutdown(self):
"""
Clean up, end execution
"""
logger.debug('shutdown')
turn_off(self.hal)
del self.hal

57
pizzactrl/storyboard.py Normal file
View file

@ -0,0 +1,57 @@
from enum import Enum, auto
class Activity(Enum):
WAIT_FOR_INPUT = {'steps': 0}
PLAY_SOUND = {'sound': None}
RECORD_SOUND = {'duration': 0.0, 'filename': '', 'cache': False}
RECORD_VIDEO = {'duration': 0.0, 'filename': ''}
TAKE_PHOTO = {'filename': ''}
ADVANCE_UP = {'speed': 0.3, 'direction': True}
LIGHT_LAYER = {'intensity': 1.0, 'fade': 0.0, 'layer': True}
LIGHT_BACK = {'intensity': 1.0, 'fade': 0.0}
class Do:
def __init__(self, activity: Activity, **kwargs):
self.activity = activity
self.values = {}
for key, value in self.activity.value.items():
self.values[key] = kwargs.get(key, value)
class Chapter:
"""
A logical storyboard entity, which can be replayed (rewind to start).
Keeps track of advanced steps on the scrolls.
"""
def __init__(self, *activities):
self.activities = activities
self.pos = 0
self.move = True
self.move_ud = 0
def __iter__(self):
return self
def __next__(self):
if self.pos >= len(self.activities):
raise StopIteration
act = self.activities[self.pos]
if act.activity is Activity.ADVANCE_UP:
self.move_ud += 1
self.pos += 1
return act
def hasnext(self):
return self.pos < len(self.activities)
def rewind(self, **kwargs):
self.move = False
self.move_ud = 0
self.pos = 0
def mobilize(self, **kwargs):
self.move = True

7
requirements.txt Normal file
View file

@ -0,0 +1,7 @@
numpy
gpiozero
picamera
click
sounddevice
soundfile
scipy

2
setup.cfg Normal file
View file

@ -0,0 +1,2 @@
[metadata]
description-file = README.md

54
setup.py Normal file
View file

@ -0,0 +1,54 @@
import re
import ast
import scipy
import wave
import click
import gpiozero
import picamera
import pyaudio as pyaudio
import pydub
import sounddevice as sounddevice
import soundfile as soundfile
from setuptools import setup
_version_re = re.compile(r'__version__\s+=\s+(.*)')
with open('pizzactrl/__init__.py', 'rb') as f:
version = str(ast.literal_eval(_version_re.search(
f.read().decode('utf-8')).group(1)))
setup(
name='raspibox-mc',
version=version,
description='raspberry pi controller for sound, light and motors',
url='https://github.com/jpunkt/pizzabox-mc.git',
author='jpunkt',
author_email='johannes@arg-art.org',
platforms='any',
packages=[
'pizzactrl',
'pizzactrl.sounds'
],
install_requires=[
'gpiozero',
'picamera',
'click',
'sounddevice',
'soundfile',
'scipy'
],
entry_points='''
[console_scripts]
pizzabox=pizzactrl.main:main
pizza-rewind=pizzactrl.main:rewind
''',
include_package_data=True
)