# ************** CODE SPECIFIC TO THE THE PYTHON BINDING *************** try: import lvgl as lv except ImportError: import os import sys base_path = os.path.dirname(__file__) sys.path.insert(0, os.path.abspath(os.path.join(base_path, '..', 'build'))) import lvgl as lv import math import time # ******************************************************************** PHASE_C_START_ANGLE = 30 PHASE_C_STOP_ANGLE = 150 PHASE_A_START_ANGLE = 150 PHASE_A_STOP_ANGLE = 270 PHASE_B_START_ANGLE = 270 PHASE_B_STOP_ANGLE = 390 lv.init() # ************** CODE SPECIFIC TO THE THE PYTHON BINDING *************** group = lv.group_create() lv.sdl_window_create(1024, 768) mouse = lv.sdl_mouse_create() keyboard = lv.sdl_keyboard_create() lv.indev_set_group(keyboard, group) # ************************************************************************* screen = lv.scr_act() lv.obj_set_style_bg_color(screen, lv.color_hex(0xC8C8C8), 0) # lv.obj_set_style_bg_opa(screen, 255, 0) def new_style(): s = lv.style_t() lv.style_init(s) return s # uint16_t int_remap(uint16_t value, uint16_t old_min, uint16_t old_max, uint16_t new_min, uint16_t new_max); def int_remap(value, old_min, old_max, new_min, new_max): return int( (((value - old_min) * (new_max - new_min)) / ( old_max - old_min) + new_min) ) # float float_remap(float value, float old_min, float old_max, float new_min, float new_max); def float_remap(value, old_min, old_max, new_min, new_max): return ((value - old_min) * (new_max - new_min)) / ( old_max - old_min) + new_min # this is a container to hold x, y coords that are floats. it is used for the # circle math and we only convert to an lv_coord_t (uint16_t or uint32_t) # if we need to pass the coords to LVGL to lvgl. # typedef struct { # float x; # float y; # # } float_point_t; class float_point_t: def __init__(self, x, y): self.x = x self.y = y # makes an lv_obj_t object from a float_point_t object. # lv_point_t float_point_to_lv_point(float_point_t, point); def float_point_to_lv_point(point): pt = lv.point_t() pt.x = int(point.x) pt.y = int(point.y) return pt # gets the coords of a point along the circumfrance of a circle given the # center, angle and radius # float_point_t point_on_circle( # float degree, float_point_t center, uint8_t radius); def point_on_circle(degree, center, radius): radians = math.radians(degree) x = center.x + (radius * math.cos(radians)) y = center.y + (radius * math.sin(radians)) return float_point_t(x, y) # container to hold rotated curved labels # typedef struct { # lv_obj_t[] labels; # uint8_t text_len; # uint16_t start_angle; # uint16_t stop_angle; # # } curved_text_t; class curved_text_t: def __init__(self, labels, text_len, start_angle, stop_angle): self.labels = labels self.text_len = text_len self.start_angle = start_angle self.stop_angle = stop_angle # void curved_text_set_style_text_color( # curved_text_t curved_text, lv_color_t color, lv_style_selector_t selector) def curved_text_set_style_text_color(curved_text, color, selector): style = new_style() lv.style_set_text_color(style, color) for label in curved_text.labels: lv.obj_add_style(label, style, selector) # lv_color_t curved_text_get_style_text_color( # curved_text_t curved_text, lv_style_selector_t selector) def curved_text_get_style_text_color(curved_text, selector): for label in curved_text.labels: return lv.obj_get_style_text_color(label, selector) # void curved_text_set_style_text_opa( # curved_text_t curved_text, lv_opa_t opa, lv_style_selector_t selector) def curved_text_set_style_text_opa(curved_text, opa, selector): style = new_style() lv.style_set_text_opa(style, opa) for label in curved_text.labels: lv.obj_add_style(label, style, selector) # lv_opa_t curved_text_get_style_text_opa( # curved_text_t curved_text, lv_style_selector_t selector) def curved_text_get_style_text_opa(curved_text, selector): for label in curved_text.labels: return lv.obj_get_style_text_opa(label, selector) # void curved_text_clear_flag(curved_text_t curved_text, lv_obj_flag_t flag) def curved_text_clear_flag(curved_text, flag): for i in range(curved_text.text_len): lv.obj_clear_flag(curved_text.labels[i], flag) # void curved_text_add_flag(curved_text_t curved_text, lv_obj_flag_t flag) def curved_text_add_flag(curved_text, flag): for i in range(curved_text.text_len): lv.obj_add_flag(curved_text.labels[i], flag) # const char * curved_text_get_text(curved_text_t curved_text) def curved_text_get_text(curved_text): text = '' # iterate over the array of labels getting the single # character from each one for label in curved_text.labels: text += lv.label_get_text(label) # check the start and stop angles to determine if the order of the # characters is reversed. if ( 90 < curved_text.start_angle < 180 or 270 < curved_text.start_angle < 360 ): # convert string into an array text = list(text) # reverse the order of the letters text.reverse() # convert array back into a string text = ''.join(text) # the strip() removed whitespace at the begining and the end of the text. # whitespace is defined is "\n", "\t", " " and "\r" (if applicable) return text.strip() # void curved_text_set_text(curved_text_t curved_text, const char* value) def curved_text_set_text(curved_text, value): # we have to check the length of the new text against the original text # length. There are only so many character slots available. If the text # is too long it's not going to fit so cause an arror to occur if len(value) > curved_text.text_len: raise RuntimeError # if the text is smaller than the original text there are going to be labels # that contain no text, we want to split the number of those as even as # bossible for before and after the new text remainder = curved_text.text_len - len(value) value = (' ' * int(remainder / 2)) + value # checking to see if the number of empty places is even or odd. if it is # even split it right down the middle 1/2 goes before and 1/2 goes after # otherwise we add an additional one to the end of the text remainder += remainder % 2 value += ' ' * int(remainder / 2) value = list(value) if ( 90 < curved_text.start_angle < 180 or 270 < curved_text.start_angle < 360 ): value.reverse() for i, char in enumerate(value): lv.label_set_text(curved_text.labels[i], char) # curved_text_t rotated_curved_text( # lv_obj_t parent, float start_angle, float stop_angle, # const char* text, lv_font_t font, uint16_t radius, # float_point_t center) def rotated_curved_text( parent, start_angle, stop_angle, text, font, radius, center ): # get the total angle range that the text must fit into angle_range = stop_angle - start_angle text_len = len(text) style = new_style() lv.style_set_text_font(style, font) labels = [] # calculate how much of an angle change is needed between each # character in the text angle_step = float(angle_range) / (len(text) + 1) # the first character angle angle = start_angle + angle_step # convert text into an array text = list(text) # check angle position the text is supposed to go in and reverse the # order of the text if necessary if start_angle > PHASE_C_START_ANGLE and stop_angle < PHASE_C_STOP_ANGLE: text.reverse() # iterate over each character in the text for char in text: # calculate the angle of rotation that needs to be put onto # the character if start_angle > PHASE_C_START_ANGLE and stop_angle < PHASE_C_STOP_ANGLE: t_angle = 2700 - (3600 - int(round(angle, 1) * 10)) else: t_angle = 900 - (3600 - int(round(angle, 1) * 10)) # add 180 degrees of ratation based on the location of the text # if 180 < start_angle and 360 > stop_angle: # t_angle += 1800 label = lv.label_create(parent) lv.obj_add_style(label, style, 0) lv.label_set_text(label, char) lv.obj_set_size(label, lv.SIZE_CONTENT, lv.SIZE_CONTENT) lv.obj_update_layout(label) # this is a calculation in order to get the bottom edge of the # text aligned with the radius. It would have been better if I # could have centered the text instead of aligning it using the # bottom edge. The reason why is character positioning. in LVGL # each character has an identical sized container. The character # positioning inside the container varried character by character # there is no way to get the exaact dimensions of the acttual # character if start_angle > PHASE_C_START_ANGLE and stop_angle < PHASE_C_STOP_ANGLE: if len(text) == 1: l_height = lv.obj_get_self_height(label) point = point_on_circle(angle, center, int(radius - (l_height / 3))) else: point = point_on_circle(angle, center, radius) else: l_height = lv.obj_get_self_height(label) point = point_on_circle( angle, center, radius + l_height ) lv.obj_set_style_transform_angle(label, t_angle, 0) lv.obj_set_x(label, int(point.x)) lv.obj_set_y(label, int(point.y)) labels.append(label) angle += angle_step return curved_text_t(labels, text_len, start_angle, stop_angle) class phase_needle_t: def __init__(self, radius, angle, ind, point1=None, point2=None): self.radius = radius self.angle = angle self.point1 = point1 self.point2 = point2 self.ind = ind self.line = None VOLTS_MAX = 240 AMPS_MAX = 200 class phase_metrics: def __init__(self): self.ideal_volts = VOLTS_MAX self.feed_amps_max = AMPS_MAX self.amps = 0.0 self.volts = 0.0 self.max_volts = 0.0 self.volts_deviation_from_ideal = 0.0 self.max_voltage_drop = 0.0 self.amps_at_80_percent_load = 0.0 self.allowed_drop_for_load = 0.0 self.min_allowed_volts = 0.0 self.percentage_of_overload = 0.0 self.minimum_volts_at_80_percent_load = 0.0 self.render = True class phase_t: def __init__( self, start_angle, stop_angle, needle, amps, volts, scale, metrics ): self.start_angle = start_angle self.stop_angle = stop_angle self.needle = needle self.amps = amps self.volts = volts self.scale = scale self.volts_max = 0.0 self.metrics = metrics def arc_dsc(color, opa, width, start_angle, stop_angle): dsc = lv.draw_arc_dsc_t() lv.draw_arc_dsc_init(dsc) dsc.color = color dsc.width = width dsc.opa = opa dsc.start_angle = start_angle dsc.end_angle = stop_angle return dsc # lv_draw_line_dsc_t separator_dsc(lv_color_t color, lv_opa_t opa, lv_coord_t width); def line_dsc(color, opa, width): dsc = lv.draw_line_dsc_t() lv.draw_line_dsc_init(dsc) dsc.color = color dsc.width = width dsc.opa = opa dsc.round_start = False dsc.round_end = False return dsc # lv_obj_t * screen = lv_scr_act(); screen = lv.scr_act() disp = lv.disp_get_default() # lv_coord_t screen_width = LV_HOR_RES; screen_width = lv.disp_get_hor_res(disp) # lv_coord_t screen_height = LV_VER_RES; screen_height = lv.disp_get_ver_res(disp) # lv_coord_t graph_size = (lv_coord_t) (MIN(width, height) * 0.8); graph_size = min(screen_width, screen_height) - 50 outer_radius = int(graph_size / 2) graph_label_radius = int(outer_radius * 0.90) graph_volt_label_radius = int(outer_radius * 0.85) graph_radius = int(outer_radius * 0.80) # lv_obj_t * graph = lv_canvas_create(screen); graph = lv.canvas_create(screen) # lv_obj_set_size(graph, graph_size, graph_size); lv.obj_set_size(graph, graph_size, graph_size) # lv_obj_center(graph); lv.obj_center(graph) # uint8_t graph_buf[graph_size * graph_size * sizeof(lv.color_t)]; graph_buf = lv.color_t.as_array(size=graph_size * graph_size) # lv_canvas_set_buffer(graph, (void *) graph_buf, (lv_coord_t) graph_size, (lv_coord_t) graph_size, LV_COLOR_FORMAT_NATIVE); lv.canvas_set_buffer(graph, graph_buf, graph_size, graph_size, lv.COLOR_FORMAT_NATIVE) # float_point_t graph_center; # graph_center.x = (float) lv_obj_get_x_aligned(graph); # graph_center.y = (float) lv_obj_get_y_aligned(graph); graph_center = float_point_t(screen_width / 2, screen_height / 2) canvas_center = float_point_t(graph_size / 2, graph_size / 2) # curved_text_t phase_a_label = rotated_curved_text(graph, 180.0f, 240.0f, "PHASE A", font_montserrat_14, graph_label_radius, canvas_center); phase_a_label = rotated_curved_text( graph, PHASE_A_START_ANGLE + 40, PHASE_A_STOP_ANGLE - 40, 'PHASE A', lv.font_montserrat_14, graph_label_radius, canvas_center ) # curved_text_t phase_b_label = rotated_curved_text(graph, 300.0f, 360.0f, "PHASE B", font_montserrat_14, graph_label_radius, canvas_center); phase_b_label = rotated_curved_text( graph, PHASE_B_START_ANGLE + 40, PHASE_B_STOP_ANGLE - 40, 'PHASE B', lv.font_montserrat_14, graph_label_radius, canvas_center ) # curved_text_t phase_c_label = rotated_curved_text(graph, 60.0f, 120.0f, "PHASE C", font_montserrat_14, graph_label_radius, canvas_center); phase_c_label = rotated_curved_text( graph, PHASE_C_START_ANGLE + 40, PHASE_C_STOP_ANGLE - 40, 'PHASE C', lv.font_montserrat_14, graph_label_radius, canvas_center ) # curved_text_t phase_a_volts_label = rotated_curved_text(graph, 195.0f, 225.0f, "- VOLTS +", lv_font_montserrat_8, graph_volt_label_radius, canvas_center); phase_a_volts_label = rotated_curved_text( graph, PHASE_A_START_ANGLE + 50, PHASE_A_STOP_ANGLE - 50, 'VOLTS', lv.font_montserrat_10, graph_volt_label_radius, canvas_center ) phase_a_volts_minus_label = rotated_curved_text( graph, PHASE_A_START_ANGLE + 48, PHASE_A_START_ANGLE + 48, '-', lv.font_montserrat_16, graph_volt_label_radius, canvas_center ) phase_a_volts_plus_label = rotated_curved_text( graph, PHASE_A_STOP_ANGLE - 48, PHASE_A_STOP_ANGLE - 48, '+', lv.font_montserrat_16, graph_volt_label_radius, canvas_center ) phase_a_volts_right_arrow = rotated_curved_text( graph, PHASE_A_STOP_ANGLE - 16, PHASE_A_STOP_ANGLE - 16, '>', lv.font_montserrat_20, graph_volt_label_radius - 3, canvas_center ) phase_a_volts_left_arrow = rotated_curved_text( graph, PHASE_A_START_ANGLE + 15, PHASE_A_START_ANGLE + 15, '<', lv.font_montserrat_20, graph_volt_label_radius - 3, canvas_center ) # curved_text_t phase_b_volts_label = rotated_curved_text(graph, 315.0f, 345.0f, "- VOLTS +", lv_font_montserrat_8, graph_volt_label_radius, canvas_center); phase_b_volts_label = rotated_curved_text( graph, PHASE_B_START_ANGLE + 50, PHASE_B_STOP_ANGLE - 50, 'VOLTS', lv.font_montserrat_10, graph_volt_label_radius, canvas_center ) phase_b_volts_minus_label = rotated_curved_text( graph, PHASE_B_START_ANGLE + 48, PHASE_B_START_ANGLE + 48, '-', lv.font_montserrat_16, graph_volt_label_radius, canvas_center ) phase_b_volts_plus_label = rotated_curved_text( graph, PHASE_B_STOP_ANGLE - 48, PHASE_B_STOP_ANGLE - 48, '+', lv.font_montserrat_16, graph_volt_label_radius, canvas_center ) phase_b_volts_right_arrow = rotated_curved_text( graph, PHASE_B_STOP_ANGLE - 16, PHASE_B_STOP_ANGLE - 16, '>', lv.font_montserrat_20, graph_volt_label_radius - 3, canvas_center ) phase_b_volts_left_arrow = rotated_curved_text( graph, PHASE_B_START_ANGLE + 15, PHASE_B_START_ANGLE + 15, '<', lv.font_montserrat_20, graph_volt_label_radius - 3, canvas_center ) # curved_text_t phase_c_volts_label = rotated_curved_text(graph, 75.0f, 105.0f, "- VOLTS +", lv_font_montserrat_8, graph_volt_label_radius, canvas_center); phase_c_volts_label = rotated_curved_text( graph, PHASE_C_START_ANGLE + 50, PHASE_C_STOP_ANGLE - 50, 'VOLTS', lv.font_montserrat_10, graph_volt_label_radius, canvas_center ) phase_c_volts_minus_label = rotated_curved_text( graph, PHASE_C_START_ANGLE + 48, PHASE_C_START_ANGLE + 48, '-', lv.font_montserrat_16, graph_volt_label_radius, canvas_center ) phase_c_volts_plus_label = rotated_curved_text( graph, PHASE_C_STOP_ANGLE - 48, PHASE_C_STOP_ANGLE - 48, '+', lv.font_montserrat_16, graph_volt_label_radius, canvas_center ) phase_c_volts_right_arrow = rotated_curved_text( graph, PHASE_C_START_ANGLE + 16, PHASE_C_START_ANGLE + 16, '>', lv.font_montserrat_20, graph_volt_label_radius + 5, canvas_center ) phase_c_volts_left_arrow = rotated_curved_text( graph, PHASE_C_STOP_ANGLE - 15, PHASE_C_STOP_ANGLE - 15, '<', lv.font_montserrat_20, graph_volt_label_radius + 5, canvas_center ) phase_a_ind = lv.label_create(graph) phase_b_ind = lv.label_create(graph) phase_c_ind = lv.label_create(graph) lv.label_set_text(phase_a_ind, '*') lv.label_set_text(phase_b_ind, '*') lv.label_set_text(phase_c_ind, '*') lv.obj_set_style_text_font(phase_a_ind, lv.font_montserrat_18, 0) lv.obj_set_style_text_color(phase_a_ind, lv.color_hex(0xFF0000), 0) lv.obj_set_style_text_font(phase_b_ind, lv.font_montserrat_18, 0) lv.obj_set_style_text_color(phase_b_ind, lv.color_hex(0x00FF00), 0) lv.obj_set_style_text_font(phase_c_ind, lv.font_montserrat_18, 0) lv.obj_set_style_text_color(phase_c_ind, lv.color_hex(0x0000FF), 0) curved_text_set_style_text_color(phase_a_label, lv.color_hex(0xFF0000), 0) curved_text_set_style_text_color(phase_a_volts_label, lv.color_hex(0xFF0000), 0) curved_text_set_style_text_color(phase_a_volts_right_arrow, lv.color_hex(0xFF0000), 0) curved_text_set_style_text_color(phase_a_volts_left_arrow, lv.color_hex(0xFF0000), 0) curved_text_set_style_text_color(phase_b_label, lv.color_hex(0x00FF00), 0) curved_text_set_style_text_color(phase_b_volts_label, lv.color_hex(0x00FF00), 0) curved_text_set_style_text_color(phase_b_volts_right_arrow, lv.color_hex(0x00FF00), 0) curved_text_set_style_text_color(phase_b_volts_left_arrow, lv.color_hex(0x00FF00), 0) curved_text_set_style_text_color(phase_c_label, lv.color_hex(0x0000FF), 0) curved_text_set_style_text_color(phase_c_volts_label, lv.color_hex(0x0000FF), 0) curved_text_set_style_text_color(phase_c_volts_right_arrow, lv.color_hex(0x0000FF), 0) curved_text_set_style_text_color(phase_c_volts_left_arrow, lv.color_hex(0x0000FF), 0) def render_graph(bg_color, bg_opa, phase_a_dsc, phase_b_dsc, phase_c_dsc): lv.canvas_fill_bg(graph, bg_color, bg_opa) c_point = float_point_to_lv_point(canvas_center) arc_radius = int( graph_volt_label_radius + ( (graph_label_radius - graph_volt_label_radius) / 2 ) ) for start_angle, stop_angle, phase_dsc in ( (PHASE_C_START_ANGLE, PHASE_C_STOP_ANGLE, phase_c_dsc), (PHASE_A_START_ANGLE, PHASE_A_STOP_ANGLE, phase_a_dsc), (PHASE_B_START_ANGLE, PHASE_B_STOP_ANGLE, phase_b_dsc) ): point = point_on_circle(start_angle, canvas_center, graph_radius) lv.canvas_draw_line(graph, [float_point_to_lv_point(point), c_point], 2, phase_dsc) dsc = arc_dsc( phase_dsc.color, phase_dsc.opa, phase_dsc.width, start_angle, stop_angle ) lv.canvas_draw_arc( graph, int(canvas_center.x), int(canvas_center.y), int(graph_radius), start_angle, stop_angle, dsc ) mid_angle = int(start_angle + ((stop_angle - start_angle) / 2)) lv.canvas_draw_arc( graph, int(canvas_center.x), int(canvas_center.y), arc_radius, start_angle + 15, mid_angle - 15, dsc ) lv.canvas_draw_arc( graph, int(canvas_center.x), int(canvas_center.y), arc_radius, mid_angle + 15, stop_angle - 15, dsc ) step = graph_radius / 11.0 large_dsc = arc_dsc(lv.color_hex(0xC8C8C8), 255, 1, 0, 0) small_dsc = arc_dsc(lv.color_hex(0xC8C8C8), 255, 1, 0, 0) small_radius = step / 2 large_radius = step start_angle = mid_angle - 8 stop_angle = mid_angle + 8 large_dsc.start_angle = start_angle large_dsc.end_angle = stop_angle small_dsc.start_angle = start_angle + 2 small_dsc.end_angle = stop_angle - 2 while small_radius < graph_radius: # lv.draw_arc(ctx, large_dsc, c_point, large_radius, start_angle, stop_angle) # lv.draw_arc(ctx, small_dsc, c_point, small_radius, start_angle + 4, stop_angle - 4) if large_radius < graph_radius: lv.canvas_draw_arc( graph, int(canvas_center.x), int(canvas_center.y), int(large_radius), start_angle, stop_angle, large_dsc ) # lv.draw_arc(ctx, small_dsc, c_point, small_radius, start_angle + 4, stop_angle - 4) lv.canvas_draw_arc( graph, int(canvas_center.x), int(canvas_center.y), int(small_radius), start_angle + 3, stop_angle - 3, small_dsc ) small_radius += step large_radius += step def set_indicator(phase): needle = phase.needle line = needle.line ind = needle.ind if line is not None: lv.obj_del(line) style = new_style() lv.style_set_line_opa(style, 255) lv.style_set_line_width(style, 2) line = lv.line_create(graph) needle.line = line lv.obj_add_style(line, style, 0) point = point_on_circle(needle.angle, canvas_center, needle.radius) ind_point = float_point_to_lv_point(point) needle_base_point = float_point_to_lv_point(graph_center) ind_width = lv.obj_get_width(ind) ind_height = lv.obj_get_height(ind) ind_center_x = int(ind_width / 2) ind_center_y = int(ind_height / 2) lv.obj_set_pos( ind, ind_point.x - ind_center_x, ind_point.y - ind_center_y ) lv.line_set_points(line, [ind_point, needle_base_point], 2) lv.obj_invalidate(graph) def set_phase_volts(phase, volts): needle = phase.needle scale = float(phase.scale) phase.volts = volts angle_mid_point = float(phase.start_angle) + ( float(phase.stop_angle - phase.start_angle) / 2.0) needle.angle = float_remap( volts / scale, 0, float(VOLTS_MAX) / scale, float(phase.start_angle), angle_mid_point ) phase.metrics.volts = volts set_indicator(phase) def set_phase_amps(phase, amps): scale = float(phase.scale) phase.amps = amps phase.needle.radius = float_remap( phase.amps / scale, 0, float(AMPS_MAX) / scale, 0.0, graph_radius ) if amps < 5: phase.volts_max = max(phase.volts_max, phase.volts) phase.metrics.max_volts = phase.volts_max phase.metrics.amps = amps set_indicator(phase) def calculate_phase_metrics(metrics): metrics.volts_deviation_from_ideal = metrics.volts - metrics.ideal_volts metrics.max_voltage_drop = metrics.max_volts * 0.03 metrics.amps_at_80_percent_load = metrics.feed_amps_max * 0.80 max_drop_step = metrics.max_voltage_drop / metrics.amps_at_80_percent_load metrics.allowed_drop_for_load = max_drop_step * metrics.amps metrics.min_allowed_volts = metrics.max_volts - metrics.allowed_drop_for_load deviation_from_allowed_min = (metrics.volts - metrics.min_allowed_volts) if deviation_from_allowed_min < 0: metrics.percentage_of_overload = abs( deviation_from_allowed_min / metrics.allowed_drop_for_load * 100.0 ) else: metrics.percentage_of_overload = -( deviation_from_allowed_min / metrics.allowed_drop_for_load * 100.0) metrics.minimum_volts_at_80_percent_load = metrics.max_volts - metrics.max_voltage_drop # lv_draw_rect_dsc_t p_a_dsc; p_a_dsc = line_dsc(lv.color_hex(0xFF0000), 255, 2) p_b_dsc = line_dsc(lv.color_hex(0x00FF00), 255, 2) p_c_dsc = line_dsc(lv.color_hex(0x0000FF), 255, 2) # phase_t phase_a = { # .start_angle=150, # .stop_angle=270, # .needle={ # .angle=210, # .dsc={.color=lv.color_hex(0x0000FF), .opa=255, .width=2} # }, # .scale=1, # }; phase_a = phase_t( start_angle=PHASE_A_START_ANGLE + 1, stop_angle=PHASE_A_STOP_ANGLE - 1, needle=phase_needle_t( radius=0, angle=PHASE_A_START_ANGLE + int((PHASE_A_STOP_ANGLE - PHASE_A_START_ANGLE) / 2), ind=phase_a_ind ), volts=0, amps=0, scale=1, metrics=phase_metrics() ) # phase_t phase_b = { # .start_angle=270, # .stop_angle=390, # .needle={ # .angle=330, # .dsc={.color=lv.color_hex(0xFF0000), .opa=255, .width=2} # }, # .scale=1, # }; phase_b = phase_t( start_angle=PHASE_B_START_ANGLE + 1, stop_angle=PHASE_B_STOP_ANGLE - 1, needle=phase_needle_t( radius=0, angle=PHASE_B_START_ANGLE + int((PHASE_B_STOP_ANGLE - PHASE_B_START_ANGLE) / 2), ind=phase_b_ind ), volts=0, amps=0, scale=1, metrics=phase_metrics() ) # phase_t phase_c = { # .start_angle=30, # .stop_angle=150, # .needle={ # .angle=90, # .dsc={.color=lv.color_hex(0x00FF00), .opa=255, .width=2} # }, # .scale=1, # }; phase_c = phase_t( start_angle=PHASE_C_START_ANGLE + 1, stop_angle=PHASE_C_STOP_ANGLE - 1, needle=phase_needle_t( radius=0, angle=PHASE_C_START_ANGLE + int((PHASE_C_STOP_ANGLE - PHASE_C_START_ANGLE) / 2), ind=phase_c_ind ), volts=0, amps=0, scale=1, metrics=phase_metrics() ) render_graph(lv.color_hex(0x000000), 255, p_a_dsc, p_b_dsc, p_c_dsc) # ************** CODE SPECIFIC TO THE THE PYTHON BINDING *************** import random def rand_float(min_val, max_val): min_val *= 100 max_val *= 100 res = random.randrange(int(min_val), int(max_val)) return res / 100.0 # *********************************************************************** # print('setting volts') set_phase_volts(phase_a, 126.2) set_phase_volts(phase_b, 122.2) set_phase_volts(phase_c, 119.5) # print('finished') # ************** CODE SPECIFIC TO THE THE PYTHON BINDING *************** counter = 0 while True: counter += 1 if counter == 2000: counter = 0 set_phase_volts(phase_a, rand_float(110, 130)) set_phase_amps(phase_a, rand_float(5, 180)) set_phase_volts(phase_b, rand_float(110, 130)) set_phase_amps(phase_b, rand_float(5, 180)) set_phase_volts(phase_c, rand_float(110, 130)) set_phase_amps(phase_c, rand_float(5, 180)) time.sleep(0.001) lv.task_handler() # ***********************************************************************