diff --git a/__pycache__/set_timer.cpython-310.pyc b/__pycache__/set_timer.cpython-310.pyc new file mode 100644 index 0000000..c59008c Binary files /dev/null and b/__pycache__/set_timer.cpython-310.pyc differ diff --git a/__pycache__/timer_control.cpython-310.pyc b/__pycache__/timer_control.cpython-310.pyc new file mode 100644 index 0000000..42b9a7a Binary files /dev/null and b/__pycache__/timer_control.cpython-310.pyc differ diff --git a/clock-alarm-8761.mp3 b/clock-alarm-8761.mp3 new file mode 100644 index 0000000..53c2713 Binary files /dev/null and b/clock-alarm-8761.mp3 differ diff --git a/main.py b/main.py index cfa1a7a..48e7c9c 100644 --- a/main.py +++ b/main.py @@ -7,6 +7,8 @@ import subprocess import sounddevice as sd import re import asyncio +from weather_jetzt import get_weather_for_location +from timer_control import parse_time, start_timer, stop_timer, timer_status_info, format_duration #test @@ -88,7 +90,9 @@ INTENTS = { "start": { "keywords": ["starte", "start", "beginne", "stelle"], "required_slots": { - "duration": r"(\w+)\s*(sekunden|sekunde|minuten|minute|stunden|stunde)" + # "duration": r"(\w+)\s*(sekunden|sekunde|minuten|minute|stunden|stunde)" + "duration": r"((?:\w+)\s*(?:sekunden|sekunde|minuten|minute|stunden|stunde))" + } }, "stop": { @@ -117,7 +121,7 @@ def detect_intent(text): # SKILLS # ========================= -from weather_jetzt import get_weather_for_location + def weather_skill(slots): location = slots["location"] @@ -131,13 +135,33 @@ def weather_skill(slots): def start_timer_skill(slots): duration = slots["duration"] - return f"Der Timer für {duration} Minuten wurde gestartet." + seconds = parse_time(duration) + if seconds: + start_timer(seconds) + return f"Timer gestartet" +# return f"Der Timer für {duration} wurde gestartet." def stopp_timer_skill(slots): - return f"Timer wurde gestoppt." + #return f"Timer wurde gestoppt." + stop_timer() + return f"Timer wurde gestoppt" def status_timer_skill(slots): - return f"Status Timer Ausgabe" + # remaining = timer_status_info()["remaining"] + # return f"Status Timer Ausgabe {remaining}" + + info = timer_status_info() + + if info["status"] == "running": + remaining = info["remaining"] + return f"Der Timer läuft noch {format_duration(remaining)} " + elif info["status"] == "finished": + return f"Der Timer ist abgelaufen" + elif info["status"] == "stopped": + return f"Der Timer wurde gestoppt" + else: + return f"Es läuft kein Timer" + @@ -258,13 +282,14 @@ def reset_context(): "pending_slot": None, "action": None } - state = STATE_IDLE + #state = STATE_IDLE + state = STATE_LISTENING # ========================= # VOSK LISTENER # ========================= - +""" def vosk_listener(): SAMPLE_RATE_VOSK = 16000 from vosk import Model, KaldiRecognizer @@ -294,7 +319,7 @@ def vosk_listener(): else: rec.Reset() - + """ # ========================= # WAKEWORD (SIMPLIFIZIERT) # ========================= @@ -310,6 +335,8 @@ def fake_wakeword_detector(): # ========================== # WAKEWORD (PORCUPINE) # ========================== + +""" def real_wakeword_detector(): import pvporcupine import numpy as np @@ -347,12 +374,12 @@ def real_wakeword_detector(): while True: pass - + """ # ========================= # MAIN LOOP # ========================= -def main(): +""" def main(): threading.Thread(target=vosk_listener, daemon=True).start() # threading.Thread(target=fake_wakeword_detector, daemon=True).start() threading.Thread(target=real_wakeword_detector, daemon=True).start() @@ -362,7 +389,15 @@ def main(): text = audio_queue.get(timeout=0.1) handle_text(text) except queue.Empty: - pass + pass """ + +def main(): + global state + state = STATE_LISTENING + while True: + text = input("Text input: ") + handle_text(text) + if __name__ == "__main__": diff --git a/timer_control.py b/timer_control.py new file mode 100644 index 0000000..ce0080d --- /dev/null +++ b/timer_control.py @@ -0,0 +1,113 @@ +import time +import threading +from text2numde import text2num, is_number, sentence2num +from playsound3 import playsound + +timer_thread = None +timer_stop = threading.Event() +timer_status = "idle" +timer_start = 0 +timer_duration = 0 + + +def parse_time(text): + """ + Wandelt einen deutschen Text wie 'fünf Minuten' in Sekunden um. + """ + text = text.lower().strip() + + """ + 'Eine' folgt sonst mit einem fehler + """ + text = text.replace("eine ", "ein ").replace("eins ", "ein ") + + try: + if "sekunde" in text: + number_text = text.replace("sekunden", "").replace("sekunde", "").strip() + seconds = text2num(number_text) # Use text2num from text2numde + return seconds + elif "minute" in text: + number_text = text.replace("minuten", "").replace("minute", "").strip() + minutes = text2num(number_text) + return minutes * 60 # Convert minutes to seconds + elif "stunde" in text: + number_text = text.replace("stunden", "").replace("stunde", "").strip() + hours = text2num(number_text) + return hours * 3600 # Convert hours to seconds + else: + # Default: assume seconds + return text2num(text) # Convert general text to number (in seconds) + except ValueError: + print("Konnte die Zahl nicht erkennen.") + return None + + +def start_timer(seconds): + + global timer_thread, timer_status, timer_start, timer_duration + + if timer_status == "running": + return False # timer läuft bereits + + timer_stop.clear() + timer_duration = seconds + timer_start = time.time() + timer_status = "running" + + def run(): + global timer_status + if not timer_stop.wait(seconds): + timer_status = "finished" + print("Timer abgelaufen") # """ TTS """ + + timer_thread = threading.Thread(target=run, daemon=True) + timer_thread.start() + return True +""" + print(f"Timer startet für {seconds} Sekunden...") + time.sleep(seconds) + print("Timer abgelaufen!") + playsound("/home/tino/Desktop/Abschlussprojekt/test assistant/cloneAssistantAllInOne/RasPi_Voice_Assistant--WIP/clock-alarm-8761.mp3") + sound.stop() + """ + +""" # Beispielnutzung +spoken_input = "eine sekunde" # This could come from a voice assistant +seconds = parse_time(spoken_input) +if seconds: + start_timer(seconds) """ + +def stop_timer(): + global timer_status + if timer_status != "running": + print("Kein Timer gestellt") + return False + + timer_stop.set() + timer_status = "stopped" + return True + +def timer_status_info(): + if timer_status != "running": + return {"status": timer_status, "remaining": 0} + + elapsed = time.time() - timer_start + remaining = max(0, int(timer_duration - elapsed)) + + return { + "status": "running", + "remaining": remaining + } + +def format_duration(seconds): + if seconds < 60: + return f"{seconds} Sekunden" + elif seconds < 3600: + minutes = seconds // 60 + return f"{minutes} Minuten" + else: + hours = seconds // 3600 + return f"{hours} Stunden" + + +