mirror of
https://github.com/natekspencer/hacs-oasis_mini.git
synced 2025-12-06 18:44:14 -05:00
📝 Add docstrings to mqtt
Docstrings generation was requested by @natekspencer. * https://github.com/natekspencer/hacs-oasis_mini/pull/98#issuecomment-3568450288 The following files were modified: * `custom_components/oasis_mini/__init__.py` * `custom_components/oasis_mini/binary_sensor.py` * `custom_components/oasis_mini/button.py` * `custom_components/oasis_mini/config_flow.py` * `custom_components/oasis_mini/coordinator.py` * `custom_components/oasis_mini/entity.py` * `custom_components/oasis_mini/helpers.py` * `custom_components/oasis_mini/image.py` * `custom_components/oasis_mini/light.py` * `custom_components/oasis_mini/media_player.py` * `custom_components/oasis_mini/number.py` * `custom_components/oasis_mini/pyoasiscontrol/clients/cloud_client.py` * `custom_components/oasis_mini/pyoasiscontrol/clients/http_client.py` * `custom_components/oasis_mini/pyoasiscontrol/clients/mqtt_client.py` * `custom_components/oasis_mini/pyoasiscontrol/clients/transport.py` * `custom_components/oasis_mini/pyoasiscontrol/device.py` * `custom_components/oasis_mini/pyoasiscontrol/utils.py` * `custom_components/oasis_mini/select.py` * `custom_components/oasis_mini/sensor.py` * `custom_components/oasis_mini/switch.py` * `custom_components/oasis_mini/update.py` * `update_tracks.py`
This commit is contained in:
committed by
GitHub
parent
cf21a5d995
commit
4ef28fc741
@@ -22,29 +22,64 @@ class OasisHttpClient(OasisClientProtocol):
|
||||
"""
|
||||
|
||||
def __init__(self, host: str, session: ClientSession | None = None) -> None:
|
||||
"""
|
||||
Initialize the HTTP client for a specific device host.
|
||||
|
||||
Parameters:
|
||||
host (str): Hostname or IP address of the target device (used to build the base HTTP URL).
|
||||
session (ClientSession | None): Optional aiohttp ClientSession to reuse for requests. If omitted, a new session will be created and owned by this client.
|
||||
"""
|
||||
self._host = host
|
||||
self._session: ClientSession | None = session
|
||||
self._owns_session: bool = session is None
|
||||
|
||||
@property
|
||||
def session(self) -> ClientSession:
|
||||
"""
|
||||
Ensure and return a usable aiohttp ClientSession for this client.
|
||||
|
||||
If no session exists or the existing session is closed, a new ClientSession is created and the client records ownership of that session so it can be closed later.
|
||||
|
||||
Returns:
|
||||
An active aiohttp ClientSession instance associated with this client.
|
||||
"""
|
||||
if self._session is None or self._session.closed:
|
||||
self._session = ClientSession()
|
||||
self._owns_session = True
|
||||
return self._session
|
||||
|
||||
async def async_close(self) -> None:
|
||||
"""Close owned session."""
|
||||
"""
|
||||
Close the client's owned HTTP session if one exists and is open.
|
||||
|
||||
Does nothing when there is no session, the session is already closed, or the client does not own the session.
|
||||
"""
|
||||
if self._session and not self._session.closed and self._owns_session:
|
||||
await self._session.close()
|
||||
|
||||
@property
|
||||
def url(self) -> str:
|
||||
# These devices are plain HTTP, no TLS
|
||||
"""
|
||||
Base HTTP URL for the target device.
|
||||
|
||||
Returns:
|
||||
The device base URL using plain HTTP (no TLS), including a trailing slash (e.g. "http://{host}/").
|
||||
"""
|
||||
return f"http://{self._host}/"
|
||||
|
||||
async def _async_request(self, method: str, url: str, **kwargs: Any) -> Any:
|
||||
"""Low-level HTTP helper."""
|
||||
"""
|
||||
Perform an HTTP request using the client's session and decode the response.
|
||||
|
||||
Logs the request URL and query parameters. If the response status is 200, returns the response body as a string for `text/plain`, the parsed JSON for `application/json`, or `None` for other content types. On non-200 responses, raises the client response error.
|
||||
|
||||
Returns:
|
||||
The response body as `str` for `text/plain`, the parsed JSON value for `application/json`, or `None` for other content types.
|
||||
|
||||
Raises:
|
||||
aiohttp.ClientResponseError: If the response status is not 200.
|
||||
"""
|
||||
session = self.session
|
||||
_LOGGER.debug(
|
||||
"%s %s",
|
||||
@@ -65,15 +100,38 @@ class OasisHttpClient(OasisClientProtocol):
|
||||
resp.raise_for_status()
|
||||
|
||||
async def _async_get(self, **kwargs: Any) -> str | None:
|
||||
"""
|
||||
Perform a GET request to the client's base URL using the provided request keyword arguments.
|
||||
|
||||
Parameters:
|
||||
**kwargs: Additional request keyword arguments forwarded to the underlying request (for example `params`, `headers`, `timeout`).
|
||||
|
||||
Returns:
|
||||
`str` response text when the server responds with `text/plain`, `None` otherwise.
|
||||
"""
|
||||
return await self._async_request("GET", self.url, **kwargs)
|
||||
|
||||
async def _async_command(self, **kwargs: Any) -> str | None:
|
||||
"""
|
||||
Execute a device command by issuing a GET request with the provided query parameters and return the parsed response.
|
||||
|
||||
Parameters:
|
||||
**kwargs: Mapping of query parameter names to values sent with the GET request.
|
||||
|
||||
Returns:
|
||||
str | None: The device response as a string, a parsed JSON value, or None when the response has an unsupported content type.
|
||||
"""
|
||||
result = await self._async_get(**kwargs)
|
||||
_LOGGER.debug("Result: %s", result)
|
||||
return result
|
||||
|
||||
async def async_get_mac_address(self, device: OasisDevice) -> str | None:
|
||||
"""Fetch MAC address via HTTP GETMAC."""
|
||||
"""
|
||||
Fetch the device MAC address using the device's HTTP GETMAC endpoint.
|
||||
|
||||
Returns:
|
||||
str: The MAC address with surrounding whitespace removed, or `None` if it could not be retrieved.
|
||||
"""
|
||||
try:
|
||||
mac = await self._async_get(params={"GETMAC": ""})
|
||||
if isinstance(mac, str):
|
||||
@@ -89,6 +147,13 @@ class OasisHttpClient(OasisClientProtocol):
|
||||
device: OasisDevice,
|
||||
speed: int,
|
||||
) -> None:
|
||||
"""
|
||||
Send a ball speed command to the specified device.
|
||||
|
||||
Parameters:
|
||||
device (OasisDevice): Target device for the command.
|
||||
speed (int): Speed value to set for the device's ball mechanism.
|
||||
"""
|
||||
await self._async_command(params={"WRIOASISSPEED": speed})
|
||||
|
||||
async def async_send_led_command(
|
||||
@@ -99,10 +164,25 @@ class OasisHttpClient(OasisClientProtocol):
|
||||
led_speed: int,
|
||||
brightness: int,
|
||||
) -> None:
|
||||
"""
|
||||
Send an LED control command to the device.
|
||||
|
||||
Parameters:
|
||||
device (OasisDevice): Target device to receive the command.
|
||||
led_effect (str): Effect name or identifier to apply to the LEDs.
|
||||
color (str): Color value recognized by the device (e.g., hex code or device color name).
|
||||
led_speed (int): Animation speed value; larger values increase animation speed.
|
||||
brightness (int): Brightness level for the LEDs.
|
||||
"""
|
||||
payload = f"{led_effect};0;{color};{led_speed};{brightness}"
|
||||
await self._async_command(params={"WRILED": payload})
|
||||
|
||||
async def async_send_sleep_command(self, device: OasisDevice) -> None:
|
||||
"""
|
||||
Send a sleep command to the device.
|
||||
|
||||
Requests the device to enter sleep mode.
|
||||
"""
|
||||
await self._async_command(params={"CMDSLEEP": ""})
|
||||
|
||||
async def async_send_move_job_command(
|
||||
@@ -111,6 +191,14 @@ class OasisHttpClient(OasisClientProtocol):
|
||||
from_index: int,
|
||||
to_index: int,
|
||||
) -> None:
|
||||
"""
|
||||
Move a job in the device's playlist from one index to another.
|
||||
|
||||
Parameters:
|
||||
device (OasisDevice): Target device whose job list will be modified.
|
||||
from_index (int): Zero-based index of the job to move.
|
||||
to_index (int): Zero-based destination index where the job will be placed.
|
||||
"""
|
||||
await self._async_command(params={"MOVEJOB": f"{from_index};{to_index}"})
|
||||
|
||||
async def async_send_change_track_command(
|
||||
@@ -118,6 +206,12 @@ class OasisHttpClient(OasisClientProtocol):
|
||||
device: OasisDevice,
|
||||
index: int,
|
||||
) -> None:
|
||||
"""
|
||||
Change the device's current track to the specified track index.
|
||||
|
||||
Parameters:
|
||||
index (int): Zero-based index of the track to select.
|
||||
"""
|
||||
await self._async_command(params={"CMDCHANGETRACK": index})
|
||||
|
||||
async def async_send_add_joblist_command(
|
||||
@@ -126,6 +220,15 @@ class OasisHttpClient(OasisClientProtocol):
|
||||
tracks: list[int],
|
||||
) -> None:
|
||||
# The old code passed the list directly; if the device expects CSV:
|
||||
"""
|
||||
Send an "add joblist" command to the device with a list of track indices.
|
||||
|
||||
The provided track indices are serialized as a comma-separated string and sent to the device using the `ADDJOBLIST` parameter.
|
||||
|
||||
Parameters:
|
||||
device (OasisDevice): Target device to receive the command.
|
||||
tracks (list[int]): Track indices to add; these are sent as a CSV string (e.g., [1,2,3] -> "1,2,3").
|
||||
"""
|
||||
await self._async_command(params={"ADDJOBLIST": ",".join(map(str, tracks))})
|
||||
|
||||
async def async_send_set_playlist_command(
|
||||
@@ -133,6 +236,13 @@ class OasisHttpClient(OasisClientProtocol):
|
||||
device: OasisDevice,
|
||||
playlist: list[int],
|
||||
) -> None:
|
||||
"""
|
||||
Set the device's playlist on the target device and optimistically update the local device state.
|
||||
|
||||
Parameters:
|
||||
device (OasisDevice): Target device to receive the playlist command; its state will be updated optimistically.
|
||||
playlist (list[int]): Ordered list of track indices to set as the device's playlist.
|
||||
"""
|
||||
await self._async_command(params={"WRIJOBLIST": ",".join(map(str, playlist))})
|
||||
# optional: optimistic state update
|
||||
device.update_from_status_dict({"playlist": playlist})
|
||||
@@ -142,6 +252,12 @@ class OasisHttpClient(OasisClientProtocol):
|
||||
device: OasisDevice,
|
||||
repeat: bool,
|
||||
) -> None:
|
||||
"""
|
||||
Set the device's playlist repeat flag.
|
||||
|
||||
Parameters:
|
||||
repeat (bool): `True` to enable playlist repeat, `False` to disable it.
|
||||
"""
|
||||
await self._async_command(params={"WRIREPEATJOB": 1 if repeat else 0})
|
||||
|
||||
async def async_send_set_autoplay_command(
|
||||
@@ -149,6 +265,13 @@ class OasisHttpClient(OasisClientProtocol):
|
||||
device: OasisDevice,
|
||||
option: str,
|
||||
) -> None:
|
||||
"""
|
||||
Set the device's autoplay (wait-after) option.
|
||||
|
||||
Parameters:
|
||||
device (OasisDevice): Target device whose autoplay option will be updated.
|
||||
option (str): The value for the device's wait-after/autoplay setting as expected by the device firmware.
|
||||
"""
|
||||
await self._async_command(params={"WRIWAITAFTER": option})
|
||||
|
||||
async def async_send_upgrade_command(
|
||||
@@ -156,25 +279,55 @@ class OasisHttpClient(OasisClientProtocol):
|
||||
device: OasisDevice,
|
||||
beta: bool,
|
||||
) -> None:
|
||||
"""
|
||||
Send a firmware upgrade command to the specified device.
|
||||
|
||||
Parameters:
|
||||
device (OasisDevice): Target device to receive the upgrade command.
|
||||
beta (bool): If True, request the beta firmware; if False, request the stable firmware.
|
||||
"""
|
||||
await self._async_command(params={"CMDUPGRADE": 1 if beta else 0})
|
||||
|
||||
async def async_send_play_command(self, device: OasisDevice) -> None:
|
||||
"""
|
||||
Send the play command to the device.
|
||||
"""
|
||||
await self._async_command(params={"CMDPLAY": ""})
|
||||
|
||||
async def async_send_pause_command(self, device: OasisDevice) -> None:
|
||||
"""
|
||||
Send a pause command to the device.
|
||||
"""
|
||||
await self._async_command(params={"CMDPAUSE": ""})
|
||||
|
||||
async def async_send_stop_command(self, device: OasisDevice) -> None:
|
||||
"""
|
||||
Sends the device stop command to halt playback or activity.
|
||||
|
||||
Sends an HTTP command to request the device stop its current operation.
|
||||
"""
|
||||
await self._async_command(params={"CMDSTOP": ""})
|
||||
|
||||
async def async_send_reboot_command(self, device: OasisDevice) -> None:
|
||||
"""
|
||||
Send a reboot command to the device.
|
||||
|
||||
Sends a reboot request to the target device using the CMDBOOT control parameter.
|
||||
"""
|
||||
await self._async_command(params={"CMDBOOT": ""})
|
||||
|
||||
async def async_get_status(self, device: OasisDevice) -> None:
|
||||
"""Fetch status via GETSTATUS and update the device."""
|
||||
"""
|
||||
Retrieve the device status from the device and apply it to the given OasisDevice.
|
||||
|
||||
If the device does not return a status, the device object is not modified.
|
||||
|
||||
Parameters:
|
||||
device (OasisDevice): Device instance to update with the fetched status.
|
||||
"""
|
||||
raw_status = await self._async_get(params={"GETSTATUS": ""})
|
||||
if raw_status is None:
|
||||
return
|
||||
|
||||
_LOGGER.debug("Status for %s: %s", device.serial_number, raw_status)
|
||||
device.update_from_status_string(raw_status)
|
||||
device.update_from_status_string(raw_status)
|
||||
Reference in New Issue
Block a user