Thursday, June 2, 2016

Asterisk PBX and IBM Watson Text to Speech

Evaluating IBM Watson Text to Speech API with Asterisk PBX. Using a Bash script to create and format the recording. Script uses curl and avconv commands. This is running on Ubuntu 14.04 with Asterisk 11.7.0.

Bash script /usr/share/asterisk/agi-bin/tts_ibm.sh for Asterisk Gateway Interface (AGI)

#!/bin/bash
#
# Use IBM Watson text to speech service for Asterisk.
#
text=""
regex="200 result=1 \((.*)\)"
checkresults() {
  while read line
  do
    logger "$0 $line"
    case ${line:0:4} in
      "200 " ) echo $line >&2
               if [[ $line =~ $regex ]]
               then
                 text="${BASH_REMATCH[1]}"
               fi
               return;;
      "510 " ) echo $line >&2
               return;;
      "520 " ) echo $line >&2
              return;;
      *      ) echo $line >&2;;
    esac
  done
}
echo "GET VARIABLE text0"
checkresults
textHash="$(/bin/echo $text | md5sum | awk '{print $1}')"
originalFile="/tmp/$textHash"
finalFile="/tmp/final$textHash.wav"
logger "$0 Hash: $textHash original: $originalFile file: $finalFile"
if [ -f $finalFile ]
then
  logger "$0 File $originalFile already exists. Not contacting IBM."
else
  logger "$0 Creating file $originalFile. Contacting IBM."
  /usr/bin/curl -s -X POST -u USERNAME:PASSWORD \
    --header "Content-Type: application/json" \
    --header "Accept: audio/wav" \
    --data "{\"text\":\"$text\"}" \
    --output "$originalFile" \
    "https://stream.watsonplatform.net/text-to-speech/api/v1/synthesize"
  /usr/bin/avconv -loglevel quiet -y -i $originalFile -ar 8000 -ac 1 -ab 64 $finalFile
fi
fileWithoutExtension=${finalFile%.*}
logger "$0 Stream file $fileWithoutExtension"
echo "STREAM FILE $fileWithoutExtension \"\""
checkresults
exit 0;

Dial plan snippet /etc/asterisk/extensions.conf

[PremiseVisitSurvey]
exten => s,1(StartPremiseVisitSurvey),Wait(0.3)
  same => n,Set(text0=This is ABC Company with a five question survey about your recent service visit. After each question, press 1 for yes, or press 2 for no.)
  same => n,Set(randomNumber=${RAND()})
  same => n,agi(tts_ibm.sh)
  same => n,Set(text0=Did your recent ABC Company service visit meet your satisfaction?)
  same => n,agi(tts_ibm.sh)
  same => n,Playback(beep)
  same => n,Read(response,,1)
  same => n,System(/opt/scripts/postIvrResponse.sh ${phoneNumber} ${CONTEXT}_1_${randomNumber} ${response} ${accountNumber} ${orderNumber})
  same => n,Set(text0=Were you satisfied with the timeliness of the service?)
  same => n,agi(tts_ibm.sh)
  same => n,Playback(beep)
  same => n,Read(response,,1)
  same => n,System(/opt/scripts/postIvrResponse.sh ${phoneNumber} ${CONTEXT}_2_${randomNumber} ${response} ${accountNumber} ${orderNumber})
  same => n,Set(text0=Were you satisfied with the quality of the service?)
  same => n,agi(tts_ibm.sh)
  same => n,Playback(beep)
  same => n,Read(response,,1)
  same => n,System(/opt/scripts/postIvrResponse.sh ${phoneNumber} ${CONTEXT}_3_${randomNumber} ${response} ${accountNumber} ${orderNumber})
  same => n,Set(text0=Was the ABC Company technician knowledgeable and professional?)
  same => n,agi(tts_ibm.sh)
  same => n,Playback(beep)
  same => n,Read(response,,1)
  same => n,System(/opt/scripts/postIvrResponse.sh ${phoneNumber} ${CONTEXT}_4_${randomNumber} ${response} ${accountNumber} ${orderNumber})
  same => n,Set(text0=Would you like a follow-up call to discuss your responses to this survey?)
  same => n,agi(tts_ibm.sh)
  same => n,Playback(beep)
  same => n,Read(response,,1)
  same => n,System(/opt/scripts/postIvrResponse.sh ${phoneNumber} ${CONTEXT}_5_${randomNumber} ${response} ${accountNumber} ${orderNumber})
  same => n,Set(text0=Thank you. Good bye.)
  same => n,agi(tts_ibm.sh)
  same => n,hangup()

Call file /var/spool/asterisk/outgoing/premise_visit_survey_123456.call

