Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions examples/upgrade.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
"""Asynchronous Python client for WLED."""

import asyncio
import sys

from wled import WLED, WLEDReleases


async def main() -> None:
"""Show example on upgrade your WLED device."""
# async with WLEDReleases("MoonModules/WLED") as releases:
async with WLEDReleases() as releases:
latest = await releases.releases()
print(f"Latest stable version: {latest.stable}")
Expand All @@ -17,12 +19,13 @@ async def main() -> None:
print("No stable version found")
return

async with WLED("10.10.11.54") as led:
async with WLED(sys.argv[1]) as led:
device = await led.update()
print(f"Current version: {device.info.version}")
print(f"Current release: {device.info.release}")

print("Upgrading WLED....")
await led.upgrade(version=latest.stable)
await led.upgrade(version=latest.stable,repo=latest.repo) # stable not default option

print("Waiting for WLED to come back....")
await asyncio.sleep(5)
Expand Down
1 change: 1 addition & 0 deletions src/wled/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

MIN_REQUIRED_VERSION = AwesomeVersion("0.14.0")

WLED_DEFAULT_REPO = "Aircoookie/WLED"

class LightCapability(IntFlag):
"""Enumeration representing the capabilities of a light in WLED."""
Expand Down
4 changes: 4 additions & 0 deletions src/wled/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,9 @@ class Info(BaseModel): # pylint: disable=too-many-instance-attributes
)
"""Version of the WLED software."""

release: str | None = field(metadata=field_options(alias="release"))
"""Release info of the WLED software."""

websocket: int | None = field(default=None, metadata=field_options(alias="ws"))
"""
Number of currently connected WebSockets clients.
Expand Down Expand Up @@ -847,3 +850,4 @@ class Releases(BaseModel):

beta: AwesomeVersion | None
stable: AwesomeVersion | None
repo: str
18 changes: 14 additions & 4 deletions src/wled/wled.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import orjson
from yarl import URL

from wled.const import WLED_DEFAULT_REPO

from .exceptions import (
WLEDConnectionClosedError,
WLEDConnectionError,
Expand Down Expand Up @@ -572,7 +574,7 @@ async def nightlight(
nightlight = {k: v for k, v in nightlight.items() if v is not None}
await self.request("/json/state", method="POST", data={"nl": nightlight})

async def upgrade(self, *, version: str | AwesomeVersion) -> None:
async def upgrade(self, *, version: str | AwesomeVersion, repo) -> None:
"""Upgrades WLED device to the specified version.

Args:
Expand Down Expand Up @@ -637,7 +639,7 @@ async def upgrade(self, *, version: str | AwesomeVersion) -> None:
architecture = self._device.info.architecture.upper()
update_file = f"WLED_{version}_{architecture}{ethernet}.bin{gzip}"
download_url = (
"https://github.com/Aircoookie/WLED/releases/download"
f"https://github.com/{repo}/releases/download"
f"/v{version}/{update_file}"
)

Expand All @@ -659,7 +661,7 @@ async def upgrade(self, *, version: str | AwesomeVersion) -> None:
raise WLEDConnectionTimeoutError(msg) from exception
except aiohttp.ClientResponseError as exception:
if exception.status == 404:
msg = f"Requested WLED version '{version}' does not exists"
msg = f"Requested WLED bin {update_file} for version '{version}' does not exists"
raise WLEDUpgradeError(msg) from exception
msg = (
f"Could not download requested WLED version '{version}'"
Expand Down Expand Up @@ -710,10 +712,16 @@ class WLEDReleases:

request_timeout: float = 8.0
session: aiohttp.client.ClientSession | None = None
repo: str = WLED_DEFAULT_REPO


_client: aiohttp.ClientWebSocketResponse | None = None
_close_session: bool = False

def __init__(self, repo=None):
if repo is not None:
self.repo = repo

@backoff.on_exception(backoff.expo, WLEDConnectionError, max_tries=3, logger=None)
async def releases(self) -> Releases:
"""Fetch WLED version information from GitHub.
Expand All @@ -736,10 +744,11 @@ async def releases(self) -> Releases:
self.session = aiohttp.ClientSession()
self._close_session = True

print(f"https://api.github.com/repos/{self.repo}/releases")
try:
async with asyncio.timeout(self.request_timeout):
response = await self.session.get(
"https://api.github.com/repos/Aircoookie/WLED/releases",
f"https://api.github.com/repos/{self.repo}/releases",
headers={"Accept": "application/json"},
)
except asyncio.TimeoutError as exception:
Expand Down Expand Up @@ -784,6 +793,7 @@ async def releases(self) -> Releases:
return Releases(
beta=version_latest_beta,
stable=version_latest,
repo=self.repo,
)

async def close(self) -> None:
Expand Down