diff --git a/components/ehmtx/EHMTX.cpp b/components/ehmtx/EHMTX.cpp index 31a0e33..00451de 100644 --- a/components/ehmtx/EHMTX.cpp +++ b/components/ehmtx/EHMTX.cpp @@ -14,7 +14,7 @@ namespace esphome this->today_color = Color(C_RED, C_GREEN, C_BLUE); this->weekday_color = Color(CD_RED, CD_GREEN, CD_BLUE); this->clock_color = Color(C_RED, C_GREEN, C_BLUE); - + this->rainbow_color = Color(CA_RED, CA_GREEN, CA_BLUE); this->alarm_color = Color(CA_RED, CA_GREEN, CA_BLUE); this->gauge_color = Color(CD_RED, CD_GREEN, CD_BLUE); this->gauge_value = 0; @@ -25,7 +25,7 @@ namespace esphome this->queue[i] = new EHMTX_queue(this); } - this->is_running =false; + this->is_running = false; } void EHMTX::set_time_format(std::string s) @@ -171,14 +171,14 @@ namespace esphome register_service(&EHMTX::show_gauge, "show_gauge", {"percent", "r", "g", "b"}); register_service(&EHMTX::show_alarm, "show_alarm", {"r", "g", "b"}); register_service(&EHMTX::show_indicator, "show_indicator", {"r", "g", "b"}); - + register_service(&EHMTX::set_text_color, "text_color", {"r", "g", "b"}); register_service(&EHMTX::set_clock_color, "clock_color", {"r", "g", "b"}); register_service(&EHMTX::set_today_color, "today_color", {"r", "g", "b"}); register_service(&EHMTX::set_weekday_color, "weekday_color", {"r", "g", "b"}); - - register_service(&EHMTX::del_screen, "del_screen", {"icon_name","mode"}); - register_service(&EHMTX::force_screen, "force_screen", {"icon_name","mode"}); + + register_service(&EHMTX::del_screen, "del_screen", {"icon_name", "mode"}); + register_service(&EHMTX::force_screen, "force_screen", {"icon_name", "mode"}); register_service(&EHMTX::fullscreen, "fullscreen", {"icon_name", "lifetime", "screen_time"}); register_service(&EHMTX::icon_screen, "icon_screen", {"icon_name", "text", "lifetime", "screen_time", "default_font", "r", "g", "b"}); @@ -186,10 +186,12 @@ namespace esphome register_service(&EHMTX::clock_screen, "clock_screen", {"lifetime", "screen_time", "default_font", "r", "g", "b"}); register_service(&EHMTX::blank_screen, "blank_screen", {"lifetime", "screen_time"}); register_service(&EHMTX::date_screen, "date_screen", {"lifetime", "screen_time", "default_font", "r", "g", "b"}); - - register_service(&EHMTX::set_brightness, "brightness", {"value"}); + register_service(&EHMTX::rainbow_icon_screen, "rainbow_icon_screen", {"icon_name", "text", "lifetime", "screen_time", "default_font"}); + register_service(&EHMTX::rainbow_text_screen, "rainbow_text_screen", {"text", "lifetime", "screen_time", "default_font"}); - this->is_running=true; + register_service(&EHMTX::set_brightness, "brightness", {"value"}); + + this->is_running = true; } void EHMTX::show_alarm(int r, int g, int b) @@ -230,7 +232,7 @@ namespace esphome if (this->queue[i]->mode == mode) { bool force = true; - if ((mode == MODE_ICONSCREEN)||(mode == MODE_FULLSCREEN)) + if ((mode == MODE_ICONSCREEN) || (mode == MODE_FULLSCREEN) || (mode == MODE_RAINBOW_ICON)) { if (strcmp(this->queue[i]->icon_name.c_str(), icon_name.c_str()) != 0) { @@ -248,211 +250,215 @@ namespace esphome } } } - uint8_t EHMTX::find_oldest_queue_element() + uint8_t EHMTX::find_oldest_queue_element() + { + uint8_t hit = MAXQUEUE; + time_t last_time = this->clock->now().timestamp; + for (size_t i = 0; i < MAXQUEUE; i++) { - uint8_t hit = MAXQUEUE; - time_t last_time = this->clock->now().timestamp; - for (size_t i = 0; i < MAXQUEUE; i++) - { - if ((this->queue[i]->endtime > 0) && (this->queue[i]->last_time < last_time)) - { - hit = i; - last_time = this->queue[i]->last_time; - } - } - if (hit != MAXQUEUE) + if ((this->queue[i]->endtime > 0) && (this->queue[i]->last_time < last_time)) { - // ESP_LOGD(TAG, "find_oldest_queue_element: oldest screen is: %d", hit); - this->queue[hit]->status(); + hit = i; + last_time = this->queue[i]->last_time; } - return hit; } + if (hit != MAXQUEUE) + { + // ESP_LOGD(TAG, "find_oldest_queue_element: oldest screen is: %d", hit); + this->queue[hit]->status(); + } + return hit; + } - void EHMTX::remove_expired_queue_element() + void EHMTX::remove_expired_queue_element() + { + time_t ts = this->clock->now().timestamp; + std::string infotext; + for (size_t i = 0; i < MAXQUEUE; i++) { - time_t ts = this->clock->now().timestamp; - std::string infotext; - for (size_t i = 0; i < MAXQUEUE; i++) + if ((this->queue[i]->endtime > 0) && (this->queue[i]->endtime < ts)) { - if ((this->queue[i]->endtime > 0) && (this->queue[i]->endtime < ts)) + this->queue[i]->endtime = 0; + if (this->queue[i]->mode != MODE_EMPTY) { - this->queue[i]->endtime = 0; - if ((this->queue[i]->mode == MODE_ICONSCREEN) || (this->queue[i]->mode == MODE_FULLSCREEN)) + ESP_LOGD(TAG, "remove_expired_queue_element: removed slot %d: icon_name: %s text: %s", i, this->queue[i]->icon_name.c_str(), this->queue[i]->text.c_str()); + for (auto *t : on_expired_screen_triggers_) { - ESP_LOGD(TAG, "remove_expired_queue_element: removed slot %d: icon_name: %s text: %s", i, this->queue[i]->icon_name.c_str(), this->queue[i]->text.c_str()); - for (auto *t : on_expired_screen_triggers_) + infotext = ""; + switch (this->queue[i]->mode) { - infotext = ""; - switch (this->queue[i]->mode) - { - case MODE_EMPTY: - break; - case MODE_BLANK: - break; - case MODE_CLOCK: - infotext = "clock"; - break; - case MODE_DATE: - infotext = "clock"; - break; - case MODE_FULLSCREEN: - infotext = "fullscreen " + this->queue[i]->icon_name; - break; - case MODE_ICONSCREEN: - infotext = this->queue[i]->icon_name.c_str(); - break; - case MODE_TEXT: - infotext = "TEXT"; - break; - default: - break; - } - t->process(this->queue[i]->icon_name, infotext); + case MODE_EMPTY: + break; + case MODE_BLANK: + break; + case MODE_CLOCK: + infotext = "clock"; + break; + case MODE_DATE: + infotext = "clock"; + break; + case MODE_FULLSCREEN: + infotext = "fullscreen " + this->queue[i]->icon_name; + break; + case MODE_ICONSCREEN: + case MODE_RAINBOW_ICON: + infotext = this->queue[i]->icon_name.c_str(); + break; + case MODE_RAINBOW_TEXT: + case MODE_TEXT: + infotext = "TEXT"; + break; + default: + break; } + t->process(this->queue[i]->icon_name, infotext); } - this->queue[i]->mode = MODE_EMPTY; } + this->queue[i]->mode = MODE_EMPTY; } } - void EHMTX::tick() + } + void EHMTX::tick() + { + + if (this->is_running) { - - if (this->is_running) + time_t ts = this->clock->now().timestamp; + if (ts > this->next_action_time) { - time_t ts = this->clock->now().timestamp; - if (ts > this->next_action_time) + this->remove_expired_queue_element(); + this->screen_pointer = find_oldest_queue_element(); + if (this->screen_pointer != MAXQUEUE) { - this->remove_expired_queue_element(); - this->screen_pointer = find_oldest_queue_element(); - if (this->screen_pointer != MAXQUEUE) + this->queue[this->screen_pointer]->reset_shiftx(); + this->queue[this->screen_pointer]->last_time = ts + this->queue[this->screen_pointer]->screen_time; + if (this->queue[this->screen_pointer]->icon < this->icon_count) { - this->queue[this->screen_pointer]->reset_shiftx(); - this->queue[this->screen_pointer]->last_time = ts + this->queue[this->screen_pointer]->screen_time; - if (this->queue[this->screen_pointer]->icon < this->icon_count) { - this->icons[this->queue[this->screen_pointer]->icon]->set_frame(0); - } - this->next_action_time = this->queue[this->screen_pointer]->last_time; - // Todo switch for Triggers - if (this->queue[this->screen_pointer]->mode == MODE_CLOCK) - { - for (auto *t : on_next_clock_triggers_) - { - t->process(); - } - } - else + this->icons[this->queue[this->screen_pointer]->icon]->set_frame(0); + } + this->next_action_time = this->queue[this->screen_pointer]->last_time; + // Todo switch for Triggers + if (this->queue[this->screen_pointer]->mode == MODE_CLOCK) + { + for (auto *t : on_next_clock_triggers_) { - for (auto *t : on_next_screen_triggers_) - { - t->process(this->queue[this->screen_pointer]->icon_name, this->queue[this->screen_pointer]->text); - } + t->process(); } } else { - ESP_LOGW(TAG, "tick: nothing to do. Restarting clock display!"); - this->clock_screen(24 * 60, this->clock_time, false, C_RED, C_GREEN, C_BLUE); - this->date_screen(24 * 60, (int)this->clock_time / 2, false, C_RED, C_GREEN, C_BLUE); - this->next_action_time = ts + this->clock_time; + for (auto *t : on_next_screen_triggers_) + { + t->process(this->queue[this->screen_pointer]->icon_name, this->queue[this->screen_pointer]->text); + } } } - } - else { - uint8_t w = ((uint8_t) (32/14) * (this->boot_anim / 14)) % 32; - this->display->rectangle(0,1,w,6,Color(120,190,40)); - this->boot_anim++; + else + { + ESP_LOGW(TAG, "tick: nothing to do. Restarting clock display!"); + this->clock_screen(24 * 60, this->clock_time, false, C_RED, C_GREEN, C_BLUE); + this->date_screen(24 * 60, (int)this->clock_time / 2, false, C_RED, C_GREEN, C_BLUE); + this->next_action_time = ts + this->clock_time; + } } } - - void EHMTX::set_screen_time(uint16_t t) + else { - ESP_LOGD(TAG, "default screen time: %d", t); - this->screen_time = t; + uint8_t w = ((uint8_t)(32 / 14) * (this->boot_anim / 14)) % 32; + this->display->rectangle(0, 2, w, 4, Color(120, 190, 40)); + this->boot_anim++; } + } - void EHMTX::skip_screen() - { - this->next_action_time = this->clock->now().timestamp - 1; - } + void EHMTX::set_screen_time(uint16_t t) + { + ESP_LOGD(TAG, "default screen time: %d", t); + this->screen_time = t; + } - void EHMTX::hold_screen() - { - this->next_action_time += this->hold_time; - } + void EHMTX::skip_screen() + { + this->next_action_time = this->clock->now().timestamp - 1; + } - void EHMTX::get_status() - { - time_t ts = this->clock->now().timestamp; - ESP_LOGI(TAG, "status time: %d.%d.%d %02d:%02d", this->clock->now().day_of_month, - this->clock->now().month, this->clock->now().year, - this->clock->now().hour, this->clock->now().minute); - ESP_LOGI(TAG, "status brightness: %d (0..255)", this->brightness_); - ESP_LOGI(TAG, "status date format: %s", this->date_fmt.c_str()); - ESP_LOGI(TAG, "status time format: %s", this->time_fmt.c_str()); - ESP_LOGI(TAG, "status text_color: RGB(%d,%d,%d)", this->text_color.r, this->text_color.g, this->text_color.b); - ESP_LOGI(TAG, "status alarm_color: RGB(%d,%d,%d)", this->alarm_color.r, this->alarm_color.g, this->alarm_color.b); - if (this->display_indicator) - { - ESP_LOGI(TAG, "status indicator on"); - } - else - { - ESP_LOGI(TAG, "status indicator off"); - } - if (this->show_display) - { - ESP_LOGI(TAG, "status display on"); - } - else - { - ESP_LOGI(TAG, "status display off"); - } + void EHMTX::hold_screen() + { + this->next_action_time += this->hold_time; + } - this->queue_status(); + void EHMTX::get_status() + { + time_t ts = this->clock->now().timestamp; + ESP_LOGI(TAG, "status time: %d.%d.%d %02d:%02d", this->clock->now().day_of_month, + this->clock->now().month, this->clock->now().year, + this->clock->now().hour, this->clock->now().minute); + ESP_LOGI(TAG, "status brightness: %d (0..255)", this->brightness_); + ESP_LOGI(TAG, "status date format: %s", this->date_fmt.c_str()); + ESP_LOGI(TAG, "status time format: %s", this->time_fmt.c_str()); + ESP_LOGI(TAG, "status text_color: RGB(%d,%d,%d)", this->text_color.r, this->text_color.g, this->text_color.b); + ESP_LOGI(TAG, "status alarm_color: RGB(%d,%d,%d)", this->alarm_color.r, this->alarm_color.g, this->alarm_color.b); + if (this->display_indicator) + { + ESP_LOGI(TAG, "status indicator on"); } - - void EHMTX::queue_status() + else { - uint8_t empty = 0; - for (uint8_t i = 0; i < MAXQUEUE; i++) - { - if (this->queue[i]->mode != MODE_EMPTY) - this->queue[i]->status(); - else - empty++; - } - if (empty > 0) - ESP_LOGI(TAG, "queue: %d empty slots", empty); + ESP_LOGI(TAG, "status indicator off"); } - - void EHMTX::set_default_font(display::Font * font) + if (this->show_display) { - this->default_font = font; + ESP_LOGI(TAG, "status display on"); } - - void EHMTX::set_special_font(display::Font * font) + else { - this->special_font = font; + ESP_LOGI(TAG, "status display off"); } - void EHMTX::set_frame_interval(uint16_t fi) - { - this->frame_interval = fi; - } + this->queue_status(); + } - void EHMTX::set_scroll_interval(uint16_t si) + void EHMTX::queue_status() + { + uint8_t empty = 0; + for (uint8_t i = 0; i < MAXQUEUE; i++) { - this->scroll_interval = si; + if (this->queue[i]->mode != MODE_EMPTY) + this->queue[i]->status(); + else + empty++; } + if (empty > 0) + ESP_LOGI(TAG, "queue: %d empty slots", empty); + } - void EHMTX::del_screen(std::string icon_name,int mode) - { + void EHMTX::set_default_font(display::Font *font) + { + this->default_font = font; + } + + void EHMTX::set_special_font(display::Font *font) + { + this->special_font = font; + } + + void EHMTX::set_frame_interval(uint16_t fi) + { + this->frame_interval = fi; + } + + void EHMTX::set_scroll_interval(uint16_t si) + { + this->scroll_interval = si; + } + + void EHMTX::del_screen(std::string icon_name, int mode) + { for (uint8_t i = 0; i < MAXQUEUE; i++) { if (this->queue[i]->mode == mode) { bool force = true; - if ((mode == MODE_ICONSCREEN)||(mode == MODE_FULLSCREEN)) + if ((mode == MODE_ICONSCREEN) || (mode == MODE_FULLSCREEN) || (mode == MODE_RAINBOW_ICON)) { if (strcmp(this->queue[i]->icon_name.c_str(), icon_name.c_str()) != 0) { @@ -460,369 +466,408 @@ namespace esphome } } if (force) + { + this->queue[i]->mode = MODE_EMPTY; + this->queue[i]->endtime = 0; + ESP_LOGW(TAG, "del_screen: icon %s in position: %d mode %d", icon_name.c_str(), i, mode); + if (i == this->screen_pointer) { - this->queue[i]->mode = MODE_EMPTY; - this->queue[i]->endtime = 0; - ESP_LOGW(TAG, "del_screen: icon %s in position: %d mode %d", icon_name.c_str(),i, mode); - if (i == this->screen_pointer){ - this->next_action_time= this->clock->now().timestamp; - } + this->next_action_time = this->clock->now().timestamp; } + } } } + } + + 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()); + + if (icon >= this->icon_count) + { + ESP_LOGW(TAG, "icon %d not found => default: 0", icon); + icon = 0; + } + EHMTX_queue *screen = this->find_icon_queue_element(icon); + + int x, y, w, h; + if (default_font) + { + this->display->get_text_bounds(0, 0, text.c_str(), this->default_font, display::TextAlign::LEFT, &x, &y, &w, &h); } - - void EHMTX::icon_screen(std::string iconname, std::string text, int lifetime, int screen_time, bool default_font, int r, int g, int b) + else { - uint8_t icon = this->find_icon(iconname.c_str()); + this->display->get_text_bounds(0, 0, text.c_str(), this->special_font, display::TextAlign::LEFT, &x, &y, &w, &h); + } + screen->set_text(text, icon, w, lifetime, screen_time); + screen->text_color = Color(r, g, b); + screen->default_font = default_font; + screen->mode = MODE_ICONSCREEN; + screen->icon_name = iconname; + 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(); + } - if (icon >= this->icon_count) - { - ESP_LOGW(TAG, "icon %d not found => default: 0", icon); - icon = 0; - } - EHMTX_queue *screen = this->find_icon_queue_element(icon); + 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()); - int x, y, w, h; - if (default_font) - { - this->display->get_text_bounds(0, 0, text.c_str(), this->default_font, display::TextAlign::LEFT, &x, &y, &w, &h); - } - else - { - this->display->get_text_bounds(0, 0, text.c_str(), this->special_font, display::TextAlign::LEFT, &x, &y, &w, &h); - } - screen->set_text(text, icon, w, lifetime, screen_time); - screen->text_color = Color(r, g, b); - screen->default_font = default_font; - screen->mode = MODE_ICONSCREEN; - screen->icon_name = iconname; - 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(); + if (icon >= this->icon_count) + { + ESP_LOGW(TAG, "icon %d not found => default: 0", icon); + icon = 0; } + EHMTX_queue *screen = this->find_icon_queue_element(icon); - void EHMTX::timer_screen(std::string icon_name, int seconds, int lifetime, int screen_time, bool default_font, int r, int g, int b) + int x, y, w, h; + if (default_font) { - uint8_t icon = this->find_icon(icon_name.c_str()); + this->display->get_text_bounds(0, 0, text.c_str(), this->default_font, display::TextAlign::LEFT, &x, &y, &w, &h); + } + else + { + this->display->get_text_bounds(0, 0, text.c_str(), this->special_font, display::TextAlign::LEFT, &x, &y, &w, &h); + } + screen->set_text(text, icon, w, lifetime, screen_time); + screen->default_font = default_font; + screen->mode = MODE_RAINBOW_ICON; + screen->icon_name = iconname; + 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(); + } - if (icon >= this->icon_count) - { - ESP_LOGW(TAG, "icon %d not found => default: 0", icon); - icon = 0; - } - EHMTX_queue *screen = this->find_icon_queue_element(icon); + void EHMTX::text_screen(std::string text, int lifetime, int screen_time, bool default_font, int r, int g, int b) + { + EHMTX_queue *screen = this->find_free_queue_element(); - screen->text = "00:00"; - screen->icon = icon; - screen->text_color = Color(r, g, b); - screen->default_font = default_font; - screen->mode = MODE_TIMER; - screen->icon_name = icon_name; - screen->screen_time = screen_time; - screen->endtime = this->clock->now().timestamp + lifetime * 60; - ESP_LOGD(TAG, "TIMER_screen icon: %d icon_ name: %s seconds: %d lifetime: %d screen_time: %d", icon, icon_name.c_str(), seconds, lifetime, screen_time); - screen->status(); + int x, y, w, h; + if (default_font) + { + this->display->get_text_bounds(0, 0, text.c_str(), this->default_font, display::TextAlign::LEFT, &x, &y, &w, &h); + } + else + { + this->display->get_text_bounds(0, 0, text.c_str(), this->special_font, display::TextAlign::LEFT, &x, &y, &w, &h); } - void EHMTX::text_screen(std::string text, int lifetime, int screen_time, bool default_font, int r, int g, int b) + screen->text = text; + screen->pixels_ = w; + if (screen->pixels_ < 32) { - EHMTX_queue *screen = this->find_free_queue_element(); + screen->centerx_ = ceil((32 - screen->pixels_) / 2); + } - int x, y, w, h; - if (default_font) - { - this->display->get_text_bounds(0, 0, text.c_str(), this->default_font, display::TextAlign::LEFT, &x, &y, &w, &h); - } - else - { - this->display->get_text_bounds(0, 0, text.c_str(), this->special_font, display::TextAlign::LEFT, &x, &y, &w, &h); - } + screen->shiftx_ = 0; + float display_duration = ceil((this->scroll_count * w * this->scroll_interval) / 1000); + screen->screen_time = (display_duration > screen_time) ? display_duration : screen_time; + ESP_LOGD(TAG, "text_screen text: text: %s pixels %d screen_time: %d lifetime: %d", text.c_str(), w, screen->screen_time, lifetime); + screen->endtime = this->clock->now().timestamp + lifetime * 60; - screen->text = text; - screen->pixels_ = w; - if (screen->pixels_ < 32) - { - screen->centerx_ = ceil((32 - screen->pixels_) / 2); - } + screen->text_color = Color(r, g, b); + screen->default_font = default_font; + screen->mode = MODE_TEXT; - screen->shiftx_ = 0; - float display_duration = ceil((this->scroll_count * w * this->scroll_interval) / 1000); - screen->screen_time = (display_duration > screen_time) ? display_duration : screen_time; - ESP_LOGD(TAG, "text_screen text: text: %s pixels %d screen_time: %d lifetime: %d", text.c_str(), w, screen->screen_time, lifetime); - screen->endtime = this->clock->now().timestamp + lifetime * 60; + screen->status(); + } - screen->text_color = Color(r, g, b); - screen->default_font = default_font; - screen->mode = MODE_TEXT; + void EHMTX::rainbow_text_screen(std::string text, int lifetime, int screen_time, bool default_font) + { + EHMTX_queue *screen = this->find_free_queue_element(); - screen->status(); + int x, y, w, h; + if (default_font) + { + this->display->get_text_bounds(0, 0, text.c_str(), this->default_font, display::TextAlign::LEFT, &x, &y, &w, &h); } - - void EHMTX::fullscreen(std::string iconname, int lifetime, int screen_time) + else { - uint8_t icon = this->find_icon(iconname.c_str()); - - if (icon >= this->icon_count) - { - ESP_LOGW(TAG, "fullscreen: icon %d not found => default: 0", icon); - icon = 0; - } - EHMTX_queue *screen = this->find_icon_queue_element(icon); - - screen->mode = MODE_FULLSCREEN; - screen->icon = icon; - screen->icon_name = iconname; - screen->screen_time = screen_time; - screen->endtime = this->clock->now().timestamp + lifetime * 60; - ESP_LOGD(TAG, "fullscreen: icon: %d iconname: %s lifetime: %d screen_time:%d ", icon, iconname.c_str(), lifetime, screen_time); - screen->status(); + this->display->get_text_bounds(0, 0, text.c_str(), this->special_font, display::TextAlign::LEFT, &x, &y, &w, &h); } - void EHMTX::clock_screen(int lifetime, int screen_time, bool default_font, int r, int g, int b) + screen->text = text; + screen->pixels_ = w; + if (screen->pixels_ < 32) { - EHMTX_queue *screen = this->find_free_queue_element(); - - screen->text_color = Color(r, g, b); - 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->endtime = this->clock->now().timestamp + lifetime * 60; - screen->status(); + screen->centerx_ = ceil((32 - screen->pixels_) / 2); } - void EHMTX::date_screen(int lifetime, int screen_time, bool default_font, int r, int g, int b) - { - EHMTX_queue *screen = this->find_free_queue_element(); + screen->shiftx_ = 0; + float display_duration = ceil((this->scroll_count * w * this->scroll_interval) / 1000); + screen->screen_time = (display_duration > screen_time) ? display_duration : screen_time; + ESP_LOGD(TAG, "text_screen text: text: %s pixels %d screen_time: %d lifetime: %d", text.c_str(), w, screen->screen_time, lifetime); + screen->endtime = this->clock->now().timestamp + lifetime * 60; - screen->text_color = Color(r, g, b); - ESP_LOGD(TAG, "date_screen lifetime: %d screen_time: %d red: %d green: %d blue: %d", lifetime, screen_time, r, g, b); - screen->mode = MODE_DATE; - screen->screen_time = screen_time; - screen->default_font = default_font; - screen->endtime = this->clock->now().timestamp + lifetime * 60; - screen->status(); - } + screen->default_font = default_font; + screen->mode = MODE_RAINBOW_TEXT; - EHMTX_queue *EHMTX::find_icon_queue_element(uint8_t icon) - { - for (size_t i = 0; i < MAXQUEUE; i++) - { - if ((this->queue[i]->mode == MODE_ICONSCREEN) && (this->queue[i]->icon == icon)) - { - ESP_LOGD(TAG, "free_screen: found by icon"); - return this->queue[i]; - } - } - return this->find_free_queue_element(); - } + screen->status(); + } - EHMTX_queue *EHMTX::find_free_queue_element() + void EHMTX::fullscreen(std::string iconname, int lifetime, int screen_time) + { + uint8_t icon = this->find_icon(iconname.c_str()); + + if (icon >= this->icon_count) { - time_t ts = this->clock->now().timestamp; - for (size_t i = 0; i < MAXQUEUE; i++) - { - if (this->queue[i]->endtime < ts) - { - ESP_LOGD(TAG, "free_screen: found by endtime %d", i); - return this->queue[i]; - } - } - return this->queue[0]; + ESP_LOGW(TAG, "fullscreen: icon %d not found => default: 0", icon); + icon = 0; } + EHMTX_queue *screen = this->find_icon_queue_element(icon); + + screen->mode = MODE_FULLSCREEN; + screen->icon = icon; + screen->icon_name = iconname; + screen->screen_time = screen_time; + screen->endtime = this->clock->now().timestamp + lifetime * 60; + ESP_LOGD(TAG, "fullscreen: icon: %d iconname: %s lifetime: %d screen_time:%d ", icon, iconname.c_str(), lifetime, screen_time); + screen->status(); + } - void EHMTX::set_show_date(bool b) + void EHMTX::clock_screen(int lifetime, int screen_time, bool default_font, int r, int g, int b) + { + EHMTX_queue *screen = this->find_free_queue_element(); + + screen->text_color = Color(r, g, b); + 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->endtime = this->clock->now().timestamp + lifetime * 60; + screen->status(); + } + + void EHMTX::date_screen(int lifetime, int screen_time, bool default_font, int r, int g, int b) + { + EHMTX_queue *screen = this->find_free_queue_element(); + + screen->text_color = Color(r, g, b); + ESP_LOGD(TAG, "date_screen lifetime: %d screen_time: %d red: %d green: %d blue: %d", lifetime, screen_time, r, g, b); + screen->mode = MODE_DATE; + screen->screen_time = screen_time; + screen->default_font = default_font; + screen->endtime = this->clock->now().timestamp + lifetime * 60; + screen->status(); + } + + EHMTX_queue *EHMTX::find_icon_queue_element(uint8_t icon) + { + for (size_t i = 0; i < MAXQUEUE; i++) { - this->show_date = b; - if (b) - { - ESP_LOGI(TAG, "show date"); - } - else + if ((this->queue[i]->mode == MODE_ICONSCREEN) && (this->queue[i]->icon == icon)) { - ESP_LOGI(TAG, "don't show date"); + ESP_LOGD(TAG, "free_screen: found by icon"); + return this->queue[i]; } } + return this->find_free_queue_element(); + } - void EHMTX::set_show_seconds(bool b) + EHMTX_queue *EHMTX::find_free_queue_element() + { + time_t ts = this->clock->now().timestamp; + for (size_t i = 0; i < MAXQUEUE; i++) { - this->show_seconds = b; - if (b) + if (this->queue[i]->endtime < ts) { - ESP_LOGI(TAG, "show seconds"); - } - else - { - ESP_LOGI(TAG, "don't show seconds"); + ESP_LOGD(TAG, "free_screen: found by endtime %d", i); + return this->queue[i]; } } + return this->queue[0]; + } - void EHMTX::set_show_day_of_week(bool b) + void EHMTX::set_show_date(bool b) + { + this->show_date = b; + if (b) { - this->show_day_of_week = b; - if (b) - { - ESP_LOGI(TAG, "show day of week"); - } - else - { - ESP_LOGI(TAG, "don't show day of week"); - } + ESP_LOGI(TAG, "show date"); } - - void EHMTX::set_week_start(bool b) + else { - this->week_starts_monday = b; - if (b) - { - ESP_LOGI(TAG, "weekstart: monday"); - } - else - { - ESP_LOGI(TAG, "weekstart: sunday"); - } + ESP_LOGI(TAG, "don't show date"); } + } - void EHMTX::set_brightness(int value) + void EHMTX::set_show_seconds(bool b) + { + this->show_seconds = b; + if (b) { - if (value < 256) - { - this->brightness_ = value; - float br = (float)value / (float)255; - ESP_LOGI(TAG, "set_brightness %d => %.2f %%", value, 100 * br); - this->display->get_light()->set_correction(br, br, br); - } + ESP_LOGI(TAG, "show seconds"); } - - uint8_t EHMTX::get_brightness() + else { - return this->brightness_; + ESP_LOGI(TAG, "don't show seconds"); } + } - void EHMTX::set_clock_time(uint16_t t) + void EHMTX::set_show_day_of_week(bool b) + { + this->show_day_of_week = b; + if (b) { - this->clock_time = t; + ESP_LOGI(TAG, "show day of week"); } - - void EHMTX::set_hold_time(uint16_t t) + else { - this->hold_time = t; + ESP_LOGI(TAG, "don't show day of week"); } + } - void EHMTX::set_scroll_count(uint8_t c) + void EHMTX::set_week_start(bool b) + { + this->week_starts_monday = b; + if (b) { - this->scroll_count = c; + ESP_LOGI(TAG, "weekstart: monday"); } - - void EHMTX::set_display(addressable_light::AddressableLightDisplay * disp) + else { - this->display = disp; - this->show_display = true; + ESP_LOGI(TAG, "weekstart: sunday"); } + } - void EHMTX::set_clock(time::RealTimeClock * clock) + void EHMTX::set_brightness(int value) + { + if (value < 256) { - this->clock = clock; + this->brightness_ = value; + float br = (float)value / (float)255; + ESP_LOGI(TAG, "set_brightness %d => %.2f %%", value, 100 * br); + this->display->get_light()->set_correction(br, br, br); } + } + + uint8_t EHMTX::get_brightness() + { + return this->brightness_; + } + + void EHMTX::set_clock_time(uint16_t t) + { + this->clock_time = t; + } + + void EHMTX::set_hold_time(uint16_t t) + { + this->hold_time = t; + } + + void EHMTX::set_scroll_count(uint8_t c) + { + this->scroll_count = c; + } + + void EHMTX::set_display(addressable_light::AddressableLightDisplay *disp) + { + this->display = disp; + this->show_display = true; + } + + void EHMTX::set_clock(time::RealTimeClock *clock) + { + this->clock = clock; + } - void EHMTX::draw_day_of_week() + void EHMTX::draw_day_of_week() + { + if (this->show_day_of_week) { - if (this->show_day_of_week) + auto dow = this->clock->now().day_of_week - 1; // SUN = 0 + for (uint8_t i = 0; i <= 6; i++) { - auto dow = this->clock->now().day_of_week - 1; // SUN = 0 - for (uint8_t i = 0; i <= 6; i++) + if (((!this->week_starts_monday) && (dow == i)) || + ((this->week_starts_monday) && ((dow == (i + 1)) || ((dow == 0 && i == 6))))) { - if (((!this->week_starts_monday) && (dow == i)) || - ((this->week_starts_monday) && ((dow == (i + 1)) || ((dow == 0 && i == 6))))) - { - this->display->line(2 + i * 4, 7, i * 4 + 4, 7, this->today_color); - } - else - { - this->display->line(2 + i * 4, 7, i * 4 + 4, 7, this->weekday_color); - } + this->display->line(2 + i * 4, 7, i * 4 + 4, 7, this->today_color); + } + else + { + this->display->line(2 + i * 4, 7, i * 4 + 4, 7, this->weekday_color); } } - }; + } + }; + + void EHMTX::set_default_font_offset(int8_t y, int8_t x) + { + this->default_xoffset = x; + this->default_yoffset = y; + ESP_LOGD(TAG, "set_default_font_offset x: %d y: %d", x, y); + } - void EHMTX::set_default_font_offset(int8_t y, int8_t x) + void EHMTX::set_special_font_offset(int8_t y, int8_t x) + { + this->special_xoffset = x; + this->special_yoffset = y; + ESP_LOGD(TAG, "set_special_font_offset x: %d y: %d", x, y); + } + + void EHMTX::dump_config() + { + ESP_LOGCONFIG(TAG, "EspHoMatriX %s", EHMTX_VERSION); + 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, "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); + ESP_LOGCONFIG(TAG, "Displaytime (s) clock: %d screen: %d", this->clock_time, this->screen_time); + if (this->show_day_of_week) { - this->default_xoffset = x; - this->default_yoffset = y; - ESP_LOGD(TAG, "set_default_font_offset x: %d y: %d", x, y); + ESP_LOGCONFIG(TAG, "show day of week"); } - - void EHMTX::set_special_font_offset(int8_t y, int8_t x) + if (this->show_date) { - this->special_xoffset = x; - this->special_yoffset = y; - ESP_LOGD(TAG, "set_special_font_offset x: %d y: %d", x, y); + ESP_LOGCONFIG(TAG, "show date"); } - - void EHMTX::dump_config() + if (this->week_starts_monday) { - ESP_LOGCONFIG(TAG, "EspHoMatriX %s", EHMTX_VERSION); - 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, "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); - ESP_LOGCONFIG(TAG, "Displaytime (s) clock: %d screen: %d", this->clock_time, this->screen_time); - if (this->show_day_of_week) - { - ESP_LOGCONFIG(TAG, "show day of week"); - } - if (this->show_date) - { - ESP_LOGCONFIG(TAG, "show date"); - } - if (this->week_starts_monday) - { - ESP_LOGCONFIG(TAG, "weekstart: monday"); - } - else - { - ESP_LOGCONFIG(TAG, "weekstart: sunday"); - } + ESP_LOGCONFIG(TAG, "weekstart: monday"); } - - void EHMTX::add_icon(EHMTX_Icon * icon) + else { - this->icons[this->icon_count] = icon; - ESP_LOGD(TAG, "add_icon no.: %d name: %s frame_duration: %d ms", this->icon_count, icon->name.c_str(), icon->frame_duration); - this->icon_count++; + ESP_LOGCONFIG(TAG, "weekstart: sunday"); } + } - void EHMTX::draw() + void EHMTX::add_icon(EHMTX_Icon *icon) + { + this->icons[this->icon_count] = icon; + ESP_LOGD(TAG, "add_icon no.: %d name: %s frame_duration: %d ms", this->icon_count, icon->name.c_str(), icon->frame_duration); + this->icon_count++; + } + + void EHMTX::draw() + { + if ((this->is_running) && (this->show_display) && (this->screen_pointer != MAXQUEUE)) { - if ((this->is_running) && (this->show_display) && (this->screen_pointer != MAXQUEUE)) - { - this->queue[this->screen_pointer]->draw(); - this->draw_gauge(); + this->queue[this->screen_pointer]->draw(); + this->draw_gauge(); - if (this->display_indicator) - { - this->display->line(31, 5, 29, 7, this->indicator_color); - this->display->draw_pixel_at(30, 7, this->indicator_color); - this->display->draw_pixel_at(31, 6, this->indicator_color); - this->display->draw_pixel_at(31, 7, this->indicator_color); - } + if (this->display_indicator) + { + this->display->line(31, 5, 29, 7, this->indicator_color); + this->display->draw_pixel_at(30, 7, this->indicator_color); + this->display->draw_pixel_at(31, 6, this->indicator_color); + this->display->draw_pixel_at(31, 7, this->indicator_color); } } + } - void EHMTXNextScreenTrigger::process(std::string iconname, std::string text) - { - this->trigger(iconname, text); - } + void EHMTXNextScreenTrigger::process(std::string iconname, std::string text) + { + this->trigger(iconname, text); + } - void EHMTXExpiredScreenTrigger::process(std::string iconname, std::string text) - { - this->trigger(iconname, text); - } + void EHMTXExpiredScreenTrigger::process(std::string iconname, std::string text) + { + this->trigger(iconname, text); + } - void EHMTXNextClockTrigger::process() - { - this->trigger(); - } + void EHMTXNextClockTrigger::process() + { + this->trigger(); } +} diff --git a/components/ehmtx/EHMTX.h b/components/ehmtx/EHMTX.h index 7dc5fee..7056a76 100644 --- a/components/ehmtx/EHMTX.h +++ b/components/ehmtx/EHMTX.h @@ -23,7 +23,7 @@ const uint8_t TEXTSTARTOFFSET = (32 - 8); const uint16_t TICKINTERVAL = 1000; // each 1000ms static const char *const EHMTX_VERSION = "Version: 2023.5.0"; static const char *const TAG = "EHMTX"; -enum show_mode : uint8_t { MODE_EMPTY = 0,MODE_BLANK = 1, MODE_CLOCK = 2, MODE_DATE = 3, MODE_FULLSCREEN = 4, MODE_ICONSCREEN = 5, MODE_TEXT = 6 , MODE_TIMER = 7,MODE_RAINBOW_TEXT = 8 }; +enum show_mode : uint8_t { MODE_EMPTY = 0,MODE_BLANK = 1, MODE_CLOCK = 2, MODE_DATE = 3, MODE_FULLSCREEN = 4, MODE_ICONSCREEN = 5, MODE_TEXT = 6 , MODE_RAINBOW_ICON = 7,MODE_RAINBOW_TEXT = 8 }; namespace esphome { @@ -135,12 +135,13 @@ namespace esphome void fullscreen(std::string icon, int lifetime=D_LIFETIME, int screen_time=D_SCREEN_TIME); void icon_screen(std::string icon, std::string text, int lifetime=D_LIFETIME, int screen_time=D_SCREEN_TIME,bool default_font=true,int r=C_RED, int g=C_GREEN, int b=C_BLUE); - void timer_screen(std::string icon, int seconds, int lifetime=D_LIFETIME, int screen_time=D_SCREEN_TIME, bool default_font=true, int r=C_RED, int g=C_GREEN, int b=C_BLUE); void text_screen(std::string text, int lifetime=D_LIFETIME, int screen_time=D_SCREEN_TIME, bool default_font=true, int r=C_RED, int g=C_GREEN, int b=C_BLUE); void clock_screen(int lifetime=D_LIFETIME, int screen_time=D_SCREEN_TIME,bool default_font=true,int r=C_RED, int g=C_GREEN, int b=C_BLUE); void date_screen(int lifetime=D_LIFETIME, int screen_time=D_SCREEN_TIME,bool default_font=true, int r=C_RED, int g=C_GREEN, int b=C_BLUE); void blank_screen(int lifetime=D_LIFETIME, int screen_time=D_SCREEN_TIME); - + void rainbow_icon_screen(std::string icon_name, std::string text, int lifetime=D_LIFETIME, int screen_time=D_SCREEN_TIME, bool default_font=true); + void rainbow_text_screen(std::string text, int lifetime=D_LIFETIME, int screen_time=D_SCREEN_TIME, bool default_font=true); + void del_screen(std::string icon, int mode=MODE_ICONSCREEN); void draw_gauge(); @@ -178,7 +179,6 @@ namespace esphome void status(); void draw(); - void draw_(); bool isfree(); void reset_shiftx(); bool update_slot(uint8_t _icon); diff --git a/components/ehmtx/EHMTX_queue.cpp b/components/ehmtx/EHMTX_queue.cpp index e78d56b..63b453c 100644 --- a/components/ehmtx/EHMTX_queue.cpp +++ b/components/ehmtx/EHMTX_queue.cpp @@ -42,8 +42,11 @@ namespace esphome case MODE_TEXT: ESP_LOGD(TAG, "queue: show text text: %s for %d sec", this->text.c_str(), this->screen_time); break; - case MODE_TIMER: - ESP_LOGD(TAG, "queue: show timer text: %s for %d sec", this->text.c_str(), this->screen_time); + case MODE_RAINBOW_ICON: + ESP_LOGD(TAG, "queue: show rainbow icon: %s text: %s for %d sec",this->icon_name.c_str(), this->text.c_str(), this->screen_time); + break; + case MODE_RAINBOW_TEXT: + ESP_LOGD(TAG, "queue: show rainbow text: %s for %d sec", this->text.c_str(), this->screen_time); break; default: ESP_LOGD(TAG, "queue: UPPS"); @@ -81,7 +84,7 @@ namespace esphome this->config_->rainbow_color = Color(uint8_t (255 * red),uint8_t (255 * green),uint8_t (255 * blue)); } - if (this->mode == MODE_ICONSCREEN) + if (this->mode == MODE_ICONSCREEN || this->mode == MODE_RAINBOW_ICON) { if (millis() - this->config_->last_scroll_time >= this->config_->scroll_interval && this->pixels_ > TEXTSTARTOFFSET) { @@ -93,7 +96,7 @@ namespace esphome this->config_->last_scroll_time = millis(); } } - if (this->mode == MODE_TEXT) + if (this->mode == MODE_TEXT || this->mode == MODE_RAINBOW_TEXT) { if (millis() - this->config_->last_scroll_time >= this->config_->scroll_interval && this->pixels_ >= 32) { @@ -114,16 +117,13 @@ namespace esphome } } - void EHMTX_queue::draw_() - { - } - void EHMTX_queue::draw() { display::Font *font = this->default_font ? this->config_->default_font : this->config_->special_font; int8_t yoffset = this->default_font ? this->config_->default_xoffset : this->config_->special_xoffset; int8_t xoffset = this->default_font ? this->config_->default_yoffset : this->config_->special_yoffset; int8_t extraoffset = 0; + Color color_=Color(40,140,0); switch (this->mode) { @@ -168,7 +168,7 @@ namespace esphome case MODE_FULLSCREEN: this->config_->display->image(0, 0, this->config_->icons[this->icon]); break; - case MODE_ICONSCREEN: + case MODE_ICONSCREEN: case MODE_RAINBOW_ICON: { if (this->pixels_ > TEXTSTARTOFFSET) { @@ -178,10 +178,11 @@ namespace esphome { extraoffset += 2; } - - this->config_->display->print(this->centerx_ + TEXTSCROLLSTART - this->shiftx_ + extraoffset + xoffset, yoffset, font, this->text_color, esphome::display::TextAlign::BASELINE_LEFT, + + color_ = (this->mode == MODE_RAINBOW_TEXT)?this->config_->rainbow_color:this->text_color; + this->config_->display->print(this->centerx_ + TEXTSCROLLSTART - this->shiftx_ + extraoffset + xoffset, yoffset, font, color_, esphome::display::TextAlign::BASELINE_LEFT, this->text.c_str()); - + if (this->config_->display_alarm) { this->config_->display->draw_pixel_at(30, 0, this->config_->alarm_color); @@ -202,7 +203,7 @@ namespace esphome } } break; - case MODE_TEXT: + case MODE_TEXT: case MODE_RAINBOW_TEXT: if (this->pixels_ > 32) { @@ -212,13 +213,8 @@ namespace esphome { extraoffset += 2; } - - this->config_->display->print(this->centerx_ - this->shiftx_ + xoffset + extraoffset, yoffset, font, this->text_color, esphome::display::TextAlign::BASELINE_LEFT, - this->text.c_str()); - break; - case MODE_TIMER: - this->config_->display->image(0, 0, this->config_->icons[this->icon]); - this->config_->display->print(9+xoffset, yoffset, font, this->config_->rainbow_color, esphome::display::TextAlign::BASELINE_LEFT, + color_ = (this->mode== MODE_RAINBOW_TEXT)?this->config_->rainbow_color:this->text_color; + this->config_->display->print(this->centerx_ - this->shiftx_ + xoffset + extraoffset, yoffset, font, color_, esphome::display::TextAlign::BASELINE_LEFT, this->text.c_str()); break; default: diff --git a/copy2esphome/EHMTX_easy_delete.yaml b/copy2esphome/EHMTX_easy_delete.yaml index a329c2e..ebfe48d 100644 --- a/copy2esphome/EHMTX_easy_delete.yaml +++ b/copy2esphome/EHMTX_easy_delete.yaml @@ -34,6 +34,10 @@ blueprint: value: "4" - label: MODE_TEXT value: "6" + - label: MODE_RAINBOW_ICON + value: "7" + - label: MODE_RAINBOW_TEXT + value: "8" default: "5" icon_name: name: the icon