Thursday, February 11, 2016

The Evolution of Pi - Part I

A few years ago, I bought a Raspberry Pi model B for my son as a Christmas gift, hopefully he would show some excitement. Understandably now that it didn't turn out so.

It was in the closet for a few years, then a need for a project surfaced:
We often get phone calls during diner time. We either rush over to the phone and found it was a telemarketing call, or sitting and worrying that we might miss an important call. Wouldn't it be great if the phone can make voice announcement?

There are multiple possibilities:

  • We could buy a phone with such features, but that would be lame, Plus it would be against my philosophy of doing more with what we have.
  • Very few phones could announce both the number and name from the caller ID.
  • It really costs money if you want to buy a cordless system, with voice mail, etc.
Why not use the Pi (from the closet) to monitor the phone with a modem, and send the voice output to a speaker?
  • The only additional thing we would need was a USB modem. The Trendnet TFM-561U looked like a perfect little device. The price was great.

The Solution Details:

The Pi needs to be connected to some audio device, that is loud enough so we can hear easily at the other end of the house. The Pi would quietly monitor the phone line via the modem, When a call comes in, it would announce the caller ID (number & name) to the audio output.

We have a pair of cheap PC speakers, and we could switch it on/off with the Pi using a relay. But I must concede the voice has a lot to be desired :-(  Then, why not connect the Pi to the Yamaha RX-V473 receiver -- great sound and can be as loud as we want. There are a few lingering challenges.
  1. For this to work, the receiver needs to be on. But we don't want to leave the receiver on all the time just for the few phone calls.
  2. Also, if the receiver is set for a different source (like watching a movie) and a call comes in, it would ignore the announcement.
Some research (and reading the manuals of the RX-V473) discovered that it is a rather intelligent device. Not only it is network enabled, it also has API so you can control it. Even better, there is a python library called rxv that is readily available.  We also added a few nice features
  • Save the current state (mode/source, volume, etc) and restore it at the end of the caller ID announcement. 
  • Use Google Translate API (translate shell) to transform a text string to voice. We also decided to enjoy English, Chinese, and Spanish for most part.

Here is the code for the script:
#!/usr/bin/python
#usage: yamaha-rx-v473.py [translate string]
#ex:    yamaha-rx-v473.py  #announce in English
#ex:    yamaha-rx-v473.py  EN=zh-CN #announce in Chinese

import rxv, shlex, subprocess, sys, os, time
receivers = rxv.find()
rx = receivers[0]
# Save current stats
save_power = rx.on
save_volume = rx.volume
save_input = rx.input

if not save_power:
  rx.on = True

rx.input = 'AUDIO'
rx.volume = -22

#read standard in into an array so we can pipe it out multiple times
list=[]
for line in sys.stdin:
    list.append(line)

#play the message, trans automatically handle multiple lines of inputs.
FNULL = open(os.devnull, 'w')
subargs = shlex.split('/usr/bin/trans -p -player /usr/bin/mpg123 -b')
subp = subprocess.Popen(subargs, stdin=subprocess.PIPE, stdout=FNULL, stderr=FNULL)
for line in list :
    subp.stdin.write(line)
subp.stdin.close()
subp.wait()

if len(sys.argv) == 2:
    subargs = shlex.split('/usr/bin/trans -p -player /usr/bin/mpg123 -b ' + sys.argv[1])
    subp = subprocess.Popen(subargs, stdin=subprocess.PIPE, stdout=FNULL, stderr=FNULL)
    for line in  list :
        subp.stdin.write(line)
    subp.stdin.close()
    subp.wait()

#sleep for 3 seconds between swiching back. So the receiver isn't turned off 
#too early before the announcement is over.
time.sleep(3)

#Restore the saved values
rx.input = save_input
rx.volume = save_volume

#Send system standin to subprocess and play it
if not save_power:
  rx.on = False

Tying'em Together:

Of course, there is also the code of interacting with the modem. For that the NCID package works perfectly as advertised. In particular, we configured the ncid-speak to invoke the custom python script. Of course, we created the rc scripts, and "update-rc.d" to start ncidd and ncid-speak at boot time.

Reflections:
We have had the system up and running for about a year now (as of Feb 2016), by and large it worked great. We had to update the translate-shell a few times, as Google changes its API. As good as it is, it takes the on-going feeding, which is beyond the appetite of most typical households. So buying a phone with voice announcement might not be a bad idea. Pulling all the pieces together was great.

No comments:

Post a Comment