2024-11-16 15:38:09 +00:00
"""
uv - belichter - software - the SETTINGS submenu
Copyright ( C ) 2024 Benjamin Burkhardt
This program is free software : you can redistribute it and / or modify it under the terms of the GNU General Public License as published by the Free Software Foundation , either version 3 of the License , or ( at your option ) any later version .
This program is distributed in the hope that it will be useful , but WITHOUT ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License for more details .
You should have received a copy of the GNU General Public License along with this program . If not , see < https : / / www . gnu . org / licenses / > .
"""
2024-11-16 15:31:33 +00:00
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 )