mirror of
https://github.com/tomaae/homeassistant-mikrotik_router.git
synced 2025-06-27 11:18:55 +02:00
Optimized the process of fetching release notes in the Mikrotik Router integration by utilizing the existing HTTP client session from Home Assistant's aiohttp_client. This change avoids creating a new session for each request, leading to more efficient resource usage and potentially reducing the likelihood of encountering issues related to session management. By leveraging `async_get_clientsession`, the update component now aligns better with Home Assistant's recommended practices for external HTTP requests, ensuring consistency and reliability in how network calls are made within integrations.
163 lines
5.2 KiB
Python
163 lines
5.2 KiB
Python
"""Support for the Mikrotik Router update service."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from logging import getLogger
|
|
import aiohttp
|
|
from typing import Any
|
|
|
|
from homeassistant.config_entries import ConfigEntry
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
|
|
|
from homeassistant.components.update import (
|
|
UpdateEntity,
|
|
UpdateDeviceClass,
|
|
UpdateEntityFeature,
|
|
)
|
|
|
|
from .coordinator import MikrotikCoordinator
|
|
from .entity import MikrotikEntity, async_add_entities
|
|
from .update_types import (
|
|
SENSOR_TYPES,
|
|
SENSOR_SERVICES,
|
|
)
|
|
|
|
_LOGGER = getLogger(__name__)
|
|
DEVICE_UPDATE = "device_update"
|
|
|
|
|
|
# ---------------------------
|
|
# async_setup_entry
|
|
# ---------------------------
|
|
async def async_setup_entry(
|
|
hass: HomeAssistant,
|
|
config_entry: ConfigEntry,
|
|
_async_add_entities: AddEntitiesCallback,
|
|
) -> None:
|
|
"""Set up entry for component"""
|
|
dispatcher = {
|
|
"MikrotikRouterOSUpdate": MikrotikRouterOSUpdate,
|
|
"MikrotikRouterBoardFWUpdate": MikrotikRouterBoardFWUpdate,
|
|
}
|
|
await async_add_entities(hass, config_entry, dispatcher)
|
|
|
|
|
|
# ---------------------------
|
|
# MikrotikRouterOSUpdate
|
|
# ---------------------------
|
|
class MikrotikRouterOSUpdate(MikrotikEntity, UpdateEntity):
|
|
"""Define an Mikrotik Controller Update entity."""
|
|
|
|
def __init__(
|
|
self,
|
|
coordinator: MikrotikCoordinator,
|
|
entity_description,
|
|
uid: str | None = None,
|
|
):
|
|
"""Set up device update entity."""
|
|
super().__init__(coordinator, entity_description, uid)
|
|
|
|
self._attr_supported_features = UpdateEntityFeature.INSTALL
|
|
self._attr_supported_features |= UpdateEntityFeature.BACKUP
|
|
self._attr_supported_features |= UpdateEntityFeature.RELEASE_NOTES
|
|
self._attr_title = self.entity_description.title
|
|
|
|
@property
|
|
def is_on(self) -> bool:
|
|
"""Return true if device is on."""
|
|
return self._data[self.entity_description.data_attribute]
|
|
|
|
@property
|
|
def installed_version(self) -> str:
|
|
"""Version installed and in use."""
|
|
return self._data["installed-version"]
|
|
|
|
@property
|
|
def latest_version(self) -> str:
|
|
"""Latest version available for install."""
|
|
return self._data["latest-version"]
|
|
|
|
async def options_updated(self) -> None:
|
|
"""No action needed."""
|
|
|
|
async def async_install(self, version: str, backup: bool, **kwargs: Any) -> None:
|
|
"""Install an update."""
|
|
if backup:
|
|
self.coordinator.execute("/system/backup", "save", None, None)
|
|
|
|
self.coordinator.execute("/system/package/update", "install", None, None)
|
|
|
|
async def async_release_notes(self) -> str:
|
|
"""Return the release notes."""
|
|
try:
|
|
session = async_get_clientsession(self.hass)
|
|
async with session.get(
|
|
f"https://cdn.mikrotik.com/routeros/{self._data['latest-version']}/CHANGELOG"
|
|
) as response:
|
|
if response.status == 200:
|
|
text = await response.text()
|
|
return text.replace("*) ", "- ")
|
|
else:
|
|
_LOGGER.warning(
|
|
"Failed to fetch release notes due to a network error."
|
|
)
|
|
return "Failed to fetch release notes due to a network error."
|
|
except Exception as e:
|
|
_LOGGER.warning("Failed to download release notes (%s)", e)
|
|
|
|
return "Error fetching release notes."
|
|
|
|
@property
|
|
def release_url(self) -> str:
|
|
"""URL to the full release notes of the latest version available."""
|
|
return "https://mikrotik.com/download/changelogs"
|
|
|
|
|
|
# ---------------------------
|
|
# MikrotikRouterBoardFWUpdate
|
|
# ---------------------------
|
|
class MikrotikRouterBoardFWUpdate(MikrotikEntity, UpdateEntity):
|
|
"""Define an Mikrotik Controller Update entity."""
|
|
|
|
TYPE = DEVICE_UPDATE
|
|
_attr_device_class = UpdateDeviceClass.FIRMWARE
|
|
|
|
def __init__(
|
|
self,
|
|
coordinator: MikrotikCoordinator,
|
|
entity_description,
|
|
uid: str | None = None,
|
|
):
|
|
"""Set up device update entity."""
|
|
super().__init__(coordinator, entity_description, uid)
|
|
|
|
self._attr_supported_features = UpdateEntityFeature.INSTALL
|
|
self._attr_title = self.entity_description.title
|
|
|
|
@property
|
|
def is_on(self) -> bool:
|
|
"""Return true if device is on."""
|
|
return (
|
|
self.data["routerboard"]["current-firmware"]
|
|
!= self.data["routerboard"]["upgrade-firmware"]
|
|
)
|
|
|
|
@property
|
|
def installed_version(self) -> str:
|
|
"""Version installed and in use."""
|
|
return self._data["current-firmware"]
|
|
|
|
@property
|
|
def latest_version(self) -> str:
|
|
"""Latest version available for install."""
|
|
return self._data["upgrade-firmware"]
|
|
|
|
async def options_updated(self) -> None:
|
|
"""No action needed."""
|
|
|
|
async def async_install(self, version: str, backup: bool, **kwargs: Any) -> None:
|
|
"""Install an update."""
|
|
self.coordinator.execute("/system/routerboard", "upgrade", None, None)
|
|
self.coordinator.execute("/system", "reboot", None, None)
|