Homeassistant Tracking Waste Collection Dates
I want to have the next waste disposal dates in Homeassistant. There is an all-solved-solution (hacs_waste_collection_schedule) that also supports the city I live in. But this is a lot of code to copy around when not using Home Assistant Community Store, which I try to not use. The following solution has a lot less code and when it breaks it is easy for me to fix.
In February I wrote a bit of code to parse the ical for waste collection dates from the city of Stuttgart and documented it in a blog post. Let us modify this script to generate the json we need for a template webhook upload in homeassistant.
But first the homeassistant configuration that is needed:
template: - trigger: - platform: webhook webhook_id: !secret waste-disposal allowed_methods: - POST local_only: true unique_id: "waste" sensor: - name: "waste: residual" state: "{{ trigger.json.waste_residual }}" device_class: date unique_id: "waste_residual" - name: "waste: paper" state: "{{ trigger.json.waste_paper }}" device_class: date unique_id: "waste_paper" - name: "waste: yellow bag" state: "{{ trigger.json.waste_yellow_bag }}" device_class: date unique_id: "waste_yellow_bag"
The script to upload will run on the same host as my homeassistant instance, so local_only can be true.
Now the script that downloads the calendar and uploads to home assistant:
import datetime import json import sys from pathlib import Path import requests def parse(stream): ds = {} for line in stream.split("\n"): if line.strip() == "BEGIN:VEVENT" and ds: yield ds ds = {} if line.startswith("DTSTART"): ds["date"] = str( datetime.datetime.strptime( line.split(":")[-1].split("T")[0], "%Y%m%d" ).date() ) if line.startswith("SUMMARY"): ds["summary"] = line.split(":")[-1].strip() if __name__ == "__main__": # copy webhook secret into file .secret secret = (Path(__file__).parent / ".secret").open().read().strip() # url is set in the first commandline argument r = requests.get(url=sys.argv[1]) key_map = { "Restmüll 02-wöchentl.": "waste_residual", "Altpapier 03-wöchentl.": "waste_paper", "Gelber Sack 03-wöchentl.": "waste_yellow_bag", } dataset = {} for item in parse(r.text): _k = item.get("summary") if _k in key_map: dataset[key_map[_k]] = item.get("date") del key_map[_k] r = requests.post(f"http://localhost:8123/api/webhook/{secret}", json=dataset) assert r.status_code == 200
The parsing part is exactly the same as in the old blog post. The modifications to the February version are:
using requests -- because it is already installed
the addition of a key_map to rename the keys to the ones expected by the sensor template
code to push to homeassistant
The result in homeassistant looks like this:
I use a cron that runs every day at 4am to push the current collection dates to homeassistant.