diff --git a/CHANGELOG.md b/CHANGELOG.md index 11c20f2..43a80fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,47 +1,5 @@ # Changelog -## 2023.4.1 -- breaking: removed show_icons +## 2023.5.0 -## 2023.4.0 -- new: set_screen_color service to set color for a screen (service & action) -- breaking: all settings and parameters are named more consistant -- changed: center small text instead of left aligned -- removed: select component - -## 2023.3.5 -- new: show_seconds indicator top left corner -- breaking: removed automatic scaling of images -- new: support 8x32 icons without text -- breaking: added status,display_on,display_off as default service => remove these from your yaml -- breaking: added indicator_on/off as default service => remove these from your yaml -- breaking: added alarm_color,text_color,clock_color as default service => remove these from your yaml -- breaking: gauge is also schown while the clock is displayed but without moving the screen to the right -- breaking: show_icons as default service => remove from yaml - -## 2023.3.4 - -- added: option to not display clock/date #53 -- added: dynamic set_show_clock -- added: on_next_clock trigger - -## 2023.3.3 - -- fixed: force_screen skips imediatly to the selected screen -- added: hold_time configurable - -## 2023.3.2 - -- added: hold_screen for 20 additional seconds - -## 2023.3.1 - -- added: del_screen with wildcards -- changed: maximum icons to 80 -- fixed: skip_next -- fixed: show_all_icons on boot - -## 2023.3.0 - -see README.md for features -e.g. Service **display_on** / **display_off** +- beta release \ No newline at end of file diff --git a/README.md b/README.md index 64bff6e..fbc0a9b 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,18 @@ -# This is a work in progress. Don't use it for production! +# EspHoMaTriX version 2 (EHMTXv2) + +## This is a prerelease beta version! ## Important information If you like my work, please donate me a star on github and consider sponsoring me!! -# EspHoMaTriX version 2 (EHMTXv2) +## Introduction -A simple but very flexible DIY status display, built with a flexible 8x32 RGB LED panel implemented with [esphome.io](https://esphome.io) +A simple but very flexible DIY status display, built with a flexible 8x32 RGB LED panel, e.g. the ULANZI TC001 implemented with [esphome.io](https://esphome.io) ![sample image](./images/sample.png) -## Important information - -If you like my work, please donate me a star on github and consider sponsoring me!! - -## Introduction +## Background There are some "RGB-matrices" status displays/clocks out there, the commercial ones from LaMetric and Ulanzi, also some very good DIY-alternatives. @@ -22,33 +20,12 @@ There are some "RGB-matrices" status displays/clocks out there, the commercial o - [Ulanzi TC001](https://www.aliexpress.com/item/1005005008682055.html) commercial ~ €50 - [AWTRIX](https://awtrixdocs.blueforcer.de/#/) (project has been discontinued after more than 4 years now in August 2022) - [Pixel It](https://docs.bastelbunker.de/pixelit/) (project is under active development) -- [AWTRIX-Light](https://github.com/Blueforcer/awtrix-light) From the developer of Awtrix, optimized for the Ulanzi TC001 -Hardware -- [lamatrix](https://github.com/noahwilliamsson/lamatrix/tree/master) micropython based and around 5 years old +- [AWTRIX-Light](https://github.com/Blueforcer/awtrix-light) From the developer of Awtrix, optimized for the Ulanzi TC001 Hardware The solutions have their pros and cons. I tried some and used AwTrix for a long time. But the cons are so big (in my opinion) that I started an esphome.io variant. Targeted to an optimized Home Assistant integration, without paid blueprints and the need of MQTT. But it had to be extensible, e.g. for the use as pool thermometer or as media player. All done by the magical power of esphome. -### EspHoMaTriX in the media - -See this German tutorial video with information on setting up your display [RGB-LED Status Display für Home Assistant mit ESPHome | ESPHoMaTrix](https://www.youtube.com/watch?v=DTd9vAhet9A). - -Another german tutorial video focused at the Ulanzi [Smarte Pixel Clock über Home Assistant steuern - Entitäten / Icons und mehr in der Ulanzi](https://www.youtube.com/watch?v=LgaT0mNbl34) - -See this [nice article](https://blakadder.com/esphome-pixel-clock/) about EsphoMaTrix on a Ulanzi TC001 from [blakadder](https://github.com/blakadder). - -Short video on Instagram [@blak_adder](https://www.insbuiltagram.com/reel/CpYVByRIaSI) - -See this english discussions: -[Share your projects](https://community.home-assistant.io/t/esphomatrix-a-simple-clock-status-display/425325) -[ESPHOME](https://community.home-assistant.io/t/a-simple-diy-status-display-with-an-8x32-rgb-led/379051) - -It was also mentiond in the blog [Building the Open Home](https://building.open-home.io/local-control-is-the-only-way/) and in the home assistant [livestream](https://youtu.be/IGnCGDaXR0M?t=6267) - -Or in german: -[Showroom](https://community.simon42.com/t/8x32-pixel-uhr-mit-homeassistant-anbindung/1076) - ### Features Based on a 8x32 RGB matrix, it displays a clock, the date and up to 24 other 'screens' provided by Home Assistant. Each screen (value/text) can be associated with a 8x8 bit RGB icon or GIF animation (see [installation](#installation)). The values/text can be updated or deleted from the display queue. Each screen has a lifetime, if not refreshed in its lifetime, it will disappear. Even 8x32 GIF animations are possible. You can control nearly everything of the component. @@ -61,26 +38,26 @@ After the [old](https://github.com/lubeda/EsphoMaTrix) component became favorite ### The easy way -There is a little hype around the Ulanzi TC001 pixel clock. This hardware can be used with **EspHoMaTriX v2**. +There is a little hype around the Ulanzi TC001 pixel clock. The easy way works with the Ulanzi TC001 hardware. For more customization and other hardware look [here](#the-funny-but-more-elaborate-way). -### Steps (easy) +In easy mode you'll have a clock with auto brightness control and after step 3 you can send states to the display an toggle on or off additional screen elements. #### Step 1 -Copy these files: +Copy these files from the source folder `copy2esphome`: - ulanzi-simple.yaml - EHMTXv2.ttf -to your esphome directory (usually /config/esphome). In your esphome dashboard, you will find a new device named `ulanzi-simple`. +to your esphome directory (usually /config/esphome). In your esphome dashboard, you will find a new device named `ulanzi-easy`. #### Step 2 -connect your ulanzi device to your host with USB-C and flash the firmware. +Connect your ulanzi device to your host with USB-C and flash the firmware. #### Step 3 -Copy `EHMTX_easy_state.yaml` to your blueprint path (usually /config/blueprints/automation/) in a subfolder named `ehmtxv2`. +Copy the blueprints `EHMTX_easy_*.yaml` to your blueprint path (usually /config/blueprints/automation/) in a subfolder named `ehmtxv2`. Reload your automations and have fun after configuring some automations with this blueprint. @@ -90,7 +67,7 @@ The device should boot ![boot](images/booting.png) -and after a while (~30 seconds) it should display the correct time +and after a while (~30 seconds) it should display the correct time. ![clock screen](images/clock_screen.png). @@ -98,34 +75,41 @@ If not, check the esphome logs for further investigations. ### The funny but more elaborate way -This is for the more advanced users. If you understand the concept of esphome, you can display nearly everything with this component. +This is for the more advanced users. If you understand the concept of esphome, you can display nearly everything with this component. You are also able to create your own customized esphome based display with multiple sensors or even use it as microphone for the new [voice assist](https://esphome.io/components/voice_assistant.html) feature from home assistant. #### Concept You can add screens to a queue and all these screens are displayed one after another. ![timing](./images/timingv2.png) -Each screen can display different information or is of a different kind. They all have a lifetime, if a screen isn't refreshed during its lifetime it will be removed from the queue. If there is nothing left in the queue, the date and time screens are displayed. Some screens can show additional features like an alarm or indicator see [elements](#elements). -You can add screens from home assistant with services or from esphome via YAML. +Each screen can display different information or animation or text, even in rainbox color. They all have a lifetime, if a screen isn't refreshed during its lifetime it will be removed from the queue. If there is nothing left in the queue, the date and time screens are displayed. Some screens can show additional features like an alarm or indicator see [elements](#display-elements). +You can add screens from home assistant with service-calls or from esphome via lambdas in your YAML. -#### Screen types +#### Screen types a.k.a. what is possible ##### Date/Time screen ![clock screen](./images/clock_screen.png) -###### Service +###### Service via API + +You can call this from e.g. the [developer tools service](https://my.home-assistant.io/redirect/developer_services/) ```c clock_screen => {"lifetime", "screen_time", "default_font", "r", "g", "b"} +rainbow_clock_screen => {"lifetime", "screen_time", "default_font"} date_screen => {"lifetime", "screen_time", "default_font", "r", "g", "b"} +rainbow_date_screen => {"lifetime", "screen_time", "default_font"} ``` -###### API +###### Lambda + +You cann use these in [lambdas](https://esphome.io/guides/automations.html?highlight=lambda#lambda-action) in your esphome YAML. all parameters have a default value. ```c 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 rainbow_clock_screen(int lifetime=D_LIFETIME, int screen_time=D_SCREEN_TIME, bool default_font=true); 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); ``` @@ -133,16 +117,18 @@ void date_screen(int lifetime=D_LIFETIME, int screen_time=D_SCREEN_TIME,bool def ![icon screen](./images/icon_screen.png) -###### service +###### Service via API ```c icon_screen => {"icon_name", "text", "lifetime", "screen_time", "default_font", "r", "g", "b"} +rainbow_icon_screen => {"icon_name", "text", "lifetime", "screen_time", "default_font"} ``` -###### api +###### Lambda ```c 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 rainbow_icon_screen(std::string icon, std::string text, int lifetime=D_LIFETIME, int screen_time=D_SCREEN_TIME,bool default_font=true); ``` ##### full_screen @@ -151,39 +137,40 @@ For 8x32 icons or animations ![full_screen](./images/fullscreen.png) -###### service +###### service via API ```c full_screen => {"icon_name", "lifetime", "screen_time"} ``` -###### api +###### Lambda ```c -void EHMTX::full_screen(std::string iconname, int lifetime, int screen_time) +void full_screen(string iconname, int =D_LIFETIME, int screen_time=D_SCREEN_TIME); ``` -#### Elements +#### Display Elements ![elements](./images/elements.png) ##### alarm -The alarm is displayed in the upper right corner at all screen types! You can set its color. +The alarm is displayed in the upper right corner at all screen types! You can set its color and its size. ###### service ```c -show_alarm => { "r", "g", "b","s"} +show_alarm => { "r", "g", "b","size"} ``` ###### api ```c -void EHMTX::show_alarm(int r, int g, int b, int s=2); +void EHMTX::show_alarm(int r, int g, int b, int size=2); ``` r,g,b: 0-255 color components +size: 0-3 (zero turns it off) To remove it, call: @@ -193,10 +180,10 @@ To remove it, call: hide_alarm => no parameter ``` -###### API +###### Lambda ```c -void EHMTX::hide_alarm(); +void hide_alarm(); ``` ##### Indicator @@ -206,16 +193,17 @@ The indicator is in the lower left corner, but not displayed in fullscreen 8x32 ###### Service ```c -show_indicator => { "r", "g", "b","s"} +show_indicator => { "r", "g", "b","size"} ``` ###### API ```c -void EHMTX::show_indicator(int r, int g, int ,int s=3); +void show_indicator(int r, int g, int ,int size=3); ``` r,g,b: 0-255 color components +size: 0-3 (zero turns it off) To remove it, call: @@ -225,10 +213,10 @@ To remove it, call: hide_indicator => no parameter ``` -###### API +###### Lambda ```c -void EHMTX::hide_indicator(); +void hide_indicator(); ``` ##### gauge @@ -244,10 +232,10 @@ show_gauge => {"value","r", "g", "b"} ###### api ```c -void EHMTX::show_gauge(int value, int r, int g, int b); +void show_gauge(int percent, int r, int g, int b); ``` -value: 0-100 (resolution: one pixel per 12,5%) +percent: 0-100 (resolution: one pixel per 12,5%) r,g,b: 0-255 color components To remove it call: @@ -261,16 +249,14 @@ hide_gauge => no parameter ###### api ```c -void EHMTX::hide_gauge(); +void hide_gauge(); ``` -#### Installation - -##### **EspHoMaTriXv2** custom component +#### Installation of **EspHoMaTriXv2** custom component **EspHoMaTriXv2** is a custom component, you have to include it in your YAML configuration. To always use the newest features you should use the repo, to use a stable version, you copy a working version to your esphome installation. -###### local use +##### use of local copy If you download the components-folder from the repo and install it in your esphome you have a stable installation. But if there are new features, you won't see them. If needed, customize the YAML to your folder structure. @@ -290,10 +276,10 @@ external_components: - source: type: git url: https://github.com/lubeda/EspHoMaTriXv2 - ref: release # optional select a special branch or tag + ref: stable # optional select a special branch or tag ``` -##### Addressable_light component +#### Addressable_light component The **EspHoMaTriXv2** component requires a 8x32 pixel addressable_light, it is referenced by the id `matrix_component`. @@ -301,7 +287,7 @@ See the default [options](https://esphome.io/components/display/index.html) There are some different matrices-types on the market, to adapt them to **EspHoMaTriXv2** you have to find the proper pixel mapper. If there is garbage on your display, try the other `pixel_mapper`. Here are the most common types for flexible 8x32 matrices: -#### Type 1 +##### Type 1 Common for 8x32 RGB flexible matrices. @@ -319,7 +305,7 @@ display: ..... ``` -#### Type 2 (e.g. Ulanzi TC001) +##### Type 2 (e.g. Ulanzi TC001) Under the display tag, specify this pixel mapper: @@ -335,7 +321,7 @@ display: ..... ``` -#### Type 3 (daisy chained 8x8 panels) +##### Type 3 (daisy chained 8x8 panels) ```yaml display: @@ -346,7 +332,7 @@ display: ..... ``` -#### How to configure the pixel_mapper +##### How to configure the pixel_mapper You have to configure this `lambda` under the `display:` section to use the **EspHoMaTriXv2** component @@ -406,6 +392,8 @@ You can configure two fonts if you like. DarkPoet78 is also providing special fonts for 8x32 matrices in his [repo](https://github.com/darkpoet78/MatrixClockFonts) +For european starters you can use the font EHMTXv2.ttf of the copy2esphome folder. + ```yaml font: - file: EHMTXv2.ttf @@ -417,7 +405,7 @@ font: #### Icons and Animations -Download and install all needed icons (.jpg/.png) and animations (.GIF) under the `ehmtx:` key. All icons have to be 8x8 or 8x32 pixels in size. If necessary, scale them with gimp, check "as animation" for GIFs. +Download and install all needed icons (.jpg/.png) and animations (.GIF) under the `ehmtxv2:` key. All icons have to be 8x8 or 8x32 pixels in size. If necessary, scale them with gimp, check "as animation" for GIFs. You can also specify a URL to directly download the image file. The URLs will only be downloaded once at compile time, so there is no additional traffic on the hosting website. @@ -438,8 +426,11 @@ emhtx: - id: yoga file: icons/yoga-bridge.GIF pingpong: true + - id: jackshome + url: https://awtrix.blueforcer.de/animations/JackHomePage + resize: 32x8 - id: garage - file: garage.GIF + lameid: 1234 duration: 100 - id: homeassistant url: https://github.com/home-assistant/assets/raw/master/logo/logo-special.png @@ -466,22 +457,21 @@ This component is highly customizable. ```yaml ehmtxv2: id: rgb8x32 - clock_time: 7 - screen_time: 9 show_seconds: true matrix_component: ehmtx_display time_component: ehmtx_time icons2html: true default_font_id: default_font + default_font_yoffset: 6 special_font_id: special_font special_font_yoffset: 7 - default_font_yoffset: 6 brightness: 80 # percent time_format: "%H:%M" date_format: "%d.%m." week_start_monday: true # false equals sunday scroll_count: 2 # scroll long text at least two times scroll_interval: 80 # milliseconds + rainbow_interval: 32 # milliseconds frame_interval: 192 # milliseconds icons: ..... @@ -491,12 +481,6 @@ ehmtxv2: **id** (required, ID): Manually specify the ID used for code generation and in service definitions. -**clock_time** (optional, seconds): duration to display the clock after this time the date is displayed until the next "show_screen". If `show_date` is false and `clock_time` > 0 the clock will be display as long as a normal screen! Setting `clock_time` to 0 will not show the clock or date. If there are no screens ind the queue, the display will be blank until the next screen is sent. - -**screen_time** (optional, seconds): default duration to display a screen or a clock/date sequence, a long text will be scrolled at least `scroll_count` times (default: 10 seconds). This may be overwritten by the add_screen service. - -**hold_time** (optional, seconds): extends the display time of the current screen in seconds (default=20). Used in services or automations, see `hold_screen` - **date_format** (optional, string): formats the date display with [strftime syntax](https://esphome.io/components/time.html?highlight=strftime), defaults `"%d.%m."` (use `"%m.%d."` for the US) **show_seconds** (optional, boolean): toggle an indicator for seconds while the clock is displayed (default: false) @@ -556,9 +540,39 @@ See [icon details](#icons-and-animations) ## Control your display -A lot of features are accessible with actions, you can use in your YAML. - -### Local actions/lambdas +A lot of features are accessible with services from home assistant and lambdas you can use in your YAML. + +### Public functions/services + +|service|parameter|result| +|---|---|---| +|`status`|none|write some status information to the esphome logs| +|`display_on`|none|turn display off| +|`display_off`|none|turn display on| +|`hold_screen`|none|show the screen that is currently displayed for the number of seconds longer| +|`hide_indicator`|none|hides the indicator| +|`hide_gauge`|none|hides the gauge| +|`hide_alarm`|none|hides the alarm| +|`show_gauge"`|"percent", "r", "g", "b"|set the heught of the gauge according to the percentage in the given color| +|`show_alarm`|"r", "g", "b", "size"|shows the color with the given size in the upper right corner| +|`show_indicator`|"r", "g", "b", "size"|shows the color with the given size in the lower right corner| +|`clock_color`|"r", "g", "b"|set the default color for the clock/date display| +|`today_color"`|"r", "g", "b"|set the special color for today in the day of week line| +|`weekday_color"`|"r", "g", "b"|set the default color in the day of week line| +|`del_screen`|"icon_name", "mode"|deletes the specified icon screen from the queue, the [mode](#modes) is a filter| +|`force_screen`|"icon_name", "mode"|displayes the seleted the specified icon screen from the queue, the [mode](#modes) is a filter| +|`full_screen`|"icon_name", "lifetime", "screen_time"|show the specified 8x32 icon as fullscreen| +|`icon_screen`|"icon_name", "text", "lifetime", "screen_time", "default_font", "r", "g", "b"|show the specified icon with text| +|`rainbow_icon_screen`|"icon_name", "text", "lifetime", "screen_time", "default_font"|show the specified icon with text in rainbow color| +|`text_screen`|"text", "lifetime", "screen_time", "default_font", "r", "g", "b"|show the specified text| +|`rainbow_text_screen`|"text", "lifetime", "screen_time", "default_font"|show the specified text in rainbow colors| +|`clock_screen`|"lifetime", "screen_time", "default_font", "r", "g", "b"|show the clock| +|`rainbow_clock_screen`|"lifetime", "screen_time", "default_font"|show the clock in rainbow color| +|`blank_screen`|"lifetime", "screen_time"|"show" an empty screen| +|`date_screen`|"lifetime", "screen_time", "default_font", "r", "g", "b"|show the date| +|`brightness`|"value"|set the display brightness| + +### Local lambdas #### Add screen to your display queue @@ -582,7 +596,6 @@ sensor: id(rgb8x32)->icon_screen("sun", text); // uses default values for color etc. ``` -#### Set (alarm/clock/gauge/text/today/weekday) color action ##### Force screen @@ -601,7 +614,7 @@ Experienced programmers can use these public methods: ```c ``` -### Local trigger +### Local triggers To use the display without homeassistant automations, you may use the [advanced functionality](#change-configuration-during-runtime) with triggers. The triggers can be fired by sensors, time or by the ehmtx component. @@ -697,14 +710,20 @@ For example, if you have multiple icons named weather_sunny, weather_rain & weat - ```icon_name```: Icon `id` defined in the YAML (see installation) - ```mode```: The mode is for internal purposes use `5` for icon_screen +##### modes + |mode|value| |----|----| |MODE_BLANK|1| |MODE_CLOCK | 2| | MODE_DATE | 3| | MODE_FULL_SCREEN | 4| -|MODE_ICONSCREEN | 5| -|MODE_TEXT | 6| +|MODE_ICON_SCREEN | 5| +|MODE_TEXT_SCREEN | 6| +|MODE_RAINBOW_ICON | 7| +|MODE_RAINBOW_TEXT |8| +| MODE_RAINBOW_CLOCK | 9| +| MODE_RAINBOW_DATE | 10| **(D)** Service **display_on** / **display_off** @@ -749,7 +768,7 @@ binary_sensor: Service **hold_screen** -Displays the current screen for a configured amount (see **hold_time**) (default=20) seconds longer. +Displays the current screen for a configured amount (see **hold_time**) (default=30) seconds longer. e.g. on the Ulanzi TC001 @@ -761,7 +780,7 @@ binary_sensor: inverted: true on_press: lambda: - id(rgb8x32)->hold_screen(); + id(rgb8x32)->hold_screen(120); ``` **(D)** Service **status** @@ -960,9 +979,24 @@ sensor: **nothing yet, since it is new** -## Usage +## EspHoMaTriX in the media -The integration works with the Home Assistant API so, after boot of the device, it takes a few seconds until the service calls start working. If you see a growing green rectangle after boot, you have to wait a bit until the API is connected etc. +See this German tutorial video with information on setting up your display [RGB-LED Status Display für Home Assistant mit ESPHome | ESPHoMaTrix](https://www.youtube.com/watch?v=DTd9vAhet9A). + +Another german tutorial video focused at the Ulanzi [Smarte Pixel Clock über Home Assistant steuern - Entitäten / Icons und mehr in der Ulanzi](https://www.youtube.com/watch?v=LgaT0mNbl34) + +See this [nice article](https://blakadder.com/esphome-pixel-clock/) about EsphoMaTrix on a Ulanzi TC001 from [blakadder](https://github.com/blakadder). + +Short video on Instagram [@blak_adder](https://www.insbuiltagram.com/reel/CpYVByRIaSI) + +See this english discussions: +[Share your projects](https://community.home-assistant.io/t/esphomatrix-a-simple-clock-status-display/425325) +[ESPHOME](https://community.home-assistant.io/t/a-simple-diy-status-display-with-an-8x32-rgb-led/379051) + +It was also mentiond in the blog [Building the Open Home](https://building.open-home.io/local-control-is-the-only-way/) and in the home assistant [livestream](https://youtu.be/IGnCGDaXR0M?t=6267) + +Or in german: +[Showroom](https://community.simon42.com/t/8x32-pixel-uhr-mit-homeassistant-anbindung/1076) ## Disclaimer @@ -978,6 +1012,7 @@ THE SOFTWARE IS PROVIDED "AS IS", use at your own risk! - **[ofirsnb](https://github.com/ofirsnb)** for his contributions - **[darkpoet78](https://github.com/darkpoet78/MatrixClockFonts)** for his work on optimized fonts - **[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 - ** everbody that found bugs/issues and reported them! ## Special thanks to all sponsors diff --git a/components/ehmtxv2/EHMTX.cpp b/components/ehmtxv2/EHMTX.cpp index 7fdc7e5..8ae8e08 100644 --- a/components/ehmtxv2/EHMTX.cpp +++ b/components/ehmtxv2/EHMTX.cpp @@ -2,12 +2,14 @@ namespace esphome { - EHMTX::EHMTX() : PollingComponent(TICKINTERVAL) + EHMTX::EHMTX() : PollingComponent(POLLINGINTERVAL) { this->show_display = true; this->display_gauge = false; this->display_indicator = 0; this->display_alarm = 0; + this->clock_time = 10; + this->hold_time = 10; this->icon_count = 0; this->hue_ = 0; this->text_color = Color(C_RED, C_GREEN, C_BLUE); @@ -38,9 +40,14 @@ namespace esphome void EHMTX::show_indicator(int r, int g, int b, int size) { - this->indicator_color = Color((uint8_t)r & 248, (uint8_t)g & 252, (uint8_t)b & 248); - this->display_indicator = size; + 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->hide_indicator(); + } + } void EHMTX::hide_indicator() @@ -152,7 +159,7 @@ namespace esphome register_service(&EHMTX::get_status, "status"); register_service(&EHMTX::set_display_on, "display_on"); register_service(&EHMTX::set_display_off, "display_off"); - register_service(&EHMTX::hold_screen, "hold_screen"); + register_service(&EHMTX::hold_screen, "hold_screen", {"time"}); register_service(&EHMTX::hide_indicator, "hide_indicator"); register_service(&EHMTX::hide_gauge, "hide_gauge"); register_service(&EHMTX::hide_alarm, "hide_alarm"); @@ -169,13 +176,19 @@ namespace esphome register_service(&EHMTX::full_screen, "full_screen", {"icon_name", "lifetime", "screen_time"}); register_service(&EHMTX::icon_screen, "icon_screen", {"icon_name", "text", "lifetime", "screen_time", "default_font", "r", "g", "b"}); + register_service(&EHMTX::rainbow_icon_screen, "rainbow_icon_screen", {"icon_name", "text", "lifetime", "screen_time", "default_font"}); + register_service(&EHMTX::text_screen, "text_screen", {"text", "lifetime", "screen_time", "default_font", "r", "g", "b"}); + register_service(&EHMTX::rainbow_text_screen, "rainbow_text_screen", {"text", "lifetime", "screen_time", "default_font"}); + 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::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::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"}); + 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!"); @@ -183,9 +196,13 @@ namespace esphome void EHMTX::show_alarm(int r, int g, int b, int size) { - this->alarm_color = Color((uint8_t)r & 248, (uint8_t)g & 252, (uint8_t)b & 248); - this->display_alarm = size; + 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->hide_alarm(); + } } void EHMTX::hide_alarm() @@ -204,7 +221,7 @@ namespace esphome void EHMTX::update() // called from polling component { - if (! this->is_running){ + if (!this->is_running){ if (this->clock->now().timestamp > 6000) { ESP_LOGD(TAG, "time sync => starting"); this->is_running = true; @@ -225,7 +242,7 @@ namespace esphome if (this->queue[i]->mode == mode) { bool force = true; - if ((mode == MODE_ICONSCREEN) || (mode == MODE_FULL_SCREEN) || (mode == MODE_RAINBOW_ICON)) + if ((mode == MODE_ICON_SCREEN) || (mode == MODE_FULL_SCREEN) || (mode == MODE_RAINBOW_ICON)) { if (strcmp(this->queue[i]->icon_name.c_str(), icon_name.c_str()) != 0) { @@ -292,12 +309,12 @@ namespace esphome case MODE_FULL_SCREEN: infotext = "full screen " + this->queue[i]->icon_name; break; - case MODE_ICONSCREEN: + case MODE_ICON_SCREEN: case MODE_RAINBOW_ICON: infotext = this->queue[i]->icon_name.c_str(); break; case MODE_RAINBOW_TEXT: - case MODE_TEXT: + case MODE_TEXT_SCREEN: infotext = "TEXT"; break; default: @@ -375,9 +392,10 @@ namespace esphome this->next_action_time = this->clock->now().timestamp - 1; } - void EHMTX::hold_screen() + void EHMTX::hold_screen(int time) { this->next_action_time += this->hold_time; + this->hold_time = time; } void EHMTX::get_status() @@ -449,7 +467,7 @@ namespace esphome { bool force = true; ESP_LOGW(TAG, "del_screen: icon %s in position: %d mode %d", icon_name.c_str(), i, mode); - if ((mode == MODE_ICONSCREEN) || (mode == MODE_FULL_SCREEN) || (mode == MODE_RAINBOW_ICON)) + if ((mode == MODE_ICON_SCREEN) || (mode == MODE_FULL_SCREEN) || (mode == MODE_RAINBOW_ICON)) { if (strcmp(this->queue[i]->icon_name.c_str(), icon_name.c_str()) != 0) { @@ -493,7 +511,7 @@ namespace esphome 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->mode = MODE_ICON_SCREEN; 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(); @@ -511,6 +529,19 @@ namespace esphome screen->status(); } + void EHMTX::rainbow_date_screen(int lifetime, int screen_time, bool default_font) + { + EHMTX_queue *screen = this->find_free_queue_element(); + + ESP_LOGD(TAG, "rainbow_date_screen lifetime: %d screen_time: %d", lifetime, screen_time); + screen->mode = MODE_RAINBOW_DATE; + screen->default_font = default_font; + screen->screen_time = screen_time; + screen->endtime = this->clock->now().timestamp + lifetime * 60; + screen->status(); + } + + void EHMTX::rainbow_icon_screen(std::string iconname, std::string text, int lifetime, int screen_time, bool default_font) { @@ -522,22 +553,13 @@ namespace esphome 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); - } - 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->icon_name = iconname; screen->text = text; - screen->pixels_ = w; + screen->endtime = this->clock->now().timestamp + lifetime * 60; + screen->screen_time = screen_time; + screen->default_font = default_font; screen->mode = MODE_RAINBOW_ICON; - screen->icon_name = iconname; + screen->calc_scroll_time(); 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(); } @@ -546,33 +568,13 @@ namespace esphome { EHMTX_queue *screen = this->find_free_queue_element(); - 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->text = text; - screen->pixels_ = w; - if (screen->pixels_ < 32) - { - screen->centerx_ = ceil((32 - screen->pixels_) / 2); - } - - 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); + screen->screen_time = screen_time; screen->default_font = default_font; - screen->mode = MODE_TEXT; - + screen->text_color = Color(r, g, b); + screen->mode = MODE_TEXT_SCREEN; + screen->calc_scroll_time(); screen->status(); } @@ -580,32 +582,12 @@ namespace esphome { EHMTX_queue *screen = this->find_free_queue_element(); - 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->text = text; - screen->pixels_ = w; - if (screen->pixels_ < 32) - { - screen->centerx_ = ceil((32 - screen->pixels_) / 2); - } - - 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->screen_time = screen_time; screen->default_font = default_font; screen->mode = MODE_RAINBOW_TEXT; - + screen->calc_scroll_time(); screen->status(); } @@ -659,7 +641,7 @@ namespace esphome { for (size_t i = 0; i < MAXQUEUE; i++) { - if ((this->queue[i]->mode == MODE_ICONSCREEN) && (this->queue[i]->icon == icon)) + if ((this->queue[i]->mode == MODE_ICON_SCREEN) && (this->queue[i]->icon == icon)) { ESP_LOGD(TAG, "free_screen: found by icon"); return this->queue[i]; @@ -755,11 +737,6 @@ namespace esphome 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; diff --git a/components/ehmtxv2/EHMTX.h b/components/ehmtxv2/EHMTX.h index 1773ef7..1da158b 100644 --- a/components/ehmtxv2/EHMTX.h +++ b/components/ehmtxv2/EHMTX.h @@ -20,10 +20,10 @@ const uint8_t MAXICONS = 90; 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.5.0"; +const uint16_t POLLINGINTERVAL = 800; +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_ICONSCREEN = 5, MODE_TEXT = 6 , MODE_RAINBOW_ICON = 7,MODE_RAINBOW_TEXT = 8, MODE_RAINBOW_CLOCK = 9 }; +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 }; namespace esphome { @@ -69,7 +69,7 @@ namespace esphome void remove_expired_queue_element(); uint8_t find_oldest_queue_element(); uint8_t find_icon_in_queue(std::string); - void force_screen(std::string name,int mode=MODE_ICONSCREEN); + void force_screen(std::string name,int mode=MODE_ICON_SCREEN); EHMTX_Icon *icons[MAXICONS]; EHMTX_queue *queue[MAXQUEUE]; void add_icon(EHMTX_Icon *icon); @@ -99,11 +99,11 @@ namespace esphome void get_status(); void queue_status(); void skip_screen(); - void hold_screen(); + void hold_screen(int t=30); void set_display(addressable_light::AddressableLightDisplay *disp); - void set_hold_time(uint16_t t); - void set_clock_time(uint16_t t); + void set_hold_time(uint16_t t=30); + void set_clock_time(uint16_t t=10); void set_show_day_of_week(bool b); void set_show_seconds(bool b); void set_show_date(bool b); @@ -142,7 +142,8 @@ namespace esphome 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 rainbow_clock_screen(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 rainbow_date_screen(int lifetime=D_LIFETIME, int screen_time=D_SCREEN_TIME, bool default_font=true); + void del_screen(std::string icon, int mode=MODE_ICON_SCREEN); void draw_gauge(); void draw_alarm(); @@ -186,6 +187,7 @@ namespace esphome 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(); }; class EHMTXNextScreenTrigger : public Trigger diff --git a/components/ehmtxv2/EHMTX_queue.cpp b/components/ehmtxv2/EHMTX_queue.cpp index 32c1173..143c643 100644 --- a/components/ehmtxv2/EHMTX_queue.cpp +++ b/components/ehmtxv2/EHMTX_queue.cpp @@ -37,10 +37,10 @@ namespace esphome case MODE_FULL_SCREEN: ESP_LOGD(TAG, "queue: full screen: %s for %d sec", this->icon_name.c_str(), this->screen_time); break; - case MODE_ICONSCREEN: + case MODE_ICON_SCREEN: ESP_LOGD(TAG, "queue: icon screen: %s text: %s for %d sec", this->icon_name.c_str(), this->text.c_str(), this->screen_time); break; - case MODE_TEXT: + case MODE_TEXT_SCREEN: ESP_LOGD(TAG, "queue: text text: %s for %d sec", this->text.c_str(), this->screen_time); break; case MODE_RAINBOW_ICON: @@ -52,6 +52,9 @@ namespace esphome case MODE_RAINBOW_CLOCK: ESP_LOGD(TAG, "queue: clock for %d sec", this->screen_time); break; + case MODE_RAINBOW_DATE: + ESP_LOGD(TAG, "queue: date for %d sec", this->screen_time); + break; default: ESP_LOGD(TAG, "queue: UPPS"); break; @@ -73,7 +76,7 @@ namespace esphome this->config_->last_rainbow_time = millis(); } - if ((this->mode == MODE_ICONSCREEN) || (this->mode == MODE_RAINBOW_ICON)) + if ((this->mode == MODE_ICON_SCREEN) || (this->mode == MODE_RAINBOW_ICON)) { if (millis() - this->config_->last_scroll_time >= this->config_->scroll_interval && this->pixels_ > TEXTSTARTOFFSET) { @@ -85,7 +88,7 @@ namespace esphome this->config_->last_scroll_time = millis(); } } - if ((this->mode == MODE_TEXT) || (this->mode == MODE_RAINBOW_TEXT)) + if ((this->mode == MODE_TEXT_SCREEN) || (this->mode == MODE_RAINBOW_TEXT)) { if (millis() - this->config_->last_scroll_time >= this->config_->scroll_interval && this->pixels_ >= 32) { @@ -141,17 +144,21 @@ namespace esphome this->config_->display->print(15 + xoffset, yoffset, font, this->config_->alarm_color, display::TextAlign::BASELINE_CENTER, "!t!"); } break; + case MODE_RAINBOW_DATE: case MODE_DATE: if (this->config_->clock->now().timestamp > 6000) // valid time { + color_ = (this->mode == MODE_RAINBOW_DATE) ? this->config_->rainbow_color : this->text_color; time_t ts = this->config_->clock->now().timestamp; - this->config_->display->strftime(xoffset + 15, yoffset, font, this->text_color, display::TextAlign::BASELINE_CENTER, this->config_->date_fmt.c_str(), + this->config_->display->strftime(xoffset + 15, yoffset, font, color_, display::TextAlign::BASELINE_CENTER, this->config_->date_fmt.c_str(), this->config_->clock->now()); if ((this->config_->clock->now().second % 2 == 0) && this->config_->show_seconds) { - this->config_->display->draw_pixel_at(0, 0, this->config_->clock_color); + this->config_->display->draw_pixel_at(0, 0, color_); + } + if (this->mode != MODE_RAINBOW_DATE){ + this->config_->draw_day_of_week(); } - this->config_->draw_day_of_week(); } else { @@ -161,7 +168,7 @@ namespace esphome case MODE_FULL_SCREEN: this->config_->display->image(0, 0, this->config_->icons[this->icon]); break; - case MODE_ICONSCREEN: + case MODE_ICON_SCREEN: case MODE_RAINBOW_ICON: { if (this->pixels_ > TEXTSTARTOFFSET) @@ -189,7 +196,7 @@ namespace esphome } } break; - case MODE_TEXT: + case MODE_TEXT_SCREEN: case MODE_RAINBOW_TEXT: if (this->pixels_ > 32) @@ -235,4 +242,48 @@ namespace esphome this->endtime = this->config_->clock->now().timestamp + et * 60; this->icon = icon; } + + void EHMTX_queue::calc_scroll_time() + { + int x, y, w, h; + float display_duration; + 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); + } + else + { + this->config_->display->get_text_bounds(0, 0, text.c_str(), this->config_->special_font, display::TextAlign::LEFT, &x, &y, &w, &h); + } + + this->pixels_ = w; + this->shiftx_ = 0; + + switch (this->mode) + { + case MODE_RAINBOW_TEXT: + case MODE_TEXT_SCREEN: + display_duration = ceil((28+(this->config_->scroll_count * (32 + this->pixels_)) * this->config_->scroll_interval) / 1000); + this->screen_time = (display_duration > this->screen_time) ? display_duration : this->screen_time; + if (this->pixels_ < 32) + { + this->centerx_ = ceil((32 - this->pixels_) / 2); + } + break; + case MODE_RAINBOW_ICON: + case MODE_ICON_SCREEN: + display_duration = ceil(((28-TEXTSTARTOFFSET)+(this->config_->scroll_count * (TEXTSTARTOFFSET + this->pixels_)) * this->config_->scroll_interval) / 1000); + this->screen_time = (display_duration > this->screen_time) ? display_duration : this->screen_time; + if (this->pixels_ < 23) + { + this->centerx_ = ceil((23 - this->pixels_) / 2); + } + break; + default: + break; + } + + this->shiftx_ = 0; + ESP_LOGD(TAG, "display text: %s pixels %d calculated: %d", text.c_str(), this->pixels_, this->screen_time); + } } diff --git a/components/ehmtxv2/__init__.py b/components/ehmtxv2/__init__.py index 7680922..6d5bbe9 100644 --- a/components/ehmtxv2/__init__.py +++ b/components/ehmtxv2/__init__.py @@ -27,8 +27,7 @@ SVG_FULL_SCREEN_START = '' SVG_END = "" logging.warning(f"") -logging.warning(f"If you are upgrading EsphoMaTrix from a version before 2023.5.0,") -logging.warning(f"you should read the manual https://github.com/lubeda/EspHoMaTriXv2 for tips.") +logging.warning(f"This is a beta version of https://github.com/lubeda/EspHoMaTriXv2") logging.warning(f"") def rgb565_svg(x,y,r,g,b): @@ -50,7 +49,6 @@ NextClockTrigger = ehmtx_ns.class_( "EHMTXNextClockTrigger", automation.Trigger.template(cg.std_string) ) -CONF_CLOCKTIME = "clock_time" CONF_EHMTX = "ehmtx" CONF_URL = "url" CONF_FLAG = "flag" @@ -61,7 +59,6 @@ CONF_ICONS = "icons" CONF_SHOWDOW = "show_dow" CONF_SHOWDATE = "show_date" CONF_FRAMEDURATION = "frame_duration" -CONF_HOLD_TIME = "hold_time" CONF_SCROLLCOUNT = "scroll_count" CONF_MATRIXCOMPONENT = "matrix_component" CONF_HTML = "icons2html" @@ -93,9 +90,6 @@ 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_CLOCKTIME, default="5" - ): cv.templatable(cv.positive_int), cv.Optional( CONF_HTML, default=False ): cv.boolean, @@ -132,9 +126,6 @@ EHMTX_SCHEMA = cv.Schema({ cv.Optional( CONF_special_FONT_YOFFSET, default="6" ): cv.templatable(cv.int_range(min=-32, max=32)), - cv.Optional( - CONF_HOLD_TIME, default="20" - ): cv.templatable(cv.int_range(min=0, max=3600)), cv.Optional(CONF_SCROLLINTERVAL, default="80" ): cv.templatable(cv.positive_int), cv.Optional(CONF_RAINBOWINTERVAL, default="32" @@ -233,8 +224,6 @@ async def ehmtx_set_week_color_action_to_code(config, action_id, template_arg, a return var - - CODEOWNERS = ["@lubeda"] async def to_code(config): @@ -392,7 +381,6 @@ async def to_code(config): ehmtxtime = await cg.get_variable(config[CONF_TIMECOMPONENT]) cg.add(var.set_clock(ehmtxtime)) - cg.add(var.set_clock_time(config[CONF_CLOCKTIME])) cg.add(var.set_brightness(config[CONF_BRIGHTNESS])) cg.add(var.set_scroll_interval(config[CONF_SCROLLINTERVAL])) cg.add(var.set_rainbow_interval(config[CONF_SCROLLINTERVAL])) @@ -402,7 +390,6 @@ async def to_code(config): 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])) - cg.add(var.set_hold_time(config[CONF_HOLD_TIME])) cg.add(var.set_show_date(config[CONF_SHOWDATE])) cg.add(var.set_show_seconds(config[CONF_SHOW_SECONDS])) cg.add(var.set_default_font_offset(config[CONF_DEFAULT_FONT_XOFFSET], config[CONF_DEFAULT_FONT_YOFFSET] )) diff --git a/copy2esphome/EHMTX_easy_delete.yaml b/copy2esphome/EHMTX_easy_delete.yaml index e16d3e9..0fcdedf 100644 --- a/copy2esphome/EHMTX_easy_delete.yaml +++ b/copy2esphome/EHMTX_easy_delete.yaml @@ -22,7 +22,7 @@ blueprint: custom_value: true mode: dropdown options: - - label: MODE_ICONSCREEN + - label: MODE_ICON_SCREEN value: "5" - label: MODE_BLANK value: "1" @@ -32,7 +32,7 @@ blueprint: value: "3" - label: MODE_FULL_SCREEN value: "4" - - label: MODE_TEXT + - label: MODE_TEXT_SCREEN value: "6" - label: MODE_RAINBOW_ICON value: "7" diff --git a/copy2esphome/ehtmxv2-template.yaml b/copy2esphome/ehtmxv2-template.yaml new file mode 100644 index 0000000..9ba87bb --- /dev/null +++ b/copy2esphome/ehtmxv2-template.yaml @@ -0,0 +1,110 @@ +substitutions: + devicename: ehmtxv2 + friendly_name: LED Matrix + board: esp32dev + matrix_pin: GPIO32 + +external_components: + - source: + type: git + url: https://github.com/lubeda/EspHoMaTriXv2 + ref: release + refresh: 60s + components: [ ehmtxv2 ] + +esphome: + comment: "EHMTXv2 from LuBeDa" + name: $devicename + +esp32: + board: esp32dev + +font: + - file: EHMTXv2.ttf + size: 16 + id: default_font + glyphs: | + !?"%()+*=,-_.:°0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnÖÄÜöäüopqrstuvwxyz@<>ß§€/ + +binary_sensor: + - platform: status + name: "$devicename Status" + +logger: + level: WARN + +api: + +sensor: + +ota: + password: !secret ota_password + +wifi: + ssid: !secret wifi_ssid + password: !secret wifi_password + +web_server: + +light: + - platform: neopixelbus + id: ehmtx_light + type: GRB + internal: true + variant: WS2812 + pin: $ledpin + num_leds: 256 + color_correct: [30%, 30%, 30%] + gamma_correct: 2.0 + name: "$devicename Light" + restore_mode: ALWAYS_OFF + +time: + - platform: homeassistant + id: ehmtx_time + +display: + - platform: addressable_light + id: ehmtx_display + addressable_light_id: ehmtx_light + width: 32 + height: 8 + pixel_mapper: |- + if (y % 2 == 0) { + return (y * 32) + x; + } + return (y * 32) + (31 - x); + rotation: 0° + update_interval: 16ms + auto_clear_enabled: true + lambda: |- + id(rgb8x32)->tick(); + id(rgb8x32)->draw(); + +ehmtxv2: + id: rgb8x32 + icons2html: true + matrix_component: ehmtx_display + time_component: ehmtx_time + time_format: "%H:%M" + date_format: "%d.%m." + show_seconds: false + default_font_id: default_font + special_font_id: default_font + icons: + - id: error + lameid: 40530 + - id: home_assistant + lameid: 47693 + - id: temperature + lameid: 2056 + - id: lightbulb + lameid: 1762 + - id: music + lameid: 45625 + - id: phone + lameid: 1232 + - id: car + lameid: 2819 + - id: sleep8x32 + url: https://user-images.githubusercontent.com/16407309/224850723-634c9b2d-55d9-44f2-9f93-765c0485b090.gif diff --git a/copy2esphome/Ulanzi-simple.yaml b/copy2esphome/ulanzi-easy.yaml similarity index 78% rename from copy2esphome/Ulanzi-simple.yaml rename to copy2esphome/ulanzi-easy.yaml index b6553b8..d8ebdc0 100644 --- a/copy2esphome/Ulanzi-simple.yaml +++ b/copy2esphome/ulanzi-easy.yaml @@ -1,5 +1,5 @@ substitutions: - devicename: ulanzi-simple + devicename: ledpin: GPIO32 buzzerpin: GPIO15 friendly_name: LED Matrix @@ -15,13 +15,47 @@ substitutions: scl_pin: GPIO22 sda_pin: GPIO21 +- platform: template + name: "Auto-Adjust Brightness" + id: switch_autobrightness + icon: mdi:brightness-auto + restore_mode: RESTORE_DEFAULT_ON + lambda: |- + if (id(aab_enable)) { + return true; + } else { + return false; + } + turn_on_action: + lambda: |- + id(aab_enable) = true; + turn_off_action: + lambda: |- + id(aab_enable) = false; + +globals: + # aab = auto-adjustable brightness + - id: aab_enable + type: "bool" + restore_value: true + initial_value: "true" + - id: aab_add + type: int + initial_value: '10' + - id: aab_max + type: int + initial_value: '220' + - id: aab_min + type: int + initial_value: '20' + external_components: - source: type: git url: https://github.com/lubeda/EspHoMaTriXv2 ref: release refresh: 60s - components: [ ehmtx ] + components: [ ehmtxv2 ] esphome: comment: "EHMTXv2 from LuBeDa" @@ -111,19 +145,17 @@ sensor: filters: - lambda: |- return (x / 10000.0) * 2000000.0 - 15 ; - on_value_range: - - below: 100.0 - then: - lambda: |- - id(rgb8x32)->set_brightness(20); - - below: 250.0 - then: - lambda: |- - id(rgb8x32)->set_brightness(40); - - above: 250.0 - then: - lambda: |- - id(rgb8x32)->set_brightness(80); + on_value: + then: + - lambda: |- + if ( id(aab_enable) ) { + int n = x / 4 + id(aab_add); // new_value + if (n > id(aab_max)) n = id(aab_max); + if (n < id(aab_min)) n = id(aab_min); + int c = id(rgb8x32)->get_brightness(); // current value + int d = (n - c) * 100 / c; // diff in % + if ( abs(d) > 2 ) id(rgb8x32)->set_brightness(n); + } ota: password: !secret ota_password @@ -190,21 +222,14 @@ display: ehmtxv2: id: rgb8x32 - clock_time: 10 - screen_time: 10 - hold_time: 30 icons2html: true - default_font_yoffset: 6 matrix_component: ehmtx_display time_component: ehmtx_time time_format: "%H:%M" date_format: "%d.%m." show_seconds: false default_font_id: default_font - special_font_id: default_font # for starters yust one font - - # used in blueprints - # "error","home_assistant","temperature","lightbulb","music","phone","car","sleep8x32" + special_font_id: default_font icons: - id: error lameid: 40530 diff --git a/images/events.png b/images/events.png new file mode 100644 index 0000000..43bb5f8 Binary files /dev/null and b/images/events.png differ