This commit is contained in:
Paulus Schoutsen 2022-09-26 11:18:42 -04:00 committed by GitHub
commit 77a933d6f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 133 additions and 124 deletions

View File

@ -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": [
{

View File

@ -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"],

View File

@ -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"

View File

@ -1,4 +1,5 @@
"""Component for the Portuguese weather service - IPMA."""
import asyncio
import logging
import async_timeout
@ -22,22 +23,21 @@ 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))
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)",
@ -47,10 +47,6 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
location.id_station,
location.global_id_local,
)
except IPMAException as err:
raise ConfigEntryNotReady(
f"Could not get location for ({latitude},{longitude})"
) from err
hass.data.setdefault(DOMAIN, {})
hass.data[DOMAIN][config_entry.entry_id] = {DATA_API: api, DATA_LOCATION: location}

View File

@ -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"]

View File

@ -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,

View File

@ -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 },

View File

@ -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
)

View File

@ -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",

View File

@ -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):
self._async_abort_entries_match({CONF_PORT: prt})
if await self._test_connection(prt):
return self._create_device(name, prt)
else:
self._errors[CONF_PORT] = "already_configured"
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")

View File

@ -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)

View File

@ -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,

View File

@ -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

View File

@ -357,7 +357,6 @@ 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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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 = (

View File

@ -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"