mirror of
https://github.com/natekspencer/hacs-oasis_mini.git
synced 2025-12-06 18:44:14 -05:00
* 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>
121 lines
4.1 KiB
Python
121 lines
4.1 KiB
Python
"""Oasis device update entity."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from datetime import timedelta
|
|
import logging
|
|
from typing import Any
|
|
|
|
from homeassistant.components.update import (
|
|
UpdateDeviceClass,
|
|
UpdateEntity,
|
|
UpdateEntityDescription,
|
|
UpdateEntityFeature,
|
|
)
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|
|
|
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__)
|
|
|
|
SCAN_INTERVAL = timedelta(hours=6)
|
|
|
|
|
|
async def async_setup_entry(
|
|
hass: HomeAssistant, # noqa: ARG001
|
|
entry: OasisDeviceConfigEntry,
|
|
async_add_entities: AddEntitiesCallback,
|
|
) -> 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.
|
|
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(
|
|
key="software", device_class=UpdateDeviceClass.FIRMWARE
|
|
)
|
|
|
|
|
|
class OasisDeviceUpdateEntity(OasisDeviceEntity, UpdateEntity):
|
|
"""Oasis device update entity."""
|
|
|
|
_attr_supported_features = (
|
|
UpdateEntityFeature.INSTALL | UpdateEntityFeature.PROGRESS
|
|
)
|
|
|
|
@property
|
|
def in_progress(self) -> bool | int:
|
|
"""Update installation progress."""
|
|
if self.device.status_code == STATUS_UPDATING:
|
|
return self.device.download_progress
|
|
return False
|
|
|
|
@property
|
|
def installed_version(self) -> str:
|
|
"""Version installed and in use."""
|
|
return self.device.software_version
|
|
|
|
@property
|
|
def should_poll(self) -> bool:
|
|
"""Set polling to True."""
|
|
return True
|
|
|
|
async def async_install(
|
|
self, version: str | None, backup: bool, **kwargs: Any
|
|
) -> 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.
|
|
**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:
|
|
"""
|
|
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"]
|
|
self._attr_release_summary = software["description"]
|
|
self._attr_release_url = f"https://app.grounded.so/software/{software['id']}"
|