Connecting snips to openhab


#1

Hello all
I was asked to share my knowledge about connecting snips with openhab, so I will. :grinning:

I set up snips on a different device (rapsberry pi) as my openhab system is running (another raspberry pi).

  1. Install the mqtt binding and mqtt action in openhab

  2. Do mqtt bridging by editing the /etc/mosquitto/mosquitto.conf file on your snips server and add

    connection snips-openhab-bridge
    address <name or ip of openhab server>:1883
    clientid snips
    start_type automatic
    username <username>
    password <password>
    notifications false
    try_private true
    topic hermes/intent/# both 0
    topic hermes/dialogueManager/# both 0

Replace the parts in <> with your configuration data.
This will publish all snips intents of the snips mqtt broker to the openhab mqtt broker, too.

  1. In openhab create an item to get the snips mqtt messages.
String Snips_Intent "Snips Intent" { mqtt="&lt;[mqtt-openhab:hermes/intent/#:state:default]" }
  1. Create a rule in openhab to get the snips intent data
rule "Snips"
when
    Item Snips_Intent received update
then
    //logInfo("Snips Intent", Snips_Intent.toString)

    var String intentName = transform("JSONPATH", "$.intent.intentName", Snips_Intent.state.toString) 
    var String snipsIntent  = intentName.split(":").get(1);
    var String snipsSlot1RawValue = transform("JSONPATH", "$.slots[0].rawValue", Snips_Intent.state.toString)
    var String snipsSlot1Value    = transform("JSONPATH", "$.slots[0].value.value", Snips_Intent.state.toString)

    logInfo("snips.rule", "intent: " + snipsIntent)
    logInfo("snips.rule", "raw value: " + snipsSlot1RawValue)
    logInfo("snips.rule", "slot: " + snipsSlot1Value)
end

Within this rule you can do anything what is possible in openhab.

In my environment I have temperature sensors in my house that I can ask snips to reply the current temperature.

For this I created a snips app with the intent TemperaturAbfrage.
This intent has one slot for the room.
For example a snips output could be:

{
  "input": "wie ist die temperatur in wohnzimmer",
  "intent": {
    "intentName": "Agamemnon:TemperaturAbfrage",
    "probability": 1
  },
  "slots": [
    {
      "rawValue": "wohnzimmer",
      "value": {
        "kind": "Custom",
        "value": "Wohnzimmer"
      },
      "range": {
        "start": 26,
        "end": 36
      },
      "entity": "roomNames",
      "slotName": "RoomName"
    }
  ]
}

In the openhab rule I added the following:

import org.eclipse.smarthome.model.script.ScriptServiceUtil

if (snipsIntent == 'TemperaturAbfrage') {
        var ItemName = "LaCrosseTemperatureSensor" + snipsSlot1Value + "_Temperatur"
        val MyItem = ScriptServiceUtil.getItemRegistry.getItem(ItemName)
        var CurrentTemperature = MyItem.state.toString
        CurrentTemperature = CurrentTemperature.replace(".", ",")
        publish("mqtt-openhab", "hermes/dialogueManager/startSession", "{\"siteId\":\"default\",\"init\":{\"type\":\"notification\",\"text\":\"Die Temperatur beträgt " + CurrentTemperature + " Grad\"}}")
        logInfo("snips.rule", "Temperatur in " + snipsSlot1Value + ": " + CurrentTemperature)
}

This is creating the openhab item name out of the slot of the intent.
I then use this itemname with the getItemRegistry function to get the item and the state (temperature).
At least I use the mqtt publish action to publish the result to the local (openhab) mqtt broker.
Due tu the bridging on top it is automatically published to the snips mqtt broker (dialogueManager), too.

Ask, if you need further support on this setup.

Best regards,
Matthias


Change voice feedback to german
#2

Thank you for sharing your setup. Great idea. I will try to build it like this.
Is there a reason why you use mqtt and not the REST API?


#3

I am already using mqtt in openhab for other connections and snips is using mqtt, too.
For me that was by far the easiest way to connect both systems without any programming.


#4

Thank you for sharing, I’m trying to move from Alexa to snips and making my first steps, with your example I get the snips output in the openhab log.

But, I can’t get the “ScriptServiceUtil” to work.
Have I something to import?

Great work, go on


#5

My fault… I forgot the very first line.
Yes, you need to import the ScriptServiceUtils

import org.eclipse.smarthome.model.script.ScriptServiceUtil

I modified the initial post.
Thanks for that hint.

BR
Matthias


#6

Thank you for fast replay,
I’ll try this afternoon.

Have a nice day

BR
Matthias :wink:


#7

Hello,

I use snips with openhab too. But i did it in different way.
I added mqtt bind (client) to openhab. And create a bridge with a channel by intent :

Bridge mqtt:broker:mymqttsnips "MQTT Snips Broker" [ host="snips-master" ] 
{
    Thing topic thsnips "Generic MQTT Snips" 
    {
        Channels:
            Type string : light_off "Light off"  [ stateTopic="hermes/intent/cedcox:eteindreLumiere", commandTopic="", formatBeforePublish="" ]
            Type string : light_dim_down "Light DIM down"  [ stateTopic="hermes/intent/cedcox:varierBasLumiere", commandTopic="", formatBeforePublish="" ]
        [....... and so on ....]
}

}

and after, i create one rule by intent :

rule "light off"
    when
        Item Snips_Intent_light_off received update 
    then
        confidence = transform("JSONPATH", "$.intent.probability", Snips_Intent_light_off.state.toString)
        logInfo("rule light off", "confidence : " + confidence.toString)  

    if (Double::parseDouble(confidence) > 0.8) {
        //
        // Get variables
        //   

        siteId = transform("JSONPATH", "$.siteId", Snips_Intent_light_off.state.toString)
        logInfo("rule light off", "siteId : " + siteId.toString)  

        sessionId = transform("JSONPATH", "$.sessionId", Snips_Intent_light_off.state.toString)
        logInfo("rule light off", "sessionId : " + sessionId.toString)  

        entity_room = transform("JSONPATH", "$.slots.[?(@.slotName== 'house_room')].value.value", Snips_Intent_light_off.state.toString)
        entity_room = entity_room.replace("-","_")
        entity_room = entity_room.replace(" le ","")
        entity_room = entity_room.replace(" la ","")
        entity_room = entity_room.replace(" du ","")
        entity_room = entity_room.replace(" d'","")
        entity_room = entity_room.replace(" l'","")
        entity_room = entity_room.replace(" ","_")
        entity_room = entity_room.replace("'","_")
        entity_room = entity_room.replace("é","e")
        entity_room = entity_room.replace("à","a")
        entity_room = entity_room.replace("ê","e")
        entity_room = entity_room.replace("î","i")
        logInfo("rule light off", "entity_room : " + entity_room)  

    [.... blablablabla ...]

An alternative solution that does not need a mqtt srever on openhab (if you did not need it before :wink: )
Does not manage multislot of house_room, but i have already an idea to implement… I just need time :slight_smile:

Ced


#8

Thank you for that alternative.
I like the idea to check for the confidence, will implement that, too. :grin: