Open khalob opened 7 months ago
That's a great idea!
It's surely possible. Just a matter to find the best solution.
Wouldn't an auto volume level based on the mic levels be as good ? Then if the noise in the room was loud it would be high volume. Like the mycroft auto volume
A temporary workaround that works system-wide is to SSH into the satellite:
alsamixer
I hope will be possible to expose the volume slider to home assistant BTW as mentioned above.
So another idea is to ssh in load a alsa profile?
alsactl -f /home/pi/asound.state restore
You could have different ones for each volume level...
I have worked a volume control method using Node-RED and MQTT. It is basic, and could use some polish, and it doesnt integrate brilliantly, but atleast there is volume control accessible inside home assistant.
This is installed on a Pi Zero 2 W setup as per https://github.com/rhasspy/wyoming-satellite/blob/master/docs/tutorial_2mic.md
the temporary solution above looks awesome, but could anyone please explain it in more simple terms?
I will make a gist about the process including some updates I have made. I will post here when available. I am doing some background research into including it natively in the project (not in its current form), but I am a bit time short at the moment so it wont be soon.
For now, Node-Red needs to be installed on the Pi (https://nodered.org/docs/getting-started/raspberrypi). In the Node-Red interface, you can import the Flow I included above (Some changes need to be made for the MQTT broker). Then in Home Assistant, you add the configuration block to your configuation.yaml.
You can do
amixer -M -c seeed2micvoicec set Speaker 10%
instead of alsamixer. That could be set to shell command in HA, and bound to input_number with automation. Not that i want to do it, i guess it would be much better to have inbuilt solution - but this is possible.
just going to add this here as it may help someone else also shrug. These are the steps i just took to do exactly that.
This guide will help you set up your Raspberry Pi volume control in Home Assistant. for example when using wyoming assist on a raspberry pi
ssh-keygen -t rsa -b 4096 -f /config/.ssh/id_rsa
ssh-copy-id -i /config/.ssh/id_rsa.pub pi@<Raspberry_Pi_IP>
ssh -i /config/.ssh/id_rsa pi@<Raspberry_Pi_IP>
amixer controls
Look for something that says 'PCM Playback Volume.' The start of that line will indicate the numid, which could be 0, 1, or another number. For example, if it says 0, then in the Pi terminal type:
amixer -c 0 sset PCM 90
Hit enter, and you should see a result like this:
Simple mixer control 'PCM',0
Capabilities: pvolume pvolume-joined pswitch pswitch-joined
Playback channels: Mono
Limits: Playback -10239 - 400
Mono: Playback 90 [97%] [0.90dB] [on]
If that works and the playback shows 90 or whatever number you chose, then continue with the steps below.
Create the Monitor Script: On your Raspberry Pi, create a script to monitor the ALSA volume and publish changes to an MQTT topic. Save the following script as /usr/local/bin/monitor_volume.sh
: remember to change the pi address of your HA MQTT broker, username and password and the amixer c1 number to the number you determined earlier.
#!/bin/bash
BROKER_ADDRESS="<your-HA-MQTT-Broker-IP>"
MQTT_TOPIC="home/assist/volume"
MQTT_USERNAME="<your-MQTT-username>"
MQTT_PASSWORD="Your-MQTT-Password>"
PREVIOUS_VOLUME=""
while true; do
CURRENT_VOLUME=$(amixer -c 1 get PCM | grep -oP "\[\d+%\]" | head -n1 | tr -d "[]%")
if [ "$CURRENT_VOLUME" != "$PREVIOUS_VOLUME" ]; then
mosquitto_pub -h "$BROKER_ADDRESS" -t "$MQTT_TOPIC" -u "$MQTT_USERNAME" -P "$MQTT_PASSWORD" -m "$CURRENT_VOLUME"
PREVIOUS_VOLUME="$CURRENT_VOLUME"
fi
sleep 5
done
1.2 In Home assistant, edit the configuration.yaml and add this under mqtt: sensor
mqtt:
sensor:
- name: Speaker Volume
state_topic: "home/assist/volume"
Set Up the Systemd Service: Create a systemd service to run the monitoring script automatically. Save the following as /etc/systemd/system/monitor_volume.service
on your assist pi:
[Unit]
Description=Monitor ALSA Volume and Send MQTT Messages
[Service]
ExecStart=/usr/local/bin/monitor_volume.sh
Restart=always
User=pi
[Install]
WantedBy=multi-user.target
Enable and Start the Service: Enable and start the service so that it runs on boot and monitors the volume continuously.
sudo systemctl enable monitor_volume.service
sudo systemctl start monitor_volume.service
Add Shell Commands: In your configuration.yaml
, add shell commands to control the volume.
NOTE: Replace pi@192.168.0.42
with your Pi's IP address as per Step 1.2) and replace amixer c 1
with whatever number you determined in Step 2.
shell_command:
volume_up: ssh -i /config/.ssh/id_rsa -o StrictHostKeyChecking=no pi@192.168.0.42 'amixer -c 1 sset PCM 5%+'
volume_down: ssh -i /config/.ssh/id_rsa -o StrictHostKeyChecking=no pi@192.168.0.42 'amixer -c 1 sset PCM 5%-'
volume_mute: ssh -i /config/.ssh/id_rsa -o StrictHostKeyChecking=no pi@192.168.0.42 'amixer -c 1 sset PCM toggle'
set_volume: >
ssh -i /config/.ssh/id_rsa -o StrictHostKeyChecking=no pi@192.168.0.42 'amixer -c 1 sset PCM {{ volume }}%'
Add an Input Number for Volume Control: In the same configuration.yaml
, add an input number to create a slider for volume control.
input_number:
speaker_volume:
name: Speaker Volume
initial: 50
min: 0
max: 100
step: 1
automation:
- id: 'set_pi_volume'
alias: Set Pi Volume
trigger:
- platform: state
entity_id: input_number.speaker_volume
action:
- service: shell_command.set_volume
data_template:
volume: "{{ states('input_number.speaker_volume') | int }}"
input_number.speaker_volume
entity will now reflect the Pi’s volume, and you can adjust the volume using this slider in the HA UI.volume_up
, volume_down
, volume_mute
, and set_volume
shell commands as needed.Here's an example automation that will sync the slider to whatever the assist speaker currently is set to:
- id: '1720785157943'
alias: Sync Speaker Volume
description: Sync the input_number with the sensor volume
trigger:
- platform: state
entity_id: sensor.speaker_volume
condition: []
action:
- data_template:
entity_id: input_number.speaker_volume
value: "{% if states('sensor.speaker_volume') not in ['unknown', 'unavailable'] %}
{{ states('sensor.speaker_volume') | int(default=50) }}
{% else %}
00
{% endif %}"
"
action: input_number.set_value
mode: single
In theory, you could also ask Assist to set speaker volume to 80%, although I haven't tried this yet, but there's probably no reason why you couldn't—get creative :)
EDITED: was missing a -c in original post, updated to to add the - , good catch thanks @ejpenney
When I check amixer controls I get the following:
tony@Aida-livingroom:~/wyoming-satellite $ amixer controls numid=4,iface=MIXER,name='Master Playback Switch' numid=3,iface=MIXER,name='Master Playback Volume' numid=2,iface=MIXER,name='Capture Switch' numid=1,iface=MIXER,name='Capture Volume'
When I type in amixer, it says my volume is at 90% but you can only just barely hear anything from my speaker.
tony@Aida-livingroom:~/wyoming-satellite $ amixer Simple mixer control 'Master',0 Capabilities: pvolume pswitch pswitch-joined Playback channels: Front Left - Front Right Limits: Playback 0 - 65536 Mono: Front Left: Playback 59000 [90%] [on] Front Right: Playback 59000 [90%] [on] Simple mixer control 'Capture',0 Capabilities: cvolume cswitch cswitch-joined Capture channels: Front Left - Front Right Limits: Capture 0 - 65536 Front Left: Capture 65536 [100%] [on] Front Right: Capture 65536 [100%] [on]
My setup is Wyoming Satellite, running on a raspberry Pi 4. I am using a USB mic and open wakeword. This part works fine, but for the life of me I can not get any audio out. HA logs show that TTS was sent to my pi.
My Satellite config is:
[Unit] Description=Wyoming Satellite Wants=network-online.target After=network-online.target
[Service] Type=simple ExecStart=/home/tony/wyoming-satellite/script/run --name 'Ada-Livingroom' --uri 'tcp://0.0.0.0:10700' --mic-command 'arecord -D plughw:CARD=JV601,DEV=0 -r 16000 -c 1 -f S16_LE -t raw' --snd-command 'aplay -r 22050 -c 1 -f S16_LE -t raw' WorkingDirectory=/home/tony/wyoming-satellite Restart=always RestartSec=1
[Install] WantedBy=default.target
@codemonkey2k5 did you try this https://github.com/rhasspy/wyoming-satellite/issues/106#issuecomment-2233497024 ?
It works for me. Just use 100% there.
I did try that, but it gave me an error about not existing. Honestly, it would be better if I could just run the satellite on my windows pc as a service. I'm in front of it all day and it has a mic and speaker that I know work well. I have python installed (running Ollama server) so I bet it can be done, but I only know enough to be dangerous when it comes to python. And I couldn't find any examples of anyone else doing it.
Thanks @LazzaAU ! This was super helpful, a couple of notes I ran into after doing C+P from your guide:
Example command:
amixer c 0 sset PCM 90
Should read:
amixer -c 0 sset PCM 90%
Might be worth noting some users may need to modify the field "User=" in /etc/systemd/system/monitor_volume.service
, if using non-default users.
Also, I modified the script to have the volume value retained in MQTT (-r) and use the last published value as PREVIOUS_VOLUME. This is useful because if volume isn't changed for several hours MQTT may mark it as unknown. Getting the previous value from MQTT adds additional assurance that the value is accurate and the script/MQTT haven't (somehow) gotten out of sync. This happened a couple of times in the hour I was playing with it, so I'm paranoid.
Granted, this service is a little less polite, querying every 5 seconds instead of only when it believes something has changed.
#!/bin/bash
BROKER_ADDRESS="<your-HA-MQTT-Broker-IP>"
MQTT_TOPIC="home/assist/volume"
MQTT_USERNAME="<your-MQTT-username>"
MQTT_PASSWORD="Your-MQTT-Password>"
PREVIOUS_VOLUME=""
while true; do
CURRENT_VOLUME=$(amixer -c 1 get PCM | grep -oP "\[\d+%\]" | head -n1 | tr -d "[]%")
if [ "$CURRENT_VOLUME" != "$PREVIOUS_VOLUME" ]; then
mosquitto_pub -h "$BROKER_ADDRESS" -t "$MQTT_TOPIC" -u "$MQTT_USERNAME" -P "$MQTT_PASSWORD" -m "$CURRENT_VOLUME" -r
fi
sleep 5
PREVIOUS_VOLUME=$(mosquitto_sub -h "$BROKER_ADDRESS" -t "$MQTT_TOPIC" -u "$MQTT_USERNAME" -P $MQTT_PASSWORD -C 1)
done
Great work, love what you do as always. I know this is an "in progress" situation, but installing this got me thinking:
It would be nice to be able to adjust the
--snd-volume
via a slider in Home assistant or some external means. (See existing home assistant slider example image bellow)Use case: sometimes I want my speaker loud, sometimes I do not. Ideally I would adjust it via voice commands :)