Did a huge refactoring and outsouring for modularity and a small performance improvement
This commit is contained in:
		
							
								
								
									
										352
									
								
								main.py
									
									
									
									
									
								
							
							
						
						
									
										352
									
								
								main.py
									
									
									
									
									
								
							| @@ -13,336 +13,11 @@ You should have received a copy of the GNU General Public License along with thi | |||||||
| import utils | import utils | ||||||
| from lcdMenu import lcdMenu | from lcdMenu import lcdMenu | ||||||
| from WelcomeScreen import WelcomeScreen | from WelcomeScreen import WelcomeScreen | ||||||
| from time import sleep, time_ns |  | ||||||
| from gc import collect  # garbage collector for better memory performance | from gc import collect  # garbage collector for better memory performance | ||||||
|  |  | ||||||
| config = utils.Config() | config = utils.Config() | ||||||
| btn_mapping = {"ok_btn": config.PIN_IN_BTN_1, "next_btn": config.PIN_IN_BTN_2}  # the btn mapping for all lcdMenus | btn_mapping = {"ok_btn": config.PIN_IN_BTN_1, "next_btn": config.PIN_IN_BTN_2}  # the btn mapping for all lcdMenus | ||||||
|  |  | ||||||
| # extra functions to access the garbage collector |  | ||||||
| def manual(): |  | ||||||
|     config.LCD.clear() |  | ||||||
|     set_value = config.PIN_OUT_RELAIS.value() |  | ||||||
|     config.LCD.putstr(f"---- MANUAL ----    State: {set_value}    ") |  | ||||||
|     while True: |  | ||||||
|         if set_value != config.PIN_IN_SWITCH.value(): |  | ||||||
|             config.PIN_OUT_RELAIS.value(config.PIN_IN_SWITCH.value()) |  | ||||||
|             set_value = config.PIN_OUT_RELAIS.value() |  | ||||||
|             config.LCD.putstr(f"---- MANUAL ----    State: {set_value}    ") |  | ||||||
|         if config.PIN_IN_BTN_1.value() == 1 or config.PIN_IN_BTN_2.value() == 1: |  | ||||||
|             return True  # exit on press of these buttons; True to disable the Quitting message from lcdMenu |  | ||||||
| def timer(): |  | ||||||
|     timer_menu = lcdMenu(config.LCD, btn_mapping, scroll_direction=True, cycle=True, hide_menu_name=False, name="TIMERS") |  | ||||||
|     timer_values_original = [config.TIMER_1_DURATION, config.TIMER_2_DURATION, config.TIMER_3_DURATION] |  | ||||||
|     timer_values = timer_values_original.copy()  # here, the current timers time is stored when interrupting via the interrupt_pin (see below) |  | ||||||
|     timer_splits = [lambda: divmod(round(timer_values[0]), 60), lambda: divmod(round(timer_values[1]), 60), lambda: divmod(round(timer_values[2]), 60)] |  | ||||||
|     interrupt_pin = config.PIN_IN_BTN_1  # the interrupt btn stops the timer, saves the current time and goes back to the menu |  | ||||||
|     reset_pin = config.PIN_IN_BTN_2  # the reset btn restores the default value |  | ||||||
|     start_stop_pin = config.PIN_IN_SWITCH  # the start_stop switch starts/stops the timer |  | ||||||
|      |  | ||||||
|     # timer_number is the number of the timer that will be run, starting at 1 |  | ||||||
|     # the _timer variable is needed because otherwise python will throw crazy errors regarding "variable accessed before assignment"... |  | ||||||
|     # ...just see it as a copy of the timer_number-1'th elemnt of the timer_values list (see above) |  | ||||||
|     def run_timer(timer_number: int, _timer: int): |  | ||||||
|         config.LCD.clear() |  | ||||||
|         config.LCD.putstr(f"Timer {timer_number}".center(16)) |  | ||||||
|         last_start_stop_value = start_stop_pin.value() |  | ||||||
|         config.PIN_OUT_RELAIS.value(last_start_stop_value) |  | ||||||
|         last_time_ns = time_ns() |  | ||||||
|         while True:  # now run the timer (if the switch is high) |  | ||||||
|             config.LCD.move_to(0,1) |  | ||||||
|             _timer_div = divmod(round(_timer), 60) |  | ||||||
|             config.LCD.putstr(f"{_timer_div[0]:02d}:{_timer_div[1]:02d}".center(16)) |  | ||||||
|             if interrupt_pin.value() == 1: |  | ||||||
|                 timer_values[timer_number-1] = _timer  # save the current state |  | ||||||
|                 last_start_stop_value = 0  # turn the LEDs off! |  | ||||||
|                 config.PIN_OUT_RELAIS.value(last_start_stop_value) |  | ||||||
|                 return None |  | ||||||
|             if reset_pin.value() == 1: |  | ||||||
|                 _timer = timer_values_original[timer_number-1]  # reset the timers |  | ||||||
|             if _timer <= 0: |  | ||||||
|                 config.PIN_OUT_RELAIS.off() |  | ||||||
|                 return True |  | ||||||
|             sleep(0.05) |  | ||||||
|             if last_start_stop_value != (new_value := start_stop_pin.value()): |  | ||||||
|                 last_start_stop_value = new_value |  | ||||||
|                 config.PIN_OUT_RELAIS.value(new_value) |  | ||||||
|                 last_time_ns = time_ns() |  | ||||||
|             if start_stop_pin.value() == 1: |  | ||||||
|                 _timer -= (time_ns() - last_time_ns) / 1000**3 |  | ||||||
|                 last_time_ns = time_ns() |  | ||||||
|      |  | ||||||
|     timer_programs = [(f"T1 - {timer_splits[0]()[0]:02d}:{timer_splits[0]()[1]:02d}", lambda: run_timer(1, timer_values[0])), |  | ||||||
|                       (f"T2 - {timer_splits[1]()[0]:02d}:{timer_splits[1]()[1]:02d}", lambda: run_timer(2, timer_values[1])), |  | ||||||
|                       (f"T3 - {timer_splits[2]()[0]:02d}:{timer_splits[2]()[1]:02d}", lambda: run_timer(3, timer_values[2])), |  | ||||||
|                       ("Exit", timer_menu.stop)] |  | ||||||
|     timer_menu.setup(timer_programs)  # give it the callback list |  | ||||||
|     timer_menu.run() |  | ||||||
|     del timer_menu, timer_programs |  | ||||||
|     collect() |  | ||||||
|     return True  # disable the "Quitting" message from lcdMenu |  | ||||||
| def settings(): |  | ||||||
|     settings_menu = lcdMenu(config.LCD, btn_mapping, scroll_direction=True, cycle=True, hide_menu_name=False, name="SETTINGS") |  | ||||||
|     def toggle_show_welcome(): |  | ||||||
|         current_value = config.STARTUP_WELCOME_SHOW |  | ||||||
|         config.LCD.clear() |  | ||||||
|         config.LCD.putstr(f"Currently {'on' if current_value else 'off'}".center(16)) |  | ||||||
|         config.LCD.putstr("< keep  change >") |  | ||||||
|         keep_btn = config.PIN_IN_BTN_1 |  | ||||||
|         change_btn = config.PIN_IN_BTN_2 |  | ||||||
|         while True: |  | ||||||
|             if keep_btn.value() == 1: |  | ||||||
|                 config.LCD.move_to(0,1)  # move to the second row |  | ||||||
|                 config.LCD.putstr(f"Stay {'on' if current_value else 'off'}!".center(16)) |  | ||||||
|                 sleep(0.5) |  | ||||||
|                 return True |  | ||||||
|             if change_btn.value() == 1: |  | ||||||
|                 config.STARTUP_WELCOME_SHOW = not current_value |  | ||||||
|                 config.LCD.move_to(0,1)  # move to the second row |  | ||||||
|                 config.LCD.putstr(f"Turned {'on' if not current_value else 'off'}!".center(16)) |  | ||||||
|                 sleep(0.5) |  | ||||||
|                 return True |  | ||||||
|     def welcome_cycles(): |  | ||||||
|         config.LCD.clear() |  | ||||||
|         current_cycles = config.STARTUP_WELCOME_CYCLES |  | ||||||
|          |  | ||||||
|         option_down = [" ", "v"][current_cycles>1] |  | ||||||
|         config.LCD.putstr(f"     Cycles     \n{option_down} {str(current_cycles).center(12)} ^") |  | ||||||
|         btn_left = config.PIN_IN_BTN_1 |  | ||||||
|         btn_right = config.PIN_IN_BTN_2 |  | ||||||
|         while True: |  | ||||||
|             if btn_left.value() == 1: |  | ||||||
|                 sleep(0.1)  # this value is a good compromise between being able to press both buttons and a fast up/down speed |  | ||||||
|                 if btn_right.value() == 1: |  | ||||||
|                     config.STARTUP_WELCOME_CYCLES = current_cycles |  | ||||||
|                     config.LCD.move_to(0,1)  # move to the second row |  | ||||||
|                     config.LCD.putstr(f"Saved!".center(16))  # show a little info that it is now set |  | ||||||
|                     sleep(0.5) |  | ||||||
|                     while btn_right.value() == 1 or btn_left.value() == 1:  # wait till both btns are released |  | ||||||
|                         pass |  | ||||||
|                     return True |  | ||||||
|                  |  | ||||||
|                 current_cycles -= 1 |  | ||||||
|                 if current_cycles < 1: current_cycles = 1 |  | ||||||
|                 option_down = [" ", "v"][current_cycles>1] |  | ||||||
|                 config.LCD.putstr(f"     Cycles     \n{option_down} {str(current_cycles).center(12)} ^") |  | ||||||
|             if btn_right.value() == 1: |  | ||||||
|                 sleep(0.1) |  | ||||||
|                 if btn_left.value() == 1: |  | ||||||
|                     config.STARTUP_WELCOME_CYCLES = current_cycles |  | ||||||
|                     config.LCD.move_to(0,1)  # move to the second row |  | ||||||
|                     config.LCD.putstr(f"Saved!".center(16))  # show a little info that it is now set |  | ||||||
|                     sleep(0.5) |  | ||||||
|                     while btn_right.value() == 1 or btn_left.value() == 1:  # wait till both btns are released |  | ||||||
|                         pass |  | ||||||
|                     return True |  | ||||||
|                 current_cycles += 1 |  | ||||||
|                 option_down = [" ", "v"][current_cycles>1] |  | ||||||
|                 config.LCD.putstr(f"     Cycles     \n{option_down} {str(current_cycles).center(12)} ^") |  | ||||||
|      |  | ||||||
|     # with n being the number of the timer (starting at 0) |  | ||||||
|     def set_n_timer(n: int): |  | ||||||
|         # a small helper function to save the value of the n'th timer... |  | ||||||
|         # as you can't programatically access TIMER_n_DURATION |  | ||||||
|         def set_timer_helper(n, value): |  | ||||||
|             if n == 0: |  | ||||||
|                 config.TIMER_1_DURATION = value |  | ||||||
|             elif n == 1: |  | ||||||
|                 config.TIMER_2_DURATION = value |  | ||||||
|             elif n == 2: |  | ||||||
|                 config.TIMER_3_DURATION = value |  | ||||||
|             else: |  | ||||||
|                 utils.log(0, "There are only 3 timers at all. Trying to set the timer number {n} failed.") |  | ||||||
|                  |  | ||||||
|         config.LCD.clear() |  | ||||||
|         timer_values = [config.TIMER_1_DURATION, config.TIMER_2_DURATION, config.TIMER_3_DURATION] |  | ||||||
|         current_timer = timer_values[n]  # get the n'th timer |  | ||||||
|         current_timer_div = lambda: divmod(current_timer, 60) |  | ||||||
|          |  | ||||||
|  |  | ||||||
|         config.LCD.putstr(f"Timer {n+1}".center(16)) |  | ||||||
|         config.LCD.putstr(f"{'v' if current_timer > 1 else ' '} " + f"{current_timer_div()[0]:02d}:{current_timer_div()[1]:02d}".center(12) + " ^") |  | ||||||
|         btn_left = config.PIN_IN_BTN_1 |  | ||||||
|         btn_right = config.PIN_IN_BTN_2 |  | ||||||
|         left_was_released = True |  | ||||||
|         right_was_released = True |  | ||||||
|         while True: |  | ||||||
|             if btn_left.value() == 1: |  | ||||||
|                 if left_was_released: |  | ||||||
|                     time_press_start = time_ns() |  | ||||||
|                     left_was_released = False |  | ||||||
|                 sleep(0.1)  # this value is a good compromise between being able to press both buttons and a fast up/down speed |  | ||||||
|                 if btn_right.value() == 1:  # exit if both btns are pressed |  | ||||||
|                     set_timer_helper(n, current_timer) |  | ||||||
|                     config.LCD.move_to(0,1)  # move to the second row |  | ||||||
|                     config.LCD.putstr(f"Saved!".center(16))  # show a little info that it is now set |  | ||||||
|                     sleep(0.5) |  | ||||||
|                     while btn_right.value() == 1 or btn_left.value() == 1:  # wait till both btns are released |  | ||||||
|                         pass |  | ||||||
|                     return True |  | ||||||
|                 # define the step width |  | ||||||
|                 time_now = time_ns() |  | ||||||
|                 if (time_now - time_press_start) <= 1*(10**9):  # max. 1 seconds pressed |  | ||||||
|                     current_timer -= 1 |  | ||||||
|                 elif (time_now - time_press_start) <= 2*(10**9):  # max. 2 seconds pressed |  | ||||||
|                     current_timer -= 5 |  | ||||||
|                 elif (time_now - time_press_start) <= 3*(10**9):  # max. 3 seconds pressed |  | ||||||
|                     current_timer -= 10 |  | ||||||
|                 elif (time_now - time_press_start) <= 4*(10**9):  # max. 4 seconds pressed |  | ||||||
|                     current_timer -= 30 |  | ||||||
|                 elif (time_now - time_press_start) <= 5*(10**9):  # max. 5 seconds pressed |  | ||||||
|                     current_timer -= 60 |  | ||||||
|                 else:  # longer than 5s pressed |  | ||||||
|                     current_timer -= 300 |  | ||||||
|                 if current_timer < 1: current_timer = 5999 |  | ||||||
|                 config.LCD.move_to(0,1) |  | ||||||
|                 config.LCD.putstr("v " + f"{current_timer_div()[0]:02d}:{current_timer_div()[1]:02d}".center(12) + " ^") |  | ||||||
|             else: |  | ||||||
|                 left_was_released = True |  | ||||||
|             if btn_right.value() == 1: |  | ||||||
|                 if right_was_released: |  | ||||||
|                     time_press_start = time_ns() |  | ||||||
|                     right_was_released = False |  | ||||||
|                 sleep(0.1) |  | ||||||
|                 if btn_left.value() == 1:  # exit if both btns are pressed |  | ||||||
|                     set_timer_helper(n, current_timer) |  | ||||||
|                     config.LCD.move_to(0,1)  # move to the second row |  | ||||||
|                     config.LCD.putstr(f"Saved!".center(16))  # show a little info that it is now set |  | ||||||
|                     sleep(0.5) |  | ||||||
|                     while btn_right.value() == 1 or btn_left.value() == 1:  # wait till both btns are released |  | ||||||
|                         pass |  | ||||||
|                     return True |  | ||||||
|                 # define the step width |  | ||||||
|                 time_now = time_ns() |  | ||||||
|                 if (time_now - time_press_start) <= 1*(10**9):  # max. 1 seconds pressed |  | ||||||
|                     current_timer += 1 |  | ||||||
|                 elif (time_now - time_press_start) <= 2*(10**9):  # max. 2 seconds pressed |  | ||||||
|                     current_timer += 5 |  | ||||||
|                 elif (time_now - time_press_start) <= 3*(10**9):  # max. 3 seconds pressed |  | ||||||
|                     current_timer += 10 |  | ||||||
|                 elif (time_now - time_press_start) <= 4*(10**9):  # max. 4 seconds pressed |  | ||||||
|                     current_timer += 30 |  | ||||||
|                 elif (time_now - time_press_start) <= 5*(10**9):  # max. 5 seconds pressed |  | ||||||
|                     current_timer += 60 |  | ||||||
|                 else:  # longer than 5s pressed |  | ||||||
|                     current_timer += 300 |  | ||||||
|                 if current_timer > 5999: current_timer = 1 |  | ||||||
|                 config.LCD.move_to(0,1) |  | ||||||
|                 config.LCD.putstr("v " + f"{current_timer_div()[0]:02d}:{current_timer_div()[1]:02d}".center(12) + " ^") |  | ||||||
|             else: |  | ||||||
|                 right_was_released = True |  | ||||||
|     def set_log_level(): |  | ||||||
|         config.LCD.clear() |  | ||||||
|         current_level = config.LOG_LEVEL |  | ||||||
|         log_levels = ["WARN", "INFO", "DEBUG"] |  | ||||||
|          |  | ||||||
|         config.LCD.putstr(f"Log level".center(16)) |  | ||||||
|         config.LCD.putstr("v " + f"{log_levels[current_level]} ({current_level})".center(12) + " ^")  # show the log level and it's name in the second row |  | ||||||
|         btn_left = config.PIN_IN_BTN_1 |  | ||||||
|         btn_right = config.PIN_IN_BTN_2 |  | ||||||
|         while True: |  | ||||||
|             if btn_left.value() == 1: |  | ||||||
|                 sleep(0.1)  # this value is a good compromise between being able to press both buttons and a fast up/down speed |  | ||||||
|                 if btn_right.value() == 1: |  | ||||||
|                     config.LOG_LEVEL = current_level |  | ||||||
|                     config.LCD.move_to(0,1)  # move to the second row |  | ||||||
|                     config.LCD.putstr(f"Saved!".center(16))  # show a little info that it is now set |  | ||||||
|                     sleep(0.5) |  | ||||||
|                     while btn_right.value() == 1 or btn_left.value() == 1:  # wait till both btns are released |  | ||||||
|                         pass |  | ||||||
|                     return True |  | ||||||
|                  |  | ||||||
|                 current_level -= 1 |  | ||||||
|                 if current_level < 0: current_level = 2 |  | ||||||
|                 config.LCD.move_to(0,0) |  | ||||||
|                 config.LCD.putstr(f"Log level".center(16)) |  | ||||||
|                 config.LCD.putstr("v " + f"{log_levels[current_level]} ({current_level})".center(12) + " ^")  # show the log level and it's name in the second row |  | ||||||
|             if btn_right.value() == 1: |  | ||||||
|                 sleep(0.1) |  | ||||||
|                 if btn_left.value() == 1: |  | ||||||
|                     config.LOG_LEVEL = current_level |  | ||||||
|                     config.LCD.move_to(0,1)  # move to the second row |  | ||||||
|                     config.LCD.putstr(f"Saved!".center(16))  # show a little info that it is now set |  | ||||||
|                     sleep(0.5) |  | ||||||
|                     while btn_right.value() == 1 or btn_left.value() == 1:  # wait till both btns are released |  | ||||||
|                         pass |  | ||||||
|                     return True |  | ||||||
|                 current_level += 1 |  | ||||||
|                 if current_level > 2: current_level = 0 |  | ||||||
|                 config.LCD.move_to(0,0) |  | ||||||
|                 config.LCD.putstr(f"Log level".center(16)) |  | ||||||
|                 config.LCD.putstr("v " + f"{log_levels[current_level]} ({current_level})".center(12) + " ^")  # show the log level and it's name in the second row |  | ||||||
|          |  | ||||||
|     def reset():  # reset all user-settable configuration to the default values |  | ||||||
|         config.LCD.clear() |  | ||||||
|         config.LCD.putstr("Sure about that?") |  | ||||||
|         config.LCD.putstr("< no       yes >") |  | ||||||
|         no_btn = config.PIN_IN_BTN_1 |  | ||||||
|         yes_btn = config.PIN_IN_BTN_2 |  | ||||||
|         while True: |  | ||||||
|             if no_btn.value() == 1: |  | ||||||
|                 return None |  | ||||||
|             if yes_btn.value() == 1: |  | ||||||
|                 config.LCD.putstr("Resetting...".center(16)) |  | ||||||
|                 config.LCD.putstr("Welcome Screen".center(16)) |  | ||||||
|                 config.STARTUP_WELCOME_SHOW = True |  | ||||||
|                 config.STARTUP_WELCOME_CYCLES = 1 |  | ||||||
|                 sleep(0.5) |  | ||||||
|                 config.LCD.move_to(0,1) |  | ||||||
|                 config.LCD.putstr("Timers".center(16)) |  | ||||||
|                 config.TIMER_1_DURATION = 60 |  | ||||||
|                 config.TIMER_2_DURATION = 2400 |  | ||||||
|                 config.TIMER_3_DURATION = 2700 |  | ||||||
|                 sleep(0.5) |  | ||||||
|                 config.LCD.move_to(0,1) |  | ||||||
|                 config.LCD.putstr("Logging".center(16)) |  | ||||||
|                 config.LOG_LEVEL = 1 |  | ||||||
|                 sleep(0.5) |  | ||||||
|                 return True |  | ||||||
|              |  | ||||||
|     settings_programs = [("Show welcome", toggle_show_welcome), |  | ||||||
|                          ("Welcome cycles", welcome_cycles), |  | ||||||
|                          ("Timer 1", lambda: set_n_timer(0)), |  | ||||||
|                          ("Timer 2", lambda: set_n_timer(1)), |  | ||||||
|                          ("Timer 3", lambda: set_n_timer(2)), |  | ||||||
|                          ("Log level", set_log_level), |  | ||||||
|                          ("Reset", reset), |  | ||||||
|                          ("Exit", settings_menu.stop)] |  | ||||||
|     settings_menu.setup(settings_programs)  # give it the callback list |  | ||||||
|     settings_menu.run()  # run the menu until it's closed |  | ||||||
|     del settings_menu, settings_programs |  | ||||||
|     collect() |  | ||||||
|     return True |  | ||||||
| def run_demo_menu(): |  | ||||||
|     def lcd_driver_demo(): |  | ||||||
|         import lcd_driver_demo as ldd |  | ||||||
|         ldd.run(config.LCD) |  | ||||||
|         del ldd |  | ||||||
|         collect() |  | ||||||
|         return True |  | ||||||
|     def lcd_big_hello(): |  | ||||||
|         import lcd_big_hello as lbh |  | ||||||
|         lbh.run(config.LCD) |  | ||||||
|         del lbh |  | ||||||
|         collect() |  | ||||||
|         return True |  | ||||||
|     def input_tests(): |  | ||||||
|         import input_tests as input_tests |  | ||||||
|         input_tests.run(serial_output=False) |  | ||||||
|         del input_tests |  | ||||||
|         collect() |  | ||||||
|         return True |  | ||||||
|     demo_menu = lcdMenu(config.LCD, btn_mapping, scroll_direction=True, cycle=True, hide_menu_name=False, name="DEMOS") |  | ||||||
|     demo_programs = [("LCD Demo", lcd_driver_demo), |  | ||||||
|                      ("Hello world", lcd_big_hello), |  | ||||||
|                      ("Input tests", input_tests), |  | ||||||
|                      ("Exit", demo_menu.stop)] |  | ||||||
|     demo_menu.setup(demo_programs)  # give it the callback list |  | ||||||
|     demo_menu.run() |  | ||||||
|     del demo_menu, demo_programs |  | ||||||
|     collect() |  | ||||||
|     return True |  | ||||||
|  |  | ||||||
| if config.STARTUP_WELCOME_SHOW: | if config.STARTUP_WELCOME_SHOW: | ||||||
|     ws = WelcomeScreen(config.LCD, |     ws = WelcomeScreen(config.LCD, | ||||||
|                        interrupt_pins=[config.PIN_IN_BTN_1, config.PIN_IN_BTN_2, config.PIN_IN_SWITCH], |                        interrupt_pins=[config.PIN_IN_BTN_1, config.PIN_IN_BTN_2, config.PIN_IN_SWITCH], | ||||||
| @@ -353,12 +28,37 @@ if config.STARTUP_WELCOME_SHOW: | |||||||
|     del ws |     del ws | ||||||
|     collect() |     collect() | ||||||
|  |  | ||||||
|  | # extra functions to access the garbage collector | ||||||
|  | def timer(): | ||||||
|  |         import programs.timer as t | ||||||
|  |         t.run(config, btn_mapping, utils.log, lcdMenu) | ||||||
|  |         del t | ||||||
|  |         collect() | ||||||
|  |         return True | ||||||
|  | def manual(): | ||||||
|  |         import programs.manual as m | ||||||
|  |         m.run(config) | ||||||
|  |         del m | ||||||
|  |         collect() | ||||||
|  |         return True | ||||||
|  | def demos(): | ||||||
|  |         import programs.demos as d | ||||||
|  |         d.run(config, btn_mapping, utils.log, lcdMenu) | ||||||
|  |         del d | ||||||
|  |         collect() | ||||||
|  |         return True | ||||||
|  | def settings(): | ||||||
|  |         import programs.settings as s | ||||||
|  |         s.run(config, btn_mapping, utils.log, lcdMenu) | ||||||
|  |         del s | ||||||
|  |         collect() | ||||||
|  |         return True | ||||||
|      |      | ||||||
| # create the menus | # create the menus | ||||||
| main_menu = lcdMenu(config.LCD, btn_mapping, scroll_direction=True, cycle=True, hide_menu_name=False, name="PROGRAMS") | main_menu = lcdMenu(config.LCD, btn_mapping, scroll_direction=True, cycle=True, hide_menu_name=False, name="PROGRAMS") | ||||||
| main_programs = [("Timer", timer), | main_programs = [("Timer", timer), | ||||||
|                  ("Manual", manual), |                  ("Manual", manual), | ||||||
|                  ("Demos", run_demo_menu), |                  ("Demos", demos), | ||||||
|                  ("Settings", settings)] |                  ("Settings", settings)] | ||||||
| main_menu.setup(main_programs)  # give it the callback list | main_menu.setup(main_programs)  # give it the callback list | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										41
									
								
								programs/demos.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								programs/demos.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | |||||||
|  | from gc import collect | ||||||
|  |  | ||||||
|  | # All the arguments this method takes are there for one reason: reduce the amount of libraries loaded into the picos memory and thus improving performance | ||||||
|  | # config: utils.Config object | ||||||
|  | # btn_mapping: a dict containing the btn mapping for the menu operation (given to the lcdMenu object) | ||||||
|  | # log: the utils.log function | ||||||
|  | # lcdMenu: the lcdMenu class (not an object of that class!) | ||||||
|  | def run(config, btn_mapping, log, lcdMenu): | ||||||
|  |     def lcd_driver_demo(): | ||||||
|  |         import demos.lcd_driver_demo as ldd | ||||||
|  |         ldd.run(config.LCD) | ||||||
|  |         del ldd | ||||||
|  |         collect() | ||||||
|  |         return True | ||||||
|  |     def lcd_big_hello(): | ||||||
|  |         import demos.lcd_big_hello as lbh | ||||||
|  |         lbh.run(config.LCD) | ||||||
|  |         del lbh | ||||||
|  |         collect() | ||||||
|  |         return True | ||||||
|  |     def input_tests(): | ||||||
|  |         import demos.input_tests as it | ||||||
|  |         it.run(serial_output=False) | ||||||
|  |         del it | ||||||
|  |         collect() | ||||||
|  |         return True | ||||||
|  |     demo_menu = lcdMenu(config.LCD, btn_mapping, scroll_direction=True, cycle=True, hide_menu_name=False, name="DEMOS") | ||||||
|  |     demo_programs = [("LCD Demo", lcd_driver_demo), | ||||||
|  |                      ("Hello world", lcd_big_hello), | ||||||
|  |                      ("Input tests", input_tests), | ||||||
|  |                      ("Exit", demo_menu.stop)] | ||||||
|  |     demo_menu.setup(demo_programs)  # give it the callback list | ||||||
|  |     demo_menu.run() | ||||||
|  |     return True | ||||||
|  |  | ||||||
|  | if __name__ == "__main__": | ||||||
|  |     from utils import Config, log | ||||||
|  |     from lcdMenu import lcdMenu | ||||||
|  |     config = Config() | ||||||
|  |     btn_mapping = {"ok_btn": config.PIN_IN_BTN_1, "next_btn": config.PIN_IN_BTN_2}  # the btn mapping for all lcdMenus | ||||||
|  |     run(Config(), btn_mapping, log, lcdMenu) | ||||||
							
								
								
									
										17
									
								
								programs/manual.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								programs/manual.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | def run(config): | ||||||
|  |     config.LCD.clear() | ||||||
|  |     set_value = config.PIN_OUT_RELAIS.value() | ||||||
|  |     config.LCD.putstr(f"---- MANUAL ----    State: {set_value}    ") | ||||||
|  |     while True: | ||||||
|  |         if set_value != config.PIN_IN_SWITCH.value(): | ||||||
|  |             config.PIN_OUT_RELAIS.value(config.PIN_IN_SWITCH.value()) | ||||||
|  |             set_value = config.PIN_OUT_RELAIS.value() | ||||||
|  |             config.LCD.putstr(f"---- MANUAL ----    State: {set_value}    ") | ||||||
|  |         if config.PIN_IN_BTN_1.value() == 1 or config.PIN_IN_BTN_2.value() == 1: | ||||||
|  |             return True  # exit on press of these buttons; True to disable the Quitting message from lcdMenu | ||||||
|  |  | ||||||
|  | if __name__ == "__main__": | ||||||
|  |     from utils import Config, log | ||||||
|  |     config = Config() | ||||||
|  |     btn_mapping = {"ok_btn": config.PIN_IN_BTN_1, "next_btn": config.PIN_IN_BTN_2}  # the btn mapping for all lcdMenus | ||||||
|  |     run(Config(), btn_mapping, log) | ||||||
							
								
								
									
										243
									
								
								programs/settings.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										243
									
								
								programs/settings.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,243 @@ | |||||||
|  | from time import sleep, time_ns | ||||||
|  |  | ||||||
|  | # All the arguments this method takes are there for one reason: reduce the amount of libraries loaded into the picos memory and thus improving performance | ||||||
|  | # config: utils.Config object | ||||||
|  | # btn_mapping: a dict containing the btn mapping for the menu operation (given to the lcdMenu object) | ||||||
|  | # log: the utils.log function | ||||||
|  | # lcdMenu: the lcdMenu class (not an object of that class!) | ||||||
|  | def run(config, btn_mapping, log, lcdMenu): | ||||||
|  |     settings_menu = lcdMenu(config.LCD, btn_mapping, scroll_direction=True, cycle=True, hide_menu_name=False, name="SETTINGS") | ||||||
|  |     def toggle_show_welcome(): | ||||||
|  |         current_value = config.STARTUP_WELCOME_SHOW | ||||||
|  |         config.LCD.clear() | ||||||
|  |         config.LCD.putstr(f"Currently {'on' if current_value else 'off'}".center(16)) | ||||||
|  |         config.LCD.putstr("< keep  change >") | ||||||
|  |         keep_btn = config.PIN_IN_BTN_1 | ||||||
|  |         change_btn = config.PIN_IN_BTN_2 | ||||||
|  |         while True: | ||||||
|  |             if keep_btn.value() == 1: | ||||||
|  |                 config.LCD.move_to(0,1)  # move to the second row | ||||||
|  |                 config.LCD.putstr(f"Stay {'on' if current_value else 'off'}!".center(16)) | ||||||
|  |                 sleep(0.5) | ||||||
|  |                 return True | ||||||
|  |             if change_btn.value() == 1: | ||||||
|  |                 config.STARTUP_WELCOME_SHOW = not current_value | ||||||
|  |                 config.LCD.move_to(0,1)  # move to the second row | ||||||
|  |                 config.LCD.putstr(f"Turned {'on' if not current_value else 'off'}!".center(16)) | ||||||
|  |                 sleep(0.5) | ||||||
|  |                 return True | ||||||
|  |     def welcome_cycles(): | ||||||
|  |         config.LCD.clear() | ||||||
|  |         current_cycles = config.STARTUP_WELCOME_CYCLES | ||||||
|  |          | ||||||
|  |         option_down = [" ", "v"][current_cycles>1] | ||||||
|  |         config.LCD.putstr(f"     Cycles     \n{option_down} {str(current_cycles).center(12)} ^") | ||||||
|  |         btn_left = config.PIN_IN_BTN_1 | ||||||
|  |         btn_right = config.PIN_IN_BTN_2 | ||||||
|  |         while True: | ||||||
|  |             if btn_left.value() == 1: | ||||||
|  |                 sleep(0.1)  # this value is a good compromise between being able to press both buttons and a fast up/down speed | ||||||
|  |                 if btn_right.value() == 1: | ||||||
|  |                     config.STARTUP_WELCOME_CYCLES = current_cycles | ||||||
|  |                     config.LCD.move_to(0,1)  # move to the second row | ||||||
|  |                     config.LCD.putstr(f"Saved!".center(16))  # show a little info that it is now set | ||||||
|  |                     sleep(0.5) | ||||||
|  |                     while btn_right.value() == 1 or btn_left.value() == 1:  # wait till both btns are released | ||||||
|  |                         pass | ||||||
|  |                     return True | ||||||
|  |                  | ||||||
|  |                 current_cycles -= 1 | ||||||
|  |                 if current_cycles < 1: current_cycles = 1 | ||||||
|  |                 option_down = [" ", "v"][current_cycles>1] | ||||||
|  |                 config.LCD.putstr(f"     Cycles     \n{option_down} {str(current_cycles).center(12)} ^") | ||||||
|  |             if btn_right.value() == 1: | ||||||
|  |                 sleep(0.1) | ||||||
|  |                 if btn_left.value() == 1: | ||||||
|  |                     config.STARTUP_WELCOME_CYCLES = current_cycles | ||||||
|  |                     config.LCD.move_to(0,1)  # move to the second row | ||||||
|  |                     config.LCD.putstr(f"Saved!".center(16))  # show a little info that it is now set | ||||||
|  |                     sleep(0.5) | ||||||
|  |                     while btn_right.value() == 1 or btn_left.value() == 1:  # wait till both btns are released | ||||||
|  |                         pass | ||||||
|  |                     return True | ||||||
|  |                 current_cycles += 1 | ||||||
|  |                 option_down = [" ", "v"][current_cycles>1] | ||||||
|  |                 config.LCD.putstr(f"     Cycles     \n{option_down} {str(current_cycles).center(12)} ^") | ||||||
|  |      | ||||||
|  |     # with n being the number of the timer (starting at 0) | ||||||
|  |     def set_n_timer(n: int): | ||||||
|  |         # a small helper function to save the value of the n'th timer... | ||||||
|  |         # as you can't programatically access TIMER_n_DURATION | ||||||
|  |         def set_timer_helper(n, value): | ||||||
|  |             if n == 0: | ||||||
|  |                 config.TIMER_1_DURATION = value | ||||||
|  |             elif n == 1: | ||||||
|  |                 config.TIMER_2_DURATION = value | ||||||
|  |             elif n == 2: | ||||||
|  |                 config.TIMER_3_DURATION = value | ||||||
|  |             else: | ||||||
|  |                 log(0, "There are only 3 timers at all. Trying to set the timer number {n} failed.") | ||||||
|  |                  | ||||||
|  |         config.LCD.clear() | ||||||
|  |         timer_values = [config.TIMER_1_DURATION, config.TIMER_2_DURATION, config.TIMER_3_DURATION] | ||||||
|  |         current_timer = timer_values[n]  # get the n'th timer | ||||||
|  |         current_timer_div = lambda: divmod(current_timer, 60) | ||||||
|  |          | ||||||
|  |  | ||||||
|  |         config.LCD.putstr(f"Timer {n+1}".center(16)) | ||||||
|  |         config.LCD.putstr(f"{'v' if current_timer > 1 else ' '} " + f"{current_timer_div()[0]:02d}:{current_timer_div()[1]:02d}".center(12) + " ^") | ||||||
|  |         btn_left = config.PIN_IN_BTN_1 | ||||||
|  |         btn_right = config.PIN_IN_BTN_2 | ||||||
|  |         left_was_released = True | ||||||
|  |         right_was_released = True | ||||||
|  |         while True: | ||||||
|  |             if btn_left.value() == 1: | ||||||
|  |                 if left_was_released: | ||||||
|  |                     time_press_start = time_ns() | ||||||
|  |                     left_was_released = False | ||||||
|  |                 sleep(0.1)  # this value is a good compromise between being able to press both buttons and a fast up/down speed | ||||||
|  |                 if btn_right.value() == 1:  # exit if both btns are pressed | ||||||
|  |                     set_timer_helper(n, current_timer) | ||||||
|  |                     config.LCD.move_to(0,1)  # move to the second row | ||||||
|  |                     config.LCD.putstr(f"Saved!".center(16))  # show a little info that it is now set | ||||||
|  |                     sleep(0.5) | ||||||
|  |                     while btn_right.value() == 1 or btn_left.value() == 1:  # wait till both btns are released | ||||||
|  |                         pass | ||||||
|  |                     return True | ||||||
|  |                 # define the step width | ||||||
|  |                 time_now = time_ns() | ||||||
|  |                 if (time_now - time_press_start) <= 1*(10**9):  # max. 1 seconds pressed | ||||||
|  |                     current_timer -= 1 | ||||||
|  |                 elif (time_now - time_press_start) <= 2*(10**9):  # max. 2 seconds pressed | ||||||
|  |                     current_timer -= 5 | ||||||
|  |                 elif (time_now - time_press_start) <= 3*(10**9):  # max. 3 seconds pressed | ||||||
|  |                     current_timer -= 10 | ||||||
|  |                 elif (time_now - time_press_start) <= 4*(10**9):  # max. 4 seconds pressed | ||||||
|  |                     current_timer -= 30 | ||||||
|  |                 elif (time_now - time_press_start) <= 5*(10**9):  # max. 5 seconds pressed | ||||||
|  |                     current_timer -= 60 | ||||||
|  |                 else:  # longer than 5s pressed | ||||||
|  |                     current_timer -= 300 | ||||||
|  |                 if current_timer < 1: current_timer = 5999 | ||||||
|  |                 config.LCD.move_to(0,1) | ||||||
|  |                 config.LCD.putstr("v " + f"{current_timer_div()[0]:02d}:{current_timer_div()[1]:02d}".center(12) + " ^") | ||||||
|  |             else: | ||||||
|  |                 left_was_released = True | ||||||
|  |             if btn_right.value() == 1: | ||||||
|  |                 if right_was_released: | ||||||
|  |                     time_press_start = time_ns() | ||||||
|  |                     right_was_released = False | ||||||
|  |                 sleep(0.1) | ||||||
|  |                 if btn_left.value() == 1:  # exit if both btns are pressed | ||||||
|  |                     set_timer_helper(n, current_timer) | ||||||
|  |                     config.LCD.move_to(0,1)  # move to the second row | ||||||
|  |                     config.LCD.putstr(f"Saved!".center(16))  # show a little info that it is now set | ||||||
|  |                     sleep(0.5) | ||||||
|  |                     while btn_right.value() == 1 or btn_left.value() == 1:  # wait till both btns are released | ||||||
|  |                         pass | ||||||
|  |                     return True | ||||||
|  |                 # define the step width | ||||||
|  |                 time_now = time_ns() | ||||||
|  |                 if (time_now - time_press_start) <= 1*(10**9):  # max. 1 seconds pressed | ||||||
|  |                     current_timer += 1 | ||||||
|  |                 elif (time_now - time_press_start) <= 2*(10**9):  # max. 2 seconds pressed | ||||||
|  |                     current_timer += 5 | ||||||
|  |                 elif (time_now - time_press_start) <= 3*(10**9):  # max. 3 seconds pressed | ||||||
|  |                     current_timer += 10 | ||||||
|  |                 elif (time_now - time_press_start) <= 4*(10**9):  # max. 4 seconds pressed | ||||||
|  |                     current_timer += 30 | ||||||
|  |                 elif (time_now - time_press_start) <= 5*(10**9):  # max. 5 seconds pressed | ||||||
|  |                     current_timer += 60 | ||||||
|  |                 else:  # longer than 5s pressed | ||||||
|  |                     current_timer += 300 | ||||||
|  |                 if current_timer > 5999: current_timer = 1 | ||||||
|  |                 config.LCD.move_to(0,1) | ||||||
|  |                 config.LCD.putstr("v " + f"{current_timer_div()[0]:02d}:{current_timer_div()[1]:02d}".center(12) + " ^") | ||||||
|  |             else: | ||||||
|  |                 right_was_released = True | ||||||
|  |     def set_log_level(): | ||||||
|  |         config.LCD.clear() | ||||||
|  |         current_level = config.LOG_LEVEL | ||||||
|  |         log_levels = ["WARN", "INFO", "DEBUG"] | ||||||
|  |          | ||||||
|  |         config.LCD.putstr(f"Log level".center(16)) | ||||||
|  |         config.LCD.putstr("v " + f"{log_levels[current_level]} ({current_level})".center(12) + " ^")  # show the log level and it's name in the second row | ||||||
|  |         btn_left = config.PIN_IN_BTN_1 | ||||||
|  |         btn_right = config.PIN_IN_BTN_2 | ||||||
|  |         while True: | ||||||
|  |             if btn_left.value() == 1: | ||||||
|  |                 sleep(0.1)  # this value is a good compromise between being able to press both buttons and a fast up/down speed | ||||||
|  |                 if btn_right.value() == 1: | ||||||
|  |                     config.LOG_LEVEL = current_level | ||||||
|  |                     config.LCD.move_to(0,1)  # move to the second row | ||||||
|  |                     config.LCD.putstr(f"Saved!".center(16))  # show a little info that it is now set | ||||||
|  |                     sleep(0.5) | ||||||
|  |                     while btn_right.value() == 1 or btn_left.value() == 1:  # wait till both btns are released | ||||||
|  |                         pass | ||||||
|  |                     return True | ||||||
|  |                  | ||||||
|  |                 current_level -= 1 | ||||||
|  |                 if current_level < 0: current_level = 2 | ||||||
|  |                 config.LCD.move_to(0,0) | ||||||
|  |                 config.LCD.putstr(f"Log level".center(16)) | ||||||
|  |                 config.LCD.putstr("v " + f"{log_levels[current_level]} ({current_level})".center(12) + " ^")  # show the log level and it's name in the second row | ||||||
|  |             if btn_right.value() == 1: | ||||||
|  |                 sleep(0.1) | ||||||
|  |                 if btn_left.value() == 1: | ||||||
|  |                     config.LOG_LEVEL = current_level | ||||||
|  |                     config.LCD.move_to(0,1)  # move to the second row | ||||||
|  |                     config.LCD.putstr(f"Saved!".center(16))  # show a little info that it is now set | ||||||
|  |                     sleep(0.5) | ||||||
|  |                     while btn_right.value() == 1 or btn_left.value() == 1:  # wait till both btns are released | ||||||
|  |                         pass | ||||||
|  |                     return True | ||||||
|  |                 current_level += 1 | ||||||
|  |                 if current_level > 2: current_level = 0 | ||||||
|  |                 config.LCD.move_to(0,0) | ||||||
|  |                 config.LCD.putstr(f"Log level".center(16)) | ||||||
|  |                 config.LCD.putstr("v " + f"{log_levels[current_level]} ({current_level})".center(12) + " ^")  # show the log level and it's name in the second row | ||||||
|  |          | ||||||
|  |     def reset():  # reset all user-settable configuration to the default values | ||||||
|  |         config.LCD.clear() | ||||||
|  |         config.LCD.putstr("Sure about that?") | ||||||
|  |         config.LCD.putstr("< no       yes >") | ||||||
|  |         no_btn = config.PIN_IN_BTN_1 | ||||||
|  |         yes_btn = config.PIN_IN_BTN_2 | ||||||
|  |         while True: | ||||||
|  |             if no_btn.value() == 1: | ||||||
|  |                 return None | ||||||
|  |             if yes_btn.value() == 1: | ||||||
|  |                 config.LCD.putstr("Resetting...".center(16)) | ||||||
|  |                 config.LCD.putstr("Welcome Screen".center(16)) | ||||||
|  |                 config.STARTUP_WELCOME_SHOW = True | ||||||
|  |                 config.STARTUP_WELCOME_CYCLES = 1 | ||||||
|  |                 sleep(0.5) | ||||||
|  |                 config.LCD.move_to(0,1) | ||||||
|  |                 config.LCD.putstr("Timers".center(16)) | ||||||
|  |                 config.TIMER_1_DURATION = 60 | ||||||
|  |                 config.TIMER_2_DURATION = 2400 | ||||||
|  |                 config.TIMER_3_DURATION = 2700 | ||||||
|  |                 sleep(0.5) | ||||||
|  |                 config.LCD.move_to(0,1) | ||||||
|  |                 config.LCD.putstr("Logging".center(16)) | ||||||
|  |                 config.LOG_LEVEL = 1 | ||||||
|  |                 sleep(0.5) | ||||||
|  |                 return True | ||||||
|  |              | ||||||
|  |     settings_programs = [("Show welcome", toggle_show_welcome), | ||||||
|  |                          ("Welcome cycles", welcome_cycles), | ||||||
|  |                          ("Timer 1", lambda: set_n_timer(0)), | ||||||
|  |                          ("Timer 2", lambda: set_n_timer(1)), | ||||||
|  |                          ("Timer 3", lambda: set_n_timer(2)), | ||||||
|  |                          ("Log level", set_log_level), | ||||||
|  |                          ("Reset", reset), | ||||||
|  |                          ("Exit", settings_menu.stop)] | ||||||
|  |     settings_menu.setup(settings_programs)  # give it the callback list | ||||||
|  |     settings_menu.run()  # run the menu until it's closed | ||||||
|  |  | ||||||
|  | if __name__ == "__main__": | ||||||
|  |     from utils import Config, log | ||||||
|  |     from lcdMenu import lcdMenu | ||||||
|  |     config = Config() | ||||||
|  |     btn_mapping = {"ok_btn": config.PIN_IN_BTN_1, "next_btn": config.PIN_IN_BTN_2}  # the btn mapping for all lcdMenus | ||||||
|  |     run(Config(), btn_mapping, log, lcdMenu) | ||||||
							
								
								
									
										62
									
								
								programs/timer.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								programs/timer.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | |||||||
|  | from time import sleep, time_ns | ||||||
|  |  | ||||||
|  | # All the arguments this method takes are there for one reason: reduce the amount of libraries loaded into the picos memory and thus improving performance | ||||||
|  | # config: utils.Config object | ||||||
|  | # btn_mapping: a dict containing the btn mapping for the menu operation (given to the lcdMenu object) | ||||||
|  | # log: the utils.log function | ||||||
|  | # lcdMenu: the lcdMenu class (not an object of that class!) | ||||||
|  | def run(config, btn_mapping, log, lcdMenu): | ||||||
|  |     timer_menu = lcdMenu(config.LCD, btn_mapping, scroll_direction=True, cycle=True, hide_menu_name=False, name="TIMERS") | ||||||
|  |     timer_values_original = [config.TIMER_1_DURATION, config.TIMER_2_DURATION, config.TIMER_3_DURATION] | ||||||
|  |     timer_values = timer_values_original.copy()  # here, the current timers time is stored when interrupting via the interrupt_pin (see below) | ||||||
|  |     timer_splits = [lambda: divmod(round(timer_values[0]), 60), lambda: divmod(round(timer_values[1]), 60), lambda: divmod(round(timer_values[2]), 60)] | ||||||
|  |     interrupt_pin = config.PIN_IN_BTN_1  # the interrupt btn stops the timer, saves the current time and goes back to the menu | ||||||
|  |     reset_pin = config.PIN_IN_BTN_2  # the reset btn restores the default value | ||||||
|  |     start_stop_pin = config.PIN_IN_SWITCH  # the start_stop switch starts/stops the timer | ||||||
|  |      | ||||||
|  |     # timer_number is the number of the timer that will be run, starting at 1 | ||||||
|  |     # the _timer variable is needed because otherwise python will throw crazy errors regarding "variable accessed before assignment"... | ||||||
|  |     # ...just see it as a copy of the timer_number-1'th elemnt of the timer_values list (see above) | ||||||
|  |     def run_timer(timer_number: int, _timer: int): | ||||||
|  |         config.LCD.clear() | ||||||
|  |         config.LCD.putstr(f"Timer {timer_number}".center(16)) | ||||||
|  |         last_start_stop_value = start_stop_pin.value() | ||||||
|  |         config.PIN_OUT_RELAIS.value(last_start_stop_value) | ||||||
|  |         last_time_ns = time_ns() | ||||||
|  |         while True:  # now run the timer (if the switch is high) | ||||||
|  |             config.LCD.move_to(0,1) | ||||||
|  |             _timer_div = divmod(round(_timer), 60) | ||||||
|  |             config.LCD.putstr(f"{_timer_div[0]:02d}:{_timer_div[1]:02d}".center(16)) | ||||||
|  |             if interrupt_pin.value() == 1: | ||||||
|  |                 timer_values[timer_number-1] = _timer  # save the current state | ||||||
|  |                 last_start_stop_value = 0  # turn the LEDs off! | ||||||
|  |                 config.PIN_OUT_RELAIS.value(last_start_stop_value) | ||||||
|  |                 return None | ||||||
|  |             if reset_pin.value() == 1: | ||||||
|  |                 _timer = timer_values_original[timer_number-1]  # reset the timers | ||||||
|  |             if _timer <= 0: | ||||||
|  |                 config.PIN_OUT_RELAIS.off() | ||||||
|  |                 return True | ||||||
|  |             sleep(0.05) | ||||||
|  |             if last_start_stop_value != (new_value := start_stop_pin.value()): | ||||||
|  |                 last_start_stop_value = new_value | ||||||
|  |                 config.PIN_OUT_RELAIS.value(new_value) | ||||||
|  |                 last_time_ns = time_ns() | ||||||
|  |             if start_stop_pin.value() == 1: | ||||||
|  |                 _timer -= (time_ns() - last_time_ns) / 1000**3 | ||||||
|  |                 last_time_ns = time_ns() | ||||||
|  |      | ||||||
|  |     timer_programs = [(f"T1 - {timer_splits[0]()[0]:02d}:{timer_splits[0]()[1]:02d}", lambda: run_timer(1, timer_values[0])), | ||||||
|  |                       (f"T2 - {timer_splits[1]()[0]:02d}:{timer_splits[1]()[1]:02d}", lambda: run_timer(2, timer_values[1])), | ||||||
|  |                       (f"T3 - {timer_splits[2]()[0]:02d}:{timer_splits[2]()[1]:02d}", lambda: run_timer(3, timer_values[2])), | ||||||
|  |                       ("Exit", timer_menu.stop)] | ||||||
|  |     timer_menu.setup(timer_programs)  # give it the callback list | ||||||
|  |     timer_menu.run() | ||||||
|  |     return True  # disable the "Quitting" message from lcdMenu | ||||||
|  |  | ||||||
|  | if __name__ == "__main__": | ||||||
|  |     from utils import Config, log | ||||||
|  |     from lcdMenu import lcdMenu | ||||||
|  |     config = Config() | ||||||
|  |     btn_mapping = {"ok_btn": config.PIN_IN_BTN_1, "next_btn": config.PIN_IN_BTN_2}  # the btn mapping for all lcdMenus | ||||||
|  |     run(Config(), btn_mapping, log, lcdMenu) | ||||||
		Reference in New Issue
	
	Block a user