0Bin collections in Home Assistant

I’ve been devel­op­ing my Home Assist­ant based smarthome setup for around a year now (since leav­ing SmartTh­ings) and after an ini­tial steep learn­ing curve I’ve been veyr happy with home assist­ant so I have star­ted work­ing to expand the things it does as I am con­if­dent it offers a long term basis for my smarthome. One thing I wanted to add was bin col­lec­tion data to remind me which bin is due when. As I live in Shef­field I needed to pull this data from the loc­al author­it­ies out-sources pro­vider (veolia). The fol­low­ing details how I did this, build­ing very much on the work of oth­ers who have done it already for oth­er regions

Update 10-Aug-2022

I’ve tweaked the script to make it com­pat­ible with home assist­ant after the switch to Python 3

Update 20-Dec-2021

I’ve made a change to both ths bash script AND the tem­plate — the first to make sure required pack­ages are avail­able and the second to fix a break­ing change made by recent releases of home assistant

I used a script which i mod­i­fied from vari­ous examples on a HA sup­port thread by Rob­Brad. For this script to run I needed to install the beau­ti­ful­soup mod­ule on home-assistant.

Add a script

  • I use the ‘Samba Share’ super­visor addon to access my home assist­ant files dir­ectly from my win­dows PC — unless you already have a pre­ferred access meth­od I recom­mend doing the same
  • browse to \\ha-ip-address\config
  • cre­ate a python-scripts folder
  • Cre­ate a new python script in this folder — I called mine bin_collection.py
  • Insert the fol­low­ing script 
    import sys
    import subprocess
    import pkg_resources
    
    required = {'beautifulsoup4', 'python-dateutil', 'requests'}
    installed = {pkg.key for pkg in pkg_resources.working_set}
    missing = required - installed
    
    if missing:
        python = sys.executable
        subprocess.check_call([python, '-m', 'pip', 'install', *missing], stdout=subprocess.DEVNULL)
    
    from bs4 import BeautifulSoup
    import datetime
    from dateutil import parser
    import requests
    import json
    
    url = 'https://wasteservices.sheffield.gov.uk/property/############'
    page = requests.get(url)
    
    if page.status_code != 200:
        exit(1)
    
    soup = BeautifulSoup(page.text, 'html.parser')
    
    out = {}
    bh3s = soup.find_all('td', class_="service-name")
    bpds = soup.find_all('td', class_="next-service")
    
    for i in range(len(bpds)):
        bin_colour = str(bh3s[i].contents[3]).lower().split('>')[1].split(' ')[0]
        out[bin_colour] = parser.parse(bpds[i].contents[2].lstrip().split(',')[0]).strftime('%Y-%m-%d')
    
    print(json.dumps(out))
    
  • You will need to replace the ############ with the unique num­ber for your prop­erty which I will explain how to get in the next step

Get your unique address

  • Browse to https://wasteservices.sheffield.gov.uk/property/
  • Enter your post code and select your address from the list
  • Make a note of the new url. Use it in the url line in the script above — the only part you will need to change is the 12 digit num­ber at the end

Call your script from configuration.yaml

  • A simple entry in configuration.yaml is all that is needed to make the script run
  • You may want to adjust the fre­quency of the run. Mine runs once per day. 
    sensor:
     - platform: command_line
       name: "Bin collections"
       command: "python3 /config/python-scripts/bin_collection.py"
       scan_interval: 86400
       command_timeout: 60 #needed as the website is slow to respond and will often timeout if left at default
    

Create entities for each type of bin using configuration.yaml

  • Imme­di­ately under the above sec­tion (so still under the sensor: sec­tion) add the following 
     - platform: template
       sensors:
         black_bin:
           device_class: timestamp
           value_template: '{{ strptime((states("sensor.bin_collections")|from_json())["black"], "%Y-%m-%d") | as_local }}'
           unique_id: "black_bin"
         brown_bin:
           device_class: timestamp
           value_template: '{{ strptime((states("sensor.bin_collections")|from_json())["brown"], "%Y-%m-%d") | as_local }}'
           unique_id: "brown_bin"
         blue_bin:
           device_class: timestamp
           value_template: '{{ strptime((states("sensor.bin_collections")|from_json())["blue"], "%Y-%m-%d") | as_local }}'
           unique_id: "blue_bin"
    

Display the results on the front end

  • To show the res­ults on the front end simply add a card with the 3 sensors on it (spe­cific­ally sensor.black_bin, sensor.blue_bin, and sensor.brown_bin)
  • Note you may need to restart home assist­ant to load the new sensors you added to configuration.yaml

Leave a Reply