Improve handling of old firmware versions (#125406)

* Update Info fixture with new fields from pysmlight 0.0.14

* Create repair if device is running unsupported firmware

* Add test for legacy firmware info

* Add strings for repair issue
This commit is contained in:
TimL 2024-09-06 23:46:08 +10:00 committed by Paulus Schoutsen
parent a3f42e36ac
commit 0b95cf1251
5 changed files with 65 additions and 5 deletions

View File

@ -9,8 +9,10 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryError
from homeassistant.helpers import issue_registry as ir
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.device_registry import format_mac
from homeassistant.helpers.issue_registry import IssueSeverity
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import DOMAIN, LOGGER, SCAN_INTERVAL
@ -40,6 +42,7 @@ class SmDataUpdateCoordinator(DataUpdateCoordinator[SmData]):
self.unique_id: str | None = None
self.client = Api2(host=host, session=async_get_clientsession(hass))
self.legacy_api: int = 0
async def _async_setup(self) -> None:
"""Authenticate if needed during initial setup."""
@ -60,11 +63,28 @@ class SmDataUpdateCoordinator(DataUpdateCoordinator[SmData]):
info = await self.client.get_info()
self.unique_id = format_mac(info.MAC)
if info.legacy_api:
self.legacy_api = info.legacy_api
ir.async_create_issue(
self.hass,
DOMAIN,
"unsupported_firmware",
is_fixable=False,
is_persistent=False,
learn_more_url="https://smlight.tech/flasher/#SLZB-06",
severity=IssueSeverity.ERROR,
translation_key="unsupported_firmware",
)
async def _async_update_data(self) -> SmData:
"""Fetch data from the SMLIGHT device."""
try:
sensors = Sensors()
if not self.legacy_api:
sensors = await self.client.get_sensors()
return SmData(
sensors=await self.client.get_sensors(),
sensors=sensors,
info=await self.client.get_info(),
)
except SmlightConnectionError as err:

View File

@ -45,5 +45,11 @@
"name": "RAM usage"
}
}
},
"issues": {
"unsupported_firmware": {
"title": "SLZB core firmware update required",
"description": "Your SMLIGHT SLZB-06x device is running an unsupported core firmware version. Please update it to the latest version to enjoy all the features of this integration."
}
}
}

View File

@ -3,10 +3,12 @@
"device_ip": "192.168.1.161",
"fs_total": 3456,
"fw_channel": "dev",
"legacy_api": 0,
"hostname": "SLZB-06p7",
"MAC": "AA:BB:CC:DD:EE:FF",
"model": "SLZB-06p7",
"ram_total": 296,
"sw_version": "v2.3.1.dev",
"sw_version": "v2.3.6",
"wifi_mode": 0,
"zb_flash_size": 704,
"zb_hw": "CC2652P7",

View File

@ -27,7 +27,7 @@
'primary_config_entry': <ANY>,
'serial_number': None,
'suggested_area': None,
'sw_version': 'core: v2.3.1.dev / zigbee: -1',
'sw_version': 'core: v2.3.6 / zigbee: -1',
'via_device_id': None,
})
# ---

View File

@ -3,15 +3,17 @@
from unittest.mock import MagicMock
from freezegun.api import FrozenDateTimeFactory
from pysmlight.exceptions import SmlightAuthError, SmlightConnectionError
from pysmlight import Info
from pysmlight.exceptions import SmlightAuthError, SmlightConnectionError, SmlightError
import pytest
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.smlight.const import SCAN_INTERVAL
from homeassistant.components.smlight.const import DOMAIN, SCAN_INTERVAL
from homeassistant.config_entries import ConfigEntryState
from homeassistant.const import STATE_UNAVAILABLE
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.issue_registry import IssueRegistry
from .conftest import setup_integration
@ -92,3 +94,33 @@ async def test_device_info(
)
assert device_entry is not None
assert device_entry == snapshot
async def test_device_legacy_firmware(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_smlight_client: MagicMock,
device_registry: dr.DeviceRegistry,
issue_registry: IssueRegistry,
) -> None:
"""Test device setup for old firmware version that dont support required API."""
LEGACY_VERSION = "v2.3.1"
mock_smlight_client.get_sensors.side_effect = SmlightError
mock_smlight_client.get_info.return_value = Info(
legacy_api=1, sw_version=LEGACY_VERSION, MAC="AA:BB:CC:DD:EE:FF"
)
entry = await setup_integration(hass, mock_config_entry)
assert entry.unique_id == "aa:bb:cc:dd:ee:ff"
device_entry = device_registry.async_get_device(
connections={(dr.CONNECTION_NETWORK_MAC, entry.unique_id)}
)
assert LEGACY_VERSION in device_entry.sw_version
issue = issue_registry.async_get_issue(
domain=DOMAIN, issue_id="unsupported_firmware"
)
assert issue is not None
assert issue.domain == DOMAIN
assert issue.issue_id == "unsupported_firmware"