rhasspy / wyoming-satellite

Remote voice satellite using Wyoming protocol
MIT License
609 stars 89 forks source link

Wyoming Satellite Service: INFO:root:Disconnected from server #133

Open vitalized opened 6 months ago

vitalized commented 6 months ago

Hi all, The satellite keeps disconnecting and reconnecting to the server after almost every voice command. It's linked to using two Python scripts that control a servo (for R2-D2) and an LED (for C3-PO), which are used in the --detect-command and --tts-stop-command

--detect-command '/home/satellite1/wyoming-satellite/awake.sh' --tts-stop-command '/home/satellite1/wyoming-satellite/done.sh'

Here's the log from: journalctl -u wyoming-satellite.service -f These are the two lines below to look at: Mar 13 16:08:34 satellite1 run[2876]: INFO:root:Disconnected from server Mar 13 16:08:34 satellite1 run[2876]: INFO:root:Connected to server

Mar 13 16:08:26 satellite1 run[2910]: Playing raw data 'stdin' : Signed 16 bit Little Endian, Rate 16000 Hz, Mono
Mar 13 16:08:31 satellite1 run[2908]: LED on
...
Mar 13 16:08:31 satellite1 run[2908]: LED off
Mar 13 16:08:31 satellite1 run[2908]: End of done.sh script
Mar 13 16:08:31 satellite1 run[2908]: All done!... Goodbye
Mar 13 16:08:34 satellite1 run[2876]: INFO:root:Disconnected from server
Mar 13 16:08:34 satellite1 run[2876]: INFO:root:Connected to server
Mar 13 16:08:36 satellite1 run[2912]: Start PWM running, but with value of 0 (pulse off)
Mar 13 16:08:36 satellite1 run[2912]: Turn R2-D2's head
Mar 13 16:08:36 satellite1 run[2912]: End of awake.sh script
Mar 13 16:08:36 satellite1 run[2876]: INFO:root:Waiting for wake word

awake.sh

#!/usr/bin/env python3

# Import libraries
import RPi.GPIO as GPIO
import time

# Cowards way out, but I think there's a "awake.sh:11 RuntimeWarning: This channel is already in use" because there's a Mic HAT on the 40 pins.
# GPIO.setwarnings(False)

# Set GPIO numbering mode
GPIO.setmode(GPIO.BOARD)

# Set pin 16 as an output, and set servo1 as pin 16 as PWM
GPIO.setup(11,GPIO.OUT)
#GPIO.setup(37,GPIO.OUT)

servo1 = GPIO.PWM(11,50) # Note 11 is pin, 50 = 50Hz pulse

#start PWM running, but with value of 0 (pulse off)
servo1.start(0)
print ("Start PWM running, but with value of 0 (pulse off)")
time.sleep(0)

# Move R2-D2's head
print ("Turn R2-D2's head")
servo1.ChangeDutyCycle(7)
time.sleep(0.5)
servo1.ChangeDutyCycle(11)
time.sleep(0.5)
servo1.ChangeDutyCycle(10)
time.sleep(0.2)
servo1.ChangeDutyCycle(12)
time.sleep(0.5)

#Clean things up at the end
servo1.stop()

GPIO.cleanup()

print ("End of awake.sh script")

done.sh

#!/usr/bin/env python3

import RPi.GPIO as GPIO         # Import Raspberry Pi GPIO library
from time import sleep          # Import the sleep function 

pinLED = 14                     # LED GPIO Pin

GPIO.setmode(GPIO.BCM)          # Use GPIO pin number
#GPIO.setwarnings(False)         # Ignore warnings in our case
GPIO.setup(pinLED, GPIO.OUT)    # GPIO pin as output pin

sleep(0.5)

