diff --git a/Makefile b/Makefile index 05c1c3d..6110bc7 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ setup-python-env: ## Setups python dev environment .PHONY: setup setup: ## Downloads and setups required dependencies mkdir micropython - wget -P micropython https://micropython.org/resources/firmware/rp2-pico-w-20230426-v1.20.0.uf2 + wget -P micropython https://micropython.org/resources/firmware/RPI_PICO_W-20251209-v1.27.0.uf2 mkdir temp cp src/config.py.template src/settings.py diff --git a/main.py b/main.py index 0e5dafd..713fb7f 100644 --- a/main.py +++ b/main.py @@ -1,4 +1,4 @@ -import uasyncio +import asyncio import src from src import settings @@ -9,7 +9,7 @@ def main(): hardware: Hardware = src.hardware.get_hardware() webserver = WebServer(settings.webserver, hardware) - uasyncio.run( webserver.run()) + asyncio.run( webserver.run()) if __name__ == "__main__": diff --git a/src/gunpla/nu_gundam.py b/src/gunpla/nu_gundam.py index 1ac995b..165129c 100644 --- a/src/gunpla/nu_gundam.py +++ b/src/gunpla/nu_gundam.py @@ -1,7 +1,6 @@ +import asyncio import random -import uasyncio - from src.gunpla.base_gundam import BaseGundam from src.pi.led_effect import LEDEffects @@ -24,9 +23,9 @@ async def activation(self) -> None: """ head_led = self._get_led_from_name("head") head_led.on() - await uasyncio.sleep(0.1) + await asyncio.sleep(0.1) head_led.off() - await uasyncio.sleep(0.5) + await asyncio.sleep(0.5) await LEDEffects.brighten(head_led) async def fire_funnels(self) -> None: @@ -52,4 +51,4 @@ async def random_funnels(self) -> None: while True: funnel = random.choice(funnels) await LEDEffects.charge_fire(funnel) - await uasyncio.sleep(random.uniform(0, 3)) + await asyncio.sleep(random.uniform(0, 3)) diff --git a/src/gunpla/unicorn_banshee.py b/src/gunpla/unicorn_banshee.py index 31879bc..e4ee1cc 100644 --- a/src/gunpla/unicorn_banshee.py +++ b/src/gunpla/unicorn_banshee.py @@ -1,4 +1,4 @@ -import uasyncio +import asyncio from src.gunpla.base_gundam import BaseGundam from src.pi.led_effect import LEDEffects @@ -20,5 +20,5 @@ async def glow(self) -> None: Runs the glow lightshow """ await LEDEffects.brighten_all(self.get_all_leds()) - await uasyncio.sleep(3) + await asyncio.sleep(3) self._all_leds_off() diff --git a/src/hardware/Hardware.py b/src/hardware/Hardware.py index 2163619..42a62c6 100644 --- a/src/hardware/Hardware.py +++ b/src/hardware/Hardware.py @@ -17,7 +17,6 @@ def get_pwm(self, pin_obj): def reset_pin(self, pin_num): raise NotImplementedError - @property def networking(self) -> Networking: raise NotImplementedError diff --git a/src/hardware/Networking.py b/src/hardware/Networking.py index 6798760..5cfc6e5 100644 --- a/src/hardware/Networking.py +++ b/src/hardware/Networking.py @@ -1,4 +1,4 @@ -import uasyncio +import asyncio class Networking: @@ -38,7 +38,7 @@ async def connect_to_wifi(self, ssid: str, password: str, attempts=10) -> str: print(f"Connected to {ssid}") return wlan.ifconfig()[0] # Wait to retry - await uasyncio.sleep(1) + await asyncio.sleep(1) print("WiFi failed") raise Exception("WiFi connection failed") diff --git a/src/hardware/PicoHardwre.py b/src/hardware/PicoHardwre.py index 8db8fb0..7b5a45e 100644 --- a/src/hardware/PicoHardwre.py +++ b/src/hardware/PicoHardwre.py @@ -12,17 +12,17 @@ def __init__(self): from machine import PWM, Pin self.Pin = Pin self.PWM = PWM - self.networking = Networking() - self.board_led = BoardLED() + self._networking = Networking() + self._board_led = BoardLED() - def networking(self): + def networking(self) -> Networking: """ :return: networking """ - return self.networking + return self._networking - def board_led(self): - return self.board_led + def board_led(self) -> BoardLED: + return self._board_led def get_pin(self, pin_num, mode="OUT"): # machine.Pin.OUT is an integer constant diff --git a/src/hardware/VirtualHardware.py b/src/hardware/VirtualHardware.py index 541103a..ca8c031 100644 --- a/src/hardware/VirtualHardware.py +++ b/src/hardware/VirtualHardware.py @@ -48,7 +48,7 @@ class NoOpNetworking(Networking): def __init__(self): pass - async def connect_to_wifi(self, ssid: str, password: str, attempts=10) -> str or None: + async def connect_to_wifi(self, ssid: str, password: str, attempts=10) -> str: return "123.123.123.123" def configure_host(self, host_name: str): @@ -76,7 +76,6 @@ def get_pwm(self, pin_obj): def board_led(self) -> BoardLED: return self.MockBoardLED() - @property def networking(self) -> Networking: return self.NoOpNetworking() diff --git a/src/pi/led_effect.py b/src/pi/led_effect.py index 59e1f63..0a7ac92 100644 --- a/src/pi/led_effect.py +++ b/src/pi/led_effect.py @@ -1,7 +1,6 @@ +import asyncio import time -import uasyncio - import src.hardware from src.pi import LED @@ -19,9 +18,9 @@ async def blink(led: LED) -> None: led.on() time.sleep(0.5) led.off() - await uasyncio.sleep(0.5) + await asyncio.sleep(0.5) led.on() - await uasyncio.sleep(0.5) + await asyncio.sleep(0.5) led.off() @staticmethod @@ -32,7 +31,7 @@ async def fire(led: LED) -> None: :return: """ led.on() - await uasyncio.sleep(.5) + await asyncio.sleep(.5) led.off() @staticmethod @@ -42,10 +41,10 @@ async def charge_fire(led: LED, charge_speed: int = 1) -> None: """ await LEDEffects.brighten(led, start_percent=0, end_percent=75, speed=charge_speed) led.off() - await uasyncio.sleep(0.5) + await asyncio.sleep(0.5) # LEDEffects.brighten(led, start_percent=75, end_percent=100, speed=1) led.on() - await uasyncio.sleep(2) + await asyncio.sleep(2) led.off() @staticmethod @@ -70,7 +69,7 @@ async def brighten(led: LED, start_percent: int = 0, end_percent: int = 100, spe for percent in range(start_percent, end_percent, step_rate): duty = int((percent / 100) * 65_535) pwm.duty_u16(duty) - await uasyncio.sleep(sleep_time) + await asyncio.sleep(sleep_time) pwm.deinit() @staticmethod @@ -97,7 +96,7 @@ async def brighten_all(leds: list[LED], start_percent: int = 0, end_percent: int duty = int((percent / 100) * 65_535) for pwm in pwms: pwm.duty_u16(duty) - await uasyncio.sleep(sleep_time) + await asyncio.sleep(sleep_time) for pwm in pwms: pwm.deinit() diff --git a/src/server/RouteDecorator.py b/src/server/RouteDecorator.py index 18c5f80..e9f2a19 100644 --- a/src/server/RouteDecorator.py +++ b/src/server/RouteDecorator.py @@ -1,4 +1,4 @@ -import uasyncio +import asyncio def lightshow_route(gunpla, manager_attr="current_task"): @@ -15,11 +15,11 @@ async def wrapper(request, *args, **kwargs): try: gunpla.all_off() await existing_task # Wait for cleanup - except uasyncio.CancelledError: + except asyncio.CancelledError: pass # Start the new show and track it - task = uasyncio.create_task(func()) + task = asyncio.create_task(func()) setattr(gunpla, manager_attr, task) # Return common HTTP response that the show started. diff --git a/src/server/microdot/Microdot.py b/src/server/microdot/Microdot.py index 33e402b..04da2ec 100644 --- a/src/server/microdot/Microdot.py +++ b/src/server/microdot/Microdot.py @@ -5,12 +5,11 @@ The ``microdot`` module defines a few classes that help implement HTTP-based servers for MicroPython and standard Python. """ +import asyncio import io import re import time -import uasyncio - try: import orjson as json except ImportError: @@ -28,7 +27,7 @@ async def invoke_handler(handler, *args, **kwargs): if iscoroutinefunction(handler): ret = await handler(*args, **kwargs) else: - ret = await uasyncio.get_running_loop().run_in_executor( + ret = await asyncio.get_running_loop().run_in_executor( None, partial(handler, *args, **kwargs)) return ret except ImportError: # pragma: no cover @@ -38,7 +37,7 @@ def iscoroutine(coro): async def invoke_handler(handler, *args, **kwargs): """Invoke a handler and return the result. - This method runs sync handlers in the uasyncio thread, which can + This method runs sync handlers in the asyncio thread, which can potentially cause blocking and performance issues. """ ret = handler(*args, **kwargs) @@ -1240,7 +1239,7 @@ async def start_server(self, host='0.0.0.0', port=5000, debug=False, Example:: - import uasyncio + import asyncio from microdot import Microdot app = Microdot() @@ -1252,7 +1251,7 @@ async def index(request): async def main(): await app.start_server(debug=True) - uasyncio.run(main()) + asyncio.run(main()) """ self.ssl = ssl self.debug = debug @@ -1279,24 +1278,24 @@ async def aclose(self): host=host, port=port)) try: - self.server = await uasyncio.start_server(serve, host, port, - ssl=ssl) + self.server = await asyncio.start_server(serve, host, port, + ssl=ssl) except TypeError: # pragma: no cover - self.server = await uasyncio.start_server(serve, host, port) + self.server = await asyncio.start_server(serve, host, port) while True: try: if hasattr(self.server, 'serve_forever'): # pragma: no cover try: await self.server.serve_forever() - except uasyncio.CancelledError: + except asyncio.CancelledError: pass await self.server.wait_closed() break except AttributeError: # pragma: no cover # the task hasn't been initialized in the server object yet # wait a bit and try again - await uasyncio.sleep(0.1) + await asyncio.sleep(0.1) def run(self, host='0.0.0.0', port=5000, debug=False, ssl=None): """Start the web server. This function does not normally return, as @@ -1329,8 +1328,8 @@ async def index(request): app.run(debug=True) """ - uasyncio.run(self.start_server(host=host, port=port, debug=debug, - ssl=ssl)) # pragma: no cover + asyncio.run(self.start_server(host=host, port=port, debug=debug, + ssl=ssl)) # pragma: no cover def shutdown(self): """Request a server shutdown. The server will then exit its request diff --git a/src/server/webserver.py b/src/server/webserver.py index f763de9..025cd63 100644 --- a/src/server/webserver.py +++ b/src/server/webserver.py @@ -1,7 +1,6 @@ +import asyncio import sys -import uasyncio - from src.gunpla.generic_gundam import GenericGundam from src.hardware.Hardware import Hardware from src.pi.led_effect import LEDEffects @@ -33,14 +32,14 @@ async def canary(self, request: Request): """ Sanity check to make sure webserver is running. """ - uasyncio.create_task(LEDEffects.blink(self.hardware.board_led)) + asyncio.create_task(LEDEffects.blink(self.hardware.board_led)) return "chirp", 202 async def _connect_to_wifi(self): - ipaddress: str = await self.hardware.networking.connect_to_wifi(self.settings['ssid'], self.settings['password']) + ipaddress: str = await self.hardware.networking().connect_to_wifi(self.settings['ssid'], self.settings['password']) if ipaddress: print(f"Server started on {ipaddress}") - await LEDEffects.blink(self.hardware.board_led) + await LEDEffects.blink(self.hardware.board_led()) else: print("Server failed to connect") sys.exit("Cannot start server") @@ -50,7 +49,7 @@ async def run(self): Main runner of the webserver. Loads configurations, paths, connects to wifi and runs the server """ - self.hardware.networking.configure_host(self.settings['hostname']) + self.hardware.networking().configure_host(self.settings['hostname']) await self._connect_to_wifi() self._add_routes() diff --git a/tests/LocalServerTest.py b/tests/LocalServerTest.py index 011c137..9d74f6d 100644 --- a/tests/LocalServerTest.py +++ b/tests/LocalServerTest.py @@ -1,8 +1,7 @@ +import asyncio import json -import uasyncio - from src.gunpla.generic_gundam import GenericGundam from src.hardware.VirtualHardware import VirtualHardware from src.server.webserver import WebServer @@ -55,7 +54,7 @@ def main(): } webserver = WebServer(test_settings, VirtualHardware()) - uasyncio.run(webserver.run()) + asyncio.run(webserver.run()) if __name__ == "__main__":