arendst / Tasmota

Alternative firmware for ESP8266 and ESP32 based devices with easy configuration using webUI, OTA updates, automation using timers or rules, expandability and entirely local control over MQTT, HTTP, Serial or KNX. Full documentation at
https://tasmota.github.io/docs
GNU General Public License v3.0
21.98k stars 4.77k forks source link

Berry LVGL Image button set_src fails if IMGBTN_STATE_RELEASED not used #20350

Closed ukoda closed 8 months ago

ukoda commented 8 months ago

PROBLEM DESCRIPTION

The image button set_src function only works if the first argument is lv.IMGBTN_STATE_RELEASED. If lv.IMGBTN_STATE_PRESSED, lv.IMGBTN_STATE_CHECKED_PRESSED or lv.IMGBTN_STATE_CHECKED_RELEASED is used it will fail with incomplete screen render. After a while the Berry console becomes available and shows the error message "BRY: failed to run compiled code 'type_error' - Unexpected argument type 'i', expected 'lv.lv_imgbtn_state'".

Code snippet, full code at end of this post:

ui_Main_ImgButton = lv.imgbtn(ui_StatePanel)
ui_Main_ImgButton.set_src(lv.IMGBTN_STATE_RELEASED, nil, "A:/sleeping113x80.png", nil)          # Renders without error
# These three all fail with error:
# BRY: failed to run compiled code 'type_error' - Unexpected argument type 'i', expected 'lv.lv_imgbtn_state'
ui_Main_ImgButton.set_src(lv.IMGBTN_STATE_PRESSED, nil, "A:/campfire113x80.png", nil)           # Fails
ui_Main_ImgButton.set_src(lv.IMGBTN_STATE_CHECKED_PRESSED, nil, "A:/sleeping113x80.png", nil)   # Fails
ui_Main_ImgButton.set_src(lv.IMGBTN_STATE_CHECKED_RELEASED, nil, "A:/campfire113x80.png", nil)  # Fails
ui_Main_ImgButton.set_width(113)
ui_Main_ImgButton.set_height(80)
ui_Main_ImgButton.set_align(lv.ALIGN_CENTER)

My code is an attempted port of an existing native C app I created and currently in use. My objective is to retain the existing functionality while bringing in the advantages Tasmota offers.

NB: The existing C code is just using the image button as a status image that is toggled using the checkbox state. It was the easy way to to do things with the prior environment. I realise there is probably other, better, ways to do this but figure this issue will hit someone else as the Berry LVGL support sees wider use and therefore worth reporting rather than simply trying to working around.

I am aware of issue 11784. I have searched the Tasmota source code and it would appear IMGBTN_STATE_PRESSED etc are present and do not appear to be treated differently from IMGBTN_STATE_RELEASED. In parallel with waiting for feedback on this issue I will dig deeper to try and understand how Berry works in this case.

REQUESTED INFORMATION

Make sure your have performed every step and checked the applicable boxes before submitting your issue. Thank you!

- [N] If using rules, provide the output of this command: `Backlog Rule1; Rule2; Rule3`:
```lua
  Rules output here:
- [N] Set `weblog` to 4 and then, when you experience your issue, provide the output of the Console log:
```lua
  Console output here:

TO REPRODUCE

  1. Transfer a suitable display.ini file for you display. Mine is 240x320 landscape mode.
  2. Transfer the attached image files.
  3. Transfer the autoexec.be file, below, after screenshots section.
  4. Restart the device. campfire113x80 DarkBlueArrow RedArrow sleeping113x80

EXPECTED BEHAVIOUR

The screen should be fully render, as shown below, and no error message on the Berry console.

SCREENSHOTS

This what it should look like if rendering completes: TasmotaBerryLVGL_Ok

ADDITIONAL CONTEXT

Full code:

#-----------------------------------------------------------------------------

  EMA Panel Heater

-----------------------------------------------------------------------------#

# Start LVGL and init environment

lv.start()
lv.OBJ_FLAG_SCROLLABLE = false
scr = lv.scr_act()
scr.set_style_bg_color(lv.color(0x000000), lv.PART_MAIN | lv.STATE_DEFAULT)
var lg_font = lv.font_montserrat(28)

# Mode panel

ui_ModePanel = lv.obj(scr)
ui_ModePanel.set_width(130)
ui_ModePanel.set_height(220)
ui_ModePanel.set_x(10)
ui_ModePanel.set_y(0)
ui_ModePanel.set_align(lv.ALIGN_LEFT_MID)
#ui_ModePanel.OBJ_FLAG_SCROLLABLE = false
ui_ModePanel.set_style_bg_color(lv.color(0x000000), lv.PART_MAIN | lv.STATE_DEFAULT)
ui_ModePanel.set_style_text_color(lv.color(0xFFFFFF), lv.PART_MAIN | lv.STATE_DEFAULT)
ui_ModePanel.set_style_border_color(lv.color(0x787676), lv.PART_MAIN | lv.STATE_DEFAULT)
ui_ModePanel.set_style_border_opa(255, lv.PART_MAIN | lv.STATE_DEFAULT)

ui_RemoteButton = lv.btn(ui_ModePanel)
ui_RemoteButton.set_width(100)
ui_RemoteButton.set_height(50)
ui_RemoteButton.set_x(0)
ui_RemoteButton.set_y(-68)
ui_RemoteButton.set_align(lv.ALIGN_CENTER)
#add_flag(lv.OBJ_FLAG_SCROLL_ON_FOCUS)
#clear_flag(lv.OBJ_FLAG_SCROLLABLE)
ui_RemoteButton.set_style_outline_color(lv.color_hex(0xFFFEFE), lv.STATE_USER_1)
ui_RemoteButton.set_style_outline_opa(255, lv.STATE_USER_1)
ui_RemoteButton.set_style_outline_width(2, lv.STATE_USER_1)
ui_RemoteButton.set_style_outline_pad(2, lv.STATE_USER_1)

ui_RemoteButtonLabel = lv.label(ui_RemoteButton)
ui_RemoteButtonLabel.set_width(lv.SIZE_CONTENT)
ui_RemoteButtonLabel.set_height(lv.SIZE_CONTENT)
ui_RemoteButtonLabel.set_align(lv.ALIGN_CENTER)
ui_RemoteButtonLabel.set_text("Remote")

ui_OnButton = lv.btn(ui_ModePanel)
ui_OnButton.set_width(100)
ui_OnButton.set_height(50)
ui_OnButton.set_align(lv.ALIGN_CENTER)
#ui_OnButton.add_flag(lv.OBJ_FLAG_SCROLL_ON_FOCUS)
#ui_OnButton.clear_flag(lv.OBJ_FLAG_SCROLLABLE)
ui_OnButton.set_style_outline_width(2, lv.PART_MAIN | lv.STATE_DEFAULT)
ui_OnButton.set_style_outline_pad(2, lv.PART_MAIN | lv.STATE_DEFAULT)
ui_OnButton.set_style_text_color(lv.color_hex(0xFFFFFF), lv.PART_MAIN | lv.STATE_DEFAULT)
ui_OnButton.set_style_text_opa(255, lv.PART_MAIN | lv.STATE_DEFAULT)
ui_OnButton.set_style_outline_color(lv.color_hex(0xFFFEFE), lv.STATE_USER_1)
ui_OnButton.set_style_outline_opa(255, lv.STATE_USER_1)
ui_OnButton.set_style_outline_width(2, lv.STATE_USER_1)
ui_OnButton.set_style_outline_pad(2, lv.STATE_USER_1)

ui_OnButtonLabel = lv.label(ui_OnButton)
ui_OnButtonLabel.set_width(lv.SIZE_CONTENT)
ui_OnButtonLabel.set_height(lv.SIZE_CONTENT)
ui_OnButtonLabel.set_align(lv.ALIGN_CENTER)
ui_OnButtonLabel.set_text("On")

ui_OffButton = lv.btn(ui_ModePanel)
ui_OffButton.set_width(100)
ui_OffButton.set_height(50)
ui_OffButton.set_x(0)
ui_OffButton.set_y(68)
ui_OffButton.set_align(lv.ALIGN_CENTER)
#ui_OffButton.add_flag(lv.OBJ_FLAG_SCROLL_ON_FOCUS)
#ui_OffButton.clear_flag(lv.OBJ_FLAG_SCROLLABLE)
ui_OffButton.set_style_text_color(lv.color_hex(0xFFFFFF), lv.PART_MAIN | lv.STATE_DEFAULT)
ui_OffButton.set_style_text_opa(255, lv.PART_MAIN | lv.STATE_DEFAULT)
ui_OffButton.set_style_outline_color(lv.color_hex(0xFFFEFE), lv.STATE_USER_1)
ui_OffButton.set_style_outline_opa(255, lv.STATE_USER_1)
ui_OffButton.set_style_outline_width(2, lv.STATE_USER_1)
ui_OffButton.set_style_outline_pad(2, lv.STATE_USER_1)

ui_OffButtonLabel = lv.label(ui_OffButton)
ui_OffButtonLabel.set_width(lv.SIZE_CONTENT)
ui_OffButtonLabel.set_height(lv.SIZE_CONTENT)
ui_OffButtonLabel.set_align(lv.ALIGN_CENTER)
ui_OffButtonLabel.set_text("Off")

# Status panel

ui_StatePanel = lv.obj(scr)
ui_StatePanel.set_width(160)
ui_StatePanel.set_height(105)
ui_StatePanel.set_x(-10)
ui_StatePanel.set_y(10)
ui_StatePanel.set_align(lv.ALIGN_TOP_RIGHT)
#ui_StatePanel.clear_flag(lv.OBJ_FLAG_SCROLLABLE)
ui_StatePanel.set_style_bg_color(lv.color(0x000000), lv.PART_MAIN | lv.STATE_DEFAULT)
ui_StatePanel.set_style_border_color(lv.color_hex(0x787676), lv.PART_MAIN | lv.STATE_DEFAULT)
ui_StatePanel.set_style_border_opa(255, lv.PART_MAIN | lv.STATE_DEFAULT)

ui_Main_ImgButton = lv.imgbtn(ui_StatePanel)
ui_Main_ImgButton.set_src(lv.IMGBTN_STATE_RELEASED, nil, "A:/sleeping113x80.png", nil)          # Renders without error
# These three all fail with error:
# BRY: failed to run compiled code 'type_error' - Unexpected argument type 'i', expected 'lv.lv_imgbtn_state'
ui_Main_ImgButton.set_src(lv.IMGBTN_STATE_PRESSED, nil, "A:/campfire113x80.png", nil)           # Fails
ui_Main_ImgButton.set_src(lv.IMGBTN_STATE_CHECKED_PRESSED, nil, "A:/sleeping113x80.png", nil)   # Fails
ui_Main_ImgButton.set_src(lv.IMGBTN_STATE_CHECKED_RELEASED, nil, "A:/campfire113x80.png", nil)  # Fails
ui_Main_ImgButton.set_width(113)
ui_Main_ImgButton.set_height(80)
ui_Main_ImgButton.set_align(lv.ALIGN_CENTER)

# Temperature panel

ui_TemperaturePanel = lv.obj(scr)
ui_TemperaturePanel.set_width(160)
ui_TemperaturePanel.set_height(105)
ui_TemperaturePanel.set_x(-10)
ui_TemperaturePanel.set_y(-10)
ui_TemperaturePanel.set_align(lv.ALIGN_BOTTOM_RIGHT)
#ui_TemperaturePanel.OBJ_FLAG_SCROLLABLE = false
ui_TemperaturePanel.set_style_bg_color(lv.color(0x000000), lv.PART_MAIN | lv.STATE_DEFAULT)
ui_TemperaturePanel.set_style_text_color(lv.color(0xFFFFFF), lv.PART_MAIN | lv.STATE_DEFAULT)
ui_TemperaturePanel.set_style_border_color(lv.color(0x787676), lv.PART_MAIN | lv.STATE_DEFAULT)
ui_TemperaturePanel.set_style_border_opa(255, lv.PART_MAIN | lv.STATE_DEFAULT)

