Automating “should be the bins be out… and are they?”
Changes
2023-11-24 V1.1 files added to download with node red JSON and HA yaml
2023-11-24 V1.0 First version
Summary
(needless?*) automation and hardware to tell my family if it is rubbish day, which bins need to go out…. but only tell us if any of the bins haven’t been put out yet.
How does it do it?
1. Uses a combination of the ESPresense project, and BLE Beacons to track the distance of each of 3 rubbish bins from their usual location beside the house.
2. Uses a custom component for HA called Waste Collection Schedule (check first if this will work for your local country/area)
3. Uses some Node red flows, (including some JavaScript) and also MQTT plus Home Assistant components to:
- check the local council data to see if it is bin day “today” or “tomorrow”
- work out which bins (out of the 3 different types) need to go out (today or tomorrow)
- determine if the bins are beside the house… or are actually already by the road
- voice and push notify at certain determined intervals with the requirements (or do nothing if bins already out)
Note that this is a guide only and may not include everything you need if you want to try it yourself (eg I’ve skipped most of the notification steps) – some reasonable knowledge of home automation components such as HA, MQTT, hardware etc is assumed here.
Hardware Requirements
BLE Tracking receiver
With the obvious additions of having some hardware that is running Home Assistant, MQTT and Node Red, something that will run ESPresense is needed (at least one, but multiple could be better for more precise tracking). The easiest is any cheap ESP32 development board, which i had a few of already.
You could probably also use ESPHome and the ESP32 BLE Beacon component – especially if you have an ESP32 running ESPHome already, or you aren’t a fan of MQTT for some reason. There are warnings however that ESPHome doesn’t perform well if you are using a lot of sensors on an ESP32, and also want BLE. I find ESPresense a good solution though and multiple devices can work well together to triangulate location for presence. I also already had some ESPresense devices running to track our vehicle home/away status.
BLE Beacons
You also need some beacons, and there are heaps of options for tracking with ESPresense. Just look for anything labelled iBeacons or eddystone. Because of the nature of the project, the beacons need to be waterproof, and probably a method of securing them that isn’t just double sided tape, so I picked these (and also they were cheap enough).
I’m not sure yet about battery life, as they only take a CR2032 button cell. Previous beacons I had purchased before used CR2477 cells which is good, but this is also a curse as those batteries aren’t that easily obtainable and are not cheap.
I mounted these iBeacons on each of the 3 bins. I tried to put them under a lip for more weather resistance, and they have some signage double sided tape plus one small self tapping screw to hold them in. Apparently some councils (not ours currently) have RFID tags on these bins in a similar spot that they detect on collection time.
Software requirements
ESPresense
If you haven’t before, get familiar with the setup of ESPresense and make yourself some notes. There is plenty of detail online, but one of my tips is to set up your esp32 on a bench and get all your beacons registered with it at the same time.
Also, I tend to put the 12 (hex) digit IDs of known beacons in the “Known BLE mac addresses” as it makes them easier to track. The show up as known:1234567890ab etc.
MQTT & Home Assistant
ESPresense integrates nicely with MQTT. I also recommend (although not totally necessary) creating MQTT sensors in Home Assistant for each beacon and below is the YAML code example I use. I tend to put all my beacon IDs in my secrets file as I often share my HA configs in my git repository. I label all my beacons BTBXX (and physically engrave them the same so I know which ones I’m dealing with!). One of these HA sensor entries is required for each beacon.
sensor:
- platform: mqtt_room
unique_id: !secret btb01_uID
device_id: !secret btb01_dID
name: !secret btb01_name
state_topic: !secret btb01_topic
timeout: 60
away_timeout: 120 #seconds after which the entity will get status not_home
My secrets.yaml file has entries that match, like this (one ID for each beacon)
btb01_uID: Rubbish_Bin_Recycling_Waste_(BTB01)"
btb01_dID: "known:xxxxxxxxxxxx"
btb01_name: "Rubbish Bin Recycling Waste (BTB01)"
btb01_topic: espresense/devices/known:xxxxxxxxxxxx
The next step is to create HA sensors for the location status of the bins. The inputs for this are shown later and calculated in Node Red. Again, doing this is not mandatory, as you could use the MQTT values, but I do use HA sensor status nodes in my Node red flows below. You need one of these sensors for each bin.
mqtt:
sensor:
- unique_id: local_council_green_recycling_bin_out
name: "Green Recycling Bin Out"
state_topic: "home-status/rubbishbinstatus/greenbin-out"
Home Assistant Custom Component
The check of the rubbish schedule requires a custom component called Waste Collection Schedule. I had previously just used fortnightly values to notify about rubbish days, but this doesn’t work after public holiday changes etc.
As of writing this, the custom component is well supported and maintained in its repository.
I won’t be giving instructions for installing it here, but it isn’t difficult. Here is my yaml setup to get it pulling the right data (but parts are redacted, so don’t copy/paste thinking it will work)
waste_collection_schedule:
sources:
- name: mycouncil_govt
args:
area_number: 1234567890 # see 'How to get the source argument below'
sensor:
- platform: waste_collection_schedule
#source_index: 0
name: My Council Red Waste
details_format: upcoming
count: 1
leadtime: 1
#value_template: VALUE_TEMPLATE
#date_template: DATE_TEMPLATE
add_days_to: true
#event_index: EVENT_INDEX
types:
- rubbish
The above just shows the overall source for the custom component and one sensor for our red (non recyclable) rubbish. I added a seperate sensor for each of my 3 rubbish types. The interface to my council calls the three types “rubbish”, “recycle” and “food-waste”, but check custom component instructions for your local area.
Node red flows
Startup Variables
I use some persistent flow variables for the rest of my flows. The way I do this is put them in a function node, in the ‘On Start’ tab.
// Anything over this distance in metres means that bin is out.
flow.set("distanceOut", 3);
// default value for the bin action is 'nothingrequired'
flow.set("redBin", "nothingrequired");
flow.set("greenBin", "nothingrequired");
flow.set("foodBin", "nothingrequired");
Calculate if bins are in or out
The summary of the above flow:
- Check distance for each bin any time the beacon reports in (which seems to be continually when in range)
- Compare the distance with the preset ‘out’ distance.
- Update MQTT (and subsequently Home Assistant, see the sensors above) with boolean values of TRUE (the bin is out) or FALSE (the bin is still by the house).
- An additional trigger waits 60s for any reports from a beacon. If nothing received, it is either because it is too far away (therefore the bin is out), or the beacon is lost/out of battery. Either of these cases it reports TRUE. (Note that other methods are planned in the future to check battery and avoid this situation)
- Note that any function node I label ‘passthrough’ is just there for the sake of having a prettier flow.
Check council dates then compare if bins are out
The summary of the above flow:
- Check requirements for each bin from Home Assistant. The interface sensor returns a value in number of days until bin day.
- Caculate for each bin whether bin day is Today, Tomorrow, or otherwise.
- If bin day is Today or tomorrow, check whether the matching bin is in or out.
- Set the appropriate flow variable to either “today”,”tomorrow”, or “nothing required”. “nothing required” is also generated if the bins have already been correctly put out.
- The flow is set to run every hour. This is not strictly necessary, as it is also set to run just a few seconds for each announcement, but the status is planned to be used for some further displays in future.
- The outputs are also in msg.payload, but this is strictly for monitoring in a debug node.
Create announcement statements and announce
The summary of the above flow:
- Inject at certain times of the day (every day)
- give some randomness to the announcement timing.
- At each check time, run the previous flow to check the council dates and check where the bins are.
- run some javascript to check status of all bins (ie, are they still to be put out, or nothing to do)
- Send the announcement text (in my case using msg.summary) to another set of nodes that actually does my announcements.
Javascript in announcement flow
Pretty simple, and these ‘if’ statements should probably be nested (or case statements used) but it does the job. This code is repeated for the ‘TODAY’ section, but with the “tomorrow” values replaced with “today”
// Check the status of each bin, and construct the announcement
var redBin = flow.get("redBin") || "nothingrequired" ;
var greenBin = flow.get("greenBin") || "nothingrequired";
var foodBin = flow.get("foodBin") || "nothingrequired";
var announcement = "" ;
if ( redBin === "tomorrow"
&& foodBin === "tomorrow"
&& greenBin === "tomorrow" )
{
announcement = "It is rubbish day tomorrow, all bins need to be put out."
}
if (redBin === "tomorrow"
&& foodBin === "tomorrow"
&& greenBin === "nothingrequired")
{
announcement = "It is rubbish day tomorrow, but not a recycling day. Please put the red bin and food bin out."
}
if (redBin === "correctlyout"
&& foodBin === "tomorrow"
&& greenBin === "nothingrequired") {
announcement = "It is rubbish day tomorrow. The red bin is out but the food bin still needs to be put out."
}
if (redBin === "correctlyout"
&& foodBin === "tomorrow"
&& greenBin === "tomorrow") {
announcement = "It is rubbish day tomorrow. The red bin is out but the recycling and food bins still needs to be put out."
}
if (redBin === "correctlyout"
&& foodBin === "tomorrow"
&& greenBin === "correctlyout") {
announcement = "It is rubbish day tomorrow. The red and green bins are out but the food bin still needs to be put out."
}
if (redBin === "correctlyout"
&& foodBin === "tomorrow"
&& greenBin === "nothingrequired") {
announcement = "It is rubbish day tomorrow, but not a recycling day. The red bin is out but not the food bin yet."
}
if (redBin === "tomorrow"
&& foodBin === "correctlyout"
&& greenBin === "nothingrequired") {
announcement = "It is rubbish day tomorrow, but not a recycling day. The food bin is out but not the red bin yet."
}
if (redBin === "tomorrow"
&& foodBin === "correctlyout"
&& greenBin === "correctlyout") {
announcement = "It is rubbish and recycling day tomorrow. The food bin and red bin are out but not the green bin yet."
}
//if (redBin === "nothingrequired"
// && foodBin === "nothingrequired"
// && greenBin === "nothingrequired") {
// announcement = "Nothing required"
//}
msg.payload = announcement;
return msg;
Notifications
I don’t have my notification nodes on the Node Red code here but there are obviously plenty of ways to be notified.
An example notification I get, using Pushover on Android and iPhone is below (Pushover is non free, but only a one off cost for each device if you are only sending a few hundred messages daily, and works on Android and iPhone). Notifications could equally be used over email, twitter, text messaging or another push notification system.
I also use voice notifications extensively, so this same text is announced over an audio system in our living area (uses a PC running MPD). I also flash up a summary on my Sony TV (it runs android and has a banner announcement HA API)
House Notification It is rubbish day tomorrow, but not a recycling day. The red bin is already out but the food bin is not.
Code to download
The entire Node red flow to download is below. Some parts are redacted and there is noting for actual notifications. Remember my notification text comes out of the last node as msg.summary (not msg.payload)
The yaml code I use for home assistant (note I use ‘packages’ in Home Assistant, so all of this is in one yaml file for convenience). This is not however the yaml that takes care of the beacons, I have that in a different package (with the sample shown above)
Improvements
Some additions to this I am planning (or have already implemented since this article)
- The system can’t determine if a beacon is too far away…. or dead (eg battery low). A system to monitor this would be useful.
- There would definitely be needed improvements to some of the code if you have a more complex pickup cycle for your waste. Eg, something could be due tomorrow as well as today for yours… that doesn’t happen for me as all rubbish is picked up same day presently.
- A button to press (or a voice ‘request’ using amazon echo, or google home) might be handy when I want to ask the status of the bins, rather than waiting for the scheduled announcements. Maybe a button placed by the front door.
- I plan to add more visuals to the bin status likely a set of LEDs that show in/out etc, or adding more graphics to our touch screen displays.
* and of course, many people when I tell them I have set this up say “why?” or “why don’t you just look outside and see what other bins people are putting out”. Well, those of you who enjoy home automation projects will already know why, and probably wouldn’t be here reading this if you didn’t.
Working on this and am at a roadblock. Already using espresence to track our phones and it works well with home assistant.
I purchased a couple of these from aliexpress. I can see them in the fingerprints on my esp32 wrooms and can see where it’s showing in MQTT explorer so I know it’s out there.
1. You mention above that you add your beacons to the “known” devices. Not seeing where to do that in espresence. I know how to enroll, I added all of our phones that way.
2. The device shows up as the same name as it’s bt mac address so my state topic is espresense/devices/xxxxxxxxxxxx. Added to my configuration.yaml the same way I did with my phones:
– platform: mqtt_room
name: “Trash Bin”
unique_id: “trash_bin”
device_id: “trash_bin”
state_topic: “espresense/devices/xxxxxxxxxxxx”
timeout: 5
away_timeout: 120
The sensor shows up in home assistant but the location always just shows as not home.
Any pointers on where I would look?
I actually found how to put them in known BLE mac addresses. Duh. Added known: to the beginning in my yaml as well and restarting HA, Still not showing in HA though even though in mqtt explorer it’s showing up as .66m away (which is not quite accurate but close enough.
glad you got it sorted, yes it isn’t clear and is a bit annoying that you have to add the known: devices in espresence and then also in the HA yaml… my notes were long enough so didn’t include much ESPresence setup sorry. I think you may be able to do distance calibration, but RF is black magic… you’ll never get it very accurate unless you use a lot of nodes.
I just hope that ESPresence merges with ESPHome at some stage… it is great but I’d like all my ESP32s to do presence detection plus other I/O and ESPresence has more features than ESPHome presence (although there are projects to merge some parts like using the Apple IRK for apple products).
@Zorruno:
Many thanks for the documentation. Yesterday I implemented https://github.com/mampfes/hacs_waste_collection_schedule and today I ordered for all bins this ibeacons:
https://de.aliexpress.com/item/1005002008916105.html
and
this ESP32s
https://shop.m5stack.com/products/atom-lite-esp32-development-kit
excellent! Hopefully it all works well for you. I do note that some of the ibeacons don’t have a huge battery life so if I did it again, I may look at ones with larger batteries (I’ve used some to monitor the home/not home status of my cars)