diff --git a/README.md b/README.md index 53f9f32..fae1834 100644 --- a/README.md +++ b/README.md @@ -1032,7 +1032,9 @@ sensor: ## Breaking changes -### **nothing yet, since it is new** +### 2023.5.0 + +- removed the rtttl buzzer from the ulanzi easy template, because it often caused reboots! ## EspHoMaTriX in the media @@ -1065,7 +1067,7 @@ THE SOFTWARE IS PROVIDED "AS IS", use at your own risk! - **[aptonline](https://github.com/aptonline)** for his work on the ulanzi hardware - **[wsbtak](https://github.com/wsbtak)** for the work on the ulanzi hardware - **[ofirsnb](https://github.com/ofirsnb)** for his contributions -- **[darkpoet78](https://github.com/darkpoet78/MatrixClockFonts)** for his work on optimized fonts +- **[darkpoet78](https://github.com/darkpoet78/MatrixClockFonts)** for his work on optimized fonts and user support - **[pplucky](https://user-images.githubusercontent.com/16407309/224850723-634c9b2d-55d9-44f2-9f93-765c0485b090.GIF)** for his 8x32 GIF animation - **[dennisse](https://github.com/dennisse)** Auto brightness for the Ulanzi - **[geekofweek](https://github.com/geekofweek)** fixed sample YAML diff --git a/TODO.md b/TODO.md index e990520..25e8427 100644 --- a/TODO.md +++ b/TODO.md @@ -2,17 +2,18 @@ ## function +- [ ] screen_time on ms sec base +- [ ] scroll left to right +- [ ] seconds point moveable - [x] alarm on all screens but full screen - [x] indicator on all screens but full screen and clock - [x] refreshing an icon screen should extend the display time -- [ ] scroll left to right - [x] size of indicator and alarm - [x] center text - [x] alarm independent of screen - [x] del_screen with * and filter by type, do delete all clocks etc. - [x] force_screen with * and filter by type, do delete all clocks etc. - [x] gauge with color and del_gaugeall clocks etc. -- [ ] seconds point moveable - [x] seconds point to clock screen only - [x] rainbow icon and text - [x] del_slot still active? @@ -22,16 +23,16 @@ ## user experience - [ ] blueprints -- [x] Color in blueprints -- [ ] all modes in one blueprint - [ ] external HTML with more blueprint helpers (icons and modes) +- [ ] ~~all modes in one blueprint~~ +- [x] Color in blueprints - [x] default values for all functions - [x] provide sample font from [url](https://www.pentacom.jp/pentacom/bitfontmaker2/) - [x] start animation ## style -- [ ] in screen rename text_color to color +- [x] ~~in screen rename text_color to color~~ - [x] default_font before alarm parameter - [x] screen_time instead of showtime - [x] lifetime instead of durations diff --git a/components/ehmtxv2/EHMTX.cpp b/components/ehmtxv2/EHMTX.cpp index e25d500..37d975e 100644 --- a/components/ehmtxv2/EHMTX.cpp +++ b/components/ehmtxv2/EHMTX.cpp @@ -20,7 +20,9 @@ namespace esphome this->alarm_color = Color(CA_RED, CA_GREEN, CA_BLUE); this->gauge_color = Color(CD_RED, CD_GREEN, CD_BLUE); this->gauge_value = 0; - this->screen_pointer = 0; + this->next_action_time = 0; + this->last_scroll_time = 0; + this->screen_pointer = MAXQUEUE; for (uint8_t i = 0; i < MAXQUEUE; i++) { @@ -228,9 +230,9 @@ namespace esphome { if (!this->is_running) { - if (this->clock->now().timestamp > 15) + if (this->clock->now().is_valid()) { - ESP_LOGD(TAG, "time sync => starting"); + ESP_LOGD(TAG, "time sync => start running"); this->is_running = true; } } @@ -238,12 +240,6 @@ namespace esphome void EHMTX::force_screen(std::string icon_name, int mode) { - // if (this->string_has_ending(icon_name, "*")) - // { - // // remove the * - // icon_name = icon_name.substr(0, icon_name.length() - 1); - // } - for (uint8_t i = 0; i < MAXQUEUE; i++) { if (this->queue[i]->mode == mode) @@ -294,9 +290,9 @@ namespace esphome 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 ((this->queue[i]->mode == MODE_CLOCK) || (this->queue[i]->mode == MODE_RAINBOW_CLOCK)) { - if (ts > (this->queue[i]->last_time + this->clock_interval)) + if (ts > (this->queue[i]->last_time + this->clock_interval)) { hit = i; } @@ -359,9 +355,10 @@ namespace esphome } } } + void EHMTX::tick() { - this->hue_++; + this->hue_++; if (this->hue_ == 360) { this->hue_ = 0; @@ -369,31 +366,36 @@ namespace esphome float red, green, blue; esphome::hsv_to_rgb(this->hue_, 0.8, 0.8, red, green, blue); this->rainbow_color = Color(uint8_t(255 * red), uint8_t(255 * green), uint8_t(255 * blue)); - - if (millis() - this->last_scroll_time >= this->scroll_interval){ - this->scroll_step++; - this->last_scroll_time = millis(); - - if (this->scroll_step > this->queue[this->screen_pointer]->pixels_ + 32) { - this->scroll_step = 0; - } - } - + time_t ts = this->clock->now().timestamp; if (this->is_running) { + if (millis() - this->last_scroll_time >= this->scroll_interval) + { + this->scroll_step++; + this->last_scroll_time = millis(); + if (this->scroll_step > this->queue[this->screen_pointer]->scroll_reset) + { + ESP_LOGD(TAG, "end scroll at: %d",this->scroll_step); + this->scroll_step = 0; + } + } + if (ts > this->next_action_time) { this->remove_expired_queue_element(); this->screen_pointer = this->find_last_clock(); + this->scroll_step = 0; + if (this->screen_pointer == MAXQUEUE) { this->screen_pointer = find_oldest_queue_element(); } + if (this->screen_pointer != MAXQUEUE) { - this->scroll_step=0; + 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) { @@ -561,7 +563,7 @@ namespace esphome screen->mode = MODE_ICON_SCREEN; screen->icon_name = iconname; screen->icon = icon; - screen->calc_scroll_time(text,screen_time); + screen->calc_scroll_time(text, screen_time); for (auto *t : on_add_screen_triggers_) { t->process(screen->icon_name, (uint8_t)screen->mode); @@ -584,15 +586,15 @@ namespace esphome } } EHMTX_queue *screen = this->find_icon_queue_element(icon); - + screen->text = text; - + screen->endtime = this->clock->now().timestamp + lifetime * 60; screen->default_font = default_font; screen->mode = MODE_RAINBOW_ICON; screen->icon_name = iconname; screen->icon = icon; - screen->calc_scroll_time(text,screen_time); + screen->calc_scroll_time(text, screen_time); for (auto *t : on_add_screen_triggers_) { t->process(screen->icon_name, (uint8_t)screen->mode); @@ -608,7 +610,14 @@ namespace esphome 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 > this->clock_interval)?screen_time:this->clock_interval-1; + if (this->clock_interval == 0 || (this->clock_interval > screen_time)) + { + screen->screen_time_ = screen_time; + } + else + { + screen->screen_time_ = this->clock_interval - 2; + } screen->endtime = this->clock->now().timestamp + lifetime * 60; screen->status(); } @@ -634,7 +643,7 @@ namespace esphome screen->default_font = default_font; screen->text_color = Color(r, g, b); screen->mode = MODE_TEXT_SCREEN; - screen->calc_scroll_time(text,screen_time); + screen->calc_scroll_time(text, screen_time); screen->status(); } @@ -645,7 +654,7 @@ namespace esphome screen->endtime = this->clock->now().timestamp + lifetime * 60; screen->default_font = default_font; screen->mode = MODE_RAINBOW_TEXT; - screen->calc_scroll_time(text,screen_time); + screen->calc_scroll_time(text, screen_time); screen->status(); } @@ -685,7 +694,14 @@ namespace esphome 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_ = (this->clock_interval > screen_time )?screen_time:this->clock_interval-1; + if (this->clock_interval == 0 || (this->clock_interval > screen_time)) + { + screen->screen_time_ = screen_time; + } + else + { + screen->screen_time_ = this->clock_interval - 2; + } screen->endtime = this->clock->now().timestamp + lifetime * 60; screen->status(); } @@ -881,6 +897,10 @@ namespace esphome { ESP_LOGCONFIG(TAG, "show date"); } + if (this->rtl) + { + ESP_LOGCONFIG(TAG, "RTL activated"); + } if (this->week_starts_monday) { ESP_LOGCONFIG(TAG, "weekstart: monday"); diff --git a/components/ehmtxv2/EHMTX.h b/components/ehmtxv2/EHMTX.h index b80be31..037aa98 100644 --- a/components/ehmtxv2/EHMTX.h +++ b/components/ehmtxv2/EHMTX.h @@ -20,7 +20,7 @@ const uint8_t MAXICONS = 90; const uint8_t TEXTSCROLLSTART = 8; const uint8_t TEXTSTARTOFFSET = (32 - 8); -const uint16_t POLLINGINTERVAL = 800; +const uint16_t POLLINGINTERVAL = 1000; static const char *const EHMTX_VERSION = "Version: 2023.5.0 beta"; static const char *const TAG = "EHMTXv2"; enum show_mode : uint8_t { MODE_EMPTY = 0,MODE_BLANK = 1, MODE_CLOCK = 2, MODE_DATE = 3, MODE_FULL_SCREEN = 4, MODE_ICON_SCREEN = 5, MODE_TEXT_SCREEN = 6 , MODE_RAINBOW_ICON = 7,MODE_RAINBOW_TEXT = 8, MODE_RAINBOW_CLOCK = 9,MODE_RAINBOW_DATE=10 }; @@ -37,7 +37,7 @@ namespace esphome class EHMTX : public PollingComponent, public api::CustomAPIDevice { protected: - float get_setup_priority() const override { return esphome::setup_priority::PROCESSOR; } + float get_setup_priority() const override { return esphome::setup_priority::BEFORE_CONNECTION; } uint8_t brightness_; uint32_t boot_anim=0; uint8_t screen_pointer; @@ -57,7 +57,7 @@ namespace esphome EHMTX(); Color text_color, alarm_color, gauge_color,indicator_color,clock_color; Color today_color,weekday_color,rainbow_color; - int hue_; + uint16_t hue_=0; void dump_config(); std::string time_fmt; std::string date_fmt; @@ -95,6 +95,7 @@ namespace esphome 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; unsigned long last_rainbow_time; @@ -109,7 +110,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_clock_interval(uint16_t t=90); void set_hold_time(uint16_t t=30); void set_clock_time(uint16_t t=10); void set_show_day_of_week(bool b); @@ -141,7 +142,6 @@ namespace esphome void hide_gauge(); void hide_indicator(); void hide_alarm(); - void full_screen(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 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); @@ -182,6 +182,7 @@ namespace esphome time_t endtime; time_t last_time; uint8_t icon; + uint16_t scroll_reset; Color text_color; show_mode mode; diff --git a/components/ehmtxv2/EHMTX_queue.cpp b/components/ehmtxv2/EHMTX_queue.cpp index 192a6df..eeeb90c 100644 --- a/components/ehmtxv2/EHMTX_queue.cpp +++ b/components/ehmtxv2/EHMTX_queue.cpp @@ -64,6 +64,7 @@ namespace esphome { uint8_t width = 32; uint8_t startx = 0; + int result = 0; switch (this->mode) { case MODE_RAINBOW_ICON: @@ -75,7 +76,7 @@ namespace esphome // no correction break; } - + if (this->config_->display_gauge) { startx += 2; @@ -86,24 +87,26 @@ namespace esphome { if (this->pixels_ < width) { - return 32 - ceil((width - this->pixels_) / 2); + result = 32 - ceil((width - this->pixels_) / 2); } else { - return startx + this->config_->scroll_step; + + result = startx + this->config_->scroll_step; } } else { if (this->pixels_ < width) { - return startx + ceil((width - this->pixels_) / 2); + result = startx + ceil((width - this->pixels_) / 2); } else { - return startx - this->config_->scroll_step + width; + result = startx - this->config_->scroll_step + width; } } + return result; } void EHMTX_queue::update_screen() @@ -145,7 +148,7 @@ namespace esphome break; case MODE_RAINBOW_CLOCK: case MODE_CLOCK: - if (this->config_->clock->now().timestamp > 6000) // valid time + if (this->config_->clock->now().is_valid()) // valid time { color_ = (this->mode == MODE_RAINBOW_CLOCK) ? this->config_->rainbow_color : this->config_->clock_color; time_t ts = this->config_->clock->now().timestamp; @@ -167,7 +170,7 @@ namespace esphome break; case MODE_RAINBOW_DATE: case MODE_DATE: - if (this->config_->clock->now().timestamp > 6000) // valid time + if (this->config_->clock->now().is_valid()) { color_ = (this->mode == MODE_RAINBOW_DATE) ? this->config_->rainbow_color : this->config_->clock_color; time_t ts = this->config_->clock->now().timestamp; @@ -203,13 +206,15 @@ namespace esphome } color_ = (this->mode == MODE_RAINBOW_ICON) ? this->config_->rainbow_color : this->text_color; - if (this->config_->rtl) { + if (this->config_->rtl) + { this->config_->display->print(this->xpos() + xoffset, yoffset, font, color_, esphome::display::TextAlign::BASELINE_RIGHT, - this->text.c_str()); + this->text.c_str()); } - else { + else + { this->config_->display->print(this->xpos() + xoffset, yoffset, font, color_, esphome::display::TextAlign::BASELINE_LEFT, - this->text.c_str()); + this->text.c_str()); } if (this->config_->display_gauge) { @@ -235,8 +240,16 @@ namespace esphome extraoffset += 2; } color_ = (this->mode == MODE_RAINBOW_TEXT) ? this->config_->rainbow_color : this->text_color; - this->config_->display->print(this->xpos() + xoffset, yoffset, font, color_, esphome::display::TextAlign::BASELINE_LEFT, - this->text.c_str()); + if (this->config_->rtl) + { + this->config_->display->print(this->xpos() + xoffset, yoffset, font, color_, esphome::display::TextAlign::BASELINE_RIGHT, + this->text.c_str()); + } + else + { + this->config_->display->print(this->xpos() + xoffset, yoffset, font, color_, esphome::display::TextAlign::BASELINE_LEFT, + this->text.c_str()); + } break; default: break; @@ -257,6 +270,11 @@ namespace esphome { int x, y, w, h; float display_duration; + + uint8_t width = 32; + uint8_t startx = 0; + uint16_t max_steps = 0; + if (this->default_font) { this->config_->display->get_text_bounds(0, 0, text.c_str(), this->config_->default_font, display::TextAlign::LEFT, &x, &y, &w, &h); @@ -272,7 +290,7 @@ namespace esphome switch (this->mode) { case MODE_RAINBOW_TEXT: - case MODE_TEXT_SCREEN: + case MODE_TEXT_SCREEN: if (this->pixels_ < 32) { this->screen_time_ = screen_time; @@ -280,12 +298,14 @@ namespace esphome } else { - display_duration = ceil((28 + (this->config_->scroll_count * (32 + this->pixels_)) * this->config_->scroll_interval) / 1000); + max_steps = (this->config_->scroll_count + 1) * (width - startx) + this->config_->scroll_count * this->pixels_; + display_duration = ceil((max_steps * this->config_->scroll_interval) / 1000); this->screen_time_ = (display_duration > screen_time) ? display_duration : screen_time; } break; case MODE_RAINBOW_ICON: case MODE_ICON_SCREEN: + startx = 8; if (this->pixels_ < 23) { this->screen_time_ = screen_time; @@ -293,7 +313,8 @@ namespace esphome } else { - display_duration = ceil((this->config_->scroll_count * (TEXTSTARTOFFSET + this->pixels_) * this->config_->scroll_interval) / 1000); + max_steps = (this->config_->scroll_count + 1) * (width - startx) + this->config_->scroll_count * this->pixels_; + display_duration = ceil((max_steps * this->config_->scroll_interval) / 1000); this->screen_time_ = (display_duration > screen_time) ? display_duration : screen_time; } break; @@ -301,6 +322,9 @@ namespace esphome break; } - ESP_LOGD(TAG, "calc_scroll_time: mode: %d text: \"%s\" pixels %d calculated: %d defined: %d", this->mode, text.c_str(), this->pixels_, this->screen_time_, screen_time); + this->scroll_reset = (width - startx) + this->pixels_; + ; + + ESP_LOGD(TAG, "calc_scroll_time: mode: %d text: \"%s\" pixels %d calculated: %d defined: %d max_steps: %d", this->mode, text.c_str(), this->pixels_, this->screen_time_, screen_time, this->scroll_reset); } } diff --git a/copy2esphome/ulanzi-easy.yaml b/copy2esphome/ulanzi-easy.yaml index 1a2a49f..e42d99f 100644 --- a/copy2esphome/ulanzi-easy.yaml +++ b/copy2esphome/ulanzi-easy.yaml @@ -1,7 +1,5 @@ substitutions: devicename: ulanzi - ledpin: GPIO32 - buzzerpin: GPIO15 friendly_name: LED Matrix board: esp32dev # Pin definition from https://github.com/aptonline/PixelIt_Ulanzi @@ -11,7 +9,6 @@ substitutions: left_button_pin: GPIO26 mid_button_pin: GPIO27 right_button_pin: GPIO14 - buzzer_pin: GPIO15 scl_pin: GPIO22 sda_pin: GPIO21 @@ -99,13 +96,6 @@ logger: level: WARN api: - services: - - service: tune - variables: - tune: string - then: - - rtttl.play: - rtttl: !lambda 'return tune;' sensor: - platform: sht3xd @@ -168,14 +158,6 @@ wifi: web_server: -output: - - platform: ledc - pin: $buzzerpin - id: rtttl_out - -rtttl: - output: rtttl_out - i2c: sda: $sda_pin scl: $scl_pin diff --git a/tests/ulanzi-easy.yaml b/tests/ulanzi-easy.yaml index 1a2a49f..e42d99f 100644 --- a/tests/ulanzi-easy.yaml +++ b/tests/ulanzi-easy.yaml @@ -1,7 +1,5 @@ substitutions: devicename: ulanzi - ledpin: GPIO32 - buzzerpin: GPIO15 friendly_name: LED Matrix board: esp32dev # Pin definition from https://github.com/aptonline/PixelIt_Ulanzi @@ -11,7 +9,6 @@ substitutions: left_button_pin: GPIO26 mid_button_pin: GPIO27 right_button_pin: GPIO14 - buzzer_pin: GPIO15 scl_pin: GPIO22 sda_pin: GPIO21 @@ -99,13 +96,6 @@ logger: level: WARN api: - services: - - service: tune - variables: - tune: string - then: - - rtttl.play: - rtttl: !lambda 'return tune;' sensor: - platform: sht3xd @@ -168,14 +158,6 @@ wifi: web_server: -output: - - platform: ledc - pin: $buzzerpin - id: rtttl_out - -rtttl: - output: rtttl_out - i2c: sda: $sda_pin scl: $scl_pin