You can imagine MQTT as a chat room. As a user
, you connect to a chat room created, you can subscribe to specific topics to filter out messages. You can send and receive messages from other users on specific topics.
In our case, users
are Snips Platform's components
, like the Hotword
, Automatic Speech Recognition
or Text To Speech
These components are sending and receiving messages to each other on predefined topics. We call it the Hermes Protocol. You can learn more by reading the Hermes Protocol documentation.
The bare minimum your action code needs to do is react to intents being detected by the NLU (Natural Language Understanding). When it detects an intent, the NLU component sends a message over MQTT. This means your action code simply needs to connect to MQTT, and listen to the right topics. The sample code we are going to provide here can be extrapolated to any language you may choose to code your action, as long as you are able to find an MQTT client for that language.
If you are coding your app in Python, we are providing you with a helper library, Hermes Python, that makes it easier to send and receive messages from MQTT. Jump straight to this page if you want to use it.
Let's now give you an example on how to connect to MQTT. We'll illustrate this in Python, but the logic would be the same using any MQTT client in any language.
Prerequisites
Snips platform installed and running on the Pi
Snips' official weather app installed
Python pip & virtualenv installed
In Python, the Eclipse's paho.mqtt library is perfect for what we need. You can create and run the following python file on your computer. First, we connect to the relevant MQTT topic:
# !/usr/bin/env python# encoding: utf-8import paho.mqtt.client as mqttdef on_connect(client, userdata, flags, rc):print('Connected')mqtt.subscribe('hermes/intent/#')mqtt = mqtt.Client()mqtt.on_connect = on_connectmqtt.connect('raspberrypi.local', 1883)mqtt.loop_forever()
Note that in the code above, #
is used as a wildcard, to connect to all topics starting by hermes/intent
. An alternative is to connect to the topic of a given topic, for example:
mqtt.subscribe('hermes/intent/searchWeatherForecast')
We now need to add a callback, to be able to react to the messages being received. For this, we will also need to import the json module. Here is the complete code, to simply print the objects being broadcated over the intent topics on MQTT:
# !/usr/bin/env python# encoding: utf-8import paho.mqtt.client as mqttimport jsondef on_connect(client, userdata, flags, rc):print('Connected')mqtt.subscribe('hermes/intent/#')def on_message(client, userdata, msg):# Parse the json responseintent_json = json.loads(msg.payload)intentName = intent_json['intent']['intentName']slots = intent_json['slots']print('Intent {}'.format(intentName))for slot in slots:slot_name = slot['slotName']raw_value = slot['rawValue']value = slot['value']['value']print('Slot {} -> \n\tRaw: {} \tValue: {}'.format(slot_name, raw_value, value))mqtt = mqtt.Client()mqtt.on_connect = on_connectmqtt.on_message = on_messagemqtt.connect('raspberrypi.local', 1883)mqtt.loop_forever()
Let's test this. Install the paho-mqtt
dependency. For this we recommend using a virtualenv
.
cd <path_to_your_action>virtualenv venvsource venv/bin/activatepip install paho-mqttpython your-action.py
If you have the Snips Weather demo installed, try:
'Hey Snips! What will be the weather in London in two days?'
You should see the output:
ConnectedIntent searchWeatherForecastforecast_localityRaw: london Value: Londonforecast_start_datetimeRaw: in two days Value: 2018-06-22 00:00:00 +00:00
The corresponding JSON
sent by the platform on MQTT on the topic hermes/intent/searchWeatherForecast
{"sessionId": "4d2d171d-fb21-4bea-a76d-0293634f50d9","customData": null,"siteId": "default","input": "what will be the weather in london in two days","intent": {"intentName": "searchWeatherForecast","probability": 0.9337856},"slots": [{"rawValue": "london","value": {"kind": "Custom","value": "London"},"range": {"start": 28,"end": 34},"entity": "locality","slotName": "forecast_locality"},{"rawValue": "in two days","value": {"kind": "InstantTime","value": "2018-06-22 00:00:00 +00:00","grain": "Day","precision": "Exact"},"range": {"start": 35,"end": 46},"entity": "snips/datetime","slotName": "forecast_start_datetime"}]}
Once you are able to react to intents being shared on MQTT, it's up to you to write what you want to do after receiving the intent!