Compare commits
4 Commits
678ebfe7aa
...
v0.6
Author | SHA1 | Date | |
---|---|---|---|
78ced9e7ea
|
|||
eb31a92cea
|
|||
fd2a4117b3
|
|||
864a833a43
|
49
README.md
49
README.md
@@ -45,25 +45,25 @@ 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 |
|
| 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` |
|
| `"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_WELCOME_SHOW"` | bool | show the startup screen? | `true` |
|
||||||
| `"STARTUP\_PROJECT\_NAME"` | str | the name shown at the welcome/startup screen | `" UV-Belichter "` |
|
| `"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_MESSAGE_STARTING"` | str | the message shown at startup when starting | `"Starting..."` |
|
||||||
| `"STARTUP\_PROJECT\_FINISHED"` | str | the message shown at startup when finished | `" Started! "` |
|
| `"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` |
|
| `"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_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_BTN_2"` | dict | as above | `{"pin": 14, "pull": "down"}` |
|
||||||
| `"PIN\_IN\_SWITCH"` | dict | as above | `{"pin": 13, "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_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_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` |
|
| `"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_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_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\_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` |
|
| `"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_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_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) |
|
| `"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.
|
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.
|
||||||
|
|
||||||
@@ -104,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
|
- [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
|
## License
|
||||||
|
|
||||||
This project is licensed under GPL-3.0-or-later. See [LICENSE](LICENSE).
|
This project is licensed under GPL-3.0-or-later. See [LICENSE](LICENSE).
|
||||||
|
Submodule lib/lcdMenu updated: 50e9b5211b...4b7e5723ca
47
main.py
47
main.py
@@ -32,10 +32,51 @@ def manual():
|
|||||||
if config.PIN_IN_BTN_1.value() == 1 or config.PIN_IN_BTN_2.value() == 1:
|
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
|
return True # exit on press of these buttons; True to disable the Quitting message from lcdMenu
|
||||||
def timer():
|
def timer():
|
||||||
# display WIP
|
timer_menu = lcdMenu(config.LCD, btn_mapping, scroll_direction=True, cycle=True, hide_menu_name=False, name="TIMERS")
|
||||||
|
timer_values = [config.TIMER_1_DURATION, config.TIMER_2_DURATION, config.TIMER_3_DURATION]
|
||||||
|
timer_splits = [lambda: divmod(round(timer_values[0]), 60), lambda: divmod(round(timer_values[1]), 60), lambda: divmod(round(timer_values[2]), 60)]
|
||||||
|
|
||||||
|
def run_timer(timer_number: int, _timer: int):
|
||||||
|
interrupt_pin = config.PIN_IN_BTN_1
|
||||||
|
reset_pin = config.PIN_IN_BTN_2
|
||||||
|
start_stop_pin = config.PIN_IN_SWITCH
|
||||||
|
original = _timer
|
||||||
config.LCD.clear()
|
config.LCD.clear()
|
||||||
config.LCD.putstr(" Still work-in-progress")
|
config.LCD.putstr(f"Timer {timer_number}".center(16))
|
||||||
sleep(3)
|
last_start_stop_value = start_stop_pin.value()
|
||||||
|
config.PIN_OUT_RELAIS.value(last_start_stop_value)
|
||||||
|
last_time_ns = time_ns()
|
||||||
|
while True:
|
||||||
|
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 = original # 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"{timer_splits[0]()[0]:02d}:{timer_splits[0]()[1]:02d}", lambda: run_timer(1, timer_values[0])),
|
||||||
|
(f"{timer_splits[1]()[0]:02d}:{timer_splits[1]()[1]:02d}", lambda: run_timer(2, timer_values[1])),
|
||||||
|
(f"{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
|
return True # disable the "Quitting" message from lcdMenu
|
||||||
def uv_on():
|
def uv_on():
|
||||||
config.PIN_OUT_RELAIS.value(1)
|
config.PIN_OUT_RELAIS.value(1)
|
||||||
|
6
utils.py
6
utils.py
@@ -39,7 +39,10 @@ class Config:
|
|||||||
"LCD_I2C_ADDR", # the i2c adress of the display
|
"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_ROWS", # how many rows for character display has the display?
|
||||||
"LCD_I2C_NUM_COLS", # and how many characters can it display per row?
|
"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._config_file = config_file
|
||||||
self.load_config()
|
self.load_config()
|
||||||
|
|
||||||
@@ -130,4 +133,3 @@ def log(log_level: int, message: str):
|
|||||||
print(f"{message}")
|
print(f"{message}")
|
||||||
elif cfg.LOG_LEVEL >= log_level: # if log level is valid
|
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