-
-
Save JeffersGlass/b4c5d59578f6d7db972cd448dca0891f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from gpiozero import Servo, PWMLED, MotionSensor | |
from time import sleep | |
import requests | |
from datetime import datetime | |
from dateutil import tz | |
import simpleaudio | |
import glob | |
from random import randint | |
class PumpkinPi(): | |
def __init__(self, eyes, eyebrows): | |
self.leftEye = PWMLED(eyes[0], frequency=5000) | |
self.rightEye = PWMLED(eyes[1], frequency=5000) | |
self.eyes = [self.leftEye, self.rightEye] | |
self.leftEyebrow = Servo(eyebrows[0]) | |
self.rightEyebrow = Servo(eyebrows[1]) | |
self.eyebrows = [self.leftEyebrow, self.rightEyebrow] | |
self.setEyebrowPosition(0) | |
self.setEyeBrightness(0) | |
self.neutralEyeValue = 0.0 | |
self.sunset = None | |
self.seenSunsetToday = False | |
self.ms = MotionSensor(19) | |
jokes = sorted(glob.glob('./jokes/joke*.wav')) | |
punchlines = sorted(glob.glob('./jokes/punch*.wav')) | |
self.jokeList = list(zip(jokes, punchlines)) | |
print (self.jokeList) | |
#Takes a value between 0 and 1.0 | |
def setEyeBrightness(self, brightness): | |
for e in self.eyes: | |
if brightness == 0: e.off() | |
else: | |
e.on() | |
e.value = brightness | |
#Takes a position between -1.0 and 1.0 | |
#1 is up, -1 is down | |
def setEyebrowPosition(self, pos): | |
self.leftEyebrow.value = -1 * pos | |
self.rightEyebrow.value = pos | |
def neutral(self): | |
self.setEyebrowPosition(0) | |
self.setEyeBrightness(self.neutralEyeValue) | |
def playSound(self, soundfile): | |
wave_obj = simpleaudio.WaveObject.from_wave_file('./' + soundfile + '.wav') | |
play_obj = wave_obj.play() | |
def getSunsetToday(self): | |
payload = { | |
'lat' : 41.8916, | |
'lng' : -87.6285, | |
'formatted': 0 | |
} | |
r = requests.get("https://api.sunrise-sunset.org/json", params=payload) | |
j = r.json() | |
#Get the time of sunrise as a string | |
sunset = j['results']['sunset'] | |
#Create a datetime object from this standardized string format | |
sunsetTime = datetime.fromisoformat(sunset) | |
sunsetInMyTZ = sunsetTime.astimezone(tz = tz.gettz('America/Chicago')) | |
self.sunset = sunsetInMyTZ.replace(microsecond=0) | |
def checkSunset(self): | |
if not self.seenSunsetToday: | |
if self.sunset == None: self.getSunsetToday() | |
if datetime.now().replace(microsecond=0).time() == self.sunset.time(): | |
print("It's sunset time!") | |
self.seenSunsetToday = True | |
self.saySunset() | |
else: | |
print(f"Current time: {datetime.now()}\tSunset at: {self.sunset.time()}") | |
def saySunset(self): | |
self.playSound('happyhollaween') | |
for i in range(0, 100): | |
self.setEyeBrightness(i/100) | |
self.setEyebrowPosition(-i/100) | |
sleep(.018) | |
def afterSunset(self): | |
if self.sunset == None: self.getSunsetToday() | |
if datetime.now().replace(microsecond=0).time() > self.sunset.time(): return True | |
else: return False | |
def haunt(self): | |
numJokes = len(self.jokeList) | |
jokeSelection = randint(0, numJokes) | |
print(f"Telling Joke {jokeSelection}") | |
#tell the joke | |
self.setEyeBrightness(.8) | |
self.setEyebrowPosition(-.8) | |
joke_obj = simpleaudio.WaveObject.from_wave_file(self.jokeList[jokeSelection][0]) | |
play_obj = joke_obj.play() | |
play_obj.wait_done() | |
self.neutral() | |
#wait between 1 and 3 seconds for punchline | |
sleep(1 + randint(0, 20)/10) | |
self.setEyeBrightness(1) | |
self.setEyebrowPosition(1) | |
punch_obj = simpleaudio.WaveObject.from_wave_file(self.jokeList[jokeSelection][1]) | |
play_obj = punch_obj.play() | |
play_obj.wait_done() | |
self.neutral() | |
if __name__ == '__main__': | |
#To set the time on a raspberry pi: | |
#timedatectl set-ntp false | |
#timedatectl set-time '2020-10-25 17:52:30' | |
p = PumpkinPi([18, 23],[21, 20]) | |
p.neutral() | |
while (True): | |
p.checkSunset() | |
if (p.afterSunset()): | |
p.neutralEyeValue = .01 | |
if p.ms.motion_detected: | |
p.haunt() | |
sleep(.5) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment