HASPmota error when page '1' is not defined (#22220)

This commit is contained in:
s-hadinger 2024-09-29 21:58:24 +02:00 committed by GitHub
parent 5d4230d39b
commit 75001a024d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 742 additions and 713 deletions

View File

@ -14,6 +14,7 @@ All notable changes to this project will be documented in this file.
### Fixed ### Fixed
- ESP32 Range Extender compile error with core 3.0.0 (#22205) - ESP32 Range Extender compile error with core 3.0.0 (#22205)
- HASPmota error when page '1' is not defined
### Removed ### Removed

View File

@ -613,11 +613,11 @@ class lvh_obj : lvh_root
lv.EVENT_VALUE_CHANGED: "changed", lv.EVENT_VALUE_CHANGED: "changed",
} }
def register_event_cb() def register_event_cb()
var oh = self._page._oh var hm = self._page._hm
var b = self._EVENTS var b = self._EVENTS
var i = 0 var i = 0
while (i < size(b)) while (i < size(b))
oh.register_event(self, b[i]) hm.register_event(self, b[i])
i += 1 i += 1
end end
end end
@ -626,11 +626,11 @@ class lvh_obj : lvh_root
# the callback avoids doing anything sophisticated in the cb # the callback avoids doing anything sophisticated in the cb
# defer the actual action to the Tasmota event loop # defer the actual action to the Tasmota event loop
# print("-> CB fired","self",self,"obj",obj,"event",event.tomap(),"code",event.code) # print("-> CB fired","self",self,"obj",obj,"event",event.tomap(),"code",event.code)
var oh = self._page._oh # haspmota global object var hm = self._page._hm # haspmota global object
var code = event.get_code() # materialize to a local variable, otherwise the value can change (and don't capture event object) var code = event.get_code() # materialize to a local variable, otherwise the value can change (and don't capture event object)
if self.action != "" && code == lv.EVENT_CLICKED if self.action != "" && code == lv.EVENT_CLICKED
# if clicked and action is declared, do the page change event # if clicked and action is declared, do the page change event
tasmota.set_timer(0, /-> oh.do_action(self, code)) tasmota.set_timer(0, /-> hm.do_action(self, code))
end end
var event_hasp = self._event_map.find(code) var event_hasp = self._event_map.find(code)
@ -1553,7 +1553,7 @@ class lvh_dropdown_list : lvh_obj
def post_init() def post_init()
self._lv_obj = nil # default to nil object, whatever it was initialized with self._lv_obj = nil # default to nil object, whatever it was initialized with
# check if it is the parent is a spangroup # check if it is the parent is a spangroup
if isinstance(self._parent_lvh, self._page._oh.lvh_dropdown) if isinstance(self._parent_lvh, self._page._hm.lvh_dropdown)
self._lv_obj = lv.list(self._parent_lvh._lv_obj.get_list()._p) self._lv_obj = lv.list(self._parent_lvh._lv_obj.get_list()._p)
else else
print("HSP: '_dropdown_list' should have a parent of type 'dropdown'") print("HSP: '_dropdown_list' should have a parent of type 'dropdown'")
@ -1571,7 +1571,7 @@ class lvh_bar : lvh_obj
def post_init() def post_init()
super(self).post_init() super(self).post_init()
if isinstance(self._parent_lvh, self._page._oh.lvh_scale) if isinstance(self._parent_lvh, self._page._hm.lvh_scale)
# if sub-object of scale, copy min and max # if sub-object of scale, copy min and max
var min = self._parent_lvh._lv_obj.get_range_min_value() var min = self._parent_lvh._lv_obj.get_range_min_value()
var max = self._parent_lvh._lv_obj.get_range_max_value() var max = self._parent_lvh._lv_obj.get_range_max_value()
@ -1679,7 +1679,7 @@ class lvh_scale_section : lvh_root
self._min = 0 # default value by LVGL self._min = 0 # default value by LVGL
self._max = 0 # default value by LVGL self._max = 0 # default value by LVGL
# check if it is the parent is a spangroup # check if it is the parent is a spangroup
if isinstance(self._parent_lvh, self._page._oh.lvh_scale) if isinstance(self._parent_lvh, self._page._hm.lvh_scale)
# print(">>> GOOD") # print(">>> GOOD")
self._lv_obj = self._parent_lvh._lv_obj.add_section() self._lv_obj = self._parent_lvh._lv_obj.add_section()
self._style = lv.style() # we create a specific lv.style object for this object self._style = lv.style() # we create a specific lv.style object for this object
@ -1809,7 +1809,7 @@ class lvh_scale_line : lvh_line
def post_init() def post_init()
# check if it is the parent is a spangroup # check if it is the parent is a spangroup
if !isinstance(self._parent_lvh, self._page._oh.lvh_scale) if !isinstance(self._parent_lvh, self._page._hm.lvh_scale)
print("HSP: 'scale_line' should have a parent of type 'scale'") print("HSP: 'scale_line' should have a parent of type 'scale'")
end end
self._needle_length = 0 self._needle_length = 0
@ -1872,7 +1872,7 @@ class lvh_span : lvh_root
def post_init() def post_init()
self._lv_obj = nil # default to nil object, whatever it was initialized with self._lv_obj = nil # default to nil object, whatever it was initialized with
# check if it is the parent is a spangroup # check if it is the parent is a spangroup
if isinstance(self._parent_lvh, self._page._oh.lvh_spangroup) if isinstance(self._parent_lvh, self._page._hm.lvh_spangroup)
# print(">>> GOOD") # print(">>> GOOD")
self._lv_obj = self._parent_lvh._lv_obj.new_span() self._lv_obj = self._parent_lvh._lv_obj.new_span()
self._style = self._lv_obj.get_style() self._style = self._lv_obj.get_style()
@ -2112,7 +2112,7 @@ class lvh_page
var _obj_id # (map) of `lvh_obj` objects by id numbers var _obj_id # (map) of `lvh_obj` objects by id numbers
var _page_id # (int) id number of this page var _page_id # (int) id number of this page
var _lv_scr # (lv_obj) lvgl screen object var _lv_scr # (lv_obj) lvgl screen object
var _oh # HASPmota global object var _hm # HASPmota global object
# haspmota attributes for page are on item `#0` # haspmota attributes for page are on item `#0`
var prev, next, back # (int) id values for `prev`, `next`, `back` buttons var prev, next, back # (int) id values for `prev`, `next`, `back` buttons
@ -2122,12 +2122,12 @@ class lvh_page
# arg1: `page_number` (int) HASPmota page id # arg1: `page_number` (int) HASPmota page id
# defaults to `1` if not specified # defaults to `1` if not specified
# page 0 is special, visible on all pages. Internally uses `layer_top` # page 0 is special, visible on all pages. Internally uses `layer_top`
# arg2: `oh` global HASPmota monad object # arg2: `hm` global HASPmota monad object
# page_number: haspmota page number, defaults to `1` if not specified # page_number: haspmota page number, defaults to `1` if not specified
#==================================================================== #====================================================================
def init(page_number, oh) def init(page_number, hm)
import global import global
self._oh = oh # memorize HASPmota parent object self._hm = hm # memorize HASPmota parent object
# if no parameter, default to page #1 # if no parameter, default to page #1
page_number = int(page_number) page_number = int(page_number)
@ -2139,9 +2139,7 @@ class lvh_page
# initialize the LVGL object for the page # initialize the LVGL object for the page
# uses a lv_scr object except for page 0 where we use layer_top # uses a lv_scr object except for page 0 where we use layer_top
# page 1 is mapped directly to the default screen `scr_act` # page 1 is mapped directly to the default screen `scr_act`
if page_number == 1 if page_number == 0
self._lv_scr = lv.scr_act() # default screen
elif page_number == 0
self._lv_scr = lv.layer_top() # top layer, visible over all screens self._lv_scr = lv.layer_top() # top layer, visible over all screens
else else
self._lv_scr = lv.obj(0) # allocate a new screen self._lv_scr = lv.obj(0) # allocate a new screen
@ -2150,7 +2148,7 @@ class lvh_page
end end
# page object is also stored in the object map at id `0` as instance of `lvg_scr` # page object is also stored in the object map at id `0` as instance of `lvg_scr`
var lvh_scr_class = self._oh.lvh_scr var lvh_scr_class = self._hm.lvh_scr
var obj_scr = lvh_scr_class(nil, self, nil, self._lv_scr) # store screen in a virtual object var obj_scr = lvh_scr_class(nil, self, nil, self._lv_scr) # store screen in a virtual object
self._obj_id[0] = obj_scr self._obj_id[0] = obj_scr
@ -2207,7 +2205,7 @@ class lvh_page
#==================================================================== #====================================================================
# `show` transition from one page to another # `show` transition from one page to another
# duration: in ms, default 500 ms # duration: in ms, default 500 ms
# anim: -1 right to left, 1 left to right (default) # anim: -1 right to left, 1 left to right (default), `nil` auto, 0 none
# #
# show this page, with animation # show this page, with animation
#==================================================================== #====================================================================
@ -2227,25 +2225,29 @@ class lvh_page
if self._lv_scr._p == lv.scr_act()._p return end # do nothing if self._lv_scr._p == lv.scr_act()._p return end # do nothing
# default duration of 500ms # default duration of 500ms
if duration == nil duration = 500 end if (duration == nil) duration = 500 end
# if anim is `nil` try to guess the direction from current screen # if anim is `nil` try to guess the direction from current screen
if anim == nil if anim == nil
anim = self._oh.page_dir_to(self.id()) anim = self._hm.page_dir_to(self.id())
end end
# send page events # send page events
var event_str_in = format('{"hasp":{"p%i":"out"}}', self._oh.lvh_page_cur_idx) var event_str_in = format('{"hasp":{"p%i":"out"}}', self._hm.lvh_page_cur_idx)
tasmota.set_timer(0, /-> tasmota.publish_rule(event_str_in)) tasmota.set_timer(0, /-> tasmota.publish_rule(event_str_in))
var event_str_out = format('{"hasp":{"p%i":"in"}}', self._page_id) var event_str_out = format('{"hasp":{"p%i":"in"}}', self._page_id)
tasmota.set_timer(0, /-> tasmota.publish_rule(event_str_out)) tasmota.set_timer(0, /-> tasmota.publish_rule(event_str_out))
# change current page # change current page
self._oh.lvh_page_cur_idx = self._page_id self._hm.lvh_page_cur_idx = self._page_id
var anim_lvgl = self.show_anim.find(anim, lv.SCR_LOAD_ANIM_NONE) if (anim == 0)
# load new screen with animation, no delay, 500ms transition time, no auto-delete lv.screen_load(self._lv_scr)
lv.screen_load_anim(self._lv_scr, anim_lvgl, duration, 0, false) else # animation
var anim_lvgl = self.show_anim.find(anim, lv.SCR_LOAD_ANIM_NONE)
# load new screen with animation, no delay, 500ms transition time, no auto-delete
lv.screen_load_anim(self._lv_scr, anim_lvgl, duration, 0, false)
end
end end
end end
@ -2403,10 +2405,6 @@ class HASPmota
def _load(templ_name) def _load(templ_name)
import string import string
import json import json
#- pages -#
self.lvh_page_cur_idx = 1
var lvh_page_class = self.lvh_page
self.lvh_pages[1] = lvh_page_class(1, self) # always create page #1
var f = open(templ_name,"r") var f = open(templ_name,"r")
var f_content = f.read() var f_content = f.read()
@ -2426,6 +2424,9 @@ class HASPmota
end end
self.parse_page(jline) # parse page first to create any page related objects, may change self.lvh_page_cur_idx self.parse_page(jline) # parse page first to create any page related objects, may change self.lvh_page_cur_idx
# objects are created in the current page # objects are created in the current page
if (self.lvh_pages == nil)
raise "value_error", "no page 'id' defined"
end
self.parse_obj(jline, self.lvh_pages[self.lvh_page_cur_idx]) # then parse object within this page self.parse_obj(jline, self.lvh_pages[self.lvh_page_cur_idx]) # then parse object within this page
else else
# check if it's invalid json # check if it's invalid json
@ -2439,7 +2440,12 @@ class HASPmota
jsonl = nil # make all of it freeable jsonl = nil # make all of it freeable
# current page is always 1 when we start # current page is always 1 when we start
self.lvh_page_cur_idx = 1 var pages_sorted = self.pages_list_sorted(nil) # nil for full list
if (size(pages_sorted) == 0)
raise "value_error", "no page object defined"
end
self.lvh_page_cur_idx = pages_sorted[0]
self.lvh_pages[self.lvh_page_cur_idx].show(0, 0) # show first page
end end
#==================================================================== #====================================================================
@ -2474,12 +2480,12 @@ class HASPmota
def pages_list_sorted(cur_page) def pages_list_sorted(cur_page)
# get list of pages as sorted array # get list of pages as sorted array
var pages = [] var pages = []
if cur_page == 0 cur_page = self.lvh_page_cur_idx end if (cur_page == 0) cur_page = self.lvh_page_cur_idx end
for p: self.lvh_pages.keys() for p: self.lvh_pages.keys()
if p != 0 pages.push(p) end # discard page 0 if p != 0 pages.push(p) end # discard page 0
end end
pages = self.sort(pages) pages = self.sort(pages)
if cur_page == nil return cur_page end if (cur_page == nil) return pages end
var count_pages = size(pages) # how many pages are defined var count_pages = size(pages) # how many pages are defined
pages = pages + pages # double the list to splice it pages = pages + pages # double the list to splice it
@ -2560,15 +2566,17 @@ class HASPmota
if to_page == nil to_page = sorted_pages_list[1] end # if no next, take the next page if to_page == nil to_page = sorted_pages_list[1] end # if no next, take the next page
elif action == 'back' elif action == 'back'
to_page = int(cur_page.back) to_page = int(cur_page.back)
if to_page == nil to_page = 1 end # if no nack, take page number 1 if to_page == nil # if no back, take first page
to_page = self.pages_list_sorted(nil)[0]
end
elif self.re_page_target.match(action) elif self.re_page_target.match(action)
# action is supposed to be `p<number>` format # action is supposed to be `p<number>` format
to_page = int(action[1..-1]) # just skip first char and convert the rest to a string to_page = int(action[1..-1]) # just skip first char and convert the rest to a string
end end
# print("to_page=",to_page) # print("to_page=",to_page)
if to_page != nil && to_page > 0 # we have a target if to_page != nil && to_page > 0 # we have a target
self.lvh_pages[to_page].show() # switvh to the target page self.lvh_pages[to_page].show() # switch to the target page
end end
end end
@ -2762,8 +2770,8 @@ haspmota.HASPmota = HASPmota
# This means that the object is never garbage collected # This means that the object is never garbage collected
# #
haspmota.init = def (m) # `init(m)` is called during first `import haspmota` haspmota.init = def (m) # `init(m)` is called during first `import haspmota`
var oh = m.HASPmota var hm = m.HASPmota
return oh() return hm()
end end
#@ solidify:haspmota,weak #@ solidify:haspmota,weak