mirror of
https://github.com/home-assistant/core.git
synced 2026-07-04 23:51:32 +02:00
Make Shelly deprecated firmware issue more general (#154539)
This commit is contained in:
@@ -59,8 +59,8 @@ from .coordinator import (
|
||||
)
|
||||
from .repairs import (
|
||||
async_manage_ble_scanner_firmware_unsupported_issue,
|
||||
async_manage_deprecated_firmware_issue,
|
||||
async_manage_outbound_websocket_incorrectly_enabled_issue,
|
||||
async_manage_wall_display_firmware_unsupported_issue,
|
||||
)
|
||||
from .utils import (
|
||||
async_create_issue_unsupported_firmware,
|
||||
@@ -337,7 +337,7 @@ async def _async_setup_rpc_entry(hass: HomeAssistant, entry: ShellyConfigEntry)
|
||||
await hass.config_entries.async_forward_entry_setups(
|
||||
entry, runtime_data.platforms
|
||||
)
|
||||
async_manage_wall_display_firmware_unsupported_issue(hass, entry)
|
||||
async_manage_deprecated_firmware_issue(hass, entry)
|
||||
async_manage_ble_scanner_firmware_unsupported_issue(
|
||||
hass,
|
||||
entry,
|
||||
|
||||
@@ -5,7 +5,7 @@ from __future__ import annotations
|
||||
from enum import StrEnum
|
||||
from logging import Logger, getLogger
|
||||
import re
|
||||
from typing import Final
|
||||
from typing import Final, TypedDict
|
||||
|
||||
from aioshelly.const import (
|
||||
MODEL_BULB,
|
||||
@@ -232,7 +232,6 @@ class BLEScannerMode(StrEnum):
|
||||
|
||||
|
||||
BLE_SCANNER_MIN_FIRMWARE = "1.5.1"
|
||||
WALL_DISPLAY_MIN_FIRMWARE = "2.3.0"
|
||||
|
||||
MAX_PUSH_UPDATE_FAILURES = 5
|
||||
PUSH_UPDATE_ISSUE_ID = "push_update_{unique}"
|
||||
@@ -245,9 +244,28 @@ BLE_SCANNER_FIRMWARE_UNSUPPORTED_ISSUE_ID = "ble_scanner_firmware_unsupported_{u
|
||||
OUTBOUND_WEBSOCKET_INCORRECTLY_ENABLED_ISSUE_ID = (
|
||||
"outbound_websocket_incorrectly_enabled_{unique}"
|
||||
)
|
||||
WALL_DISPLAY_FIRMWARE_UNSUPPORTED_ISSUE_ID = (
|
||||
"wall_display_firmware_unsupported_{unique}"
|
||||
)
|
||||
DEPRECATED_FIRMWARE_ISSUE_ID = "deprecated_firmware_{unique}"
|
||||
|
||||
|
||||
class DeprecatedFirmwareInfo(TypedDict):
|
||||
"""TypedDict for Deprecated Firmware Info."""
|
||||
|
||||
min_firmware: str
|
||||
ha_version: str
|
||||
|
||||
|
||||
# Provide firmware deprecation data:
|
||||
# key: device model
|
||||
# value: dict with:
|
||||
# min_firmware: minimum supported firmware version
|
||||
# ha_version: Home Assistant version when older firmware will be deprecated
|
||||
# Example:
|
||||
# DEPRECATED_FIRMWARES: dict[str, DeprecatedFirmwareInfo] = {
|
||||
# MODEL_WALL_DISPLAY: DeprecatedFirmwareInfo(
|
||||
# {"min_firmware": "2.3.0", "ha_version": "2025.10.0"}
|
||||
# ),
|
||||
# }
|
||||
DEPRECATED_FIRMWARES: dict[str, DeprecatedFirmwareInfo] = {}
|
||||
|
||||
GAS_VALVE_OPEN_STATES = ("opening", "opened")
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from aioshelly.const import MODEL_OUT_PLUG_S_G3, MODEL_PLUG_S_G3, MODEL_WALL_DISPLAY
|
||||
from aioshelly.const import MODEL_OUT_PLUG_S_G3, MODEL_PLUG_S_G3
|
||||
from aioshelly.exceptions import DeviceConnectionError, RpcCallError
|
||||
from aioshelly.rpc_device import RpcDevice
|
||||
from awesomeversion import AwesomeVersion
|
||||
@@ -19,10 +19,10 @@ from .const import (
|
||||
BLE_SCANNER_FIRMWARE_UNSUPPORTED_ISSUE_ID,
|
||||
BLE_SCANNER_MIN_FIRMWARE,
|
||||
CONF_BLE_SCANNER_MODE,
|
||||
DEPRECATED_FIRMWARE_ISSUE_ID,
|
||||
DEPRECATED_FIRMWARES,
|
||||
DOMAIN,
|
||||
OUTBOUND_WEBSOCKET_INCORRECTLY_ENABLED_ISSUE_ID,
|
||||
WALL_DISPLAY_FIRMWARE_UNSUPPORTED_ISSUE_ID,
|
||||
WALL_DISPLAY_MIN_FIRMWARE,
|
||||
BLEScannerMode,
|
||||
)
|
||||
from .coordinator import ShellyConfigEntry
|
||||
@@ -70,21 +70,25 @@ def async_manage_ble_scanner_firmware_unsupported_issue(
|
||||
|
||||
|
||||
@callback
|
||||
def async_manage_wall_display_firmware_unsupported_issue(
|
||||
def async_manage_deprecated_firmware_issue(
|
||||
hass: HomeAssistant,
|
||||
entry: ShellyConfigEntry,
|
||||
) -> None:
|
||||
"""Manage the Wall Display firmware unsupported issue."""
|
||||
issue_id = WALL_DISPLAY_FIRMWARE_UNSUPPORTED_ISSUE_ID.format(unique=entry.unique_id)
|
||||
"""Manage deprecated firmware issue."""
|
||||
issue_id = DEPRECATED_FIRMWARE_ISSUE_ID.format(unique=entry.unique_id)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
assert entry.runtime_data.rpc is not None
|
||||
|
||||
device = entry.runtime_data.rpc.device
|
||||
model = entry.data["model"]
|
||||
|
||||
if model in DEPRECATED_FIRMWARES:
|
||||
min_firmware = DEPRECATED_FIRMWARES[model]["min_firmware"]
|
||||
ha_version = DEPRECATED_FIRMWARES[model]["ha_version"]
|
||||
|
||||
if entry.data["model"] == MODEL_WALL_DISPLAY:
|
||||
firmware = AwesomeVersion(device.shelly["ver"])
|
||||
if firmware < WALL_DISPLAY_MIN_FIRMWARE:
|
||||
if firmware < min_firmware:
|
||||
ir.async_create_issue(
|
||||
hass,
|
||||
DOMAIN,
|
||||
@@ -92,11 +96,12 @@ def async_manage_wall_display_firmware_unsupported_issue(
|
||||
is_fixable=True,
|
||||
is_persistent=True,
|
||||
severity=ir.IssueSeverity.WARNING,
|
||||
translation_key="wall_display_firmware_unsupported",
|
||||
translation_key="deprecated_firmware",
|
||||
translation_placeholders={
|
||||
"device_name": device.name,
|
||||
"ip_address": device.ip_address,
|
||||
"firmware": firmware,
|
||||
"ha_version": ha_version,
|
||||
},
|
||||
data={"entry_id": entry.entry_id},
|
||||
)
|
||||
@@ -241,7 +246,7 @@ async def async_create_fix_flow(
|
||||
|
||||
if (
|
||||
"ble_scanner_firmware_unsupported" in issue_id
|
||||
or "wall_display_firmware_unsupported" in issue_id
|
||||
or "deprecated_firmware" in issue_id
|
||||
):
|
||||
return FirmwareUpdateFlow(device)
|
||||
|
||||
|
||||
@@ -312,13 +312,13 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"wall_display_firmware_unsupported": {
|
||||
"deprecated_firmware": {
|
||||
"title": "{device_name} is running outdated firmware",
|
||||
"fix_flow": {
|
||||
"step": {
|
||||
"confirm": {
|
||||
"title": "{device_name} is running outdated firmware",
|
||||
"description": "Your Shelly device {device_name} with IP address {ip_address} is running firmware {firmware}. This firmware version will not be supported by Shelly integration starting from Home Assistant 2025.11.0.\n\nSelect **Submit** button to start the OTA update to the latest stable firmware version."
|
||||
"description": "Your Shelly device {device_name} with IP address {ip_address} is running firmware {firmware}. This firmware version will not be supported by Shelly integration starting from Home Assistant {ha_version}.\n\nSelect **Submit** button to start the OTA update to the latest stable firmware version."
|
||||
}
|
||||
},
|
||||
"abort": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Test repairs handling for Shelly."""
|
||||
|
||||
from unittest.mock import Mock
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
from aioshelly.const import MODEL_WALL_DISPLAY
|
||||
from aioshelly.exceptions import DeviceConnectionError, RpcCallError
|
||||
@@ -9,10 +9,11 @@ import pytest
|
||||
from homeassistant.components.shelly.const import (
|
||||
BLE_SCANNER_FIRMWARE_UNSUPPORTED_ISSUE_ID,
|
||||
CONF_BLE_SCANNER_MODE,
|
||||
DEPRECATED_FIRMWARE_ISSUE_ID,
|
||||
DOMAIN,
|
||||
OUTBOUND_WEBSOCKET_INCORRECTLY_ENABLED_ISSUE_ID,
|
||||
WALL_DISPLAY_FIRMWARE_UNSUPPORTED_ISSUE_ID,
|
||||
BLEScannerMode,
|
||||
DeprecatedFirmwareInfo,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import issue_registry as ir
|
||||
@@ -215,17 +216,25 @@ async def test_outbound_websocket_incorrectly_enabled_issue_exc(
|
||||
assert len(issue_registry.issues) == 1
|
||||
|
||||
|
||||
async def test_wall_display_unsupported_firmware_issue(
|
||||
async def test_deprecated_firmware_issue(
|
||||
hass: HomeAssistant,
|
||||
hass_client: ClientSessionGenerator,
|
||||
mock_rpc_device: Mock,
|
||||
issue_registry: ir.IssueRegistry,
|
||||
) -> None:
|
||||
"""Test repair issues handling for Wall Display with unsupported firmware."""
|
||||
issue_id = WALL_DISPLAY_FIRMWARE_UNSUPPORTED_ISSUE_ID.format(unique=MOCK_MAC)
|
||||
"""Test repair issues handling deprecated firmware."""
|
||||
issue_id = DEPRECATED_FIRMWARE_ISSUE_ID.format(unique=MOCK_MAC)
|
||||
assert await async_setup_component(hass, "repairs", {})
|
||||
await hass.async_block_till_done()
|
||||
await init_integration(hass, 2, model=MODEL_WALL_DISPLAY)
|
||||
with patch(
|
||||
"homeassistant.components.shelly.repairs.DEPRECATED_FIRMWARES",
|
||||
{
|
||||
MODEL_WALL_DISPLAY: DeprecatedFirmwareInfo(
|
||||
{"min_firmware": "2.3.0", "ha_version": "2025.10.0"}
|
||||
)
|
||||
},
|
||||
):
|
||||
await init_integration(hass, 2, model=MODEL_WALL_DISPLAY)
|
||||
|
||||
# The default fw version in tests is 1.0.0, the repair issue should be created.
|
||||
assert issue_registry.async_get_issue(DOMAIN, issue_id)
|
||||
|
||||
Reference in New Issue
Block a user