10000 2021.12.4 by balloob · Pull Request #62366 · home-assistant/core · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

2021.12.4 #62366

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 36 commits into from
Dec 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
c507c72
Honeywell unique id fix (#59393)
rdfurman Dec 14, 2021
22867ac
Add vicare strings (#61593)
oischinger Dec 17, 2021
735deff
Fix "vevent" KeyError in caldav component (#61718)
jkuettner Dec 17, 2021
a87ed13
Silently retry Fronius inverter endpoint 2 times (#61826)
farmio Dec 19, 2021
4e96ff7
Avoid setting nexia humidity to the same value since it causes the ap…
bdraco Dec 19, 2021
895dcaf
Force Lyric token refresh on first authentication failure (#62100)
timmo001 Dec 17, 2021
9a0f42f
Bump pydexcom to 0.2.2 (#62207)
gagebenne Dec 19, 2021
57b7b28
Fix spurious RainMachine config entry reload (#62215)
bachya Dec 17, 2021
f665c4e
Fix bug in which SimpliSafe websocket won't reconnect on error (#62241)
bachya Dec 19, 2021
bc2949e
bump pynetgear to 0.8.0 (#62261)
starkillerOG Dec 18, 2021
2395c75
Fix logging for Shelly climate platform (#62264)
chemelli74 Dec 19, 2021
cd65aae
Upgrade tailscale to 0.1.6 (#62267)
frenck Dec 18, 2021
4efa3b6
Fix fitbit no SSL URL handling (#62270)
MartinHjelmare Dec 18, 2021
3fde6bf
Fix Non-thread-safe operation in rflink binary_sensor (#62286)
bdraco Dec 18, 2021
c1d0fe9 8000
Fix Non-thread-safe operation in zwave node_added (#62287)
bdraco Dec 18, 2021
dc4659b
Bump flux_led to 0.27.8 to fix discovery of older devices (#62292)
bdraco Dec 19, 2021
311ebd4
Bump async-upnp-client to 0.23.0 (#62223)
Flameeyes Dec 17, 2021
b327628
Update async-upnp-client library to 0.23.1 (#62298)
chishm Dec 19, 2021
5f2a228
Bump ring to 0.7.2 (#62299)
balloob Dec 19, 2021
7db1618
Fix missing brightness for Velbus entities (#62314)
wlcrs Dec 19, 2021
7c92577
Fix velbus climate current temp (#62329)
cereal2nd Dec 19, 2021
beb5a99
Ensure existing SimpliSafe websocket tasks are cancelled appropriatel…
bachya Dec 19, 2021
bfd8579
Bump pywemo==0.7.0 (#62360)
esev Dec 20, 2021
eb4b041
Bump voluptuous_serialize to 2.5.0 (#62363)
balloob Dec 20, 2021
4802e4e
Bumped version to 2021.12.4
balloob Dec 20, 2021
dcc08a0
Don't use the homeassistant media app when casting media (#62385)
emontnemery Dec 20, 2021
7ec369d
Bump brunt to 1.1.0 (#62386)
eavanvalkenburg Dec 20, 2021
e80f4e0
Update frontend to 20211220.0 (#62389)
bramkragten Dec 20, 2021
b8f8b30
Bump pychromecast to 10.2.2 (#62390)
emontnemery Dec 20, 2021
5a2bc8e
Update xknx to 0.18.14 (#62411)
farmio Dec 20, 2021
d90c107
Invalidate CI cache when bumping dependencies, part 2 (#62412)
frenck Dec 20, 2021
520c341
Invalidate CI cache when bumping dependencies (#62394)
frenck Dec 20, 2021
836d8a6
Make it possible to turn on audio only google cast devices (#62420)
emontnemery Dec 20, 2021
a1fc223
Bump bimmer_connected to 0.8.7 (#62435)
rikroe Dec 20, 2021
1f0c13f
bump aiohue to 3.0.7 (#62444)
marcelveldt Dec 20, 2021
5e0ea9f
Change Hue availability blacklist logic a bit (#62446)
marcelveldt Dec 21, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 18 additions & 8 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -155,10 +155,15 @@ jobs:
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
steps.generate-python-key.outputs.key }}
restore-keys: |
${{ runner.os }}-${{ steps.python.outputs.python-version }}-base-venv-${{ env.CACHE_VERSION }}-${{ hashFiles('requirements.txt') }}-${{ hashFiles('requirements_test.txt') }}-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-base-venv-${{ env.CACHE_VERSION }}-${{ hashFiles('requirements.txt') }}-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-base-venv-${{ env.CACHE_VERSION }}-
# Temporary disabling the restore of environments when bumping
# a dependency. It seems that we are experiencing issues with
# restoring environments in GitHub Actions, although unclear why.
# First attempt: https://github.com/home-assistant/core/pull/62383
#
# restore-keys: |
# ${{ runner.os }}-${{ steps.python.outputs.python-version }}-base-venv-${{ env.CACHE_VERSION }}-${{ hashFiles('requirements.txt') }}-${{ hashFiles('requirements_test.txt') }}-
# ${{ runner.os }}-${{ steps.python.outputs.python-version }}-base-venv-${{ env.CACHE_VERSION }}-${{ hashFiles('requirements.txt') }}-
# ${{ runner.os }}-${{ steps.python.outputs.python-version }}-base-venv-${{ env.CACHE_VERSION }}-
- name: Create Python virtual environment
if: steps.cache-venv.outputs.cache-hit != 'true'
run: |
Expand Down Expand Up @@ -517,10 +522,15 @@ jobs:
key: >-
${{ runner.os }}-${{ matrix.python-version }}-${{
steps.generate-python-key.outputs.key }}
restore-keys: |
${{ runner.os }}-${{ matrix.python-version }}-venv-${{ env.CACHE_VERSION }}-${{ hashFiles('requirements_test.txt') }}-${{ hashFiles('requirements_all.txt') }}-
${{ runner.os }}-${{ matrix.python-version }}-venv-${{ env.CACHE_VERSION }}-${{ hashFiles('requirements_test.txt') }}-
${{ runner.os }}-${{ matrix.python-version }}-venv-${{ env.CACHE_VERSION }}-
# Temporary disabling the restore of environments when bumping
# a dependency. It seems that we are experiencing issues with
# restoring environments in GitHub Actions, although unclear why.
# First attempt: https://github.com/home-assistant/core/pull/62383
#
# restore-keys: |
# ${{ runner.os }}-${{ matrix.python-version }}-venv-${{ env.CACHE_VERSION }}-${{ hashFiles('requirements_test.txt') }}-${{ hashFiles('requirements_all.txt') }}-
# ${{ runner.os }}-${{ matrix.python-version }}-venv-${{ env.CACHE_VERSION }}-${{ hashFiles('requirements_test.txt') }}-
# ${{ runner.os }}-${{ matrix.python-version }}-venv-${{ env.CACHE_VERSION }}-
- name: Create full Python ${{ matrix.python-version }} virtual environment
if: steps.cache-venv.outputs.cache-hit != 'true'
run: |
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/bmw_connected_drive/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"domain": "bmw_connected_drive",
"name": "BMW Connected Drive",
"documentation": "https://www.home-assistant.io/integrations/bmw_connected_drive",
"requirements": ["bimmer_connected==0.8.5"],
"requirements": ["bimmer_connected==0.8.7"],
"codeowners": ["@gerard33", "@rikroe"],
"config_flow": true,
"iot_class": "cloud_polling"
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/brunt/__init__.py
10000
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ async def async_update_data():
try:
async with async_timeout.timeout(10):
things = await bapi.async_get_things(force=True)
return {thing.SERIAL: thing for thing in things}
return {thing.serial: thing for thing in things}
except ServerDisconnectedError as err:
raise UpdateFailed(f"Error communicating with API: {err}") from err
except ClientResponseError as err:
Expand Down
21 changes: 9 additions & 12 deletions homeassistant/components/brunt/cover.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def __init__(

self._remove_update_listener = None

self._attr_name = self._thing.NAME
self._attr_name = self._thing.name
self._attr_device_class = DEVICE_CLASS_SHADE
self._attr_supported_features = COVER_FEATURES
self._attr_attribution = ATTRIBUTION
Expand All @@ -109,8 +109,8 @@ def __init__(
name=self._attr_name,
via_device=(DOMAIN, self._entry_id),
manufacturer="Brunt",
sw_version=self._thing.FW_VERSION,
model=self._thing.MODEL,
sw_version=self._thing.fw_version,
model=self._thing.model,
)

async def async_added_to_hass(self) -> None:
Expand All @@ -127,8 +127,7 @@ def current_cover_position(self) -> int | None:

None is unknown, 0 is closed, 100 is fully open.
"""
pos = self.coordinator.data[self.unique_id].currentPosition
return int(pos) if pos is not None else None
return self.coordinator.data[self.unique_id].current_position

@property
def request_cover_position(self) -> int | None:
Expand All @@ -139,8 +138,7 @@ def request_cover_position(self) -> int | None:
to Brunt, at times there is a diff of 1 to current
None is unknown, 0 is closed, 100 is fully open.
"""
pos = self.coordinator.data[self.unique_id].requestPosition
return int(pos) if pos is not None else None
return self.coordinator.data[self.unique_id].request_position

@property
def move_state(self) -> int | None:
Expand All @@ -149,8 +147,7 @@ def move_state(self) -> int | None:

None is unknown, 0 when stopped, 1 when opening, 2 when closing
"""
mov = self.coordinator.data[self.unique_id].moveState
return int(mov) if mov is not None else None
return self.coordinator.data[self.unique_id].move_state

@property
def is_opening(self) -> bool:
Expand Down Expand Up @@ -190,11 +187,11 @@ async def _async_update_cover(self, position: int) -> None:
"""Set the cover to the new position and wait for the update to be reflected."""
try:
await self._bapi.async_change_request_position(
position, thingUri=self._thing.thingUri
position, thing_uri=self._thing.thing_uri
)
except ClientResponseError as exc:
raise HomeAssistantError(
f"Unable to reposition {self._thing.NAME}"
f"Unable to reposition {self._thing.name}"
) from exc
self.coordinator.update_interval = FAST_INTERVAL
await self.coordinator.async_request_refresh()
Expand All @@ -204,7 +201,7 @@ def _brunt_update_listener(self) -> None:
"""Update the update interval after each refresh."""
if (
self.request_cover_position
== self._bapi.last_requested_positions[self._thing.thingUri]
== self._bapi.last_requested_positions[self._thing.thing_uri]
and self.move_state == 0
):
self.coordinator.update_interval = REGULAR_INTERVAL
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/brunt/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "Brunt Blind Engine",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/brunt",
"requirements": ["brunt==1.0.2"],
"requirements": ["brunt==1.1.0"],
"codeowners": ["@eavanvalkenburg"],
"iot_class": "cloud_polling"
}
6 changes: 6 additions & 0 deletions homeassistant/components/caldav/calendar.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,9 @@ async def async_get_events(self, hass, start_date, end_date):
)
event_list = []
for event in vevent_list:
if not hasattr(event.instance, "vevent"):
_LOGGER.warning("Skipped event with missing 'vevent' property")
continue
vevent = event.instance.vevent
if not self.is_matching(vevent, self.search):
continue
Expand Down Expand Up @@ -198,6 +201,9 @@ def update(self):
# and they would not be properly parsed using their original start/end dates.
new_events = []
for event in results:
if not hasattr(event.instance, "vevent"):
_LOGGER.warning("Skipped event with missing 'vevent' property")
continue
vevent = event.instance.vevent
for start_dt in vevent.getrruleset() or []:
_start_of_today = start_of_today
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/cast/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "Google Cast",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/cast",
"requirements": ["pychromecast==10.2.1"],
"requirements": ["pychromecast==10.2.2"],
"after_dependencies": [
"cloud",
"http",
Expand Down
15 changes: 9 additions & 6 deletions homeassistant/components/cast/media_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,11 +395,14 @@ def turn_on(self):
return

if self._chromecast.app_id is not None:
# Quit the previous app before starting splash screen
# Quit the previous app before starting splash screen or media player
self._chromecast.quit_app()

# The only way we can turn the Chromecast is on is by launching an app
self._chromecast.play_media(CAST_SPLASH, pychromecast.STREAM_TYPE_BUFFERED)
if self._chromecast.cast_type == pychromecast.const.CAST_TYPE_CHROMECAST:
self._chromecast.play_media(CAST_SPLASH, pychromecast.STREAM_TYPE_BUFFERED)
else:
self._chromecast.start_app(pychromecast.config.APP_MEDIA_RECEIVER)

def turn_off(self):
"""Turn off the cast device."""
Expand Down Expand Up @@ -526,7 +529,7 @@ def play_media(self, media_type, media_id, **kwargs):
controller.play_media(media)
else:
app_data = {"media_id": media_id, "media_type": media_type, **extra}
quick_play(self._chromecast, "homeassistant_media", app_data)
quick_play(self._chromecast, "default_media_receiver", app_data)

def _media_status(self):
"""
Expand Down Expand Up @@ -674,9 +677,9 @@ def supported_features(self):
support = SUPPORT_CAST
media_status = self._media_status()[0]

if (
self._chromecast
and self._chromecast.cast_type == pychromecast.const.CAST_TYPE_CHROMECAST
if self._chromecast and self._chromecast.cast_type in (
pychromecast.const.CAST_TYPE_CHROMECAST,
pychromecast.const.CAST_TYPE_AUDIO,
):
support |= SUPPORT_TURN_ON

Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/dexcom/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "Dexcom",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/dexcom",
"requirements": ["pydexcom==0.2.1"],
"requirements": ["pydexcom==0.2.2"],
"codeowners": ["@gagebenne"],
"iot_class": "cloud_polling"
}
2 changes: 1 addition & 1 deletion homeassistant/components/dlna_dmr/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "DLNA Digital Media Renderer",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/dlna_dmr",
"requirements": ["async-upnp-client==0.22.12"],
"requirements": ["async-upnp-client==0.23.1"],
"dependencies": ["ssdp"],
"ssdp": [
{
Expand Down
9 changes: 5 additions & 4 deletions homeassistant/components/fitbit/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,11 @@ def fitbit_configuration_callback(fields: list[dict[str, str]]) -> None:
Then come back here and hit the below button.
"""
except NoURLAvailableError:
error_msg = """Could not find a SSL enabled URL for your Home Assistant instance.
Fitbit requires that your Home Assistant instance is accessible via HTTPS.
"""
configurator.notify_errors(_CONFIGURING["fitbit"], error_msg)
_LOGGER.error(
"Could not find an SSL enabled URL for your Home Assistant instance. "
"Fitbit requires that your Home Assistant instance is accessible via HTTPS"
)
return

submit = "I have saved my Client ID and Client Secret into fitbit.conf."

Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/flux_led/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "Flux LED/MagicHome",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/flux_led",
"requirements": ["flux_led==0.26.15"],
"requirements": ["flux_led==0.27.8"],
"quality_scale": "platinum",
"codeowners": ["@icemanch"],
"iot_class": "local_push",
Expand Down
24 changes: 19 additions & 5 deletions homeassistant/components/fronius/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from datetime import timedelta
from typing import TYPE_CHECKING, Any, Dict, TypeVar

from pyfronius import FroniusError
from pyfronius import BadStatusError, FroniusError

from homeassistant.components.sensor import SensorEntityDescription
from homeassistant.core import callback
Expand Down Expand Up @@ -43,6 +43,8 @@ class FroniusCoordinatorBase(
error_interval: timedelta
valid_descriptions: list[SensorEntityDescription]

MAX_FAILED_UPDATES = 3

def __init__(self, *args: Any, solar_net: FroniusSolarNet, **kwargs: Any) -> None:
"""Set up the FroniusCoordinatorBase class."""
self._failed_update_count = 0
Expand All @@ -62,7 +64,7 @@ async def _async_update_data(self) -> dict[SolarNetId, Any]:
data = await self._update_method()
except FroniusError as err:
self._failed_update_count += 1
if self._failed_update_count == 3:
if self._failed_update_count == self.MAX_FAILED_UPDATES:
self.update_interval = self.error_interval
raise UpdateFailed(err) from err

Expand Down Expand Up @@ -116,6 +118,8 @@ class FroniusInverterUpdateCoordinator(FroniusCoordinatorBase):
error_interval = timedelta(minutes=10)
valid_descriptions = INVERTER_ENTITY_DESCRIPTIONS

SILENT_RETRIES = 3

def __init__(
self, *args: Any, inverter_info: FroniusDeviceInfo, **kwargs: Any
) -> None:
Expand All @@ -125,9 +129,19 @@ def __init__(

async def _update_method(self) -> dict[SolarNetId, Any]:
"""Return data per solar net id from pyfronius."""
data = await self.solar_net.fronius.current_inverter_data(
self.inverter_info.solar_net_id
)
# almost 1% of `current_inverter_data` requests on Symo devices result in
# `BadStatusError Code: 8 - LNRequestTimeout` due to flaky internal
# communication between the logger and the inverter.
for silent_retry in range(self.SILENT_RETRIES):
try:
data = await self.solar_net.fronius.current_inverter_data(
self.inverter_info.solar_net_id
)
except BadStatusError as err:
if silent_retry == (self.SILENT_RETRIES - 1):
raise err
continue
break
# wrap a single devices data in a dict with solar_net_id key for
# FroniusCoordinatorBase _async_update_data and add_entities_for_seen_keys
return {self.inverter_info.solar_net_id: data}
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/frontend/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "Home Assistant Frontend",
"documentation": "https://www.home-assistant.io/integrations/frontend",
"requirements": [
"home-assistant-frontend==20211215.0"
"home-assistant-frontend==20211220.0"
],
"dependencies": [
"api",
Expand Down
35 changes: 23 additions & 12 deletions homeassistant/components/honeywell/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,13 @@ async def async_setup_entry(hass, config):
loc_id = config.data.get(CONF_LOC_ID)
dev_id = config.data.get(CONF_DEV_ID)

devices = []
devices = {}

for location in client.locations_by_id.values():
for device in location.devices_by_id.values():
if (not loc_id or location.locationid == loc_id) and (
not dev_id or device.deviceid == dev_id
):
devices.append(device)
if not loc_id or location.locationid == loc_id:
for device in location.devices_by_id.values():
if not dev_id or device.deviceid == dev_id:
devices[device.deviceid] = device

if len(devices) == 0:
_LOGGER.debug("No devices found")
Expand Down Expand Up @@ -107,23 +106,30 @@ async def _retry(self) -> bool:
if self._client is None:
return False

devices = [
refreshed_devices = [
device
for location in self._client.locations_by_id.values()
for device in location.devices_by_id.values()
]

if len(devices) == 0:
_LOGGER.error("Failed to find any devices")
if len(refreshed_devices) == 0:
_LOGGER.error("Failed to find any devices after retry")
return False

self.devices = devices
for updated_device in refreshed_devices:
if updated_device.deviceid in self.devices:
self.devices[updated_device.deviceid] = updated_device
else:
_LOGGER.info(
"New device with ID %s detected, reload the honeywell integration if you want to access it in Home Assistant"
)

await self._hass.config_entries.async_reload(self._config.entry_id)
return True

async def _refresh_devices(self):
"""Refresh each enabled device."""
for device in self.devices:
for device in self.devices.values():
await self._hass.async_add_executor_job(device.refresh)
await asyncio.sleep(UPDATE_LOOP_SLEEP_TIME)

Expand All @@ -143,11 +149,16 @@ async def async_update(self) -> None:
) as exp:
retries -= 1
if retries == 0:
38CC _LOGGER.error(
"Ran out of retry attempts (3 attempts allocated). Error: %s",
exp,
)
raise exp

result = await self._retry()

if not result:
_LOGGER.error("Retry result was empty. Error: %s", exp)
raise exp

_LOGGER.error("SomeComfort update failed, Retrying - Error: %s", exp)
_LOGGER.info("SomeComfort update failed, retrying. Error: %s", exp)
Loading
0