diff --git a/homeassistant/components/environment_canada/config_flow.py b/homeassistant/components/environment_canada/config_flow.py index e1eda36c345..683f312d9d5 100644 --- a/homeassistant/components/environment_canada/config_flow.py +++ b/homeassistant/components/environment_canada/config_flow.py @@ -20,13 +20,12 @@ async def validate_input(data): lat = data.get(CONF_LATITUDE) lon = data.get(CONF_LONGITUDE) station = data.get(CONF_STATION) - lang = data.get(CONF_LANGUAGE) + lang = data.get(CONF_LANGUAGE).lower() - weather_data = ECWeather( - station_id=station, - coordinates=(lat, lon), - language=lang.lower(), - ) + if station: + weather_data = ECWeather(station_id=station, language=lang) + else: + weather_data = ECWeather(coordinates=(lat, lon), language=lang) await weather_data.update() if lat is None or lon is None: diff --git a/homeassistant/components/flux_led/__init__.py b/homeassistant/components/flux_led/__init__.py index 248ce7261e9..717a3c9e2b0 100644 --- a/homeassistant/components/flux_led/__init__.py +++ b/homeassistant/components/flux_led/__init__.py @@ -182,7 +182,7 @@ class FluxLedUpdateCoordinator(DataUpdateCoordinator): hass, _LOGGER, name=self.device.ipaddr, - update_interval=timedelta(seconds=5), + update_interval=timedelta(seconds=10), # We don't want an immediate refresh since the device # takes a moment to reflect the state change request_refresh_debouncer=Debouncer( diff --git a/homeassistant/components/flux_led/manifest.json b/homeassistant/components/flux_led/manifest.json index 4b5a63542c9..d0134d07f79 100644 --- a/homeassistant/components/flux_led/manifest.json +++ b/homeassistant/components/flux_led/manifest.json @@ -3,7 +3,7 @@ "name": "Flux LED/MagicHome", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/flux_led", - "requirements": ["flux_led==0.24.13"], + "requirements": ["flux_led==0.24.14"], "quality_scale": "platinum", "codeowners": ["@icemanch"], "iot_class": "local_push", diff --git a/homeassistant/components/nut/__init__.py b/homeassistant/components/nut/__init__.py index 81dd5f91f59..f0f2777373a 100644 --- a/homeassistant/components/nut/__init__.py +++ b/homeassistant/components/nut/__init__.py @@ -39,8 +39,11 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: # strip out the stale options CONF_RESOURCES if CONF_RESOURCES in entry.options: + new_data = {**entry.data, CONF_RESOURCES: entry.options[CONF_RESOURCES]} new_options = {k: v for k, v in entry.options.items() if k != CONF_RESOURCES} - hass.config_entries.async_update_entry(entry, options=new_options) + hass.config_entries.async_update_entry( + entry, data=new_data, options=new_options + ) config = entry.data host = config[CONF_HOST] diff --git a/homeassistant/components/octoprint/config_flow.py b/homeassistant/components/octoprint/config_flow.py index acc1449bd96..04efde16952 100644 --- a/homeassistant/components/octoprint/config_flow.py +++ b/homeassistant/components/octoprint/config_flow.py @@ -189,7 +189,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): try: user_input[CONF_API_KEY] = await octoprint.request_app_key( - "Home Assistant", user_input[CONF_USERNAME], 30 + "Home Assistant", user_input[CONF_USERNAME], 300 ) finally: # Continue the flow after show progress when the task is done. diff --git a/homeassistant/components/pvpc_hourly_pricing/manifest.json b/homeassistant/components/pvpc_hourly_pricing/manifest.json index 612376a7931..a30ae1e2732 100644 --- a/homeassistant/components/pvpc_hourly_pricing/manifest.json +++ b/homeassistant/components/pvpc_hourly_pricing/manifest.json @@ -3,7 +3,7 @@ "name": "Spain electricity hourly pricing (PVPC)", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/pvpc_hourly_pricing", - "requirements": ["aiopvpc==2.2.0"], + "requirements": ["aiopvpc==2.2.1"], "codeowners": ["@azogue"], "quality_scale": "platinum", "iot_class": "cloud_polling" diff --git a/homeassistant/components/recorder/__init__.py b/homeassistant/components/recorder/__init__.py index 465209c7ed7..9d19e0d876e 100644 --- a/homeassistant/components/recorder/__init__.py +++ b/homeassistant/components/recorder/__init__.py @@ -793,7 +793,7 @@ class Recorder(threading.Thread): if statistics.add_external_statistics(self, metadata, stats): return # Schedule a new statistics task if this one didn't finish - self.queue.put(StatisticsTask(metadata, stats)) + self.queue.put(ExternalStatisticsTask(metadata, stats)) def _process_one_event(self, event): """Process one event.""" diff --git a/homeassistant/components/recorder/migration.py b/homeassistant/components/recorder/migration.py index 508476e0c2b..fe3e1aeb84d 100644 --- a/homeassistant/components/recorder/migration.py +++ b/homeassistant/components/recorder/migration.py @@ -12,6 +12,7 @@ from sqlalchemy.exc import ( SQLAlchemyError, ) from sqlalchemy.schema import AddConstraint, DropConstraint +from sqlalchemy.sql.expression import true from .models import ( SCHEMA_VERSION, @@ -24,7 +25,7 @@ from .models import ( StatisticsShortTerm, process_timestamp, ) -from .statistics import get_metadata_with_session, get_start_time +from .statistics import get_start_time from .util import session_scope _LOGGER = logging.getLogger(__name__) @@ -558,21 +559,25 @@ def _apply_update(instance, session, new_version, old_version): # noqa: C901 session.add(StatisticsRuns(start=fake_start_time)) fake_start_time += timedelta(minutes=5) - # Copy last hourly statistic to the newly created 5-minute statistics table - sum_statistics = get_metadata_with_session( - instance.hass, session, statistic_type="sum" - ) - for metadata_id, _ in sum_statistics.values(): + # When querying the database, be careful to only explicitly query for columns + # which were present in schema version 21. If querying the table, SQLAlchemy + # will refer to future columns. + for sum_statistic in session.query(StatisticsMeta.id).filter_by(has_sum=true()): last_statistic = ( - session.query(Statistics) - .filter_by(metadata_id=metadata_id) + session.query( + Statistics.start, + Statistics.last_reset, + Statistics.state, + Statistics.sum, + ) + .filter_by(metadata_id=sum_statistic.id) .order_by(Statistics.start.desc()) .first() ) if last_statistic: session.add( StatisticsShortTerm( - metadata_id=last_statistic.metadata_id, + metadata_id=sum_statistic.id, start=last_statistic.start, last_reset=last_statistic.last_reset, state=last_statistic.state, diff --git a/homeassistant/components/recorder/util.py b/homeassistant/components/recorder/util.py index b4bbce27130..6c53347a536 100644 --- a/homeassistant/components/recorder/util.py +++ b/homeassistant/components/recorder/util.py @@ -49,7 +49,7 @@ MIN_VERSION_MARIA_DB_ROWNUM = AwesomeVersion("10.2.0", AwesomeVersionStrategy.SI MIN_VERSION_MYSQL = AwesomeVersion("8.0.0", AwesomeVersionStrategy.SIMPLEVER) MIN_VERSION_MYSQL_ROWNUM = AwesomeVersion("5.8.0", AwesomeVersionStrategy.SIMPLEVER) MIN_VERSION_PGSQL = AwesomeVersion("12.0", AwesomeVersionStrategy.SIMPLEVER) -MIN_VERSION_SQLITE = AwesomeVersion("3.32.1", AwesomeVersionStrategy.SIMPLEVER) +MIN_VERSION_SQLITE = AwesomeVersion("3.31.0", AwesomeVersionStrategy.SIMPLEVER) MIN_VERSION_SQLITE_ROWNUM = AwesomeVersion("3.25.0", AwesomeVersionStrategy.SIMPLEVER) # This is the maximum time after the recorder ends the session @@ -295,7 +295,7 @@ def _warn_unsupported_dialect(dialect): "Starting with Home Assistant 2022.2 this will prevent the recorder from " "starting. Please migrate your database to a supported software before then", dialect, - "MariaDB ≥ 10.3, MySQL ≥ 8.0, PostgreSQL ≥ 12, SQLite ≥ 3.32.1", + "MariaDB ≥ 10.3, MySQL ≥ 8.0, PostgreSQL ≥ 12, SQLite ≥ 3.31.0", ) diff --git a/homeassistant/components/sharkiq/vacuum.py b/homeassistant/components/sharkiq/vacuum.py index 3851dab7303..33412963cda 100644 --- a/homeassistant/components/sharkiq/vacuum.py +++ b/homeassistant/components/sharkiq/vacuum.py @@ -138,11 +138,6 @@ class SharkVacuumEntity(CoordinatorEntity, StateVacuumEntity): """Flag vacuum cleaner robot features that are supported.""" return SUPPORT_SHARKIQ - @property - def is_docked(self) -> bool | None: - """Is vacuum docked.""" - return self.sharkiq.get_property_value(Properties.DOCKED_STATUS) - @property def error_code(self) -> int | None: """Return the last observed error code (or None).""" @@ -175,7 +170,7 @@ class SharkVacuumEntity(CoordinatorEntity, StateVacuumEntity): In the app, these are (usually) handled by showing the robot as stopped and sending the user a notification. """ - if self.is_docked: + if self.sharkiq.get_property_value(Properties.CHARGING_STATUS): return STATE_DOCKED return self.operating_mode diff --git a/homeassistant/components/velbus/manifest.json b/homeassistant/components/velbus/manifest.json index 4541b428a4a..454b9d24d07 100644 --- a/homeassistant/components/velbus/manifest.json +++ b/homeassistant/components/velbus/manifest.json @@ -2,7 +2,7 @@ "domain": "velbus", "name": "Velbus", "documentation": "https://www.home-assistant.io/integrations/velbus", - "requirements": ["velbus-aio==2021.10.7"], + "requirements": ["velbus-aio==2021.11.0"], "config_flow": true, "codeowners": ["@Cereal2nd", "@brefra"], "iot_class": "local_push" diff --git a/homeassistant/components/xiaomi_miio/binary_sensor.py b/homeassistant/components/xiaomi_miio/binary_sensor.py index 1bdd647da79..ef172bbbbc5 100644 --- a/homeassistant/components/xiaomi_miio/binary_sensor.py +++ b/homeassistant/components/xiaomi_miio/binary_sensor.py @@ -29,6 +29,7 @@ from .const import ( MODELS_HUMIDIFIER_MJJSQ, MODELS_VACUUM, MODELS_VACUUM_WITH_MOP, + MODELS_VACUUM_WITH_SEPARATE_MOP, ) from .device import XiaomiCoordinatedMiioEntity @@ -77,7 +78,7 @@ FAN_ZA5_BINARY_SENSORS = (ATTR_POWERSUPPLY_ATTACHED,) VACUUM_SENSORS = { ATTR_MOP_ATTACHED: XiaomiMiioBinarySensorDescription( - key=ATTR_MOP_ATTACHED, + key=ATTR_WATER_BOX_ATTACHED, name="Mop Attached", icon="mdi:square-rounded", parent_key=VacuumCoordinatorDataAttributes.status, @@ -105,6 +106,19 @@ VACUUM_SENSORS = { ), } +VACUUM_SENSORS_SEPARATE_MOP = { + **VACUUM_SENSORS, + ATTR_MOP_ATTACHED: XiaomiMiioBinarySensorDescription( + key=ATTR_MOP_ATTACHED, + name="Mop Attached", + icon="mdi:square-rounded", + parent_key=VacuumCoordinatorDataAttributes.status, + entity_registry_enabled_default=True, + device_class=DEVICE_CLASS_CONNECTIVITY, + entity_category=ENTITY_CATEGORY_DIAGNOSTIC, + ), +} + HUMIDIFIER_MIIO_BINARY_SENSORS = (ATTR_WATER_TANK_DETACHED,) HUMIDIFIER_MIOT_BINARY_SENSORS = (ATTR_WATER_TANK_DETACHED,) HUMIDIFIER_MJJSQ_BINARY_SENSORS = (ATTR_NO_WATER, ATTR_WATER_TANK_DETACHED) @@ -118,8 +132,12 @@ def _setup_vacuum_sensors(hass, config_entry, async_add_entities): device = hass.data[DOMAIN][config_entry.entry_id].get(KEY_DEVICE) coordinator = hass.data[DOMAIN][config_entry.entry_id][KEY_COORDINATOR] entities = [] + sensors = VACUUM_SENSORS - for sensor, description in VACUUM_SENSORS.items(): + if config_entry.data[CONF_MODEL] in MODELS_VACUUM_WITH_SEPARATE_MOP: + sensors = VACUUM_SENSORS_SEPARATE_MOP + + for sensor, description in sensors.items(): parent_key_data = getattr(coordinator.data, description.parent_key) if getattr(parent_key_data, description.key, None) is None: _LOGGER.debug( diff --git a/homeassistant/components/xiaomi_miio/const.py b/homeassistant/components/xiaomi_miio/const.py index c140ad526e2..60c16a0717a 100644 --- a/homeassistant/components/xiaomi_miio/const.py +++ b/homeassistant/components/xiaomi_miio/const.py @@ -202,6 +202,7 @@ ROCKROBO_S4_MAX = "roborock.vacuum.a19" ROCKROBO_S5_MAX = "roborock.vacuum.s5e" ROCKROBO_S6_PURE = "roborock.vacuum.a08" ROCKROBO_E2 = "roborock.vacuum.e2" +ROCKROBO_GENERIC = "roborock.vacuum" MODELS_VACUUM = [ ROCKROBO_V1, ROCKROBO_E2, @@ -213,6 +214,7 @@ MODELS_VACUUM = [ ROCKROBO_S6_MAXV, ROCKROBO_S6_PURE, ROCKROBO_S7, + ROCKROBO_GENERIC, ] MODELS_VACUUM_WITH_MOP = [ ROCKROBO_E2, @@ -223,6 +225,9 @@ MODELS_VACUUM_WITH_MOP = [ ROCKROBO_S6_PURE, ROCKROBO_S7, ] +MODELS_VACUUM_WITH_SEPARATE_MOP = [ + ROCKROBO_S7, +] MODELS_AIR_MONITOR = [ MODEL_AIRQUALITYMONITOR_V1, diff --git a/homeassistant/components/xiaomi_miio/device.py b/homeassistant/components/xiaomi_miio/device.py index 6d56c7c44bd..cb708fd4379 100644 --- a/homeassistant/components/xiaomi_miio/device.py +++ b/homeassistant/components/xiaomi_miio/device.py @@ -166,8 +166,7 @@ class XiaomiCoordinatedMiioEntity(CoordinatorEntity): return cls._parse_datetime_time(value) if isinstance(value, datetime.datetime): return cls._parse_datetime_datetime(value) - if isinstance(value, datetime.timedelta): - return cls._parse_time_delta(value) + if value is None: _LOGGER.debug("Attribute %s is None, this is unexpected", attribute) @@ -175,7 +174,7 @@ class XiaomiCoordinatedMiioEntity(CoordinatorEntity): @staticmethod def _parse_time_delta(timedelta: datetime.timedelta) -> int: - return timedelta.seconds + return int(timedelta.total_seconds()) @staticmethod def _parse_datetime_time(time: datetime.time) -> str: @@ -191,7 +190,3 @@ class XiaomiCoordinatedMiioEntity(CoordinatorEntity): @staticmethod def _parse_datetime_datetime(time: datetime.datetime) -> str: return time.isoformat() - - @staticmethod - def _parse_datetime_timedelta(time: datetime.timedelta) -> int: - return time.seconds diff --git a/homeassistant/components/xiaomi_miio/sensor.py b/homeassistant/components/xiaomi_miio/sensor.py index f818a809a5c..aefeea7c20a 100644 --- a/homeassistant/components/xiaomi_miio/sensor.py +++ b/homeassistant/components/xiaomi_miio/sensor.py @@ -299,7 +299,7 @@ HUMIDIFIER_MIOT_SENSORS = ( ATTR_USE_TIME, ATTR_WATER_LEVEL, ) -HUMIDIFIER_MJJSQ_SENSORS = (ATTR_HUMIDITY, ATTR_TEMPERATURE, ATTR_USE_TIME) +HUMIDIFIER_MJJSQ_SENSORS = (ATTR_HUMIDITY, ATTR_TEMPERATURE) PURIFIER_MIIO_SENSORS = ( ATTR_FILTER_LIFE_REMAINING, diff --git a/homeassistant/const.py b/homeassistant/const.py index 9eade8bd476..36b43ee25f1 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -5,7 +5,7 @@ from typing import Final MAJOR_VERSION: Final = 2021 MINOR_VERSION: Final = 11 -PATCH_VERSION: Final = "0" +PATCH_VERSION: Final = "1" __short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__: Final = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 8, 0) diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index 7d670da646c..2dd084fc5fc 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -36,8 +36,8 @@ zeroconf==0.36.11 pycryptodome>=3.6.6 -# Constrain urllib3 to ensure we deal with CVE-2019-11236 & CVE-2019-11324 -urllib3>=1.24.3 +# Constrain urllib3 to ensure we deal with CVE-2020-26137 and CVE-2021-33503 +urllib3>=1.26.5 # Constrain H11 to ensure we get a new enough version to support non-rfc line endings h11>=0.12.0 diff --git a/requirements_all.txt b/requirements_all.txt index fdf88bf284b..c5f93ad7251 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -234,7 +234,7 @@ aiopulse==0.4.2 aiopvapi==1.6.14 # homeassistant.components.pvpc_hourly_pricing -aiopvpc==2.2.0 +aiopvpc==2.2.1 # homeassistant.components.webostv aiopylgtv==0.4.0 @@ -652,7 +652,7 @@ fjaraskupan==1.0.2 flipr-api==1.4.1 # homeassistant.components.flux_led -flux_led==0.24.13 +flux_led==0.24.14 # homeassistant.components.homekit fnvhash==0.1.0 @@ -2360,7 +2360,7 @@ uvcclient==0.11.0 vallox-websocket-api==2.8.1 # homeassistant.components.velbus -velbus-aio==2021.10.7 +velbus-aio==2021.11.0 # homeassistant.components.venstar venstarcolortouch==0.14 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 148bd558d7e..fdacbc25dd2 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -161,7 +161,7 @@ aiopulse==0.4.2 aiopvapi==1.6.14 # homeassistant.components.pvpc_hourly_pricing -aiopvpc==2.2.0 +aiopvpc==2.2.1 # homeassistant.components.webostv aiopylgtv==0.4.0 @@ -387,7 +387,7 @@ fjaraskupan==1.0.2 flipr-api==1.4.1 # homeassistant.components.flux_led -flux_led==0.24.13 +flux_led==0.24.14 # homeassistant.components.homekit fnvhash==0.1.0 @@ -1364,7 +1364,7 @@ url-normalize==1.4.1 uvcclient==0.11.0 # homeassistant.components.velbus -velbus-aio==2021.10.7 +velbus-aio==2021.11.0 # homeassistant.components.venstar venstarcolortouch==0.14 diff --git a/script/gen_requirements_all.py b/script/gen_requirements_all.py index 3d2ace4c240..3deec512b4f 100755 --- a/script/gen_requirements_all.py +++ b/script/gen_requirements_all.py @@ -63,8 +63,8 @@ CONSTRAINT_PATH = os.path.join( CONSTRAINT_BASE = """ pycryptodome>=3.6.6 -# Constrain urllib3 to ensure we deal with CVE-2019-11236 & CVE-2019-11324 -urllib3>=1.24.3 +# Constrain urllib3 to ensure we deal with CVE-2020-26137 and CVE-2021-33503 +urllib3>=1.26.5 # Constrain H11 to ensure we get a new enough version to support non-rfc line endings h11>=0.12.0 diff --git a/tests/components/environment_canada/test_config_flow.py b/tests/components/environment_canada/test_config_flow.py index f2ebb48346c..2614778f9b4 100644 --- a/tests/components/environment_canada/test_config_flow.py +++ b/tests/components/environment_canada/test_config_flow.py @@ -123,7 +123,24 @@ async def test_exception_handling(hass, error): assert result["errors"] == {"base": base_error} -async def test_lat_or_lon_not_specified(hass): +async def test_import_station_not_specified(hass): + """Test that the import step works.""" + with mocked_ec(), patch( + "homeassistant.components.environment_canada.async_setup_entry", + return_value=True, + ): + fake_config = dict(FAKE_CONFIG) + del fake_config[CONF_STATION] + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": SOURCE_IMPORT}, data=fake_config + ) + await hass.async_block_till_done() + assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY + assert result["data"] == FAKE_CONFIG + assert result["title"] == FAKE_TITLE + + +async def test_import_lat_lon_not_specified(hass): """Test that the import step works.""" with mocked_ec(), patch( "homeassistant.components.environment_canada.async_setup_entry", @@ -131,6 +148,7 @@ async def test_lat_or_lon_not_specified(hass): ): fake_config = dict(FAKE_CONFIG) del fake_config[CONF_LATITUDE] + del fake_config[CONF_LONGITUDE] result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_IMPORT}, data=fake_config ) diff --git a/tests/components/recorder/test_util.py b/tests/components/recorder/test_util.py index da88d17f02a..940925c48ca 100644 --- a/tests/components/recorder/test_util.py +++ b/tests/components/recorder/test_util.py @@ -364,20 +364,16 @@ def test_supported_pgsql(caplog, pgsql_version): "sqlite_version,message", [ ( - "3.32.0", - "Version 3.32.0 of SQLite is not supported; minimum supported version is 3.32.1.", - ), - ( - "3.31.0", - "Version 3.31.0 of SQLite is not supported; minimum supported version is 3.32.1.", + "3.30.0", + "Version 3.30.0 of SQLite is not supported; minimum supported version is 3.31.0.", ), ( "2.0.0", - "Version 2.0.0 of SQLite is not supported; minimum supported version is 3.32.1.", + "Version 2.0.0 of SQLite is not supported; minimum supported version is 3.31.0.", ), ( "dogs", - "Version dogs of SQLite is not supported; minimum supported version is 3.32.1.", + "Version dogs of SQLite is not supported; minimum supported version is 3.31.0.", ), ], ) @@ -410,7 +406,7 @@ def test_warn_outdated_sqlite(caplog, sqlite_version, message): @pytest.mark.parametrize( "sqlite_version", [ - ("3.32.1"), + ("3.31.0"), ("3.33.0"), ], ) diff --git a/tests/components/xiaomi_miio/test_config_flow.py b/tests/components/xiaomi_miio/test_config_flow.py index 24aa5ac04e4..206da7ad4ae 100644 --- a/tests/components/xiaomi_miio/test_config_flow.py +++ b/tests/components/xiaomi_miio/test_config_flow.py @@ -695,6 +695,52 @@ async def config_flow_device_success(hass, model_to_test): } +async def config_flow_generic_roborock(hass): + """Test a successful config flow for a generic roborock vacuum.""" + DUMMY_MODEL = "roborock.vacuum.dummy" + + result = await hass.config_entries.flow.async_init( + const.DOMAIN, context={"source": config_entries.SOURCE_USER} + ) + + assert result["type"] == "form" + assert result["step_id"] == "cloud" + assert result["errors"] == {} + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + {const.CONF_MANUAL: True}, + ) + + assert result["type"] == "form" + assert result["step_id"] == "manual" + assert result["errors"] == {} + + mock_info = get_mock_info(model=DUMMY_MODEL) + + with patch( + "homeassistant.components.xiaomi_miio.device.Device.info", + return_value=mock_info, + ): + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + {CONF_HOST: TEST_HOST, CONF_TOKEN: TEST_TOKEN}, + ) + + assert result["type"] == "create_entry" + assert result["title"] == DUMMY_MODEL + assert result["data"] == { + const.CONF_FLOW_TYPE: const.CONF_DEVICE, + const.CONF_CLOUD_USERNAME: None, + const.CONF_CLOUD_PASSWORD: None, + const.CONF_CLOUD_COUNTRY: None, + CONF_HOST: TEST_HOST, + CONF_TOKEN: TEST_TOKEN, + const.CONF_MODEL: DUMMY_MODEL, + const.CONF_MAC: TEST_MAC, + } + + async def zeroconf_device_success(hass, zeroconf_name_to_test, model_to_test): """Test a successful zeroconf discovery of a device (base class).""" result = await hass.config_entries.flow.async_init(