Berry prep for OpenHASP

This commit is contained in:
Stephan Hadinger 2022-04-05 21:38:43 +02:00
parent 66f1b39a89
commit d9cfe6128a
11 changed files with 1060 additions and 782 deletions

View File

@ -308,7 +308,9 @@ bool ZipArchive::parse(void) {
const size_t zip_header_size = sizeof(header) - sizeof(header.padding);
while (1) {
// AddLog(LOG_LEVEL_DEBUG, "ZIP: f->seek(%i)", offset);
f->seek(offset);
// AddLog(LOG_LEVEL_DEBUG, "ZIP: f->read(%i)", zip_header_size);
int32_t bytes_read = f->read(sizeof(header.padding) + (uint8_t*) &header, zip_header_size);
if (bytes_read != zip_header_size) {
break;
@ -348,6 +350,7 @@ bool ZipArchive::parse(void) {
// read full filename
char fname[header.filename_size + 1];
// AddLog(LOG_LEVEL_DEBUG, "ZIP: f->read(%i)", header.filename_size);
if (f->read((uint8_t*) &fname[0], header.filename_size) != header.filename_size) {
return false;
}

View File

@ -65,7 +65,6 @@ extern const bcstring be_const_str_I2C_X3A;
extern const bcstring be_const_str_INTERNAL_DAC;
extern const bcstring be_const_str_INTERNAL_PDM;
extern const bcstring be_const_str_LVG_X3A_X20call_X20to_X20unsupported_X20callback;
extern const bcstring be_const_str_LVG_X3A_X20object_X3A;
extern const bcstring be_const_str_Leds;
extern const bcstring be_const_str_MAX_RMT;
extern const bcstring be_const_str_MD5;
@ -247,6 +246,7 @@ extern const bcstring be_const_str_abs;
extern const bcstring be_const_str_acos;
extern const bcstring be_const_str_add;
extern const bcstring be_const_str_add_anim;
extern const bcstring be_const_str_add_cb_event_closure;
extern const bcstring be_const_str_add_cmd;
extern const bcstring be_const_str_add_cron;
extern const bcstring be_const_str_add_driver;
@ -472,6 +472,7 @@ extern const bcstring be_const_str_get_cb_list;
extern const bcstring be_const_str_get_coords;
extern const bcstring be_const_str_get_current_module_name;
extern const bcstring be_const_str_get_current_module_path;
extern const bcstring be_const_str_get_event_cb;
extern const bcstring be_const_str_get_free_heap;
extern const bcstring be_const_str_get_height;
extern const bcstring be_const_str_get_hor_res;
@ -505,7 +506,6 @@ extern const bcstring be_const_str_group_def;
extern const bcstring be_const_str_groups;
extern const bcstring be_const_str_h;
extern const bcstring be_const_str_has;
extern const bcstring be_const_str_has_X20already_X20an_X20event_X20callback;
extern const bcstring be_const_str_has_arg;
extern const bcstring be_const_str_height_def;
extern const bcstring be_const_str_hex;

View File

@ -139,13 +139,12 @@ be_define_const_str(I2C_Driver, "I2C_Driver", 1714501658u, 0, 10, &be_const_str_
be_define_const_str(INTERNAL_DAC, "INTERNAL_DAC", 1097623719u, 0, 12, &be_const_str_flush);
be_define_const_str(INTERNAL_PDM, "INTERNAL_PDM", 3043685628u, 0, 12, &be_const_str_SERIAL_5E2);
be_define_const_str(LVG_X3A_X20call_X20to_X20unsupported_X20callback, "LVG: call to unsupported callback", 504176819u, 0, 33, &be_const_str_lv_wifi_arcs);
be_define_const_str(LVG_X3A_X20object_X3A, "LVG: object:", 3824079937u, 0, 12, &be_const_str_set_chr);
be_define_const_str(Leds, "Leds", 2709245275u, 0, 4, &be_const_str_read_sensors);
be_define_const_str(MAX_RMT, "MAX_RMT", 1615574873u, 0, 7, NULL);
be_define_const_str(MD5, "MD5", 1935726387u, 0, 3, &be_const_str_create_segment);
be_define_const_str(MI32, "MI32", 4074273414u, 0, 4, &be_const_str_init_draw_line_dsc);
be_define_const_str(None, "None", 810547195u, 0, 4, NULL);
be_define_const_str(OPTION_A, "OPTION_A", 1133299440u, 0, 8, NULL);
be_define_const_str(OPTION_A, "OPTION_A", 1133299440u, 0, 8, &be_const_str_get_event_cb);
be_define_const_str(OneWire, "OneWire", 2298990722u, 0, 7, &be_const_str_set_ldo_voltage);
be_define_const_str(PART_MAIN, "PART_MAIN", 2473491508u, 0, 9, &be_const_str_lv_clock);
be_define_const_str(POST, "POST", 1929554311u, 0, 4, &be_const_str_has);
@ -208,7 +207,7 @@ be_define_const_str(_ccmd, "_ccmd", 2163421413u, 0, 5, &be_const_str_argument_X2
be_define_const_str(_change_buffer, "_change_buffer", 2101848693u, 0, 14, NULL);
be_define_const_str(_class, "_class", 2732146350u, 0, 6, &be_const_str_delete_all_configs);
be_define_const_str(_cmd, "_cmd", 3419822142u, 0, 4, NULL);
be_define_const_str(_crons, "_crons", 1000733579u, 0, 6, &be_const_str_has_X20already_X20an_X20event_X20callback);
be_define_const_str(_crons, "_crons", 1000733579u, 0, 6, &be_const_str_tasmota_X2Eget_light_X28_X29_X20is_X20deprecated_X2C_X20use_X20light_X2Eget_X28_X29);
be_define_const_str(_debug_present, "_debug_present", 4063411725u, 0, 14, &be_const_str_wifi_bars);
be_define_const_str(_def, "_def", 1985022181u, 0, 4, &be_const_str_decode);
be_define_const_str(_dirty, "_dirty", 283846766u, 0, 6, &be_const_str_local);
@ -239,6 +238,7 @@ be_define_const_str(abs, "abs", 709362235u, 0, 3, NULL);
be_define_const_str(acos, "acos", 1006755615u, 0, 4, &be_const_str_pixels_buffer);
be_define_const_str(add, "add", 993596020u, 0, 3, &be_const_str_publish);
be_define_const_str(add_anim, "add_anim", 3980662668u, 0, 8, &be_const_str_get_hor_res);
be_define_const_str(add_cb_event_closure, "add_cb_event_closure", 1775958321u, 0, 20, &be_const_str_split);
be_define_const_str(add_cmd, "add_cmd", 3361630879u, 0, 7, NULL);
be_define_const_str(add_cron, "add_cron", 2475327477u, 0, 8, &be_const_str_content_button);
be_define_const_str(add_driver, "add_driver", 1654458371u, 0, 10, &be_const_str_argument_X20must_X20be_X20a_X20list);
@ -464,6 +464,7 @@ be_define_const_str(get_cb_list, "get_cb_list", 1605319182u, 0, 11, &be_const_st
be_define_const_str(get_coords, "get_coords", 1044089006u, 0, 10, NULL);
be_define_const_str(get_current_module_name, "get_current_module_name", 2379270740u, 0, 23, &be_const_str_param);
be_define_const_str(get_current_module_path, "get_current_module_path", 3206673408u, 0, 23, &be_const_str_set_alternate);
be_define_const_str(get_event_cb, "get_event_cb", 375876088u, 0, 12, NULL);
be_define_const_str(get_free_heap, "get_free_heap", 625069757u, 0, 13, &be_const_str_rule);
be_define_const_str(get_height, "get_height", 3571755523u, 0, 10, &be_const_str_min);
be_define_const_str(get_hor_res, "get_hor_res", 37131144u, 0, 11, &be_const_str_get_vbus_current);
@ -497,7 +498,6 @@ be_define_const_str(group_def, "group_def", 1524213328u, 0, 9, &be_const_str_int
be_define_const_str(groups, "groups", 2943077229u, 0, 6, NULL);
be_define_const_str(h, "h", 3977000791u, 0, 1, NULL);
be_define_const_str(has, "has", 3988721635u, 0, 3, &be_const_str_tolower);
be_define_const_str(has_X20already_X20an_X20event_X20callback, "has already an event callback", 2421565249u, 0, 29, &be_const_str_tasmota_X2Eget_light_X28_X29_X20is_X20deprecated_X2C_X20use_X20light_X2Eget_X28_X29);
be_define_const_str(has_arg, "has_arg", 424878688u, 0, 7, NULL);
be_define_const_str(height_def, "height_def", 2348238838u, 0, 10, NULL);
be_define_const_str(hex, "hex", 4273249610u, 0, 3, NULL);
@ -1013,7 +1013,7 @@ static const bstring* const m_string_table[] = {
(const bstring *)&be_const_str__archive,
(const bstring *)&be_const_str_BRY_X3A_X20failed_X20to_X20load_X20_persist_X2Ejson,
(const bstring *)&be_const_str_SERIAL_7O2,
(const bstring *)&be_const_str_LVG_X3A_X20object_X3A,
(const bstring *)&be_const_str_set_chr,
(const bstring *)&be_const_str_AudioOpusDecoder,
(const bstring *)&be_const_str_solidified,
(const bstring *)&be_const_str_time_str,
@ -1123,7 +1123,7 @@ static const bstring* const m_string_table[] = {
(const bstring *)&be_const_str_zip,
(const bstring *)&be_const_str_widget_destructor,
(const bstring *)&be_const_str_AXP192,
(const bstring *)&be_const_str_split,
(const bstring *)&be_const_str_add_cb_event_closure,
(const bstring *)&be_const_str_SERIAL_6O1,
(const bstring *)&be_const_str_out_X20of_X20range,
(const bstring *)&be_const_str_web_send,

View File

@ -181,10 +181,11 @@ intptr_t be_convert_single_elt(bvm *vm, int idx, const char * arg_type, int *buf
arg_type++; // skip first character
if (be_isclosure(vm, idx)) {
ret = be_find_global_or_module_member(vm, "cb.make_cb");
// ret may 1 if direct function, or 2 if method+instance. 0 indicates an error
if (ret) {
be_pushvalue(vm, idx);
be_pushvalue(vm, 1);
be_pushstring(vm, arg_type);
be_pushvalue(vm, idx); // push function/closure as arg1
be_pushvalue(vm, 1); // push `self` as arg2
be_pushstring(vm, arg_type); // push name of the callback type (string) as arg3
be_call(vm, 2 + ret);
const void * func = be_tocomptr(vm, -(3 + ret));
be_pop(vm, 3 + ret);

File diff suppressed because it is too large Load Diff

View File

@ -5,8 +5,8 @@
class LVGL_glob
# all variables are lazily initialized to reduce the memory pressure. Until they are used, they consume zero memory
var cb_obj # map between a native C pointer (as int) and the corresponding lv.lv_* berry object, also helps marking the objects as non-gc-able
var cb_event_closure # mapping for event closures per LVGL native pointer (int)
var event_cb # native callback for lv.lv_event
var cb_event_closure # mapping for event closures per LVGL native pointer (int). For each int key, contains either a closure or an array with multiple closures
var event_cb # array of native callback for lv.lv_event (when multiple are needed)
var timer_cb # native callback for lv.lv_timer
var event # keep aroud the current lv_event to avoid repeated allocation
@ -14,7 +14,7 @@ class LVGL_glob
var null_cb # cb called if type is not supported
var widget_ctor_cb
var widget_dtor_cb
var widget_event_cb
var widget_event_cb # callback object that calls `widget_event_impl(object, event)`
var widget_struct_default
var widget_struct_by_class
@ -36,25 +36,42 @@ class LVGL_glob
self.cb_obj[obj._p] = obj
end
# get event callback by rank number, expand the list if needed
def get_event_cb(n)
if self.event_cb == nil self.event_cb = [] end # lazy initial initialization
var cb_arr = self.event_cb
for i: size(cb_arr) .. n
var next_cb = cb.gen_cb(/ event_ptr -> self.lvgl_event_dispatch(i, event_ptr))
cb_arr.push(next_cb)
end
return cb_arr[n]
end
def get_object_from_ptr(ptr)
if self.cb_obj != nil
return self.cb_obj.find(ptr) # raise an exception if something is wrong
end
end
def lvgl_event_dispatch(event_ptr_i)
def lvgl_event_dispatch(rank, event_ptr_i)
import introspect
var event_ptr = introspect.toptr(event_ptr_i)
# use always the same instance of lv.lv_event by changing pointer, create a new the first time
if self.event self.event._change_buffer(event_ptr)
else self.event = lv.lv_event(event_ptr)
end
var target = self.event.target
var f = self.cb_event_closure[target]
var obj = self.get_object_from_ptr(target)
#print('>> lvgl_event_dispatch', f, obj, event)
f(obj, self.event)
var target = self.event.target # LVGL native object as target of the event (comptr)
var obj = self.get_object_from_ptr(target) # get the corresponding Berry LVGL object previously recorded as its container
var f = self.cb_event_closure[target] # get the closure or closure list known for this object
if type(f) == 'function' # if only one callback, just use it
f(obj, self.event)
elif rank < size(f) # if more than one, then it's a list - use the closure for `rank`
f[rank](obj, self.event)
end
end
def lvgl_timer_dispatch(timer_int)
@ -63,7 +80,38 @@ class LVGL_glob
var timer_ptr = introspect.toptr(timer_int)
var f = self.cb_event_closure[timer_ptr]
#print('>> lvgl_timer_dispatch', f, obj, event)
f(timer_ptr)
if type(f) == 'function'
f(timer_ptr)
else
# array
var i = 0
while i < size(f)
f[i](timer_ptr)
i += 1
end
end
end
# add a closure `f` to the object `o`
#
# returns: rank of the cb for this object, starting at `0`
def add_cb_event_closure(o, f)
if self.cb_event_closure == nil self.cb_event_closure = {} end # lazy instanciation
if self.cb_event_closure.contains(o)
# contains already a value, create an array if needed
var cur = self.cb_event_closure[o]
if type(cur) == 'function'
self.cb_event_closure[o] = [cur, f]
return 1
else
# should be already an array
self.cb_event_closure[o].push(f)
return size(self.cb_event_closure[o]) - 1
end
else
self.cb_event_closure[o] = f
return 0
end
end
def make_cb(f, obj, name)
@ -71,25 +119,18 @@ class LVGL_glob
# print('>> make_cb', f, name, obj)
# record the object, whatever the callback
if name == "lv_event_cb"
if self.cb_event_closure == nil self.cb_event_closure = {} end # lazy instanciation
if self.event_cb == nil self.event_cb = cb.gen_cb(/ event_ptr -> self.lvgl_event_dispatch(event_ptr)) end # encapsulate 'self' in closure
if name == "lv_event_cb"
self.register_obj(obj) # keep a record of the object to prevent from being gc'ed
if self.cb_event_closure.contains(obj._p)
tasmota.log("LVG: object:" + str(obj) + "has already an event callback", 2)
end
self.cb_event_closure[obj._p] = f # keep a mapping of the closure to call, indexed by internal lvgl native pointer
return self.event_cb
var rank = self.add_cb_event_closure(obj._p, f)
# if self.cb_event_closure.contains(obj._p)
# tasmota.log("LVG: object:" + str(obj) + "has already an event callback", 2)
# end
# self.cb_event_closure[obj._p] = f # keep a mapping of the closure to call, indexed by internal lvgl native pointer
return self.get_event_cb(rank)
elif name == "lv_timer_cb"
if self.cb_event_closure == nil self.cb_event_closure = {} end # lazy instanciation
if self.timer_cb == nil self.timer_cb = cb.gen_cb(/ timer_ptr -> self.lvgl_timer_dispatch(timer_ptr)) end # encapsulate 'self' in closure
# no need to register the object since it's only a pointer to a timer
if self.cb_event_closure.contains(obj._p)
tasmota.log("LVG: object:" + str(obj) + "has already an event callback", 2)
end
self.cb_event_closure[obj._p] = f # keep a mapping of the closure to call, indexed by internal lvgl native pointer
self.add_cb_event_closure(obj._p, f)
return self.timer_cb
# elif name == "<other_cb>"
@ -133,7 +174,6 @@ class LVGL_glob
obj.widget_event(cl, event)
end
end
# print("widget_event_impl", cl, obj_ptr, obj, event)
end

View File

@ -1,4 +1,6 @@
#- start LVGL and init environment -#
import global
lv.start()
hres = lv.get_hor_res() # should be 320
@ -80,28 +82,33 @@ prev_btn.add_event_cb(btn_clicked_cb, lv.EVENT_CLICKED, 0)
next_btn.add_event_cb(btn_clicked_cb, lv.EVENT_CLICKED, 0)
home_btn.add_event_cb(btn_clicked_cb, lv.EVENT_CLICKED, 0)
import lv_wifi_graph
ws_h = 40
ws_w = 80
ws = lv_wifi_graph(scr)
ws.set_size(ws_w,ws_h)
ws.set_pos(hres-ws_w, stat_line.get_height())
tasmota.add_driver(ws)
ws.set_pos(hres-ws_w - 3, stat_line.get_height() + 3)
# info bloc
import lv_tasmota_info
var info = lv_tasmota_info(scr)
info.set_pos(0, stat_line.get_height())
info.set_size(hres - 80 + 1, 40)
tasmota.add_driver(info)
info.set_pos(3, stat_line.get_height()+ 3)
info.set_size(hres - 80 + 1 - 10, 40)
# logs
import lv_tasmota_log_roboto
var lg = lv_tasmota_log_roboto(scr, 6)
lg.set_size(hres, 90)
lg.set_pos(0, stat_line.get_height() + 40 - 1)
tasmota.add_driver(lg)
lg.set_size(hres - 6, 90)
lg.set_pos(3, stat_line.get_height() + 40 + 6)
# 3D cube
var cube
if global.accelerator
import lv_3D_cube_widget
cube = lv_3D_cube_widget(scr, global.accelerator)
cube.set_pos(3,161)
end
#-
sb120 = lv.load_freetype_font("sketchbook.ttf", 120, 0)

View File

@ -26,14 +26,17 @@ class lv_tasmota_info : lv.label
self.msg = "IP: - \nFree: - kB"
self.set_text(self.msg)
self.delay = 1
self.add_event_cb(/->self.before_del(), lv.EVENT_DELETE, 0) # register `before_del` to be called when object is deleted
tasmota.add_driver(self)
end
def update()
var wifi_ip = "IP: " + tasmota.wifi().find('ip', '') + " " + tasmota.eth().find('ip', '')
var wifi_ip = "IP: " + tasmota.wifi().find('ip', '') + " " + tasmota.eth().find('ip', '')
var tas_mem = tasmota.memory()
var mem_msg = "Free: " + str(tas_mem['heap_free']) + " kB"
var mem_msg = "Free: " + str(tas_mem['heap_free']) + " kB"
if tas_mem.contains('psram_free')
mem_msg += " | PSRam: " + str(tas_mem['psram_free']) + " kB"
mem_msg += " PSRam: " + str(tas_mem['psram_free']) + " kB"
end
var msg = wifi_ip + "\n" + mem_msg
@ -51,6 +54,9 @@ class lv_tasmota_info : lv.label
end
end
def before_del()
tasmota.remove_driver(self)
end
end
return lv_tasmota_info

View File

@ -1,12 +1,13 @@
# lv_tasmota_log class
class lv_tasmota_log : lv.label
class lv_tasmota_log : lv.obj
var label # contains the sub lv_label object
var lines
var line_len
var log_reader
var log_level
def init(parent, line_len)
def init(parent)
super(self).init(parent)
self.set_width(parent.get_width())
self.set_pos(0, 0)
@ -19,21 +20,68 @@ class lv_tasmota_log : lv.label
self.set_style_pad_all(2, lv.PART_MAIN | lv.STATE_DEFAULT)
self.set_style_border_color(lv.color(0x0099EE), lv.PART_MAIN | lv.STATE_DEFAULT)
self.set_style_border_width(1, lv.PART_MAIN | lv.STATE_DEFAULT)
self.refr_size()
self.refr_pos()
self.set_style_text_color(lv.color(0x00FF00), lv.PART_MAIN | lv.STATE_DEFAULT)
self.set_long_mode(lv.LABEL_LONG_CLIP)
var lg_font = lv.font_montserrat(10)
self.set_style_text_font(lg_font, lv.PART_MAIN | lv.STATE_DEFAULT)
self.set_text("")
self.label = lv.label(self)
self.label.set_width(self.get_width() - 12)
self.line_len = line_len
self.label.set_style_text_color(lv.color(0x00FF00), lv.PART_MAIN | lv.STATE_DEFAULT)
self.label.set_long_mode(lv.LABEL_LONG_CLIP)
self.label.set_text("") # bug, still displays "Text"
self.add_event_cb( / obj, evt -> self.size_changed_cb(obj, evt), lv.EVENT_SIZE_CHANGED | lv.EVENT_STYLE_CHANGED | lv.EVENT_DELETE, 0)
self.lines = []
self.line_len = 0
self.log_reader = tasmota_log_reader()
self.log_level = 2
self._size_changed()
# fill with empty strings
self.lines = []
for i:1..line_len
self.lines.push("")
tasmota.add_driver(self)
end
def set_lines_count(line_len)
if line_len > self.line_len # increase lines
for i: self.line_len .. line_len-1
self.lines.insert(0, "")
end
elif line_len < self.line_len # decrease lines
for i: line_len .. self.line_len-1
self.lines.remove(0)
end
end
self.line_len = line_len
end
def _size_changed()
# print(">>> lv.EVENT_SIZE_CHANGED")
var pad_hor = self.get_style_pad_left(lv.PART_MAIN | lv.STATE_DEFAULT)
+ self.get_style_pad_right(lv.PART_MAIN | lv.STATE_DEFAULT)
+ self.get_style_border_width(lv.PART_MAIN | lv.STATE_DEFAULT) * 2
+ 3
var pad_ver = self.get_style_pad_top(lv.PART_MAIN | lv.STATE_DEFAULT)
+ self.get_style_pad_bottom(lv.PART_MAIN | lv.STATE_DEFAULT)
+ self.get_style_border_width(lv.PART_MAIN | lv.STATE_DEFAULT) * 2
+ 3
var w = self.get_width() - pad_hor
var h = self.get_height() - pad_ver
self.label.set_size(w, h)
# print("w",w,"h",h,"pad_hor",pad_hor,"pad_ver",pad_ver)
# compute how many lines should be displayed
var h_font = lv.font_get_line_height(self.label.get_style_text_font(0)) # current font's height
var lines_count = ((h * 2 / h_font) + 1 ) / 2
# print("h_font",h_font,"h",h,"lines_count",lines_count)
self.set_lines_count(lines_count)
end
def size_changed_cb(obj, event)
var code = event.code
if code == lv.EVENT_SIZE_CHANGED || code == lv.EVENT_STYLE_CHANGED
self._size_changed()
elif code == lv.EVENT_DELETE
tasmota.remove_driver(self)
end
end
@ -51,14 +99,8 @@ class lv_tasmota_log : lv.label
def update()
var msg = self.lines.concat("\n")
self.set_text(msg)
self.label.set_text(msg)
end
end
return lv_tasmota_log
# import lv_tasmota_log
# var lg = lv_tasmota_log(scr, 8)
# lg.set_size(hres, 95)
# lg.set_pos(0, stat_line.get_height() + 40)
# tasmota.add_driver(lg)

View File

@ -1,12 +1,13 @@
# lv_tasmota_log class
class lv_tasmota_log_roboto : lv.label
class lv_tasmota_log_roboto : lv.obj
var label # contains the sub lv_label object
var lines
var line_len
var log_reader
var log_level
def init(parent, line_len)
def init(parent)
super(self).init(parent)
self.set_width(parent.get_width())
self.set_pos(0, 0)
@ -19,23 +20,71 @@ class lv_tasmota_log_roboto : lv.label
self.set_style_pad_all(2, lv.PART_MAIN | lv.STATE_DEFAULT)
self.set_style_border_color(lv.color(0x0099EE), lv.PART_MAIN | lv.STATE_DEFAULT)
self.set_style_border_width(1, lv.PART_MAIN | lv.STATE_DEFAULT)
self.refr_size()
self.refr_pos()
self.set_style_text_color(lv.color(0x00FF00), lv.PART_MAIN | lv.STATE_DEFAULT)
self.set_long_mode(lv.LABEL_LONG_CLIP)
self.label = lv.label(self)
self.label.set_width(self.get_width() - 12)
self.label.set_style_text_color(lv.color(0x00FF00), lv.PART_MAIN | lv.STATE_DEFAULT)
self.label.set_long_mode(lv.LABEL_LONG_CLIP)
var roboto12 = lv.font_robotocondensed_latin1(12)
self.set_style_text_font(roboto12, lv.PART_MAIN | lv.STATE_DEFAULT)
self.label.set_style_text_font(roboto12, lv.PART_MAIN | lv.STATE_DEFAULT)
# var lg_font = lv.font_montserrat(10)
# self.set_style_text_font(lg_font, lv.PART_MAIN | lv.STATE_DEFAULT)
self.set_text("")
self.label.set_text("") # bug, still displays "Text"
self.line_len = line_len
self.add_event_cb( / obj, evt -> self.size_changed_cb(obj, evt), lv.EVENT_SIZE_CHANGED | lv.EVENT_STYLE_CHANGED | lv.EVENT_DELETE, 0)
self.lines = []
self.line_len = 0
self.log_reader = tasmota_log_reader()
self.log_level = 2
self._size_changed()
# fill with empty strings
self.lines = []
for i:1..line_len
self.lines.push("")
tasmota.add_driver(self)
end
def set_lines_count(line_len)
if line_len > self.line_len # increase lines
for i: self.line_len .. line_len-1
self.lines.insert(0, "")
end
elif line_len < self.line_len # decrease lines
for i: line_len .. self.line_len-1
self.lines.remove(0)
end
end
self.line_len = line_len
end
def _size_changed()
# print(">>> lv.EVENT_SIZE_CHANGED")
var pad_hor = self.get_style_pad_left(lv.PART_MAIN | lv.STATE_DEFAULT)
+ self.get_style_pad_right(lv.PART_MAIN | lv.STATE_DEFAULT)
+ self.get_style_border_width(lv.PART_MAIN | lv.STATE_DEFAULT) * 2
+ 3
var pad_ver = self.get_style_pad_top(lv.PART_MAIN | lv.STATE_DEFAULT)
+ self.get_style_pad_bottom(lv.PART_MAIN | lv.STATE_DEFAULT)
+ self.get_style_border_width(lv.PART_MAIN | lv.STATE_DEFAULT) * 2
+ 3
var w = self.get_width() - pad_hor
var h = self.get_height() - pad_ver
self.label.set_size(w, h)
# compute how many lines should be displayed
var h_font = lv.font_get_line_height(self.label.get_style_text_font(0)) # current font's height
var lines_count = ((h * 2 / h_font) + 1 ) / 2
# print("h_font",h_font,"h",h,"lines_count",lines_count)
self.set_lines_count(lines_count)
end
def size_changed_cb(obj, event)
var code = event.code
if code == lv.EVENT_SIZE_CHANGED || code == lv.EVENT_STYLE_CHANGED
self._size_changed()
elif code == lv.EVENT_DELETE
tasmota.remove_driver(self)
end
end
@ -53,7 +102,7 @@ class lv_tasmota_log_roboto : lv.label
def update()
var msg = self.lines.concat("\n")
self.set_text(msg)
self.label.set_text(msg)
end
end

View File

@ -38,6 +38,9 @@ class lv_wifi_graph : lv.chart
self.wsl.set_align(lv.ALIGN_BOTTOM_MID)
self.delay = 1
self.add_event_cb(/->self.before_del(), lv.EVENT_DELETE, 0) # register `before_del` to be called when object is deleted
tasmota.add_driver(self)
end
def add_wifi_point()
@ -55,6 +58,10 @@ class lv_wifi_graph : lv.chart
self.delay = 2
end
end
def before_del()
tasmota.remove_driver(self)
end
end
return lv_wifi_graph