mirror of
https://github.com/home-assistant/core.git
synced 2025-07-27 15:17:35 +00:00
Add support for Shelly Gen3 devices (#104874)
* Add support for Gen3 devices * Add RPC_GENERATIONS const * Add gen3 to tests * More tests * Add BLOCK_GENERATIONS const * Use *_GENERATIONS constants from aioshelly
This commit is contained in:
parent
662e19999d
commit
bf93929826
@ -6,6 +6,7 @@ from typing import Any, Final
|
|||||||
|
|
||||||
from aioshelly.block_device import BlockDevice, BlockUpdateType
|
from aioshelly.block_device import BlockDevice, BlockUpdateType
|
||||||
from aioshelly.common import ConnectionOptions
|
from aioshelly.common import ConnectionOptions
|
||||||
|
from aioshelly.const import RPC_GENERATIONS
|
||||||
from aioshelly.exceptions import (
|
from aioshelly.exceptions import (
|
||||||
DeviceConnectionError,
|
DeviceConnectionError,
|
||||||
InvalidAuthError,
|
InvalidAuthError,
|
||||||
@ -123,7 +124,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
|
|
||||||
get_entry_data(hass)[entry.entry_id] = ShellyEntryData()
|
get_entry_data(hass)[entry.entry_id] = ShellyEntryData()
|
||||||
|
|
||||||
if get_device_entry_gen(entry) == 2:
|
if get_device_entry_gen(entry) in RPC_GENERATIONS:
|
||||||
return await _async_setup_rpc_entry(hass, entry)
|
return await _async_setup_rpc_entry(hass, entry)
|
||||||
|
|
||||||
return await _async_setup_block_entry(hass, entry)
|
return await _async_setup_block_entry(hass, entry)
|
||||||
@ -313,7 +314,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
if not entry.data.get(CONF_SLEEP_PERIOD):
|
if not entry.data.get(CONF_SLEEP_PERIOD):
|
||||||
platforms = RPC_PLATFORMS
|
platforms = RPC_PLATFORMS
|
||||||
|
|
||||||
if get_device_entry_gen(entry) == 2:
|
if get_device_entry_gen(entry) in RPC_GENERATIONS:
|
||||||
if unload_ok := await hass.config_entries.async_unload_platforms(
|
if unload_ok := await hass.config_entries.async_unload_platforms(
|
||||||
entry, platforms
|
entry, platforms
|
||||||
):
|
):
|
||||||
|
@ -4,6 +4,8 @@ from __future__ import annotations
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import Final, cast
|
from typing import Final, cast
|
||||||
|
|
||||||
|
from aioshelly.const import RPC_GENERATIONS
|
||||||
|
|
||||||
from homeassistant.components.binary_sensor import (
|
from homeassistant.components.binary_sensor import (
|
||||||
BinarySensorDeviceClass,
|
BinarySensorDeviceClass,
|
||||||
BinarySensorEntity,
|
BinarySensorEntity,
|
||||||
@ -224,7 +226,7 @@ async def async_setup_entry(
|
|||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up sensors for device."""
|
"""Set up sensors for device."""
|
||||||
if get_device_entry_gen(config_entry) == 2:
|
if get_device_entry_gen(config_entry) in RPC_GENERATIONS:
|
||||||
if config_entry.data[CONF_SLEEP_PERIOD]:
|
if config_entry.data[CONF_SLEEP_PERIOD]:
|
||||||
async_setup_entry_rpc(
|
async_setup_entry_rpc(
|
||||||
hass,
|
hass,
|
||||||
|
@ -5,6 +5,8 @@ from collections.abc import Callable, Coroutine
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import TYPE_CHECKING, Any, Final, Generic, TypeVar
|
from typing import TYPE_CHECKING, Any, Final, Generic, TypeVar
|
||||||
|
|
||||||
|
from aioshelly.const import RPC_GENERATIONS
|
||||||
|
|
||||||
from homeassistant.components.button import (
|
from homeassistant.components.button import (
|
||||||
ButtonDeviceClass,
|
ButtonDeviceClass,
|
||||||
ButtonEntity,
|
ButtonEntity,
|
||||||
@ -126,7 +128,7 @@ async def async_setup_entry(
|
|||||||
return async_migrate_unique_ids(entity_entry, coordinator)
|
return async_migrate_unique_ids(entity_entry, coordinator)
|
||||||
|
|
||||||
coordinator: ShellyRpcCoordinator | ShellyBlockCoordinator | None = None
|
coordinator: ShellyRpcCoordinator | ShellyBlockCoordinator | None = None
|
||||||
if get_device_entry_gen(config_entry) == 2:
|
if get_device_entry_gen(config_entry) in RPC_GENERATIONS:
|
||||||
coordinator = get_entry_data(hass)[config_entry.entry_id].rpc
|
coordinator = get_entry_data(hass)[config_entry.entry_id].rpc
|
||||||
else:
|
else:
|
||||||
coordinator = get_entry_data(hass)[config_entry.entry_id].block
|
coordinator = get_entry_data(hass)[config_entry.entry_id].block
|
||||||
|
@ -6,6 +6,7 @@ from dataclasses import asdict, dataclass
|
|||||||
from typing import Any, cast
|
from typing import Any, cast
|
||||||
|
|
||||||
from aioshelly.block_device import Block
|
from aioshelly.block_device import Block
|
||||||
|
from aioshelly.const import RPC_GENERATIONS
|
||||||
from aioshelly.exceptions import DeviceConnectionError, InvalidAuthError
|
from aioshelly.exceptions import DeviceConnectionError, InvalidAuthError
|
||||||
|
|
||||||
from homeassistant.components.climate import (
|
from homeassistant.components.climate import (
|
||||||
@ -51,7 +52,7 @@ async def async_setup_entry(
|
|||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up climate device."""
|
"""Set up climate device."""
|
||||||
if get_device_entry_gen(config_entry) == 2:
|
if get_device_entry_gen(config_entry) in RPC_GENERATIONS:
|
||||||
return async_setup_rpc_entry(hass, config_entry, async_add_entities)
|
return async_setup_rpc_entry(hass, config_entry, async_add_entities)
|
||||||
|
|
||||||
coordinator = get_entry_data(hass)[config_entry.entry_id].block
|
coordinator = get_entry_data(hass)[config_entry.entry_id].block
|
||||||
|
@ -6,6 +6,7 @@ from typing import Any, Final
|
|||||||
|
|
||||||
from aioshelly.block_device import BlockDevice
|
from aioshelly.block_device import BlockDevice
|
||||||
from aioshelly.common import ConnectionOptions, get_info
|
from aioshelly.common import ConnectionOptions, get_info
|
||||||
|
from aioshelly.const import BLOCK_GENERATIONS, RPC_GENERATIONS
|
||||||
from aioshelly.exceptions import (
|
from aioshelly.exceptions import (
|
||||||
DeviceConnectionError,
|
DeviceConnectionError,
|
||||||
FirmwareUnsupported,
|
FirmwareUnsupported,
|
||||||
@ -66,7 +67,9 @@ async def validate_input(
|
|||||||
"""
|
"""
|
||||||
options = ConnectionOptions(host, data.get(CONF_USERNAME), data.get(CONF_PASSWORD))
|
options = ConnectionOptions(host, data.get(CONF_USERNAME), data.get(CONF_PASSWORD))
|
||||||
|
|
||||||
if get_info_gen(info) == 2:
|
gen = get_info_gen(info)
|
||||||
|
|
||||||
|
if gen in RPC_GENERATIONS:
|
||||||
ws_context = await get_ws_context(hass)
|
ws_context = await get_ws_context(hass)
|
||||||
rpc_device = await RpcDevice.create(
|
rpc_device = await RpcDevice.create(
|
||||||
async_get_clientsession(hass),
|
async_get_clientsession(hass),
|
||||||
@ -81,7 +84,7 @@ async def validate_input(
|
|||||||
"title": rpc_device.name,
|
"title": rpc_device.name,
|
||||||
CONF_SLEEP_PERIOD: sleep_period,
|
CONF_SLEEP_PERIOD: sleep_period,
|
||||||
"model": rpc_device.shelly.get("model"),
|
"model": rpc_device.shelly.get("model"),
|
||||||
"gen": 2,
|
"gen": gen,
|
||||||
}
|
}
|
||||||
|
|
||||||
# Gen1
|
# Gen1
|
||||||
@ -96,7 +99,7 @@ async def validate_input(
|
|||||||
"title": block_device.name,
|
"title": block_device.name,
|
||||||
CONF_SLEEP_PERIOD: get_block_device_sleep_period(block_device.settings),
|
CONF_SLEEP_PERIOD: get_block_device_sleep_period(block_device.settings),
|
||||||
"model": block_device.model,
|
"model": block_device.model,
|
||||||
"gen": 1,
|
"gen": gen,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -165,7 +168,7 @@ class ShellyConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||||||
"""Handle the credentials step."""
|
"""Handle the credentials step."""
|
||||||
errors: dict[str, str] = {}
|
errors: dict[str, str] = {}
|
||||||
if user_input is not None:
|
if user_input is not None:
|
||||||
if get_info_gen(self.info) == 2:
|
if get_info_gen(self.info) in RPC_GENERATIONS:
|
||||||
user_input[CONF_USERNAME] = "admin"
|
user_input[CONF_USERNAME] = "admin"
|
||||||
try:
|
try:
|
||||||
device_info = await validate_input(
|
device_info = await validate_input(
|
||||||
@ -194,7 +197,7 @@ class ShellyConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||||||
else:
|
else:
|
||||||
user_input = {}
|
user_input = {}
|
||||||
|
|
||||||
if get_info_gen(self.info) == 2:
|
if get_info_gen(self.info) in RPC_GENERATIONS:
|
||||||
schema = {
|
schema = {
|
||||||
vol.Required(CONF_PASSWORD, default=user_input.get(CONF_PASSWORD)): str,
|
vol.Required(CONF_PASSWORD, default=user_input.get(CONF_PASSWORD)): str,
|
||||||
}
|
}
|
||||||
@ -331,7 +334,7 @@ class ShellyConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||||||
await self.hass.config_entries.async_reload(self.entry.entry_id)
|
await self.hass.config_entries.async_reload(self.entry.entry_id)
|
||||||
return self.async_abort(reason="reauth_successful")
|
return self.async_abort(reason="reauth_successful")
|
||||||
|
|
||||||
if self.entry.data.get("gen", 1) == 1:
|
if self.entry.data.get("gen", 1) in BLOCK_GENERATIONS:
|
||||||
schema = {
|
schema = {
|
||||||
vol.Required(CONF_USERNAME): str,
|
vol.Required(CONF_USERNAME): str,
|
||||||
vol.Required(CONF_PASSWORD): str,
|
vol.Required(CONF_PASSWORD): str,
|
||||||
@ -360,7 +363,7 @@ class ShellyConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||||||
def async_supports_options_flow(cls, config_entry: ConfigEntry) -> bool:
|
def async_supports_options_flow(cls, config_entry: ConfigEntry) -> bool:
|
||||||
"""Return options flow support for this handler."""
|
"""Return options flow support for this handler."""
|
||||||
return (
|
return (
|
||||||
config_entry.data.get("gen") == 2
|
config_entry.data.get("gen") in RPC_GENERATIONS
|
||||||
and not config_entry.data.get(CONF_SLEEP_PERIOD)
|
and not config_entry.data.get(CONF_SLEEP_PERIOD)
|
||||||
and config_entry.data.get("model") != MODEL_WALL_DISPLAY
|
and config_entry.data.get("model") != MODEL_WALL_DISPLAY
|
||||||
)
|
)
|
||||||
|
@ -4,6 +4,7 @@ from __future__ import annotations
|
|||||||
from typing import Any, cast
|
from typing import Any, cast
|
||||||
|
|
||||||
from aioshelly.block_device import Block
|
from aioshelly.block_device import Block
|
||||||
|
from aioshelly.const import RPC_GENERATIONS
|
||||||
|
|
||||||
from homeassistant.components.cover import (
|
from homeassistant.components.cover import (
|
||||||
ATTR_POSITION,
|
ATTR_POSITION,
|
||||||
@ -26,7 +27,7 @@ async def async_setup_entry(
|
|||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up covers for device."""
|
"""Set up covers for device."""
|
||||||
if get_device_entry_gen(config_entry) == 2:
|
if get_device_entry_gen(config_entry) in RPC_GENERATIONS:
|
||||||
return async_setup_rpc_entry(hass, config_entry, async_add_entities)
|
return async_setup_rpc_entry(hass, config_entry, async_add_entities)
|
||||||
|
|
||||||
return async_setup_block_entry(hass, config_entry, async_add_entities)
|
return async_setup_block_entry(hass, config_entry, async_add_entities)
|
||||||
|
@ -6,7 +6,7 @@ from dataclasses import dataclass
|
|||||||
from typing import TYPE_CHECKING, Any, Final
|
from typing import TYPE_CHECKING, Any, Final
|
||||||
|
|
||||||
from aioshelly.block_device import Block
|
from aioshelly.block_device import Block
|
||||||
from aioshelly.const import MODEL_I3
|
from aioshelly.const import MODEL_I3, RPC_GENERATIONS
|
||||||
|
|
||||||
from homeassistant.components.event import (
|
from homeassistant.components.event import (
|
||||||
DOMAIN as EVENT_DOMAIN,
|
DOMAIN as EVENT_DOMAIN,
|
||||||
@ -80,7 +80,7 @@ async def async_setup_entry(
|
|||||||
|
|
||||||
coordinator: ShellyRpcCoordinator | ShellyBlockCoordinator | None = None
|
coordinator: ShellyRpcCoordinator | ShellyBlockCoordinator | None = None
|
||||||
|
|
||||||
if get_device_entry_gen(config_entry) == 2:
|
if get_device_entry_gen(config_entry) in RPC_GENERATIONS:
|
||||||
coordinator = get_entry_data(hass)[config_entry.entry_id].rpc
|
coordinator = get_entry_data(hass)[config_entry.entry_id].rpc
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
assert coordinator
|
assert coordinator
|
||||||
|
@ -4,7 +4,7 @@ from __future__ import annotations
|
|||||||
from typing import Any, cast
|
from typing import Any, cast
|
||||||
|
|
||||||
from aioshelly.block_device import Block
|
from aioshelly.block_device import Block
|
||||||
from aioshelly.const import MODEL_BULB
|
from aioshelly.const import MODEL_BULB, RPC_GENERATIONS
|
||||||
|
|
||||||
from homeassistant.components.light import (
|
from homeassistant.components.light import (
|
||||||
ATTR_BRIGHTNESS,
|
ATTR_BRIGHTNESS,
|
||||||
@ -53,7 +53,7 @@ async def async_setup_entry(
|
|||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up lights for device."""
|
"""Set up lights for device."""
|
||||||
if get_device_entry_gen(config_entry) == 2:
|
if get_device_entry_gen(config_entry) in RPC_GENERATIONS:
|
||||||
return async_setup_rpc_entry(hass, config_entry, async_add_entities)
|
return async_setup_rpc_entry(hass, config_entry, async_add_entities)
|
||||||
|
|
||||||
return async_setup_block_entry(hass, config_entry, async_add_entities)
|
return async_setup_block_entry(hass, config_entry, async_add_entities)
|
||||||
|
@ -6,6 +6,7 @@ from dataclasses import dataclass
|
|||||||
from typing import Final, cast
|
from typing import Final, cast
|
||||||
|
|
||||||
from aioshelly.block_device import Block
|
from aioshelly.block_device import Block
|
||||||
|
from aioshelly.const import RPC_GENERATIONS
|
||||||
|
|
||||||
from homeassistant.components.sensor import (
|
from homeassistant.components.sensor import (
|
||||||
RestoreSensor,
|
RestoreSensor,
|
||||||
@ -925,7 +926,7 @@ async def async_setup_entry(
|
|||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up sensors for device."""
|
"""Set up sensors for device."""
|
||||||
if get_device_entry_gen(config_entry) == 2:
|
if get_device_entry_gen(config_entry) in RPC_GENERATIONS:
|
||||||
if config_entry.data[CONF_SLEEP_PERIOD]:
|
if config_entry.data[CONF_SLEEP_PERIOD]:
|
||||||
async_setup_entry_rpc(
|
async_setup_entry_rpc(
|
||||||
hass,
|
hass,
|
||||||
|
@ -5,7 +5,7 @@ from dataclasses import dataclass
|
|||||||
from typing import Any, cast
|
from typing import Any, cast
|
||||||
|
|
||||||
from aioshelly.block_device import Block
|
from aioshelly.block_device import Block
|
||||||
from aioshelly.const import MODEL_2, MODEL_25, MODEL_GAS
|
from aioshelly.const import MODEL_2, MODEL_25, MODEL_GAS, RPC_GENERATIONS
|
||||||
|
|
||||||
from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
|
from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
@ -49,7 +49,7 @@ async def async_setup_entry(
|
|||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up switches for device."""
|
"""Set up switches for device."""
|
||||||
if get_device_entry_gen(config_entry) == 2:
|
if get_device_entry_gen(config_entry) in RPC_GENERATIONS:
|
||||||
return async_setup_rpc_entry(hass, config_entry, async_add_entities)
|
return async_setup_rpc_entry(hass, config_entry, async_add_entities)
|
||||||
|
|
||||||
return async_setup_block_entry(hass, config_entry, async_add_entities)
|
return async_setup_block_entry(hass, config_entry, async_add_entities)
|
||||||
|
@ -6,6 +6,7 @@ from dataclasses import dataclass
|
|||||||
import logging
|
import logging
|
||||||
from typing import Any, Final, cast
|
from typing import Any, Final, cast
|
||||||
|
|
||||||
|
from aioshelly.const import RPC_GENERATIONS
|
||||||
from aioshelly.exceptions import DeviceConnectionError, InvalidAuthError, RpcCallError
|
from aioshelly.exceptions import DeviceConnectionError, InvalidAuthError, RpcCallError
|
||||||
|
|
||||||
from homeassistant.components.update import (
|
from homeassistant.components.update import (
|
||||||
@ -119,7 +120,7 @@ async def async_setup_entry(
|
|||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up update entities for Shelly component."""
|
"""Set up update entities for Shelly component."""
|
||||||
if get_device_entry_gen(config_entry) == 2:
|
if get_device_entry_gen(config_entry) in RPC_GENERATIONS:
|
||||||
if config_entry.data[CONF_SLEEP_PERIOD]:
|
if config_entry.data[CONF_SLEEP_PERIOD]:
|
||||||
async_setup_entry_rpc(
|
async_setup_entry_rpc(
|
||||||
hass,
|
hass,
|
||||||
|
@ -7,12 +7,14 @@ from typing import Any, cast
|
|||||||
from aiohttp.web import Request, WebSocketResponse
|
from aiohttp.web import Request, WebSocketResponse
|
||||||
from aioshelly.block_device import COAP, Block, BlockDevice
|
from aioshelly.block_device import COAP, Block, BlockDevice
|
||||||
from aioshelly.const import (
|
from aioshelly.const import (
|
||||||
|
BLOCK_GENERATIONS,
|
||||||
MODEL_1L,
|
MODEL_1L,
|
||||||
MODEL_DIMMER,
|
MODEL_DIMMER,
|
||||||
MODEL_DIMMER_2,
|
MODEL_DIMMER_2,
|
||||||
MODEL_EM3,
|
MODEL_EM3,
|
||||||
MODEL_I3,
|
MODEL_I3,
|
||||||
MODEL_NAMES,
|
MODEL_NAMES,
|
||||||
|
RPC_GENERATIONS,
|
||||||
)
|
)
|
||||||
from aioshelly.rpc_device import RpcDevice, WsServer
|
from aioshelly.rpc_device import RpcDevice, WsServer
|
||||||
|
|
||||||
@ -284,7 +286,7 @@ def get_info_gen(info: dict[str, Any]) -> int:
|
|||||||
|
|
||||||
def get_model_name(info: dict[str, Any]) -> str:
|
def get_model_name(info: dict[str, Any]) -> str:
|
||||||
"""Return the device model name."""
|
"""Return the device model name."""
|
||||||
if get_info_gen(info) == 2:
|
if get_info_gen(info) in RPC_GENERATIONS:
|
||||||
return cast(str, MODEL_NAMES.get(info["model"], info["model"]))
|
return cast(str, MODEL_NAMES.get(info["model"], info["model"]))
|
||||||
|
|
||||||
return cast(str, MODEL_NAMES.get(info["type"], info["type"]))
|
return cast(str, MODEL_NAMES.get(info["type"], info["type"]))
|
||||||
@ -420,4 +422,4 @@ def get_release_url(gen: int, model: str, beta: bool) -> str | None:
|
|||||||
if beta or model in DEVICES_WITHOUT_FIRMWARE_CHANGELOG:
|
if beta or model in DEVICES_WITHOUT_FIRMWARE_CHANGELOG:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return GEN1_RELEASE_URL if gen == 1 else GEN2_RELEASE_URL
|
return GEN1_RELEASE_URL if gen in BLOCK_GENERATIONS else GEN2_RELEASE_URL
|
||||||
|
@ -55,6 +55,7 @@ DISCOVERY_INFO_WITH_MAC = zeroconf.ZeroconfServiceInfo(
|
|||||||
[
|
[
|
||||||
(1, MODEL_1),
|
(1, MODEL_1),
|
||||||
(2, MODEL_PLUS_2PM),
|
(2, MODEL_PLUS_2PM),
|
||||||
|
(3, MODEL_PLUS_2PM),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_form(
|
async def test_form(
|
||||||
@ -109,6 +110,12 @@ async def test_form(
|
|||||||
{"password": "test2 password"},
|
{"password": "test2 password"},
|
||||||
"admin",
|
"admin",
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
3,
|
||||||
|
MODEL_PLUS_2PM,
|
||||||
|
{"password": "test2 password"},
|
||||||
|
"admin",
|
||||||
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_form_auth(
|
async def test_form_auth(
|
||||||
@ -465,6 +472,11 @@ async def test_form_auth_errors_test_connection_gen2(
|
|||||||
MODEL_PLUS_2PM,
|
MODEL_PLUS_2PM,
|
||||||
{"mac": "test-mac", "model": MODEL_PLUS_2PM, "auth": False, "gen": 2},
|
{"mac": "test-mac", "model": MODEL_PLUS_2PM, "auth": False, "gen": 2},
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
3,
|
||||||
|
MODEL_PLUS_2PM,
|
||||||
|
{"mac": "test-mac", "model": MODEL_PLUS_2PM, "auth": False, "gen": 3},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_zeroconf(
|
async def test_zeroconf(
|
||||||
@ -742,6 +754,7 @@ async def test_zeroconf_require_auth(hass: HomeAssistant, mock_block_device) ->
|
|||||||
[
|
[
|
||||||
(1, {"username": "test user", "password": "test1 password"}),
|
(1, {"username": "test user", "password": "test1 password"}),
|
||||||
(2, {"password": "test2 password"}),
|
(2, {"password": "test2 password"}),
|
||||||
|
(3, {"password": "test2 password"}),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_reauth_successful(
|
async def test_reauth_successful(
|
||||||
@ -780,6 +793,7 @@ async def test_reauth_successful(
|
|||||||
[
|
[
|
||||||
(1, {"username": "test user", "password": "test1 password"}),
|
(1, {"username": "test user", "password": "test1 password"}),
|
||||||
(2, {"password": "test2 password"}),
|
(2, {"password": "test2 password"}),
|
||||||
|
(3, {"password": "test2 password"}),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_reauth_unsuccessful(hass: HomeAssistant, gen, user_input) -> None:
|
async def test_reauth_unsuccessful(hass: HomeAssistant, gen, user_input) -> None:
|
||||||
|
@ -41,7 +41,7 @@ async def test_custom_coap_port(
|
|||||||
assert "Starting CoAP context with UDP port 7632" in caplog.text
|
assert "Starting CoAP context with UDP port 7632" in caplog.text
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("gen", [1, 2])
|
@pytest.mark.parametrize("gen", [1, 2, 3])
|
||||||
async def test_shared_device_mac(
|
async def test_shared_device_mac(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
gen,
|
gen,
|
||||||
@ -74,7 +74,7 @@ async def test_setup_entry_not_shelly(
|
|||||||
assert "probably comes from a custom integration" in caplog.text
|
assert "probably comes from a custom integration" in caplog.text
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("gen", [1, 2])
|
@pytest.mark.parametrize("gen", [1, 2, 3])
|
||||||
async def test_device_connection_error(
|
async def test_device_connection_error(
|
||||||
hass: HomeAssistant, gen, mock_block_device, mock_rpc_device, monkeypatch
|
hass: HomeAssistant, gen, mock_block_device, mock_rpc_device, monkeypatch
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -90,7 +90,7 @@ async def test_device_connection_error(
|
|||||||
assert entry.state == ConfigEntryState.SETUP_RETRY
|
assert entry.state == ConfigEntryState.SETUP_RETRY
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("gen", [1, 2])
|
@pytest.mark.parametrize("gen", [1, 2, 3])
|
||||||
async def test_mac_mismatch_error(
|
async def test_mac_mismatch_error(
|
||||||
hass: HomeAssistant, gen, mock_block_device, mock_rpc_device, monkeypatch
|
hass: HomeAssistant, gen, mock_block_device, mock_rpc_device, monkeypatch
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -106,7 +106,7 @@ async def test_mac_mismatch_error(
|
|||||||
assert entry.state == ConfigEntryState.SETUP_RETRY
|
assert entry.state == ConfigEntryState.SETUP_RETRY
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("gen", [1, 2])
|
@pytest.mark.parametrize("gen", [1, 2, 3])
|
||||||
async def test_device_auth_error(
|
async def test_device_auth_error(
|
||||||
hass: HomeAssistant, gen, mock_block_device, mock_rpc_device, monkeypatch
|
hass: HomeAssistant, gen, mock_block_device, mock_rpc_device, monkeypatch
|
||||||
) -> None:
|
) -> None:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user