119 lines
2.8 KiB
Python
119 lines
2.8 KiB
Python
import signal
|
|
import sys
|
|
import time
|
|
from datetime import datetime
|
|
import subprocess
|
|
from lib.slovak_datetime_formatter import get_datetime_as_slovak_sentence
|
|
|
|
if len(sys.argv) > 1 and sys.argv[1] == "test":
|
|
import lib.dummygpio as GPIO
|
|
else:
|
|
import RPi.GPIO as GPIO
|
|
|
|
TTS_API_URL = "https://tts.virtonline.eu/api/tts"
|
|
BUTTON_TIMEOUT = 30 # button release timeout terminates playing
|
|
FILENAME = "presny_cas.wav"
|
|
PIN = 27 # listen to changes on this GPIO pin
|
|
GPIO.setmode(GPIO.BCM) # use BCM pin layout
|
|
GPIO.setwarnings(False)
|
|
|
|
|
|
def setup_pin():
|
|
GPIO.setup(PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
|
|
|
|
|
|
def terminate_playing(proc):
|
|
print("Terminating playing...")
|
|
proc.terminate()
|
|
proc.wait(timeout=5)
|
|
print("Terminated")
|
|
|
|
|
|
def play_presny_cas():
|
|
print(f"Playing {FILENAME}")
|
|
proc = subprocess.Popen(["aplay", FILENAME])
|
|
wait_for_button_release_or_timeout(PIN, BUTTON_TIMEOUT)
|
|
print("GPIO went HIGH - terminating playing")
|
|
terminate_playing(proc)
|
|
|
|
|
|
def play_beep():
|
|
print("Playing beep.wav")
|
|
subprocess.run(["aplay", "beep.wav"], check=True)
|
|
|
|
|
|
def get_credentials():
|
|
with open("credentials.txt") as f:
|
|
cred_line = f.readline().strip()
|
|
username, password = cred_line.split(":")
|
|
|
|
return username, password
|
|
|
|
|
|
def generate_presny_cas():
|
|
text = get_datetime_as_slovak_sentence(datetime.now())
|
|
print(f"Calling remote TTS API for '{text}'")
|
|
username, password = get_credentials()
|
|
command = [
|
|
"curl",
|
|
"-s",
|
|
"-w",
|
|
"%{http_code}",
|
|
"-u",
|
|
f"{username}:{password}",
|
|
"--get",
|
|
"--data-urlencode",
|
|
f"text={text}",
|
|
TTS_API_URL,
|
|
"--output",
|
|
FILENAME,
|
|
]
|
|
# print(f"Executing: {' '.join(command)}")
|
|
result = subprocess.run(
|
|
command,
|
|
check=True,
|
|
capture_output=True,
|
|
text=True,
|
|
)
|
|
if result.stdout != "200":
|
|
raise Exception(f"API call failed with status code {result.stdout}")
|
|
print(f"Generated {FILENAME}")
|
|
|
|
|
|
def wait_for_button_release_or_timeout(pin, timeout):
|
|
timeout_start = time.time()
|
|
while time.time() < timeout_start + timeout:
|
|
if GPIO.input(pin) == GPIO.HIGH:
|
|
break
|
|
time.sleep(0.05)
|
|
|
|
|
|
def handle_pin(pin):
|
|
print(f"GPIO {pin} LOW - event triggered")
|
|
generate_presny_cas()
|
|
play_presny_cas()
|
|
|
|
|
|
def signal_handler(sig, frame):
|
|
print("Interrupt received, cleaning up!")
|
|
GPIO.cleanup()
|
|
sys.exit(0)
|
|
|
|
|
|
signal.signal(signal.SIGINT, signal_handler)
|
|
|
|
try:
|
|
setup_pin()
|
|
play_beep()
|
|
play_beep()
|
|
GPIO.add_event_detect(PIN, GPIO.FALLING, callback=handle_pin, bouncetime=1000)
|
|
print(f"Waiting for the GPIO {PIN} to go LOW...")
|
|
while True:
|
|
time.sleep(0.01)
|
|
|
|
except Exception as e:
|
|
print("Caught exception: ", e)
|
|
sys.exit()
|
|
finally:
|
|
GPIO.cleanup()
|