Is there a way to display a timer helper from HA on I2C display in esphome. tried it as sensor with the internal flag, but no lock.
thanks!
Is there a way to display a timer helper from HA on I2C display in esphome. tried it as sensor with the internal flag, but no lock.
thanks!
HI,
Use a text_sensor:
text_sensor:
- platform: homeassistant
entity_id: input_datetime.<your_entity>
id: my_helper
and in the display component:
display:
- platform: ...
model: ...
id: my_oled
lambda: |-
it.printf(0, 0, id(my_font), "helper: %s", id(my_helper).state.c_str());
thanks for the hint, but I do have a timer in HA, not a datetime input helper
Second attempt
text_sensor:
- platform: homeassistant
id: my_helper
entity_id: timer.timer_test
- platform: homeassistant
id: my_helper_end
entity_id: timer.timer_test
attribute: finishes_at
This gives you the timer status and the date/time the timer will finish when the timer is active. Now you can calculate the remaining time between the current time (see time platform) and the end time of the timer and the result you can display with for instance and update_interval of 1s
thanks - works like a charm I always tried it with sensors instead of textsensors…
a) Do you have a solution for converting the id (my_helper_end) with is like “2022-02-11T08:18:24+00:00” to a “HH:MM” format? because now it is string and not a timestamp… ideally this will be the ETA, when the timer finishes.
b) the id(my_helper) is either “idle” or “active”: how to get the remaining time?
@jsuanet thanks again!
Here is some code which shows the state of the timer and the remaining hours and minutes when the timer is active. It is possible to show also the remaining seconds, however there is a slight delay between the timer in HA and the information available within the ESP device.
time:
- platform: homeassistant
id: ha_time
text_sensor:
- platform: homeassistant
id: timer_status
entity_id: timer.timer_test
- platform: homeassistant
id: timer_finish
entity_id: timer.timer_test
attribute: finishes_at
display:
- platform: ssd1306_i2c
model: "SSD1306 128x64"
address: 0x3C
update_interval: 5s
id: oled
lambda: |-
it.printf(0, 0, id(my_font), "Timer: %s", id(timer_status).state.c_str());
if (id(timer_status).state == "active") {
struct tm tm_finish{}, tm_ha_time{};
time_t t_helper;
double remain;
int remain_h, remain_m, remain_s;
strptime(id(timer_finish).state.c_str(), "%Y-%m-%dT%T", &tm_finish); // Convert string to time struct
t_helper = mktime(&tm_finish) + 3600; // Convert to time_t and add 1 hour (correct for your timezone)
tm_ha_time = id(ha_time).now().to_c_tm(); // Get current time in a tm struct
remain = difftime(t_helper, mktime(&tm_ha_time)); // Calculate difference in seconds
remain_h = (int) remain/3600;
remain_m = (int) (remain - 3600*remain_h)/60;
remain_s = (int) remain - 3600*remain_h - 60*remain_m;
it.printf(40, 30, id(my_font), "%02d:%02d", remain_h, remain_m);
// it.printf(0, 30, id(my_font), "%02d:%02d:%02d", remain_h, remain_m, remain_s);
} else {
it.printf(0, 30, id(my_font), " "); // clear second line
}
big thanks!
works like a charm … but I want to display also the finishing time …
the only way that works is:
it.printf(63, 42, id(font_t12), TextAlign::BASELINE_RIGHT, "%02d:%02d", tm_finish.tm_hour+1, tm_finish.tm_min);
is there a better way? eg with the function “strftime”`?
is there a way to get the corret timezone from HA? with the function localtime()?
maybe you can give me some feedback on this topic
big thanks again!
Yes it would be nice if the finishes_at
already contains the right end_time. So I created a template sensor in HA which holds the local end timestamp
and is updated whenever the finishes_at
is updated.
platform: template
sensors:
timer_test_endtime:
value_template: '{{ as_timestamp(state_attr("timer.timer_test", "finishes_at")) | timestamp_local }}'
If you use the !include_dir_list option
for sensors in your HA configuration.yaml, then you can put this in a yaml-file in your HA sensor directory.
Otherwise you have to add this to your sensor part in the configuration.yaml and add some -
and “tabs” to format the yaml correct
This HA template sensor is exposed to ESPHome and used in the lambda to calculate the remaining time and to display the end time.
Here is the changed part of the ESPHome yaml
text_sensor:
- platform: homeassistant
id: timer_status
entity_id: timer.timer_test
# - platform: homeassistant
# id: timer_finish
# entity_id: timer.timer_test
# attribute: finishes_at
- platform: homeassistant
id: timer_finish
entity_id: sensor.timer_test_endtime
display:
- platform: ssd1306_i2c
model: "SSD1306 128x64"
address: 0x3C
update_interval: 5s
id: oled
lambda: |-
it.printf(0, 0, id(my_font), "Timer: %s", id(timer_status).state.c_str());
if (id(timer_status).state == "active") {
struct tm tm_finish{}, tm_ha_time{};
time_t t_helper;
double remain;
int remain_h, remain_m, remain_s;
strptime(id(timer_finish).state.c_str(), "%Y-%m-%dT%T", &tm_finish); // Convert string to time struct
t_helper = mktime(&tm_finish); // Convert to time_t
tm_ha_time = id(ha_time).now().to_c_tm(); // Get current time in a tm struct
remain = difftime(t_helper, mktime(&tm_ha_time)); // Calculate difference in seconds
remain_h = (int) remain/3600;
remain_m = (int) (remain - 3600*remain_h)/60;
remain_s = (int) remain - 3600*remain_h - 60*remain_m;
it.printf(40, 20, id(my_font), "%02d:%02d", remain_h, remain_m);
//it.printf(20, 20, id(my_font), "%02d:%02d:%02d", remain_h, remain_m, remain_s);
it.printf(0, 40, id(my_font), "End: %02d:%02d", tm_finish.tm_hour, tm_finish.tm_min);
} else {
it.printf(0, 20, id(my_font), " "); // clear second line
it.printf(0, 40, id(my_font), " "); // clear third line
}
thanks - but I will stick to my solution
it.printf(63, 42, id(font_t12), TextAlign::BASELINE_RIGHT, "%02d:%02d", tm_finish.tm_hour+1, tm_finish.tm_min);
this is an esphome only solution … hopefully the “tm_hour+1” will also work when we switch the DST - but we’ll see.
as a summery I can say, that calculating with time is not that simple especially in esphome. eg the strftime function does not work as expected when used inside a lambda with local “struct tm” variable. only works with an esphome-time ID.
again - big thanks for your help! highly appreciated!
Just a note of thanks to @jsuanet as I came across this thread while looking for display code for a timer helper. Works perfectly with a couple of modifications.
I’m grateful, thank you.
Is there a special trick to getting this to recognize the active state of the timer.timer_test entity?
I definitely have a running timer named timer_test
in HA but it never outputs anything to the display, instead it goes straight to the else statement and prints a blank space.
EDIT: Never mind, I’m a dummy, I completely forgot to add this device in HA, it was only in ESPHome.
Pefect!
I am using this for my teatimer for a while now and love it a lot.
Although over time I came across some strange “slippage” of time.
It seems to be connected to the uptime of the actual device.
It adds a second to the displayed time for around every half an hour of uptime.
So e.g. one hour after reboot the timer starts at 2:02 on the display (max7219) (while HA shows 2:00) and ends at 0:02 (HA: 0:00), so it does not affect the actual runtime just the display.
weird, right?
internal clock problems?
display timing?
any ideas?
I am stumped…
thanks for the time
struct tm tm_finish{}, tm_ha_time{}, tm_duration;
time_t t_helper,bar_helper;
double remain;
int remain_h, remain_m, remain_s, remain_all;
strptime(id(tea_done).state.c_str(), "%Y-%m-%dT%T", &tm_finish); // Convert string to time struct .minus 2 seconds for esphome ha delay??
t_helper = mktime(&tm_finish) + 3600; // Convert to time_t and add 1 hour (correct for your timezone)
tm_ha_time = id(esptime).now().to_c_tm(); // Get current time in a tm struct
remain = difftime(t_helper, mktime(&tm_ha_time)); // Calculate difference in seconds
ESP_LOGD("time debug", "All remaining seconds: %i", int(remain));
remain_h = (int) remain/3600;
remain_m = (int) (remain - 3600*remain_h)/60;
remain_s = (int) remain - 3600*remain_h - 60*remain_m;
ESP_LOGD("time debug", "Remaining: %i:%i:%i", int(remain_h),int(remain_m),int(remain_s));
it.printf(0, 0, font, "t%2d:%02d", remain_m, remain_s );
I tried to get this metod ob my nextion Display. The usecase is Cooking Timer, which should show the Seconds. I didnt found an other solution.
I made Template Sensor in esphome with the Code below. For testing return only the hours.
By installing i get the Error, that it could Not be convert remain, remain_h and so on from e.g. int to ‘esphome::optional<Std::__cxx11::basic_string >’
Is there a solution? I am Amateur in esphome…