Make Domoticz speak from a dzVents script
Posted: Thursday 10 August 2017 17:15
I frequently use a dzVents helper function to have messages spoken. It can be that paper mail arrived, an alarm sensor has been tripped or that a door has been unlocked for a while. This is not a HOWTO. It's just an example how I have done it and it can be done differently.
I have a second Raspberry Pi that streams swedish radio all day using mpc (Command-line client for MPD). This machine is connected to an external speaker.
In a dzVents script, I do this:
The second argument tells the function that it is allowed to speak at night. If omitted, silence will not be broken.
Then I have defined a dzVents helper function in global_data.lua
The command is sent to run in the background and won't delay the Domoticz eventsystem.
My Domoticz host has been allowed to ssh into myotherhost (Authentication SSH-Keygen Keys)
Then on myotherhost I have a script named /home/user/scripts/sh/text2speech.sh :
It will pause the radio streaming using MPC in case it's playing. Current state is saved.
It raises the volume using amixer.
Then looks if that phrase has been spoken before.(All spoken phrases are saved on harddisk) If not it asks google translate to make a sound file for us and saves the file. It works for a lot of languages. Swedish works for example so Dutch would probably also be OK.
It plays the sound file(s) and resets the volume to normal.
Finally it restarts the radio streaming using mpc.
That's it. It sounds like it wouldn't work but it works more or less flawlessly.
There may be a lot of solutions out there for having Domoticz speaking. Before I used an old cellphone and tasker app for this. I had problems though that the phone wasn't reliable, it went to sleep sometimes or just disconnected from the WiFi. The TTS voice was nice and clear though.
It was hard to find a good TTS engine for my Raspberry Pi but Google Translate makes a decent work.
Feel free to post in this thread how you have solved the same task.
I have a second Raspberry Pi that streams swedish radio all day using mpc (Command-line client for MPD). This machine is connected to an external speaker.
In a dzVents script, I do this:
Code: Select all
domoticz.helpers.speak(domoticz, 'Hallå eller? Elva miljoner. I Balltorp', 1)Then I have defined a dzVents helper function in global_data.lua
Code: Select all
return {
data = {
},
helpers = {
speak = function(domoticz, speakMessage, canSpeakAtNight)
local NOTHINGTOSAY = 'Nothing to say'
speakMessage = speakMessage or NOTHINGTOSAY
canSpeakAtNight = canSpeakAtNight or 0
if ((domoticz.security ~= domoticz.SECURITY_DISARMED) and canSpeakAtNight == 0) then
return -- Not a good time to speak unless canSpeakAtNight flag was specified
end
domoticz.log('Speaking: '..speakMessage, domoticz.LOG_FORCE)
-- The following will execute as root and it's public key must have been added into authorized_keys
os.execute('ssh pi@myotherhost \'/home/user/scripts/sh/text2speech.sh ' .. speakMessage .. '\' > /dev/null 2>&1 &')
end,
}
}
My Domoticz host has been allowed to ssh into myotherhost (Authentication SSH-Keygen Keys)
Then on myotherhost I have a script named /home/user/scripts/sh/text2speech.sh :
Code: Select all
#!/bin/bash
ME=`basename "$0"`;
LCK="/var/tmp/${ME}.LCK";
exec 8>$LCK;
flock -x 8;
#echo "I'm in ($$)";
INPUT=$*
STRINGNUM=0
mpc | grep "playing" > /dev/null 2>&1
if [[ "$?" == "0" ]]; then
echo "mpc is playing"
mpc toggle
MPCPLAYS=1
else
MPCPLAYS=0
fi
amixer -q set Speaker 80%
ary=($INPUT)
for key in "${!ary[@]}"
do
SHORTTMP[$STRINGNUM]="${SHORTTMP[$STRINGNUM]} ${ary[$key]}"
LENGTH=$(echo ${#SHORTTMP[$STRINGNUM]})
#echo "word:$key, ${ary[$key]}"
#echo "adding to: $STRINGNUM"
if [[ "$LENGTH" -lt "100" ]]; then
#echo starting new line
SHORT[$STRINGNUM]=${SHORTTMP[$STRINGNUM]}
else
STRINGNUM=$(($STRINGNUM+1))
SHORTTMP[$STRINGNUM]="${ary[$key]}"
SHORT[$STRINGNUM]="${ary[$key]}"
fi
done
for key in "${!SHORT[@]}"
do
FILE=/home/pi/domoticz/phrases/$(echo ${SHORT[$key]} | gawk '{x = tolower($0); print x;}' | sed 's/[ \t]*$//' | sed 's/\.$//' | sed -e 's/[^a-z0-9_]/_/g'|sed -e 'y/åäöüé/aaoue/').mp3
if [ ! -f "$FILE" ]; then
echo "Requesting the file from google translate"
#echo "line: $key is: ${SHORT[$key]}"
#echo "Playing line: $(($key+1)) of $(($STRINGNUM+1))"
NEXTURL=$(echo ${SHORT[$key]} | xxd -plain | tr -d '\n' | sed 's/\(..\)/%\1/g')
wget --user-agent='Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0' "http://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&q=$NEXTURL&fl=sv&tl=sv" -O "$FILE"
fi
mpg123 -q --buffer 1024 "$FILE"
done
amixer -q set Speaker 40%
if [ "$MPCPLAYS" -eq "1" ]; then
echo "Restart mpc"
sleep 1
mpc toggle
sleep 1
fi
#echo "I'm done ($$)";It raises the volume using amixer.
Then looks if that phrase has been spoken before.(All spoken phrases are saved on harddisk) If not it asks google translate to make a sound file for us and saves the file. It works for a lot of languages. Swedish works for example so Dutch would probably also be OK.
It plays the sound file(s) and resets the volume to normal.
Finally it restarts the radio streaming using mpc.
That's it. It sounds like it wouldn't work but it works more or less flawlessly.
There may be a lot of solutions out there for having Domoticz speaking. Before I used an old cellphone and tasker app for this. I had problems though that the phone wasn't reliable, it went to sleep sometimes or just disconnected from the WiFi. The TTS voice was nice and clear though.
It was hard to find a good TTS engine for my Raspberry Pi but Google Translate makes a decent work.
Feel free to post in this thread how you have solved the same task.