Open segfly opened 4 months ago
@clydebarrow I've create a proof of concept for the lambda assignment of pages: https://github.com/segfly/esphome-lvgl
Basically, when the lambda:
property is present, it takes the return value and assigns to {page.obj}
struct instead of the generated lv_obj_create
call. This allows a great deal of flexibility for page creation outside of yaml, while still allowing for other parts of the LVGL ESPHome component to interact with the "injected" page.
The only (minor) issues I ran into were with the EEZ Studio generated code, I had to change the default generation templates to specify the right "lvgl.h" path and add a fake method for getFlowState
call, which I think is generated as a bug in their code for LVGL-only projects.
Once that was done, I can now design pages in the EEZ Studio, and then use with the LVGL ESPHome component.
Here is a snippet of what the yaml looks like:
sensor:
- platform: uptime
id: sys_uptime
update_interval: 1s
on_value:
then:
- lambda: lv_label_set_text(objects.label_uptime, std::to_string(static_cast<int>(id(sys_uptime).get_state())).c_str());
button:
- platform:
name: Show Uptime
on_press:
- lvgl.page.show: uptime_page
lvgl:
pages:
- id: welcome_page
widgets:
- label:
align: CENTER
text: "Welcome!"
- id: uptime_page
lambda: |-
create_screen_uptime_page();
return objects.uptime_page;
Thoughts?
Let's tun things around: how about discussing with EEZ project (after this is merged) so they could directly output ESPHome yaml?
A similar thought crossed my mind, but that seems like a huge amount of work. It would be wonderful though, I don't disagree.
I was thinking as a short-term solution, this simple lambda approach provides a lot of flexibility - plus, it theoretically can be used with any other LVGL designer, like SquareLine Studio.
yaml->compile->upload->test
You could use ESPHome host + vnc to speed things up considerably.
Ah interesting. I did not know this existed, probably because it's not documented: https://github.com/esphome/feature-requests/issues/2388#issuecomment-1913045915
It won't make UI design as fast or easy as using a UI designer, but will certainly streamline integration testing, before testing on device. Thanks.
The sdl display driver is even simpler to use than VNC now, and it's merged into ESPHome release.
I'd like to use a LVGL designer like EEZ Studio to generate the more complex pages, widgets, etc. and use the yaml syntax for the simpler stuff like simple pages/widgets, event handling, setup, etc.
Do you have any suggestions on how one might inject code within the generated pages and widgets blocks? Lambdas don't appear to be supported right now.
I've gotten pretty far by adding the generated code from EEZ Studio to the esphome
includes:
yaml. EEZ generates simple methods for each of the screens and child components (e.g.create_screen_main()
) that registers a handle to a globalobjects
struct.Here is an example of an EEZ Studio generated create function:
Using an empty page/widgets block:
The LVGL component generates the following:
If I could just replace or later reassign
test_page->page = lv_obj_create(nullptr);
I think I could use most of the generate code from EEZ Studio. The problem, is I can't find a good way to inject the code:Placing this in a
on_boot:
lambda injects the code way too early insetup()
. And trying to put it inon_loop:
seems to be too late to have an effect.It would be nice if I could do something like this for "external" pages/widgets along with yaml-only delcared pages/widgets:
And so on for the other LVGL types.
But I could be looking at this all the wrong way... Do you have a better idea on how to streamline the UI design process using this esphome component? While it's great to do simple stuff, the yaml->compile->upload->test cycle is very slow - lots trial/error and waiting?