Compare commits
10 Commits
v0.4
...
f0d6b49d6e
Author | SHA1 | Date | |
---|---|---|---|
f0d6b49d6e
|
|||
a4adaac9b4
|
|||
78ced9e7ea
|
|||
eb31a92cea
|
|||
fd2a4117b3
|
|||
864a833a43
|
|||
678ebfe7aa
|
|||
9d395bd2b8
|
|||
78933f6090
|
|||
f48315f18e
|
48
README.md
48
README.md
@@ -45,26 +45,29 @@ All the configuration can be done in the [config.json](config.json) file in JSON
|
||||
|
||||
| Attribute name (on top level in config.json) | Type | Description | Default |
|
||||
| -------------------------------------------- | ---- | ----------- | ------- |
|
||||
| "LOG\_LEVEL" | int | defines up to which log level to show log messages in the serial console: warn (0), info (1), debug (2) | 2 |
|
||||
| "STARTUP\_WELCOME\_SHOW" | bool | show the startup screen? | true |
|
||||
| "STARTUP\_PROJECT\_NAME" | str | the name shown at the welcome/startup screen | " UV-Belichter " |
|
||||
| "STARTUP\_MESSAGE\_STARTING | str | the message shown at startup when starting | "Starting..." |
|
||||
| "STARTUP\_PROJECT\_FINISHED" | str | the message shown at startup when finished | " Started! " |
|
||||
| "STARTUP\_WELCOME\_CYCLES" | int | how often the starting string shall go over the welcome screen | 1 |
|
||||
| "PIN\_IN\_BTN\_1" | dict | the dict must contain the "pin" and "pull" keys with respective values | {"pin": 15, "pull": "down"} |
|
||||
| "PIN\_IN\_BTN\_2" | dict | as above | {"pin": 14, "pull": "down"} |
|
||||
| "PIN\_IN\_SWITCH" | dict | as above | {"pin": 13, "pull": "down"} |
|
||||
| "PIN\_OUT\_RELAIS" | int | pin number where the relais is connected | 21 |
|
||||
| "PIN\_SDA" | int | the pin number of the sda wire connected to the lcd | 8 |
|
||||
| "PIN\_SCL" | int | the pin number of the scl wire connected to the lcd | 9 |
|
||||
| "LCD\_I2C\_CH" | int | the channel of the i2c bus used | 0 |
|
||||
| "LCD\_I2C\_ADDR" | int | the i2c address of the lcd; make sure to convert hexadecimal to decimal numbers | 38 |
|
||||
| "LCD\_I2C\_NUM\_ROWS" | int | how many rows for character display has the display? | 2 |
|
||||
| "LCD\_I2C\_NUM\_COLS" | int | and how many characters can it display per row? | 16 |
|
||||
| `"LOG_LEVEL"` | int | defines up to which log level to show log messages in the serial console: warn (0), info (1), debug (2) | `2` |
|
||||
| `"STARTUP_WELCOME_SHOW"` | bool | show the startup screen? | `true` |
|
||||
| `"STARTUP_PROJECT_NAME"` | str | the name shown at the welcome/startup screen | `" UV-Belichter "` |
|
||||
| `"STARTUP_MESSAGE_STARTING"` | str | the message shown at startup when starting | `"Starting..."` |
|
||||
| `"STARTUP_PROJECT_FINISHED"` | str | the message shown at startup when finished | `" Started! "` |
|
||||
| `"STARTUP_WELCOME_CYCLES"` | int | how often the starting string shall go over the welcome screen | `1` |
|
||||
| `"PIN_IN_BTN_1"` | dict | the dict must contain the "pin" and "pull" keys with respective values | `{"pin": 15, "pull": "down"}` |
|
||||
| `"PIN_IN_BTN_2"` | dict | as above | `{"pin": 14, "pull": "down"}` |
|
||||
| `"PIN_IN_SWITCH"` | dict | as above | `{"pin": 13, "pull": "down"}` |
|
||||
| `"PIN_OUT_RELAIS"` | int | pin number where the relais is connected | `21` |
|
||||
| `"PIN_SDA"` | int | the pin number of the sda wire connected to the lcd | `8` |
|
||||
| `"PIN_SCL"` | int | the pin number of the scl wire connected to the lcd | `9` |
|
||||
| `"LCD_I2C_CH"` | int | the channel of the i2c bus used | `0` |
|
||||
| `"LCD_I2C_ADDR"` | int | the i2c address of the lcd; make sure to convert hexadecimal to decimal numbers | `38` |
|
||||
| `"LCD_I2C_NUM\_ROWS"` | int | how many rows for character display has the display? | `2` |
|
||||
| `"LCD_I2C_NUM\_COLS"` | int | and how many characters can it display per row? | `16` |
|
||||
| `"TIMER_1_DURATION"` | int | the timer duration of the first timer; IN SECONDS | `60` (1min) |
|
||||
| `"TIMER_2_DURATION"` | int | as above, but of the seconds timer; IN SECONDS | `2400` (40min) |
|
||||
| `"TIMER_3_DURATION"` | int | as above, but of the third timer; IN SECONDS | `2700` (45min) |
|
||||
|
||||
Note that this software has it's own small wrapper for the config file, e.g. to have instant access to an LCD object generated on the fly. These are all documented in the [utils.py](utils.py) file! When setting configuration options from your custom code, keep in mind that doing this via the `Config().<ATTR_NAME>` way just means writing the value directly to the file, while getting it goes through the wrapper to make e.g. the pin a machine.Pin object. But you just can't write a pin back into an attribute.
|
||||
|
||||
This wont work:
|
||||
This will NOT work:
|
||||
|
||||
```python
|
||||
from utils import Config
|
||||
@@ -101,6 +104,17 @@ So, as the `Config` class uses python's magic function for getting and setting a
|
||||
- [lcdMenu](https://git.privacynerd.de/BlueFox/lcdMenu) - used for the menus
|
||||
|
||||
|
||||
## Learning curve
|
||||
|
||||
Here are some of the websites I learnt a lot from while programming this project - mainly here for documentation reasons.
|
||||
|
||||
- [A handy guide into configuration files in json](https://bhave.sh/micropython-json-config/)
|
||||
- [The official micropython wiki page about the same topic](https://docs.micropython.org/en/latest/library/json.html)
|
||||
- [StackOverflow thread about how to format a json file (used by this project to make it a bit more readable)](https://stackoverflow.com/questions/16311562/python-json-without-whitespaces)
|
||||
- [A guide about magic functions for settings and getting attributes](https://staskoltsov.medium.com/python-magic-methods-to-get-set-attributes-716a12d0b106)
|
||||
- [The official guide into git submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules)
|
||||
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under GPL-3.0-or-later. See [LICENSE](LICENSE).
|
||||
|
@@ -15,4 +15,7 @@
|
||||
"LCD_I2C_ADDR": 39,
|
||||
"LCD_I2C_NUM_ROWS": 2,
|
||||
"LCD_I2C_NUM_COLS": 16,
|
||||
"TIMER_1_DURATION": 60,
|
||||
"TIMER_2_DURATION": 2400,
|
||||
"TIMER_3_DURATION": 2700,
|
||||
}
|
@@ -14,26 +14,13 @@ You should have received a copy of the GNU General Public License along with thi
|
||||
@ Feature: Fades "HELLO" over two lines in and out
|
||||
"""
|
||||
|
||||
import machine
|
||||
import time
|
||||
import config
|
||||
|
||||
lcd = config.LCD
|
||||
|
||||
lcd.custom_char(0, bytearray([0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03])) # right
|
||||
lcd.custom_char(1, bytearray([0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18])) # left
|
||||
lcd.custom_char(2, bytearray([0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F])) # 2-down
|
||||
lcd.custom_char(3, bytearray([0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00])) # 2-up
|
||||
lcd.custom_char(4, bytearray([0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x1F])) # e-up
|
||||
lcd.custom_char(5, bytearray([0x1F,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F])) # e-down
|
||||
lcd.custom_char(6, bytearray([0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x1F])) # l-down
|
||||
lcd.custom_char(7, bytearray([0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18])) # l-right
|
||||
|
||||
line1 = str(chr(0) + chr(2) + chr(1) + chr(0) + chr(4) + " " + chr(1) + " " + chr(1) + " " + chr(0) + chr(3) + chr(1))
|
||||
line2 = str(chr(0) + chr(3) + chr(1) + chr(0) + chr(5) + " " + chr(6) + chr(7) + chr(6) + chr(7) + chr(0) + chr(2) + chr(1))
|
||||
|
||||
|
||||
def right2left(line1, line2, speed=0.3):
|
||||
def right2left(lcd, line1, line2, speed=0.3):
|
||||
padding = " " # 16 spaces
|
||||
line2 = padding + line2 + padding
|
||||
line1 = padding + line1 + padding
|
||||
@@ -44,7 +31,7 @@ def right2left(line1, line2, speed=0.3):
|
||||
time.sleep(speed)
|
||||
|
||||
|
||||
def top2bottom(line1, line2, speed=0.2):
|
||||
def top2bottom(lcd, line1, line2, speed=0.2):
|
||||
lcd.clear()
|
||||
time.sleep(speed)
|
||||
lcd.putstr(line2)
|
||||
@@ -61,7 +48,7 @@ def top2bottom(line1, line2, speed=0.2):
|
||||
lcd.clear()
|
||||
time.sleep(speed)
|
||||
|
||||
def showAll(waitAfter=0.5):
|
||||
def showAll(lcd, waitAfter=0.5):
|
||||
lcd.clear()
|
||||
lcd.putstr(line1)
|
||||
lcd.move_to(0,1)
|
||||
@@ -69,11 +56,21 @@ def showAll(waitAfter=0.5):
|
||||
time.sleep(waitAfter)
|
||||
|
||||
|
||||
def run(): # for the ProgramChooser as callback
|
||||
right2left(line1, line2, 0.2)
|
||||
top2bottom(line1, line2, 0.2)
|
||||
showAll()
|
||||
|
||||
def run(lcd): # for the ProgramChooser as callback
|
||||
lcd.custom_char(0, bytearray([0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03])) # right
|
||||
lcd.custom_char(1, bytearray([0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18])) # left
|
||||
lcd.custom_char(2, bytearray([0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F])) # 2-down
|
||||
lcd.custom_char(3, bytearray([0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00])) # 2-up
|
||||
lcd.custom_char(4, bytearray([0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x1F])) # e-up
|
||||
lcd.custom_char(5, bytearray([0x1F,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F])) # e-down
|
||||
lcd.custom_char(6, bytearray([0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x1F])) # l-down
|
||||
lcd.custom_char(7, bytearray([0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18])) # l-right
|
||||
right2left(lcd, line1, line2, 0.2)
|
||||
top2bottom(lcd, line1, line2, 0.2)
|
||||
showAll(lcd)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
run() # run once
|
||||
from utils import Config
|
||||
cfg = Config()
|
||||
run(cfg.LCD) # run once
|
Submodule lib/lcdMenu updated: 50e9b5211b...4b7e5723ca
226
main.py
226
main.py
@@ -13,7 +13,7 @@ You should have received a copy of the GNU General Public License along with thi
|
||||
import utils
|
||||
from lcdMenu import lcdMenu
|
||||
from WelcomeScreen import WelcomeScreen
|
||||
from time import sleep
|
||||
from time import sleep, time_ns
|
||||
from gc import collect # garbage collector for better memory performance
|
||||
|
||||
config = utils.Config()
|
||||
@@ -30,28 +30,60 @@ def manual():
|
||||
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
|
||||
return True # exit on press of these buttons; True to disable the Quitting message from lcdMenu
|
||||
def timer():
|
||||
# display WIP
|
||||
config.LCD.clear()
|
||||
config.LCD.putstr(" Still work-in-progress")
|
||||
sleep(3)
|
||||
return True # disable the "Quitting" message from lcdMenu
|
||||
def uv_on():
|
||||
config.RELAIS.value(1)
|
||||
config.LCD.clear()
|
||||
config.LCD.putstr("------ UV ------ turned on ")
|
||||
sleep(1)
|
||||
return True # disable the "Quitting" message from lcdMenu
|
||||
def uv_off():
|
||||
config.RELAIS.value(0)
|
||||
config.LCD.clear()
|
||||
config.LCD.putstr("------ UV ------ turned off ")
|
||||
sleep(1)
|
||||
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 lcd_big_hello():
|
||||
import lcd_big_hello as lbh
|
||||
lbh.run()
|
||||
lbh.run(config.LCD)
|
||||
del lbh
|
||||
collect()
|
||||
return True
|
||||
@@ -61,10 +93,152 @@ def input_tests():
|
||||
collect()
|
||||
return True
|
||||
def settings():
|
||||
# display WIP
|
||||
config.LCD.clear()
|
||||
config.LCD.putstr(" Still work-in-progress")
|
||||
sleep(3)
|
||||
settings_menu = lcdMenu(config.LCD, btn_mapping, scroll_direction=True, cycle=True, hide_menu_name=False, name="SETTINGS")
|
||||
def swap_welcome():
|
||||
config.STARTUP_WELCOME_SHOW = not config.STARTUP_WELCOME_SHOW
|
||||
config.LCD.clear()
|
||||
config.LCD.putstr(f" Welcome Screen ")
|
||||
if config.STARTUP_WELCOME_SHOW:
|
||||
config.LCD.putstr("--- Enabled! ---")
|
||||
else:
|
||||
config.LCD.putstr("--- Disabled ---")
|
||||
sleep(1)
|
||||
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"Now set to {current_cycles}".center(16)) # show a little info that it is now set
|
||||
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"Now set to {current_cycles}".center(16)) # show a little info that it is now set
|
||||
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
|
||||
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
|
||||
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
|
||||
|
||||
settings_programs = [("Show welcome", swap_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)),
|
||||
("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():
|
||||
demo_menu = lcdMenu(config.LCD, btn_mapping, scroll_direction=True, cycle=True, hide_menu_name=False, name="DEMOS")
|
||||
@@ -72,10 +246,10 @@ def run_demo_menu():
|
||||
("Input tests", input_tests),
|
||||
("Exit", demo_menu.stop)]
|
||||
demo_menu.setup(demo_programs) # give it the callback list
|
||||
ret = demo_menu.run()
|
||||
demo_menu.run()
|
||||
del demo_menu, demo_programs
|
||||
collect()
|
||||
return ret
|
||||
return True
|
||||
|
||||
if config.STARTUP_WELCOME_SHOW:
|
||||
ws = WelcomeScreen(config.LCD,
|
||||
@@ -92,8 +266,6 @@ if config.STARTUP_WELCOME_SHOW:
|
||||
main_menu = lcdMenu(config.LCD, btn_mapping, scroll_direction=True, cycle=True, hide_menu_name=False, name="PROGRAMS")
|
||||
main_programs = [("Timer", timer),
|
||||
("Manual", manual),
|
||||
("UV off", uv_off),
|
||||
("UV on", uv_on),
|
||||
("Demos", run_demo_menu),
|
||||
("Settings", settings)]
|
||||
main_menu.setup(main_programs) # give it the callback list
|
||||
|
12
utils.py
12
utils.py
@@ -39,7 +39,10 @@ class Config:
|
||||
"LCD_I2C_ADDR", # the i2c adress of the display
|
||||
"LCD_I2C_NUM_ROWS", # how many rows for character display has the display?
|
||||
"LCD_I2C_NUM_COLS", # and how many characters can it display per row?
|
||||
"LCD"] # the actual lcd object (of the PCF8574T I2C_LCD class, see libraries)
|
||||
"LCD", # the actual lcd object (of the PCF8574T I2C_LCD class, see libraries)
|
||||
"TIMER_1_DURATION", # the duration of the first timer in seconds
|
||||
"TIMER_2_DURATION", # the duration of the second first timer in seconds
|
||||
"TIMER_3_DURATION"] # the duration of the third timer in seconds
|
||||
self._config_file = config_file
|
||||
self.load_config()
|
||||
|
||||
@@ -117,8 +120,6 @@ class Config:
|
||||
def __delattr__(self, name):
|
||||
raise AttributeError(f"You may not delete any attribute of the '{self.__class__.__name__}' object")
|
||||
|
||||
cfg = Config()
|
||||
|
||||
|
||||
"""
|
||||
Very simple logging function
|
||||
@@ -131,7 +132,4 @@ def log(log_level: int, message: str):
|
||||
print(f"[LOGGER] Got a message of unknown log level ({log_level}). Original message is printed below.")
|
||||
print(f"{message}")
|
||||
elif cfg.LOG_LEVEL >= log_level: # if log level is valid
|
||||
print(f"[{log_mapping[log_level]}] {message}")
|
||||
|
||||
|
||||
|
||||
print(f"[{log_mapping[log_level]}] {message}")
|
Reference in New Issue
Block a user