Rhasspy vs SEPIA Comparison
I think SEPIA might be a better fit for that use case. At any rate, an interesting comparison in this thread. I added some keywords under a heading to help the search robots.
Now back to OT…
Getting Rhasspy Working with openHAB
I suppose now is as good of a time as any to go ahead and post up my working config (otherwise I may never get around to it ).
Rhasspy bills itself as being made for Home Assistant, but there is no reason we cannot also use it for openHAB. The way that Rhasspi integrates with HA is through MQTT using JSON, which makes it equally easy to use with openHAB!
0. MQTT Broker
Getting the MQTT broker working is outside the scope of this post. I will just state however that I am using mosquitto broker on Debian, installed from repositories, and not the built-in openHAB one (although it shouldn’t matter). I already had the MQTT broker working from something else before starting this.
1. Rhasspy
I think next I actually started working from the Rhasspy side. Get that all working:
1.1. Install
Install by your preffered method. I did Python VE, but there are Docker images, etc.
1.2. Get your mic working.
You might have to “Tap to Record” in Rhasspy (Speech tab) and then check PAVC and then select your mic for input into Rhasspy.
1.3. Training
Come up with some Sentences, Train Rhasspy, and then test recognition (see video above and documentation). Look at output below. It’s really easy, actually.
1.3.1. Important Note - Conversions
I almost forgot, I do some conversions from common spoken language (eg. “right [or] left desk light [or] lamp”) directly to openHAB Item names in this step, like so (read Training - Rhasspy docs to understand this syntax):
sentences.ini:
[Lights]
turn (right desk (light|lamp)){item:mysensors_light_bcc8b6a2_light_1_1_status} (on:ON | off:OFF){status}
turn (left desk (light|lamp)){item:mysensors_light_bcc8b6a2_light_1_2_status} (on:ON | off:OFF){status}
turn (both desk (lights|lamps)){item:gDeskLights} (on:ON | off:OFF){status}
You don’t have to do it this way, but I do think this way is easier (but still thinking about it ). You will see why below when we write our openHAB rule.
1.4.1 Set up MQTT settings from Rhasspy side
Should be straightforward.
2. Check MQTT Messages
Using https://mqtt-explorer.com/ (or similar) I made sure I could see the MQTT messages being sent.
3. openHAB Side
Finally, time to get things working on the openHAB side:
3.1. MQTT Broker Thing
First I made a Thing for the mosquitto broker, with a Rhasspy intent channel:
mqtt.things:
Thing mqtt:topic:mosquitto:rhasspy "Rhasspy voice control" (mqtt:broker:mosquitto) {
Channels:
Type string : intent_lights "Rhasspy Intent Lights" [ stateTopic="rhasspy/intent/Lights" ]
}
I called the intent lights but you could call it onoff (perhaps more appropriate, see my thgoughts in post(s) above) or whatever you like. It just has to match what you set up in Rhasspy (above). The intent name becomes the last part of the topic.
3.2. Item
Next, an Item to hold the incoming text string:
mqtt.items:
String rhasspy_intent_lights "Rhasspy Intent Lights" { channel="mqtt:topic:mosquitto:rhasspy:intent:Lights" }
Just as I am typing this, I realize this is where I may have messed up. I ended up with two different items and wrong one linked somehow, which caused me frustration later. I am still not too far from being a newbie in openHAB myself.
3.2. Rule
Finally, a Rule to act when the text string is updated, and then do things. As I recall, some of the logging syntax changed here from other examples I found. Also I think this way is simpler than other examples I found. It just gets the Item name and Status from the JSON and directly uses them. But there are lots of different (and likely more elegant) ways you can structure this. I just want to post a working example as a starting point.
rhasspy.rules:
rule "Rhaspy"
when
Item rhasspy_intent_lights received update
then
var String intentItem = transform("JSONPATH", "$.item", rhasspy_intent_lights.state.toString)
var String intentStatus = transform("JSONPATH", "$.status", rhasspy_intent_lights.state.toString)
logInfo ("rhasspy_intent", "Rhasspy raw JSON: " + rhasspy_intent_lights.toString)
logInfo ("rhasspy_intent", "Rhasspy intentItem: ", intentItem)
logInfo ("rhasspy_intent", "Rhasspy intentStatus: ", intentStatus)
intentItem.sendCommand(intentStatus)
end
Conclusion
Whew!
OK, I think that covers most if not all of it. It’s still pretty fresh in my mind, luckily. Feel free to post questions if you get stuck though. But plan on doing some reading. These are very powerful and flexible tools.
Next Steps
- Get a wake word working
- Integrate more voice commands and services (weather, perhaps news, etc…)