Merge pull request #76679 from home-assistant/rc

pull/76769/head 2022.8.4
Paulus Schoutsen 2022-08-12 14:48:45 -04:00 committed by GitHub
commit e2fae855e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 293 additions and 121 deletions

View File

@ -56,7 +56,7 @@ class BMWNotificationService(BaseNotificationService):
"""Set up the notification service.""" """Set up the notification service."""
self.targets: dict[str, MyBMWVehicle] = targets self.targets: dict[str, MyBMWVehicle] = targets
def send_message(self, message: str = "", **kwargs: Any) -> None: async def async_send_message(self, message: str = "", **kwargs: Any) -> None:
"""Send a message or POI to the car.""" """Send a message or POI to the car."""
for vehicle in kwargs[ATTR_TARGET]: for vehicle in kwargs[ATTR_TARGET]:
vehicle = cast(MyBMWVehicle, vehicle) vehicle = cast(MyBMWVehicle, vehicle)
@ -81,6 +81,6 @@ class BMWNotificationService(BaseNotificationService):
} }
) )
vehicle.remote_services.trigger_send_poi(location_dict) await vehicle.remote_services.trigger_send_poi(location_dict)
else: else:
raise ValueError(f"'data.{ATTR_LOCATION}' is required.") raise ValueError(f"'data.{ATTR_LOCATION}' is required.")

View File

@ -128,26 +128,17 @@ class EvoClimateEntity(EvoDevice, ClimateEntity):
_attr_temperature_unit = TEMP_CELSIUS _attr_temperature_unit = TEMP_CELSIUS
def __init__(self, evo_broker, evo_device) -> None:
"""Initialize a Climate device."""
super().__init__(evo_broker, evo_device)
self._preset_modes = None
@property @property
def hvac_modes(self) -> list[str]: def hvac_modes(self) -> list[str]:
"""Return a list of available hvac operation modes.""" """Return a list of available hvac operation modes."""
return list(HA_HVAC_TO_TCS) return list(HA_HVAC_TO_TCS)
@property
def preset_modes(self) -> list[str] | None:
"""Return a list of available preset modes."""
return self._preset_modes
class EvoZone(EvoChild, EvoClimateEntity): class EvoZone(EvoChild, EvoClimateEntity):
"""Base for a Honeywell TCC Zone.""" """Base for a Honeywell TCC Zone."""
_attr_preset_modes = list(HA_PRESET_TO_EVO)
def __init__(self, evo_broker, evo_device) -> None: def __init__(self, evo_broker, evo_device) -> None:
"""Initialize a Honeywell TCC Zone.""" """Initialize a Honeywell TCC Zone."""
super().__init__(evo_broker, evo_device) super().__init__(evo_broker, evo_device)
@ -233,7 +224,7 @@ class EvoZone(EvoChild, EvoClimateEntity):
""" """
return self._evo_device.setpointCapabilities["maxHeatSetpoint"] return self._evo_device.setpointCapabilities["maxHeatSetpoint"]
async def async_set_temperature(self, **kwargs) -> None: async def async_set_temperature(self, **kwargs: Any) -> None:
"""Set a new target temperature.""" """Set a new target temperature."""
temperature = kwargs["temperature"] temperature = kwargs["temperature"]
@ -249,7 +240,7 @@ class EvoZone(EvoChild, EvoClimateEntity):
self._evo_device.set_temperature(temperature, until=until) self._evo_device.set_temperature(temperature, until=until)
) )
async def async_set_hvac_mode(self, hvac_mode: str) -> None: async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
"""Set a Zone to one of its native EVO_* operating modes. """Set a Zone to one of its native EVO_* operating modes.
Zones inherit their _effective_ operating mode from their Controller. Zones inherit their _effective_ operating mode from their Controller.
@ -387,7 +378,7 @@ class EvoController(EvoClimateEntity):
"""Return the current preset mode, e.g., home, away, temp.""" """Return the current preset mode, e.g., home, away, temp."""
return TCS_PRESET_TO_HA.get(self._evo_tcs.systemModeStatus["mode"]) return TCS_PRESET_TO_HA.get(self._evo_tcs.systemModeStatus["mode"])
async def async_set_temperature(self, **kwargs) -> None: async def async_set_temperature(self, **kwargs: Any) -> None:
"""Raise exception as Controllers don't have a target temperature.""" """Raise exception as Controllers don't have a target temperature."""
raise NotImplementedError("Evohome Controllers don't have target temperatures.") raise NotImplementedError("Evohome Controllers don't have target temperatures.")

View File

@ -67,6 +67,7 @@ class GoveeConfigFlow(ConfigFlow, domain=DOMAIN):
if user_input is not None: if user_input is not None:
address = user_input[CONF_ADDRESS] address = user_input[CONF_ADDRESS]
await self.async_set_unique_id(address, raise_on_progress=False) await self.async_set_unique_id(address, raise_on_progress=False)
self._abort_if_unique_id_configured()
return self.async_create_entry( return self.async_create_entry(
title=self._discovered_devices[address], data={} title=self._discovered_devices[address], data={}
) )

View File

@ -19,6 +19,10 @@
"manufacturer_id": 818, "manufacturer_id": 818,
"service_uuid": "00008551-0000-1000-8000-00805f9b34fb" "service_uuid": "00008551-0000-1000-8000-00805f9b34fb"
}, },
{
"manufacturer_id": 59970,
"service_uuid": "00008151-0000-1000-8000-00805f9b34fb"
},
{ {
"manufacturer_id": 14474, "manufacturer_id": 14474,
"service_uuid": "00008151-0000-1000-8000-00805f9b34fb" "service_uuid": "00008151-0000-1000-8000-00805f9b34fb"
@ -28,7 +32,7 @@
"service_uuid": "00008251-0000-1000-8000-00805f9b34fb" "service_uuid": "00008251-0000-1000-8000-00805f9b34fb"
} }
], ],
"requirements": ["govee-ble==0.14.0"], "requirements": ["govee-ble==0.14.1"],
"dependencies": ["bluetooth"], "dependencies": ["bluetooth"],
"codeowners": ["@bdraco"], "codeowners": ["@bdraco"],
"iot_class": "local_push" "iot_class": "local_push"

View File

@ -3,7 +3,7 @@
"name": "HomeKit Controller", "name": "HomeKit Controller",
"config_flow": true, "config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/homekit_controller", "documentation": "https://www.home-assistant.io/integrations/homekit_controller",
"requirements": ["aiohomekit==1.2.8"], "requirements": ["aiohomekit==1.2.9"],
"zeroconf": ["_hap._tcp.local.", "_hap._udp.local."], "zeroconf": ["_hap._tcp.local.", "_hap._udp.local."],
"bluetooth": [{ "manufacturer_id": 76, "manufacturer_data_start": [6] }], "bluetooth": [{ "manufacturer_id": 76, "manufacturer_data_start": [6] }],
"dependencies": ["bluetooth", "zeroconf"], "dependencies": ["bluetooth", "zeroconf"],

View File

