Part 1 – The Basics (using a Linux VM)
Intro
After trying and failing to get SiriProxy up and running last year, I was inspired to get it working on my Raspberry PI by this article, but had much grander plans. There have been lots of posts about installing a SiriProxy, but a lot are very specific applications that don’t interest me (using GPIB to open a garage door for example) or there have been too many vagaries in the instructions: usually because your environment is different from the authors. My aim is to remedy this so that mere mortals can enjoy tinkering with Siri.
As expected, while following the instructions in the above article, everything didn’t go as expected. Further, in addition to installing on my Raspberry PI, I installed the SiriProxy on a Linux VM while tinkering with MythTV. Having now installed this over a dozen times on several distro’s of Linux and discovered there are slight nuances with each, I’m pretty experienced with the SiriProxu installation and configuration process.
In this article, I’ll show where to download a 55MB VMWare appliance and provide all the instructions to have a siri proxy server up and running (guaranteed) in about 30 mins. (On my last run through, it took me about 10 minutes.) I also include instructions to install it on a Raspberry PI running Raspian—Debian Wheezy. This takes a few hours, as the Raspberry is much slower: Ruby install takes over an hour. That said, functions perfectly once installed.
In addition, I’ll give you download links to my guaranteed virus/spyware free (to the best of my knowledge) working LinuxVM and Raspberry PI image. All that’s needed for these to be deployed is to change an IP address in one file, install the certificate on your phone and you’ll have a working SiriProxy server in about 10 minutes. For those who prefer this approach, skip to the downloads section.
Skills Required
You should be able to complete this with little or no Linux knowledge. For those who are totally new to Linux, I’ve include a section called “Linux Fundamentals”, which includes a few helpful tips for getting around.
I’m no expert on Linux; however, I worked in R&D about 10 years ago and developed an automated benchmarking tool entirely with UNIX shell scripts. The tool could control from one to (theoretically) an unlimited number of IBM RS6000 machines running IBM’s AIX operating system. I also developed a number of tools with shell scripts. That said, everything I developed was for turnkey systems that had no communications with the outside world, so I never had to be too concerned with security, etc. I’ve also forgotten most of it. Over the last few weeks, I’ve unintentionally re-learned a lot of this.
I’m assuming you’re running a bash shell, but I don’t think there’s anything in the commands that wouldn’t work with other shells (other than a few things related to .bash_profile)
NOTE: if you transfer any scripts from windows to UNIX use dos2unix to fix line endings (see installing dos2unix)
My Configuration
There’s nothing special about my configuration.
- iPhone 5 (6.0.2)
- VMWare Player 5.0.2 on Windows 8
Linux Distros
I’ve successfully got the SiriProxy working on the following.
- VMWare – Jeos VMWare Applicance (Ubuntu 12.04LTS) – 55MB download!
- VMWare – LinuxMint14 with Mate (Ubuntu 12.10)
- VMWare – Ubuntu 12.10 Desktop
- RapsberryPI (Model B, 2GB SD Card) – Debian Wheezy
These instructions focus on No 1, as it’s such a small download (but no GUI). I’ve included some tips you may need if you’re using one of the other distros mentioned. There are also instructions for Raspberry installation below
How Does the SiriProxy Work?
When you say something to Siri, it simultaneously sends it to Apple’s server and sends it a recognition engine on the iPhone to see if it’s something that can be executed locally (like “Open Safari” or “Play Stairway to heaven”)
If the command can be serviced locally, the server request is cancelled. If not, it waits for a response from the server.
When the SiriProxy server is installed (and the iPhone is pointed at it) it essentially behaves as a local recognition engine on the LAN. Instead of commands being sent to the Apple server, they are sent to the local SiriProxy. If they are recognized there they respond to the phone (as if it’s Apple’s server), if not, they are forwarded to Apple’s server as normal.
This essentially gives us a precedence:
- iPhone
- SiriProxy
- Apple Server
When integration with a Home Automation system, No 1 can be a real pain as commands like “Open…”, “Play…”, etc. are interpreted by the iPhone as commands to run apps or play songs/videos.
Installation
If you’re using the 55MB Jeos (pronounced “juice”) download then start here. The key commands are in red, so if you want skip all the verbage, just run the commands in red.
If you’re using your own VM. Skip ahead to “Main SiriProxy Install”. (You may want to create a user called “siri”. If not, just make sure you swap your user name anywhere you see “/home/siri/”.) There are a few things you made need to do. These are highliighted in green.
If you’re using my pre-configured VM, go to the downloads section and follow the instructions there.
Installing the Linux Virtual machine
Download and install VMWare Player (Windows) or VMWare Fusion for Mac
Download Virtual Appliance and Unzip (https://solutionexchange.vmware.com/store/products/12-04-lts-jeos-ubuntu )
Go to VMWare Player, Select Open a Virtual Machine, browse to extracted folder and open the VM (Ubuntu-12.04-LTS-Jeos-1.0.ovf)
Click Virtual Machine Settings
- Allocate RAM (I’m using 1GB on 8GB host PC, you can probably use much less)
- Set networking to Bridged mode (very important)
That’s it. Click “Play Virtual Machine” and voila!, a Linux VM is running
Linux Configuration
We’ll need to do the first few steps as root. Once we get sudo installed, we’ll switch to a regular user. If any of the commands prompt for confirmation, say yes.
Login as user: root password: root
An Easier to use Editor than vi
Most people aren’t that comfortable with the vi editor, so the first thing we’ll do is get an easier to use editor. Before doing this, we’ll update our packager manager sources so it has all the latest info. If you’re OK with vi, skip this. Even with nano, it’s unlikely your number pad will work, so use the numbers on the main keyboard when editing.
Update Package Manager Sources
apt-get update
Editor
Skip this if comfortable with vi
apt-get install nano
Update Package Sources
Now we’ll edit our Package Source list (required later to get dnsmasq). There were a lot of changes in dns and dhcp in 12.04 and later. So I just installed dnsmasq as normal. This will fail if the sources are not updated. (If anyone knows how to setup the DNS entries correctly with Network Manager in 12.04 and later, I’d be grateful for the instructions.)
nano /etc/apt/sources.list
Change the line in this file from:
deb http://archive.ubuntu.com/ubuntu precise main
to
deb http://archive.ubuntu.com/ubuntu precise main universe restricted multiverse
Save and Exit (Ctrl-O, Enter, Ctrl-X)
Now update sources again
apt-get update
Create hosts file
nano /etc/hosts
Add a line containing the following (or whatever hostname you like) then save and exit
127.0.0.1 ubuntu
Get sudo
It’s considered poor practice to do everything as root (su). The best practice is to add a user to the sudo group, which will allow them to execute commands as su. (e.g. sudo reboot). First we’ll install sudo:
apt-get install sudo
Create a new user
Add user for siri (this can be any user, I just setup a dedicated user called “siri: so I could remember it easily. I also set my password to “siri”)
adduser siri
Add to sudo group
adduser siri sudo
Logout (Ctrl-D) and log back in as user siri
Install Ancillary Packages
These are just a bunch of things that I find makes it easier. Skip any you feel you don’t need.
OpenSSH Server
I prefer to use SSH instead of running a terminal in the in VM (easier to copy and paste and don’t have to keep pressing Ctrl-Alt to get the mouse out of the VM and back into windows). You can skip this step if you’re happy to use a terminal.
sudo apt-get install openssh-server
Now, it’s possible to ssh to the VM. TerraTerm is great and free SSH/Telnet client
Find out IP address
In order to connect we need to find out IP address
ifconfig
Look for IP address next to eth0 and inet addr
If it’s not on same network as your PC/Mac, you probably didn’t enable bridged mode. (See instructions above.) Close the VM and change network setting then restart VM.
Main SiriProxy Install
I’ve added a user named siri (see creating a VM). If you’re using a different user, anywhere you see “/home/siri” replace “siri” with your user name and check items in green.
Start here if you’ve already got a distro installed (i.e. not using the Jeos VM). The key commands are in red, so if you want skip all the verbage, just run the commands in red.
If you’re not using Jeos you may need to be running a login shell for this.
One common way to check is to run:
echo $0
If the result starts with a “-“ (i.e. “-bash”) it’s a login shell.
If it doesn’t start a login shell:
bash -l
or
bash --login
Networking
You’re going to need a static IP or DHCP reservation. If you use DHCP, setting up a reservation is best. To find the Mac address and current IP run ifconfig (as shown above). Do this first and then reboot (or restart the networking services if you know how) before continuing.
1. Install Required Packages
sudo apt-get install dnsmasq ruby build-essential openssl libreadline6 libreadline6-dev curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-0 libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev ncurses-dev automake libtool bison subversion
Select ‘y’ to continue.
2. Edit DNS
(You can skip this if you have another DNS server on your network and can configure it there.)
sudo nano /etc/dnsmasq.conf
Find the line starting with: #address=/double-click.net/127.0.0.1 (use Ctrl-W to search)
Add a new line redirecting the Apple’s Siri server to your Linux VM’s IP
address=/guzzoni.apple.com/192.168.168.63
Save and exit (Ctrl-O, Enter, Ctrl-X)
Restart dnsmasq
sudo /etc/init.d/dnsmasq restart
Test DNS is resolving correctly
ping guzzoni.apple.com
as soon as you see an IP address (almost immediately).
Ctrl-C
This should return Apple’s IP address (I got 17.174.8.16). Apple blocks ICMP, so the pings will timeout just make sure it resolves into a 17.x.y.z address.
If it doesn’t, it’s DNS issue and on Ubuntu 12.04 onwards, it’s probably a conflict a conflict with network manager. See “Problem XXX” below). (I’d be eternally grateful if someone could tell me how to do this step correctly when running NM on 12.04+)
3. Install RVM
bash < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)
Don’t worry about the warning in red, the next two commands take care of it
Load RVM as a function and update profile
[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm"
echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm" # Load RVM function' >> ~/.bash_profile
rvm install 1.9.3
(answer “Y” to all prompts – takes quite a while to run)
Don’t worry if you see two messages saying failed to make directories. It’s always worked for me, despite these.
Set Ruby 1.9.3 as default
rvm use 1.9.3 --default
4. Install the SiriProxy
git clone git://github.com/plamoni/SiriProxy.git
cd SiriProxy
Select ‘y’ to warning to continue.
mkdir ~/.siriproxy
cp ./config.example.yml ~/.siriproxy/config.yml
rake install
echo 'export rvmsudo_secure_path=1 ' >> ~/.bash_profile
source ~/.bash_profile
5. Generate Certificates
siriproxy gencerts
6. Install the Certificate on your iPhone
You can use any mechanism to get it to the iPhone. As I’m using TerraTerm, I just used SSH SCP (File menu -> SSH SCP…)
Another great alternative (if you’ll be doing a lot of editing on your local machine is WinSCP):
E-mail the certificate yourself, click it and install on phone (ignore warning about it being untrusted)
7. Run Bundler
rvmsudo siriproxy bundle
8. Start the server
rvmsudo siriproxy server
A message should appear saying something like:
Starting SiriProxy on 0.0.0.0:443.. SiriProxy up and running.
9. Set DNS server on phone
The last step is to point your iPhone at your DNS server. This will be the Linux VM’s IP unless you are using an external DNS server.
- Got to Settings -> Wi-Fi
- Click the blue arrow next to your connection
- Enter the Linux VM’s IP
10. Test
Press and hold the home button.
(If you got an error—highly likely, see the fixes below – especially InvalidByteSequence)
Say the exact phrase “Test Siri Proxy”. It should respond with exactly “Siri Proxy is up and running”. The output on the terminal should be something like this:
Create server for iPhone connection start conn #, @zip_stream=#, @consumed_ace=false, @name="iPhone", @ssled=false> [Info - Plugin Manager] Plugins laoded: [#>] [Info - iPhone] Received Object: LoadAssistant [Info - iPhone] Received Object: SetRestrictions [Info - iPhone] Received Object: SetRestrictions [Info - iPhone] Received Object: ClearContext [Info - iPhone] Received Object: SetSessionObjects [Info - Guzzoni] Received Object: AssistantLoaded [Info - iPhone] Received Object: StartSpeechRequest [Info - iPhone] Received Object: SetRequestOrigin [Info - User Location] lat: XX.07408038900973, long: -YY.70323611215576 [Info - iPhone] Received Object: SpeechPacket [Info - Guzzoni] Received Object: SetConnectionHeader [Info - iPhone] Received Object: SpeechPacket [Info - iPhone] Received Object: SpeechPacket [Info - iPhone] Received Object: SpeechPacket [Info - iPhone] Received Object: SpeechPacket [Info - iPhone] Received Object: SpeechPacket [Info - iPhone] Received Object: SpeechPacket [Info - iPhone] Received Object: SpeechPacket [Info - iPhone] Received Object: SpeechPacket [Info - iPhone] Received Object: SpeechPacket [Info - iPhone] Received Object: SpeechPacket [Info - iPhone] Received Object: FinishSpeech [Info - Guzzoni] Received Object: SpeechRecognized [Info - Plugin Manager] Processing 'Test Siri proxy ' [Info - Plugin Manager] Processing plugin # [Info - Plugin Manager] Matches (?i-mx:test siri proxy) [Info - Plugin Manager] Applicable states: [Info - Plugin Manager] Current state: [Info - Plugin Manager] Matches, executing block [Info - Plugin Manager] Say: Siri Proxy is up and running! [Info - Plugin Manager] Sending Request Completed
Running the proxy after initial power on
Make sure you’re in a login shell (echo $0). If not run bash -l.
cd SiriProxy
rvmsudo siriproxy server
If you want to connect to a headless server, start the server, then disconnect, use one of these methods. I prefer tmux.
- nohup
- screen
- tmux
Using tmux
- ssh or telnet to server
- run tmux
- start siriproxy server
- close ssh/telnet
- reconnect via ssh or telnet
- tmux attach
Adding Functionality
Simple Messages
In order to extend the functionality,you need to edit the siriproxy-example.rb in the plugin directory. If you’re running a GUI, use a decent graphical editor. If not, you can copy to PC/Mac, edit and copy back. Way easier if you’re making extensive changes. WinSCP is great for this
sudo nano ~/SiriProxy/plugins/siriproxy-example/lib/siriproxy-example.rb
Then simply copy and paste “listen_for” sections:
See “Home Automation Integration” for more examples.
After changing the config, the SiriProxy needs updating – run:
siriproxy update .
(Note the period. This will cause the update to use the local clone of the repo instead of going to github. Saves a few seconds).
rvmsudo siriproxy server
Running Linux Commands
This is the way I’m integrating with my Home Automation System (more on that later)
“Puts %x{ }” runs the command between braces. (back ticks also work).
Alternatively, the system function can be used:
system("ssh root@192.168.168.23 shutdown -h now")
Adding Plug-ins
I have a Radio Thermostat CT-30 which is the same as the one that the original developer of the Proxy has, so I downloaded this. If you’ve worked with Ruby, Bundler and git before, the instructions on the site will probably make sense. Unfortunately, it made little sense to me, so here are the exact steps I figured out:
sudo nano ~/.siriproxy/config.yml
Uncomment the following lines and change the IP to match your thermostat’s. Note: the column alignment and spacing are critical on this, so make sure you match the example.
- name: 'Thermostat' git: 'git://github.com/plamoni/SiriProxy-Thermostat.git' host: '192.168.168.200'
If the lines are not there, copy from the config.yml at https://github.com/plamoni/SiriProxy-Thermostat
If you want a local copy for updates, use git clone
cd ~/SiriProxy
siriproxy update
rvmsudo siriproxy server
Test by entering a phrase such as “Get Thermostat Status” or “Set Thermostat to 72 degrees”
A list of other plug-ins can be found here: https://github.com/plamoni/SiriProxy/wiki/Plugins
Known Errors and Fixes
InvalidByteSequenceError
It’s extremely likely that the first time you test, you’ll get an error on the Linux host when you hold down the home button
/home/siri/.rvm/gems/ruby-1.9.3-p374@SiriProxy/gems/CFPropertyList-2.2.0/lib/rbBinaryCFPropertyList.rb:217:in `encode': "\xDD" followed by "n" on UTF-8 (Encoding::InvalidByteSequenceError)
This seems to be due to CFPropertyList-2.2.0 being downloaded in place of CFPropertyList-2.1.2. I’ve seen various suggestions for a fix (google it). I know this is not the right way to do it, but it worked every time. We’re basically downloading CFPropertyList-2.1.2 and copying its contents to the 2.2.0 directory.
gem install CFPropertyList -v 2.1.2
sudo cp -r ~/.rvm/gems/ruby-1.9.3-p374@SiriProxy/gems/CFPropertyList-2.1.2/* ~/.rvm/gems/ruby-1.9.3-p374@SiriProxy/gems/CFPropertyList-2.2.0
rvmsudo siriproxy server
siriproxy: No such file or directory
You’re in the wrong directory. Run
cd ~/SiriProxy
(see “Running the proxy after initial power on”)
Config.yml not found
If you get a message saying “config.yml not found. Copy config.example.yml to config.yml, then modify it.” Make sure it’s there. If it is there, it’s probably because it’s looking in /root/.siriproxy directory (because of rvmsudo). This can be fixed by making a symbolic link to /root/.siriproxy
sudo ln -s ~/.siriproxy /root/.siriproxy
zlib(finalizer): the stream was freed prematurely (after very fast scrolling of error messages)
This error is a DNS issue. This is because guzzoni.apple.com is resolving to your local IP and not apple.
It shouldn’t happen if you’re using Jeos as Network-manager is not installed. If you’re using a normal distro of Ubunto 12.04 or 12.10, this should help. I don’t fully understand the issue (here’s a full explanation: http://www.stgraber.org/2012/02/24/dns-in-ubuntu-12-04/ ) and wasted a lot of time trying to find out how to enter the equivalent DNS entry in 12.04.
I don’t recall the exact steps, but I’m pretty sure it was
sudo nano /etc/NetworkManager/NetworkManager.conf
comment out the line: dns=dnsmasq
sudo restart network-manager
sudo apt-get remove --purge resolvconf
Other Good Sources Installation/Configuration Info
In Part 2, we’ll cover how to install SiriProxy on the Raspberry PI, and in Part 3, we’ll look at Home Automation integration.
Downloads
If you don’t have the time or inclination to start from scratch, you can download a fully configured working VMWare Appliance or Raspberry PI image, change a few settings and be up and running.
VM Installation
These only require the free version of VMWare. (The Mac and Windows downloads below are identical.)
Mac OS X (VMWare Fusion) | Windows (VMWare Player) | Raspberry PI |
---|---|---|
Download the VMWare ZIP (239MB)Select File -> ImportBrowse to the vmx and select itClick “Upgrade” (if prompted)Select “I copied it” when promptedLeave networking set BridgedClick the “Play” or “Power On” button | Download the VMWare ZIP (239MB)Select “Open a Virtual Machine”Browse to the vmx and select itClick “Upgrade” (if prompted)Select “I copied it” when promptedLeave networking set BridgedClick “Play the Virtual Machine” | Download the SD Image (7-zip format) (423MB)Use an image copying tool to copy the image to an SD card (MINIMUM 8GB) – (See Part 2 for imaging the SD card)Insert into RaspberryPower On |
Configuration
Once you reach the login prompt the procedure should be the same for all three platforms
login as siri
password siri
1. IP address
run ifconfig to find IP address
Make this static or setup a DHCP reservation. If you change it from it’s initial address, reboot (sudo reboot)
2. DNS
edit dnsmasq and enter your VM’s new IP
sudo nano /etc/dnsmasq.conf
Find the line containing guzzoni.apple.com (use Ctrl-W to search) and change IP
address=/guzzoni.apple.com/192.168.168.63
Save and exit (Ctrl-O, Enter, Ctrl-X)
Restart dnsmasq
sudo /etc/init.d/dnsmasq restart
Test DNS is resolving correctly
ping guzzoni.apple.com
Type Ctrl-C as soon as you see an ip address (almost immediately)
This should return Apple’s IP address (I got 17.174.8.16). Apple blocks ICMP, so the pings will timeout just make sure it resolves into a 17.x.y.z address.
3. Install certificate
e-mail yourself the certificate from (see step 6 in part 1 for methods)
/home/siri/.siriproxy/ca.pem
install on phone
4. Point iPhone DNS at VM
The last step is to point your iPhone at your DNS server. This will be the Linux VM’s IP unless you are using an external DNS server.
- Got to Settings -> Wi-Fi
- Click the blue arrow next to your connection
- Enter the Linux VM’s IP
5. Start server
cd ~/SiriProxy
rvmsudo siriproxy server
6. Test
Press and hold home button
Say exactly “Test Siri Proxy
It should respond with exactly “Siri Proxy is up and running”
For those who want to learn how to install the SiriProxy on a Rasberry PI, continue to Part 2. For details about integrating the SiriProxy with other systems (such as Home Automation systems), see Part 3.
Linux Fundamentals
For those of you who’ve never used Linux, here’s a few tips. Generally, it’s considered bad practice to do anything as the super user (root). On most installs, you will have to run sudo to run a command with super user if you’re running as the super user, jut leave “sudo” off the commands below
Reboot
sudo reboot
Shutdown
sudo halt
Copy and Paste
On mist Linux GUI’s (Linux Mint is one exception), you highlight the text you want to copy and right click to paste. If you’re using something like TerraTerm, copy the text from Windows/Mac and right click to paste in the terminal session
Login shells
It’s important that most of this is executed under a login shell. You can usually tell if you’re in a login shell by running the command echo $0. If the first character is a “-“ it’s a login shell. (See this article for info.). This is generally an issue if you’re running a terminal session in a Linux GUI. if you’re using my VM or Raspberry image, no need to worry about it.
Editing
You cannot use Ctrl-C., Ctrl-V to copy and paste in a command shell. See “Copy and Paste” above. It’s unlikely you’re number pad will work (unless you’ve specifically configured it), so stick to the number keys on the main section of the keyboard.
Use a GUI editor if running full distro
If you have a desktop environment (such as Gnone, XDE, Mate, etc.). Use a graphical editor instead of vi or nano. It’ll normally be under accessories.
Editing Files/Scripts on a PC
If you are doing this, I’d recommend something like Notepad++, which has syntax coloring. Make sure you do one of the following when transferring files to Linux:
- Save with Linux line endings
- Convert during transfer
- Run dos2unix (or fromdos) after transferring
Finding Files
To find a file use the command:
find / -name siri* -print (find anything from root down starting with “siri”)
To find a command use
whereis ifconfig
Running Commands Scripts
If it’s not in your search path it won’t run! If I want to run a script in my current directory 9and it’s not in the search path, I need to use
./script.sh
Home Directory
~ is a shortcut for your home directory. If I’m logged in as “siri”, the following are equivalent
cd ~/SiriProxy and cd /home/siri/SiriProxy
Repeating a Command
Up arrow will scroll backwards through commands.
History is a great tool. This will display all your previous commands. (To display a page at a time, pipe the results to ‘more’. To limit results to a specifc string, pie the results to ‘grep’. See this article for examples.)
history ... 31 sudo nano /etc/hosts 32 sudo nano plugins/siriproxy-example/lib/siriproxy-example.rb ...
To re-run 32 use:
!32
Here endeth Part 1. For those who want to learn how to install the SiriProxy on a Rasberry PI, continue to Part 2. For details about integrating the SiriProxy with other systems (such as Home Automation systems), see Part 3.