diff --git a/homeassistant/components/august/manifest.json b/homeassistant/components/august/manifest.json index c688aa1a775..3aef3f5960d 100644 --- a/homeassistant/components/august/manifest.json +++ b/homeassistant/components/august/manifest.json @@ -2,7 +2,7 @@ "domain": "august", "name": "August", "documentation": "https://www.home-assistant.io/integrations/august", - "requirements": ["yalexs==1.2.1"], + "requirements": ["yalexs==1.2.2"], "codeowners": ["@bdraco"], "dhcp": [ { diff --git a/homeassistant/components/bosch_shc/manifest.json b/homeassistant/components/bosch_shc/manifest.json index a5927162e50..df902601e75 100644 --- a/homeassistant/components/bosch_shc/manifest.json +++ b/homeassistant/components/bosch_shc/manifest.json @@ -3,7 +3,7 @@ "name": "Bosch SHC", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/bosch_shc", - "requirements": ["boschshcpy==0.2.30"], + "requirements": ["boschshcpy==0.2.35"], "zeroconf": [{ "type": "_http._tcp.local.", "name": "bosch shc*" }], "iot_class": "local_push", "codeowners": ["@tschamm"], diff --git a/homeassistant/components/govee_ble/manifest.json b/homeassistant/components/govee_ble/manifest.json index 537ae9c7ed5..29af7502ded 100644 --- a/homeassistant/components/govee_ble/manifest.json +++ b/homeassistant/components/govee_ble/manifest.json @@ -12,6 +12,11 @@ "service_uuid": "00008451-0000-1000-8000-00805f9b34fb", "connectable": false }, + { + "manufacturer_id": 63391, + "service_uuid": "00008351-0000-1000-8000-00805f9b34fb", + "connectable": false + }, { "manufacturer_id": 26589, "service_uuid": "00008351-0000-1000-8000-00805f9b34fb", @@ -32,6 +37,11 @@ "service_uuid": "00008551-0000-1000-8000-00805f9b34fb", "connectable": false }, + { + "manufacturer_id": 43682, + "service_uuid": "00008151-0000-1000-8000-00805f9b34fb", + "connectable": false + }, { "manufacturer_id": 59970, "service_uuid": "00008151-0000-1000-8000-00805f9b34fb", @@ -58,7 +68,7 @@ "connectable": false } ], - "requirements": ["govee-ble==0.17.3"], + "requirements": ["govee-ble==0.19.0"], "dependencies": ["bluetooth"], "codeowners": ["@bdraco"], "iot_class": "local_push" diff --git a/homeassistant/components/ipma/__init__.py b/homeassistant/components/ipma/__init__.py index 315362247a2..eec16a0c811 100644 --- a/homeassistant/components/ipma/__init__.py +++ b/homeassistant/components/ipma/__init__.py @@ -1,4 +1,5 @@ """Component for the Portuguese weather service - IPMA.""" +import asyncio import logging import async_timeout @@ -22,36 +23,31 @@ PLATFORMS = [Platform.WEATHER] _LOGGER = logging.getLogger(__name__) -async def async_get_api(hass): - """Get the pyipma api object.""" - websession = async_get_clientsession(hass) - return IPMA_API(websession) - - async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool: """Set up IPMA station as config entry.""" latitude = config_entry.data[CONF_LATITUDE] longitude = config_entry.data[CONF_LONGITUDE] - api = await async_get_api(hass) + api = IPMA_API(async_get_clientsession(hass)) + try: async with async_timeout.timeout(30): location = await Location.get(api, float(latitude), float(longitude)) - - _LOGGER.debug( - "Initializing for coordinates %s, %s -> station %s (%d, %d)", - latitude, - longitude, - location.station, - location.id_station, - location.global_id_local, - ) - except IPMAException as err: + except (IPMAException, asyncio.TimeoutError) as err: raise ConfigEntryNotReady( f"Could not get location for ({latitude},{longitude})" ) from err + _LOGGER.debug( + "Initializing for coordinates %s, %s -> station %s (%d, %d)", + latitude, + longitude, + location.station, + location.id_station, + location.global_id_local, + ) + hass.data.setdefault(DOMAIN, {}) hass.data[DOMAIN][config_entry.entry_id] = {DATA_API: api, DATA_LOCATION: location} diff --git a/homeassistant/components/ipma/manifest.json b/homeassistant/components/ipma/manifest.json index 23558600373..36dca71e957 100644 --- a/homeassistant/components/ipma/manifest.json +++ b/homeassistant/components/ipma/manifest.json @@ -3,7 +3,7 @@ "name": "Instituto Portugu\u00eas do Mar e Atmosfera (IPMA)", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/ipma", - "requirements": ["pyipma==3.0.4"], + "requirements": ["pyipma==3.0.5"], "codeowners": ["@dgomes", "@abmantis"], "iot_class": "cloud_polling", "loggers": ["geopy", "pyipma"] diff --git a/homeassistant/components/lametric/config_flow.py b/homeassistant/components/lametric/config_flow.py index 4bb293b0a4d..59797e3caf1 100644 --- a/homeassistant/components/lametric/config_flow.py +++ b/homeassistant/components/lametric/config_flow.py @@ -13,6 +13,7 @@ from demetriek import ( Model, Notification, NotificationIconType, + NotificationPriority, NotificationSound, Simple, Sound, @@ -227,6 +228,7 @@ class LaMetricFlowHandler(AbstractOAuth2FlowHandler, domain=DOMAIN): await lametric.notify( notification=Notification( + priority=NotificationPriority.CRITICAL, icon_type=NotificationIconType.INFO, model=Model( cycles=2, diff --git a/homeassistant/components/motion_blinds/manifest.json b/homeassistant/components/motion_blinds/manifest.json index 90ad330bd40..e6e4c50c7fe 100644 --- a/homeassistant/components/motion_blinds/manifest.json +++ b/homeassistant/components/motion_blinds/manifest.json @@ -3,7 +3,7 @@ "name": "Motion Blinds", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/motion_blinds", - "requirements": ["motionblinds==0.6.12"], + "requirements": ["motionblinds==0.6.13"], "dependencies": ["network"], "dhcp": [ { "registered_devices": true }, diff --git a/homeassistant/components/mqtt/device_tracker/schema_discovery.py b/homeassistant/components/mqtt/device_tracker/schema_discovery.py index 105442b176e..907d424e8a4 100644 --- a/homeassistant/components/mqtt/device_tracker/schema_discovery.py +++ b/homeassistant/components/mqtt/device_tracker/schema_discovery.py @@ -1,7 +1,6 @@ """Support for tracking MQTT enabled devices identified through discovery.""" from __future__ import annotations -import asyncio import functools import voluptuous as vol @@ -28,12 +27,7 @@ from .. import subscription from ..config import MQTT_RO_SCHEMA from ..const import CONF_QOS, CONF_STATE_TOPIC from ..debug_info import log_messages -from ..mixins import ( - MQTT_ENTITY_COMMON_SCHEMA, - MqttEntity, - async_get_platform_config_from_yaml, - async_setup_entry_helper, -) +from ..mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entry_helper from ..models import MqttValueTemplate CONF_PAYLOAD_HOME = "payload_home" @@ -58,16 +52,6 @@ async def async_setup_entry_from_discovery( async_add_entities: AddEntitiesCallback, ) -> None: """Set up MQTT device tracker configuration.yaml and dynamically through MQTT discovery.""" - # load and initialize platform config from configuration.yaml - await asyncio.gather( - *( - _async_setup_entity(hass, async_add_entities, config, config_entry) - for config in await async_get_platform_config_from_yaml( - hass, device_tracker.DOMAIN - ) - ) - ) - # setup for discovery setup = functools.partial( _async_setup_entity, hass, async_add_entities, config_entry=config_entry ) diff --git a/homeassistant/components/openweathermap/const.py b/homeassistant/components/openweathermap/const.py index 836a56c70b2..5a370604e1f 100644 --- a/homeassistant/components/openweathermap/const.py +++ b/homeassistant/components/openweathermap/const.py @@ -86,7 +86,7 @@ FORECAST_MODES = [ FORECAST_MODE_ONECALL_HOURLY, FORECAST_MODE_ONECALL_DAILY, ] -DEFAULT_FORECAST_MODE = FORECAST_MODE_ONECALL_DAILY +DEFAULT_FORECAST_MODE = FORECAST_MODE_HOURLY LANGUAGES = [ "af", diff --git a/homeassistant/components/velbus/config_flow.py b/homeassistant/components/velbus/config_flow.py index 993146d375c..32f1f3a500d 100644 --- a/homeassistant/components/velbus/config_flow.py +++ b/homeassistant/components/velbus/config_flow.py @@ -10,21 +10,12 @@ import voluptuous as vol from homeassistant import config_entries from homeassistant.components import usb from homeassistant.const import CONF_NAME, CONF_PORT -from homeassistant.core import HomeAssistant, callback from homeassistant.data_entry_flow import FlowResult from homeassistant.util import slugify from .const import DOMAIN -@callback -def velbus_entries(hass: HomeAssistant) -> set[str]: - """Return connections for Velbus domain.""" - return { - entry.data[CONF_PORT] for entry in hass.config_entries.async_entries(DOMAIN) - } - - class VelbusConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): """Handle a config flow.""" @@ -51,10 +42,6 @@ class VelbusConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): return False return True - def _prt_in_configuration_exists(self, prt: str) -> bool: - """Return True if port exists in configuration.""" - return prt in velbus_entries(self.hass) - async def async_step_user( self, user_input: dict[str, Any] | None = None ) -> FlowResult: @@ -63,11 +50,9 @@ class VelbusConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): if user_input is not None: name = slugify(user_input[CONF_NAME]) prt = user_input[CONF_PORT] - if not self._prt_in_configuration_exists(prt): - if await self._test_connection(prt): - return self._create_device(name, prt) - else: - self._errors[CONF_PORT] = "already_configured" + self._async_abort_entries_match({CONF_PORT: prt}) + if await self._test_connection(prt): + return self._create_device(name, prt) else: user_input = {} user_input[CONF_NAME] = "" @@ -93,8 +78,7 @@ class VelbusConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): usb.get_serial_by_id, discovery_info.device ) # check if this device is not already configured - if self._prt_in_configuration_exists(dev_path): - return self.async_abort(reason="already_configured") + self._async_abort_entries_match({CONF_PORT: dev_path}) # check if we can make a valid velbus connection if not await self._test_connection(dev_path): return self.async_abort(reason="cannot_connect") diff --git a/homeassistant/const.py b/homeassistant/const.py index 6c3d2a32ea3..68ca7fa33ea 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -7,7 +7,7 @@ from .backports.enum import StrEnum MAJOR_VERSION: Final = 2022 MINOR_VERSION: Final = 9 -PATCH_VERSION: Final = "6" +PATCH_VERSION: Final = "7" __short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__: Final = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 9, 0) diff --git a/homeassistant/generated/bluetooth.py b/homeassistant/generated/bluetooth.py index 22bb93d1bda..6553f9bcfb6 100644 --- a/homeassistant/generated/bluetooth.py +++ b/homeassistant/generated/bluetooth.py @@ -56,6 +56,12 @@ BLUETOOTH: list[dict[str, bool | str | int | list[int]]] = [ "service_uuid": "00008451-0000-1000-8000-00805f9b34fb", "connectable": False }, + { + "domain": "govee_ble", + "manufacturer_id": 63391, + "service_uuid": "00008351-0000-1000-8000-00805f9b34fb", + "connectable": False + }, { "domain": "govee_ble", "manufacturer_id": 26589, @@ -80,6 +86,12 @@ BLUETOOTH: list[dict[str, bool | str | int | list[int]]] = [ "service_uuid": "00008551-0000-1000-8000-00805f9b34fb", "connectable": False }, + { + "domain": "govee_ble", + "manufacturer_id": 43682, + "service_uuid": "00008151-0000-1000-8000-00805f9b34fb", + "connectable": False + }, { "domain": "govee_ble", "manufacturer_id": 59970, diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index 8a0ee6c3205..d74601cef13 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -132,3 +132,6 @@ iso4217!=1.10.20220401 # Pandas 1.4.4 has issues with wheels om armhf + Py3.10 pandas==1.4.3 + +# pyopenssl 22.1.0 requires pycryptography > 38 and we have 37 +pyopenssl==22.0.0 diff --git a/homeassistant/setup.py b/homeassistant/setup.py index 8d5f9e52025..d85e4043505 100644 --- a/homeassistant/setup.py +++ b/homeassistant/setup.py @@ -357,11 +357,10 @@ async def async_process_deps_reqs( if failed_deps := await _async_process_dependencies(hass, config, integration): raise DependencyError(failed_deps) - if not hass.config.skip_pip and integration.requirements: - async with hass.timeout.async_freeze(integration.domain): - await requirements.async_get_integration_with_requirements( - hass, integration.domain - ) + async with hass.timeout.async_freeze(integration.domain): + await requirements.async_get_integration_with_requirements( + hass, integration.domain + ) processed.add(integration.domain) diff --git a/pyproject.toml b/pyproject.toml index 2f4d1e5315d..c0368421577 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "homeassistant" -version = "2022.9.6" +version = "2022.9.7" license = {text = "Apache-2.0"} description = "Open-source home automation platform running on Python 3." readme = "README.rst" diff --git a/requirements_all.txt b/requirements_all.txt index 608c558b7ef..70d1e467639 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -442,7 +442,7 @@ bluetooth-auto-recovery==0.3.3 bond-async==0.1.22 # homeassistant.components.bosch_shc -boschshcpy==0.2.30 +boschshcpy==0.2.35 # homeassistant.components.amazon_polly # homeassistant.components.route53 @@ -778,7 +778,7 @@ googlemaps==2.5.1 goslide-api==0.5.1 # homeassistant.components.govee_ble -govee-ble==0.17.3 +govee-ble==0.19.0 # homeassistant.components.remote_rpi_gpio gpiozero==1.6.2 @@ -1079,7 +1079,7 @@ moat-ble==0.1.1 moehlenhoff-alpha2==1.2.1 # homeassistant.components.motion_blinds -motionblinds==0.6.12 +motionblinds==0.6.13 # homeassistant.components.motioneye motioneye-client==0.3.12 @@ -1614,7 +1614,7 @@ pyinsteon==1.2.0 pyintesishome==1.8.0 # homeassistant.components.ipma -pyipma==3.0.4 +pyipma==3.0.5 # homeassistant.components.ipp pyipp==0.11.0 @@ -2551,7 +2551,7 @@ yalesmartalarmclient==0.3.9 yalexs-ble==1.9.2 # homeassistant.components.august -yalexs==1.2.1 +yalexs==1.2.2 # homeassistant.components.yeelight yeelight==0.7.10 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index ffca40fe7da..7e642ed926a 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -353,7 +353,7 @@ bluetooth-auto-recovery==0.3.3 bond-async==0.1.22 # homeassistant.components.bosch_shc -boschshcpy==0.2.30 +boschshcpy==0.2.35 # homeassistant.components.broadlink broadlink==0.18.2 @@ -579,7 +579,7 @@ google-nest-sdm==2.0.0 googlemaps==2.5.1 # homeassistant.components.govee_ble -govee-ble==0.17.3 +govee-ble==0.19.0 # homeassistant.components.gree greeclimate==1.3.0 @@ -778,7 +778,7 @@ moat-ble==0.1.1 moehlenhoff-alpha2==1.2.1 # homeassistant.components.motion_blinds -motionblinds==0.6.12 +motionblinds==0.6.13 # homeassistant.components.motioneye motioneye-client==0.3.12 @@ -1127,7 +1127,7 @@ pyicloud==1.0.0 pyinsteon==1.2.0 # homeassistant.components.ipma -pyipma==3.0.4 +pyipma==3.0.5 # homeassistant.components.ipp pyipp==0.11.0 @@ -1755,7 +1755,7 @@ yalesmartalarmclient==0.3.9 yalexs-ble==1.9.2 # homeassistant.components.august -yalexs==1.2.1 +yalexs==1.2.2 # homeassistant.components.yeelight yeelight==0.7.10 diff --git a/script/gen_requirements_all.py b/script/gen_requirements_all.py index d0eb830f088..eec89d4210c 100755 --- a/script/gen_requirements_all.py +++ b/script/gen_requirements_all.py @@ -142,6 +142,9 @@ iso4217!=1.10.20220401 # Pandas 1.4.4 has issues with wheels om armhf + Py3.10 pandas==1.4.3 + +# pyopenssl 22.1.0 requires pycryptography > 38 and we have 37 +pyopenssl==22.0.0 """ IGNORE_PRE_COMMIT_HOOK_ID = ( diff --git a/tests/components/velbus/test_config_flow.py b/tests/components/velbus/test_config_flow.py index 207f745e495..454290b3581 100644 --- a/tests/components/velbus/test_config_flow.py +++ b/tests/components/velbus/test_config_flow.py @@ -7,9 +7,8 @@ from velbusaio.exceptions import VelbusConnectionFailed from homeassistant import data_entry_flow from homeassistant.components import usb -from homeassistant.components.velbus import config_flow from homeassistant.components.velbus.const import DOMAIN -from homeassistant.config_entries import SOURCE_USB +from homeassistant.config_entries import SOURCE_USB, SOURCE_USER from homeassistant.const import CONF_NAME, CONF_PORT, CONF_SOURCE from homeassistant.core import HomeAssistant @@ -53,63 +52,76 @@ def mock_controller_connection_failed(): yield -def init_config_flow(hass: HomeAssistant): - """Init a configuration flow.""" - flow = config_flow.VelbusConfigFlow() - flow.hass = hass - return flow - - @pytest.mark.usefixtures("controller") async def test_user(hass: HomeAssistant): """Test user config.""" - flow = init_config_flow(hass) - - result = await flow.async_step_user() - assert result["type"] == data_entry_flow.FlowResultType.FORM - assert result["step_id"] == "user" - - result = await flow.async_step_user( - {CONF_NAME: "Velbus Test Serial", CONF_PORT: PORT_SERIAL} + # simple user form + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": SOURCE_USER} ) - assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY - assert result["title"] == "velbus_test_serial" - assert result["data"][CONF_PORT] == PORT_SERIAL + assert result + assert result.get("flow_id") + assert result.get("type") == data_entry_flow.FlowResultType.FORM + assert result.get("step_id") == "user" - result = await flow.async_step_user( - {CONF_NAME: "Velbus Test TCP", CONF_PORT: PORT_TCP} + # try with a serial port + result = await hass.config_entries.flow.async_init( + DOMAIN, + context={"source": SOURCE_USER}, + data={CONF_NAME: "Velbus Test Serial", CONF_PORT: PORT_SERIAL}, ) - assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY - assert result["title"] == "velbus_test_tcp" - assert result["data"][CONF_PORT] == PORT_TCP + assert result + assert result.get("type") == data_entry_flow.FlowResultType.CREATE_ENTRY + assert result.get("title") == "velbus_test_serial" + data = result.get("data") + assert data[CONF_PORT] == PORT_SERIAL + + # try with a ip:port combination + result = await hass.config_entries.flow.async_init( + DOMAIN, + context={"source": SOURCE_USER}, + data={CONF_NAME: "Velbus Test TCP", CONF_PORT: PORT_TCP}, + ) + assert result + assert result.get("type") == data_entry_flow.FlowResultType.CREATE_ENTRY + assert result.get("title") == "velbus_test_tcp" + data = result.get("data") + assert data[CONF_PORT] == PORT_TCP @pytest.mark.usefixtures("controller_connection_failed") async def test_user_fail(hass: HomeAssistant): """Test user config.""" - flow = init_config_flow(hass) - - result = await flow.async_step_user( - {CONF_NAME: "Velbus Test Serial", CONF_PORT: PORT_SERIAL} + result = await hass.config_entries.flow.async_init( + DOMAIN, + context={"source": SOURCE_USER}, + data={CONF_NAME: "Velbus Test Serial", CONF_PORT: PORT_SERIAL}, ) - assert result["type"] == data_entry_flow.FlowResultType.FORM - assert result["errors"] == {CONF_PORT: "cannot_connect"} + assert result + assert result.get("type") == data_entry_flow.FlowResultType.FORM + assert result.get("errors") == {CONF_PORT: "cannot_connect"} - result = await flow.async_step_user( - {CONF_NAME: "Velbus Test TCP", CONF_PORT: PORT_TCP} + result = await hass.config_entries.flow.async_init( + DOMAIN, + context={"source": SOURCE_USER}, + data={CONF_NAME: "Velbus Test TCP", CONF_PORT: PORT_TCP}, ) - assert result["type"] == data_entry_flow.FlowResultType.FORM - assert result["errors"] == {CONF_PORT: "cannot_connect"} + assert result + assert result.get("type") == data_entry_flow.FlowResultType.FORM + assert result.get("errors") == {CONF_PORT: "cannot_connect"} @pytest.mark.usefixtures("config_entry") async def test_abort_if_already_setup(hass: HomeAssistant): """Test we abort if Velbus is already setup.""" - flow = init_config_flow(hass) - - result = await flow.async_step_user({CONF_PORT: PORT_TCP, CONF_NAME: "velbus test"}) - assert result["type"] == data_entry_flow.FlowResultType.FORM - assert result["errors"] == {"port": "already_configured"} + result = await hass.config_entries.flow.async_init( + DOMAIN, + context={"source": SOURCE_USER}, + data={CONF_PORT: PORT_TCP, CONF_NAME: "velbus test"}, + ) + assert result + assert result.get("type") == data_entry_flow.FlowResultType.ABORT + assert result.get("reason") == "already_configured" @pytest.mark.usefixtures("controller") @@ -121,14 +133,16 @@ async def test_flow_usb(hass: HomeAssistant): context={CONF_SOURCE: SOURCE_USB}, data=DISCOVERY_INFO, ) - assert result["type"] == data_entry_flow.FlowResultType.FORM - assert result["step_id"] == "discovery_confirm" + assert result + assert result.get("type") == data_entry_flow.FlowResultType.FORM + assert result.get("step_id") == "discovery_confirm" result = await hass.config_entries.flow.async_configure( result["flow_id"], user_input={}, ) - assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY + assert result + assert result.get("type") == data_entry_flow.FlowResultType.CREATE_ENTRY # test an already configured discovery entry = MockConfigEntry( @@ -141,8 +155,9 @@ async def test_flow_usb(hass: HomeAssistant): context={CONF_SOURCE: SOURCE_USB}, data=DISCOVERY_INFO, ) - assert result["type"] == data_entry_flow.FlowResultType.ABORT - assert result["reason"] == "already_configured" + assert result + assert result.get("type") == data_entry_flow.FlowResultType.ABORT + assert result.get("reason") == "already_configured" @pytest.mark.usefixtures("controller_connection_failed") @@ -154,5 +169,6 @@ async def test_flow_usb_failed(hass: HomeAssistant): context={CONF_SOURCE: SOURCE_USB}, data=DISCOVERY_INFO, ) - assert result["type"] == data_entry_flow.FlowResultType.ABORT - assert result["reason"] == "cannot_connect" + assert result + assert result.get("type") == data_entry_flow.FlowResultType.ABORT + assert result.get("reason") == "cannot_connect"