ui_SetLabel = lv.label(ui_TemperaturePanel)
ui_SetLabel.set_width(50)
ui_SetLabel.set_height(lv.SIZE_CONTENT)
ui_SetLabel.set_align(lv.ALIGN_BOTTOM_LEFT)
ui_SetLabel.set_text("Set")
ui_SetLabel.set_style_text_align(lv.TEXT_ALIGN_CENTER, lv.PART_MAIN | lv.STATE_DEFAULT)

ui_RoomLabel = lv.label(ui_TemperaturePanel)
ui_RoomLabel.set_width(50)
ui_RoomLabel.set_height(lv.SIZE_CONTENT)
ui_RoomLabel.set_align(lv.ALIGN_BOTTOM_RIGHT)
ui_RoomLabel.set_text("Room")
ui_RoomLabel.set_style_text_align(lv.TEXT_ALIGN_CENTER, lv.PART_MAIN | lv.STATE_DEFAULT)

ui_TempUpButton = lv.imgbtn(ui_TemperaturePanel)
ui_TempUpButton.set_src(lv.IMGBTN_STATE_RELEASED, nil, "A:/RedArrow.png", nil)
ui_TempUpButton.set_width(20)
ui_TempUpButton.set_height(20)
ui_TempUpButton.set_align(lv.ALIGN_TOP_MID)

ui_TempDownButton = lv.imgbtn(ui_TemperaturePanel)
ui_TempDownButton.set_src(lv.IMGBTN_STATE_RELEASED, nil, "A:/DarkBlueArrow.png", nil)
ui_TempDownButton.set_width(20)
ui_TempDownButton.set_height(20)
ui_TempDownButton.set_align(lv.ALIGN_BOTTOM_MID)

ui_SetValueLabel = lv.label(ui_TemperaturePanel)
ui_SetValueLabel.set_width(50)
ui_SetValueLabel.set_height(40)
ui_SetValueLabel.set_x(0)
ui_SetValueLabel.set_y(5)
ui_SetValueLabel.set_text("25")
ui_SetValueLabel.set_style_text_align(lv.TEXT_ALIGN_CENTER, lv.PART_MAIN | lv.STATE_DEFAULT)
ui_SetValueLabel.set_style_text_font(lg_font, lv.PART_MAIN | lv.STATE_DEFAULT)

ui_RoomValueLabel = lv.label(ui_TemperaturePanel)
ui_RoomValueLabel.set_width(50)
ui_RoomValueLabel.set_height(40)
ui_RoomValueLabel.set_x(0)
ui_RoomValueLabel.set_y(5)
ui_RoomValueLabel.set_align(lv.ALIGN_TOP_RIGHT)
ui_RoomValueLabel.set_text("20")
ui_RoomValueLabel.set_style_text_align(lv.TEXT_ALIGN_CENTER, lv.PART_MAIN | lv.STATE_DEFAULT)
ui_RoomValueLabel.set_style_text_font(lg_font, lv.PART_MAIN | lv.STATE_DEFAULT)

(Please, remember to close the issue when the problem has been addressed)

s-hadinger commented 8 months ago

Oops, you are right. The type mapping from lv_imgbtn_state_t to int was missed. It is now fixed in the latest development release #20354.

Thanks for reporting.

And nice display !!!

ukoda commented 8 months ago

I can confirm that has resolved my issue. EMA and I thank you for the prompt fix :-)

ukoda commented 8 months ago

@s-hadinger a similar bug may exist with the clear_flag function which works with lv.OBJ_FLAG_HIDDEN but fails with lv.OBJ_FLAG_SCROLLABLE. It gives the error "BRY: failed to run compiled code 'type_error' - Unexpected argument type 'b', expected 'i'".

It is time for bed now so I will do more digging tomorrow and look to create a new issue if needed.

s-hadinger commented 8 months ago

This is because you put lv.OBJ_FLAG_SCROLLABLE = false at the beginning of the script. You just masked the actual value of lv.OBJ_FLAG_SCROLLABLE which is 16