Giter Site home page Giter Site logo

clydebarrow / esphome Goto Github PK

View Code? Open in Web Editor NEW

This project forked from esphome/esphome

11.0 11.0 9.0 27.56 MB

ESPHome is a system to control your ESP8266/ESP32 by simple yet powerful configuration files and control them remotely through Home Automation systems.

Home Page: https://esphome.io/

License: Other

Shell 0.07% C++ 69.69% Python 30.02% C 0.15% Groovy 0.01% Dockerfile 0.06%

esphome's People

Contributors

agners avatar anonym-tsk avatar ayufan avatar balloob avatar bdraco avatar buxtronix avatar carlosgs avatar clydebarrow avatar dependabot[bot] avatar dudanov avatar edwardtfn avatar fabian-schmidt avatar frenck avatar glmnet avatar guillempages avatar heman avatar jesserockz avatar kahrendt avatar kbx81 avatar kpfleming avatar martgras avatar mmakaay avatar nielsnl68 avatar ottowinter avatar oxan avatar paulmonigatti avatar puuu avatar robomagus avatar senexcrenshaw avatar ssieb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

esphome's Issues

Allow sensor and number ids in values

Templatable values in LVGL allow the use of an ID of a Sensor (for float values) or BinarySensor (for booleans.)

This should be extended to include Number and Switch. This will probably require the Number and Sensor classes e.g. to inherit a common class that exposes the state.

Value in `x` for other triggers

We need the value of the widget in variable x for a couple of other triggers too, like on_release, on_click, on_defocus.
The most prominent case is the use of slider and arc for adjustments which need only target values, and not intermediate values.

For example this:

        - slider:
            ...
            on_value:
              - logger.log:
                  format: "Value on_value: %.0f"
                  args: [ 'x' ]

dragged from min to max, results in:

[D][main:881]: Value on_value: 1
[D][main:881]: Value on_value: 2
[D][main:881]: Value on_value: 3
[D][main:881]: Value on_value: 7
[D][main:881]: Value on_value: 15
[D][main:881]: Value on_value: 21
[D][main:881]: Value on_value: 28
[D][main:881]: Value on_value: 32
[D][main:881]: Value on_value: 47
[D][main:881]: Value on_value: 53
[D][main:881]: Value on_value: 57
[D][main:881]: Value on_value: 67
[D][main:881]: Value on_value: 73
[D][main:881]: Value on_value: 78
[D][main:881]: Value on_value: 83
[D][main:881]: Value on_value: 86
[D][main:881]: Value on_value: 93
[D][main:881]: Value on_value: 98
[D][main:881]: Value on_value: 99
[D][main:881]: Value on_value: 100

Which means that on_value is being triggered this often. Which is very good for adjusting the volume of a media player which immediately jumps the volume level to the specified value.

Not sure about a dimmable light, because if the transition time of the light from one value to the other is longer than the time between these triggers, something nasty may happen unless the transition is cancelled when the next command comes in. Maybe this is already handled on the light side.

But if we want to adjust for example a window cover like a roller-shutter which is actuated by a motor and is implemented with a time-based cover platform, that is surely going to go nuts with relays ticking all around and likely break the whole thing.

Also if used as a thermostat control, a more complex heating device like a heatpump wouldn't really reward it if you'd repeatedly set a new target temperature as often as a 10 times per second...

For such cases we need on_release which is trigggered only once at the end, with the new value of the slider, which represents the target value where the component should go by itself (dimmer with its own transition speed, or motorized cover by its own mechanical features).

If it's easier to just add it to all the triggers, I don't think it would be redundant.

`state` options templatable

To implement like this:

        - btn:
            checkable: true
            id: button_light
            state:
              checked: !lambda |-
                return id(ha_light_binary_sensor).state;

instead of tedious on_state/on_click automations at the binary sensor...

Default font setting

Currently it seems the default font is globally hardcoded to montserrat_14. Although a different font can be set individually at the widgets or in theme/style defs, it would be nice if it would simply be possible to override the global default for the widgets not using any of these.

