mirror of
https://github.com/natekspencer/hacs-oasis_mini.git
synced 2025-12-06 18:44:14 -05:00
Swap out direct HTTP connection with server MQTT connection to handle firmware 2.60+ (#98)
* Switch to using mqtt * Better mqtt handling when connection is interrupted * Get track info from the cloud when playlist or index changes * Add additional helpers * Dynamically handle devices and other enhancements * 📝 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` * Fix formatting in transport.py * Replace tabs with spaces * Use tuples instead of sets for descriptors * Encode svg in image entity * Fix iot_class * Fix tracks list url * Ensure update_tracks closes the connection * Fix number typing and docstring * Fix docstring in update_tracks * Cache playlist based on type * Fix formatting in device.py * Add missing async_send_auto_clean_command to http client * Propagate UnauthenticatedError from async_get_track_info * Adjust exceptions * Move create_client outside of try block in config_flow * Formatting * Address PR comments * Formatting * Add noqa: ARG001 on unused hass * Close cloud/MQTT clients if initial coordinator refresh fails. * Address PR again * PR fixes * Pass config entry to coordinator * Remove async_timeout (thanks ChatGPT... not) * Address PR * Replace magic numbers for status code * Update autoplay wording/ordering --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
"""Oasis Mini update entity."""
|
||||
"""Oasis device update entity."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -15,9 +15,10 @@ from homeassistant.components.update import (
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import OasisMiniConfigEntry
|
||||
from .coordinator import OasisMiniCoordinator
|
||||
from .entity import OasisMiniEntity
|
||||
from . import OasisDeviceConfigEntry, setup_platform_from_coordinator
|
||||
from .entity import OasisDeviceEntity
|
||||
from .pyoasiscontrol import OasisDevice
|
||||
from .pyoasiscontrol.const import STATUS_UPDATING
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@@ -25,14 +26,35 @@ SCAN_INTERVAL = timedelta(hours=6)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
entry: OasisMiniConfigEntry,
|
||||
hass: HomeAssistant, # noqa: ARG001
|
||||
entry: OasisDeviceConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up Oasis Mini updates using config entry."""
|
||||
coordinator: OasisMiniCoordinator = entry.runtime_data
|
||||
if coordinator.device.access_token:
|
||||
async_add_entities([OasisMiniUpdateEntity(coordinator, DESCRIPTOR)], True)
|
||||
"""
|
||||
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.
|
||||
async_add_entities (AddEntitiesCallback): Callback to add created entities to Home Assistant.
|
||||
"""
|
||||
|
||||
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.
|
||||
"""
|
||||
return [
|
||||
OasisDeviceUpdateEntity(entry.runtime_data, device, DESCRIPTOR)
|
||||
for device in new_devices
|
||||
]
|
||||
|
||||
setup_platform_from_coordinator(entry, async_add_entities, make_entities, True)
|
||||
|
||||
|
||||
DESCRIPTOR = UpdateEntityDescription(
|
||||
@@ -40,8 +62,8 @@ DESCRIPTOR = UpdateEntityDescription(
|
||||
)
|
||||
|
||||
|
||||
class OasisMiniUpdateEntity(OasisMiniEntity, UpdateEntity):
|
||||
"""Oasis Mini update entity."""
|
||||
class OasisDeviceUpdateEntity(OasisDeviceEntity, UpdateEntity):
|
||||
"""Oasis device update entity."""
|
||||
|
||||
_attr_supported_features = (
|
||||
UpdateEntityFeature.INSTALL | UpdateEntityFeature.PROGRESS
|
||||
@@ -50,7 +72,7 @@ class OasisMiniUpdateEntity(OasisMiniEntity, UpdateEntity):
|
||||
@property
|
||||
def in_progress(self) -> bool | int:
|
||||
"""Update installation progress."""
|
||||
if self.device.status_code == 11:
|
||||
if self.device.status_code == STATUS_UPDATING:
|
||||
return self.device.download_progress
|
||||
return False
|
||||
|
||||
@@ -67,17 +89,30 @@ class OasisMiniUpdateEntity(OasisMiniEntity, UpdateEntity):
|
||||
async def async_install(
|
||||
self, version: str | None, backup: bool, **kwargs: Any
|
||||
) -> None:
|
||||
"""Install an update."""
|
||||
version = await self.device.async_get_software_version()
|
||||
if version == self.latest_version:
|
||||
"""
|
||||
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.
|
||||
**kwargs: Additional keyword arguments are ignored.
|
||||
"""
|
||||
if self.latest_version == self.device.software_version:
|
||||
return
|
||||
await self.device.async_upgrade()
|
||||
|
||||
async def async_update(self) -> None:
|
||||
"""Update the entity."""
|
||||
await self.device.async_get_software_version()
|
||||
software = await self.device.async_cloud_get_latest_software_details()
|
||||
if not software:
|
||||
"""
|
||||
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.
|
||||
"""
|
||||
client = self.coordinator.cloud_client
|
||||
if not (software := await client.async_get_latest_software_details()):
|
||||
_LOGGER.warning("Unable to get latest software details")
|
||||
return
|
||||
self._attr_latest_version = software["version"]
|
||||
|
||||
Reference in New Issue
Block a user