async def test_callbacks_hotword(mocker): """Test hotword callbacks.""" app = HermesApp("Test HotwordDetected", mqtt_client=mocker.MagicMock()) # Mock wake callback and apply on_hotword decorator. wake = mocker.MagicMock() app.on_hotword(wake) # Simulate app.run() without the MQTT client. app._subscribe_callbacks() # Check whether callback has been added to the app. assert len(app._callbacks_hotword) == 1 assert app._callbacks_hotword[0] == wake # Simulate detected hotword. await app.on_raw_message(HOTWORD_TOPIC, HOTWORD_PAYLOAD) # Check whether callback has been called with the right Rhasspy Hermes object. wake.assert_called_once_with(HotwordDetected.from_json(HOTWORD_PAYLOAD))
async def on_raw_message(self, topic: str, payload: bytes): """This method handles messages from the MQTT broker. Arguments: topic: The topic of the received MQTT message. payload: The payload of the received MQTT message. .. warning:: Don't override this method in your app. This is where all the magic happens in Rhasspy Hermes App. """ try: if HotwordDetected.is_topic(topic): # hermes/hotword/<wakeword_id>/detected try: hotword_detected = HotwordDetected.from_json(payload) for function_h in self._callbacks_hotword: await function_h(hotword_detected) except KeyError as key: _LOGGER.error("Missing key %s in JSON payload for %s: %s", key, topic, payload) elif NluIntent.is_topic(topic): # hermes/intent/<intent_name> try: nlu_intent = NluIntent.from_json(payload) intent_name = nlu_intent.intent.intent_name if intent_name in self._callbacks_intent: for function_i in self._callbacks_intent[intent_name]: await function_i(nlu_intent) except KeyError as key: _LOGGER.error("Missing key %s in JSON payload for %s: %s", key, topic, payload) elif NluIntentNotRecognized.is_topic(topic): # hermes/nlu/intentNotRecognized try: nlu_intent_not_recognized = NluIntentNotRecognized.from_json( payload) for function_inr in self._callbacks_intent_not_recognized: await function_inr(nlu_intent_not_recognized) except KeyError as key: _LOGGER.error("Missing key %s in JSON payload for %s: %s", key, topic, payload) elif DialogueIntentNotRecognized.is_topic(topic): # hermes/dialogueManager/intentNotRecognized try: dialogue_intent_not_recognized = DialogueIntentNotRecognized.from_json( payload) for function_dinr in self._callbacks_dialogue_intent_not_recognized: await function_dinr(dialogue_intent_not_recognized) except KeyError as key: _LOGGER.error("Missing key %s in JSON payload for %s: %s", key, topic, payload) else: unexpected_topic = True if topic in self._callbacks_topic: for function_1 in self._callbacks_topic[topic]: await function_1(TopicData(topic, {}), payload) unexpected_topic = False else: for function_2 in self._callbacks_topic_regex: if hasattr(function_2, "topic_extras"): topic_extras = getattr(function_2, "topic_extras") for pattern, named_positions in topic_extras: if re.match(pattern, topic) is not None: data = TopicData(topic, {}) parts = topic.split(sep="/") if named_positions is not None: for name, position in named_positions.items( ): data.data[name] = parts[position] function_2(data, payload) unexpected_topic = False if unexpected_topic: _LOGGER.warning("Unexpected topic: %s", topic) except Exception: _LOGGER.exception("on_raw_message")