Alexa - what bin day is it?


Bin day is the most magical time of the week! Children of all ages cry "Which bins is it?! Oh! Which bins?"

Row of recycling bins - photo by  Dave Goodman

Is today recycling day? Or green waste day? Or humble landfill day? Should my food caddy go out? Gosh! Who can keep track? I mean, obviously I could look at my calendar. Or sign up for free SMS alert. Or use push notifications in their app. But where's the fun in that?

"Alexa..."

The code I've written uses Oxford City Council's civic data APIs - which will deal with bank holidays and other issues.

I've written before on how to build a Flash Briefing skill. You just need to host a scrap of JSON somewhere. In this case:

{
  "uid": "https://example.com/bins/",
  "updateDate": "2017-07-04T00:00:00+01:00",
  "titleText": "Bins",
  "mainText": "Today's bin collection is Green Refuse Bins and Food Caddies",
  "redirectionUrl": "https://www.oxford.gov.uk/homepage/154/find_your_bin_collection_day"
}

Why I'm not releasing this skill to the public

There's no official API yet. I am using some... errr... "borrowed" credentials I found inside the official Oxford City Council app. I'm chatting to someone at the council to see if there's a more official route I can take.

Update! I'm delighted to say that there is an open API! Details at the end.

Secondly, I'm afraid of handling personal data. The bins API requires a home's UPRN - Unique Property Reference Number. Most people don't know their number, which means I'd need to integrate address lookup into the system. That would mean I would know which of my neighbours has purchased an Amazon Echo.

I'd also have to store that data, process it, and generally have to comply with data protection laws. Which is a bit of a faff for a five-minute project.

Code

If you have access to the API, you can run this PHP code and set up your own Alexa skill.

For postcode to UPRN lookups:

https://apps.cloud9technologies.com/oxford/citizenmobile/openapi/addresses?postcode=OX1%203HZ

For bin lookups (last value is the UPRN):

https://apps.cloud9technologies.com/oxford/citizenmobile/openapi/wastecollections/200004675068

WARNING this really is a scrap of code that I threw together early on a Tuesday morning. No guarantees of style, substance, or efficacy. Released under the MIT License

<?php

$wasteURL = "https://apps.cloud9technologies.com/oxford/citizenmobile/openapi/wastecollections/";
$uprn = "";

//  Get the data
$data = file_get_contents($wasteURL . $uprn);

//  Data is in JSON 
$json = json_decode($data, true);

//  Strip out unneeded elements
unset($json["WasteCollectionDates"]["UPRN"]);

//  An array to hold the collection information
$collections = array ();

//  Loop through the array
//  Store the data as timestamp=>bins
foreach ($json["WasteCollectionDates"] as $key => $value) {
    $details =  $value["ContainerDescription"];
    $date = strtotime($value["CollectionDate"]);
    if ($collections[$date] != null)
    {
        //  Multiple bins can be collected each day
        $details = " and " . $details;
    }

    //  Ignore empty elements
    if ($date != null)
    {
        $collections[$date] .= $details;
    }
}

//  Date order the array
ksort($collections);
//  Place pointer at the start of array
reset($collections);

//  The array key is a UNIX timestamp
$first_date = key($collections);
$first_bins = $collections[$first_date];

//  Is the next bin collection today, tomorrow, or further in the future?
//  https://stackoverflow.com/a/25623230/1127699
$today = new DateTime(); // This object represents current date/time

$today->setTime( 0, 0, 0 ); // reset time part, to prevent partial comparison

//  Get the timezone as the bins API doesn't return it
$timezone = $today->getTimezone();

//  What is the date of the next bin collection?
$match_date = DateTime::createFromFormat("U", $first_date);
//  Set the timezone based on the local time
$match_date->setTimezone($timezone);
$match_date->setTime( 0, 0, 0 ); // reset time part, to prevent partial comparison

$diff = $today->diff( $match_date );
$diffDays = (integer)$diff->format( "%R%a" ); // Extract days count in interval

$headline = "";

switch( $diffDays ) {
    case 0:
        $headline = "Today's bin collection is " . $first_bins;
        break;
    case +1:
        $headline = "Tomorrow's bin collection is " . $first_bins;
        break;
    default:
        $headline = "The next bin collection is " . $first_bins . " on ". $match_date->format('l');
}

//  Set the correct header for JSON data
header('Content-Type: application/json');
?>{
  "uid": "https://example.com/bins/",
  "updateDate": "<?php echo $today->format(DateTime::ATOM); ?>",
  "titleText": "Bins",
  "mainText": "<?php echo $headline; ?>",
  "redirectionUrl": "https://www.oxford.gov.uk/homepage/154/find_your_bin_collection_day"
}

Thanks!

If you've enjoyed this post, please leave a comment or you can get me something from my Amazon wishlist

2 thoughts on “Alexa - what bin day is it?

  1. Going to be looking at doing the same with Leeds/Bradford/Halifax. Will let you know how I get along.

What do you reckon?