diff --git a/main.py b/main.py index 812bf58..0c30394 100644 --- a/main.py +++ b/main.py @@ -35,7 +35,8 @@ context = { "intent": None, "slots": {}, "required_slots": [], - "pending_slot": None + "pending_slot": None, + "action": None, } audio_queue = queue.Queue() @@ -73,11 +74,17 @@ def speak(text): INTENTS = { "weather": { "keywords": ["wetter", "temperatur", "regen"], - "required_slots": ["location"] + "required_slots": { + "location": r"\bin\b\s*(\w+)" + }, + "subactions": ["info"] }, "timer": { "keywords": ["timer"], - "required_slots": ["duration"] + "required_slots": { + "duration": r"(sekunde|minute|stunde)" + }, + "subactiions": ["start", "stop", "status"] } } @@ -122,9 +129,9 @@ def handle_text(text): print(f"[STT] {text}") # 1. Rückfrage beantworten - if context["pending_slot"]: - context["slots"][context["pending_slot"]] = text - context["pending_slot"] = None + # if context["pending_slot"]: + # context["slots"][context["pending_slot"]] = text + # context["pending_slot"] = None # 2. Intent erkennen if not context["intent"]: @@ -135,41 +142,48 @@ def handle_text(text): return context["intent"] = intent - context["required_slots"] = INTENTS[intent]["required_slots"] + context["required_slots"] = INTENTS[intent]["required_slots"] # man könnte per liste drüber iterieren wenn man mehrere required slots hat - check_required(text) + if not check_required(text): + return # 3. Fehlende Slots prüfen - for slot in context["required_slots"]: - if slot not in context["slots"]: - context["pending_slot"] = slot - ask_for_slot(slot) - return + # for slot in context["required_slots"]: + # if slot not in context["slots"]: + # context["pending_slot"] = slot + # ask_for_slot(slot) + # return # 4. Skill ausführen + + + result = SKILLS[context["intent"]](context["slots"]) speak(result) reset_context() def check_required(text): - if context["intent"] == "weather" or context["pending_slot"] != None: - if not re.search(r'in\b', text): - print("LOCATION ABFRAGEN") + intent_data = INTENTS[context["intent"]] + text = text.lower() - else: - print("LOCATION ERMITTELN") - context["pending_slot"] = None + for slot, pattern in intent_data.get("required_slots", {}).items(): + if slot not in context["slots"]: + match = re.search(pattern, text) + if match: + context["slots"][slot] = match.group(1) # schau an + else: + context["pending_slot"] = slot + ask_for_slot(slot) + return False - elif context["intent"] == "timer": - if not re.search(r'\b(sekunde|minute|stunde)n?\b', text): - print("DURATION ABFRAGEN") - else: - print("DURATION ERMITTELN") - context["pending_slot"] = None + for action in intent_data.get("subactions", []): + if action in text: + context["slots"]["action"] = action + + context["pending_slot"] = None + return True - - def ask_for_slot(slot): questions = { "location": "Für welchen Ort?", @@ -261,6 +275,7 @@ def real_wakeword_detector(): state = STATE_LISTENING print("WAKE WORD DETECTED") speak("Ja, wie kann ich helfen?") + with sd.InputStream( samplerate=porcupine.sample_rate,