From e0d0dc05e4c251b410eaf44d0710f2ad0bd21ba5 Mon Sep 17 00:00:00 2001 From: Michael <35783820+mib1185@users.noreply.github.com> Date: Sun, 22 Jan 2023 17:20:12 +0100 Subject: [PATCH 1/7] Support password less PI-Hole installations (#86183) --- homeassistant/components/pi_hole/__init__.py | 4 -- .../components/pi_hole/config_flow.py | 26 +++++++- homeassistant/components/pi_hole/strings.json | 6 +- .../components/pi_hole/translations/en.json | 6 +- tests/components/pi_hole/__init__.py | 19 +++++- tests/components/pi_hole/test_config_flow.py | 64 +++++++++++++------ tests/components/pi_hole/test_init.py | 15 +---- 7 files changed, 95 insertions(+), 45 deletions(-) diff --git a/homeassistant/components/pi_hole/__init__.py b/homeassistant/components/pi_hole/__init__.py index ba7949c0c30..b33b9438354 100644 --- a/homeassistant/components/pi_hole/__init__.py +++ b/homeassistant/components/pi_hole/__init__.py @@ -117,10 +117,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: entry_data.pop(CONF_STATISTICS_ONLY) hass.config_entries.async_update_entry(entry, data=entry_data) - # start reauth to force api key is present - if CONF_API_KEY not in entry.data: - raise ConfigEntryAuthFailed - _LOGGER.debug("Setting up %s integration with host %s", DOMAIN, host) session = async_get_clientsession(hass, verify_tls) diff --git a/homeassistant/components/pi_hole/config_flow.py b/homeassistant/components/pi_hole/config_flow.py index 637f906b9ee..519ef5a7628 100644 --- a/homeassistant/components/pi_hole/config_flow.py +++ b/homeassistant/components/pi_hole/config_flow.py @@ -56,7 +56,6 @@ class PiHoleFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): CONF_LOCATION: user_input[CONF_LOCATION], CONF_SSL: user_input[CONF_SSL], CONF_VERIFY_SSL: user_input[CONF_VERIFY_SSL], - CONF_API_KEY: user_input[CONF_API_KEY], } self._async_abort_entries_match( @@ -71,6 +70,9 @@ class PiHoleFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): title=user_input[CONF_NAME], data=self._config ) + if CONF_API_KEY in errors: + return await self.async_step_api_key() + user_input = user_input or {} return self.async_show_form( step_id="user", @@ -80,7 +82,6 @@ class PiHoleFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): vol.Required( CONF_PORT, default=user_input.get(CONF_PORT, 80) ): vol.Coerce(int), - vol.Required(CONF_API_KEY): str, vol.Required( CONF_NAME, default=user_input.get(CONF_NAME, DEFAULT_NAME) ): str, @@ -101,6 +102,25 @@ class PiHoleFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): errors=errors, ) + async def async_step_api_key( + self, user_input: dict[str, Any] | None = None + ) -> FlowResult: + """Handle step to setup API key.""" + errors = {} + if user_input is not None: + self._config[CONF_API_KEY] = user_input[CONF_API_KEY] + if not (errors := await self._async_try_connect()): + return self.async_create_entry( + title=self._config[CONF_NAME], + data=self._config, + ) + + return self.async_show_form( + step_id="api_key", + data_schema=vol.Schema({vol.Required(CONF_API_KEY): str}), + errors=errors, + ) + async def async_step_import(self, user_input: dict[str, Any]) -> FlowResult: """Handle a flow initiated by import.""" @@ -178,7 +198,7 @@ class PiHoleFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): session, location=self._config[CONF_LOCATION], tls=self._config[CONF_SSL], - api_token=self._config[CONF_API_KEY], + api_token=self._config.get(CONF_API_KEY), ) try: await pi_hole.get_data() diff --git a/homeassistant/components/pi_hole/strings.json b/homeassistant/components/pi_hole/strings.json index 120ab8cb80a..2f04b8fe47e 100644 --- a/homeassistant/components/pi_hole/strings.json +++ b/homeassistant/components/pi_hole/strings.json @@ -7,11 +7,15 @@ "port": "[%key:common::config_flow::data::port%]", "name": "[%key:common::config_flow::data::name%]", "location": "[%key:common::config_flow::data::location%]", - "api_key": "[%key:common::config_flow::data::api_key%]", "ssl": "[%key:common::config_flow::data::ssl%]", "verify_ssl": "[%key:common::config_flow::data::verify_ssl%]" } }, + "api_key": { + "data": { + "api_key": "[%key:common::config_flow::data::api_key%]" + } + }, "reauth_confirm": { "title": "PI-Hole [%key:common::config_flow::title::reauth%]", "description": "Please enter a new api key for PI-Hole at {host}/{location}", diff --git a/homeassistant/components/pi_hole/translations/en.json b/homeassistant/components/pi_hole/translations/en.json index 815182731c2..940e3950281 100644 --- a/homeassistant/components/pi_hole/translations/en.json +++ b/homeassistant/components/pi_hole/translations/en.json @@ -9,6 +9,11 @@ "invalid_auth": "Invalid authentication" }, "step": { + "api_key": { + "data": { + "api_key": "API Key" + } + }, "reauth_confirm": { "data": { "api_key": "API Key" @@ -18,7 +23,6 @@ }, "user": { "data": { - "api_key": "API Key", "host": "Host", "location": "Location", "name": "Name", diff --git a/tests/components/pi_hole/__init__.py b/tests/components/pi_hole/__init__.py index 49e15391f8c..8658fc84ffe 100644 --- a/tests/components/pi_hole/__init__.py +++ b/tests/components/pi_hole/__init__.py @@ -74,7 +74,6 @@ CONFIG_DATA = { CONFIG_FLOW_USER = { CONF_HOST: HOST, CONF_PORT: PORT, - CONF_API_KEY: API_KEY, CONF_LOCATION: LOCATION, CONF_NAME: NAME, CONF_SSL: SSL, @@ -85,7 +84,7 @@ CONFIG_FLOW_API_KEY = { CONF_API_KEY: API_KEY, } -CONFIG_ENTRY = { +CONFIG_ENTRY_WITH_API_KEY = { CONF_HOST: f"{HOST}:{PORT}", CONF_LOCATION: LOCATION, CONF_NAME: NAME, @@ -94,7 +93,15 @@ CONFIG_ENTRY = { CONF_VERIFY_SSL: VERIFY_SSL, } -CONFIG_ENTRY_IMPORTED = {**CONFIG_ENTRY, CONF_STATISTICS_ONLY: False} +CONFIG_ENTRY_WITHOUT_API_KEY = { + CONF_HOST: f"{HOST}:{PORT}", + CONF_LOCATION: LOCATION, + CONF_NAME: NAME, + CONF_SSL: SSL, + CONF_VERIFY_SSL: VERIFY_SSL, +} + +CONFIG_ENTRY_IMPORTED = {**CONFIG_ENTRY_WITH_API_KEY, CONF_STATISTICS_ONLY: False} SWITCH_ENTITY_ID = "switch.pi_hole" @@ -128,3 +135,9 @@ def _patch_config_flow_hole(mocked_hole): return patch( "homeassistant.components.pi_hole.config_flow.Hole", return_value=mocked_hole ) + + +def _patch_setup_hole(): + return patch( + "homeassistant.components.pi_hole.async_setup_entry", return_value=True + ) diff --git a/tests/components/pi_hole/test_config_flow.py b/tests/components/pi_hole/test_config_flow.py index 65f21418bad..8c38803de64 100644 --- a/tests/components/pi_hole/test_config_flow.py +++ b/tests/components/pi_hole/test_config_flow.py @@ -1,6 +1,5 @@ """Test pi_hole config flow.""" import logging -from unittest.mock import patch from homeassistant.components.pi_hole.const import DOMAIN from homeassistant.config_entries import SOURCE_IMPORT, SOURCE_USER @@ -11,30 +10,26 @@ from homeassistant.data_entry_flow import FlowResultType from . import ( CONFIG_DATA, CONFIG_DATA_DEFAULTS, - CONFIG_ENTRY, CONFIG_ENTRY_IMPORTED, + CONFIG_ENTRY_WITH_API_KEY, + CONFIG_ENTRY_WITHOUT_API_KEY, + CONFIG_FLOW_API_KEY, CONFIG_FLOW_USER, NAME, ZERO_DATA, _create_mocked_hole, _patch_config_flow_hole, _patch_init_hole, + _patch_setup_hole, ) from tests.common import MockConfigEntry -def _patch_setup(): - return patch( - "homeassistant.components.pi_hole.async_setup_entry", - return_value=True, - ) - - async def test_flow_import(hass: HomeAssistant, caplog): """Test import flow.""" mocked_hole = _create_mocked_hole() - with _patch_config_flow_hole(mocked_hole), _patch_setup(): + with _patch_config_flow_hole(mocked_hole), _patch_setup_hole(): result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_IMPORT}, data=CONFIG_DATA ) @@ -53,7 +48,7 @@ async def test_flow_import(hass: HomeAssistant, caplog): async def test_flow_import_invalid(hass: HomeAssistant, caplog): """Test import flow with invalid server.""" mocked_hole = _create_mocked_hole(True) - with _patch_config_flow_hole(mocked_hole), _patch_setup(): + with _patch_config_flow_hole(mocked_hole), _patch_setup_hole(): result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_IMPORT}, data=CONFIG_DATA ) @@ -62,10 +57,10 @@ async def test_flow_import_invalid(hass: HomeAssistant, caplog): assert len([x for x in caplog.records if x.levelno == logging.ERROR]) == 1 -async def test_flow_user(hass: HomeAssistant): - """Test user initialized flow.""" +async def test_flow_user_with_api_key(hass: HomeAssistant): + """Test user initialized flow with api key needed.""" mocked_hole = _create_mocked_hole(has_data=False) - with _patch_config_flow_hole(mocked_hole), _patch_init_hole(mocked_hole): + with _patch_config_flow_hole(mocked_hole), _patch_setup_hole() as mock_setup: result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_USER}, @@ -79,17 +74,26 @@ async def test_flow_user(hass: HomeAssistant): user_input=CONFIG_FLOW_USER, ) assert result["type"] == FlowResultType.FORM - assert result["step_id"] == "user" + assert result["step_id"] == "api_key" + assert result["errors"] == {} + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + user_input={CONF_API_KEY: "some_key"}, + ) + assert result["type"] == FlowResultType.FORM + assert result["step_id"] == "api_key" assert result["errors"] == {CONF_API_KEY: "invalid_auth"} mocked_hole.data = ZERO_DATA result = await hass.config_entries.flow.async_configure( result["flow_id"], - user_input=CONFIG_FLOW_USER, + user_input=CONFIG_FLOW_API_KEY, ) assert result["type"] == FlowResultType.CREATE_ENTRY assert result["title"] == NAME - assert result["data"] == CONFIG_ENTRY + assert result["data"] == CONFIG_ENTRY_WITH_API_KEY + mock_setup.assert_called_once() # duplicated server result = await hass.config_entries.flow.async_init( @@ -101,10 +105,32 @@ async def test_flow_user(hass: HomeAssistant): assert result["reason"] == "already_configured" -async def test_flow_user_invalid(hass): +async def test_flow_user_without_api_key(hass: HomeAssistant): + """Test user initialized flow without api key needed.""" + mocked_hole = _create_mocked_hole() + with _patch_config_flow_hole(mocked_hole), _patch_setup_hole() as mock_setup: + result = await hass.config_entries.flow.async_init( + DOMAIN, + context={"source": SOURCE_USER}, + ) + assert result["type"] == FlowResultType.FORM + assert result["step_id"] == "user" + assert result["errors"] == {} + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + user_input=CONFIG_FLOW_USER, + ) + assert result["type"] == FlowResultType.CREATE_ENTRY + assert result["title"] == NAME + assert result["data"] == CONFIG_ENTRY_WITHOUT_API_KEY + mock_setup.assert_called_once() + + +async def test_flow_user_invalid(hass: HomeAssistant): """Test user initialized flow with invalid server.""" mocked_hole = _create_mocked_hole(True) - with _patch_config_flow_hole(mocked_hole), _patch_setup(): + with _patch_config_flow_hole(mocked_hole): result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_USER}, data=CONFIG_FLOW_USER ) diff --git a/tests/components/pi_hole/test_init.py b/tests/components/pi_hole/test_init.py index 75d9dd27aee..b863898db25 100644 --- a/tests/components/pi_hole/test_init.py +++ b/tests/components/pi_hole/test_init.py @@ -10,8 +10,7 @@ from homeassistant.components.pi_hole.const import ( SERVICE_DISABLE, SERVICE_DISABLE_ATTR_DURATION, ) -from homeassistant.config_entries import ConfigEntryState -from homeassistant.const import ATTR_ENTITY_ID, CONF_API_KEY, CONF_HOST +from homeassistant.const import ATTR_ENTITY_ID, CONF_HOST from homeassistant.core import HomeAssistant from homeassistant.setup import async_setup_component @@ -200,15 +199,3 @@ async def test_remove_obsolete(hass: HomeAssistant): with _patch_init_hole(mocked_hole): assert await hass.config_entries.async_setup(entry.entry_id) assert CONF_STATISTICS_ONLY not in entry.data - - -async def test_missing_api_key(hass: HomeAssistant): - """Tests start reauth flow if api key is missing.""" - mocked_hole = _create_mocked_hole() - data = CONFIG_DATA_DEFAULTS.copy() - data.pop(CONF_API_KEY) - entry = MockConfigEntry(domain=pi_hole.DOMAIN, data=data) - entry.add_to_hass(hass) - with _patch_init_hole(mocked_hole): - assert not await hass.config_entries.async_setup(entry.entry_id) - assert entry.state == ConfigEntryState.SETUP_ERROR From 72dae914fcca9c131f3d827227c7db26dcc10ec7 Mon Sep 17 00:00:00 2001 From: Klaas Schoute Date: Fri, 20 Jan 2023 03:26:51 +0100 Subject: [PATCH 2/7] Bump odp-amsterdam to v5.0.1 (#86252) Bump package version to v5.0.1 --- homeassistant/components/garages_amsterdam/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/garages_amsterdam/manifest.json b/homeassistant/components/garages_amsterdam/manifest.json index 1d6e91293db..a889ed062a8 100644 --- a/homeassistant/components/garages_amsterdam/manifest.json +++ b/homeassistant/components/garages_amsterdam/manifest.json @@ -3,7 +3,7 @@ "name": "Garages Amsterdam", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/garages_amsterdam", - "requirements": ["odp-amsterdam==5.0.0"], + "requirements": ["odp-amsterdam==5.0.1"], "codeowners": ["@klaasnicolaas"], "iot_class": "cloud_polling" } diff --git a/requirements_all.txt b/requirements_all.txt index 3f6fecf57da..ce2dc8322ec 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1220,7 +1220,7 @@ oauth2client==4.1.3 objgraph==3.5.0 # homeassistant.components.garages_amsterdam -odp-amsterdam==5.0.0 +odp-amsterdam==5.0.1 # homeassistant.components.oem oemthermostat==1.1.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index fa5c72da0af..3c77014a07f 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -892,7 +892,7 @@ oauth2client==4.1.3 objgraph==3.5.0 # homeassistant.components.garages_amsterdam -odp-amsterdam==5.0.0 +odp-amsterdam==5.0.1 # homeassistant.components.omnilogic omnilogic==0.4.5 From 9669b286c493c098f664d36694b4cb10e54f97ba Mon Sep 17 00:00:00 2001 From: Shay Levy Date: Fri, 20 Jan 2023 21:27:31 +0200 Subject: [PATCH 3/7] Fix Shelly sleeping Gen2 - do not refresh from zeroconf discovery (#86296) --- .../components/shelly/coordinator.py | 3 +- tests/components/shelly/test_config_flow.py | 36 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/shelly/coordinator.py b/homeassistant/components/shelly/coordinator.py index 96852512334..9029f18eb22 100644 --- a/homeassistant/components/shelly/coordinator.py +++ b/homeassistant/components/shelly/coordinator.py @@ -660,7 +660,8 @@ async def async_reconnect_soon( ) -> None: """Try to reconnect soon.""" if ( - not hass.is_stopping + not entry.data.get(CONF_SLEEP_PERIOD) + and not hass.is_stopping and entry.state == config_entries.ConfigEntryState.LOADED and (entry_data := get_entry_data(hass).get(entry.entry_id)) and (coordinator := entry_data.rpc) diff --git a/tests/components/shelly/test_config_flow.py b/tests/components/shelly/test_config_flow.py index 7338747cbaf..fbaf2d98ba2 100644 --- a/tests/components/shelly/test_config_flow.py +++ b/tests/components/shelly/test_config_flow.py @@ -1187,3 +1187,39 @@ async def test_zeroconf_already_configured_triggers_refresh( mock_rpc_device.mock_disconnected() await hass.async_block_till_done() assert len(mock_rpc_device.initialize.mock_calls) == 2 + + +async def test_zeroconf_sleeping_device_not_triggers_refresh( + hass, mock_rpc_device, monkeypatch, caplog +): + """Test zeroconf discovery does not triggers refresh for sleeping device.""" + entry = MockConfigEntry( + domain="shelly", + unique_id="AABBCCDDEEFF", + data={"host": "1.1.1.1", "gen": 2, "sleep_period": 1000, "model": "SHSW-1"}, + ) + entry.add_to_hass(hass) + await hass.config_entries.async_setup(entry.entry_id) + await hass.async_block_till_done() + + mock_rpc_device.mock_update() + + assert "online, resuming setup" in caplog.text + + with patch( + "aioshelly.common.get_info", + return_value={"mac": "AABBCCDDEEFF", "type": "SHSW-1", "auth": False}, + ): + result = await hass.config_entries.flow.async_init( + DOMAIN, + data=DISCOVERY_INFO, + context={"source": config_entries.SOURCE_ZEROCONF}, + ) + assert result["type"] == data_entry_flow.FlowResultType.ABORT + assert result["reason"] == "already_configured" + + monkeypatch.setattr(mock_rpc_device, "connected", False) + mock_rpc_device.mock_disconnected() + await hass.async_block_till_done() + assert len(mock_rpc_device.initialize.mock_calls) == 0 + assert "device did not update" not in caplog.text From 71d54da6730adf47782d98e7b4383bbac1efcc32 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 21 Jan 2023 12:05:06 -1000 Subject: [PATCH 4/7] Bump recommended esphome version for bluetooth proxies to 2022.12.4 (#86308) This will fix an MTU issue reported with airthings and other devices. needs https://github.com/esphome/esphome/pull/4323 --- homeassistant/components/esphome/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/esphome/__init__.py b/homeassistant/components/esphome/__init__.py index bfee5658679..b0f046ef1eb 100644 --- a/homeassistant/components/esphome/__init__.py +++ b/homeassistant/components/esphome/__init__.py @@ -65,7 +65,7 @@ CONF_NOISE_PSK = "noise_psk" _LOGGER = logging.getLogger(__name__) _R = TypeVar("_R") -STABLE_BLE_VERSION_STR = "2022.12.0" +STABLE_BLE_VERSION_STR = "2022.12.4" STABLE_BLE_VERSION = AwesomeVersion(STABLE_BLE_VERSION_STR) PROJECT_URLS = { "esphome.bluetooth-proxy": "https://esphome.github.io/bluetooth-proxies/", From 974601cc2e2f620b5fdd87f0203b25bc395107ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Hjelseth=20H=C3=B8yer?= Date: Sat, 21 Jan 2023 00:01:17 +0100 Subject: [PATCH 5/7] Update pyTibber to 0.26.11 (#86316) --- homeassistant/components/tibber/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/tibber/manifest.json b/homeassistant/components/tibber/manifest.json index 403b0f2b4fc..1636c5da4bd 100644 --- a/homeassistant/components/tibber/manifest.json +++ b/homeassistant/components/tibber/manifest.json @@ -3,7 +3,7 @@ "domain": "tibber", "name": "Tibber", "documentation": "https://www.home-assistant.io/integrations/tibber", - "requirements": ["pyTibber==0.26.9"], + "requirements": ["pyTibber==0.26.11"], "codeowners": ["@danielhiversen"], "quality_scale": "silver", "config_flow": true, diff --git a/requirements_all.txt b/requirements_all.txt index ce2dc8322ec..c906fbbd94e 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1439,7 +1439,7 @@ pyRFXtrx==0.30.0 pySwitchmate==0.5.1 # homeassistant.components.tibber -pyTibber==0.26.9 +pyTibber==0.26.11 # homeassistant.components.dlink pyW215==0.7.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 3c77014a07f..1547c3dffcb 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1039,7 +1039,7 @@ pyMetno==0.9.0 pyRFXtrx==0.30.0 # homeassistant.components.tibber -pyTibber==0.26.9 +pyTibber==0.26.11 # homeassistant.components.nextbus py_nextbusnext==0.1.5 From 79a3d2e6f630d837ead4dda51de122cdccabf323 Mon Sep 17 00:00:00 2001 From: uvjustin <46082645+uvjustin@users.noreply.github.com> Date: Mon, 23 Jan 2023 03:28:17 +1100 Subject: [PATCH 6/7] Pass frag_duration as integer (#86375) fixes undefined --- homeassistant/components/stream/worker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/stream/worker.py b/homeassistant/components/stream/worker.py index 308340f74a6..aefbbf698f1 100644 --- a/homeassistant/components/stream/worker.py +++ b/homeassistant/components/stream/worker.py @@ -192,7 +192,7 @@ class StreamMuxer: # of the range, hoping that the parts stay pretty well bounded, and we adjust the part # durations a bit in the hls metadata so that everything "looks" ok. "frag_duration": str( - self._stream_settings.part_target_duration * 9e5 + int(self._stream_settings.part_target_duration * 9e5) ), } if self._stream_settings.ll_hls From 71c4588747a390462784e5667132822011b4bbd1 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Sun, 22 Jan 2023 17:48:00 +0100 Subject: [PATCH 7/7] Bumped version to 2023.1.7 --- homeassistant/const.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index d14ce310238..c738d7fca6d 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -8,7 +8,7 @@ from .backports.enum import StrEnum APPLICATION_NAME: Final = "HomeAssistant" MAJOR_VERSION: Final = 2023 MINOR_VERSION: Final = 1 -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/pyproject.toml b/pyproject.toml index 6fd631b63c6..7f970771255 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "homeassistant" -version = "2023.1.6" +version = "2023.1.7" license = {text = "Apache-2.0"} description = "Open-source home automation platform running on Python 3." readme = "README.rst"