diff --git a/.gitignore b/.gitignore index 6fbe4ee..669230d 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ components/ehmtx/EHMTX_icons._cpp ehmtx8266-select.yaml svganimtest.html servicetest +.DS_Store diff --git a/README.md b/README.md index d9b237f..0468a6b 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,8 @@ font: ``` ## icons/animations -Download and install all needed icons (.jpg/.png)/animations (.gif) under the "ehmtx"-key. All icons are automagically scaled to 8x8 on compile-time. You can also specify an url to directly download an image file. The urls will only be downloaded once at compile time, so there is no additional traffic on the hosting website. +Download and install all needed icons (.jpg/.png)/animations (.gif) under the "ehmtx"-key. All icons are automagically scaled to 8x8 on compile-time. But this doesn't work well for gif's! +You can also specify an url to directly download an image file. The urls will only be downloaded once at compile time, so there is no additional traffic on the hosting website. ``` emhtx: @@ -231,6 +232,8 @@ _Configuration variables:_ **show_clock (Optional, seconds):** duration to display the clock after this time the date is display until next "show_screen". If `show_date` is false `show_clock` is false and the clock will be display as long as a normal screen! +**clock_interval (Optional, seconds):** show the clock at least each x seconds, (default=60) + **show_screen (Optional, seconds):** duration to display a screen or a clock/date sequence, a long text will be scrolled at least two times ![timing](./images/timing.png) @@ -555,6 +558,28 @@ Service **indicator_off** removes the indicator +Service **display_on** / **display_off** + +turns the display on or off + +There's an easier way in using a switch component: + +``` +switch: + - platform: template + name: "$devicename Display" + icon: "mdi:power" + restore_mode: ALWAYS_ON + lambda: |- + return id(rgb8x32)->show_display; + turn_on_action: + lambda: |- + id(rgb8x32)->set_display_on(); + turn_off_action: + lambda: |- + id(rgb8x32)->set_display_off(); +``` + Service **skip** skips to the next screen @@ -624,6 +649,24 @@ number: id(rgb8x32)->set_brightness(x); ``` +#### display switch + +``` +switch: + - platform: template + name: "$devicename Display" + icon: "mdi:power" + restore_mode: ALWAYS_ON + lambda: |- + return id(rgb8x32)->show_display; + turn_on_action: + lambda: |- + id(rgb8x32)->set_display_on(); + turn_off_action: + lambda: |- + id(rgb8x32)->set_display_off(); +``` + #### force screen With the select component you can select, from a dropdown, which screen to show next. As with the force service if the chosen screen/icon isn't active nothing will happen. The state of the select componenten doesn't reflect the actual display because it is published only all 30s. You should also consider to not record this state in your history. @@ -696,7 +739,7 @@ The integration works with the homeassistant api so, after boot of the device, i THE SOFTWARE IS PROVIDED "AS IS", use at your own risk! # Thanks - +- **[andrew-codechimp](https://github.com/andrew-codechimp)** for his contribution (display on/off) - **[jd1](https://github.com/jd1)** for his contributions - **[aptonline](https://github.com/aptonline)** for his work on the ulanzi hardware - **[wsbtak](https://github.com/wsbtak)** for the work on the ulanzi hardware diff --git a/UlanziTC001.yaml b/UlanziTC001.yaml index 8fdcce7..47304e2 100644 --- a/UlanziTC001.yaml +++ b/UlanziTC001.yaml @@ -143,7 +143,15 @@ api: then: - ehmtx.indicator.off: id: rgb8x32 - + - service: display_on + then: + - ehmtx.display.on: + id: rgb8x32 + - service: display_off + then: + - ehmtx.display.off: + id: rgb8x32 + number: - platform: template name: "$devicename brightness" @@ -156,6 +164,20 @@ number: lambda: |- id(rgb8x32)->set_brightness(x); +switch: + - platform: template + name: "$devicename Display" + icon: "mdi:power" + restore_mode: ALWAYS_ON + lambda: |- + return id(rgb8x32)->show_display; + turn_on_action: + lambda: |- + id(rgb8x32)->set_display_on(); + turn_off_action: + lambda: |- + id(rgb8x32)->set_display_off(); + sensor: - platform: sht3xd temperature: diff --git a/components/ehmtx/EHMTX.cpp b/components/ehmtx/EHMTX.cpp old mode 100644 new mode 100755 index eabea29..532d4d2 --- a/components/ehmtx/EHMTX.cpp +++ b/components/ehmtx/EHMTX.cpp @@ -111,6 +111,18 @@ namespace esphome ESP_LOGD(TAG, "indicator on"); } + void EHMTX::set_display_off() + { + this->show_display = false; + ESP_LOGD(TAG, "display off"); + } + + void EHMTX::set_display_on() + { + this->show_display = true; + ESP_LOGD(TAG, "display on"); + } + void EHMTX::set_gauge_off() { this->show_gauge = false; @@ -194,7 +206,7 @@ namespace esphome { this->show_screen = false; - if (!(ts - this->last_clock_time > 60)) // force clock if last time more the 60s old + if (!(ts - this->last_clock_time > this->clock_interval)) // force clock if last time more the 60s old { bool has_next_screen = this->store->move_next(); if (has_next_screen) @@ -251,6 +263,14 @@ namespace esphome { ESP_LOGI(TAG, "status indicator off"); } + if (this->show_display) + { + ESP_LOGI(TAG, "status display on"); + } + else + { + ESP_LOGI(TAG, "status display off"); + } this->store->log_status(); @@ -373,6 +393,11 @@ namespace esphome this->clock_time = t; } +void EHMTX::set_clock_interval(uint16_t t) + { + this->clock_interval = t; + } + void EHMTX::set_display(addressable_light::AddressableLightDisplay *disp) { this->display = disp; @@ -467,28 +492,30 @@ namespace esphome void EHMTX::draw() { - if (this->show_icons) - { - this->icon_screen->draw(); - } - else - { - if (this->show_screen) + if (this->show_display) { + if (this->show_icons) { - this->store->current()->draw(); + this->icon_screen->draw(); } else { - this->draw_clock(); + if (this->show_screen) + { + this->store->current()->draw(); + } + else + { + this->draw_clock(); + } } - } - if (this->show_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->show_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); + } } } diff --git a/components/ehmtx/EHMTX.h b/components/ehmtx/EHMTX.h old mode 100644 new mode 100755 index 3e979f8..6b387e3 --- a/components/ehmtx/EHMTX.h +++ b/components/ehmtx/EHMTX.h @@ -8,7 +8,7 @@ const uint8_t TEXTSCROLLSTART = 8; const uint8_t TEXTSTARTOFFSET = (32 - 8); const uint16_t TICKINTERVAL = 1000; // each 1000ms -static const char *const EHMTX_VERSION = "Version: 2023.2.0"; +static const char *const EHMTX_VERSION = "Version: 2023.3.0"; static const char *const TAG = "EHMTX"; namespace esphome @@ -50,6 +50,7 @@ namespace esphome EHMTX_Icon *icons[MAXICONS]; EHMTX_screen *icon_screen; void add_icon(EHMTX_Icon *icon); + bool show_display; #ifdef USE_EHMTX_SELECT std::vector select_options; esphome::EhmtxSelect *select; @@ -64,6 +65,7 @@ namespace esphome uint16_t scroll_intervall; // ms to between scrollsteps uint16_t anim_intervall; // ms to next_frame() uint16_t clock_time; // seconds display of screen_time - clock_time = date_time + uint16_t clock_interval; // seconds display of screen_time - clock_time = date_time uint16_t screen_time; // seconds display of screen uint8_t icon_count; // max iconnumber -1 unsigned long last_scroll_time; @@ -80,6 +82,7 @@ namespace esphome void set_display(addressable_light::AddressableLightDisplay *disp); void set_screen_time(uint16_t t); void set_clock_time(uint16_t t); + void set_clock_interval(uint16_t t); void set_show_day_of_week(bool b); void set_show_date(bool b); void set_font_offset(int8_t x, int8_t y); @@ -112,6 +115,8 @@ namespace esphome void add_on_next_screen_trigger(EHMTXNextScreenTrigger *t) { this->on_next_screen_triggers_.push_back(t); } void setup(); void update(); + void set_display_on(); + void set_display_off(); }; class EHMTX_store @@ -155,6 +160,7 @@ namespace esphome void draw(); void draw_(); bool isfree(); + void reset_shiftx(); bool update_slot(uint8_t _icon); void update_screen(); bool del_slot(uint8_t _icon); @@ -369,6 +375,36 @@ namespace esphome this->parent_->set_indicator_off(); } + protected: + EHMTX *parent_; + }; + + template + class SetDisplayOn : public Action + { + public: + SetDisplayOn(EHMTX *parent) : parent_(parent) {} + + void play(Ts... x) override + { + this->parent_->set_display_on(); + } + + protected: + EHMTX *parent_; + }; + + template + class SetDisplayOff : public Action + { + public: + SetDisplayOff(EHMTX *parent) : parent_(parent) {} + + void play(Ts... x) override + { + this->parent_->set_display_off(); + } + protected: EHMTX *parent_; }; @@ -419,4 +455,4 @@ namespace esphome }; } -#endif \ No newline at end of file +#endif diff --git a/components/ehmtx/EHMTX_screen.cpp b/components/ehmtx/EHMTX_screen.cpp index 0c70e9c..e761165 100644 --- a/components/ehmtx/EHMTX_screen.cpp +++ b/components/ehmtx/EHMTX_screen.cpp @@ -23,6 +23,12 @@ namespace esphome return false; } + void EHMTX_screen::reset_shiftx() + { + this->shiftx_ = 0; + } + + void EHMTX_screen::update_screen() { if (millis() - this->config_->last_scroll_time >= this->config_->scroll_intervall && this->pixels_ > TEXTSTARTOFFSET) diff --git a/components/ehmtx/EHMTX_store.cpp b/components/ehmtx/EHMTX_store.cpp index ec5d472..e35d7de 100644 --- a/components/ehmtx/EHMTX_store.cpp +++ b/components/ehmtx/EHMTX_store.cpp @@ -74,6 +74,7 @@ namespace esphome EHMTX_screen *screen = this->slots[slot]; if (screen->active()) { + screen->reset_shiftx(); this->active_slot = slot; return true; } @@ -86,6 +87,7 @@ namespace esphome EHMTX_screen *screen = this->slots[slot]; if (screen->active()) { + screen->reset_shiftx(); this->active_slot = slot; return true; } @@ -97,6 +99,7 @@ namespace esphome EHMTX_screen *screen = this->slots[slot]; if (screen->active()) { + screen->reset_shiftx(); this->active_slot = slot; return true; } diff --git a/components/ehmtx/__init__.py b/components/ehmtx/__init__.py old mode 100644 new mode 100755 index cb36801..e2fe388 --- a/components/ehmtx/__init__.py +++ b/components/ehmtx/__init__.py @@ -43,6 +43,7 @@ def rgb565_svg(x,y,r,g,b): ) CONF_SHOWCLOCK = "show_clock" +CONF_CLOCK_INTERVAL = "clock_interval" CONF_SHOWSCREEN = "show_screen" CONF_EHMTX = "ehmtx" CONF_URL = "url" @@ -76,6 +77,9 @@ def rgb565_svg(x,y,r,g,b): cv.Optional( CONF_SHOWCLOCK, default="5" ): cv.templatable(cv.positive_int), + cv.Optional( + CONF_CLOCK_INTERVAL, default="60" + ): cv.templatable(cv.positive_int), cv.Optional( CONF_SELECT, ): cv.use_id(EHMTXSelect), @@ -405,6 +409,39 @@ async def ehmtx_set_indicator_off_action_to_code(config, action_id, template_arg return var +SetDisplayOnAction = ehmtx_ns.class_("SetDisplayOn", automation.Action) + +DISPLAY_ON_ACTION_SCHEMA = cv.Schema( + { + cv.GenerateID(): cv.use_id(EHMTX_), + } +) + +@automation.register_action( + "ehmtx.display.on", SetDisplayOnAction, DISPLAY_ON_ACTION_SCHEMA +) +async def ehmtx_set_display_on_action_to_code(config, action_id, template_arg, args): + paren = await cg.get_variable(config[CONF_ID]) + var = cg.new_Pvariable(action_id, template_arg, paren) + + return var + +SetDisplayOffAction = ehmtx_ns.class_("SetDisplayOff", automation.Action) + +DISPLAY_OFF_ACTION_SCHEMA = cv.Schema( + { + cv.GenerateID(): cv.use_id(EHMTX_), + } +) +@automation.register_action( + "ehmtx.display.off", SetDisplayOffAction, DISPLAY_OFF_ACTION_SCHEMA +) +async def ehmtx_set_display_off_action_to_code(config, action_id, template_arg, args): + paren = await cg.get_variable(config[CONF_ID]) + var = cg.new_Pvariable(action_id, template_arg, paren) + + return var + CODEOWNERS = ["@lubeda"] async def to_code(config): @@ -516,6 +553,7 @@ async def to_code(config): print("Error writing HTML file") cg.add(var.set_clock_time(config[CONF_SHOWCLOCK])) + cg.add(var.set_clock_interval(config[CONF_CLOCK_INTERVAL])) cg.add(var.set_default_brightness(config[CONF_BRIGHTNESS])) cg.add(var.set_screen_time(config[CONF_SHOWSCREEN])) cg.add(var.set_duration(config[CONF_DURATION])) diff --git a/ehmtx32.yaml b/ehmtx32.yaml index b5a1603..d811e03 100644 --- a/ehmtx32.yaml +++ b/ehmtx32.yaml @@ -90,6 +90,14 @@ api: then: lambda: |- id(rgb8x32)->set_indicator_off(); + - service: display_on + then: + - ehmtx.display.on: + id: rgb8x32 + - service: display_off + then: + - ehmtx.display.off: + id: rgb8x32 ota: password: !secret ota_password @@ -131,7 +139,21 @@ number: set_action: lambda: |- id(rgb8x32)->set_brightness(x); - + +switch: + - platform: template + name: "$devicename Display" + icon: "mdi:power" + restore_mode: ALWAYS_ON + lambda: |- + return id(rgb8x32)->show_display; + turn_on_action: + lambda: |- + id(rgb8x32)->set_display_on(); + turn_off_action: + lambda: |- + id(rgb8x32)->set_display_off(); + time: - platform: homeassistant id: ehmtx_time diff --git a/ehmtx8266-color.yaml b/ehmtx8266-color.yaml index 7616551..c5c869a 100644 --- a/ehmtx8266-color.yaml +++ b/ehmtx8266-color.yaml @@ -141,6 +141,14 @@ api: then: - ehmtx.indicator.off: id: rgb8x32 + - service: display_on + then: + - ehmtx.display.on: + id: rgb8x32 + - service: display_off + then: + - ehmtx.display.off: + id: rgb8x32 ota: password: !secret ota_password @@ -183,6 +191,20 @@ number: lambda: |- id(rgb8x32)->set_brightness(x); +switch: + - platform: template + name: "$devicename Display" + icon: "mdi:power" + restore_mode: ALWAYS_ON + lambda: |- + return id(rgb8x32)->show_display; + turn_on_action: + lambda: |- + id(rgb8x32)->set_display_on(); + turn_off_action: + lambda: |- + id(rgb8x32)->set_display_off(); + time: - platform: homeassistant id: ehmtx_time diff --git a/ehmtx8266-select.yaml b/ehmtx8266-select.yaml index 5c28d1f..94f7762 100644 --- a/ehmtx8266-select.yaml +++ b/ehmtx8266-select.yaml @@ -108,6 +108,14 @@ api: then: - ehmtx.indicator.off: id: rgb8x32 + - service: display_on + then: + - ehmtx.display.on: + id: rgb8x32 + - service: display_off + then: + - ehmtx.display.off: + id: rgb8x32 number: - platform: template @@ -121,6 +129,20 @@ number: lambda: |- id(rgb8x32)->set_brightness(x); +switch: + - platform: template + name: "$devicename Display" + icon: "mdi:power" + restore_mode: ALWAYS_ON + lambda: |- + return id(rgb8x32)->show_display; + turn_on_action: + lambda: |- + id(rgb8x32)->set_display_on(); + turn_off_action: + lambda: |- + id(rgb8x32)->set_display_off(); + ota: password: !secret ota_password diff --git a/fullfeaturetest.yaml b/fullfeaturetest.yaml index 348b7c0..8e21a69 100644 --- a/fullfeaturetest.yaml +++ b/fullfeaturetest.yaml @@ -230,6 +230,16 @@ api: - ehmtx.indicator.off: id: rgb8x32 + - service: display_on + then: + - ehmtx.display.on: + id: rgb8x32 + + - service: display_off + then: + - ehmtx.display.off: + id: rgb8x32 + number: - platform: template name: "$devicename brightness" @@ -242,6 +252,20 @@ number: lambda: |- id(rgb8x32)->set_brightness(x); +switch: + - platform: template + name: "$devicename Display" + icon: "mdi:power" + restore_mode: ALWAYS_ON + lambda: |- + return id(rgb8x32)->show_display; + turn_on_action: + lambda: |- + id(rgb8x32)->set_display_on(); + turn_off_action: + lambda: |- + id(rgb8x32)->set_display_off(); + ota: password: !secret ota_password