185 lines
4.1 KiB
Python
185 lines
4.1 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import _thread
|
|
import atexit
|
|
import RPi.GPIO as GPIO
|
|
import os
|
|
from waveloader import WaveLoader
|
|
from rgb import RGBMatrix
|
|
from rgb import RGB
|
|
from subprocess import call
|
|
from time import time
|
|
from random import randint
|
|
|
|
|
|
class Pumpkin:
|
|
def __init__(self, soundpath, GPIOS_RED = [11], GPIOS_GREEN = [12], GPIOS_BLUE = [13], GPIO_TRIGGER = 15, PWM_FREQUENCY = 60):
|
|
self.soundfiles = []
|
|
self.loadWaveFolder(soundpath)
|
|
|
|
if len(self.soundfiles) == 0:
|
|
raise IOError('No audio files found in ' + soundpath + '!')
|
|
|
|
GPIO.setmode(GPIO.BOARD)
|
|
|
|
self.GPIOS_RED = GPIOS_RED
|
|
self.GPIOS_GREEN = GPIOS_GREEN
|
|
self.GPIOS_BLUE = GPIOS_BLUE
|
|
self.GPIO_TRIGGER = GPIO_TRIGGER
|
|
self.GPIO_EVAPORATOR = 0
|
|
self.GPIO_PUMP = 0
|
|
self.GPIO_POWEROFF = 0
|
|
|
|
self.fogRuntimeMax = 3
|
|
|
|
GPIO.setup(self.GPIO_TRIGGER, GPIO.IN)
|
|
|
|
self.rgbControl = RGBMatrix(PWM_FREQUENCY)
|
|
|
|
for r in self.GPIOS_RED:
|
|
self.rgbControl.addRed(r)
|
|
|
|
for g in self.GPIOS_GREEN:
|
|
self.rgbControl.addGreen(g)
|
|
|
|
for b in self.GPIOS_BLUE:
|
|
self.rgbControl.addBlue(b)
|
|
|
|
self.color = RGB(255, 255, 255)
|
|
self.colorBackground = RGB(0, 0, 0)
|
|
self.colorFire = RGB(255, 55, 0)
|
|
|
|
atexit.register(self.cleanup)
|
|
|
|
def __del__(self):
|
|
self.cleanup()
|
|
|
|
def cleanup(self):
|
|
GPIO.cleanup()
|
|
|
|
def enableFog(self, GPIO_EVAPORATOR, GPIO_PUMP, runtimeSecondsMax = 3):
|
|
self.GPIO_EVAPORATOR = GPIO_EVAPORATOR
|
|
self.GPIO_PUMP = GPIO_PUMP
|
|
self.fogRuntimeMax = runtimeSecondsMax
|
|
|
|
if self.GPIO_EVAPORATOR != 0:
|
|
GPIO.setup(self.GPIO_EVAPORATOR, GPIO.OUT)
|
|
|
|
if self.GPIO_PUMP != 0:
|
|
GPIO.setup(self.GPIO_PUMP, GPIO.OUT)
|
|
|
|
self.stopFog()
|
|
|
|
def enablePowerOff(self, GPIO_POWEROFF):
|
|
self.GPIO_POWEROFF = GPIO_POWEROFF
|
|
|
|
if self.GPIO_POWEROFF != 0:
|
|
self.powerSwitch = GPIO.setup(self.GPIO_POWEROFF, GPIO.IN)
|
|
|
|
def loadWaveFolder(self, path):
|
|
if not path.endswith('/'):
|
|
path += '/'
|
|
|
|
files = os.listdir(path)
|
|
|
|
for f in files:
|
|
if f.endswith('.wav'):
|
|
self.soundfiles.append(path + f)
|
|
|
|
def lurk(self):
|
|
if self.isTurnedOff():
|
|
self.poweroff()
|
|
|
|
self.rgbControl.candle(self.colorFire.r, self.colorFire.g, self.colorFire.b, 0.5)
|
|
|
|
def speak(self):
|
|
self.startFog()
|
|
|
|
soundfile = self.soundfiles[randint(0, len(self.soundfiles) - 1)]
|
|
|
|
sound = WaveLoader(soundfile)
|
|
|
|
duration = sound.frameCount / sound.frameRate
|
|
t_now = 0
|
|
|
|
player = _thread.start_new_thread(call, (['aplay', soundfile],))
|
|
t_start = time()
|
|
|
|
while t_now < duration:
|
|
t_now = time() - t_start
|
|
amplitude = sound.getCurrentLevelRealtime(t_now)
|
|
|
|
if amplitude < 0.1:
|
|
red = self.colorBackground.r
|
|
green = self.colorBackground.g
|
|
blue = self.colorBackground.b
|
|
else:
|
|
amplitude = 1
|
|
red = self.color.r * amplitude
|
|
green = self.color.g * amplitude
|
|
blue = self.color.b * amplitude
|
|
|
|
self.rgbControl.setColor(red, green, blue)
|
|
|
|
if t_now > self.fogRuntimeMax:
|
|
self.stopFog()
|
|
|
|
self.stopFog()
|
|
|
|
def startFog(self):
|
|
if self.GPIO_EVAPORATOR != 0:
|
|
GPIO.output(self.GPIO_EVAPORATOR, True)
|
|
|
|
if self.GPIO_PUMP != 0:
|
|
GPIO.output(self.GPIO_PUMP, True)
|
|
|
|
def stopFog(self):
|
|
if self.GPIO_EVAPORATOR != 0:
|
|
GPIO.output(self.GPIO_EVAPORATOR, False)
|
|
|
|
if self.GPIO_PUMP != 0:
|
|
GPIO.output(self.GPIO_PUMP, False)
|
|
|
|
def isTriggered(self):
|
|
return bool(GPIO.input(self.GPIO_TRIGGER))
|
|
|
|
def isTurnedOff(self):
|
|
if self.GPIO_POWEROFF == 0:
|
|
return False
|
|
|
|
return bool(GPIO.input(self.GPIO_POWEROFF))
|
|
|
|
def poweroff(self):
|
|
call(['poweroff'])
|
|
|
|
def setAudioColor(self, red, green, blue):
|
|
self.color = RGB(red, green, blue)
|
|
|
|
def setBackgroundColor(self, red, green, blue):
|
|
self.colorBackground = RGB(red, green, blue)
|
|
|
|
def setFireColor(self, red, green, blue):
|
|
self.colorFire = RGB(red, green, blue)
|
|
|
|
def loadAudioFolder(self, path):
|
|
if os.path.isdir(path):
|
|
if not path.endswith('/'):
|
|
path += '/'
|
|
|
|
for file in os.listdir(path):
|
|
if file.endswith('.wav'):
|
|
audioFiles.append(audioPath + file)
|
|
|
|
@staticmethod
|
|
def findAudioFiles():
|
|
audioFiles = []
|
|
|
|
for home in os.listdir('/home'):
|
|
audioPath = '/home/' + home + '/.config/pumpkin/audio/'
|
|
|
|
if os.path.isdir(audioPath):
|
|
for file in os.listdir(audioPath):
|
|
audioFiles.append(audioPath + file)
|
|
|
|
return audioFiles
|