Bump aioshelly to version 7.0.0 (#105384)

* Remove get_rpc_device_sleep_period() function

* Bump aioshelly version to 7.0.0

* Remove firmware compatibility check from BLE scanner

* Remove firmware compatibility check from light transition

* Update default fw ver

* Use LightEntityFeature in tests
This commit is contained in:
Maciej Bieniek 2023-12-09 16:12:05 +01:00 committed by GitHub
parent f37f40c338
commit 35b733fa2c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 18 additions and 154 deletions

View file

@ -49,7 +49,6 @@ from .utils import (
get_block_device_sleep_period,
get_coap_context,
get_device_entry_gen,
get_rpc_device_sleep_period,
get_rpc_device_wakeup_period,
get_ws_context,
)
@ -266,9 +265,7 @@ async def _async_setup_rpc_entry(hass: HomeAssistant, entry: ConfigEntry) -> boo
if sleep_period is None:
data = {**entry.data}
data[CONF_SLEEP_PERIOD] = get_rpc_device_sleep_period(
device.config
) or get_rpc_device_wakeup_period(device.status)
data[CONF_SLEEP_PERIOD] = get_rpc_device_wakeup_period(device.status)
hass.config_entries.async_update_entry(entry, data=data)
hass.async_create_task(_async_rpc_device_setup())

View file

@ -12,7 +12,6 @@ from aioshelly.exceptions import (
InvalidAuthError,
)
from aioshelly.rpc_device import RpcDevice
from awesomeversion import AwesomeVersion
import voluptuous as vol
from homeassistant.components.zeroconf import ZeroconfServiceInfo
@ -24,7 +23,6 @@ from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.selector import SelectSelector, SelectSelectorConfig
from .const import (
BLE_MIN_VERSION,
CONF_BLE_SCANNER_MODE,
CONF_SLEEP_PERIOD,
DOMAIN,
@ -32,14 +30,13 @@ from .const import (
MODEL_WALL_DISPLAY,
BLEScannerMode,
)
from .coordinator import async_reconnect_soon, get_entry_data
from .coordinator import async_reconnect_soon
from .utils import (
get_block_device_sleep_period,
get_coap_context,
get_info_auth,
get_info_gen,
get_model_name,
get_rpc_device_sleep_period,
get_rpc_device_wakeup_period,
get_ws_context,
mac_address_from_name,
@ -78,9 +75,7 @@ async def validate_input(
)
await rpc_device.shutdown()
sleep_period = get_rpc_device_sleep_period(
rpc_device.config
) or get_rpc_device_wakeup_period(rpc_device.status)
sleep_period = get_rpc_device_wakeup_period(rpc_device.status)
return {
"title": rpc_device.name,
@ -383,15 +378,6 @@ class OptionsFlowHandler(OptionsFlow):
) -> FlowResult:
"""Handle options flow."""
if user_input is not None:
entry_data = get_entry_data(self.hass)[self.config_entry.entry_id]
if user_input[CONF_BLE_SCANNER_MODE] != BLEScannerMode.DISABLED and (
not entry_data.rpc
or AwesomeVersion(entry_data.rpc.device.version) < BLE_MIN_VERSION
):
return self.async_abort(
reason="ble_unsupported",
description_placeholders={"ble_min_version": BLE_MIN_VERSION},
)
return self.async_create_entry(title="", data=user_input)
return self.async_show_form(

View file

@ -22,7 +22,6 @@ from aioshelly.const import (
MODEL_VINTAGE_V2,
MODEL_WALL_DISPLAY,
)
from awesomeversion import AwesomeVersion
DOMAIN: Final = "shelly"
@ -33,9 +32,6 @@ CONF_COAP_PORT: Final = "coap_port"
DEFAULT_COAP_PORT: Final = 5683
FIRMWARE_PATTERN: Final = re.compile(r"^(\d{8})")
# Firmware 1.11.0 release date, this firmware supports light transition
LIGHT_TRANSITION_MIN_FIRMWARE_DATE: Final = 20210226
# max light transition time in milliseconds
MAX_TRANSITION_TIME: Final = 5000
@ -187,8 +183,6 @@ ENTRY_RELOAD_COOLDOWN = 60
SHELLY_GAS_MODELS = [MODEL_GAS]
BLE_MIN_VERSION = AwesomeVersion("0.12.0-beta2")
CONF_BLE_SCANNER_MODE = "ble_scanner_mode"

View file

@ -13,7 +13,6 @@ from aioshelly.block_device import BlockDevice, BlockUpdateType
from aioshelly.const import MODEL_VALVE
from aioshelly.exceptions import DeviceConnectionError, InvalidAuthError, RpcCallError
from aioshelly.rpc_device import RpcDevice, RpcUpdateType
from awesomeversion import AwesomeVersion
from homeassistant.config_entries import ConfigEntry, ConfigEntryState
from homeassistant.const import ATTR_DEVICE_ID, CONF_HOST, EVENT_HOMEASSISTANT_STOP
@ -33,7 +32,6 @@ from .const import (
ATTR_DEVICE,
ATTR_GENERATION,
BATTERY_DEVICES_WITH_PERMANENT_CONNECTION,
BLE_MIN_VERSION,
CONF_BLE_SCANNER_MODE,
CONF_SLEEP_PERIOD,
DATA_CONFIG_ENTRY,
@ -587,14 +585,6 @@ class ShellyRpcCoordinator(ShellyCoordinatorBase[RpcDevice]):
if ble_scanner_mode == BLEScannerMode.DISABLED and self.connected:
await async_stop_scanner(self.device)
return
if AwesomeVersion(self.device.version) < BLE_MIN_VERSION:
LOGGER.error(
"BLE not supported on device %s with firmware %s; upgrade to %s",
self.name,
self.device.version,
BLE_MIN_VERSION,
)
return
if await async_ensure_ble_enabled(self.device):
# BLE enable required a reboot, don't bother connecting
# the scanner since it will be disconnected anyway

View file

@ -24,11 +24,9 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import (
DUAL_MODE_LIGHT_MODELS,
FIRMWARE_PATTERN,
KELVIN_MAX_VALUE,
KELVIN_MIN_VALUE_COLOR,
KELVIN_MIN_VALUE_WHITE,
LIGHT_TRANSITION_MIN_FIRMWARE_DATE,
LOGGER,
MAX_TRANSITION_TIME,
MODELS_SUPPORTING_LIGHT_TRANSITION,
@ -155,12 +153,7 @@ class BlockShellyLight(ShellyBlockEntity, LightEntity):
self._attr_supported_features |= LightEntityFeature.EFFECT
if coordinator.model in MODELS_SUPPORTING_LIGHT_TRANSITION:
match = FIRMWARE_PATTERN.search(coordinator.device.settings.get("fw", ""))
if (
match is not None
and int(match[0]) >= LIGHT_TRANSITION_MIN_FIRMWARE_DATE
):
self._attr_supported_features |= LightEntityFeature.TRANSITION
self._attr_supported_features |= LightEntityFeature.TRANSITION
@property
def is_on(self) -> bool:

View file

@ -9,7 +9,7 @@
"iot_class": "local_push",
"loggers": ["aioshelly"],
"quality_scale": "platinum",
"requirements": ["aioshelly==6.1.0"],
"requirements": ["aioshelly==7.0.0"],
"zeroconf": [
{
"type": "_http._tcp.local.",

View file

@ -71,9 +71,6 @@
"ble_scanner_mode": "Bluetooth scanner mode"
}
}
},
"abort": {
"ble_unsupported": "Bluetooth support requires firmware version {ble_min_version} or newer."
}
},
"selector": {

View file

@ -267,15 +267,6 @@ def get_block_device_sleep_period(settings: dict[str, Any]) -> int:
return sleep_period * 60 # minutes to seconds
def get_rpc_device_sleep_period(config: dict[str, Any]) -> int:
"""Return the device sleep period in seconds or 0 for non sleeping devices.
sys.sleep.wakeup_period value is deprecated and not available in Shelly
firmware 1.0.0 or later.
"""
return cast(int, config["sys"].get("sleep", {}).get("wakeup_period", 0))
def get_rpc_device_wakeup_period(status: dict[str, Any]) -> int:
"""Return the device wakeup period in seconds or 0 for non sleeping devices."""
return cast(int, status["sys"].get("wakeup_period", 0))

View file

@ -356,7 +356,7 @@ aioruuvigateway==0.1.0
aiosenz==1.0.0
# homeassistant.components.shelly
aioshelly==6.1.0
aioshelly==7.0.0
# homeassistant.components.skybell
aioskybell==22.7.0

View file

@ -329,7 +329,7 @@ aioruuvigateway==0.1.0
aiosenz==1.0.0
# homeassistant.components.shelly
aioshelly==6.1.0
aioshelly==7.0.0
# homeassistant.components.skybell
aioskybell==22.7.0

View file

@ -108,19 +108,6 @@ async def test_scanner_ignores_wrong_version_and_logs(
assert "Unsupported BLE scan result version: 0" in caplog.text
async def test_scanner_minimum_firmware_log_error(
hass: HomeAssistant, mock_rpc_device, monkeypatch, caplog: pytest.LogCaptureFixture
) -> None:
"""Test scanner log error if device firmware incompatible."""
monkeypatch.setattr(mock_rpc_device, "version", "0.11.0")
await init_integration(
hass, 2, options={CONF_BLE_SCANNER_MODE: BLEScannerMode.ACTIVE}
)
assert mock_rpc_device.initialized is True
assert "BLE not supported on device" in caplog.text
async def test_scanner_warns_on_corrupt_event(
hass: HomeAssistant, mock_rpc_device, monkeypatch, caplog: pytest.LogCaptureFixture
) -> None:

View file

@ -157,14 +157,13 @@ MOCK_CONFIG = {
"sys": {
"ui_data": {},
"device": {"name": "Test name"},
"wakeup_period": 0,
},
}
MOCK_SHELLY_COAP = {
"mac": MOCK_MAC,
"auth": False,
"fw": "20201124-092854/v1.9.0@57ac4ad8",
"fw": "20210715-092854/v1.11.0@57ac4ad8",
"num_outputs": 2,
}
@ -174,8 +173,8 @@ MOCK_SHELLY_RPC = {
"mac": MOCK_MAC,
"model": MODEL_PLUS_2PM,
"gen": 2,
"fw_id": "20220830-130540/0.11.0-gfa1bc37",
"ver": "0.11.0",
"fw_id": "20230803-130540/1.0.0-gfa1bc37",
"ver": "1.0.0",
"app": "Plus2PM",
"auth_en": False,
"auth_domain": None,
@ -290,7 +289,7 @@ async def mock_block_device():
blocks=MOCK_BLOCKS,
settings=MOCK_SETTINGS,
shelly=MOCK_SHELLY_COAP,
version="0.10.0",
version="1.11.0",
status=MOCK_STATUS_COAP,
firmware_version="some fw string",
initialized=True,
@ -314,7 +313,7 @@ def _mock_rpc_device(version: str | None = None):
config=MOCK_CONFIG,
event={},
shelly=MOCK_SHELLY_RPC,
version=version or "0.12.0",
version=version or "1.0.0",
hostname="test-host",
status=MOCK_STATUS_RPC,
firmware_version="some fw string",
@ -324,23 +323,6 @@ def _mock_rpc_device(version: str | None = None):
return device
@pytest.fixture
async def mock_pre_ble_rpc_device():
"""Mock rpc (Gen2, Websocket) device pre BLE."""
with patch("aioshelly.rpc_device.RpcDevice.create") as rpc_device_mock:
def update():
rpc_device_mock.return_value.subscribe_updates.call_args[0][0](
{}, RpcUpdateType.STATUS
)
device = _mock_rpc_device("0.11.0")
rpc_device_mock.return_value = device
rpc_device_mock.return_value.mock_update = Mock(side_effect=update)
yield rpc_device_mock.return_value
@pytest.fixture
async def mock_rpc_device():
"""Mock rpc (Gen2, Websocket) device with BLE support."""
@ -363,7 +345,7 @@ async def mock_rpc_device():
{}, RpcUpdateType.DISCONNECTED
)
device = _mock_rpc_device("0.12.0")
device = _mock_rpc_device()
rpc_device_mock.return_value = device
rpc_device_mock.return_value.mock_disconnected = Mock(side_effect=disconnected)
rpc_device_mock.return_value.mock_update = Mock(side_effect=update)

View file

@ -967,62 +967,6 @@ async def test_options_flow_ble(hass: HomeAssistant, mock_rpc_device) -> None:
await hass.config_entries.async_unload(entry.entry_id)
async def test_options_flow_pre_ble_device(
hass: HomeAssistant, mock_pre_ble_rpc_device
) -> None:
"""Test setting ble options for gen2 devices with pre ble firmware."""
entry = await init_integration(hass, 2)
result = await hass.config_entries.options.async_init(entry.entry_id)
assert result["type"] == data_entry_flow.FlowResultType.FORM
assert result["step_id"] == "init"
assert result["errors"] is None
result = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={
CONF_BLE_SCANNER_MODE: BLEScannerMode.DISABLED,
},
)
await hass.async_block_till_done()
assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
assert result["data"][CONF_BLE_SCANNER_MODE] == BLEScannerMode.DISABLED
result = await hass.config_entries.options.async_init(entry.entry_id)
assert result["type"] == data_entry_flow.FlowResultType.FORM
assert result["step_id"] == "init"
assert result["errors"] is None
result = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={
CONF_BLE_SCANNER_MODE: BLEScannerMode.ACTIVE,
},
)
await hass.async_block_till_done()
assert result["type"] == data_entry_flow.FlowResultType.ABORT
assert result["reason"] == "ble_unsupported"
result = await hass.config_entries.options.async_init(entry.entry_id)
assert result["type"] == data_entry_flow.FlowResultType.FORM
assert result["step_id"] == "init"
assert result["errors"] is None
result = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={
CONF_BLE_SCANNER_MODE: BLEScannerMode.PASSIVE,
},
)
await hass.async_block_till_done()
assert result["type"] == data_entry_flow.FlowResultType.ABORT
assert result["reason"] == "ble_unsupported"
await hass.config_entries.async_unload(entry.entry_id)
async def test_zeroconf_already_configured_triggers_refresh_mac_in_name(
hass: HomeAssistant, mock_rpc_device, monkeypatch
) -> None:

View file

@ -134,7 +134,10 @@ async def test_block_device_rgb_bulb(
ColorMode.COLOR_TEMP,
ColorMode.RGB,
]
assert attributes[ATTR_SUPPORTED_FEATURES] == LightEntityFeature.EFFECT
assert (
attributes[ATTR_SUPPORTED_FEATURES]
== LightEntityFeature.EFFECT | LightEntityFeature.TRANSITION
)
assert len(attributes[ATTR_EFFECT_LIST]) == 4
assert attributes[ATTR_EFFECT] == "Off"
@ -232,7 +235,7 @@ async def test_block_device_white_bulb(
assert state.state == STATE_ON
assert attributes[ATTR_BRIGHTNESS] == 128
assert attributes[ATTR_SUPPORTED_COLOR_MODES] == [ColorMode.BRIGHTNESS]
assert attributes[ATTR_SUPPORTED_FEATURES] == 0
assert attributes[ATTR_SUPPORTED_FEATURES] == LightEntityFeature.TRANSITION
# Turn off
mock_block_device.blocks[LIGHT_BLOCK_ID].set_state.reset_mock()