From 04be6626a73008ef33a2e5afc86b546187b4bcec Mon Sep 17 00:00:00 2001 From: Nathan Spencer Date: Mon, 24 Nov 2025 04:37:10 +0000 Subject: [PATCH] Formatting --- .pre-commit-config.yaml | 2 +- LICENSE | 2 +- custom_components/oasis_mini/entity.py | 6 ++-- custom_components/oasis_mini/helpers.py | 16 ++++----- custom_components/oasis_mini/icons.json | 2 +- custom_components/oasis_mini/light.py | 18 +++++----- custom_components/oasis_mini/media_player.py | 36 +++++++++---------- .../oasis_mini/pyoasiscontrol/device.py | 2 +- custom_components/oasis_mini/select.py | 24 ++++++------- custom_components/oasis_mini/sensor.py | 1 - custom_components/oasis_mini/update.py | 14 ++++---- 11 files changed, 61 insertions(+), 62 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ffae41e..93382fc 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,7 +1,7 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.9.10 + rev: v0.14.6 hooks: # Run the linter. - id: ruff diff --git a/LICENSE b/LICENSE index cf5176c..80b43d6 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2024 Nathan Spencer +Copyright (c) Nathan Spencer Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/custom_components/oasis_mini/entity.py b/custom_components/oasis_mini/entity.py index 2a6a511..ff0087b 100644 --- a/custom_components/oasis_mini/entity.py +++ b/custom_components/oasis_mini/entity.py @@ -24,9 +24,9 @@ class OasisDeviceEntity(CoordinatorEntity[OasisDeviceCoordinator]): ) -> None: """ Initialize an entity representing an Oasis device. - + Sets the entity's unique_id from the device serial number and the provided description key, stores the given device on the entity, and constructs DeviceInfo containing identifiers, name, manufacturer, model, software version, and a network MAC connection if the device exposes a MAC address. - + Parameters: coordinator: The coordinator responsible for updating the device state. device: OasisDevice instance providing metadata and identifiers (serial_number, mac_address, name, manufacturer, model, software_version). @@ -51,4 +51,4 @@ class OasisDeviceEntity(CoordinatorEntity[OasisDeviceCoordinator]): model=device.model, serial_number=serial_number, sw_version=device.software_version, - ) \ No newline at end of file + ) diff --git a/custom_components/oasis_mini/helpers.py b/custom_components/oasis_mini/helpers.py index 9120ba4..2b06f04 100644 --- a/custom_components/oasis_mini/helpers.py +++ b/custom_components/oasis_mini/helpers.py @@ -21,11 +21,11 @@ _LOGGER = logging.getLogger(__name__) def create_client(hass: HomeAssistant, data: dict[str, Any]) -> OasisCloudClient: """ Create an Oasis cloud client configured with the Home Assistant HTTP session and access token. - + Parameters: hass: Home Assistant instance used to obtain the shared HTTP client session. data: Configuration mapping; the function reads the `CONF_ACCESS_TOKEN` key for the cloud access token. - + Returns: An `OasisCloudClient` initialized with the Home Assistant HTTP session and the configured access token. """ @@ -36,13 +36,13 @@ def create_client(hass: HomeAssistant, data: dict[str, Any]) -> OasisCloudClient async def add_and_play_track(device: OasisDevice, track: int) -> None: """ Ensure a track is present in the device playlist, position it as the next item, select it, and start playback if necessary. - + Adds the specified track to the device playlist if missing, waits up to 10 seconds for the track to appear, moves it to be the next item after the current playlist index if needed, selects that track, and starts playback when the device is not already playing. - + Parameters: device (OasisDevice): The target Oasis device. track (int): The track id to add and play. - + Raises: async_timeout.TimeoutError: If the operation does not complete within 10 seconds. """ @@ -68,10 +68,10 @@ async def add_and_play_track(device: OasisDevice, track: int) -> None: def get_track_id(track: str) -> int | None: """ Convert a track identifier or title to its integer track id. - + Parameters: track: A track reference, either a numeric id as a string or a track title. - + Returns: The integer track id if the input is a valid id or matches a known title, `None` if the input is invalid. """ @@ -85,4 +85,4 @@ def get_track_id(track: str) -> int | None: return int(track) except ValueError: _LOGGER.warning("Invalid track: %s", track) - return None \ No newline at end of file + return None diff --git a/custom_components/oasis_mini/icons.json b/custom_components/oasis_mini/icons.json index c6ecebc..3a96f57 100644 --- a/custom_components/oasis_mini/icons.json +++ b/custom_components/oasis_mini/icons.json @@ -44,4 +44,4 @@ } } } -} +} \ No newline at end of file diff --git a/custom_components/oasis_mini/light.py b/custom_components/oasis_mini/light.py index 2953e0c..3d3df29 100644 --- a/custom_components/oasis_mini/light.py +++ b/custom_components/oasis_mini/light.py @@ -39,10 +39,10 @@ async def async_setup_entry( def make_entities(new_devices: list[OasisDevice]): """ Create OasisDeviceLightEntity instances for each provided Oasis device. - + Parameters: new_devices (list[OasisDevice]): Devices to wrap as light entities. - + Returns: list[OasisDeviceLightEntity]: A list of light entity instances corresponding to the input devices. """ @@ -65,8 +65,8 @@ class OasisDeviceLightEntity(OasisDeviceEntity, LightEntity): @property def brightness(self) -> int: """ - Get the light's brightness on a 0–255 scale. - + Get the light's brightness on a 0-255 scale. + Returns: int: Brightness value between 0 and 255. """ @@ -120,19 +120,19 @@ class OasisDeviceLightEntity(OasisDeviceEntity, LightEntity): async def async_turn_on(self, **kwargs: Any) -> None: """ Turn the light on and set its LED state. - + Processes optional keyword arguments to compute the device-specific LED parameters, then updates the device's LEDs with the resulting brightness, color, and effect. - + Parameters: kwargs: Optional control parameters recognized by the method: - ATTR_BRIGHTNESS (int): Brightness in the 0–255 Home Assistant scale. When provided, + ATTR_BRIGHTNESS (int): Brightness in the 0-255 Home Assistant scale. When provided, it is converted and rounded up to the device's brightness scale (1..device.brightness_max). When omitted, uses self.device.brightness or self.device.brightness_on. ATTR_RGB_COLOR (tuple[int, int, int]): RGB tuple (R, G, B). When provided, it is converted to a hex color string prefixed with '#'. ATTR_EFFECT (str): Human-readable effect name. When provided, it is mapped to the device's internal effect key; if no mapping exists, `None` is used. - + Side effects: Updates the underlying device LED state with the computed `brightness`, `color`, and `led_effect`. """ @@ -152,4 +152,4 @@ class OasisDeviceLightEntity(OasisDeviceEntity, LightEntity): await self.device.async_set_led( brightness=brightness, color=color, led_effect=led_effect - ) \ No newline at end of file + ) diff --git a/custom_components/oasis_mini/media_player.py b/custom_components/oasis_mini/media_player.py index a025052..8c3c53b 100644 --- a/custom_components/oasis_mini/media_player.py +++ b/custom_components/oasis_mini/media_player.py @@ -35,10 +35,10 @@ async def async_setup_entry( def make_entities(new_devices: list[OasisDevice]): """ Create media player entities for the given Oasis devices. - + Parameters: new_devices (list[OasisDevice]): Devices to wrap as media player entities. - + Returns: list[OasisDeviceMediaPlayerEntity]: Media player entities corresponding to each device. """ @@ -85,7 +85,7 @@ class OasisDeviceMediaPlayerEntity(OasisDeviceEntity, MediaPlayerEntity): def media_image_url(self) -> str | None: """ URL of the image representing the currently playing media. - + Returns: The image URL as a string, or `None` if no image is available. """ @@ -95,7 +95,7 @@ class OasisDeviceMediaPlayerEntity(OasisDeviceEntity, MediaPlayerEntity): def media_position(self) -> int: """ Playback position of the current media in seconds. - + Returns: int: Position in seconds of the currently playing media. """ @@ -110,7 +110,7 @@ class OasisDeviceMediaPlayerEntity(OasisDeviceEntity, MediaPlayerEntity): def media_title(self) -> str | None: """ Provide the title of the currently playing track. - + Returns: str | None: The track title, or None if no title is available. """ @@ -120,7 +120,7 @@ class OasisDeviceMediaPlayerEntity(OasisDeviceEntity, MediaPlayerEntity): def repeat(self) -> RepeatMode: """ Get the current repeat mode for the device. - + Returns: `RepeatMode.ALL` if the device is configured to repeat the playlist, `RepeatMode.OFF` otherwise. """ @@ -156,7 +156,7 @@ class OasisDeviceMediaPlayerEntity(OasisDeviceEntity, MediaPlayerEntity): async def async_media_pause(self) -> None: """ Pause playback on the device. - + Raises: ServiceValidationError: If the device is busy and cannot accept commands. """ @@ -166,7 +166,7 @@ class OasisDeviceMediaPlayerEntity(OasisDeviceEntity, MediaPlayerEntity): async def async_media_play(self) -> None: """ Start playback on the device. - + Raises: ServiceValidationError: If the device is currently busy. """ @@ -176,7 +176,7 @@ class OasisDeviceMediaPlayerEntity(OasisDeviceEntity, MediaPlayerEntity): async def async_media_stop(self) -> None: """ Stop playback on the Oasis device. - + Raises: ServiceValidationError: If the device is currently busy. """ @@ -186,12 +186,12 @@ class OasisDeviceMediaPlayerEntity(OasisDeviceEntity, MediaPlayerEntity): async def async_set_repeat(self, repeat: RepeatMode) -> None: """ Set the device playlist repeat behavior. - + Enables or disables looping of the playlist according to the provided RepeatMode: - RepeatMode.OFF disables playlist repeat. - RepeatMode.ALL enables playlist repeat for the entire playlist. - RepeatMode.ONE enables single-track repeat, except when the device is currently repeating the entire playlist; in that case the playlist repeat is disabled to preserve single-track semantics. - + Parameters: repeat (RepeatMode): The desired repeat mode to apply to the device playlist. """ @@ -203,7 +203,7 @@ class OasisDeviceMediaPlayerEntity(OasisDeviceEntity, MediaPlayerEntity): async def async_media_previous_track(self) -> None: """ Move playback to the previous track in the device's playlist, wrapping to the last track when currently at the first. - + Raises: ServiceValidationError: If the device is busy. """ @@ -215,7 +215,7 @@ class OasisDeviceMediaPlayerEntity(OasisDeviceEntity, MediaPlayerEntity): async def async_media_next_track(self) -> None: """ Advance the device to the next track in its playlist, wrapping to the first track when at the end. - + Raises: ServiceValidationError: if the device is busy. """ @@ -233,14 +233,14 @@ class OasisDeviceMediaPlayerEntity(OasisDeviceEntity, MediaPlayerEntity): ) -> None: """ Play or enqueue one or more Oasis tracks on the device. - + Validates the media type and parses one or more track identifiers from `media_id`, then updates the device playlist according to `enqueue`. Depending on the enqueue mode the method can replace the playlist, append tracks, move appended tracks to the next play position, and optionally start playback. - + Parameters: media_type (MediaType | str): The media type being requested. media_id (str): A comma-separated string of track identifiers. enqueue (MediaPlayerEnqueue | None): How to insert the tracks into the playlist; if omitted defaults to NEXT. - + Raises: ServiceValidationError: If the device is busy, if `media_type` is a playlist (playlists are unsupported), or if `media_id` does not contain any valid track identifiers. """ @@ -287,9 +287,9 @@ class OasisDeviceMediaPlayerEntity(OasisDeviceEntity, MediaPlayerEntity): async def async_clear_playlist(self) -> None: """ Clear the device's playlist. - + Raises: ServiceValidationError: If the device is busy and cannot accept commands. """ self.abort_if_busy() - await self.device.async_clear_playlist() \ No newline at end of file + await self.device.async_clear_playlist() diff --git a/custom_components/oasis_mini/pyoasiscontrol/device.py b/custom_components/oasis_mini/pyoasiscontrol/device.py index cf305b9..d88895b 100644 --- a/custom_components/oasis_mini/pyoasiscontrol/device.py +++ b/custom_components/oasis_mini/pyoasiscontrol/device.py @@ -418,7 +418,7 @@ class OasisDevice: If the current track or its SVG content is unavailable, returns None. Returns: - progress_percent (float | None): Percentage of the drawing completed (0–100), clamped to 100; `None` if no track or SVG content is available. + progress_percent (float | None): Percentage of the drawing completed (0-100), clamped to 100; `None` if no track or SVG content is available. """ if not (self.track and (svg_content := self.track.get("svg_content"))): return None diff --git a/custom_components/oasis_mini/select.py b/custom_components/oasis_mini/select.py index 97c81c1..ccc8f3b 100644 --- a/custom_components/oasis_mini/select.py +++ b/custom_components/oasis_mini/select.py @@ -24,11 +24,11 @@ AUTOPLAY_MAP_LIST = list(AUTOPLAY_MAP) def playlists_update_handler(entity: OasisDeviceSelectEntity) -> None: """ Update the playlists select options and current option from the device's cloud playlists. - + Iterates the device's cloud playlists to build a display list of playlist names (appending " (N)" for duplicate names) and sets the entity's options to that list. If the device's current playlist matches a playlist's pattern IDs, sets the entity's current option to that playlist's display name; otherwise leaves it None. - + Parameters: entity (OasisDeviceSelectEntity): The select entity to update. """ @@ -52,9 +52,9 @@ def playlists_update_handler(entity: OasisDeviceSelectEntity) -> None: def queue_update_handler(entity: OasisDeviceSelectEntity) -> None: """ Update the select options and current selection for the device's playback queue. - + Populate the entity's options from the device's current playlist and playlist details, disambiguating duplicate track names by appending a counter (e.g., "Title (2)"). Set the entity's current option to the track at device.playlist_index (or None if the queue is empty). - + Parameters: entity (OasisDeviceSelectEntity): The select entity whose options and current option will be updated. """ @@ -88,9 +88,9 @@ async def async_setup_entry( ) -> None: """ Set up select entities for each Oasis device from a config entry. - + Creates OasisDeviceSelectEntity instances for every device and descriptor and registers them with Home Assistant via the platform setup. - + Parameters: hass: Home Assistant instance. entry: Oasis device config entry used to locate coordinator and runtime data. @@ -100,10 +100,10 @@ async def async_setup_entry( def make_entities(new_devices: list[OasisDevice]): """ Create select entity instances for each provided Oasis device. - + Parameters: new_devices (list[OasisDevice]): Devices to create select entities for. - + Returns: list[OasisDeviceSelectEntity]: A flat list of OasisDeviceSelectEntity objects created for every combination of device and descriptor. """ @@ -169,7 +169,7 @@ class OasisDeviceSelectEntity(OasisDeviceEntity, SelectEntity): ) -> None: """ Initialize the Oasis device select entity and perform an initial coordinator update. - + Parameters: coordinator (OasisDeviceCoordinator): Coordinator that manages device updates. device (OasisDevice): The Oasis device this entity represents. @@ -181,7 +181,7 @@ class OasisDeviceSelectEntity(OasisDeviceEntity, SelectEntity): async def async_select_option(self, option: str) -> None: """ Select and apply the option identified by its display string. - + Parameters: option (str): The display string of the option to select; the option's index in the current options list is used to apply the selection. """ @@ -191,7 +191,7 @@ class OasisDeviceSelectEntity(OasisDeviceEntity, SelectEntity): def _handle_coordinator_update(self) -> None: """ Update the entity's cached value and current option when coordinator data changes. - + If the derived current value differs from the stored value, update the stored value. If the entity description provides an update_handler, call it with this entity; otherwise, set the entity's current option to the string form of the device attribute named by the @@ -209,4 +209,4 @@ class OasisDeviceSelectEntity(OasisDeviceEntity, SelectEntity): getattr(self.device, self.entity_description.key) ) if self.hass: - return super()._handle_coordinator_update() \ No newline at end of file + return super()._handle_coordinator_update() diff --git a/custom_components/oasis_mini/sensor.py b/custom_components/oasis_mini/sensor.py index 8993500..7f62975 100644 --- a/custom_components/oasis_mini/sensor.py +++ b/custom_components/oasis_mini/sensor.py @@ -77,7 +77,6 @@ DESCRIPTORS.extend( entity_registry_enabled_default=False, ) for key in ("error", "led_color_id", "status") - # for key in ("error_message", "led_color_id", "status") ) diff --git a/custom_components/oasis_mini/update.py b/custom_components/oasis_mini/update.py index 880017e..17e3ffa 100644 --- a/custom_components/oasis_mini/update.py +++ b/custom_components/oasis_mini/update.py @@ -31,7 +31,7 @@ async def async_setup_entry( ) -> None: """ Set up update entities for Oasis devices from a configuration entry. - + Parameters: hass (HomeAssistant): Home Assistant core instance. entry (OasisDeviceConfigEntry): Config entry containing runtime data used to create device update entities. @@ -41,10 +41,10 @@ async def async_setup_entry( def make_entities(new_devices: list[OasisDevice]): """ Create update entities for the given Oasis devices. - + Parameters: new_devices (list[OasisDevice]): Devices to create update entities for. - + Returns: list: A list of OasisDeviceUpdateEntity instances corresponding to each device. """ @@ -90,9 +90,9 @@ class OasisDeviceUpdateEntity(OasisDeviceEntity, UpdateEntity): ) -> None: """ Trigger installation of the latest available update on the device. - + If the latest available version matches the device's currently installed software version, no action is taken. Otherwise an upgrade is started on the device. - + Parameters: version (str | None): Ignored by this implementation; the entity uses its known latest version. backup (bool): Ignored by this implementation. @@ -105,7 +105,7 @@ class OasisDeviceUpdateEntity(OasisDeviceEntity, UpdateEntity): async def async_update(self) -> None: """ Refreshes this entity's latest software metadata. - + Fetches the latest software details from the coordinator's cloud client and updates the entity's `latest_version`, `release_summary`, and `release_url` attributes. If no software details are returned, the entity's attributes are left unchanged. @@ -116,4 +116,4 @@ class OasisDeviceUpdateEntity(OasisDeviceEntity, UpdateEntity): return self._attr_latest_version = software["version"] self._attr_release_summary = software["description"] - self._attr_release_url = f"https://app.grounded.so/software/{software['id']}" \ No newline at end of file + self._attr_release_url = f"https://app.grounded.so/software/{software['id']}"