Created a custom_component which will be shared soon.
See the posts below. I will add this component to github soon.
i’m interested, can you share some more info?
At the moment I`m on a Holiday. I’ll share the custom_component upcoming weekend.
Nice.i already setup my garbage schedule but wondering how u will present yours
If your municipality has a ical calendar like mine, you can easily add the ical to Google Calendar. Next, add the Google Calendar to Home Assistant and create a automation like:
- alias: Waste Container Warning
trigger:
platform: time
at: '22:00:00'
condition:
condition: template
value_template: >-
{%- if (as_timestamp(now()) > (as_timestamp(states.calendar.afvalkalender.attributes.start_time) - 86400)) -%}
true
{%- endif -%}
action:
- service: notify.telegram_hass
data:
message: "[INFO] Do not forget to take out the {{ states.calendar.afvalkalender.attributes.description }}!"
No our municipal has none but regular pickups… So I just use time date trigger
This is scary, almost the same
The solution i came up with works like this:
- alias: 'Notify Lametric - Afvalkalender GFT'
trigger:
- platform: time
minutes: '/60'
seconds: 00
condition:
- condition: template
value_template: >-
{%- if (as_timestamp(now()) > (as_timestamp(states.calendar.afvalkalender.attributes.start_time) - 21600)) and ( as_timestamp( states.calendar.afvalkalender.attributes.start_time ) ) - ( as_timestamp( now() ) > 0 ) -%}
true
{%- endif -%}
- condition: template
value_template: "{{ states.calendar.afvalkalender.attributes.message == 'GFT' }}"
action:
- service: notify.lametric_woonkamer
data:
message: "{{ states.calendar.afvalkalender.attributes.description }} wordt morgen opgehaald"
data:
sound: 'notification3'
icon: 'i17004'
For the three different types of garbage pickups (paper, regular and lawn-and-leaf) i use three different automations to show a notification on my Lametric Time every hour from 6pm the day before the actual pick-up date.
"""
@ Author : Daniel Palstra & Bram van Dartel
@ Date : 06/12/2017
@ Description : MijnAfvalwijzer Sensor - It queries mijnafvalwijzer.nl.
@ Notes: Copy this file and place it in your
"Home Assistant Config folder\custom_components\sensor\" folder.
"""
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import Entity
from homeassistant.components.sensor import PLATFORM_SCHEMA
from homeassistant.const import (CONF_NAME)
from homeassistant.util import Throttle
from urllib.request import urlopen
from datetime import timedelta
import json
import argparse
import datetime
import logging
import voluptuous as vol
_LOGGER = logging.getLogger(__name__)
ICON = 'mdi:delete-empty'
TRASH_TYPES = [{1: "gft"}, {2: "pmd"}, {3: "papier"}, {4: "restafval"}]
SCAN_INTERVAL = timedelta(minutes=1)
#SCAN_INTERVAL = timedelta(seconds=15)
DEFAULT_NAME = 'MijnAfvalwijzer Sensor'
SENSOR_PREFIX = 'trash_'
CONST_POSTCODE = "postcode"
CONST_HUISNUMMER = "huisnummer"
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Required(CONST_POSTCODE): cv.string,
vol.Required(CONST_HUISNUMMER): cv.string,
})
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up date afval sensor."""
postcode = config.get(CONST_POSTCODE)
huisnummer = config.get(CONST_HUISNUMMER)
url = ("http://json.mijnafvalwijzer.nl/?"
"method=postcodecheck&postcode={0}&street=&huisnummer={1}&toevoeging=&platform=phone&langs=nl&").format(postcode,huisnummer)
data = TrashCollectionSchedule(url, TRASH_TYPES)
devices = []
for trash_type in TRASH_TYPES:
#print(trash_type.values())
for t in trash_type.values():
devices.append(TrashCollectionSensor(t, data))
add_devices(devices)
class TrashCollectionSensor(Entity):
"""Representation of a Sensor."""
def __init__(self, name, data):
"""Initialize the sensor."""
self._state = None
self._name = name
self.data = data
@property
def name(self):
"""Return the name of the sensor."""
return SENSOR_PREFIX + self._name
@property
def state(self):
"""Return the state of the sensor."""
return self._state
@property
def icon(self):
"""Return the icon to use in the frontend."""
return ICON
def update(self):
"""Fetch new state data for the sensor.
This is the only method that should fetch new data for Home Assistant.
"""
self.data.update()
#print(self.data.data)
for d in self.data.data:
if d['name_type'] == self._name:
self._state = d['pickup_date']
class TrashCollectionSchedule(object):
def __init__(self, url, trash_types):
self._url = url
self._trash_types = trash_types
self.data = None
@Throttle(SCAN_INTERVAL)
def update(self):
response = urlopen(self._url)
string = response.read().decode('utf-8')
json_obj = json.loads(string)
today = datetime.date.today().strftime("%Y-%m-%d")
tschedule = []
for name in TRASH_TYPES:
for item in json_obj['data']['ophaaldagen']['data'] or json_obj['data']['ophaaldagenNext']['data']:
if item['date'] > today:
if item['nameType'] in name.values():
trash = {}
#trash['shortcode'] = (next(iter(name.values())))
trash['name_type'] = item['nameType']
trash['pickup_date'] = (str(datetime.datetime.strptime(item['date'], "%Y-%m-%d")))
#trash['pickup_date'] = (str(datetime.datetime.strptime(item['date'], "%Y-%m-%d") + datetime.timedelta(days=0)))
tschedule.append(trash)
self.data = tschedule
break
And the mijnafvalwijzer platform:
- platform: mijnafvalwijzer
postcode: 1111AA
huisnummer: 1
And the sensor platform:
- platform: template
sensors:
trash_restafval_date:
friendly_name: 'Grijze bak'
value_template: '{{ as_timestamp(states.sensor.trash_restafval.state) | timestamp_custom("%Y-%m-%d") }}'
And an automated notify a day before at 20:00 hours:
- alias: 'Trash - Grijze bak'
trigger:
- platform: time
hours: 20
minutes: 0
seconds: 0
condition:
- condition: template
value_template: '{{ now().strftime("%Y-%m-%d") == (as_timestamp(states.sensor.trash_restafval.state) - (24*3600)) | timestamp_custom("%Y-%m-%d") }}'
action:
- service: notify.family
data_template:
message: 'Het is vandaag - {{ now().strftime("%Y-%m-%d") }}. De grijze bak wordt morgen geleegd!.'
And a group:
trash_pickup:
name: "Trash Pickup"
control: hidden
entities:
- sensor.trash_restafval_date
This looks great and is a good start. Unfortunately the city I live in uses slightly different codes for the various of garbage collections (one of which breaks the code).
For my installation I had to add the following trash types:
TRASH_TYPES = [{1: "gft"}, {2: "pmd"}, {3: "papier"}, {4: "restafval"}, {5: "restgft"}, {6: "plastic"}]
Due to some incompatible nameType’s in the JSON I also had to change to the type property, see code below:
for name in TRASH_TYPES:
for item in json_obj['data']['ophaaldagen']['data'] or json_obj['data']['ophaaldagenNext']['data']:
if item['date'] > today:
if item['type'] in name.values():
trash = {}
#trash['shortcode'] = (next(iter(name.values())))
trash['name_type'] = item['type']
trash['pickup_date'] = (str(datetime.datetime.strptime(item['date'], "%Y-%m-%d")))
#trash['pickup_date'] = (str(datetime.datetime.strptime(item['date'], "%Y-%m-%d") + datetime.timedelta(days=0)))
tschedule.append(trash)
self.data = tschedule
break
This was caused by the following JSON:
{
"nameType": "rest\/gft",
"type": "restgft",
"date": "2018-01-22"
}, {
"nameType": "plastic ",
"type": "plastic",
"date": "2018-01-29"
}
HI @xirixiz
trying your code, been looking for something like this before, so thanks!
I’ve made the following package containing the code above:
homeassistant:
platform: mijnafvalwijzer
postcode: !secret postcode
huisnummer: !secret huisnummer
sensor:
- platform: template
sensors:
trash_restafval_date:
friendly_name: 'Grijze bak'
value_template: '{{ as_timestamp(states.sensor.trash_restafval.state) | timestamp_custom("%Y-%m-%d") }}'
automation:
- alias: 'Trash - Grijze bak'
trigger:
- platform: time
hours: 20
minutes: 0
seconds: 0
condition:
- condition: template
value_template: '{{ now().strftime("%Y-%m-%d") == (as_timestamp(states.sensor.trash_restafval.state) - (24*3600)) | timestamp_custom("%Y-%m-%d") }}'
action:
- service: notify.family
data_template:
message: 'Het is vandaag - {{ now().strftime("%Y-%m-%d") }}. De grijze bak wordt morgen geleegd!.'
group:
trash_pickup:
name: "Trash Pickup"
control: hidden
entities:
- sensor.trash_restafval_date
the python component in /custom_component/sensor as instructed .
Because I didnt know what to do with the platform, I put it directly under homeassistant: which is accepted fine, and all checks are green.
Running it after reboot gives the following error though:
WARNING (MainThread) [homeassistant.config] Package package_afvalwijzer contains invalid customize
which is strange because there’s no customize in it…
also, the sensor.trash_restafval_date is created but no state is set, it is Unknown.
Maybe the platform definition is incorrect? How should i define that? Please have a look.
followup question:
will this component automatically create sensors for Paper, GFT and Plastics also?
Cheers, and thanks
Hi @Mariusthvdb,
It seems that the problem is at json.afvalwijzer.nl. Try to enter the following url with your postal code and housenumber:
I receive the following error at the moment:
Op dit moment is het erg druk. Probeert u het later nog eens. Onze excuses voor het ongemak.
Cheers
not sure if im doing this correctly but clicking the link above indeed results in your message. Entering the code and number into the json from the component renders the same btw, so it must be busy
"http://json.mijnafvalwijzer.nl/?"
"method=postcodecheck&postcode={0}&street=&huisnummer={1}&toevoeging=&platform=phone&langs=nl&"
about the code above here, you’re sure the double " " and " " are necessary in the url?
in your code, you mention the mijnafvalwijzer platform. How is this entered in the configuration files? Where do you out that? It is the first time i see a platform like that, so sorry if I ask the obvious…
hi @xirixiz
where did you put the - platform: mijnafvalwijzer declaration? I cant get it to work somehow…
----edit----
cool, finally managed to sort this… added the other garbage pickups
platform: mijnafvalwijzer
postcode: !secret postcode
huisnummer: !secret huisnummer
is to be placed under sensor: . I have it in a separate package so it reads:
##########################################################################################
## MijnAfvalWijzer Custom Component
## created by @xirixiz, more info on
## https://community.home-assistant.io/t/garbage-pickup-date-mijnafvalwijzer-nl-custom-component/34631
# place this package in /config/packages
# place the custom component mijnafvalwijzer.py in /config/custom_components/sensor
##########################################################################################
homeassistant:
customize:
sensor.trash_restafval_date:
entity_picture: /local/mijnafvalwijzer/restafval.png
sensor.trash_plastic_date:
entity_picture: /local/mijnafvalwijzer/plastic.png
sensor.trash_gft_date:
entity_picture: /local/mijnafvalwijzer/gft.png
sensor.trash_papier_date:
entity_picture: /local/mijnafvalwijzer/papier.png
sensor:
- platform: mijnafvalwijzer
postcode: !secret postcode
huisnummer: !secret huisnummer
- platform: template
sensors:
trash_restafval_date:
friendly_name: 'Restafval'
value_template: '{{ as_timestamp(states.sensor.trash_restafval.state) | timestamp_custom("%Y-%m-%d") }}'
trash_plastic_date:
friendly_name: 'Plastic'
value_template: '{{ as_timestamp(states.sensor.trash_plastic.state) | timestamp_custom("%Y-%m-%d") }}'
trash_gft_date:
friendly_name: 'Gft'
value_template: '{{ as_timestamp(states.sensor.trash_gft.state) | timestamp_custom("%Y-%m-%d") }}'
trash_papier_date:
friendly_name: 'Papier'
value_template: '{{ as_timestamp(states.sensor.trash_papier.state) | timestamp_custom("%Y-%m-%d") }}'
automation:
- alias: 'Trash - Restafval'
trigger:
- platform: time
hours: 20
minutes: 0
seconds: 0
condition:
- condition: template
value_template: '{{ now().strftime("%Y-%m-%d") == (as_timestamp(states.sensor.trash_restafval.state) - (24*3600)) | timestamp_custom("%Y-%m-%d") }}'
action:
- service: notify.notify
data_template:
message: 'Het is vandaag - {{ now().strftime("%Y-%m-%d") }}. Restafval wordt morgen opgehaald!.'
- alias: 'Trash - Plastic'
trigger:
- platform: time
hours: 20
minutes: 0
seconds: 0
condition:
- condition: template
value_template: '{{ now().strftime("%Y-%m-%d") == (as_timestamp(states.sensor.trash_plastic.state) - (24*3600)) | timestamp_custom("%Y-%m-%d") }}'
action:
- service: notify.notify
data_template:
message: 'Het is vandaag - {{ now().strftime("%Y-%m-%d") }}. Plastic wordt morgen opgehaald!.'
- alias: 'Trash - Gft'
trigger:
- platform: time
hours: 20
minutes: 0
seconds: 0
condition:
- condition: template
value_template: '{{ now().strftime("%Y-%m-%d") == (as_timestamp(states.sensor.trash_gft.state) - (24*3600)) | timestamp_custom("%Y-%m-%d") }}'
action:
- service: notify.notify
data_template:
message: 'Het is vandaag - {{ now().strftime("%Y-%m-%d") }}. Gft wordt morgen opgehaald!.'
- alias: 'Trash - Papier'
trigger:
- platform: time
hours: 20
minutes: 0
seconds: 0
condition:
- condition: template
value_template: '{{ now().strftime("%Y-%m-%d") == (as_timestamp(states.sensor.trash_papier.state) - (24*3600)) | timestamp_custom("%Y-%m-%d") }}'
action:
- service: notify.notify
data_template:
message: 'Het is vandaag - {{ now().strftime("%Y-%m-%d") }}. Papier wordt morgen opgehaald!.'
group:
trash_pickup:
name: "Trash Pickup"
control: hidden
entities:
- sensor.trash_restafval_date
- sensor.trash_plastic_date
- sensor.trash_gft_date
- sensor.trash_papier_date
next:
check why plastic won’t work yet (today!! which might be it coming to think of it), and add some nice persistent notifications, so not to forget the pickup!
btw, ive added the ‘official’ entity_pictures from Saver:
Can upload here, if interested.
some small edits, mainly to do with time representation in the frontend card:
trash_plastic_verpakkingsafval_date:
friendly_name: 'Plastic'
value_template: '{{ as_timestamp(states.sensor.trash_plastic_verpakkingsafval.state)
| timestamp_custom("%A %d %B") }}'
As you can see above, the name of the Trash_name was "plastic verpakkingsafval"
and not plastic
changed all references in the python component and the package accordingly (except the sensor name, which would become too long for the card to display nicely…).
final result (without date order yet, hope to be able to realize that), and maybe change the date representation in ‘Today!’ if applicable;-)
Card:
More - info:
Cheers,
Marius
hi Again, @xirixiz
trying to create a persistent notification on the day itself, ive been testing this:
condition:
- condition: template
value_template: ‘{{ now().strftime("%Y-%m-%d") ==
(as_timestamp(states.sensor.trash_plastic_verpakkingsafval.state))
| timestamp_custom("%Y-%m-%d") }}’
the timestamp gives None though…
dont really understand because
the night before this does work:
condition:
- condition: template
value_template: ‘{{ now().strftime("%Y-%m-%d") ==
(as_timestamp(states.sensor.trash_plastic_verpakkingsafval.state) -
(24*3600)) | timestamp_custom("%Y-%m-%d") }}’
and ive only token out the substraction…
-
(24*3600)
please have a look why this wouldn’t work?
also, since there’s a lot of info on the afvalwijzer page http://json.mijnafvalwijzer.nl/?method=postcodecheck&postcode={code}&street=&huisnummer={number}&toevoeging=&platform=phone&langs=nl&
i was wondering if we couldn’t create a Rest_sensor for it and extract all info out of it with a template.
this is working, but throws all of the homepage in the sensor data…
- platform: jsonrest
resource: http://json.mijnafvalwijzer.nl/?method=postcodecheck&postcode=POSTALCODE&street=&huisnummer=NUMBER
method: GET
name: Afvalwijzer info
# scan_interval: 3600
Ive made it to
{{states.sensor.afvalwijzer_info.attributes.data.ophaaldagen.data[1].date}}
for the first date, or {{states.sensor.afvalwijzer_info.attributes.data.ophaaldagen.data[-1].date}}
, and anything in between, but thats not very useful yet. Would need the date of today, and tomorrow, so some logic would need to be implemented i guess.
to show:
showing all Ophaaldagen.
How can i extract further in that list? a bit stuck because of the brackets… [] and {}
Cheers,
Marius
what about using node-red then getting that to send mqtt to HA
not sure, wha would that take? never really worked with NR, only installed the add-in…
Hi Marius,
That is the problem I struggled with all the time…no good array to parse resulting in only a list of all pickup days in the current year.
I’ll check it again if I can create a more solid solution.
Cheers
cool, thanks!
please have a look why the "today’ automation doesnt work either. Its nice to be warned the day before, but id love to have the warning on the day itself too.
Ive just noticed (in my json-sensor) that they switch very quickly showing the next pickup day, while it is still ‘today’. might make it a bit difficult, if the pickupday=today condition is never met ;-((
Anyways, thanks for the component. I like it a lot!
-
platform: scrape
resource: http://www.mijnafvalwijzer.nl/nl/postalcode/housenumber/
name: Afval Datum
select: “.firstDate”
scan_interval: 60 -
platform: scrape
resource: http://www.mijnafvalwijzer.nl/nl/postalcode/housenumber/
name: Afval Soort
select: “.firstWasteType”
scan_interval: 60
Is also working, but it only shows what trash is going to be picked up Today.