Writing a 'bin day' API: because copying your neighbours is so 2019.

Bin-day as a service

As part of my home automation dashboard, I have a card which tells me what colour the next rubbish bin due to be collected is and - on the day it’s due - I get a reminder on my phone to take it out. However, over Christmas this wonderfully simple system of is-it-wednesday broke down. As many of you will have already guessed, my old system didn’t account for any offsets caused by bank holidays.

Seeing a ripe opportunity for some over-engineering, I set out to create an API service to this huge problem.

The first step was to find a source for realtime bin information (binformation, if you will). My local council is Eastleigh, in the south of England, so I headed over to their website and found a tool where you plug in your postcode, it turns that into a UUID, and it tells you the next pickup date for each type of bin.

Off to a good start.

The second step was to write an API which would accept the UUID, request the Eastleigh council website, parse the HTML, and return the collection dates in JSON. Most importantly it should return the collection dates as an array, sorted by order such that the first bin returned is the next bin to be collected.

For this, I chose to use nodeJS with three libraries:

  • express for the webserver, allowing me to call the tool via an API
  • https for making the outgoing call to Eastleigh’s websites
  • cheerio for parsing the HTML returned from Eastleigh’s website and extracting the information we want.

The HTML parsing was fairly simple, as although the site doesn’t use IDs or unique classes for the information I wanted, it does use unique tags for the bin name and bin collection date, so I just iterate through every tag of that type and marry them up in a JSON array:

"The HTML tags surrouding the info we need"

I iterate through the <dd> and <dt> tags

Once I had the dates in a JSON array, I just had to sort them by time. This was done with the help of stackoverflow:

output.sort(function(a, b) {
  a = new Date(a.date);
  b = new Date(b.date);
  return a>b ? 1 : a<b ? 0 : -1;

I also added caching logic, such that after the first request to my API in a given day the server will return a cached value. This means that at most the tool will make 1 request per UUID per day to Eastleigh’s website. Considering that Home Assistant polls this service every 30 seconds, this will handily avoid upsetting any sysadmins over on their side.

The finished product

Finally I added some error handling as well as a help page. I run the service locally on my home network for my home automation system, but I run a public instance too at https://willow.systems/binproxy/. Of course this only works for Eastleigh, so I expect it’s daily active users to be low! "Binproxy landing page"

The high-tech landing page

The code is on Github, so feel free to fork it and adapt it to other councils. It’s a shame there isn’t a more universal system available here. Maybe something for a future project.