Guide on sending data to ESP microcontroller to control LEDs?
Hi all!
Thank you for this amazing community helping us grow and learn more things! I am hoping to take the next step and use the data from Home Assistant to control LED's into my 3D printed bins. Does anybody have a guide to do this, who has managed to do it successfully?
This is probably the best print out there for this https://www.printables.com/model/189899-wheelie-bin-for-the-bindicatorbindaycator
Ill print this and then see if I can do a guide
Just tossing in some ideas.
This would be ideal for a block of flats/units where there are many bins in one place for a guide for everybody as to which bin needs to be taken out. Or have it in your garage for when you arrive home from work to remind you to take out the bins.
Have the appropriately coloured LEDs flashing on bin day only, and not on for the rest of the time. Maybe a solar powered ESP8266 or ESP32 with MQTT input from HomeAssistant, driven by a calendar job which makes the appropriate values valid for bin day only, and the controller can query the HA values on a regular basis, such as every fifteen minutes?
You could make this a little more general by using it to trigger a port on the ESP device, with attributes such as ON/OFF/FLASHING/PIN Number passed between the devices. You could then use it to trigger anything such as a relay, siren, LED, Floodlight, etc. Come to think of it, you could make it to read the status of existing pins, so it could become a sensor.
Maybe this has already been done in a different guise and just needs a tweak in the HomeAssistant end to set up the appropriate triggers.
Looks like robbrad has already solved the physical presentation aspect. Now to do the HomeAssistant part and fire up the arduino IDE to program the ESP chip.
Planning to write up a guide.
@BenBarat : I did it using ESP-home on an ESP32 I’ll share the yaml file here on Sunday
I run ESP home on a docker image. It works with home assistant just like a normal light does, it allows you to group LEDs
Then I’ll just write an automation to control the light
ESP Home YAML
esphome:
name: bindaycator
friendly_name: BinDayCator
esp32:
board: esp32-c3-devkitm-1
framework:
type: esp-idf
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable logging
logger:
# Enable Home Assistant API
api:
light:
# 1) The parent addressable strip
- platform: esp32_rmt_led_strip
id: bindaycator_parent
name: "bindaycator (All)"
pin: GPIO0
num_leds: 14
chipset: ws2812
rgb_order: GRB
rmt_channel: 0
# 2) Each partition references the parent by `id: bindaycator_parent`
- platform: partition
name: "bindaycator Segment 1"
segments:
- id: bindaycator_parent
from: 0
to: 6
- platform: partition
name: "bindaycator Segment 2"
segments:
- id: bindaycator_parent
from: 7
to: 13
Home Assistant Automation:
This Home Assistant automation runs every day at 00:01 (one minute past midnight) and is designed to check when your waste bins are due for collection, then light up LED segments with colors that correspond to the bin type that's due soon.
Here's a breakdown of how it works:
-
Mapping Sensors to Bins:
The automation first defines a list (calledbin_sensor_map) of three items—one for each type of waste (Garden Waste, General Waste, and Mixed Recycling). For each waste type, it stores:- A sensor that tells you how many days are left until that bin is collected.
- A sensor that provides a color (either as a hex code or as a color word) for that bin.
- A friendly name for identification.
-
Determining the Next Collection:
It then calculates the minimum number of days until collection among all bins. To do this, it:- Retrieves the state (the day count) from each bin’s sensor.
- Converts these values to integers (using a default of 999 if a value isn’t valid).
- Picks the smallest number, which represents the bin that is due the soonest.
-
Filtering Bins with the Earliest Collection:
The automation then builds a list (bins_json) of only those bins whose day count equals the minimum value found. This means if more than one bin is due at the same time, all of them will be included. -
Logging for Debugging:
A debug message is written to the system log, displaying the current sensor values for each waste type. This helps in verifying what values are being read and used. -
Controlling the LED Segments:
The next part is where the LEDs are controlled based on the sensor values:- No Valid Data: If the minimum days value is 999 (meaning none of the sensors provided a valid reading), it turns off both LED segments.
-
Bin Collection Imminent: If the soonest collection is due within 1 day (i.e.
min_days <= 1), it processes up to 2 LED segments:- It parses the list of bins due soon.
- For each segment, if there’s a corresponding bin in the list, it turns on that LED segment and sets its color based on the associated color sensor.
-
Color Determination: The automation checks if the color sensor’s state is a hex code (like
#FF0000). If so, it converts the hex code into RGB values. If not, it treats the state as a color name (like "red") and uses a predefined mapping to convert that into RGB values.
-
Color Determination: The automation checks if the color sensor’s state is a hex code (like
- If there isn’t a bin corresponding to a segment (for example, if only one bin is due but there are two segments), that segment is turned off.
- Default Case: If none of the above conditions apply, it makes sure to turn off both LED segments.
-
Execution Mode:
The automation is set to “single” mode, meaning that if it’s already running, a new instance won’t start until the current one is finished.
alias: Bin Day Light
description: Light up LED segments on bin day using bin color sensor values
triggers:
- at: "00:01:00"
trigger: time
conditions: []
actions:
- variables:
bin_sensor_map:
- sensor: >-
sensor.cheshire_east_council_empty_bin_standard_garden_waste_days_until_collection
color_sensor: sensor.cheshire_east_council_empty_bin_standard_garden_waste_colour
name: Garden Waste
- sensor: >-
sensor.cheshire_east_council_empty_standard_general_waste_days_until_collection
color_sensor: sensor.cheshire_east_council_empty_standard_general_waste_colour
name: General Waste
- sensor: >-
sensor.cheshire_east_council_empty_standard_mixed_recycling_days_until_collection
color_sensor: >-
sensor.cheshire_east_council_empty_standard_mixed_recycling_days_until_collection
name: Mixed Recycling
- variables:
min_days: |
{% set all_days = bin_sensor_map
| map(attribute='sensor')
| map('states')
| map('int', default=999)
| list %}
{{ all_days | min }}
- variables:
bins_json: >
{% set bins_next = namespace(entities=[]) %} {% for item in
bin_sensor_map %}
{% if states(item.sensor)|int(default=999) == min_days %}
{% set bins_next.entities = bins_next.entities + [ item ] %}
{% endif %}
{% endfor %} {{ bins_next.entities | tojson }}
- data:
level: debug
message: |
DEBUG: Garden Waste: {{
states('sensor.cheshire_east_council_empty_bin_standard_garden_waste_days_until_collection')
}} General Waste: {{
states('sensor.cheshire_east_council_empty_standard_general_waste_days_until_collection')
}} Mixed Recycling: {{
states('sensor.cheshire_east_council_empty_standard_mixed_recycling_days_until_collection')
}}
action: system_log.write
- choose:
- conditions:
- condition: template
value_template: "{{ min_days == 999 }}"
sequence:
- target:
entity_id:
- light.bindaycator_bindaycator_segment_1
- light.bindaycator_bindaycator_segment_2
action: light.turn_off
data: {}
- conditions:
- condition: template
value_template: "{{ min_days <=1 }}"
sequence:
- variables:
bins_parsed: "{{ bins_json | string | default('[]') | from_json }}"
total_segments: 2
- repeat:
count: "{{ total_segments }}"
sequence:
- choose:
- conditions:
- condition: template
value_template: >-
{{ (repeat.index | int) - 1 < (bins_parsed | length)
}}
sequence:
- target:
entity_id: >-
light.bindaycator_bindaycator_segment_{{
repeat.index }}
data:
rgb_color: >
{% set current_bin = bins_parsed[(repeat.index |
int) - 1] %} {% set col =
states(current_bin.color_sensor) %} {% if col and
col.startswith('#') and col|length == 7 %}
[{{ col[1:3] | int(16) }}, {{ col[3:5] | int(16) }}, {{ col[5:7] | int(16) }}]
{% else %}
{% set color_word = col | lower %}
{% set colors = {
'red': [255, 0, 0],
'green': [0, 128, 0],
'blue': [0, 0, 255],
'yellow': [255, 255, 0],
'orange': [255, 165, 0],
'purple': [128, 0, 128],
'pink': [255, 192, 203],
'white': [255, 255, 255],
'black': [165, 42, 42],
'brown': [165, 42, 42],
'gray': [128, 128, 128]
} %}
{% if color_word in colors %}
{{ colors[color_word] }}
{% else %}
[255, 255, 255]
{% endif %}
{% endif %}
action: light.turn_on
default:
- target:
entity_id: >-
light.bindaycator_bindaycator_segment_{{ repeat.index
}}
data: {}
action: light.turn_off
default:
- target:
entity_id:
- light.bindaycator_bindaycator_segment_1
- light.bindaycator_bindaycator_segment_2
action: light.turn_off
data: {}
mode: single
@robbrad Just thought I'd say thanks a lot for this write-up.
Amazing and clear write up. Many thanks
This is the STL I printed https://github.com/furstyferret-dev/bindicator/tree/master/stl