The FXS gateway is needed to convert analog phone signals to VoIP. For this I chose Grandstream HT801, it cost me 35 EUR from Amazon. It has an RJ11 port to plug in your legacy phone and it connects to your home network, acting as a VoIP client. Setting it up was pretty simple, but first I had to do some soldering:

Spaghetti code IRL

I bought a few meters of standard phone cable with an RJ11 jack to hook it up to the old German TAE wiring based on some wiring chart online (your phone might be using a different wiring). You can see on the photo that I'm a software guy rather than hardware, but it worked just fine and my old rotary phone was VoIP-ready.

An important feature of the HT801 is the off-hook auto-dial. It can be programmed to call a number as soon as you pick up the handset. Another essential feature was the support for direct IP calls over SIP. Putting these together I could get my old rotary phone to call my Raspberry Pi as soon as I picked up the phone.

The FXS gateway can be configured through a web interface, much like a router. What doesn't have a built-in web server nowadays?

Off-hook auto-dial config with the *47 prefix for direct IP call

This setting tells the gateway to call the server at 192.168.1.132:5060 over SIP as soon as I pick up the handset. If you are turning your Pi on and off regularly, make sure that you configure it to have a static IP.

The next step was to build the SIP server. I found a Python library called linphone-python ` that has an implementation of this protocol. It also has pretty terrible docs and release regimen, but after some research, I found the latest binaries for Mac here and for Raspberry Pi here. The idea was to run the SIP server on the Pi, answer incoming calls automatically with a voice prompt and record the contents.

To make the voice prompt you can, of course, just record a WAW file yourself, but it's much more fun to craft a more assistant-like prompt on Amazon Polly, a text to speech service. The best part is that you can get voice personas of different languages to try to pronounce the English phrase "How can I help you?" with their own accent. I dare you to try Dutch or Japanese.

The next step was to recognize the words from the recorded phone call. For this, I used the very adequately named SpeechRecognition library that is an abstraction layer over several speech recognition libraries and services. It works with Google Speech Recognition without configuration and it gives great results very fast.

Once the phrase was recognized, all I had to do was to route it to different commands. I made this interface pluggable so that it's very easy to add new commands. For demonstration purposes, I created a command that turns my ubiquitous Philips Hue smart lights to a cozy, soft orange and plays Marvin Gaye on my smart speaker through Spotify Connect. I used Phue and Spotipy (install master ` from Github, the pip version is outdated). The implementation was trivial, the whole enchilada (including the server and speech recognition) took less than 200 lines of code. The value we get from open-source projects is astonishing.

And here it is:

That's just the beginning, I can add any command just as easily.

Next up: teaching an old washing machine to mine cryptocurrency.

PS. I put the source code online, please bear in mind that it's a DIY project for "internal use" so the code is not a marvel.