Perhaps at lvgl root level something like default_text_font.

Reason: lvgl default font only supports ASCII.

`anim_time` style option

Bar and Arc, but also Roller use the anim_time style option.
Especially for Roller is important: When the Roller is scrolled and doesn't stop exactly on an option it will scroll to the nearest valid option automatically in anim_time milliseconds as specified in the style.

Built-in fonts

Compiling .pioenvs/esp32-test-lvgl-host/src/main.o
<unicode string>: In function ‘void setup()’:
<unicode string>:2204:62: error: ‘montserrat_8’ was not declared in this scope
*** [.pioenvs/esp32-test-lvgl-host/src/main.o] Error 1

and

Compiling .pioenvs/esp32-test-lvgl-host/src/main.o
<unicode string>: In function ‘void setup()’:
<unicode string>:2204:62: error: ‘montserrat_10’ was not declared in this scope
*** [.pioenvs/esp32-test-lvgl-host/src/main.o] Error 1

and

Compiling .pioenvs/esp32-test-lvgl-host/src/main.o
<unicode string>: In function ‘void setup()’:
<unicode string>:2204:62: error: ‘simsun_16_cjk’ was not declared in this scope
*** [.pioenvs/esp32-test-lvgl-host/src/main.o] Error 1

although they are compiled:

Compiling .pioenvs/esp32-test-lvgl-host/lib09a/lvgl/font/lv_font.o
Compiling .pioenvs/esp32-test-lvgl-host/lib09a/lvgl/font/lv_font_dejavu_16_persian_hebrew.o
Compiling .pioenvs/esp32-test-lvgl-host/lib09a/lvgl/font/lv_font_fmt_txt.o
Compiling .pioenvs/esp32-test-lvgl-host/lib09a/lvgl/font/lv_font_loader.o
Compiling .pioenvs/esp32-test-lvgl-host/lib09a/lvgl/font/lv_font_montserrat_10.o
Compiling .pioenvs/esp32-test-lvgl-host/lib09a/lvgl/font/lv_font_montserrat_12.o
Compiling .pioenvs/esp32-test-lvgl-host/lib09a/lvgl/font/lv_font_montserrat_12_subpx.o
Compiling .pioenvs/esp32-test-lvgl-host/lib09a/lvgl/font/lv_font_montserrat_14.o
Compiling .pioenvs/esp32-test-lvgl-host/lib09a/lvgl/font/lv_font_montserrat_16.o
Compiling .pioenvs/esp32-test-lvgl-host/lib09a/lvgl/font/lv_font_montserrat_18.o
Compiling .pioenvs/esp32-test-lvgl-host/lib09a/lvgl/font/lv_font_montserrat_20.o
Compiling .pioenvs/esp32-test-lvgl-host/lib09a/lvgl/font/lv_font_montserrat_22.o
Compiling .pioenvs/esp32-test-lvgl-host/lib09a/lvgl/font/lv_font_montserrat_24.o
Compiling .pioenvs/esp32-test-lvgl-host/lib09a/lvgl/font/lv_font_montserrat_26.o
Compiling .pioenvs/esp32-test-lvgl-host/lib09a/lvgl/font/lv_font_montserrat_28.o
Compiling .pioenvs/esp32-test-lvgl-host/lib09a/lvgl/font/lv_font_montserrat_28_compressed.o
Compiling .pioenvs/esp32-test-lvgl-host/lib09a/lvgl/font/lv_font_montserrat_30.o
Compiling .pioenvs/esp32-test-lvgl-host/lib09a/lvgl/font/lv_font_montserrat_32.o
Compiling .pioenvs/esp32-test-lvgl-host/lib09a/lvgl/font/lv_font_montserrat_34.o
Compiling .pioenvs/esp32-test-lvgl-host/lib09a/lvgl/font/lv_font_montserrat_36.o
Compiling .pioenvs/esp32-test-lvgl-host/lib09a/lvgl/font/lv_font_montserrat_38.o
Compiling .pioenvs/esp32-test-lvgl-host/lib09a/lvgl/font/lv_font_montserrat_40.o
Compiling .pioenvs/esp32-test-lvgl-host/lib09a/lvgl/font/lv_font_montserrat_42.o
Compiling .pioenvs/esp32-test-lvgl-host/lib09a/lvgl/font/lv_font_montserrat_44.o
Compiling .pioenvs/esp32-test-lvgl-host/lib09a/lvgl/font/lv_font_montserrat_46.o
Compiling .pioenvs/esp32-test-lvgl-host/lib09a/lvgl/font/lv_font_montserrat_48.o
Compiling .pioenvs/esp32-test-lvgl-host/lib09a/lvgl/font/lv_font_montserrat_8.o
Compiling .pioenvs/esp32-test-lvgl-host/lib09a/lvgl/font/lv_font_simsun_16_cjk.o
Compiling .pioenvs/esp32-test-lvgl-host/lib09a/lvgl/font/lv_font_unscii_16.o
Compiling .pioenvs/esp32-test-lvgl-host/lib09a/lvgl/font/lv_font_unscii_8.o

