diff --git a/README.md b/README.md index ecbcba0..d2598c3 100644 --- a/README.md +++ b/README.md @@ -513,6 +513,8 @@ ehmtxv2: **frame_interval** (optional, ms): the interval in ms to display the next animation/icon frame (default = 192), should be a multiple of the ```update_interval``` of the [display](https://esphome.io/components/display/addressable_light.html). It can be overwritten per icon/GIF, see [icons](#icons-and-animations) parameter `frame_duration` +**clock_interval** (optional, s): the interval in seconds to force the clock display. By default the clock screen, if any, will be displayed according to the position in the queue. **If you set the clock_interval close to the screen_time of the clock you will only see the clock!** (default=0) + **icons2html** (optional, boolean): If true, generate the HTML-file (*filename*.html) to show all included icons. (default = `false`) ***Example output:*** diff --git a/components/ehmtxv2/EHMTX.cpp b/components/ehmtxv2/EHMTX.cpp index 9df7e45..d01cade 100644 --- a/components/ehmtxv2/EHMTX.cpp +++ b/components/ehmtxv2/EHMTX.cpp @@ -40,14 +40,16 @@ namespace esphome void EHMTX::show_indicator(int r, int g, int b, int size) { - if (size > 0 ) { + if (size > 0) + { this->indicator_color = Color((uint8_t)r & 248, (uint8_t)g & 252, (uint8_t)b & 248); - this->display_indicator = size & 3; - ESP_LOGD(TAG, "show indicator size: %d r: %d g: %d b: %d", size, r, g, b); - } else { + this->display_indicator = size & 3; + ESP_LOGD(TAG, "show indicator size: %d r: %d g: %d b: %d", size, r, g, b); + } + else + { this->hide_indicator(); } - } void EHMTX::hide_indicator() @@ -109,7 +111,7 @@ namespace esphome } } ESP_LOGW(TAG, "icon: %s not found", name.c_str()); - + return MAXICONS; } @@ -184,24 +186,26 @@ namespace esphome register_service(&EHMTX::clock_screen, "clock_screen", {"lifetime", "screen_time", "default_font", "r", "g", "b"}); register_service(&EHMTX::rainbow_clock_screen, "rainbow_clock_screen", {"lifetime", "screen_time", "default_font"}); - + register_service(&EHMTX::date_screen, "date_screen", {"lifetime", "screen_time", "default_font", "r", "g", "b"}); register_service(&EHMTX::rainbow_date_screen, "rainbow_date_screen", {"lifetime", "screen_time", "default_font"}); register_service(&EHMTX::blank_screen, "blank_screen", {"lifetime", "screen_time"}); - register_service(&EHMTX::set_brightness, "brightness", {"value"}); ESP_LOGD(TAG, "Setup and running!"); } void EHMTX::show_alarm(int r, int g, int b, int size) { - if (size > 0){ + if (size > 0) + { this->alarm_color = Color((uint8_t)r & 248, (uint8_t)g & 252, (uint8_t)b & 248); - this->display_alarm = size & 3; - ESP_LOGD(TAG, "show alarm size: %d color r: %d g: %d b: %d", size, r, g, b); - } else { + this->display_alarm = size & 3; + ESP_LOGD(TAG, "show alarm size: %d color r: %d g: %d b: %d", size, r, g, b); + } + else + { this->hide_alarm(); } } @@ -222,8 +226,10 @@ namespace esphome void EHMTX::update() // called from polling component { - if (!this->is_running){ - if (this->clock->now().timestamp > 15) { + if (!this->is_running) + { + if (this->clock->now().timestamp > 15) + { ESP_LOGD(TAG, "time sync => starting"); this->is_running = true; } @@ -280,6 +286,31 @@ namespace esphome return hit; } + uint8_t EHMTX::find_last_clock() + { + uint8_t hit = MAXQUEUE; + if (this->clock_interval > 0) + { + time_t ts = this->clock->now().timestamp; + for (size_t i = 0; i < MAXQUEUE; i++) + { + if ((this->queue[i]->mode == MODE_CLOCK)||(this->queue[i]->mode == MODE_RAINBOW_CLOCK)) + { + if (ts > (this->queue[i]->last_time + this->clock_interval)) + { + hit = i; + } + break; + } + } + if (hit != MAXQUEUE) + { + ESP_LOGD(TAG, "forced clock_interval"); + } + } + return hit; + } + void EHMTX::remove_expired_queue_element() { time_t ts = this->clock->now().timestamp; @@ -341,11 +372,15 @@ namespace esphome time_t ts = this->clock->now().timestamp; if (this->is_running) - { + { if (ts > this->next_action_time) { this->remove_expired_queue_element(); - this->screen_pointer = find_oldest_queue_element(); + this->screen_pointer = this->find_last_clock(); + if (this->screen_pointer == MAXQUEUE) + { + this->screen_pointer = find_oldest_queue_element(); + } if (this->screen_pointer != MAXQUEUE) { this->queue[this->screen_pointer]->shiftx_ = 0; @@ -382,7 +417,7 @@ namespace esphome } else { - uint8_t w = (1+(uint8_t)(32 / 16) * (this->boot_anim / 16)) % 32; + uint8_t w = (1 + (uint8_t)(32 / 16) * (this->boot_anim / 16)) % 32; this->display->rectangle(0, 2, w, 4, this->rainbow_color); // Color(120, 190, 40)); this->boot_anim++; } @@ -489,6 +524,11 @@ namespace esphome } } + void EHMTX::set_clock_interval(uint16_t t) + { + this->clock_interval = t; + } + void EHMTX::icon_screen(std::string iconname, std::string text, int lifetime, int screen_time, bool default_font, int r, int g, int b) { uint8_t icon = this->find_icon(iconname.c_str()); @@ -518,7 +558,7 @@ namespace esphome screen->centerx_ = ceil((22 - pixel) / 2); screen->screen_time = screen_time; } - else + else { screen->centerx_ = 0; int display_duration = ceil((this->scroll_count * (TEXTSTARTOFFSET + pixel) * this->scroll_interval) / 1000); @@ -535,13 +575,13 @@ namespace esphome screen->icon = icon; for (auto *t : on_add_screen_triggers_) { - t->process(screen->icon_name,(uint8_t)screen->mode); + t->process(screen->icon_name, (uint8_t)screen->mode); } ESP_LOGD(TAG, "icon screen icon: %d iconname: %s text: %s lifetime: %d screen_time: %d", icon, iconname.c_str(), text.c_str(), lifetime, screen_time); screen->status(); } -void EHMTX::rainbow_icon_screen(std::string iconname, std::string text, int lifetime, int screen_time, bool default_font) + void EHMTX::rainbow_icon_screen(std::string iconname, std::string text, int lifetime, int screen_time, bool default_font) { uint8_t icon = this->find_icon(iconname.c_str()); @@ -570,7 +610,7 @@ void EHMTX::rainbow_icon_screen(std::string iconname, std::string text, int life screen->centerx_ = ceil((22 - pixel) / 2); screen->screen_time = screen_time; } - else + else { screen->centerx_ = 0; int display_duration = ceil((this->scroll_count * (TEXTSTARTOFFSET + pixel) * this->scroll_interval) / 1000); @@ -586,14 +626,12 @@ void EHMTX::rainbow_icon_screen(std::string iconname, std::string text, int life screen->icon = icon; for (auto *t : on_add_screen_triggers_) { - t->process(screen->icon_name,(uint8_t)screen->mode); + t->process(screen->icon_name, (uint8_t)screen->mode); } ESP_LOGD(TAG, "rainbow icon screen icon: %d iconname: %s text: %s lifetime: %d screen_time: %d", icon, iconname.c_str(), text.c_str(), lifetime, screen_time); screen->status(); } - - void EHMTX::rainbow_clock_screen(int lifetime, int screen_time, bool default_font) { EHMTX_queue *screen = this->find_free_queue_element(); @@ -601,7 +639,7 @@ void EHMTX::rainbow_icon_screen(std::string iconname, std::string text, int life ESP_LOGD(TAG, "rainbow_clock_screen lifetime: %d screen_time: %d", lifetime, screen_time); screen->mode = MODE_RAINBOW_CLOCK; screen->default_font = default_font; - screen->screen_time = screen_time; + screen->screen_time = (screen_time > this->clock_interval)?screen_time:this->clock_interval-1; screen->endtime = this->clock->now().timestamp + lifetime * 60; screen->status(); } @@ -638,7 +676,7 @@ void EHMTX::rainbow_icon_screen(std::string iconname, std::string text, int life screen->text = text; screen->endtime = this->clock->now().timestamp + lifetime * 60; - screen->screen_time = screen_time; + screen->screen_time = screen_time; screen->default_font = default_font; screen->mode = MODE_RAINBOW_TEXT; screen->calc_scroll_time(); @@ -667,7 +705,7 @@ void EHMTX::rainbow_icon_screen(std::string iconname, std::string text, int life screen->endtime = this->clock->now().timestamp + lifetime * 60; for (auto *t : on_add_screen_triggers_) { - t->process(screen->icon_name,(uint8_t)screen->mode); + t->process(screen->icon_name, (uint8_t)screen->mode); } ESP_LOGD(TAG, "full screen: icon: %d iconname: %s lifetime: %d screen_time:%d ", icon, iconname.c_str(), lifetime, screen_time); screen->status(); @@ -681,7 +719,7 @@ void EHMTX::rainbow_icon_screen(std::string iconname, std::string text, int life ESP_LOGD(TAG, "clock_screen_color lifetime: %d screen_time: %d red: %d green: %d blue: %d", lifetime, screen_time, r, g, b); screen->mode = MODE_CLOCK; screen->default_font = default_font; - screen->screen_time = screen_time; + screen->screen_time = (screen_time > this->clock_interval)?screen_time:this->clock_interval-1; screen->endtime = this->clock->now().timestamp + lifetime * 60; screen->status(); } @@ -855,6 +893,7 @@ void EHMTX::rainbow_icon_screen(std::string iconname, std::string text, int life ESP_LOGCONFIG(TAG, "Boot anim: %d", this->boot_anim); ESP_LOGCONFIG(TAG, "Icons: %d of %d", this->icon_count, MAXICONS); ESP_LOGCONFIG(TAG, "Max screens: %d", MAXQUEUE); + ESP_LOGCONFIG(TAG, "Clock interval: %d s", this->clock_interval); ESP_LOGCONFIG(TAG, "Date format: %s", this->date_fmt.c_str()); ESP_LOGCONFIG(TAG, "Time format: %s", this->time_fmt.c_str()); ESP_LOGCONFIG(TAG, "Interval (ms) scroll: %d frame: %d", this->scroll_interval, this->frame_interval); diff --git a/components/ehmtxv2/EHMTX.h b/components/ehmtxv2/EHMTX.h index c07c1ca..9d1855d 100644 --- a/components/ehmtxv2/EHMTX.h +++ b/components/ehmtxv2/EHMTX.h @@ -85,11 +85,13 @@ namespace esphome int8_t default_yoffset, default_xoffset; int8_t special_yoffset, special_xoffset; uint8_t find_icon(std::string name); + uint8_t find_last_clock(); bool string_has_ending(std::string const &fullString, std::string const &ending); bool show_seconds; uint16_t scroll_interval; // ms to between scrollsteps uint16_t rainbow_interval; // ms to between scrollsteps uint16_t frame_interval; // ms to next_frame() + uint16_t clock_interval; uint16_t hold_time; // seconds display of screen_time to extend uint8_t icon_count; // max iconnumber -1 unsigned long last_scroll_time; @@ -105,7 +107,7 @@ namespace esphome void skip_screen(); void hold_screen(int t=30); void set_display(addressable_light::AddressableLightDisplay *disp); - + void set_clock_interval(uint16_t t=60); void set_hold_time(uint16_t t=30); void set_clock_time(uint16_t t=10); void set_show_day_of_week(bool b); @@ -192,7 +194,6 @@ namespace esphome bool update_slot(uint8_t _icon); void update_screen(); void hold_slot(uint8_t _sec); - void set_text(std::string text, uint8_t icon, uint16_t pixel, uint16_t et, uint16_t st); void calc_scroll_time(); }; diff --git a/components/ehmtxv2/EHMTX_queue.cpp b/components/ehmtxv2/EHMTX_queue.cpp index 327dd14..433acb6 100644 --- a/components/ehmtxv2/EHMTX_queue.cpp +++ b/components/ehmtxv2/EHMTX_queue.cpp @@ -225,24 +225,7 @@ namespace esphome } // TODO void EHMTX_queue::set_mode_icon() - void EHMTX_queue::set_text(std::string text, uint8_t icon, uint16_t pixel, uint16_t et, uint16_t screen_time) - { - this->text = text; - this->pixels_ = pixel; - - if (pixel < 23) - { - this->centerx_ = ceil((22 - pixel) / 2); - } - - this->shiftx_ = 0; - float display_duration = ceil((this->config_->scroll_count * (TEXTSTARTOFFSET + pixel) * this->config_->scroll_interval) / 1000); - this->screen_time = (display_duration > screen_time) ? display_duration : screen_time; - ESP_LOGD(TAG, "display text: %s pixels %d display_duration %d calculated: %d screen_time: %d", text.c_str(), pixel,display_duration, this->screen_time, screen_time); - this->endtime = this->config_->clock->now().timestamp + et * 60; - this->icon = icon; - } - + void EHMTX_queue::calc_scroll_time() { int x, y, w, h; diff --git a/components/ehmtxv2/__init__.py b/components/ehmtxv2/__init__.py index add1e5d..7964046 100644 --- a/components/ehmtxv2/__init__.py +++ b/components/ehmtxv2/__init__.py @@ -59,6 +59,7 @@ AddScreenTrigger = ehmtx_ns.class_( CONF_URL = "url" CONF_FLAG = "flag" +CONF_CLOCKINTERVAL = "clock_interval" CONF_TIMECOMPONENT = "time_component" CONF_LAMEID = "lameid" CONF_LIFETIME = "lifetime" @@ -99,6 +100,9 @@ EHMTX_SCHEMA = cv.Schema({ cv.Required(CONF_MATRIXCOMPONENT): cv.use_id(display), cv.Required(CONF_DEFAULT_FONT_ID): cv.use_id(font), cv.Required(CONF_special_FONT_ID): cv.use_id(font), + cv.Optional( + CONF_CLOCKINTERVAL, default="0" + ): cv.templatable(cv.positive_int), cv.Optional( CONF_HTML, default=False ): cv.boolean, @@ -361,6 +365,7 @@ async def to_code(config): cg.add(var.set_scroll_count(config[CONF_SCROLLCOUNT])) cg.add(var.set_frame_interval(config[CONF_FRAMEINTERVAL])) cg.add(var.set_week_start(config[CONF_WEEK_START_MONDAY])) + cg.add(var.set_clock_interval(config[CONF_CLOCKINTERVAL])) cg.add(var.set_time_format(config[CONF_TIME_FORMAT])) cg.add(var.set_date_format(config[CONF_DATE_FORMAT])) cg.add(var.set_show_day_of_week(config[CONF_SHOWDOW]))