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

2021.12.8 #63412

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 28 commits into from
Jan 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
eb91941
Update version of iZone library to add some bug fixes (#61548)
Swamp-Ig Dec 20, 2021
69b1a93
Fix Tuya vacuum display battery level (#61643)
dougiteixeira Jan 2, 2022
e3d2993
Update no_ip URL (#62477)
fabaff Jan 4, 2022
76d5e2e
Do not create a number LED brightness entity for Xiaomi Miio devices …
bieniu Jan 4, 2022
b78e44d
Fix local_ip handling in KNX options flow (#62969)
marvin-w Dec 30, 2021
1f81f84
Fix reporting correct colormode for 3rd party Hue lights (#63015)
marcelveldt Dec 29, 2021
5e42f95
Hue allow per-device availability override (#63025)
marcelveldt Dec 31, 2021
17dbdbb
Bump pyatmo to 6.2.1 (#62291)
cgtobi Dec 20, 2021
30620ef
Bump pyatmo to v6.2.2 (#63053)
cgtobi Dec 30, 2021
17e5766
Ignore serial number "blank" from NUT (#63066)
ollo69 Dec 30, 2021
c4d871a
Bump greeclimate to 1.0.1 (#63092)
cmroche Dec 30, 2021
9df40d7
Fix Shelly error fetching device triggers for sleeping devices (#63103)
thecode Dec 31, 2021
e39cf1a
Fix systemmonitor CPU temp for Armbian on PineA64 (#63111)
ktaragorn Jan 2, 2022
4c52b97
Fix CO/CO2 sensors mixup in Google Assistant (#63152)
ryborg Jan 4, 2022
60f4521
Bump flux_led to 0.27.28 to fix missing white channel on SK6812RGBW s…
bdraco Jan 2, 2022
5490a65
Add default Fronius logger model for v0 API (#63184)
8000 trdischat Jan 2, 2022
5910460
Prevent doorbird integration from overloading the device on startup (…
bdraco Jan 3, 2022
ed4f0a5
Bump flux_led to 0.27.32 to fix incorrect strip order on A2 devices (…
bdraco Jan 3, 2022
f2f0fba
Sisyphus: Fix bad super call (#63327)
balloob Jan 3, 2022
39cfc1c
Fix status type in Shelly climate platform (#63347)
bieniu Jan 4, 2022
4d9d186
Bump micloud to 0.5 (#63348)
starkillerOG Jan 4, 2022
9126125
Work around ingress glitch with 304 responses (#63355)
masto Jan 4, 2022
082c9c3
Fix Hue grouped light color_mode calculation (#63374)
marcelveldt Jan 4, 2022
27a74d2
Fix missing timezone in GTFS timestamp sensor (#63401)
frenck Jan 4, 2022
599c624
Bumped version to 2021.12.8
balloob Jan 4, 2022
41b4319
Fix merge conflicts
balloob Jan 4, 2022
888abd6
Handle missing monitored users in Plex options (#63411)
jjlawren Jan 4, 2022
53b3369
Handle no enabled ipv4 addresses in the network integration (#63416)
bdraco Jan 5, 2022
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
10 changes: 6 additions & 4 deletions homeassistant/components/doorbird/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,10 @@ def register_events(self, hass):
if self.custom_url is not None:
hass_url = self.custom_url

favorites = self.device.favorites()

for event in self.doorstation_events:
self._register_event(hass_url, event)
self._register_event(hass_url, event, favs=favorites)

_LOGGER.info("Successfully registered URL for %s on %s", event, self.name)

Expand All @@ -261,15 +263,15 @@ def slug(self):
def _get_event_name(self, event):
return f"{self.slug}_{event}"

def _register_event(self, hass_url, event):
def _register_event(self, hass_url, event, favs=None):
"""Add a schedule entry in the device for a sensor."""
url = f"{hass_url}{API_URL}/{event}?token={self._token}"

# Register HA URL as webhook if not already, then get the ID
if not self.webhook_is_registered(url):
if not self.webhook_is_registered(url, favs=favs):
self.device.change_favorite("http", f"Home Assistant ({event})", url)

if not self.get_webhook_id(url):
if not self.get_webhook_id(url, favs=favs):
_LOGGER.warning(
'Could not find favorite for URL "%s". ' 'Skipping sensor "%s"',
url,
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.27.21"],
"requirements": ["flux_led==0.27.32"],
"quality_scale": "platinum",
"codeowners": ["@icemanch"],
"iot_class": "local_push",
Expand Down
5 changes: 4 additions & 1 deletion homeassistant/components/fronius/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,10 @@ async def _create_solar_net_device(self) -> DeviceInfo:
)
if self.logger_coordinator:
_logger_info = self.logger_coordinator.data[SOLAR_NET_ID_SYSTEM]
solar_net_device[ATTR_MODEL] = _logger_info["product_type"]["value"]
# API v0 doesn't provide product_type
solar_net_device[ATTR_MODEL] = _logger_info.get("product_type", {}).get(
"value", "Datalogger Web"
)
solar_net_device[ATTR_SW_VERSION] = _logger_info["software_version"][
"value"
]
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/google_assistant/trait.py
Original file line number Diff line number Diff line change
Expand Up @@ -2296,8 +2296,8 @@ class SensorStateTrait(_Trait):

sensor_types = {
sensor.DEVICE_CLASS_AQI: ("AirQuality", "AQI"),
sensor.DEVICE_CLASS_CO: ("CarbonDioxideLevel", "PARTS_PER_MILLION"),
sensor.DEVICE_CLASS_CO2: ("CarbonMonoxideLevel", "PARTS_PER_MILLION"),
sensor.DEVICE_CLASS_CO: ("CarbonMonoxideLevel", "PARTS_PER_MILLION"),
sensor.DEVICE_CLASS_CO2: ("CarbonDioxideLevel", "PARTS_PER_MILLION"),
sensor.DEVICE_CLASS_PM25: ("PM2.5", "MICROGRAMS_PER_CUBIC_METER"),
sensor.DEVICE_CLASS_PM10: ("PM10", "MICROGRAMS_PER_CUBIC_METER"),
sensor.DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS: (
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/gree/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "Gree Climate",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/gree",
"requirements": ["greeclimate==0.12.5"],
"requirements": ["greeclimate==1.0.1"],
"codeowners": ["@cmroche"],
"iot_class": "local_polling"
}
4 changes: 3 additions & 1 deletion homeassistant/components/gtfs/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,9 @@ def update(self) -> None:
if not self._departure:
self._state = None
else:
self._state = self._departure["departure_time"]
self._state = self._departure["departure_time"].replace(
tzinfo=dt_util.UTC
)

# Fetch trip and route details once, unless updated
if not self._departure:
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/hassio/ingress.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ async def _handle_request(
if (
hdrs.CONTENT_LENGTH in result.headers
and int(result.headers.get(hdrs.CONTENT_LENGTH, 0)) < 4194000
):
) or result.status in (204, 304):
# Return Response
body = await result.read()
return web.Response(
Expand Down
66 changes: 53 additions & 13 deletions homeassistant/components/hue/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@
from homeassistant.const import CONF_API_KEY, CONF_HOST
from homeassistant.core import callback
from homeassistant.data_entry_flow import FlowResult
from homeassistant.helpers import aiohttp_client
from homeassistant.helpers import aiohttp_client, device_registry
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.typing import ConfigType

from .const import (
CONF_ALLOW_HUE_GROUPS,
CONF_ALLOW_UNREACHABLE,
CONF_API_VERSION,
CONF_IGNORE_AVAILABILITY,
DEFAULT_ALLOW_HUE_GROUPS,
DEFAULT_ALLOW_UNREACHABLE,
DOMAIN,
Expand All @@ -46,17 +48,11 @@ class HueFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
@callback
def async_get_options_flow(
config_entry: config_entries.ConfigEntry,
) -> HueOptionsFlowHandler:
) -> HueV1OptionsFlowHandler | HueV2OptionsFlowHandler:
"""Get the options flow for this handler."""
return HueOptionsFlowHandler(config_entry)

@classmethod
@callback
def async_supports_options_flow(
cls, config_entry: config_entries.ConfigEntry
) -> bool:
"""Return options flow support for this handler."""
return config_entry.data.get(CONF_API_VERSION, 1) == 1
if config_entry.data.get(CONF_API_VERSION, 1) == 1:
return HueV1OptionsFlowHandler(config_entry)
return HueV2OptionsFlowHandler(config_entry)

def __init__(self) -> None:
"""Initialize the Hue flow."""
Expand Down Expand Up @@ -288,8 +284,8 @@ async def async_step_import(self, import_info: ConfigType) -> FlowResult:
return await self.async_step_link()


class HueOptionsFlowHandler(config_entries.OptionsFlow):
"""Handle Hue options."""
class HueV1OptionsFlowHandler(config_entries.OptionsFlow):
"""Handle Hue options for V1 implementation."""

def __init__(self, config_entry: config_entries.ConfigEntry) -> None:
"""Initialize Hue options flow."""
Expand Down Expand Up @@ -319,3 +315,47 @@ async def async_step_init(self, user_input: ConfigType | None = None) -> FlowRes
}
),
)


class HueV2OptionsFlowHandler(config_entries.OptionsFlow):
"""Handle Hue options for V2 implementation."""

def __init__(self, config_entry: config_entries.ConfigEntry) -> None:
"""Initialize Hue options flow."""
self.config_entry = config_entry

async def async_step_init(self, user_input: ConfigType | None = None) -> FlowResult:
"""Manage Hue options."""
if user_input is not None:
return self.async_create_entry(title="", data=user_input)

# create a list of Hue device ID's that the user can select
# to ignore availability status
dev_reg = device_registry.async_get(self.hass)
entries = device_registry.async_entries_for_config_entry(
dev_reg, self.config_entry.entry_id
)
dev_ids = {
identifier[1]: entry.name
for entry in entries
for identifier in entry.identifiers
if identifier[0] == DOMAIN
}
# filter any non existing device id's from the list
cur_ids = [
item
for item in self.config_entry.options.get(CONF_IGNORE_AVAILABILITY, [])
if item in dev_ids
]

return self.async_show_form(
step_id="init",
data_schema=vol.Schema(
{
vol.Optional(
CONF_IGNORE_AVAILABILITY,
default=cur_ids,
): cv.multi_select(dev_ids),
}
),
)
1 change: 1 addition & 0 deletions homeassistant/components/hue/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
DOMAIN = "hue"

CONF_API_VERSION = "api_version"
CONF_IGNORE_AVAILABILITY = "ignore_availability"

CONF_SUBTYPE = "subtype"

Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/hue/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@
"data": {
"allow_hue_groups": "Allow Hue groups",
"allow_hue_scenes": "Allow Hue scenes",
"allow_unreachable": "Allow unreachable bulbs to report their state correctly"
"allow_unreachable": "Allow unreachable bulbs to report their state correctly",
"ignore_availability": "Ignore connectivity status for the given devices"
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/hue/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@
"data": {
"allow_hue_groups": "Allow Hue groups",
"allow_hue_scenes": "Allow Hue scenes",
"allow_unreachable": "Allow unreachable bulbs to report their state correctly"
"allow_unreachable": "Allow unreachable bulbs to report their state correctly",
"ignore_availability": "Ignore connectivity status for the given devices"
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/hue/translations/nl.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@
"data": {
"allow_hue_groups": "Sta Hue-groepen toe",
"allow_hue_scenes": "Sta Hue sc\u00e8nes toe",
"allow_unreachable": "Onbereikbare lampen toestaan hun status correct te melden"
"allow_unreachable": "Onbereikbare lampen toestaan hun status correct te melden",
"ignore_availability": "Negeer beschikbaarheid status voor deze apparaten"
}
}
}
Expand Down
62 changes: 37 additions & 25 deletions homeassistant/components/hue/v2/entity.py
10000
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from homeassistant.helpers.entity_registry import async_get as async_get_entity_registry

from ..bridge import HueBridge
from ..const import DOMAIN
from ..const import CONF_IGNORE_AVAILABILITY, DOMAIN

RESOURCE_TYPE_NAMES = {
# a simple mapping of hue resource type to Hass name
Expand Down Expand Up @@ -71,7 +71,7 @@ def name(self) -> str:

async def async_added_to_hass(self) -> None:
"""Call when entity is added."""
self._check_availability_workaround()
self._check_availability()
# Add value_changed callbacks.
self.async_on_remove(
self.controller.subscribe(
Expand All @@ -80,7 +80,7 @@ async def async_added_to_hass(self) -> None:
(EventType.RESOURCE_UPDATED, EventType.RESOURCE_DELETED),
)
)
# also subscribe to device update event to catch devicer changes (e.g. name)
# also subscribe to device update event to catch device changes (e.g. name)
if self.device is None:
return
self.async_on_remove(
Expand All @@ -92,25 +92,27 @@ async def async_added_to_hass(self) -> None:
)
# subscribe to zigbee_connectivity to catch availability changes
if zigbee := self.bridge.api.devices.get_zigbee_connectivity(self.device.id):
self.bridge.api.sensors.zigbee_connectivity.subscribe(
self._handle_event,
zigbee.id,
EventType.RESOURCE_UPDATED,
self.async_on_remove(
self.bridge.api.sensors.zigbee_connectivity.subscribe(
self._handle_event,
zigbee.id,
EventType.RESOURCE_UPDATED,
)
)

@property
def available(self) -> bool:
"""Return entity availability."""
# entities without a device attached should be always available
if self.device is None:
# entities without a device attached should be always available
return True
# the zigbee connectivity sensor itself should be always available
if self.resource.type == ResourceTypes.ZIGBEE_CONNECTIVITY:
# the zigbee connectivity sensor itself should be always available
return True
if self._ignore_availability:
return True
# all device-attached entities get availability from the zigbee connectivity
if zigbee := self.bridge.api.devices.get_zigbee_connectivity(self.device.id):
# all device-attached entities get availability from the zigbee connectivity
return zigbee.status == ConnectivityServiceStatus.CONNECTED
return True

Expand All @@ -130,30 +132,41 @@ def _handle_event(self, event_type: EventType, resource: CLIPResource) -> None:
ent_reg.async_remove(self.entity_id)
else:
self.logger.debug("Received status update for %s", self.entity_id)
self._check_availability_workaround()
self._check_availability()
self.on_update()
self.async_write_ha_state()

@callback
def _check_availability_workaround(self):
def _check_availability(self):
"""Check availability of the device."""
if self.resource.type != ResourceTypes.LIGHT:
return
# return if we already processed this entity
if self._ignore_availability is not None:
# already processed
return
# only do the availability check for entities connected to a device
if self.device is None:
return
# ignore availability if user added device to ignore list
if self.device.id in self.bridge.config_entry.options.get(
CONF_IGNORE_AVAILABILITY, []
):
self._ignore_availability = True
self.logger.info(
"Device %s is configured to ignore availability status. ",
self.name,
)
return
# certified products (normally) report their state correctly
# no need for workaround/reporting
if self.device.product_data.certified:
# certified products report their state correctly
self._ignore_availability = False
return
# some (3th party) Hue lights report their connection status incorrectly
# causing the zigbee availability to report as disconnected while in fact
# it can be controlled. Although this is in fact something the device manufacturer
# should fix, we work around it here. If the light is reported unavailable
# it can be controlled. If the light is reported unavailable
# by the zigbee connectivity but the state changes its considered as a
# malfunctioning device and we report it.
# while the user should actually fix this issue instead of ignoring it, we
# ignore the availability for this light from this point.
# While the user should actually fix this issue, we allow to
# ignore the availability for this light/device from the config options.
cur_state = self.resource.on.on
if self._last_state is None:
self._last_state = cur_state
Expand All @@ -166,9 +179,10 @@ def _check_availability_workaround(self):
# the device state changed from on->off or off->on
# while it was reported as not connected!
self.logger.warning(
"Light %s changed state while reported as disconnected. "
"This might be an indicator that routing is not working for this device. "
"Home Assistant will ignore availability for this light from now on. "
"Device %s changed state while reported as disconnected. "
"This might be an indicator that routing is not working for this device "
"or the device is having connectivity issues. "
"You can disable availability reporting for this device in the Hue options. "
"Device details: %s - %s (%s) fw: %s",
self.name,
self.device.product_data.manufacturer_name,
E 10000 xpand All @@ -178,6 +192,4 @@ def _check_availability_workaround(self):
)
# do we want to store this in some persistent storage?
self._ignore_availability = True
else:
self._ignore_availability = False
self._last_state = cur_state
9 changes: 5 additions & 4 deletions homeassistant/components/hue/v2/group.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
from aiohue.v2 import HueBridgeV2
from aiohue.v2.controllers.events import EventType
from aiohue.v2.controllers.groups import GroupedLight, Room, Zone
from aiohue.v2.models.feature import AlertEffectType

from homeassistant.components.light import (
ATTR_BRIGHTNESS,
Expand Down Expand Up @@ -103,7 +102,7 @@ def __init__(

# Entities for Hue groups are disabled by default
# unless they were enabled in old version (legacy option)
self._attr_entity_registry_enabled_default = bridge.config_entry.data.get(
self._attr_entity_registry_enabled_default = bridge.config_entry.options.get(
CONF_ALLOW_HUE_GROUPS, False
)

Expand Down Expand Up @@ -193,7 +192,6 @@ async def async_turn_on(self, **kwargs: Any) -> None:
color_xy=xy_color if light.supports_color else None,
color_temp=color_temp if light.supports_color_temperature else None,
transition_time=transition,
alert=AlertEffectType.BREATHE if flash is not None else None,
allowed_errors=ALLOWED_ERRORS,
)
for light in self.controller.get_lights(self.resource.id)
Expand Down Expand Up @@ -300,7 +298,10 @@ def _update_values(self) -> None:
supported_color_modes.add(COLOR_MODE_ONOFF)
self._attr_supported_color_modes = supported_color_modes
# pick a winner for the current colormode
if lights_in_colortemp_mode == lights_with_color_temp_support:
if (
lights_with_color_temp_support > 0
and lights_in_colortemp_mode == lights_with_color_temp_support
):
self._attr_color_mode = COLOR_MODE_COLOR_TEMP
elif lights_with_color_support > 0:
self._attr_color_mode = COLOR_MODE_XY
Expand Down
Loading
0