Get Alexa to announce TFL Rail (Elizabeth Line) Status via Voice Monkey

The nice people at TFL publish a free API to get status information. I had a few minutes spare today and decided to use it to push the info through Alexa. There are lots of clever ways to do this but I wanted to just throw something together in PHP and crontab as this doesn’t need to be a robust, industrial-scale thing, just a little quick-and-dirty test.

First thing was to get an account on VoiceMonkey and add the VoiceMonkey skill to Alexa. That should not need a walkthrough, so go do that, add a Monkey called (for example) “TFLRailStatus” and you will end up with a “virtual doorbell” in Alexa with that name.

Now create a routine in Alexa based on the “TFLRailStatus” doorbell being the trigger (under smarthome) and set the action to announce using the Voice Monkey skill and choose your target Alexa device.

Use the dashboard to get the URL required to call this Monkey as you then only need to change the actual text.

Now we need something that can call the new Monkey and thus tell Alexa to say something. The crude method is to search for “statusSeverityDescription”: and scrape the following text strings

"statusSeverityDescription":"Minor Delays","reason":"Minor delays between Liverpool Street and Shenfield due to a reason. GOOD SERVICE on the rest of the line. "

I did it with a bit of horrid PHP. Please don’t judge me. Employ your own flair to make this better before you do anything serious with it, but it will be enough to test the monkey and push a message out of Alexa:

<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

        $tflrail = file_get_contents('https://api.tfl.gov.uk/line/mode/elizabeth-line/status');
        $findme  = 'statusSeverityDescription';

        $posStart = strpos($tflrail, $findme);
        $posStart = $posStart + strlen($findme) + 3;
        $posEnd = strpos($tflrail, '"',$posStart);
        $spacer = strpos($tflrail, '"', $posEnd) + 3;
        $posDescStart = strpos($tflrail, '"', $spacer) + 3;
        $posDescEnd = strpos($tflrail, '","', $posDescStart+2);

        $cmd = 'curl "https://api.voicemonkey.io/trigger?access_token=123458&secret_token=678910&monkey=tflrailstatus&announcement=TFL%20Rail%20reports%20';

        if (substr($tflrail,$posStart,$posEnd-$posStart)=='Good Service')
                {
                $cmd = $cmd.'A%20Good%20Service."';
        } else {
                 $cmd = $cmd.str_replace(" ","%20",substr($tflrail,$posDescStart,$posDescEnd-$posDescStart)).'"';
        }
        $output = shell_exec($cmd);

?>

What this does is extract the header and description and if it is a good service, says so, otherwise it posts the delay description using the Voice Monkey URL. You could obviously use a better technique to extract the text but as I said above, I’m just chucking out what I get.

Point your web browser as this new PHP page and Alexa will tell you how the service is.

Add a crontab entry to curl that page and Alexa can give you your morning TFL briefing. All done with very little code.

sudo crontab -e

# m h  dom mon dow   command
15 7 * * 2,3,4 curl http://127.0.0.1/tflrailstatus.php

** UPDATE – From May 24th 2022, the mode name changed from “tflrail” to “elizabeth-line” and in truth the name “TFL Rail” no long applies, so amend your code appropriately. The code segment above has the new mode name in it so will work as is.