Last active
October 25, 2025 14:54
-
-
Save Staars/eed65a443970dfcc18f8063b8f753e77 to your computer and use it in GitHub Desktop.
gather some ideas
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class LVGLBenchmark | |
| var scr, hres, vres | |
| var test_running, current_test, frame_count, start_time, test_duration | |
| var status_label, test_objects, results, anim_counter, anim_loop | |
| var font_small, font_normal, font_large | |
| var header_height, result_line_height | |
| var is_small_screen, is_large_screen, scale_factor | |
| def init() | |
| lv.start() | |
| self.hres = lv.get_hor_res() | |
| self.vres = lv.get_ver_res() | |
| self.detect_screen_size() | |
| self.setup_fonts() | |
| self.test_running = false | |
| self.current_test = 0 | |
| self.frame_count = 0 | |
| self.test_duration = 3000 | |
| self.test_objects = [] | |
| self.results = {} | |
| self.anim_counter = 0 | |
| self.anim_loop = /->self.loop() | |
| self.show_start_screen() | |
| print(f"LVGL Benchmark ready - {self.hres}x{self.vres}") | |
| end | |
| def detect_screen_size() | |
| var pixels = self.hres * self.vres | |
| if pixels <= 320 * 480 | |
| self.is_small_screen = true | |
| self.is_large_screen = false | |
| self.header_height = 35 | |
| self.result_line_height = 16 | |
| self.scale_factor = 1.0 | |
| elif pixels >= 800 * 480 | |
| self.is_small_screen = false | |
| self.is_large_screen = true | |
| self.header_height = 60 | |
| self.result_line_height = 24 | |
| self.scale_factor = 2.0 | |
| else | |
| self.is_small_screen = false | |
| self.is_large_screen = false | |
| self.header_height = 45 | |
| self.result_line_height = 20 | |
| self.scale_factor = 1.5 | |
| end | |
| end | |
| def setup_fonts() | |
| if self.is_small_screen | |
| self.font_small = lv.montserrat_font(10) | |
| self.font_normal = lv.montserrat_font(14) | |
| self.font_large = lv.montserrat_font(14) | |
| elif self.is_large_screen | |
| self.font_small = lv.montserrat_font(14) | |
| self.font_normal = lv.montserrat_font(20) | |
| self.font_large = lv.montserrat_font(28) | |
| else | |
| self.font_small = lv.montserrat_font(10) | |
| self.font_normal = lv.montserrat_font(14) | |
| self.font_large = lv.montserrat_font(20) | |
| end | |
| end | |
| def show_start_screen() | |
| self.scr = lv.scr_act() | |
| self.scr.set_style_bg_color(lv.color(0x202020), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| self.scr.clean() | |
| var title = lv.label(self.scr) | |
| title.set_text("LVGL Benchmark") | |
| title.set_pos(10, 10) | |
| title.set_style_text_color(lv.color(0xFFFFFF), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| if self.font_large != nil title.set_style_text_font(self.font_large, lv.PART_MAIN | lv.STATE_DEFAULT) end | |
| var info = lv.label(self.scr) | |
| var info_text = "14 Tests x 3 sec" | |
| if !self.is_small_screen | |
| info_text = "14 Tests x 3 seconds\nWeighted scoring" | |
| end | |
| info.set_text(info_text) | |
| info.set_pos(10, 10 + int(self.header_height * 0.7)) | |
| info.set_style_text_color(lv.color(0xAAAAAA), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| if self.font_small != nil info.set_style_text_font(self.font_small, lv.PART_MAIN | lv.STATE_DEFAULT) end | |
| var device_info = lv.label(self.scr) | |
| device_info.set_text(f"{self.hres}x{self.vres}") | |
| device_info.set_pos(10, 10 + int(self.header_height * 1.3)) | |
| device_info.set_style_text_color(lv.color(0x666666), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| if self.font_small != nil device_info.set_style_text_font(self.font_small, lv.PART_MAIN | lv.STATE_DEFAULT) end | |
| var btn_w = int(120 * self.scale_factor) | |
| var btn_h = int(50 * self.scale_factor) | |
| var start_btn = lv.btn(self.scr) | |
| start_btn.set_size(btn_w, btn_h) | |
| start_btn.set_pos(int(self.hres / 2) - int(btn_w / 2), int(self.vres / 2)) | |
| start_btn.set_style_bg_color(lv.color(0x00AA00), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| var btn_label = lv.label(start_btn) | |
| btn_label.set_text("START") | |
| if self.font_normal != nil btn_label.set_style_text_font(self.font_normal, lv.PART_MAIN | lv.STATE_DEFAULT) end | |
| btn_label.center() | |
| start_btn.add_event_cb(/obj, evt -> self.start_benchmark(), lv.EVENT_CLICKED, 0) | |
| end | |
| def scaled(base_size) | |
| return int(base_size * self.scale_factor) | |
| end | |
| def calc_grid(item_width, item_height) | |
| var content_w = self.hres - 20 | |
| var content_h = self.vres - self.header_height - 10 | |
| var cols = int(content_w / item_width) | |
| var rows = int(content_h / item_height) | |
| if cols < 1 cols = 1 end | |
| if rows < 1 rows = 1 end | |
| return [cols, rows] | |
| end | |
| def start_benchmark() | |
| print("\n=== Benchmark Started ===") | |
| self.results = {} | |
| self.current_test = 1 | |
| tasmota.add_fast_loop(self.anim_loop) | |
| self.start_next_test() | |
| end | |
| def start_next_test() | |
| if self.current_test > 14 | |
| self.show_results() | |
| return | |
| end | |
| self.test_running = true | |
| self.frame_count = 0 | |
| self.start_time = tasmota.millis() | |
| self.anim_counter = 0 | |
| self.scr.clean() | |
| self.scr.set_style_bg_color(lv.color(0xE0E0E0), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| self.status_label = lv.label(self.scr) | |
| self.status_label.set_pos(10, 10) | |
| self.status_label.set_style_text_color(lv.color(0x000000), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| if self.font_small != nil self.status_label.set_style_text_font(self.font_small, lv.PART_MAIN | lv.STATE_DEFAULT) end | |
| self.test_objects = [] | |
| if self.current_test == 1 | |
| self.status_label.set_text("Test 1/13: Empty Screen") | |
| self.test_empty_screen() | |
| elif self.current_test == 2 | |
| self.status_label.set_text("Test 2/13: Single Rectangle") | |
| self.test_single_rectangle() | |
| elif self.current_test == 3 | |
| self.status_label.set_text("Test 3/13: Multiple Rectangles") | |
| self.test_multiple_rectangles() | |
| elif self.current_test == 4 | |
| self.status_label.set_text("Test 4/13: Multiple Images") | |
| self.test_multiple_rgb_images() | |
| elif self.current_test == 5 | |
| self.status_label.set_text("Test 5/13: Rotated Images") | |
| self.test_rotated_images() | |
| elif self.current_test == 6 | |
| self.status_label.set_text("Test 6/13: Multiple Labels") | |
| self.test_multiple_labels() | |
| elif self.current_test == 7 | |
| self.status_label.set_text("Test 7/13: Arcs") | |
| self.test_multiple_arcs() | |
| elif self.current_test == 8 | |
| self.status_label.set_text("Test 8/13: Containers") | |
| self.test_containers() | |
| elif self.current_test == 9 | |
| self.status_label.set_text("Test 9/13: Containers+Opa") | |
| self.test_containers_with_opa() | |
| elif self.current_test == 10 | |
| self.status_label.set_text("Test 10/13: Circles") | |
| self.test_circles() | |
| elif self.current_test == 11 | |
| self.status_label.set_text("Test 11/13: Lines") | |
| self.test_lines() | |
| elif self.current_test == 12 | |
| self.status_label.set_text("Test 12/13: Buttons") | |
| self.test_buttons() | |
| elif self.current_test == 13 | |
| self.status_label.set_text("Test 13/14: Scrolling") | |
| self.test_scrolling() | |
| elif self.current_test == 14 | |
| self.status_label.set_text("Test 14/14: Mixed Complex") | |
| self.test_mixed_complex() | |
| end | |
| end | |
| def test_empty_screen() | |
| end | |
| def test_single_rectangle() | |
| var sz = self.scaled(80) | |
| var rect = lv.obj(self.scr) | |
| rect.remove_style_all() | |
| rect.set_style_bg_opa(255, lv.PART_MAIN | lv.STATE_DEFAULT) | |
| rect.set_size(sz, sz) | |
| rect.center() | |
| self.test_objects.push(rect) | |
| end | |
| def test_multiple_rectangles() | |
| var rect_size = self.scaled(50) | |
| var grid = self.calc_grid(rect_size + 10, rect_size + 10) | |
| var cols = grid[0] | |
| var rows = grid[1] | |
| var row = 0 | |
| while row < rows | |
| var col = 0 | |
| while col < cols | |
| var rect = lv.obj(self.scr) | |
| rect.remove_style_all() | |
| rect.set_style_bg_opa(255, lv.PART_MAIN | lv.STATE_DEFAULT) | |
| rect.set_size(rect_size, rect_size) | |
| rect.set_pos(col * (rect_size + 10) + 10, row * (rect_size + 10) + self.header_height) | |
| rect.set_style_radius(self.scaled(5), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| self.test_objects.push(rect) | |
| col += 1 | |
| end | |
| row += 1 | |
| end | |
| end | |
| def test_multiple_rgb_images() | |
| var grid = self.calc_grid(80, 80) | |
| var cols = grid[0] | |
| var rows = grid[1] | |
| var spacing_x = int(self.hres / cols) | |
| var spacing_y = int((self.vres - self.header_height) / rows) | |
| var row = 0 | |
| while row < rows | |
| var col = 0 | |
| while col < cols | |
| var logo = lv.img(self.scr) | |
| logo.set_tasmota_logo() | |
| var x = col * spacing_x + int(spacing_x / 2) - 32 | |
| var y = row * spacing_y + self.header_height + int(spacing_y / 2) - 32 | |
| logo.set_pos(x, y) | |
| self.test_objects.push(logo) | |
| col += 1 | |
| end | |
| row += 1 | |
| end | |
| end | |
| def test_rotated_images() | |
| var grid = self.calc_grid(100, 100) | |
| var cols = grid[0] | |
| var rows = grid[1] | |
| var spacing_x = int(self.hres / cols) | |
| var spacing_y = int((self.vres - self.header_height) / rows) | |
| var row = 0 | |
| while row < rows | |
| var col = 0 | |
| while col < cols | |
| var logo = lv.img(self.scr) | |
| logo.set_tasmota_logo() | |
| var x = col * spacing_x + int(spacing_x / 2) - 32 | |
| var y = row * spacing_y + self.header_height + int(spacing_y / 2) - 32 | |
| logo.set_pos(x, y) | |
| var angle = ((row * cols + col) * 234) % 3600 | |
| logo.set_style_transform_pivot_x(32, lv.PART_MAIN | lv.STATE_DEFAULT) | |
| logo.set_style_transform_pivot_y(32, lv.PART_MAIN | lv.STATE_DEFAULT) | |
| logo.set_style_transform_rotation(angle, lv.PART_MAIN | lv.STATE_DEFAULT) | |
| self.test_objects.push(logo) | |
| col += 1 | |
| end | |
| row += 1 | |
| end | |
| end | |
| def test_multiple_labels() | |
| var line_height = self.is_small_screen ? 18 : (self.is_large_screen ? 30 : 24) | |
| var grid = self.calc_grid(100, line_height) | |
| var cols = grid[0] | |
| var rows = grid[1] | |
| var row = 0 | |
| while row < rows | |
| var col = 0 | |
| while col < cols | |
| var label = lv.label(self.scr) | |
| label.set_text("Hello LVGL!") | |
| label.set_pos(col * int(self.hres / cols) + 10, row * line_height + self.header_height) | |
| label.set_style_text_color(lv.color(0x000000), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| if self.font_small != nil label.set_style_text_font(self.font_small, lv.PART_MAIN | lv.STATE_DEFAULT) end | |
| self.test_objects.push(label) | |
| col += 1 | |
| end | |
| row += 1 | |
| end | |
| end | |
| def test_multiple_arcs() | |
| var arc_size = self.scaled(60) | |
| var grid = self.calc_grid(arc_size + 20, arc_size + 20) | |
| var cols = grid[0] | |
| var rows = grid[1] | |
| var spacing_x = int(self.hres / cols) | |
| var spacing_y = int((self.vres - self.header_height) / rows) | |
| var row = 0 | |
| while row < rows | |
| var col = 0 | |
| while col < cols | |
| var arc = lv.arc(self.scr) | |
| arc.set_size(arc_size, arc_size) | |
| var x = col * spacing_x + int(spacing_x / 2) - int(arc_size / 2) | |
| var y = row * spacing_y + self.header_height + int(spacing_y / 2) - int(arc_size / 2) | |
| arc.set_pos(x, y) | |
| arc.set_bg_angles(0, 360) | |
| arc.set_style_arc_opa(0, lv.PART_MAIN | lv.STATE_DEFAULT) | |
| arc.set_style_arc_width(self.scaled(5), lv.PART_INDICATOR | lv.STATE_DEFAULT) | |
| var colors = [0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0xFF00FF, 0x00FFFF] | |
| var color_idx = (row * cols + col) % 6 | |
| arc.set_style_arc_color(lv.color(colors[color_idx]), lv.PART_INDICATOR | lv.STATE_DEFAULT) | |
| self.test_objects.push(arc) | |
| col += 1 | |
| end | |
| row += 1 | |
| end | |
| end | |
| def test_containers() | |
| var card_w = self.scaled(135) | |
| var card_h = self.scaled(60) | |
| var grid = self.calc_grid(card_w + 20, card_h + 20) | |
| var cols = grid[0] | |
| var rows = grid[1] | |
| var row = 0 | |
| while row < rows | |
| var col = 0 | |
| while col < cols | |
| var card = self.create_card() | |
| var x = col * int(self.hres / cols) + 10 | |
| var y = row * (card_h + 20) + self.header_height | |
| card.set_pos(x, y) | |
| self.test_objects.push(card) | |
| col += 1 | |
| end | |
| row += 1 | |
| end | |
| end | |
| def test_containers_with_opa() | |
| var card_w = self.scaled(135) | |
| var card_h = self.scaled(60) | |
| var grid = self.calc_grid(card_w + 20, card_h + 20) | |
| var cols = grid[0] | |
| var rows = grid[1] | |
| var row = 0 | |
| while row < rows | |
| var col = 0 | |
| while col < cols | |
| var card = self.create_card() | |
| card.set_style_opa(180, lv.PART_MAIN | lv.STATE_DEFAULT) | |
| var x = col * int(self.hres / cols) + 10 | |
| var y = row * (card_h + 20) + self.header_height | |
| card.set_pos(x, y) | |
| self.test_objects.push(card) | |
| col += 1 | |
| end | |
| row += 1 | |
| end | |
| end | |
| def test_circles() | |
| var base_size = self.scaled(30) | |
| var grid = self.calc_grid(base_size + 30, base_size + 30) | |
| var cols = grid[0] | |
| var rows = grid[1] | |
| var count = 0 | |
| var row = 0 | |
| while row < rows | |
| var col = 0 | |
| while col < cols | |
| var circle = lv.obj(self.scr) | |
| circle.remove_style_all() | |
| circle.set_style_bg_opa(255, lv.PART_MAIN | lv.STATE_DEFAULT) | |
| var sz = base_size + (count * 3) | |
| circle.set_size(sz, sz) | |
| var x = col * int(self.hres / cols) + 20 | |
| var y = row * (base_size + 30) + self.header_height + 10 | |
| circle.set_pos(x, y) | |
| circle.set_style_radius(1000, lv.PART_MAIN | lv.STATE_DEFAULT) | |
| self.test_objects.push(circle) | |
| count += 1 | |
| col += 1 | |
| end | |
| row += 1 | |
| end | |
| end | |
| def test_lines() | |
| var num_lines = self.is_small_screen ? 10 : (self.is_large_screen ? 25 : 15) | |
| var line_width = self.is_small_screen ? 2 : (self.is_large_screen ? 4 : 3) | |
| var i = 0 | |
| var p1 = lv.point() | |
| var p2 = lv.point() | |
| while i < num_lines | |
| var line = lv.line(self.scr) | |
| var spacing = int((self.vres - self.header_height) / num_lines) | |
| p1.x = 0 | |
| p1.y = i * spacing | |
| p2.x = self.hres - 20 | |
| p2.y = (self.vres - self.header_height) - i * spacing | |
| var pt_arr = lv.lv_point_arr([p1, p2]) | |
| line.set_points(pt_arr, 2) | |
| line.set_style_line_width(line_width, lv.PART_MAIN | lv.STATE_DEFAULT) | |
| line.set_style_line_color(lv.color(0x0066CC), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| line.set_pos(10, self.header_height) | |
| self.test_objects.push(line) | |
| i += 1 | |
| end | |
| end | |
| def test_buttons() | |
| var btn_w = self.scaled(60) | |
| var btn_h = self.scaled(30) | |
| var grid = self.calc_grid(btn_w + 15, btn_h + 15) | |
| var cols = grid[0] | |
| var rows = grid[1] | |
| var row = 0 | |
| while row < rows | |
| var col = 0 | |
| while col < cols | |
| var btn = lv.btn(self.scr) | |
| btn.set_size(btn_w, btn_h) | |
| btn.set_pos(col * (btn_w + 15) + 10, row * (btn_h + 15) + self.header_height) | |
| var label = lv.label(btn) | |
| var btn_text = self.is_small_screen ? f"B{row * cols + col + 1}" : f"Btn {row * cols + col + 1}" | |
| label.set_text(btn_text) | |
| if self.font_small != nil label.set_style_text_font(self.font_small, lv.PART_MAIN | lv.STATE_DEFAULT) end | |
| label.center() | |
| self.test_objects.push(btn) | |
| col += 1 | |
| end | |
| row += 1 | |
| end | |
| end | |
| def test_scrolling() | |
| var scroll_cont = lv.obj(self.scr) | |
| scroll_cont.set_size(self.hres - 20, self.vres - self.header_height - 10) | |
| scroll_cont.set_pos(10, self.header_height) | |
| scroll_cont.set_style_bg_color(lv.color(0xFFFFFF), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| scroll_cont.set_style_border_width(0, lv.PART_MAIN | lv.STATE_DEFAULT) | |
| scroll_cont.set_flex_flow(lv.FLEX_FLOW_COLUMN) | |
| scroll_cont.set_style_pad_all(5, lv.PART_MAIN | lv.STATE_DEFAULT) | |
| scroll_cont.set_style_pad_row(5, lv.PART_MAIN | lv.STATE_DEFAULT) | |
| var num_items = self.is_small_screen ? 20 : (self.is_large_screen ? 40 : 30) | |
| var item_h = self.scaled(40) | |
| var i = 0 | |
| while i < num_items | |
| var item = lv.obj(scroll_cont) | |
| item.set_width(lv.pct(100)) | |
| item.set_height(item_h) | |
| item.set_style_bg_color(lv.color(0xE0E0E0), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| item.set_style_radius(self.scaled(3), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| var label = lv.label(item) | |
| label.set_text(f"Item {i + 1}") | |
| label.set_pos(10, int(item_h / 2) - 7) | |
| if self.font_small != nil label.set_style_text_font(self.font_small, lv.PART_MAIN | lv.STATE_DEFAULT) end | |
| i += 1 | |
| end | |
| self.test_objects.push(scroll_cont) | |
| end | |
| def test_mixed_complex() | |
| var base_size = self.scaled(40) | |
| var num_each = self.is_small_screen ? 2 : 3 | |
| var i = 0 | |
| while i < num_each | |
| var rect = lv.obj(self.scr) | |
| rect.remove_style_all() | |
| rect.set_style_bg_opa(255, lv.PART_MAIN | lv.STATE_DEFAULT) | |
| rect.set_size(base_size, base_size) | |
| rect.set_pos(i * (base_size + 15) + 10, self.header_height + 10) | |
| rect.set_style_radius(self.scaled(5), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| self.test_objects.push(rect) | |
| i += 1 | |
| end | |
| i = 0 | |
| while i < num_each | |
| var circle = lv.obj(self.scr) | |
| circle.remove_style_all() | |
| circle.set_style_bg_opa(255, lv.PART_MAIN | lv.STATE_DEFAULT) | |
| circle.set_size(base_size - 5, base_size - 5) | |
| circle.set_pos(i * (base_size + 15) + 10, self.header_height + base_size + 25) | |
| circle.set_style_radius(1000, lv.PART_MAIN | lv.STATE_DEFAULT) | |
| self.test_objects.push(circle) | |
| i += 1 | |
| end | |
| i = 0 | |
| var num_arcs = self.is_small_screen ? 1 : 2 | |
| while i < num_arcs | |
| var arc = lv.arc(self.scr) | |
| var arc_size = self.scaled(50) | |
| arc.set_size(arc_size, arc_size) | |
| arc.set_pos(i * (arc_size + 20) + 10, self.header_height + base_size * 2 + 40) | |
| arc.set_style_arc_width(self.scaled(4), lv.PART_INDICATOR | lv.STATE_DEFAULT) | |
| self.test_objects.push(arc) | |
| i += 1 | |
| end | |
| i = 0 | |
| var num_labels = self.is_small_screen ? 3 : 5 | |
| while i < num_labels | |
| var label = lv.label(self.scr) | |
| label.set_text(f"Text {i + 1}") | |
| var label_x = self.is_large_screen ? int(self.hres / 2) : (self.hres - 100) | |
| label.set_pos(label_x, self.header_height + 10 + i * 20) | |
| if self.font_small != nil label.set_style_text_font(self.font_small, lv.PART_MAIN | lv.STATE_DEFAULT) end | |
| self.test_objects.push(label) | |
| i += 1 | |
| end | |
| end | |
| def create_card() | |
| var card_w = self.scaled(135) | |
| var card_h = self.scaled(60) | |
| var card = lv.obj(self.scr) | |
| card.set_size(card_w, card_h) | |
| card.set_style_bg_color(lv.color(0xFFFFFF), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| card.set_style_radius(self.scaled(4), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| card.set_style_pad_all(self.scaled(4), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| var avatar_size = self.scaled(30) | |
| var avatar = lv.obj(card) | |
| avatar.set_size(avatar_size, avatar_size) | |
| avatar.set_pos(3, int(card_h / 2) - int(avatar_size / 2)) | |
| avatar.set_style_radius(1000, lv.PART_MAIN | lv.STATE_DEFAULT) | |
| avatar.set_style_bg_color(lv.color(0x2196F3), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| var name = lv.label(card) | |
| var name_text = self.is_small_screen ? "J. Smith" : "John Smith" | |
| name.set_text(name_text) | |
| name.set_pos(avatar_size + 8, 5) | |
| if self.font_small != nil name.set_style_text_font(self.font_small, lv.PART_MAIN | lv.STATE_DEFAULT) end | |
| var btn_w = self.scaled(40) | |
| var btn_h = self.scaled(18) | |
| var btn = lv.btn(card) | |
| btn.set_size(btn_w, btn_h) | |
| btn.set_pos(avatar_size + 8, card_h - btn_h - 8) | |
| btn.set_style_bg_color(lv.color(0x4CAF50), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| var btn_label = lv.label(btn) | |
| btn_label.set_text("OK") | |
| btn_label.center() | |
| if self.font_small != nil btn_label.set_style_text_font(self.font_small, lv.PART_MAIN | lv.STATE_DEFAULT) end | |
| return card | |
| end | |
| def animate_objects() | |
| if !self.test_running return end | |
| if self.current_test == 1 | |
| var colors = [0xFF0000, 0xFF3300, 0xFF6600, 0xFF9900, 0xFFCC00, 0xFFFF00, 0xCCFF00, 0x99FF00, 0x66FF00, 0x33FF00, 0x00FF00, 0x00FF33, 0x00FF66, 0x00FF99, 0x00FFCC, 0x00FFFF, 0x00CCFF, 0x0099FF, 0x0066FF, 0x0033FF, 0x0000FF, 0x3300FF, 0x6600FF, 0x9900FF, 0xCC00FF, 0xFF00FF, 0xFF00CC, 0xFF0099, 0xFF0066, 0xFF0033] | |
| var color_idx = (self.anim_counter / 3) % 30 | |
| self.scr.set_style_bg_color(lv.color(colors[color_idx]), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| end | |
| if self.current_test == 2 && size(self.test_objects) > 0 | |
| var obj = self.test_objects[0] | |
| var hue = (self.anim_counter * 6) % 360 | |
| var color_val = hue * 0x010101 | |
| obj.set_style_bg_color(lv.color(color_val), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| end | |
| if self.current_test == 3 | |
| var i = 0 | |
| while i < size(self.test_objects) | |
| var obj = self.test_objects[i] | |
| var offset = (self.anim_counter + i * 10) % 360 | |
| var color_val = offset * 0x010101 | |
| obj.set_style_bg_color(lv.color(color_val), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| i += 1 | |
| end | |
| end | |
| if self.current_test == 4 | |
| var i = 0 | |
| while i < size(self.test_objects) | |
| var logo = self.test_objects[i] | |
| var opa = 128 + int(127 * ((self.anim_counter + i * 20) % 100) / 100.0) | |
| logo.set_style_img_opa(opa, lv.PART_MAIN | lv.STATE_DEFAULT) | |
| i += 1 | |
| end | |
| end | |
| if self.current_test == 5 | |
| var i = 0 | |
| while i < size(self.test_objects) | |
| var logo = self.test_objects[i] | |
| var angle = (self.anim_counter * 10 + i * 100) % 3600 | |
| logo.set_style_transform_rotation(angle, lv.PART_MAIN | lv.STATE_DEFAULT) | |
| i += 1 | |
| end | |
| end | |
| if self.current_test == 6 | |
| var i = 0 | |
| while i < size(self.test_objects) | |
| var label = self.test_objects[i] | |
| var offset = (self.anim_counter + i * 15) % 360 | |
| var color_val = offset * 0x010101 | |
| label.set_style_text_color(lv.color(color_val), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| i += 1 | |
| end | |
| end | |
| if self.current_test == 7 | |
| var i = 0 | |
| while i < size(self.test_objects) | |
| var arc = self.test_objects[i] | |
| var value = ((self.anim_counter + i * 10) % 100) | |
| arc.set_value(value) | |
| i += 1 | |
| end | |
| end | |
| if self.current_test == 8 | |
| var i = 0 | |
| while i < size(self.test_objects) | |
| var card = self.test_objects[i] | |
| var offset = (self.anim_counter + i * 20) % 100 | |
| var brightness = 200 + int(55 * offset / 100.0) | |
| var gray = brightness * 0x010101 | |
| card.set_style_bg_color(lv.color(gray), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| i += 1 | |
| end | |
| end | |
| if self.current_test == 9 | |
| var i = 0 | |
| while i < size(self.test_objects) | |
| var card = self.test_objects[i] | |
| var opa = 100 + int(155 * ((self.anim_counter + i * 15) % 100) / 100.0) | |
| card.set_style_opa(opa, lv.PART_MAIN | lv.STATE_DEFAULT) | |
| i += 1 | |
| end | |
| end | |
| if self.current_test == 10 | |
| var i = 0 | |
| while i < size(self.test_objects) | |
| var circle = self.test_objects[i] | |
| var offset = (self.anim_counter + i * 25) % 360 | |
| var color_val = offset * 0x010101 | |
| circle.set_style_bg_color(lv.color(color_val), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| i += 1 | |
| end | |
| end | |
| if self.current_test == 11 | |
| var i = 0 | |
| while i < size(self.test_objects) | |
| var line = self.test_objects[i] | |
| var offset = (self.anim_counter + i * 30) % 360 | |
| var color_val = offset * 0x010101 | |
| line.set_style_line_color(lv.color(color_val), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| i += 1 | |
| end | |
| end | |
| if self.current_test == 12 | |
| var i = 0 | |
| while i < size(self.test_objects) | |
| var btn = self.test_objects[i] | |
| var offset = (self.anim_counter + i * 20) % 360 | |
| var color_val = offset * 0x010101 | |
| btn.set_style_bg_color(lv.color(color_val), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| i += 1 | |
| end | |
| end | |
| if self.current_test == 13 | |
| var scroll_cont = self.test_objects[0] | |
| var scroll_offset = (self.anim_counter * 2) % (self.vres * 2) | |
| scroll_cont.scroll_to_y(scroll_offset, lv.ANIM_OFF) | |
| end | |
| if self.current_test == 14 | |
| var num_each = self.is_small_screen ? 2 : 3 | |
| var i = 0 | |
| while i < num_each && i < size(self.test_objects) | |
| var obj = self.test_objects[i] | |
| var offset = (self.anim_counter + i * 30) % 360 | |
| var color_val = offset * 0x010101 | |
| obj.set_style_bg_color(lv.color(color_val), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| i += 1 | |
| end | |
| i = 0 | |
| while i < num_each && (num_each + i) < size(self.test_objects) | |
| var circle = self.test_objects[num_each + i] | |
| var offset = (self.anim_counter + i * 40) % 360 | |
| var color_val = offset * 0x010101 | |
| circle.set_style_bg_color(lv.color(color_val), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| i += 1 | |
| end | |
| var arc_start = num_each * 2 | |
| var num_arcs = self.is_small_screen ? 1 : 2 | |
| i = 0 | |
| while i < num_arcs && (arc_start + i) < size(self.test_objects) | |
| var arc = self.test_objects[arc_start + i] | |
| var value = ((self.anim_counter + i * 15) % 100) | |
| arc.set_value(value) | |
| i += 1 | |
| end | |
| var label_start = arc_start + num_arcs | |
| var num_labels = self.is_small_screen ? 3 : 5 | |
| i = 0 | |
| while i < num_labels && (label_start + i) < size(self.test_objects) | |
| var label = self.test_objects[label_start + i] | |
| var offset = (self.anim_counter + i * 25) % 360 | |
| var color_val = offset * 0x010101 | |
| label.set_style_text_color(lv.color(color_val), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| i += 1 | |
| end | |
| end | |
| self.anim_counter += 1 | |
| end | |
| def loop() | |
| if !self.test_running return end | |
| self.frame_count += 1 | |
| self.animate_objects() | |
| var now = tasmota.millis() | |
| var elapsed = now - self.start_time | |
| if elapsed >= self.test_duration | |
| self.end_current_test() | |
| end | |
| end | |
| def end_current_test() | |
| self.test_running = false | |
| var elapsed = tasmota.millis() - self.start_time | |
| var fps = int((self.frame_count * 1000.0) / elapsed) | |
| self.results[f"test{self.current_test}"] = fps | |
| self.current_test += 1 | |
| tasmota.set_timer(500, /-> self.start_next_test()) | |
| end | |
| def get_test_weight(test_num) | |
| if test_num == 2 || test_num == 7 | |
| return 0.25 | |
| end | |
| return 1.0 | |
| end | |
| def show_results() | |
| tasmota.remove_fast_loop(self.anim_loop) | |
| self.scr.clean() | |
| self.scr.set_style_bg_color(lv.color(0x000000), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| var title = lv.label(self.scr) | |
| title.set_text("Benchmark Results") | |
| title.set_pos(10, 5) | |
| title.set_style_text_color(lv.color(0xFFFFFF), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| if self.font_normal != nil title.set_style_text_font(self.font_normal, lv.PART_MAIN | lv.STATE_DEFAULT) end | |
| var info = lv.label(self.scr) | |
| info.set_text(f"{self.hres}x{self.vres}") | |
| info.set_pos(10, 5 + int(self.result_line_height * 1.2)) | |
| info.set_style_text_color(lv.color(0x888888), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| if self.font_small != nil info.set_style_text_font(self.font_small, lv.PART_MAIN | lv.STATE_DEFAULT) end | |
| var y = 5 + int(self.result_line_height * 2.5) | |
| var tests = ["Empty", "Single", "Rects", "Images", "Rotated", "Labels", "Arcs", "Cards", "Card+Opa", "Circles", "Lines", "Buttons", "Scroll", "Mixed"] | |
| var weighted_sum = 0.0 | |
| var weight_total = 0.0 | |
| var i = 1 | |
| while i <= 14 | |
| var test_name = tests[i - 1] | |
| var fps = self.results[f"test{i}"] | |
| var weight = self.get_test_weight(i) | |
| weighted_sum += fps * weight | |
| weight_total += weight | |
| var result = lv.label(self.scr) | |
| var weight_marker = (weight < 1.0) ? "*" : "" | |
| var result_text = self.is_small_screen ? f"{i}.{test_name}{weight_marker}" : f"{i}. {test_name}{weight_marker}" | |
| result.set_text(result_text) | |
| result.set_pos(10, y) | |
| result.set_style_text_color(lv.color(0xCCCCCC), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| if self.font_small != nil result.set_style_text_font(self.font_small, lv.PART_MAIN | lv.STATE_DEFAULT) end | |
| var fps_label = lv.label(self.scr) | |
| fps_label.set_text(f"{fps}") | |
| var fps_x = self.is_small_screen ? (self.hres - 45) : (self.hres - 70) | |
| fps_label.set_pos(fps_x, y) | |
| var fps_color = 0x00FF00 | |
| if fps < 30 fps_color = 0xFF0000 | |
| elif fps < 45 fps_color = 0xFF6600 | |
| elif fps < 60 fps_color = 0xFFFF00 | |
| end | |
| fps_label.set_style_text_color(lv.color(fps_color), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| if self.font_small != nil fps_label.set_style_text_font(self.font_small, lv.PART_MAIN | lv.STATE_DEFAULT) end | |
| y += self.result_line_height | |
| i += 1 | |
| end | |
| var avg = int(weighted_sum / weight_total) | |
| y += int(self.result_line_height * 0.3) | |
| var note = lv.label(self.scr) | |
| note.set_text("* weighted 0.25x") | |
| note.set_pos(10, y) | |
| note.set_style_text_color(lv.color(0x666666), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| if self.font_small != nil note.set_style_text_font(self.font_small, lv.PART_MAIN | lv.STATE_DEFAULT) end | |
| y += int(self.result_line_height * 1.2) | |
| var avg_label = lv.label(self.scr) | |
| avg_label.set_text(f"Score: {avg} FPS") | |
| avg_label.set_pos(10, y) | |
| avg_label.set_style_text_color(lv.color(0xFFFF00), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| if self.font_normal != nil avg_label.set_style_text_font(self.font_normal, lv.PART_MAIN | lv.STATE_DEFAULT) end | |
| var rating = "Excellent" | |
| var rating_color = 0x00FF00 | |
| if avg < 20 | |
| rating = "Poor" | |
| rating_color = 0xFF0000 | |
| elif avg < 35 | |
| rating = "Fair" | |
| rating_color = 0xFF6600 | |
| elif avg < 50 | |
| rating = "Good" | |
| rating_color = 0xFFFF00 | |
| end | |
| y += int(self.result_line_height * 1.3) | |
| var rating_label = lv.label(self.scr) | |
| rating_label.set_text(rating) | |
| rating_label.set_pos(10, y) | |
| rating_label.set_style_text_color(lv.color(rating_color), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| if self.font_small != nil rating_label.set_style_text_font(self.font_small, lv.PART_MAIN | lv.STATE_DEFAULT) end | |
| var btn_w = self.scaled(50) | |
| var btn_h = self.scaled(25) | |
| var repeat_btn = lv.btn(self.scr) | |
| repeat_btn.set_size(btn_w, btn_h) | |
| repeat_btn.set_pos(int(self.hres / 2) - int(btn_w / 2), self.vres - btn_h - 10) | |
| repeat_btn.set_style_bg_color(lv.color(0x0066CC), lv.PART_MAIN | lv.STATE_DEFAULT) | |
| var btn_label = lv.label(repeat_btn) | |
| btn_label.set_text("REPEAT") | |
| btn_label.center() | |
| if self.font_small != nil btn_label.set_style_text_font(self.font_small, lv.PART_MAIN | lv.STATE_DEFAULT) end | |
| repeat_btn.add_event_cb(/obj, evt -> self.start_benchmark(), lv.EVENT_CLICKED, 0) | |
| print(f"\n=== Results ({self.hres}x{self.vres}) ===") | |
| i = 1 | |
| while i <= 14 | |
| var fps = self.results[f"test{i}"] | |
| var weight = self.get_test_weight(i) | |
| var marker = (weight < 1.0) ? " *" : "" | |
| print(f"{tests[i-1]}: {fps}{marker}") | |
| i += 1 | |
| end | |
| print(f"Score: {avg} - {rating}") | |
| end | |
| end | |
| benchmark = LVGLBenchmark() | |
| tasmota.add_driver(benchmark) | |
| print("LVGL Benchmark loaded - Click START") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment