So i’ve finally found the time to build a timer for our kitchen with an esp8266 and esphome,
I’ve used the package box of on old smartphone.
Maybe in the future, i will 3d print a box, but i wanted to play with something over the weekend, so I decided to go with that
I drilled the holes for the 3 buttons which start the timer at predefined durations (the ones that we use the most), and the 4th button that adds a minute to the current timer.
For other durations, we still use lovelace.
When the timer is finished the mini speaker beeps and an alarm mp3 is played on the speakers of my DIY Frame (see here) so that we can actually hear that the timer is over.
What’s included
- Obviously the buttons for the timer. When doubled pressed, they cancel the active timer.
- a green LED that turns on when the timer is active
- a magnetic reed switch that I’ve attached to the fridge door (since it is right by the box) in order, for example, to be notified when the door is left open
- a non-invasive ct clamp sensor that I’ve attached to the stove’s power line to measure the energy consumption (using the utility meter integration)
- a mini speaker that provides audio feedback when pressing any of the buttons and also beeps when the timer is over.
The esp8266 as well as the other components are glued and soldered inside the box.
I won’t share a photo, since it is pretty messy in there.
Here’s the esphome yaml configuration
esphome:
name: kitchen
platform: ESP8266
board: nodemcu
wifi:
ssid: " "
password: " "
manual_ip:
static_ip: " "
gateway: " "
subnet: " "
fast_connect: true
logger:
ota:
api:
services:
- service: play_rtttl
variables:
song_str: string
then:
- rtttl.play:
rtttl: !lambda 'return song_str;'
sensor:
- platform: adc
pin: A0
id: adc_sensor
update_interval: 15s
- platform: ct_clamp
sensor: adc_sensor
name: "stove_watts"
sample_duration: 400ms
id: watts
update_interval: 15s
unit_of_measurement: 'W'
filters:
- lambda: return x * 230 * 100;
- calibrate_linear:
- 0 -> 0
- 1710 -> 1650
output:
- platform: esp8266_pwm
id: basic_green_led
pin:
number: D0
inverted: False
- platform: esp8266_pwm
pin: D1
id: rtttl_out
rtttl:
output: rtttl_out
light:
- platform: monochromatic
output: basic_green_led
id: timer_led
name: Timer LED
binary_sensor:
- platform: template
name: "Stove Running"
filters:
- delayed_off: 5s
lambda: |-
if (id(watts).state > 200) {
return true;
} else {
return false;
}
- platform: status
name: esp-kitchen-status
id: esp_status
- platform: gpio
pin:
number: D2
mode: INPUT_PULLUP
name: "Fridge Door"
device_class: door
- platform: gpio
id: 11_timer
pin:
number: D6
mode: INPUT_PULLUP
inverted: true
on_press:
then:
- homeassistant.service:
service: timer.start
data:
entity_id: timer.countdown
duration: '00:11:59'
on_double_click:
min_length: 50ms
max_length: 350ms
then:
- homeassistant.service:
service: timer.cancel
data:
entity_id: timer.countdown
- platform: gpio
id: 15_timer
pin:
number: D7
mode: INPUT_PULLUP
inverted: true
on_press:
then:
- homeassistant.service:
service: timer.start
data:
entity_id: timer.countdown
duration: '00:15:00'
on_double_click:
min_length: 50ms
max_length: 350ms
then:
- homeassistant.service:
service: timer.cancel
data:
entity_id: timer.countdown
- platform: gpio
id: 20_timer
pin:
number: D5
mode: INPUT_PULLUP
inverted: true
on_press:
then:
- homeassistant.service:
service: timer.start
data:
entity_id: timer.countdown
duration: '00:20:00'
on_double_click:
min_length: 50ms
max_length: 350ms
then:
- homeassistant.service:
service: timer.cancel
data:
entity_id: timer.countdown
- platform: gpio
id: plus_one
pin:
number: D3
mode: INPUT_PULLUP
inverted: true
on_press:
then:
- homeassistant.service:
service: script.timer_plus_one
switch:
- platform: restart
name: esp-kitchen-restart
Here’s the automation handling the Timer LED and the audio feedback.
alias: AUTO timer
description: ''
trigger:
- platform: event
event_type: timer.started
event_data:
entity_id: timer.countdown
- platform: event
event_type: timer.cancelled
event_data:
entity_id: timer.countdown
- platform: event
event_type: timer.finished
event_data:
entity_id: timer.countdown
condition: []
action:
- choose:
- conditions:
- condition: template
value_template: |
{{ trigger.event.event_type == 'timer.started' }}
sequence:
- service: esphome.kitchen_play_rtttl
data:
song_str: 'one short:d=1,o=5,b=100:16e6'
- service: light.turn_on
data:
entity_id: light.timer_led
default:
- service: script.continue
- choose:
- conditions:
- condition: template
value_template: |
{{ trigger.event.event_type == 'timer.cancelled' }}
sequence:
- service: esphome.kitchen_play_rtttl
data:
song_str: 'two short:d=1,o=5,b=100:16e6,16e6'
- service: light.turn_off
data:
entity_id: light.timer_led
default:
- service: script.continue
- choose:
- conditions:
- condition: template
value_template: |
{{ trigger.event.event_type == 'timer.finished' }}
sequence:
- service: esphome.kitchen_play_rtttl
data:
song_str: 'two short:d=1,o=5,b=100:16e6,16e6'
- service: light.turn_off
data:
entity_id: light.timer_led
- data:
media_content_id: /local/alarm.mp3
media_content_type: music
entity_id: media_player.frame
service: media_player.play_media
default:
- service: script.continue
mode: parallel
max: 10
And finally the trickiest part, which is the script in order to add one minute to an already running timer
alias: timer_plus_one
sequence:
- service: timer.start
data_template:
duration: |
{% if states.timer.countdown.state == 'active' %}
{% set t = states.timer.countdown.attributes.finishes_at %} {% set f =
as_timestamp(strptime(t, '%H:%M:%S')) %} {% set s = f-now().timestamp() %}
00:00:{{ s | int + 60 }}
{% else %}
00:01:00
{% endif %}
entity_id: timer.countdown
- service: esphome.kitchen_play_rtttl
data:
song_str: >
{{ 'one short:d=1,o=5,b=100:16e6' if states.timer.countdown.state ==
'active' else 'two short:d=1,o=5,b=100:16e6,16e6' }}
mode: single