|
- import subprocess
- import sys, inspect, os
-
- import wiringpi
- import time
- from datetime import datetime
- from time import sleep
-
- import lirc
- import random
- import mpd
-
- from pyudmx import pyudmx
-
- import talkey
-
- # GPIO
- pin_kugel = 2
- pin_sun = 4
- pin_pir = 0
- pin_door = 11
-
-
-
- dmxScenes = {
- "fadecolors":[255,255,255,255,255,192],
- "plain-red":[255,255,0,0,0,0],
- "strobe":[190,255,255,255,0,0],
- "nini":[120,0,255,255,0,224],
- "black":[0,0,0,0,0,0]
- }
-
- bye_sayings = [
- "Goodbye!",
- "Bye!",
- "Bye bye!",
- "See you!",
- #"Ciao!",
- "Have a nice day!",
- "Thank's for using!",
- #"I'm off!",
- "Take it easy!",
- "I look forward to our next meeting!",
- "Take care!",
- "Catch you later!",
- "Peace!"
- ]
-
- dmxUserScenes = [
- [255,255,255,255,255,192],
- [255,0,180,180,0,0],
- [255,255,0,0,0,0],
- [255,0,255,0,0,0],
- [255,0,0,255,0,0],
- [190,255,255,255,0,0],
- [120,0,255,255,0,224]
- ]
-
- def setDmxScene(scene):
- cv = [0 for v in range(0, 512)]
- errorcode = [240,255,0,0,0,0]
- for index, val in enumerate(dmxScenes.get(scene,errorcode)):
- cv[index] = val
- dev.send_multi_value(1, cv)
-
-
- def setUserDmxScene():
- global dmxScene
- if dmxScene < len(dmxUserScenes)-1:
- dmxScene += 1
- else:
- dmxScene = 0
- cv = [0 for v in range(0, 512)]
- for index, val in enumerate(dmxUserScenes[dmxScene]):
- cv[index] = val
- dev.send_multi_value(1, cv)
-
-
-
- def setKugel(state):
- if state == 'on':
- wiringpi.digitalWrite(pin_kugel, 0)
- if state == 'off':
- wiringpi.digitalWrite(pin_kugel, 1)
-
- def setSun(state):
- if state == 'off':
- wiringpi.digitalWrite(pin_sun, 0)
- if state == 'on':
- wiringpi.digitalWrite(pin_sun, 1)
-
-
-
- def startMusic(playlist, single=False, shuffle=True, repeat=True):
- try:
- client.clear() # clear playlist
- except Exception:
- client.connect("localhost", 6600)
- client.clear() # clear playlist
-
- client.add(playlist) # add file/directory to playlist
- if shuffle:
- client.shuffle() # shuffle playlist
- if repeat:
- client.repeat(1) # set playback mode repeat
- else:
- client.repeat(0) # set playback mode repeat
- if single:
- client.repeat(0) # set playback mode repeat
- client.single(1) # set playback mode single
- else:
- client.single(0) # set playback mode single
- client.setvol(80)# set volume
- client.play() # play
-
- def stopMusic():
- try:
- client.stop()
- except Exception:
- client.connect("localhost", 6600)
- client.stop()
-
- def muteMusic():
- global uservolume
- if getMpdVolume() != 0: # if not muted
- setMpdVolume(0)
- else:
- setMpdVolume(uservolume)
-
-
- def changeVolume(change=5):
- global uservolume
- global volume
- newvol = uservolume + change
- if newvol > 100:
- newvol = 100
- if newvol < 0:
- newvol = 0
-
- try:
- client.setvol(newvol)
- except Exception:
- client.connect("localhost", 6600)
- client.setvol(newvol)
- uservolume = newvol
- volume = newvol
-
-
- def setMode(string):
- global mode
- global inUse
- mode = string
- if mode == "off":
- inUse = False
-
- def setDiscoMode():
- setKugel('on')
- setDmxScene('fadecolors')
- setUserDmxScene()
- sleep(0.3)
- setSun('off')
- setMode('disco')
-
- def getMpdVolume():
- try:
- vol = int(client.status()['volume'])
- except Exception:
- client.connect("localhost", 6600)
- vol = int(client.status()['volume'])
- if vol != 0: #only if not muted
- global uservolume
- uservolume = vol
- return vol
-
-
- def setMpdVolume(vol):
- try:
- client.setvol(vol)
- except Exception:
- client.connect("localhost", 6600)
- client.setvol(vol)
- if vol != 0: #only if not muted
- global uservolume
- uservolume = vol
- return True
-
-
- def getTrackInfo():
- try:
- currentsong = client.currentsong()
- except Exception:
- client.connect("localhost", 6600)
- currentsong = client.currentsong()
- print(currentsong)
-
- volume = getMpdVolume()
-
- setMpdVolume(10)
- try:
- tts.say(currentsong['artist'] + ', ' + currentsong['title'])
- except Exception:
- tts.say('Willkommen am Discoklo!', 'de')
- setMpdVolume(volume)
-
- def tour():
- tts.say("Welcome! To the world of tomorrow!", "en")
- sleep(0.3)
- tts.say("Press 1 for nice electronic music", "en")
- sleep(0.3)
- tts.say("Press 2 for hard electronic music", "en")
- sleep(0.3)
- tts.say("Press 3 for HGichT", "en")
- sleep(0.3)
- tts.say("Press 4 for a good laugh", "en")
- sleep(0.3)
- tts.say("Press 5 for more music", "en")
- sleep(0.3)
-
-
- def setWorkingMode():
- setSun('on')
- sleep(0.3)
- setKugel('off')
- setDmxScene('black')
- setMode('work')
-
- def startTimeoutCountdown():
- global lastUsed
- global inUse
- tts.say('Timeout in')
- countdown = [5,4,3,2,1] #10,9,8,7,6,
- for sec in countdown:
- tts.say(str(sec))
- sleep(0.5)
- remotesignal = lirc.nextcode()
- if wiringpi.digitalRead(pin_pir) == 1 or remotesignal:
- lastUsed = time.time()
- tts.say('Timeout cancelled!')
- inUse = True
- toilet = lirc.nextcode()
- break
-
- if not inUse:
- tts.say('Shutting down now.', 'en')
- closeService()
-
- def closeService(sleepsecs=0):
- setSun('off')
- sleep(0.3)
- setKugel('off')
- setDmxScene('black')
-
- for x in range(0, 20):
- changeVolume(-5)
- sleep(0.1)
- stopMusic()
- setMode('off')
- sleep(sleepsecs)
-
- def initService():
- startMusic('0', True) # start intro music
- setDiscoMode()
- global volume
- global defaultvolume
- global uservolume
- try:
- client.setvol(defaultvolume)
- except Exception:
- client.connect("localhost", 6600)
- client.setvol(defaultvolume)
- volume = defaultvolume
- uservolume = defaultvolume
-
- global starttime
- starttime = time.time()
-
-
-
- def say(text, lang="en"):
- originalvol = getMpdVolume()
- setMpdVolume(10)
- tts.say(text, lang)
- setMpdVolume(originalvol)
-
- def setOnOff():
- global mode
- stopMusic()
- if mode is not 'work':
- setWorkingMode()
- else:
- initService()
-
- def doorShutdown():
- tts.say(random.choice(bye_sayings), "en")
- closeService(4) # sleep to give pir sensor some time
-
- def bootstrap():
- wiringpi.wiringPiSetup()
- wiringpi.pinMode(pin_kugel, 1) # set Relay Disokugel mode to OUTPUT
- wiringpi.pinMode(pin_door, 0) # set Circuit Door mode to INPUT
- wiringpi.pinMode(pin_sun, 1) # set Relay Sun mode to OUTPUT # TODO: Set pin!
- wiringpi.pinMode(pin_pir, 0) # set PIR Sensor mode to INPUT
-
- def timestamp(stamp=time.time()):
- return datetime.fromtimestamp(stamp).strftime('%Y-%m-%d %H:%M:%S')
-
-
-
- dmxScene = 0
- bootstrap()
- dev = pyudmx.uDMXDevice()
- dev.open()
-
- client = mpd.MPDClient()
- client.connect("localhost", 6600)
-
- tts = talkey.Talkey(
- preferred_languages=['en'],
- engine_preference=['pico'],
- )
-
-
-
- lirc.init("disco", "~/discobert/lircrc", blocking=False)
-
- starttime = time.time() # helper for doorshutdown
- lastUsed = time.time() # helper for timeout
- inUse = False # is toilet in use?
- inUseBefore = False # helper to check statechanges
- mode = "off" # can be: disco, work, off
- timeout = 2 * 60 - 10 # timeout since last user interaction
- defaultvolume = 90 # Volume when user enters the toilet
- volume = 90 # Global for actual volume
- uservolume = 90 # Global for user volume (ignores mute state)
-
- setSun('off')
-
- print(timestamp(), "Ready!")
-
-
-
-
- # Main event loop ...
- while True:
- sleep(0.25)
- pirstate = wiringpi.digitalRead(pin_pir)
- doorstate = wiringpi.digitalRead(pin_door)
- #print('pirstate: ', pirstate)
-
- # 0 => door closed
- # 1 => door open
- if doorstate == 1:
- if (time.time() > (starttime + 15) and inUse == True):
- doorShutdown()
- inUseBefore = False # Pfusch pfusch!
-
-
- if pirstate == 1:
- lastUsed = time.time()
- inUse = True
- else:
- if(time.time() > lastUsed + timeout):
- inUse = False
-
-
-
- remotesignal = lirc.nextcode()
- if remotesignal:
- lastUsed = time.time() # user is active!
- inUse = True
- for code in remotesignal:
- print('received code:', code)
- if(code == "mode_disco"):
- setDiscoMode()
- if(code == "mode_work"):
- setWorkingMode()
- if(code == "mode_power"):
- setOnOff()
- #if(code == "mode_dmx_next"):
-
- if(code == "mode_music_play_1"):
- startMusic('1')
- if(code == "mode_music_play_2"):
- startMusic('2')
- if(code == "mode_music_play_3"):
- startMusic('3')
- if(code == "mode_music_play_4"):
- startMusic('4')
- if(code == "mode_music_play_5"):
- startMusic('5')
- if(code == "mode_play_fm4"):
- startMusic('http://185.85.29.141:8000')
- if(code == "mode_play_oe1"):
- startMusic('http://185.85.29.142:8000')
- if(code == "mode_music_stop"):
- stopMusic()
- if(code == "mode_music_mute"):
- muteMusic()
- if(code == "mode_volume_up"):
- changeVolume(5)
- if(code == "mode_volume_down"):
- changeVolume(-5)
- if(code == "mode_music_info"):
- getTrackInfo()
- if(code == "mode_record"):
- say("I'm sorry, I'm afraid I can't do that!")
- if(code == "mode_home"):
- tour()
-
-
-
- if(inUseBefore != inUse):
- print(timestamp(), "State change inUse:", inUseBefore, inUse)
- if inUse:
- initService()
- else:
- startTimeoutCountdown()
- inUseBefore = inUse
-
-
- lirc.deinit() # Clean up lirc
-
- dev.close()
|