CallerID: IVR <8431234567>
Channel: SIP/8431234567@abccompany
Context: PremiseVisitSurvey
Extension: s
Archive: Yes
MaxRetries: 0
SetVar: phoneNumber=8431234567
SetVar: accountNumber=123456789
SetVar: name=John Doe
SetVar: recordingName=premise_visit_survey_8436285480_20160602_81045
SetVar: orderNumber=123456

Sunday, April 10, 2016

Whole Home Audio using Chromecast Audio

Whole home audio is awesome. I am using the following:

Kodi is installed on a mini ITX i3 Ubuntu box connected to my TV. Also installed on the Ubuntu box is pulseaudio-dlna. There are 3 Google Chromecast audio devices on my network in an audio group. The Chromecast devices are connected to my stereo in the living room, a boombox in the living room and a boombox in the bathroom. My music resides on another Ubuntu box and is served over NFS. On boot Kodi starts playing music in party-mode.

Interesting items on the Ubuntu Kodi device are:

  • Party mode autostart add-on
  • Auto-login set in Ubuntu
  • Kodi auto-start script
  • Pulseaudio-dlna auto-start specifying port 8082 so it does not interfere with Kodi web interface on port 8080

Controlling playback can be accomplished with whatever is convenient

  • Yatse Android remote app
  • Kodi web interface
  • Ubuntu Unity Launcher Kodi Remote

Kodi auto-start script

#!/bin/bash
# Loop Kodi in case you exit by mistake.
while true
do
 /usr/bin/kodi
done

Kodi auto-start setting

Pulseaudio DLNA auto-start setting

Ubuntu Sound Settings

Kodi Sound Settings

Logitech boombox with Chromecast Audio

Yatse Android Kodi Remote App

Ubuntu Unity Launcher Kodi Remote

Kodi Web Interface

Monday, March 28, 2016

Time Lapse Video Workflow

  1. Create images using GoPro Hero3-Black Edition
  2. Crop images using ImageMagick from 4000x3000 (4:3) images to 4000x2250 (16:9) mogrify -crop 4000x2250+0+0 *
  3. Import images into a Lightworks 1080p 30fps project
  4. Export the finished edit
  5. Upload video to YouTube
My Time Lapse channel.

 

Thursday, January 21, 2016

Quickest Method to Install and Try a Linux Distribution - Use netboot.xyz

Here is the easiest and quick way to try out a Linux distro. Use netboot.xyz and the following 4 commands.
  1. Download the ISO: wget --no-clobber http://boot.netboot.xyz/ipxe/netboot.xyz-dhcp.iso
  2. Create a disk for your VM: qemu-img create -f raw vm02disk 8G
  3. Start the VM and install a distro: qemu-system-x86_64 -enable-kvm -cdrom netboot.xyz-dhcp.iso -m 2G -drive file=vm02disk,format=raw
  4. Run your new VM: qemu-system-x86_64 -enable-kvm -m 2G -drive file=vm02disk

http://netboot.xyz/

Monday, January 18, 2016

PING Image Servlet

PingImageServlet returns a green image if IP address is PING'able and returns a red image when it is not PING'able. Use it to add visual indications of device status on web pages. HTML example: <img src="http://pi.pla1.net?ip=8.8.8.8"> 8.8.8.8<br>

8.8.8.8
8.8.4.4
127.0.0.1
169.254.254.254
169.254.254.253
208.67.222.222
208.67.220.220

Thursday, December 24, 2015

Copying Images from Disk to SD Cards

I've been using the dd command to copy images to SD cards for my Raspberry Pi's. I've found a faster way that takes 2+ minutes versus 11+ minutes.

Old way

dd bs=4M if=2015-05-05-raspbian-wheezy.img | pv --size=3276800000 | dd of=/dev/sdX && sync

3.05GB 0:11:25 [4.56MB/s]

New way

pv --size=3276800000 2015-05-05-raspbian-wheezy.img > /dev/sdX && sync

3.05GB 0:02:30 [20.8MB/s]

NOTES: I prep the SD card before the copy with these steps:

  • Become root sudo su
  • Un-mount the SD card. umount /media/SOMEUSER/SOMEMOUNT
  • Find the drive letter for the SD card. I use the command lsblk and/or the GUI gnome-disks. Make sure you double-check your drive letter. dd will destroy anything in its path. I've used sdX in my examples.
  • Wipe the SD card: dd if=/dev/zero of=/dev/sdX bs=512 count=1 conv=notrunc
Tests performed with Ubuntu 14.04, SanDisk SDHC I 32GB, Lexar USB 3.0 adapter.

Wednesday, June 10, 2015

Map IP Connections

Display IP connections from and to your Linux box on a map. Alternatively works with Cisco ASA syslog records. Outgoing connections are green markers and incoming connections are red markers. Uses iptables, tailf, websocketd, indexedDB, Javascript, Google Maps and Telize geoip api. Tested on Ubuntu 14.04 and 15.04. In the animated GIF below I go to a website in the US, Russia, and Japan. Let me know if you find it useful. Source code on Github.