Skip to content

Commit

Permalink
Improve handling of old firmware versions (#125406)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
tl-sl authored and balloob committed Sep 6, 2024
1 parent a3f42e3 commit 0b95cf1
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 5 deletions.
22 changes: 21 additions & 1 deletion homeassistant/components/smlight/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
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
Expand Down Expand Up @@ -40,6 +42,7 @@ def __init__(self, hass: HomeAssistant, host: str) -> None:

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."""
Expand All @@ -60,11 +63,28 @@ async def _async_setup(self) -> None:
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:
Expand Down
6 changes: 6 additions & 0 deletions homeassistant/components/smlight/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -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."
}
}
}
4 changes: 3 additions & 1 deletion tests/components/smlight/fixtures/info.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion tests/components/smlight/snapshots/test_init.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -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,
})
# ---
36 changes: 34 additions & 2 deletions tests/components/smlight/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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"

0 comments on commit 0b95cf1

Please sign in to comment.