I’m somewhat new to Rhasspy and Python.
I’ve installed Rhasspy version 2.5.11 on a Raspberry Pi 4 with Docker as per the instructions on the Rhasspy site. I’ve written a Python program to receive intents from Rhasspy using websockets and then act upon the intents.
When I start my program from the command line it works as expected. But when I auto start my program the websocket connection from my Python program to Rhasspy fails.
I’m wondering if it could be a timing issue where the Python program starts before Rhasspy. But I tried putting the websockets.connect() in the main() function and it worked. I’m missing something, so help is very much appreciated.
Thanks,
Steve
Here is the connect failure:
pi@NWI-RPI4-4:~ $ sudo systemctl status northern-wolf
● northern-wolf.service - Northern Wolf Inc.
Loaded: loaded (/lib/systemd/system/northern-wolf.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Tue 2021-08-31 11:37:48 EDT; 1min 1s ago
Process: 987 ExecStart=/usr/bin/sudo -H -u pi /usr/bin/python3 /home/pi/bin/released/controller.py > /home/pi/nwi.log 2>&1 (code=exited, status=1/FAILURE)
Main PID: 987 (code=exited, status=1/FAILURE)
Aug 31 11:37:48 NWI-RPI4-4 sudo[987]: File "/home/pi/.local/lib/python3.7/site-packages/websockets/client.py", line 517, in __aenter__
Aug 31 11:37:48 NWI-RPI4-4 sudo[987]: return await self
Aug 31 11:37:48 NWI-RPI4-4 sudo[987]: File "/home/pi/.local/lib/python3.7/site-packages/websockets/client.py", line 535, in __await_impl__
Aug 31 11:37:48 NWI-RPI4-4 sudo[987]: transport, protocol = await self._create_connection()
Aug 31 11:37:48 NWI-RPI4-4 sudo[987]: File "/usr/lib/python3.7/asyncio/base_events.py", line 968, in create_connection
Aug 31 11:37:48 NWI-RPI4-4 sudo[987]: ', '.join(str(exc) for exc in exceptions)))
Aug 31 11:37:48 NWI-RPI4-4 sudo[987]: OSError: Multiple exceptions: [Errno 111] Connect call failed ('::1', 12101, 0, 0), [Errno 111] Connect call failed ('127.
Aug 31 11:37:48 NWI-RPI4-4 sudo[987]: pam_unix(sudo:session): session closed for user pi
Aug 31 11:37:48 NWI-RPI4-4 systemd[1]: northern-wolf.service: Main process exited, code=exited, status=1/FAILURE
Aug 31 11:37:48 NWI-RPI4-4 systemd[1]: northern-wolf.service: Failed with result 'exit-code'.
pi@NWI-RPI4-4:~ $
Here is the service file I’m using:
pi@NWI-RPI4-4:/lib/systemd/system $ more northern-wolf.service
[Unit]
Description=Northern Wolf Inc.
After=multi-user.target
[Service]
ExecStart=sudo -H -u pi /usr/bin/python3 /home/pi/bin/released/controller.py > /home/pi/nwi.log 2>&1
[Install]
WantedBy=multi-user.target
pi@NWI-RPI4-4:/lib/systemd/system $
And here is my Python program:
#!/usr/bin/env python3
import asyncio
import json
import logging
import pyudev
import requests
from rhasspyclient import RhasspyClient
import serial
import serial.tools.list_ports
import subprocess
from time import strftime, localtime
import websockets
from websockets import WebSocketClientProtocol
logging.basicConfig(level = logging.INFO)
# Variables for the Rhasspy voice assistant.
RHASSPY_PROTOCOL = 'http'
RHASSPY_HOST = 'localhost'
RHASSPY_PORT = '12101'
RHASSPY_ENDPOINT_INTENT = 'api/events/intent'
RHASSPY_ENDPOINT_TEXT_TO_SPEECH = 'api/text-to-speech'
def process_intent(message, intent):
# Get the intent (i.e. command).
the_intent = intent['name']
async def consumerHandler(websocket: WebSocketClientProtocol):
# Go through the messages from the websocket with Rhasspy.
async for message in websocket:
# Deserialize (decode) the the JSON message received.
message = json.loads(message)
logging.info('Received the following message from Rhasspy:')
logging.info(json.dumps(message, indent = 2))
try:
# Get the intent that was invoked.
intent = message['intent']
except:
# An exception occurred.
logging.error('Received a message from Rhasspy that did not contain an intent.')
else:
# There is a message with an intent, now process the intent.
process_intent(message, intent)
async def consume(hostname: str, port: int, endpoint: str):
# Wait for messages on the websocket with Rhasspy.
uri = f'ws://{hostname}:{port}/{endpoint}'
async with websockets.connect(uri) as websocket:
await consumerHandler(websocket)
def main():
# Wait for messages from Rhasspy. These should have bed controller commands.
asyncio.run(
consume(
hostname = RHASSPY_HOST,
port = RHASSPY_PORT,
endpoint = RHASSPY_ENDPOINT_INTENT
)
)
if __name__ == '__main__':
main()