diff --git a/.gitignore b/.gitignore index b33f1fb..29b9988 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ __pycache__ # Configuration files /Makefile.env +/src/lightbar_cfg.py /src/webrepl_cfg.py /src/wlan_cfg.py diff --git a/Makefile b/Makefile index eec6c63..e8cbceb 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ REPL_TTY_PATH = /dev/ttyUSB0 UPLOAD_CACHE_DIR := .upload_cache # Auto-detect all .py files that should be uploaded -SRC_UPLOAD_TARGETS := $(patsubst %.py,$(UPLOAD_CACHE_DIR)/%.py.timestamp,$(wildcard src/*.py src/**/*.py)) +SRC_UPLOAD_TARGETS := $(patsubst %.py,$(UPLOAD_CACHE_DIR)/%.py.timestamp,$(wildcard src/*.py src/**/*.py src/**/**/*.py)) LIB_UPLOAD_TARGETS := $(patsubst %.py,$(UPLOAD_CACHE_DIR)/%.py.timestamp,$(wildcard lib/*.py)) # Default target @@ -55,7 +55,7 @@ $(UPLOAD_CACHE_DIR)/%.py.timestamp :: %.py repl-create-directories: @echo "(Note: If the directory already exists, rshell will print \"Unable to create [DIR]\")" @echo - rshell -p $(REPL_TTY_PATH) mkdir /pyboard/lib /pyboard/lightbar + rshell -p $(REPL_TTY_PATH) mkdir /pyboard/lib /pyboard/lightbar /pyboard/lightbar/endpoints # Clear the .upload_cache directory that contains the last upload timestamps .PHONY: clear-upload-cache clear-upload-cache-src diff --git a/examples/lightbar_cfg.py b/examples/lightbar_cfg.py new file mode 100644 index 0000000..fbb987a --- /dev/null +++ b/examples/lightbar_cfg.py @@ -0,0 +1,10 @@ +# Example file for Lightbar configuration. Copy to src/lightbar_cfg.py, adjust and upload to the board. + +# Port to start the HTTP server on +SERVER_PORT = 80 + +# Whether the HTTP server should be started in debug mode +SERVER_DEBUG = False + +# Amount of LEDs in the lightbar +NEOPIXEL_COUNT = 28 diff --git a/src/lightbar/frontend.py b/src/lightbar/endpoints/frontend.py similarity index 100% rename from src/lightbar/frontend.py rename to src/lightbar/endpoints/frontend.py diff --git a/src/lightbar/rest_api.py b/src/lightbar/endpoints/rest_api.py similarity index 100% rename from src/lightbar/rest_api.py rename to src/lightbar/endpoints/rest_api.py diff --git a/src/lightbar/lightbar_controller.py b/src/lightbar/lightbar_controller.py new file mode 100644 index 0000000..8f34e1c --- /dev/null +++ b/src/lightbar/lightbar_controller.py @@ -0,0 +1,43 @@ +import uasyncio +from machine import Pin +from neopixel import NeoPixel + +# Constants +NEOPIXEL_PIN = 26 + + +class LightbarController: + """ + Controls the LEDs using the NeoPixel library. + """ + neopixel_count: int + neopixel: NeoPixel + + def __init__(self, *, neopixel_count: int): + print('[LightbarController] Initializing Neopixels') + self.neopixel_count = neopixel_count + self.neopixel = NeoPixel(Pin(NEOPIXEL_PIN), neopixel_count) + + def start(self): + uasyncio.create_task(self.run_loop()) + + async def run_loop(self): + print('[LightbarController] Turning on Neopixels') + np = self.neopixel + np.fill((0, 0, 0)) + + color_set = [ + (255, 0, 0), + (255, 255, 0), + (0, 255, 0), + (0, 255, 255), + (0, 0, 255), + (255, 0, 255), + ] + + while True: + for i in range(self.neopixel_count): + np[i] = color_set[i % len(color_set)] + np.write() + + await uasyncio.sleep(0.5) diff --git a/src/lightbar/app.py b/src/lightbar/lightbar_server.py similarity index 67% rename from src/lightbar/app.py rename to src/lightbar/lightbar_server.py index 8e71b58..eafa0b7 100644 --- a/src/lightbar/app.py +++ b/src/lightbar/lightbar_server.py @@ -2,11 +2,14 @@ import machine import uasyncio from microdot_asyncio import Microdot -from lightbar.frontend import frontend -from lightbar.rest_api import rest_api +from lightbar.endpoints.frontend import frontend +from lightbar.endpoints.rest_api import rest_api -class Lightbar(Microdot): +class LightbarServer(Microdot): + """ + Runs the HTTP server to control the lightbar. + """ def __init__(self): super().__init__() self.mount(frontend) diff --git a/src/main.py b/src/main.py index cfd25b4..9375060 100644 --- a/src/main.py +++ b/src/main.py @@ -1,38 +1,18 @@ -from machine import Pin -from neopixel import NeoPixel -import uasyncio +from lightbar.lightbar_controller import LightbarController +from lightbar.lightbar_server import LightbarServer -from lightbar.app import Lightbar +try: + import lightbar_cfg +except Exception as e: + print('[main] Could not import lightbar_cfg.py: {}'.format(str(e))) + raise e -# TODO: Move this to config file -NEOPIXEL_COUNT = 28 +print('[main] Starting lightbar controller') +lightbar_controller = LightbarController(neopixel_count=lightbar_cfg.NEOPIXEL_COUNT) +lightbar_controller.start() +print('[main] Starting lightbar HTTP server') +api_server = LightbarServer() +api_server.run(port=lightbar_cfg.SERVER_PORT, debug=lightbar_cfg.SERVER_DEBUG) -# TODO: Move this into a LightbarController class -async def run_neopixels(): - print('[main/run_neopixels] Turning on Neopixels') - np = NeoPixel(Pin(26), NEOPIXEL_COUNT) - np.fill((0, 0, 0)) - np.write() - - color_set = [ - (255, 0, 0), - (255, 255, 0), - (0, 255, 0), - (0, 255, 255), - (0, 0, 255), - (255, 0, 255), - ] - - while True: - for i in range(NEOPIXEL_COUNT): - np[i] = color_set[i % len(color_set)] - np.write() - - await uasyncio.sleep(0.5) - -uasyncio.create_task(run_neopixels()) - -print('[main] Starting lightbar HTTP server...') -api_server = Lightbar() -api_server.run(port=80, debug=True) +print('[main] HTTP server shut down! End of main')