diff --git a/homeassistant/components/esphome/dashboard.py b/homeassistant/components/esphome/dashboard.py index 052d6161cf9..7439f8946f6 100644 --- a/homeassistant/components/esphome/dashboard.py +++ b/homeassistant/components/esphome/dashboard.py @@ -6,6 +6,7 @@ from datetime import timedelta import logging import aiohttp +from awesomeversion import AwesomeVersion from esphome_dashboard_api import ConfiguredDevice, ESPHomeDashboardAPI from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntryState @@ -83,6 +84,20 @@ class ESPHomeDashboard(DataUpdateCoordinator[dict[str, ConfiguredDevice]]): self.url = url self.api = ESPHomeDashboardAPI(url, session) + @property + def supports_update(self) -> bool: + """Return whether the dashboard supports updates.""" + if self.data is None: + raise RuntimeError("Data needs to be loaded first") + + if len(self.data) == 0: + return False + + esphome_version: str = next(iter(self.data.values()))["current_version"] + + # There is no January release + return AwesomeVersion(esphome_version) > AwesomeVersion("2023.1.0") + async def _async_update_data(self) -> dict: """Fetch device data.""" devices = await self.api.get_devices() diff --git a/homeassistant/components/esphome/update.py b/homeassistant/components/esphome/update.py index be525a6f3b8..7139c9e937f 100644 --- a/homeassistant/components/esphome/update.py +++ b/homeassistant/components/esphome/update.py @@ -68,7 +68,6 @@ class ESPHomeUpdateEntity(CoordinatorEntity[ESPHomeDashboard], UpdateEntity): _attr_has_entity_name = True _attr_device_class = UpdateDeviceClass.FIRMWARE - _attr_supported_features = UpdateEntityFeature.INSTALL _attr_title = "ESPHome" _attr_name = "Firmware" @@ -85,6 +84,8 @@ class ESPHomeUpdateEntity(CoordinatorEntity[ESPHomeDashboard], UpdateEntity): (dr.CONNECTION_NETWORK_MAC, entry_data.device_info.mac_address) } ) + if coordinator.supports_update: + self._attr_supported_features = UpdateEntityFeature.INSTALL @property def _device_info(self) -> ESPHomeDeviceInfo: diff --git a/tests/components/esphome/test_dashboard.py b/tests/components/esphome/test_dashboard.py index 0960556503a..ed2afb7e500 100644 --- a/tests/components/esphome/test_dashboard.py +++ b/tests/components/esphome/test_dashboard.py @@ -73,3 +73,29 @@ async def test_new_dashboard_fix_reauth( assert len(mock_get_encryption_key.mock_calls) == 1 assert len(mock_setup.mock_calls) == 1 assert mock_config_entry.data[CONF_NOISE_PSK] == VALID_NOISE_PSK + + +async def test_dashboard_supports_update(hass, mock_dashboard): + """Test dashboard supports update.""" + dash = dashboard.async_get_dashboard(hass) + + # No data + assert not dash.supports_update + + # supported version + mock_dashboard["configured"].append( + { + "name": "test", + "configuration": "test.yaml", + "current_version": "2023.2.0-dev", + } + ) + await dash.async_refresh() + + assert dash.supports_update + + # unsupported version + mock_dashboard["configured"][0]["current_version"] = "2023.1.0" + await dash.async_refresh() + + assert not dash.supports_update diff --git a/tests/components/esphome/test_update.py b/tests/components/esphome/test_update.py index d7ad83697af..9cfba03be9f 100644 --- a/tests/components/esphome/test_update.py +++ b/tests/components/esphome/test_update.py @@ -5,6 +5,7 @@ from unittest.mock import Mock, patch import pytest from homeassistant.components.esphome.dashboard import async_get_dashboard +from homeassistant.components.update import UpdateEntityFeature from homeassistant.helpers.dispatcher import async_dispatcher_send @@ -22,12 +23,16 @@ def stub_reconnect(): [ { "name": "test", - "current_version": "1.2.3", + "current_version": "2023.2.0-dev", "configuration": "test.yaml", } ], "on", - {"latest_version": "1.2.3", "installed_version": "1.0.0"}, + { + "latest_version": "2023.2.0-dev", + "installed_version": "1.0.0", + "supported_features": UpdateEntityFeature.INSTALL, + }, ), ( [ @@ -37,12 +42,16 @@ def stub_reconnect(): }, ], "off", - {"latest_version": "1.0.0", "installed_version": "1.0.0"}, + { + "latest_version": "1.0.0", + "installed_version": "1.0.0", + "supported_features": 0, + }, ), ( [], "unavailable", - {}, + {"supported_features": 0}, ), ], )