mirror of
https://github.com/home-assistant/core.git
synced 2025-07-24 21:57:51 +00:00
commit
c10e046323
@ -1,15 +1,16 @@
|
|||||||
"""The Airly component."""
|
"""The Airly component."""
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
import logging
|
||||||
|
|
||||||
import async_timeout
|
|
||||||
from aiohttp.client_exceptions import ClientConnectorError
|
from aiohttp.client_exceptions import ClientConnectorError
|
||||||
from airly import Airly
|
from airly import Airly
|
||||||
from airly.exceptions import AirlyError
|
from airly.exceptions import AirlyError
|
||||||
|
import async_timeout
|
||||||
|
|
||||||
from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE
|
from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE
|
||||||
from homeassistant.core import Config, HomeAssistant
|
from homeassistant.core import Config, HomeAssistant
|
||||||
|
from homeassistant.exceptions import ConfigEntryNotReady
|
||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
from homeassistant.util import Throttle
|
from homeassistant.util import Throttle
|
||||||
|
|
||||||
@ -45,6 +46,9 @@ async def async_setup_entry(hass, config_entry):
|
|||||||
|
|
||||||
await airly.async_update()
|
await airly.async_update()
|
||||||
|
|
||||||
|
if not airly.data:
|
||||||
|
raise ConfigEntryNotReady()
|
||||||
|
|
||||||
hass.data[DOMAIN] = {}
|
hass.data[DOMAIN] = {}
|
||||||
hass.data[DOMAIN][DATA_CLIENT] = {}
|
hass.data[DOMAIN][DATA_CLIENT] = {}
|
||||||
hass.data[DOMAIN][DATA_CLIENT][config_entry.entry_id] = airly
|
hass.data[DOMAIN][DATA_CLIENT][config_entry.entry_id] = airly
|
||||||
@ -81,7 +85,7 @@ class AirlyData:
|
|||||||
"""Update Airly data."""
|
"""Update Airly data."""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with async_timeout.timeout(10):
|
with async_timeout.timeout(20):
|
||||||
measurements = self.airly.create_measurements_session_point(
|
measurements = self.airly.create_measurements_session_point(
|
||||||
self.latitude, self.longitude
|
self.latitude, self.longitude
|
||||||
)
|
)
|
||||||
@ -104,11 +108,8 @@ class AirlyData:
|
|||||||
self.data[ATTR_API_CAQI_DESCRIPTION] = index["description"]
|
self.data[ATTR_API_CAQI_DESCRIPTION] = index["description"]
|
||||||
self.data[ATTR_API_ADVICE] = index["advice"]
|
self.data[ATTR_API_ADVICE] = index["advice"]
|
||||||
_LOGGER.debug("Data retrieved from Airly")
|
_LOGGER.debug("Data retrieved from Airly")
|
||||||
except (
|
except asyncio.TimeoutError:
|
||||||
ValueError,
|
_LOGGER.error("Asyncio Timeout Error")
|
||||||
AirlyError,
|
except (ValueError, AirlyError, ClientConnectorError) as error:
|
||||||
asyncio.TimeoutError,
|
|
||||||
ClientConnectorError,
|
|
||||||
) as error:
|
|
||||||
_LOGGER.error(error)
|
_LOGGER.error(error)
|
||||||
self.data = {}
|
self.data = {}
|
||||||
|
@ -2,11 +2,7 @@
|
|||||||
"domain": "environment_canada",
|
"domain": "environment_canada",
|
||||||
"name": "Environment Canada",
|
"name": "Environment Canada",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/environment_canada",
|
"documentation": "https://www.home-assistant.io/integrations/environment_canada",
|
||||||
"requirements": [
|
"requirements": ["env_canada==0.0.29"],
|
||||||
"env_canada==0.0.27"
|
|
||||||
],
|
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"codeowners": [
|
"codeowners": ["@michaeldavie"]
|
||||||
"@michaeldavie"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"name": "Jewish calendar",
|
"name": "Jewish calendar",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/jewish_calendar",
|
"documentation": "https://www.home-assistant.io/integrations/jewish_calendar",
|
||||||
"requirements": [
|
"requirements": [
|
||||||
"hdate==0.9.1"
|
"hdate==0.9.3"
|
||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"codeowners": [
|
"codeowners": [
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"name": "Myq",
|
"name": "Myq",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/myq",
|
"documentation": "https://www.home-assistant.io/integrations/myq",
|
||||||
"requirements": [
|
"requirements": [
|
||||||
"pymyq==2.0.0"
|
"pymyq==2.0.1"
|
||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"codeowners": []
|
"codeowners": []
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"name": "SAJ",
|
"name": "SAJ",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/saj",
|
"documentation": "https://www.home-assistant.io/integrations/saj",
|
||||||
"requirements": [
|
"requirements": [
|
||||||
"pysaj==0.0.12"
|
"pysaj==0.0.13"
|
||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"codeowners": [
|
"codeowners": [
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"name": "Songpal",
|
"name": "Songpal",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/songpal",
|
"documentation": "https://www.home-assistant.io/integrations/songpal",
|
||||||
"requirements": [
|
"requirements": [
|
||||||
"python-songpal==0.11.1"
|
"python-songpal==0.11.2"
|
||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"codeowners": [
|
"codeowners": [
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""Constants used by Home Assistant components."""
|
"""Constants used by Home Assistant components."""
|
||||||
MAJOR_VERSION = 0
|
MAJOR_VERSION = 0
|
||||||
MINOR_VERSION = 101
|
MINOR_VERSION = 101
|
||||||
PATCH_VERSION = "0"
|
PATCH_VERSION = "1"
|
||||||
__short_version__ = "{}.{}".format(MAJOR_VERSION, MINOR_VERSION)
|
__short_version__ = "{}.{}".format(MAJOR_VERSION, MINOR_VERSION)
|
||||||
__version__ = "{}.{}".format(__short_version__, PATCH_VERSION)
|
__version__ = "{}.{}".format(__short_version__, PATCH_VERSION)
|
||||||
REQUIRED_PYTHON_VER = (3, 6, 1)
|
REQUIRED_PYTHON_VER = (3, 6, 1)
|
||||||
|
@ -35,13 +35,21 @@ async def async_get_integration_with_requirements(
|
|||||||
This can raise IntegrationNotFound if manifest or integration
|
This can raise IntegrationNotFound if manifest or integration
|
||||||
is invalid, RequirementNotFound if there was some type of
|
is invalid, RequirementNotFound if there was some type of
|
||||||
failure to install requirements.
|
failure to install requirements.
|
||||||
|
|
||||||
|
Does not handle circular dependencies.
|
||||||
"""
|
"""
|
||||||
integration = await async_get_integration(hass, domain)
|
integration = await async_get_integration(hass, domain)
|
||||||
|
|
||||||
if hass.config.skip_pip or not integration.requirements:
|
if hass.config.skip_pip:
|
||||||
return integration
|
return integration
|
||||||
|
|
||||||
await async_process_requirements(hass, integration.domain, integration.requirements)
|
if integration.requirements:
|
||||||
|
await async_process_requirements(
|
||||||
|
hass, integration.domain, integration.requirements
|
||||||
|
)
|
||||||
|
|
||||||
|
for dependency in integration.dependencies:
|
||||||
|
await async_get_integration_with_requirements(hass, dependency)
|
||||||
|
|
||||||
return integration
|
return integration
|
||||||
|
|
||||||
|
@ -132,6 +132,17 @@ async def _async_setup_component(
|
|||||||
log_error(str(err))
|
log_error(str(err))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
# Some integrations fail on import because they call functions incorrectly.
|
||||||
|
# So we do it before validating config to catch these errors.
|
||||||
|
try:
|
||||||
|
component = integration.get_component()
|
||||||
|
except ImportError:
|
||||||
|
log_error("Unable to import component", False)
|
||||||
|
return False
|
||||||
|
except Exception: # pylint: disable=broad-except
|
||||||
|
_LOGGER.exception("Setup failed for %s: unknown error", domain)
|
||||||
|
return False
|
||||||
|
|
||||||
processed_config = await conf_util.async_process_component_config(
|
processed_config = await conf_util.async_process_component_config(
|
||||||
hass, config, integration
|
hass, config, integration
|
||||||
)
|
)
|
||||||
@ -143,12 +154,6 @@ async def _async_setup_component(
|
|||||||
start = timer()
|
start = timer()
|
||||||
_LOGGER.info("Setting up %s", domain)
|
_LOGGER.info("Setting up %s", domain)
|
||||||
|
|
||||||
try:
|
|
||||||
component = integration.get_component()
|
|
||||||
except ImportError:
|
|
||||||
log_error("Unable to import component", False)
|
|
||||||
return False
|
|
||||||
|
|
||||||
if hasattr(component, "PLATFORM_SCHEMA"):
|
if hasattr(component, "PLATFORM_SCHEMA"):
|
||||||
# Entity components have their own warning
|
# Entity components have their own warning
|
||||||
warn_task = None
|
warn_task = None
|
||||||
|
@ -456,7 +456,7 @@ enocean==0.50
|
|||||||
enturclient==0.2.0
|
enturclient==0.2.0
|
||||||
|
|
||||||
# homeassistant.components.environment_canada
|
# homeassistant.components.environment_canada
|
||||||
env_canada==0.0.27
|
env_canada==0.0.29
|
||||||
|
|
||||||
# homeassistant.components.envirophat
|
# homeassistant.components.envirophat
|
||||||
# envirophat==0.0.6
|
# envirophat==0.0.6
|
||||||
@ -622,7 +622,7 @@ hass-nabucasa==0.22
|
|||||||
hbmqtt==0.9.5
|
hbmqtt==0.9.5
|
||||||
|
|
||||||
# homeassistant.components.jewish_calendar
|
# homeassistant.components.jewish_calendar
|
||||||
hdate==0.9.1
|
hdate==0.9.3
|
||||||
|
|
||||||
# homeassistant.components.heatmiser
|
# homeassistant.components.heatmiser
|
||||||
heatmiserV3==0.9.1
|
heatmiserV3==0.9.1
|
||||||
@ -1328,7 +1328,7 @@ pymsteams==0.1.12
|
|||||||
pymusiccast==0.1.6
|
pymusiccast==0.1.6
|
||||||
|
|
||||||
# homeassistant.components.myq
|
# homeassistant.components.myq
|
||||||
pymyq==2.0.0
|
pymyq==2.0.1
|
||||||
|
|
||||||
# homeassistant.components.mysensors
|
# homeassistant.components.mysensors
|
||||||
pymysensors==0.18.0
|
pymysensors==0.18.0
|
||||||
@ -1423,7 +1423,7 @@ pyrepetier==3.0.5
|
|||||||
pysabnzbd==1.1.0
|
pysabnzbd==1.1.0
|
||||||
|
|
||||||
# homeassistant.components.saj
|
# homeassistant.components.saj
|
||||||
pysaj==0.0.12
|
pysaj==0.0.13
|
||||||
|
|
||||||
# homeassistant.components.sony_projector
|
# homeassistant.components.sony_projector
|
||||||
pysdcp==1
|
pysdcp==1
|
||||||
@ -1564,7 +1564,7 @@ python-ripple-api==0.0.3
|
|||||||
python-sochain-api==0.0.2
|
python-sochain-api==0.0.2
|
||||||
|
|
||||||
# homeassistant.components.songpal
|
# homeassistant.components.songpal
|
||||||
python-songpal==0.11.1
|
python-songpal==0.11.2
|
||||||
|
|
||||||
# homeassistant.components.synologydsm
|
# homeassistant.components.synologydsm
|
||||||
python-synology==0.2.0
|
python-synology==0.2.0
|
||||||
|
@ -230,7 +230,7 @@ hass-nabucasa==0.22
|
|||||||
hbmqtt==0.9.5
|
hbmqtt==0.9.5
|
||||||
|
|
||||||
# homeassistant.components.jewish_calendar
|
# homeassistant.components.jewish_calendar
|
||||||
hdate==0.9.1
|
hdate==0.9.3
|
||||||
|
|
||||||
# homeassistant.components.here_travel_time
|
# homeassistant.components.here_travel_time
|
||||||
herepy==0.6.3.1
|
herepy==0.6.3.1
|
||||||
|
@ -112,7 +112,17 @@ async def test_install_missing_package(hass):
|
|||||||
async def test_get_integration_with_requirements(hass):
|
async def test_get_integration_with_requirements(hass):
|
||||||
"""Check getting an integration with loaded requirements."""
|
"""Check getting an integration with loaded requirements."""
|
||||||
hass.config.skip_pip = False
|
hass.config.skip_pip = False
|
||||||
mock_integration(hass, MockModule("test_component", requirements=["hello==1.0.0"]))
|
mock_integration(
|
||||||
|
hass, MockModule("test_component_dep", requirements=["test-comp-dep==1.0.0"])
|
||||||
|
)
|
||||||
|
mock_integration(
|
||||||
|
hass,
|
||||||
|
MockModule(
|
||||||
|
"test_component",
|
||||||
|
requirements=["test-comp==1.0.0"],
|
||||||
|
dependencies=["test_component_dep"],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.util.package.is_installed", return_value=False
|
"homeassistant.util.package.is_installed", return_value=False
|
||||||
@ -126,8 +136,13 @@ async def test_get_integration_with_requirements(hass):
|
|||||||
assert integration
|
assert integration
|
||||||
assert integration.domain == "test_component"
|
assert integration.domain == "test_component"
|
||||||
|
|
||||||
assert len(mock_is_installed.mock_calls) == 1
|
assert len(mock_is_installed.mock_calls) == 2
|
||||||
assert len(mock_inst.mock_calls) == 1
|
assert mock_is_installed.mock_calls[0][1][0] == "test-comp==1.0.0"
|
||||||
|
assert mock_is_installed.mock_calls[1][1][0] == "test-comp-dep==1.0.0"
|
||||||
|
|
||||||
|
assert len(mock_inst.mock_calls) == 2
|
||||||
|
assert mock_inst.mock_calls[0][1][0] == "test-comp==1.0.0"
|
||||||
|
assert mock_inst.mock_calls[1][1][0] == "test-comp-dep==1.0.0"
|
||||||
|
|
||||||
|
|
||||||
async def test_install_with_wheels_index(hass):
|
async def test_install_with_wheels_index(hass):
|
||||||
|
@ -527,3 +527,11 @@ async def test_when_setup_already_loaded(hass):
|
|||||||
setup.async_when_setup(hass, "test", mock_callback)
|
setup.async_when_setup(hass, "test", mock_callback)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert calls == ["test", "test"]
|
assert calls == ["test", "test"]
|
||||||
|
|
||||||
|
|
||||||
|
async def test_setup_import_blows_up(hass):
|
||||||
|
"""Test that we handle it correctly when importing integration blows up."""
|
||||||
|
with mock.patch(
|
||||||
|
"homeassistant.loader.Integration.get_component", side_effect=ValueError
|
||||||
|
):
|
||||||
|
assert not await setup.async_setup_component(hass, "sun", {})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user