@ -279,11 +279,12 @@ class Router:
self._get_data( self._get_data(
KEY_WLAN_WIFI_GUEST_NETWORK_SWITCH, KEY_WLAN_WIFI_GUEST_NETWORK_SWITCH,
lambda: next( lambda: next(
filter( (
lambda ssid: ssid.get("wifiisguestnetwork") == "1", ssid
self.client.wlan.multi_basic_settings() for ssid in self.client.wlan.multi_basic_settings()
.get("Ssids", {}) .get("Ssids", {})
.get("Ssid", []), .get("Ssid", [])
if isinstance(ssid, dict) and ssid.get("wifiisguestnetwork") == "1"
), ),
{}, {},
), ),

View File

@ -37,7 +37,7 @@ async def async_setup_entry(
if router.data.get(KEY_DIALUP_MOBILE_DATASWITCH): if router.data.get(KEY_DIALUP_MOBILE_DATASWITCH):
switches.append(HuaweiLteMobileDataSwitch(router)) switches.append(HuaweiLteMobileDataSwitch(router))
if router.data.get(KEY_WLAN_WIFI_GUEST_NETWORK_SWITCH).get("WifiEnable"): if router.data.get(KEY_WLAN_WIFI_GUEST_NETWORK_SWITCH, {}).get("WifiEnable"):
switches.append(HuaweiLteWifiGuestNetworkSwitch(router)) switches.append(HuaweiLteWifiGuestNetworkSwitch(router))
async_add_entities(switches, True) async_add_entities(switches, True)
@ -151,6 +151,6 @@ class HuaweiLteWifiGuestNetworkSwitch(HuaweiLteBaseSwitch):
return "mdi:wifi" if self.is_on else "mdi:wifi-off" return "mdi:wifi" if self.is_on else "mdi:wifi-off"
@property @property
def extra_state_attributes(self) -> dict[str, str]: def extra_state_attributes(self) -> dict[str, str | None]:
"""Return the state attributes.""" """Return the state attributes."""
return {"ssid": self.router.data[self.key].get("WifiSsid")} return {"ssid": self.router.data[self.key].get("WifiSsid")}

View File

@ -67,6 +67,7 @@ class INKBIRDConfigFlow(ConfigFlow, domain=DOMAIN):
if user_input is not None: if user_input is not None:
address = user_input[CONF_ADDRESS] address = user_input[CONF_ADDRESS]
await self.async_set_unique_id(address, raise_on_progress=False) await self.async_set_unique_id(address, raise_on_progress=False)
self._abort_if_unique_id_configured()
return self.async_create_entry( return self.async_create_entry(
title=self._discovered_devices[address], data={} title=self._discovered_devices[address], data={}
) )

View File

@ -67,6 +67,7 @@ class MoatConfigFlow(ConfigFlow, domain=DOMAIN):
if user_input is not None: if user_input is not None:
address = user_input[CONF_ADDRESS] address = user_input[CONF_ADDRESS]
await self.async_set_unique_id(address, raise_on_progress=False) await self.async_set_unique_id(address, raise_on_progress=False)
self._abort_if_unique_id_configured()
return self.async_create_entry( return self.async_create_entry(
title=self._discovered_devices[address], data={} title=self._discovered_devices[address], data={}
) )

View File

@ -67,6 +67,7 @@ class SensorPushConfigFlow(ConfigFlow, domain=DOMAIN):
if user_input is not None: if user_input is not None:
address = user_input[CONF_ADDRESS] address = user_input[CONF_ADDRESS]
await self.async_set_unique_id(address, raise_on_progress=False) await self.async_set_unique_id(address, raise_on_progress=False)
self._abort_if_unique_id_configured()
return self.async_create_entry( return self.async_create_entry(
title=self._discovered_devices[address], data={} title=self._discovered_devices[address], data={}
) )

View File

@ -180,7 +180,10 @@ class SpotifyMediaPlayer(MediaPlayerEntity):
@property @property
def media_position(self) -> int | None: def media_position(self) -> int | None:
"""Position of current playing media in seconds.""" """Position of current playing media in seconds."""
if not self._currently_playing: if (
not self._currently_playing
or self._currently_playing.get("progress_ms") is None
):
return None return None
return self._currently_playing["progress_ms"] / 1000 return self._currently_playing["progress_ms"] / 1000

View File

@ -4,7 +4,6 @@ from __future__ import annotations
from contextlib import suppress from contextlib import suppress
import logging import logging
from aiohttp.hdrs import CONTENT_TYPE
import requests import requests
import voluptuous as vol import voluptuous as vol
@ -79,7 +78,7 @@ class SwisscomDeviceScanner(DeviceScanner):
def get_swisscom_data(self): def get_swisscom_data(self):
"""Retrieve data from Swisscom and return parsed result.""" """Retrieve data from Swisscom and return parsed result."""
url = f"http://{self.host}/ws" url = f"http://{self.host}/ws"
headers = {CONTENT_TYPE: "application/x-sah-ws-4-call+json"} headers = {"Content-Type": "application/x-sah-ws-4-call+json"}
data = """ data = """
{"service":"Devices", "method":"get", {"service":"Devices", "method":"get",
"parameters":{"expression":"lan and not self"}}""" "parameters":{"expression":"lan and not self"}}"""

View File

@ -205,6 +205,7 @@ class XiaomiConfigFlow(ConfigFlow, domain=DOMAIN):
if user_input is not None: if user_input is not None:
address = user_input[CONF_ADDRESS] address = user_input[CONF_ADDRESS]
await self.async_set_unique_id(address, raise_on_progress=False) await self.async_set_unique_id(address, raise_on_progress=False)
self._abort_if_unique_id_configured()
discovery = self._discovered_devices[address] discovery = self._discovered_devices[address]
self.context["title_placeholders"] = {"name": discovery.title} self.context["title_placeholders"] = {"name": discovery.title}

View File

@ -4,12 +4,12 @@
"config_flow": true, "config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/zha", "documentation": "https://www.home-assistant.io/integrations/zha",
"requirements": [ "requirements": [
"bellows==0.31.3", "bellows==0.32.0",
"pyserial==3.5", "pyserial==3.5",
"pyserial-asyncio==0.6", "pyserial-asyncio==0.6",
"zha-quirks==0.0.78", "zha-quirks==0.0.78",
"zigpy-deconz==0.18.0", "zigpy-deconz==0.18.0",
"zigpy==0.49.0", "zigpy==0.49.1",
"zigpy-xbee==0.15.0", "zigpy-xbee==0.15.0",
"zigpy-zigate==0.9.1", "zigpy-zigate==0.9.1",
"zigpy-znp==0.8.1" "zigpy-znp==0.8.1"

View File

@ -7,7 +7,7 @@ from .backports.enum import StrEnum
MAJOR_VERSION: Final = 2022 MAJOR_VERSION: Final = 2022
MINOR_VERSION: Final = 8 MINOR_VERSION: Final = 8
PATCH_VERSION: Final = "3" PATCH_VERSION: Final = "4"
__short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}" __short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}"
__version__: Final = f"{__short_version__}.{PATCH_VERSION}" __version__: Final = f"{__short_version__}.{PATCH_VERSION}"
REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 9, 0) REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 9, 0)

View File

@ -46,6 +46,11 @@ BLUETOOTH: list[dict[str, str | int | list[int]]] = [
"manufacturer_id": 818, "manufacturer_id": 818,
"service_uuid": "00008551-0000-1000-8000-00805f9b34fb" "service_uuid": "00008551-0000-1000-8000-00805f9b34fb"
}, },
{
"domain": "govee_ble",
"manufacturer_id": 59970,
"service_uuid": "00008151-0000-1000-8000-00805f9b34fb"
},
{ {
"domain": "govee_ble", "domain": "govee_ble",
"manufacturer_id": 14474, "manufacturer_id": 14474,

View File

@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "homeassistant" name = "homeassistant"
version = "2022.8.3" version = "2022.8.4"
license = {text = "Apache-2.0"} license = {text = "Apache-2.0"}
description = "Open-source home automation platform running on Python 3." description = "Open-source home automation platform running on Python 3."
readme = "README.rst" readme = "README.rst"

View File

@ -168,7 +168,7 @@ aioguardian==2022.07.0
aioharmony==0.2.9 aioharmony==0.2.9
# homeassistant.components.homekit_controller # homeassistant.components.homekit_controller
aiohomekit==1.2.8 aiohomekit==1.2.9
# homeassistant.components.emulated_hue # homeassistant.components.emulated_hue
# homeassistant.components.http # homeassistant.components.http
@ -396,7 +396,7 @@ beautifulsoup4==4.11.1
# beewi_smartclim==0.0.10 # beewi_smartclim==0.0.10
# homeassistant.components.zha # homeassistant.components.zha
bellows==0.31.3 bellows==0.32.0
# homeassistant.components.bmw_connected_drive # homeassistant.components.bmw_connected_drive
bimmer_connected==0.10.1 bimmer_connected==0.10.1
@ -760,7 +760,7 @@ googlemaps==2.5.1
goslide-api==0.5.1 goslide-api==0.5.1
# homeassistant.components.govee_ble # homeassistant.components.govee_ble
govee-ble==0.14.0 govee-ble==0.14.1
# homeassistant.components.remote_rpi_gpio # homeassistant.components.remote_rpi_gpio
gpiozero==1.6.2 gpiozero==1.6.2
@ -2535,7 +2535,7 @@ zigpy-zigate==0.9.1
zigpy-znp==0.8.1 zigpy-znp==0.8.1
# homeassistant.components.zha # homeassistant.components.zha
zigpy==0.49.0 zigpy==0.49.1
# homeassistant.components.zoneminder # homeassistant.components.zoneminder
zm-py==0.5.2 zm-py==0.5.2

View File

@ -152,7 +152,7 @@ aioguardian==2022.07.0
aioharmony==0.2.9 aioharmony==0.2.9
# homeassistant.components.homekit_controller # homeassistant.components.homekit_controller
aiohomekit==1.2.8 aiohomekit==1.2.9
# homeassistant.components.emulated_hue # homeassistant.components.emulated_hue
# homeassistant.components.http # homeassistant.components.http
@ -320,7 +320,7 @@ base36==0.1.1
beautifulsoup4==4.11.1 beautifulsoup4==4.11.1
# homeassistant.components.zha # homeassistant.components.zha
bellows==0.31.3 bellows==0.32.0
# homeassistant.components.bmw_connected_drive # homeassistant.components.bmw_connected_drive
bimmer_connected==0.10.1 bimmer_connected==0.10.1
@ -561,7 +561,7 @@ google-nest-sdm==2.0.0
googlemaps==2.5.1 googlemaps==2.5.1
# homeassistant.components.govee_ble # homeassistant.components.govee_ble
govee-ble==0.14.0 govee-ble==0.14.1
# homeassistant.components.gree # homeassistant.components.gree
greeclimate==1.3.0 greeclimate==1.3.0
@ -1709,7 +1709,7 @@ zigpy-zigate==0.9.1
zigpy-znp==0.8.1 zigpy-znp==0.8.1
# homeassistant.components.zha # homeassistant.components.zha
zigpy==0.49.0 zigpy==0.49.1
# homeassistant.components.zwave_js # homeassistant.components.zwave_js
zwave-js-server-python==0.39.0 zwave-js-server-python==0.39.0

View File

@ -78,6 +78,36 @@ async def test_async_step_user_with_found_devices(hass):
assert result2["result"].unique_id == "4125DDBA-2774-4851-9889-6AADDD4CAC3D" assert result2["result"].unique_id == "4125DDBA-2774-4851-9889-6AADDD4CAC3D"
async def test_async_step_user_device_added_between_steps(hass):
"""Test the device gets added via another flow between steps."""
with patch(
"homeassistant.components.govee_ble.config_flow.async_discovered_service_info",
return_value=[GVH5177_SERVICE_INFO],
):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_USER},
)
assert result["type"] == FlowResultType.FORM
assert result["step_id"] == "user"
entry = MockConfigEntry(
domain=DOMAIN,
unique_id="4125DDBA-2774-4851-9889-6AADDD4CAC3D",
)
entry.add_to_hass(hass)
with patch(
"homeassistant.components.govee_ble.async_setup_entry", return_value=True
):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={"address": "4125DDBA-2774-4851-9889-6AADDD4CAC3D"},
)
assert result2["type"] == FlowResultType.ABORT
assert result2["reason"] == "already_configured"
async def test_async_step_user_with_found_devices_already_setup(hass): async def test_async_step_user_with_found_devices_already_setup(hass):
"""Test setup from service info cache with devices found.""" """Test setup from service info cache with devices found."""
entry = MockConfigEntry( entry = MockConfigEntry(

View File

@ -2,7 +2,6 @@
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
from huawei_lte_api.enums.cradle import ConnectionStatusEnum from huawei_lte_api.enums.cradle import ConnectionStatusEnum
from pytest import fixture
from homeassistant.components.huawei_lte.const import DOMAIN from homeassistant.components.huawei_lte.const import DOMAIN
from homeassistant.components.switch import ( from homeassistant.components.switch import (
@ -20,94 +19,70 @@ from tests.common import MockConfigEntry
SWITCH_WIFI_GUEST_NETWORK = "switch.lte_wifi_guest_network" SWITCH_WIFI_GUEST_NETWORK = "switch.lte_wifi_guest_network"
@fixture def magic_client(multi_basic_settings_value: dict) -> MagicMock:
"""Mock huawei_lte.Client."""
information = MagicMock(return_value={"SerialNumber": "test-serial-number"})
check_notifications = MagicMock(return_value={"SmsStorageFull": 0})
status = MagicMock(
return_value={"ConnectionStatus": ConnectionStatusEnum.CONNECTED.value}
)
multi_basic_settings = MagicMock(return_value=multi_basic_settings_value)
wifi_feature_switch = MagicMock(return_value={"wifi24g_switch_enable": 1})
device = MagicMock(information=information)
monitoring = MagicMock(check_notifications=check_notifications, status=status)
wlan = MagicMock(
multi_basic_settings=multi_basic_settings,
wifi_feature_switch=wifi_feature_switch,
)
return MagicMock(device=device, monitoring=monitoring, wlan=wlan)
@patch("homeassistant.components.huawei_lte.Connection", MagicMock()) @patch("homeassistant.components.huawei_lte.Connection", MagicMock())
@patch( @patch("homeassistant.components.huawei_lte.Client", return_value=magic_client({}))
"homeassistant.components.huawei_lte.Client", async def test_huawei_lte_wifi_guest_network_config_entry_when_network_is_not_present(
return_value=MagicMock( client,
device=MagicMock(
information=MagicMock(return_value={"SerialNumber": "test-serial-number"})
),
monitoring=MagicMock(
check_notifications=MagicMock(return_value={"SmsStorageFull": 0}),
status=MagicMock(
return_value={"ConnectionStatus": ConnectionStatusEnum.CONNECTED.value}
),
),
wlan=MagicMock(
multi_basic_settings=MagicMock(
return_value={
"Ssids": {"Ssid": [{"wifiisguestnetwork": "1", "WifiEnable": "0"}]}
}
),
wifi_feature_switch=MagicMock(return_value={"wifi24g_switch_enable": 1}),
),
),
)
async def setup_component_with_wifi_guest_network(
client: MagicMock, hass: HomeAssistant
) -> None:
"""Initialize huawei_lte components."""
assert client
huawei_lte = MockConfigEntry(domain=DOMAIN, data={CONF_URL: "http://huawei-lte"})
huawei_lte.add_to_hass(hass)
assert await hass.config_entries.async_setup(huawei_lte.entry_id)
await hass.async_block_till_done()
@fixture
@patch("homeassistant.components.huawei_lte.Connection", MagicMock())
@patch(
"homeassistant.components.huawei_lte.Client",
return_value=MagicMock(
device=MagicMock(
information=MagicMock(return_value={"SerialNumber": "test-serial-number"})
),
monitoring=MagicMock(
check_notifications=MagicMock(return_value={"SmsStorageFull": 0}),
status=MagicMock(
return_value={"ConnectionStatus": ConnectionStatusEnum.CONNECTED.value}
),
),
wlan=MagicMock(
multi_basic_settings=MagicMock(return_value={}),
wifi_feature_switch=MagicMock(return_value={"wifi24g_switch_enable": 1}),
),
),
)
async def setup_component_without_wifi_guest_network(
client: MagicMock, hass: HomeAssistant
) -> None:
"""Initialize huawei_lte components."""
assert client
huawei_lte = MockConfigEntry(domain=DOMAIN, data={CONF_URL: "http://huawei-lte"})
huawei_lte.add_to_hass(hass)
assert await hass.config_entries.async_setup(huawei_lte.entry_id)
await hass.async_block_till_done()
def test_huawei_lte_wifi_guest_network_config_entry_when_network_is_not_present(
hass: HomeAssistant, hass: HomeAssistant,
setup_component_without_wifi_guest_network,
) -> None: ) -> None:
"""Test switch wifi guest network config entry when network is not present.""" """Test switch wifi guest network config entry when network is not present."""
huawei_lte = MockConfigEntry(domain=DOMAIN, data={CONF_URL: "http://huawei-lte"})
huawei_lte.add_to_hass(hass)
await hass.config_entries.async_setup(huawei_lte.entry_id)
await hass.async_block_till_done()
entity_registry: EntityRegistry = er.async_get(hass) entity_registry: EntityRegistry = er.async_get(hass)
assert not entity_registry.async_is_registered(SWITCH_WIFI_GUEST_NETWORK) assert not entity_registry.async_is_registered(SWITCH_WIFI_GUEST_NETWORK)
def test_huawei_lte_wifi_guest_network_config_entry_when_network_is_present( @patch("homeassistant.components.huawei_lte.Connection", MagicMock())
@patch(
"homeassistant.components.huawei_lte.Client",
return_value=magic_client(
{"Ssids": {"Ssid": [{"wifiisguestnetwork": "1", "WifiEnable": "0"}]}}
),
)
async def test_huawei_lte_wifi_guest_network_config_entry_when_network_is_present(
client,
hass: HomeAssistant, hass: HomeAssistant,
setup_component_with_wifi_guest_network,
) -> None: ) -> None:
"""Test switch wifi guest network config entry when network is present.""" """Test switch wifi guest network config entry when network is present."""
huawei_lte = MockConfigEntry(domain=DOMAIN, data={CONF_URL: "http://huawei-lte"})
huawei_lte.add_to_hass(hass)
await hass.config_entries.async_setup(huawei_lte.entry_id)
await hass.async_block_till_done()
entity_registry: EntityRegistry = er.async_get(hass) entity_registry: EntityRegistry = er.async_get(hass)
assert entity_registry.async_is_registered(SWITCH_WIFI_GUEST_NETWORK) assert entity_registry.async_is_registered(SWITCH_WIFI_GUEST_NETWORK)
async def test_turn_on_switch_wifi_guest_network( @patch("homeassistant.components.huawei_lte.Connection", MagicMock())
hass: HomeAssistant, setup_component_with_wifi_guest_network @patch("homeassistant.components.huawei_lte.Client")
) -> None: async def test_turn_on_switch_wifi_guest_network(client, hass: HomeAssistant) -> None:
"""Test switch wifi guest network turn on method.""" """Test switch wifi guest network turn on method."""
client.return_value = magic_client(
{"Ssids": {"Ssid": [{"wifiisguestnetwork": "1", "WifiEnable": "0"}]}}
)
huawei_lte = MockConfigEntry(domain=DOMAIN, data={CONF_URL: "http://huawei-lte"})
huawei_lte.add_to_hass(hass)
await hass.config_entries.async_setup(huawei_lte.entry_id)
await hass.async_block_till_done()
await hass.services.async_call( await hass.services.async_call(
SWITCH_DOMAIN, SWITCH_DOMAIN,
SERVICE_TURN_ON, SERVICE_TURN_ON,
@ -116,15 +91,20 @@ async def test_turn_on_switch_wifi_guest_network(
) )
await hass.async_block_till_done() await hass.async_block_till_done()
assert hass.states.is_state(SWITCH_WIFI_GUEST_NETWORK, STATE_ON) assert hass.states.is_state(SWITCH_WIFI_GUEST_NETWORK, STATE_ON)
hass.data[DOMAIN].routers[ client.return_value.wlan.wifi_guest_network_switch.assert_called_once_with(True)
"test-serial-number"
].client.wlan.wifi_guest_network_switch.assert_called_once_with(True)
async def test_turn_off_switch_wifi_guest_network( @patch("homeassistant.components.huawei_lte.Connection", MagicMock())
hass: HomeAssistant, setup_component_with_wifi_guest_network @patch("homeassistant.components.huawei_lte.Client")
) -> None: async def test_turn_off_switch_wifi_guest_network(client, hass: HomeAssistant) -> None:
"""Test switch wifi guest network turn off method.""" """Test switch wifi guest network turn off method."""
client.return_value = magic_client(
{"Ssids": {"Ssid": [{"wifiisguestnetwork": "1", "WifiEnable": "1"}]}}
)
huawei_lte = MockConfigEntry(domain=DOMAIN, data={CONF_URL: "http://huawei-lte"})
huawei_lte.add_to_hass(hass)
await hass.config_entries.async_setup(huawei_lte.entry_id)
await hass.async_block_till_done()
await hass.services.async_call( await hass.services.async_call(
SWITCH_DOMAIN, SWITCH_DOMAIN,
SERVICE_TURN_OFF, SERVICE_TURN_OFF,
@ -133,6 +113,44 @@ async def test_turn_off_switch_wifi_guest_network(
) )
await hass.async_block_till_done() await hass.async_block_till_done()
assert hass.states.is_state(SWITCH_WIFI_GUEST_NETWORK, STATE_OFF) assert hass.states.is_state(SWITCH_WIFI_GUEST_NETWORK, STATE_OFF)
hass.data[DOMAIN].routers[ client.return_value.wlan.wifi_guest_network_switch.assert_called_with(False)
"test-serial-number"
].client.wlan.wifi_guest_network_switch.assert_called_with(False)
@patch("homeassistant.components.huawei_lte.Connection", MagicMock())
@patch(
"homeassistant.components.huawei_lte.Client",
return_value=magic_client({"Ssids": {"Ssid": "str"}}),
)
async def test_huawei_lte_wifi_guest_network_config_entry_when_ssid_is_str(
client, hass: HomeAssistant
):
"""Test switch wifi guest network config entry when ssid is a str.
Issue #76244. Huawai models: H312-371, E5372 and E8372.
"""
huawei_lte = MockConfigEntry(domain=DOMAIN, data={CONF_URL: "http://huawei-lte"})
huawei_lte.add_to_hass(hass)
await hass.config_entries.async_setup(huawei_lte.entry_id)
await hass.async_block_till_done()
entity_registry: EntityRegistry = er.async_get(hass)
assert not entity_registry.async_is_registered(SWITCH_WIFI_GUEST_NETWORK)
@patch("homeassistant.components.huawei_lte.Connection", MagicMock())
@patch(
"homeassistant.components.huawei_lte.Client",
return_value=magic_client({"Ssids": {"Ssid": None}}),
)
async def test_huawei_lte_wifi_guest_network_config_entry_when_ssid_is_none(
client, hass: HomeAssistant
):
"""Test switch wifi guest network config entry when ssid is a None.
Issue #76244.
"""
huawei_lte = MockConfigEntry(domain=DOMAIN, data={CONF_URL: "http://huawei-lte"})
huawei_lte.add_to_hass(hass)
await hass.config_entries.async_setup(huawei_lte.entry_id)
await hass.async_block_till_done()
entity_registry: EntityRegistry = er.async_get(hass)
assert not entity_registry.async_is_registered(SWITCH_WIFI_GUEST_NETWORK)

View File

@ -74,6 +74,34 @@ async def test_async_step_user_with_found_devices(hass):
assert result2["result"].unique_id == "61DE521B-F0BF-9F44-64D4-75BBE1738105" assert result2["result"].unique_id == "61DE521B-F0BF-9F44-64D4-75BBE1738105"
async def test_async_step_user_device_added_between_steps(hass):
"""Test the device gets added via another flow between steps."""
with patch(
"homeassistant.components.inkbird.config_flow.async_discovered_service_info",
return_value=[SPS_SERVICE_INFO],
):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_USER},
)
assert result["type"] == FlowResultType.FORM
assert result["step_id"] == "user"
entry = MockConfigEntry(
domain=DOMAIN,
unique_id="61DE521B-F0BF-9F44-64D4-75BBE1738105",
)
entry.add_to_hass(hass)
with patch("homeassistant.components.inkbird.async_setup_entry", return_value=True):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={"address": "61DE521B-F0BF-9F44-64D4-75BBE1738105"},
)
assert result2["type"] == FlowResultType.ABORT
assert result2["reason"] == "already_configured"
async def test_async_step_user_with_found_devices_already_setup(hass): async def test_async_step_user_with_found_devices_already_setup(hass):
"""Test setup from service info cache with devices found.""" """Test setup from service info cache with devices found."""
entry = MockConfigEntry( entry = MockConfigEntry(

View File

@ -74,6 +74,34 @@ async def test_async_step_user_with_found_devices(hass):
assert result2["result"].unique_id == "aa:bb:cc:dd:ee:ff" assert result2["result"].unique_id == "aa:bb:cc:dd:ee:ff"
async def test_async_step_user_device_added_between_steps(hass):
"""Test the device gets added via another flow between steps."""
with patch(
"homeassistant.components.moat.config_flow.async_discovered_service_info",
return_value=[MOAT_S2_SERVICE_INFO],
):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_USER},
)
assert result["type"] == FlowResultType.FORM
assert result["step_id"] == "user"
entry = MockConfigEntry(
domain=DOMAIN,
unique_id="aa:bb:cc:dd:ee:ff",
)
entry.add_to_hass(hass)
with patch("homeassistant.components.moat.async_setup_entry", return_value=True):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={"address": "aa:bb:cc:dd:ee:ff"},
)
assert result2["type"] == FlowResultType.ABORT
assert result2["reason"] == "already_configured"
async def test_async_step_user_with_found_devices_already_setup(hass): async def test_async_step_user_with_found_devices_already_setup(hass):
"""Test setup from service info cache with devices found.""" """Test setup from service info cache with devices found."""
entry = MockConfigEntry( entry = MockConfigEntry(

View File

@ -78,6 +78,36 @@ async def test_async_step_user_with_found_devices(hass):
assert result2["result"].unique_id == "61DE521B-F0BF-9F44-64D4-75BBE1738105" assert result2["result"].unique_id == "61DE521B-F0BF-9F44-64D4-75BBE1738105"
async def test_async_step_user_device_added_between_steps(hass):
"""Test the device gets added via another flow between steps."""
with patch(
"homeassistant.components.sensorpush.config_flow.async_discovered_service_info",
return_value=[HTW_SERVICE_INFO],
):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_USER},
)
assert result["type"] == FlowResultType.FORM
assert result["step_id"] == "user"
entry = MockConfigEntry(
domain=DOMAIN,
unique_id="61DE521B-F0BF-9F44-64D4-75BBE1738105",
)
entry.add_to_hass(hass)
with patch(
"homeassistant.components.sensorpush.async_setup_entry", return_value=True
):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={"address": "61DE521B-F0BF-9F44-64D4-75BBE1738105"},
)
assert result2["type"] == FlowResultType.ABORT
assert result2["reason"] == "already_configured"
async def test_async_step_user_with_found_devices_already_setup(hass): async def test_async_step_user_with_found_devices_already_setup(hass):
"""Test setup from service info cache with devices found.""" """Test setup from service info cache with devices found."""
entry = MockConfigEntry( entry = MockConfigEntry(

View File

@ -708,6 +708,36 @@ async def test_async_step_user_with_found_devices_legacy_encryption_wrong_key_le
assert result2["result"].unique_id == "F8:24:41:C5:98:8B" assert result2["result"].unique_id == "F8:24:41:C5:98:8B"
async def test_async_step_user_device_added_between_steps(hass):
"""Test the device gets added via another flow between steps."""
with patch(
"homeassistant.components.xiaomi_ble.config_flow.async_discovered_service_info",
return_value=[LYWSDCGQ_SERVICE_INFO],
):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_USER},
)
assert result["type"] == FlowResultType.FORM
assert result["step_id"] == "user"
entry = MockConfigEntry(
domain=DOMAIN,
unique_id="58:2D:34:35:93:21",
)
entry.add_to_hass(hass)
with patch(
"homeassistant.components.xiaomi_ble.async_setup_entry", return_value=True
):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={"address": "58:2D:34:35:93:21"},
)
assert result2["type"] == FlowResultType.ABORT
assert result2["reason"] == "already_configured"
async def test_async_step_user_with_found_devices_already_setup(hass): async def test_async_step_user_with_found_devices_already_setup(hass):
"""Test setup from service info cache with devices found.""" """Test setup from service info cache with devices found."""
entry = MockConfigEntry( entry = MockConfigEntry(