Not sure what fmt_txt and loader fonts are, but they are compiled, would probably worth to try and see.


with text_font: montserrat_28_compressed labels are empty, and the LVGL logs this:

[I][lvgl:000]: [Warn]   (397413.594, +0)         lv_font_get_bitmap_fmt_txt: Compressed fonts is used but LV_USE_FONT_COMPRESSED is not enabled in lv_conf.h  (in lv_font_fmt_txt.c line #131)
[I][lvgl:000]: [Warn]   (397413.594, +0)         lv_draw_sw_letter: lv_draw_letter: character's bitmap not found        (in lv_draw_sw_letter.c line #145)

with text_font: montserrat_12_subpx labels are empty, and the LVGL logs this:

[I][lvgl:000]: [Warn]   (397578.880, +0)         lv_draw_sw_letter: Can't draw sub-pixel rendered letter because LV_USE_FONT_SUBPX == 0 in lv_conf.h    (in lv_draw_sw_letter.c line #153)

Click area extension option (for all obj)

There's the lv_obj_set_ext_click_size function, which is very useful in case of narrow widgets like slider or arc, where you can loose the touch while dragging if you don't follow the widget precisely with your finger.

In OpenHASP it's implemented as a common property for any object as:
ext_click_h Extended horizontal clickable are on the left and right
ext_click_v Extended vertical clickable are on the top and bottom
which are 0 by default, positive integers.

`lvgl.widget.update` for `btnmatrix`

butmat_szell is a btnmatrix widget.
I'd like to apply disabled state styles for the entire matrix:

- lvgl.widget.disable: buttons_szell
or

           - lvgl.widget.update:
               id: butmat_szell
               state:
                 disabled: true

causes error:

config/_02_host_lvgl_5_demos.yaml: In lambda function:
config/_02_host_lvgl_5_demos.yaml:105:26: error: cannot convert ‘esphome::lvgl::LvBtnmatrixType*’ to ‘lv_obj_t*’ {aka ‘_lv_obj_t*’}
In file included from .piolibdeps/esp32-test-lvgl-host/lvgl/lvgl.h:35,
                 from src/esphome/components/lvgl/lvgl_esphome.h:31,
                 from src/esphome.h:54,
                 from src/main.cpp:3:
.piolibdeps/esp32-test-lvgl-host/lvgl/src/core/lv_obj.h:261:36: note:   initializing argument 1 of ‘void lv_obj_clear_state(lv_obj_t*, lv_state_t)’
  261 | void lv_obj_clear_state(lv_obj_t * obj, lv_state_t state);
      |                         ~~~~~~~~~~~^~~
config/_02_host_lvgl_5_demos.yaml: In lambda function:
config/_02_host_lvgl_5_demos.yaml:142:24: error: cannot convert ‘esphome::lvgl::LvBtnmatrixType*’ to ‘lv_obj_t*’ {aka ‘_lv_obj_t*’}
.piolibdeps/esp32-test-lvgl-host/lvgl/src/core/lv_obj.h:253:34: note:   initializing argument 1 of ‘void lv_obj_add_state(lv_obj_t*, lv_state_t)’
  253 | void lv_obj_add_state(lv_obj_t * obj, lv_state_t state);
      |                       ~~~~~~~~~~~^~~
*** [.pioenvs/esp32-test-lvgl-host/src/main.o] Error 1

Having

               state:
                 disabled: true

in btnmatrix's config doesnt have any effect.

Tried with

              - lvgl.widget.update:
                  id: butmat_szell
                  items:
                    state:
                      disabled: true

but that results in
[items] is an invalid option for [lvgl.widget.update]. Please check the indentation.

`page` `y` property not respected

Not sure if page should respect y property in LVGL, the goal would be to shift it down by an amount of pixels so the children widgets could start at 0.
Not a big deal, but setting is accepted (though not respected) at page configuration, but if i add it to theme:

  theme:
    page:
      y: 30 #shift down all pages by 30px, to make room for the header

spits

<unicode string>: In lambda function:
<unicode string>:2327:26: error: no match for call to '(const LvLambdaType {aka const std::function<void(_lv_obj_t*)>}) (esphome::lvgl::LvPageType*&)'
In file included from /root/.platformio/packages/toolchain-xtensa-esp32/xtensa-esp32-elf/include/c++/11.2.0/functional:59,
                 from /root/.platformio/packages/toolchain-xtensa-esp32/xtensa-esp32-elf/include/c++/11.2.0/pstl/glue_algorithm_defs.h:13,
                 from /root/.platformio/packages/toolchain-xtensa-esp32/xtensa-esp32-elf/include/c++/11.2.0/algorithm:74,
                 from src/esphome/core/optional.h:19,
                 from src/esphome/components/socket/socket.h:5,
                 from src/esphome/components/api/api_frame_helper.h:14,
                 from src/esphome/components/api/api_connection.h:3,
                 from src/esphome.h:3,
                 from src/main.cpp:3:
/root/.platformio/packages/toolchain-xtensa-esp32/xtensa-esp32-elf/include/c++/11.2.0/bits/std_function.h:556:7: note: candidate: '_Res std::function<_Res(_ArgTypes ...)>::operator()(_ArgTypes ...) const [with _Res = void; _ArgTypes = {_lv_obj_t*}]'
  556 |       operator()(_ArgTypes... __args) const
      |       ^~~~~~~~
/root/.platformio/packages/toolchain-xtensa-esp32/xtensa-esp32-elf/include/c++/11.2.0/bits/std_function.h:556:27: note:   no known conversion for argument 1 from 'esphome::lvgl::LvPageType*' to '_lv_obj_t*'
  556 |       operator()(_ArgTypes... __args) const
      |                  ~~~~~~~~~^~~~~~~~~~
....

`led` light component enhancement

Set light's gamma_correct to default to 0 in our case, instead of ESPHome's default 2.8 for the lights. A virtual light on a graphical display doesn't need any gamma correction - the brightness adjustment has to be linear.

`binary_sensor` should reflect `checked` state + `publish_initial_state` config

With btn and btnmatrix, binary_sensor only activates while clicking. If the button has checkable: true set, the state should remain TRUE while checked.

Also, publish_initial_state option of binary_sensor is not respected. It defaults to true (which is good) but can't be overridden from config to false. This is important for cases when one doesn't care about the looks, but rather wouldn't want to have automations depending on this to run at boot.

`select` obj

select:

  • platform: lvgl
    name: LVGL Select
    dropdown: dropdown_id

should be obj instead of dropdown

Validate part use on a widget

Currently any known part name can be used in a style for any widget. The yaml validation should reject the use of a part that a given widget does not implement.

Make `color` configurations coherent

In ESPHome's color config, we can specify colors with hex: FF0000.
Here we can also specify colors in hexa, like border_color: 0x2F8CD8.

Would be nice if it wouldn't be required to put that 0x in front of the RGB color code.

Actions

I find it that there are too many actions registered to change some specific properties.

There's the powerful
lvgl.obj.update
action to change properties/styles/states/flags of the widget main parts:

      - lvgl.obj.update:
          id: day_label
          bg_color: 0x00FF00
          state:
            disabled: false

And there are actions like
lvgl.checkbox.update
lvgl.label.update
lvgl.arc.update
lvgl.roller.update
to change properties/styles/states/flags of certain widget's subparts.

      - lvgl.label.update:
          id: day_label
          text: "Something"

Or even
lvgl.indicator.line.update
to change properties/styles/states/flags of certain widget's parts of the subparts.

      - lvgl.indicator.line.update:
          id: minute_hand
          value: 10

Are these intended to be like shorthands?

Wouldn't it make sense to structure everything under lvgl.obj.update (moreover, something simpler like lvgl.update) and nest the subparts hierarchically?

like:

      - lvgl.update:
          id: minute_hand
          line_color: 0x00FF00
          state:
            disabled: false
          indicator:  #could only be specifict to what the widget supports, eg. knob etc.
            value: 10

or

      - lvgl.update:
          id: day_label
          bg_color: 0x00FF00
          state:
            disabled: false
          text: "Something"  #additional widget-specific options just added at the same level as the main ones

These would:

  • make the understandability easier
  • update properties of main and subparts in one go instead multiple subsequent actions
  • less code to maintain...

`obj` propagate down `state` property to children

Often using an obj to group together widgets with similar properties.

It seems like state property for obj is not propagated down to the children. I'd like to change the disabled state for all the children at runtime (eg. disable widget interaction while not connected to HA).

`meter` needle/line styling

According to this: https://docs.lvgl.io/8.3/widgets/extra/meter.html#parts-and-styles

LV_PART_INDICATOR The needle line or image using the line and img style properties, as well as the background properties to draw a square (or circle) on the pivot of the needles. Padding makes the square larger.

Trying to set the needle to be hidden but config is not accepted:

        - meter:
            align: center
            scales:
              - ticks:
                  width: 1
                  count: 81
                  length: 5
                  color: 0x000000
                  major:
                    stride: 10
                    width: 2
                    length: 8
                    color: 0xC0C0C0
                    label_gap: 8
                range_from: -30
                range_to: 50
                angle_range: 240
                rotation: 150
                indicators:
                  - line:
                      id: temperature_needle
                      width: 2
                      color: 0xFF0000
                      r_mod: -4
                  hidden: true #not accepted
                    hidden: true #not accepted
                      hidden: true #not accepted

Also I wonder what action could be used to set needle properties at runtime? lvgl.indicator.line.update or lvgl.widget.update are not suitable atm.

Use case: hide the needle when value coming from HA is invalid (aka. nan unknown unavailable). This is usually the case when the node boots but HA is not yet connected, when HA reboots and disconnects, or there's a network problem. A few automations handling these cases would hide the needle to avoid displaying invalid data. Would start with the needle in hidden state and when the first valid value comes in, show it with an action.

If hidden can't work, line_width: 0 could do it (tried, same). Or maybe delete/create if possible.

Extra widgets suggestion

Don't know if you plan to add all the widgets but I'd suggest these:

  • lv_animimg, compared to simple image only difference is that instead of one source image, you set an array of multiple source images. A flashing status icon, or battery charging for example.
  • lv_colorwheel, a color picker to set colors for lights.
  • lv_keyboard, enter Wi-Fi credentials 😄
  • lv_led, simple indicator for something ON or OFF
  • lv_menu, menus are popular in ESPHome, there's one for lcd displays so here is a must I guess
  • lv_spinbox, this is mandatory for thermostats
  • lv_spinner, I use this for my fan spinning speed visualisation, rotation speed can be customized
  • qrcode, for generation of QR Codes at runtime

Not sure about

  • lv_msgbox
  • lv_win
    These should be called with some actions...

`arc` Place another object to the knob

This is a real kickass feature: https://docs.lvgl.io/8.3/widgets/core/arc.html#place-another-object-to-the-knob
See the Simple Arc example at the bottom of the page.

Névtelen

Should be feasible with a choice from two config options:

    - arc:
        x: 10
        y: 10
        id: arc_id
        value: 75
        min_value: 1
        max_value: 100
        adjustable: true
        align_obj_to_angle:  # this or the other
          obj_to_align: id_of_the_other_object
          radius_offset: distance_wanted_from_the_arc
        rotate_obj_to_angle:
          obj_to_rotate: id_of_the_other_object
          radius_offset: distance_wanted_from_the_arc

`layout` option

Currently

            "layout": {
              "key": "Optional",
              "type": "enum",
              "values": {
                "FLEX": null,
                "GRID": null
              }

Suggestion, add "NONE", with default to "NONE".

suggestion to rename 'obj' to 'widget'

In the LVGL component you already have named button's and labels etc widgets.

But everywhere else you address them as obj's, my suggestion is to name them globally "widgets"

`publish_initial_value` - for sensors

publish_initial_value (as some other platforms implement) - to control whether the value is published upon start of ESPHome. By default, the value is only published when it changes, causing an “unknown” value at first. If the user would set this option to true in config, the value would published once after boot and when it changes.

Or maybe just simply always do that by default.

`lvgl.obj.update` shorthands

A few properties/flags deserve shortcuts to simplify automation writing:

lvgl.obj.hide: obj_id and lvgl.obj.show: obj_id shorthand to hide/show the widget (sets the hidden flag)
lvgl.obj.disable: obj_id and lvgl.obj.enable: obj_id shorthand to apply/remove the disabled styles of the widget (sets the disabled state)

`on_value` for more widgets

We need on_value for widgets supporting checkable: true, (btn, checkbox, switch etc) to make automations easier when the LV_EVENT_VALUE_CHANGED happens.

For examle here we have a checkable button with a label on it, and we want to show a differently coloured symbol based on the button's checked state.

If on_value could return a binary value x in checked state, this would be easy to accomplish in the same yaml section, without having to rely on binary sensors etc.

        - btn:
            checkable: true
            id: btn_toggle_swicth
            widgets:
              - label:
                  id: lbl_btn_apa_lampa
                  align: center
                  text_color: 0xFFFFFF
                  symbol: CLOSE
            on_value:
              then:
                if:
                  condition:
                    lambda: return x;
                  then:
                    - lvgl.label.update:
                        id: lbl_btn
                        symbol: OK
                        text_color: 0xFFFF00
                    - homeassistant.service:
                        service: light.turn_on
                        data: 
                          entity_id: light.to_be_toggled
                  else:
                    - lvgl.label.update:
                        id: lbl_btn
                        symbol: CLOSE
                        text_color: 0xFFFFFF
                    - homeassistant.service:
                        service: light.turn_off
                        data: 
                          entity_id: light.to_be_toggled

dropdown roller and btnmatrix could benefit from on_value if it would return the index x and the name n of the selected option after the LV_EVENT_VALUE_CHANGED occured.

        - dropdown:
            x: 80
            y: 180
            width: 105
            id: dropdown_id
            options:
              - Dry food
              - Wet food
              - Semi-moist
            on_value:
              - logger.log:
                  format: "Value index is: %.0f, name is %s"
                  args: [ 'x', 'n.c_str()' ]
              - homeassistant.service:
                  service: select.select_option
                  data:
                    entity_id: select.cat_feeder
                    option: !lambda return (n.c_str());

We also need the name in a variable n as string because HA's select.select_option only offers selecting options by name, not index. ESPHome's select locally supports index too, LVGL supports only index when updating the widget so it would be nice to have both in the trigger.

Escape characters in texts, eg. `label`

label supports multiline texts: https://docs.lvgl.io/8.3/widgets/core/label.html#newline
\n should start a new line. Currently:

        - label:
            align: center
            id: lbl_id
            y: 30
            recolor: true
            text: 'Write a #ff0000 red# word\nand a #0000ff blue# one'

produces:
kép
looks like \n is interpreted textually, not being escaped.

Other escape sequences like \u, \U should be supported on long term...

Also LVGL supports formatting with printf which is also ESPHome-friendly: https://docs.lvgl.io/8.3/widgets/core/label.html#set-text this could be usable when updating labels from lambdas.

Maybe some configurable options would be needed? Like escape_chars: true and use_printf: true?

`number` component

The number component have an animated option...?

I think number could support bar and spinbox widgets and indicators of meter.

Also restore_value could be very useful when used only locally and not in conjunction with HA.

VNC tweaks

There seems to be a bug in the host which prevents re-connection after disconnection. Nothing is printed in the log, but client complains "Failed to receive data from socket." If I close the client, and try to connect back again.


My vnc client has clipboard synchronisation, and it looks like that the implemented VNC client supports it. See Received cut buffer:

[D][vnc:294]: Accepted x.x.x.x
[D][vnc:650]: Read RFB 003.003
 as version
[I][vnc:666]: Client requested authentication 1
[D][vnc:563]: Read 11 encoding types
[D][vnc:623]: Received cut buffer My vnc client has clipboard syncronization
[D][vnc:623]: Received cut buffer  and it looks like that the implemented VNC client supports it. 

[W][vnc:632]: Unknown command 97
[W][vnc:632]: Unknown command 99

However it's of little use here so I'd suggest to disbale it. Seems like certain copied texts are interpreted as commands which may lead to potential issues.

Selecting `dropdown` `roller` `btnmatrix` items by item name

There is:

    - lvgl.dropdown.update:
        id: dropdown_id
        selected_index: 3

which is good if we know the index number.

The corresponding HA integrations which could be used with these widgets use states which show not the index, but the name of the currently selected option.

We need a shortcut/wrapper for the action above which could be able to resolve the index from the name, something like:

    - lvgl.dropdown.select:
        id: dropdown_id
        item_name: Bassoon

Use case: with a text sensor we can retrieve the current state name from HA, and with the just call lvgl.**.select with item_name parameter to select the item with the same name.

Use ESPHome font generator

The fonts created by the ESPHome font component are close to what LVGL needs, but don't currently work.

Some changes to the font generator will be needed to make this happen.

`msgboxes` options

I think we need a specific action here, like lvgl.msgbox.show with parameters to specify at least the displayed message/title.
Also some on_value to return which button was pressed...

Recolor could be enabled by default for body (no need for a config option, just enable it permanently) and for button texts if possible.

@nielsnl68's implementation is a bit different: #12 (comment) and I think it's not bad at all. The power in it is that it returns the answer to the same context where it was triggered from.

Map ESPHome images to LVGL images

ESPHome images are stored as a data block, with an Image object constructed at run time. It should be easy to derive an LVGL lv_img_dsc_t from it, though it would be nicer to just init the lv_img_dsc_t as a const object. This could be done by refactoring the image component to expose internal stuff.

`image` required even if not in config

In file included from src/esphome.h:60,
                 from src/main.cpp:3:
src/esphome/components/lvgl/lvgl_esphome.h:8:10: fatal error: esphome/components/image/image.h: No such file or directory
    8 | #include "esphome/components/image/image.h"
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
*** [.pioenvs/esp32-test-lvgl/src/main.o] Error 1

Have to add a dummy image to get rid of this.

Pagination implementation

Based on https://docs.lvgl.io/8.3/overview/object.html#screens

pages: element

inspired from select concept, or pages.

idea:

pages_loop: true # wrap around to the first/last when doing next/previous
pages:  
  - page:
    master: true # the "master" page is a layer shown above all the other pages. 
    skip: false #skip this screen when doing next/previous (templatable)
    id: ...
    widgets:
      - ...

The master page is to hold eg. status widgets or navigation buttons which would always be visible regardless of active page, this would save us from duplicating them on/for every screen with automations etc. Only one master page is allowed!

Pages with skip option set could only be displayed with a dedicated lvgl.page.show, they don't show with next and previous actions. Use case is a boot logo, we would show such a skipped page on_boot, and after a delay show a default home page. Another use case is an advanced settings page , which could be shown with a button, and having a Back button on it to return to the page where it was triggered from.

actions:

lvgl.page.show
lvgl.page.next
lvgl.page.previous
lvgl.page.back # when jumping around, say, from a hidden page, which was shown with a button trigger

conditions:
lvgl.is_displaying_page

trigger:
lvgl.on_page_change

Remote images

Consider reviewing esphome#4710 or implement something similar:

Two use cases here:

  • display the coverart of a song, which can be retrieved from an attribute of a HA media player (accessible via http)*
  • display a weather panel, without storing all the possible weather icons in flash (share them from HA's www directory via http)

*: http://ha_address:8123{{ state_attr('media_player.your_room','entity_picture') HA template serves the cover art picture, aka. http://ha_address:8123/api/media_player_proxy/media_player.your_room?token=XXX...

`lvgl.widget.update` for btnmatrix buttons

How to update btnmatrix button properties/styles?

              - lvgl.widget.update: 
                  
                  ID 'cov_1_up' of type lvgl::LvBtnmBtn doesn't inherit from LvObjType. Please double check your ID is pointing to the correct value.
                  id: cov_1_up

Event triggers

A thought on events from:
https://docs.lvgl.io/8.3/overview/event.html

A universal on_event trigger could be implemented with a parameter type which can be chosen from an enum of LVGL events.
A few shorthands could be implemented for most popular events:

on_press-> LV_EVENT_PRESSED
on_release-> LV_EVENT_RELEASED
on_click-> LV_EVENT_SHORT_CLICKED
on_long_press-> LV_EVENT_LONG_PRESSED

on_value-> LV_EVENT_VALUE_CHANGED, returning the value in x (slider has been moved to value x, switch/btn toggled)
on_gesture-> LV_EVENT_GESTURE, returning the gesture (eg. swipe direction)

Populating/Updating `dropdown` `roller` `btnmatrix` items at runtime (after HA connected)

Use cases:

  • display light's effect_list attribute
  • media player's source_list and sound_mode_list
  • any select options import from HA

Items for dropdown roller and btnmatrix are natively added to the widgets with a string where \n is the delimiter.

For example importing the sound_mode_list attribute of media_player.my_room into an ESPHome text sensor with filters:

text_sensor:
  - platform: homeassistant
    name: "Media Player sound modes"
    id: mplaymodes
    entity_id: media_player.my_room
    attribute: sound_mode_list
    filters:
      - substitute:
        - "', '-> \\n"
        - "[ -> "
        - "] -> "
        - "' -> "

results in:
Classic\nJazz\nNormal\nPop\nVocal
which can be used to directly populate a dropdown roller or a btnmatrix with these items.

Suggestion for dropdown roller and btnmatrix would be to have a config option like text_items which could accept strings like above mutually exclusive with buttons >text or symbol sub-options. The other styling options could still be possible per item.

With lvgl.widget.update this could be updated at runtime.

Also in pair with #40

Use case for the example above is with on_value the user could call a HA service to choose the desired sound mode (we need the selected item name in a variable, see #49 (comment))

`lvgl.widget.update` - templatable parameters

Would simplify automations a bit if this would be possible:

    on_state:
      - lvgl.widget.update:
          id: btn_relay_1
          hidden: !lambda "return x;"
          state:
            checked: !lambda "return x;"

This option is not templatable.

Also it would be good if we had on_state for the LVGL switch/etc...

`display_id` option

            "display_id": {
              "key": "Required",
              "is_list": true,
              "type": "schema",
              "maybe": "display_id",
              "schema": {
                "config_vars": {
                  "display_id": {
                    "key": "Required",
                    "use_id_type": "display::Display",
                    "type": "use_id"
                  }
                }
              }
            },

requires config like:

  display_id:
    - display_id: vnc_display
    - display_id: tft_display

It would look better like

  displays:
    - display_id: vnc_display
    - display_id: tft_display

But also, if the node has only one display configured, use it by default and this whole config item could be omitted - thus optional.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.