# Flash LED for C-3PO talking
GPIO.output(pinLED, GPIO.HIGH)
print("LED on")
sleep(0.1)
GPIO.output(pinLED, GPIO.LOW)
print("LED off")
sleep(0.1)
GPIO.output(pinLED, GPIO.HIGH)
print("LED on")
sleep(0.3)
GPIO.output(pinLED, GPIO.LOW)
print("LED off")
sleep(0.1)
GPIO.output(pinLED, GPIO.HIGH)
print("LED on")
sleep(0.2)
GPIO.output(pinLED, GPIO.LOW)
print("LED off")
sleep(0.1)
GPIO.output(pinLED, GPIO.HIGH)
print("LED on")
sleep(0.2)
GPIO.output(pinLED, GPIO.LOW)
print("LED off")

GPIO.cleanup()
print ("End of done.sh script")
print ("All done!... Goodbye")

Here's the wyoming-satellite.service config:

[Unit]
Description=Wyoming Satellite
Wants=network-online.target
After=network-online.target
Requires=wyoming-openwakeword.service
Requires=2mic_leds.service

[Service]
Type=simple
ExecStart=/home/satellite1/wyoming-satellite/script/run \
  --name 'R2D2 Satellite' \
  --uri 'tcp://0.0.0.0:10700' \
  --mic-command 'arecord -D plughw:CARD=seeed2micvoicec,DEV=0 -r 16000 -c 1 -f S16_LE -t raw' \
  --snd-command 'aplay -D plughw:CARD=seeed2micvoicec,DEV=0 -r 16000 -c 1 -f S16_LE -t raw' \
  --snd-command-rate 16000 \
  --snd-volume-multiplier 0.5 \
  --mic-auto-gain 30 \
  --detect-command '/home/satellite1/wyoming-satellite/awake.sh' \
  --tts-stop-command '/home/satellite1/wyoming-satellite/done.sh' \
  --mic-noise-suppression 2 \
  --wake-uri 'tcp://127.0.0.1:10400' \
  --wake-word-name 'hey_are_two' \
  --event-uri 'tcp://127.0.0.1:10500' \
  --awake-wav sounds/r2d2-awake.wav \
  --done-wav sounds/r2d2-done.wav
WorkingDirectory=/home/satellite1/wyoming-satellite
Restart=always
RestartSec=1

[Install]
WantedBy=default.target

Removing these two lines below from the config fixes the issue, so I assume there's something wrong with the scripts?!?! --detect-command '/home/satellite1/wyoming-satellite/awake.sh' --tts-stop-command '/home/satellite1/wyoming-satellite/done.sh'

Thanks in advance for any help.

llluis commented 6 months ago

I would say you are blocking the satellite loop and causing a timeout in the ping-pong between the satellite and home assistant. By your timestamps, the scripts run for more than 5s.

I'll try to test something after I finish reinstalling everything with python 3.12 (which is loooooooong).

vitalized commented 6 months ago

Not sure if this helps, but I have tried changing the _PONG_TIMEOUT and _PING_SEND_DELAY in the satellite.py file /home/satellite1/wyoming-satellite/wyoming_satellite/satellite.py

_PONG_TIMEOUT: Final = 30
_PING_SEND_DELAY: Final = 30
_WAKE_INFO_TIMEOUT: Final = 2
llluis commented 6 months ago

Not sure if this helps, but I have tried changing the _PONG_TIMEOUT and _PING_SEND_DELAY in the satellite.py file /home/satellite1/wyoming-satellite/wyoming_satellite/satellite.py

Didn't resolve?

llluis commented 6 months ago

I was able to replicate the behaviour if I block the detect script. However, I noticed what you really want is maybe the detection script. And this one seem to not cause disconnection issue when blocked.

What I had in mind didn't work to solve it. You would need to change your script to something like a non blocking fire and forget.

vitalized commented 6 months ago

Thank you so much for testing it and getting back to me. I kind of understand what you mean, but as you can see, I'm not really much of a coder. Can you explain what you mean by "You would need to change your script to something like a non blocking fire and forget.", or point me in the direction of info on how to make it a non-blocking script?

As a side note, what I'd really like is for the LED blinking to loop forever while the audio playback is happening (C-3PO is talking), then have a script to stop the LED blinking when the audio playback stops. Is this possible? I have tried using a third script using the --tts-played-command, but I can't get it to interact with the done.sh LED blinking script to stop the loop.