Resurrecting an old post since I am having a similar issue.
I created my own python script for a handler, and it works from container terminal, but doesn’t seem to be called from Rhasspy.
So - I copied the example handler.py to the profile/en directory, created intents to match it, and still nothing… can someone help me debug this? I’m not sure where to find any errors (the log in the GUI shows nothing useful).
I tried adding the arguments and forward_to_hass flags and those didn’t seem to have any effect.
handler.py
#!/usr/bin/env python
import sys
import json
import random
import datetime
def speech(text):
global o
o["speech"] = {"text": text}
# get json from stdin and load into python dict
o = json.loads(sys.stdin.read())
intent = o["intent"]["name"]
if intent == "GetTime":
now = datetime.datetime.now()
speech("It's %s %d %s." % (now.strftime('%H'), now.minute, now.strftime('%p')))
elif intent == "Hello":
replies = ['Hi!', 'Hello!', 'Hey there!', 'Greetings.']
speech(random.choice(replies))
# convert dict to json and print to stdout
print(json.dumps(o))
sentences.ini
[GetTime]
What time is it
[Hello]
Hello
Can anyone spot what I am missing or doing wrong?
Currently on Rhasspy version 2.5.5
Last time I tested in 2.5 after it came out I noticed that the script isn’t called. I opened an issue and kept an eye on the development and I don’t think it is fixed yet. Try the rhasspy-hermes-app or another mqtt library to get it working, that is the preferred way for 2.5 right now.
Created the script copy and pasting in the time_app.py, set the intent handler to the new file (making sure it was executable). GetTime was already a sentence, so no change there.
Still not working…
I’m sure I’m missing something stupidly simple… but I can’t figure it out.
I was digging in the code trying to understand something, and I think I found something but don’t know if it would cause a problem…
In the intent handler, there is a reference to satellites… but at least in the GUI there is no way to set them… I wasn’t sure if this would cause it to error when trying to use a local intent handler.
# Intent Handling
handle_system = profile.get("handle.system", "dummy")
if handle_system not in {"dummy", "hermes"}:
satellite_site_ids = str(profile.get("handle.satellite_site_ids", "")).split(
","
)
Since I’m pretty dev dumb… would this cause an error if the value doesn’t exist and doesn’t have a fallback default? Going to post this on your issue to help track it.
I haven’t seen you mention MQTT, but Rhasspy Hermes App is meant to be used with an MQTT broker, as the Hermes protocol is defined as MQTT messages. Have a look at the arguments such as --host to define the address of the MQTT broker in the usage documentation.
I’m probably just using it wrong. At first I was trying to use it as an intent handler (setup in the GUI). Then I ran it just in terminal realizing that it was probably stand alone.
I was running it within the container. It says in the usage docs that it uses localhost and 1883. I changed the port to 12183 since that’s what the internal MQTT uses. I didn’t change the address since it should be localhost, but I have had issues with that in containers in the past, so I will try using the container IP and see if that fixes it.
With Rhasspy Hermes App you don’t have to configure your app as an intent handler in Rhasspy’s web interface, it works completely independently from Rhasspy. It works even when there’s no intent handler defined in Rhasspy because it’s using MQTT.
Yes I did… looks like localhost worked fine - starts up and connects.
I did a sentence recognition from the GUI and that appears to be caught too…
So it looks like the speech isn’t getting back into Rhasspy.
So to run a hermes-app do you need to set it up as a service? It has to be running all the time I assume. Right now I just have a terminal running it, but of course it dies when I close.
Ah crap… I just realized I changed to a different example file and it uses the EndSession for the return… I’m going to go out on a limb and guess that doesn’t initiate speech like the speech command does. I’ll try changing to the other example file.
Ok, so the session is ended, this means that Rhasspy should have received this message over MQTT and should have activated the TTS. If you don’t hear anything, there’s something wrong with the TTS. Or does the TTS work otherwise?
Yes you have to run a Rhasspy Hermes App as a service. This could be in a systemd service or in another Docker container. An easy way to create this service is on the roadmap, but for now you’ll have to do it manually.
"""Example app to react to an intent to tell you the time."""
import logging
from datetime import datetime
from rhasspyhermes.nlu import NluIntent
from rhasspyhermes_app import EndSession, HermesApp
_LOGGER = logging.getLogger("TimeApp")
app = HermesApp("TimeApp")
@app.on_intent("GetTime")
async def get_time(intent: NluIntent):
"""Tell the time."""
now = datetime.now().strftime("%H %M")
return EndSession(f"It's {now}")
app.run()
In the connection line, it does have CERT_REQUIRED… but I don’t have any certs setup for Rhasspy since its all internal… would this cause a problem? I would expect it not to connect if that were the case…
Never mind - I added --tls-cert-reqs CERT_NONE and it didn’t fix it.
OKAY - I was able to install the mosquitto-client on the container, and subscript to the topics.
After doing recognition in Rhasspy, the hermes-app works, and does appear to post back to the correct topic:
Okay - found this error in the docker log, seems relavent:
[ERROR:2020-08-04 17:10:43,442] asyncio: Task exception was never retrieved
future: <Task finished coro=<HermesClient.publish_all() done, defined at /usr/lib/rhasspy/rhasspy-hermes/rhasspyhermes/client.py:368> exception=AssertionError('No session')>
Traceback (most recent call last):
File "/usr/lib/rhasspy/rhasspy-hermes/rhasspyhermes/client.py", line 370, in publish_all
async for maybe_message in async_generator:
File "/usr/lib/rhasspy/rhasspy-dialogue-hermes/rhasspydialogue_hermes/__init__.py", line 668, in on_message
async for end_result in self.handle_end(message):
File "/usr/lib/rhasspy/rhasspy-dialogue-hermes/rhasspydialogue_hermes/__init__.py", line 375, in handle_end
assert self.session is not None, "No session"
AssertionError: No session
Nice bonus, this actually helped me fix the other issue with the local command handler. Looks like it isn’t working with the ${RHASSPY_PROFILE_DIR} - using an absolute path seems to fix it.
Anyway, back to the hermes-app - something is wrong with the sessions I see… not sure how to dig deeper yet… will keep looking.