mirror of
https://github.com/home-assistant/core.git
synced 2026-04-01 21:16:34 +00:00
Compare commits
1 Commits
remove_dev
...
scop-tasmo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5e7e299876 |
@@ -19,6 +19,7 @@ PLATFORMS = [
|
||||
Platform.LIGHT,
|
||||
Platform.SENSOR,
|
||||
Platform.SWITCH,
|
||||
Platform.UPDATE,
|
||||
]
|
||||
|
||||
TASMOTA_EVENT = "tasmota_event"
|
||||
|
||||
38
homeassistant/components/tasmota/coordinator.py
Normal file
38
homeassistant/components/tasmota/coordinator.py
Normal file
@@ -0,0 +1,38 @@
|
||||
"""Data update coordinators for Tasmota."""
|
||||
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
|
||||
from aiogithubapi import GitHubAPI, GitHubRatelimitException, GitHubReleaseModel
|
||||
from aiogithubapi.client import GitHubConnectionException
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||
|
||||
|
||||
class TasmotaLatestReleaseUpdateCoordinator(DataUpdateCoordinator[GitHubReleaseModel]):
|
||||
"""Data update coordinator for Tasmota latest release info."""
|
||||
|
||||
def __init__(self, hass: HomeAssistant, config_entry: ConfigEntry) -> None:
|
||||
"""Initialize the coordinator."""
|
||||
self.client = GitHubAPI(session=async_get_clientsession(hass))
|
||||
super().__init__(
|
||||
hass,
|
||||
logger=logging.getLogger(__name__),
|
||||
config_entry=config_entry,
|
||||
name="Tasmota latest release",
|
||||
update_interval=timedelta(days=1),
|
||||
)
|
||||
|
||||
async def _async_update_data(self) -> GitHubReleaseModel:
|
||||
"""Get new data."""
|
||||
try:
|
||||
response = await self.client.repos.releases.latest("arendst/Tasmota")
|
||||
if response.data is None:
|
||||
raise UpdateFailed("No data received")
|
||||
except (GitHubConnectionException, GitHubRatelimitException) as ex:
|
||||
raise UpdateFailed(ex) from ex
|
||||
else:
|
||||
return response.data
|
||||
@@ -8,5 +8,5 @@
|
||||
"iot_class": "local_push",
|
||||
"loggers": ["hatasmota"],
|
||||
"mqtt": ["tasmota/discovery/#"],
|
||||
"requirements": ["HATasmota==0.10.1"]
|
||||
"requirements": ["HATasmota==0.10.1", "aiogithubapi==26.0.0"]
|
||||
}
|
||||
|
||||
79
homeassistant/components/tasmota/update.py
Normal file
79
homeassistant/components/tasmota/update.py
Normal file
@@ -0,0 +1,79 @@
|
||||
"""Update entity for Tasmota."""
|
||||
|
||||
import re
|
||||
|
||||
from homeassistant.components.update import (
|
||||
UpdateDeviceClass,
|
||||
UpdateEntity,
|
||||
UpdateEntityFeature,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
from homeassistant.helpers.device_registry import DeviceEntry
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from .coordinator import TasmotaLatestReleaseUpdateCoordinator
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up Tasmota update entities."""
|
||||
coordinator = TasmotaLatestReleaseUpdateCoordinator(hass, config_entry)
|
||||
await coordinator.async_config_entry_first_refresh()
|
||||
|
||||
device_registry = dr.async_get(hass)
|
||||
devices = device_registry.devices.get_devices_for_config_entry_id(
|
||||
config_entry.entry_id
|
||||
)
|
||||
async_add_entities(TasmotaUpdateEntity(coordinator, device) for device in devices)
|
||||
|
||||
|
||||
class TasmotaUpdateEntity(UpdateEntity):
|
||||
"""Representation of a Tasmota update entity."""
|
||||
|
||||
_attr_device_class = UpdateDeviceClass.FIRMWARE
|
||||
_attr_name = "Firmware"
|
||||
_attr_title = "Tasmota firmware"
|
||||
_attr_supported_features = UpdateEntityFeature.RELEASE_NOTES
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: TasmotaLatestReleaseUpdateCoordinator,
|
||||
device_entry: DeviceEntry,
|
||||
) -> None:
|
||||
"""Initialize the Tasmota update entity."""
|
||||
self.coordinator = coordinator
|
||||
self.device_entry = device_entry
|
||||
self._attr_unique_id = f"{device_entry.id}_update"
|
||||
|
||||
@property
|
||||
def installed_version(self) -> str | None:
|
||||
"""Return the installed version."""
|
||||
return self.device_entry.sw_version # type:ignore[union-attr]
|
||||
|
||||
@property
|
||||
def latest_version(self) -> str:
|
||||
"""Return the latest version."""
|
||||
return self.coordinator.data.tag_name.removeprefix("v")
|
||||
|
||||
@property
|
||||
def release_url(self) -> str:
|
||||
"""Return the release URL."""
|
||||
return self.coordinator.data.html_url
|
||||
|
||||
@property
|
||||
def release_summary(self) -> str:
|
||||
"""Return the release summary."""
|
||||
return self.coordinator.data.name
|
||||
|
||||
def release_notes(self) -> str | None:
|
||||
"""Return the release notes."""
|
||||
if not self.coordinator.data.body:
|
||||
return None
|
||||
return re.sub(
|
||||
r"^<picture>.*?</picture>", "", self.coordinator.data.body, flags=re.DOTALL
|
||||
)
|
||||
1
requirements_all.txt
generated
1
requirements_all.txt
generated
@@ -267,6 +267,7 @@ aioftp==0.21.3
|
||||
aioghost==0.4.0
|
||||
|
||||
# homeassistant.components.github
|
||||
# homeassistant.components.tasmota
|
||||
aiogithubapi==26.0.0
|
||||
|
||||
# homeassistant.components.guardian
|
||||
|
||||
1
requirements_test_all.txt
generated
1
requirements_test_all.txt
generated
@@ -255,6 +255,7 @@ aioflo==2021.11.0
|
||||
aioghost==0.4.0
|
||||
|
||||
# homeassistant.components.github
|
||||
# homeassistant.components.tasmota
|
||||
aiogithubapi==26.0.0
|
||||
|
||||
# homeassistant.components.guardian
|
||||
|
||||
65
tests/components/tasmota/test_update.py
Normal file
65
tests/components/tasmota/test_update.py
Normal file
@@ -0,0 +1,65 @@
|
||||
"""Tests for the Tasmota update platform."""
|
||||
|
||||
import copy
|
||||
import json
|
||||
|
||||
from aiogithubapi import GitHubReleaseModel
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.tasmota.const import DEFAULT_PREFIX
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
|
||||
from .test_common import DEFAULT_CONFIG
|
||||
|
||||
from tests.common import async_fire_mqtt_message
|
||||
from tests.typing import MqttMockHAClient
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("candidate_version", "update_available"),
|
||||
[
|
||||
("0.0.0", False),
|
||||
(".".join(str(int(x) + 1) for x in DEFAULT_CONFIG["sw"].split(".")), True),
|
||||
],
|
||||
)
|
||||
async def test_update_state(
|
||||
hass: HomeAssistant,
|
||||
mqtt_mock: MqttMockHAClient,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
setup_tasmota,
|
||||
candidate_version: str,
|
||||
update_available: bool,
|
||||
) -> None:
|
||||
"""Test setting up a device."""
|
||||
config = copy.deepcopy(DEFAULT_CONFIG)
|
||||
mac = config["mac"]
|
||||
|
||||
async_fire_mqtt_message(
|
||||
hass,
|
||||
f"{DEFAULT_PREFIX}/{mac}/config",
|
||||
json.dumps(config),
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device_entry = device_registry.async_get_device(
|
||||
connections={(dr.CONNECTION_NETWORK_MAC, mac)}
|
||||
)
|
||||
|
||||
# TODO mock coordinator.client.repos.releases.latest("arendst/Tasmota") to return this
|
||||
data = GitHubReleaseModel(
|
||||
tag_name=f"v{candidate_version}",
|
||||
name=f"Tasmota v{candidate_version} Foo",
|
||||
html_url=f"https://github.com/arendst/Tasmota/releases/tag/v{candidate_version}",
|
||||
body="""\
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="./tools/logo/TASMOTA_FullLogo_Vector_White.svg">
|
||||
<img alt="Logo" src="./tools/logo/TASMOTA_FullLogo_Vector.svg" align="right" height="76">
|
||||
</picture>
|
||||
|
||||
# RELEASE NOTES
|
||||
|
||||
... """,
|
||||
)
|
||||
|
||||
# TODO update_available test, device_entry.sw_version has the current version
|
||||
Reference in New Issue
Block a user