Help with ESP8266 visual countdown timer

I came across PaperSignals and was intrigued as I am looking for a child oriented countdown timer that can visually display time left before bedtime, getting ready for Kindergarden etc.

image

I wired up a Longrunner KY66 Servo zu an ESP8266 compiled without errors and uploaded the code but Google Assistant doesn’t communicate with my setup. Acording to some github issues this might be due to the fact that this only works in the US and I am in Germany? ¯_(ツ)_/¯

Anyways I really like the idea and was wondering if sometihing similar could be achieved with https://esphome.io/ and setting the countdown timer via an input in Home Assistant. The thing is I am just dabbing my toes into the Arduino/ESP World and have no clue, how to change the speed of my servo to move from 180 to 0 depending on the defined countdown time.

I would really appreciate if anybody could point me into the right direction of how to achieve this or suggest a different approach as to how to achieve the overall goal of creating an child oriented countdown timer.

Thanks

Should be relatively straightforward with ESPHome.

What’s you maximum timer period?

Is it always the same?

It would be great if I could individually set the timer between 5 and 60 minutes in say 5 minute increments?

Follow the getting started tutorial.

Then cut and paste the servo example into your ESPHome and home assistant config.

Get the servo moving as you would expect with the -100 to 100 slider, then we can work on templates and automations for converting a timer to position.

Thank you @tom_l everything ist setup and I can control the servo with the slider as expected. Great!

Great stuff.

What range on the input number slider corresponds to your 0 to 180° motion?

And is 0° the start or the end of the timer?

It seems that the servo is not capable of exactly 180° rather roughly 170isch°

Slider number -100 corresponds to 170° the start of the timer and Slider number +100 to 0°, which will be the end.

When the timer is set for less than 60 minutes do you still want the timer to traverse the full range (but with bigger steps). Or say, do you want 30 minutes to start at half way and the step size of the wheel to always be constant no matter what the duration is set to?

It would be great if the timer would then traverse the full range but faster.

It’s not actually going to be faster but 'bigger steps".

There will always be one step per minute.

At least the way I was thinking of doing it.

oh okay, so be it.

1 Like

Bigger steps it is.

Home assistant config (you can delete the existing -100 to 100 input number):

input number (used to set the duration):

paper_signal_time:
  name: Paper Signal Time
  min: 5
  max: 60
  step: 5
  unit_of_measurement: min
  icon: mdi:update

Input boolean (use to start and stop the timer):

paper_signal_timer:
  name: Paper Signal Timer
  icon: mdi:timer-outline

sensors (used to calculate the time remaining and servo position):

- platform: template
  sensors:
    paper_signal_time_remaining:
      friendly_name: 'Time Remaining'
      entity_id:
        - input_number.paper_signal_time
        - sensor.time
        - input_boolean.paper_signal_timer
      value_template: >
        {% if is_state('input_boolean.paper_signal_timer', 'on') %}
          {{ [ (states('input_number.paper_signal_time') | int - (as_timestamp(now()) - as_timestamp(states.input_boolean.paper_signal_timer.last_changed)) / 60) | round(0) ,0 ] | max }}
        {% else %}
          0
        {% endif %}
      unit_of_measurement: "min"
      icon_template: mdi:timelapse
    paper_signal_position: # -100 to 100
      friendly_name: 'Position'
      entity_id:
        - sensor.paper_signal_time_remaining
        - input_number.paper_signal_time
      value_template: >
        {{ ((-200/(states('input_number.paper_signal_time')|int) * states('sensor.paper_signal_time_remaining')|int + 100 ))|round(0) }}
      unit_of_measurement: "°"
      icon_template: mdi:location-exit

Change your existing automation to use the position sensor instead of the original -100 to 100 input number:

  - alias: Write Servo Value to ESP
    trigger:
      platform: state
      entity_id: sensor.paper_signal_position #### <------ This has changed
    action:
      # Replace livingroom with the name you gave the ESP
      - service: esphome.livingroom_control_servo
        data_template:
          level: '{{ trigger.to_state.state | int }}'

A Lovelace entities card to control it:

entities:
  - entity: input_boolean.paper_signal_timer
  - entity: input_number.paper_signal_time
  - type: divider
  - entity: sensor.paper_signal_time_remaining
  - entity: sensor.paper_signal_position
show_header_toggle: false
title: Paper Signal Timer
type: entities

In the likely case that it does not work, let me know any errors you receive in the log and we’ll try to debug it. Don’t forget to do a config check before restarting / reloading.

1 Like

I must say that after your preface:

In the likely case that it does not work, let me know any errors you receive

and my previous experiences of trial and error when tinkering with HA I am a little disappointed that your guide worked right out of the box and didn’t throw any errors :slight_smile: WoW, just wow, you made my day! Thank you so much for walking me through this.

Alas I am still trying to wrap my head around the math of the two sensors:

 {{ [ (states('input_number.paper_signal_time') | int - (as_timestamp(now()) - as_timestamp(states.input_boolean.paper_signal_timer.last_changed)) / 60) | round(0) ,0 ] | max }}

and

{{ ((-200/(states('input_number.paper_signal_time')|int) * states('sensor.paper_signal_time_remaining')|int + 100 ))|round(0) }}

The frist one I can sort of grasp, but with the second one, why the -200. I still don’t quite get how the position steps work in relation to the time.

Would it be too much to ask if you could briefly elaborate on these two templates?

1 Like

It’s a linear equation that maps time remaining (60 to 0 minutes) to position (-100 to 100 ).

Given any two points you can calculate the linear equation y= m.x + c , where y = position and x = time remaining. m is the slope of the line and c is the where the line crosses the y axis.

In this case the two points are (60, -100) and (0, 100).

So y = -3.3x + 100

This is made a little more complicated by the fact that 60 can actually be any number between 60 and 5 (the set duration input number) so I used a second linear equation to work out m for any timer duration between 60 and 5.

This resulted in y = (-200/duration).x + 100

1 Like