Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
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.24.14"],
"requirements": ["flux_led==0.24.17"],
"quality_scale": "platinum",
"codeowners": ["@icemanch"],
"iot_class": "local_push",
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/fritz/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ def _async_remove_empty_devices(
device_reg = async_get(self.hass)
device_list = async_entries_for_config_entry(device_reg, config_entry.entry_id)
for device_entry in device_list:
if async_entries_for_device(
if not async_entries_for_device(
entity_reg,
device_entry.id,
include_disabled_entities=True,
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==20211103.0"
"home-assistant-frontend==20211108.0"
],
"dependencies": [
"api",
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/guardian/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "Elexa Guardian",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/guardian",
"requirements": ["aioguardian==1.0.8"],
"requirements": ["aioguardian==2021.11.0"],
"zeroconf": ["_api._udp.local."],
"codeowners": ["@bachya"],
"iot_class": "local_polling",
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/mqtt/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "MQTT",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/mqtt",
"requirements": ["paho-mqtt==1.5.1"],
"requirements": ["paho-mqtt==1.6.1"],
"dependencies": ["http"],
"codeowners": ["@emontnemery"],
"iot_class": "local_push"
Expand Down
32 changes: 11 additions & 21 deletions homeassistant/components/recollect_waste/sensor.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,18 @@
"""Support for ReCollect Waste sensors."""
from __future__ import annotations

from datetime import date, datetime, time

from aiorecollect.client import PickupType

from homeassistant.components.sensor import SensorEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
ATTR_ATTRIBUTION,
CONF_FRIENDLY_NAME,
DEVICE_CLASS_TIMESTAMP,
)
from homeassistant.const import ATTR_ATTRIBUTION, CONF_FRIENDLY_NAME, DEVICE_CLASS_DATE
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity,
DataUpdateCoordinator,
)
from homeassistant.util.dt import as_utc

from .const import CONF_PLACE_ID, CONF_SERVICE_ID, DATA_COORDINATOR, DOMAIN

Expand Down Expand Up @@ -47,12 +40,6 @@ def async_get_pickup_type_names(
]


@callback
def async_get_utc_midnight(target_date: date) -> datetime:
"""Get UTC midnight for a given date."""
return as_utc(datetime.combine(target_date, time(0)))


async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
Expand All @@ -64,7 +51,7 @@ async def async_setup_entry(
class ReCollectWasteSensor(CoordinatorEntity, SensorEntity):
"""ReCollect Waste Sensor."""

_attr_device_class = DEVICE_CLASS_TIMESTAMP
_attr_device_class = DEVICE_CLASS_DATE

def __init__(self, coordinator: DataUpdateCoordinator, entry: ConfigEntry) -> None:
"""Initialize the sensor."""
Expand All @@ -91,8 +78,13 @@ async def async_added_to_hass(self) -> None:
@callback
def update_from_latest_data(self) -> None:
"""Update the state."""
pickup_event = self.coordinator.data[0]
next_pickup_event = self.coordinator.data[1]
try:
pickup_event = self.coordinator.data[0]
next_pickup_event = self.coordinator.data[1]
except IndexError:
self._attr_native_value = None
self._attr_extra_state_attributes = {}
return

self._attr_extra_state_attributes.update(
{
Expand All @@ -103,9 +95,7 @@ def update_from_latest_data(self) -> None:
ATTR_NEXT_PICKUP_TYPES: async_get_pickup_type_names(
self._entry, next_pickup_event.pickup_types
),
ATTR_NEXT_PICKUP_DATE: async_get_utc_midnight(
next_pickup_event.date
).isoformat(),
ATTR_NEXT_PICKUP_DATE: next_pickup_event.date.isoformat(),
}
)
self._attr_native_value = async_get_utc_midnight(pickup_event.date).isoformat()
self._attr_native_value = pickup_event.date.isoformat()
26 changes: 17 additions & 9 deletions homeassistant/components/shelly/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,9 +282,6 @@ def __init__(self, wrapper: BlockDeviceWrapper, block: Block) -> None:
self.wrapper = wrapper
self.block = block
self._name = get_block_entity_name(wrapper.device, block)
self._attr_device_info = DeviceInfo(
connections={(device_registry.CONNECTION_NETWORK_MAC, wrapper.mac)}
)

@property
def name(self) -> str:
Expand All @@ -296,6 +293,13 @@ def should_poll(self) -> bool:
"""If device should be polled."""
return False

@property
def device_info(self) -> DeviceInfo:
"""Device info."""
return {
"connections": {(device_registry.CONNECTION_NETWORK_MAC, self.wrapper.mac)}
}

@property
def available(self) -> bool:
"""Available."""
Expand Down Expand Up @@ -344,9 +348,9 @@ def __init__(self, wrapper: RpcDeviceWrapper, key: str) -> None:
self.wrapper = wrapper
self.key = key
self._attr_should_poll = False
self._attr_device_info = DeviceInfo(
connections={(device_registry.CONNECTION_NETWORK_MAC, wrapper.mac)}
)
self._attr_device_info = {
"connections": {(device_registry.CONNECTION_NETWORK_MAC, wrapper.mac)}
}
self._attr_unique_id = f"{wrapper.mac}-{key}"
self._attr_name = get_rpc_entity_name(wrapper.device, key)

Expand Down Expand Up @@ -490,15 +494,19 @@ def __init__(
self.description = description
self._name = get_block_entity_name(wrapper.device, None, self.description.name)
self._last_value = None
self._attr_device_info = DeviceInfo(
connections={(device_registry.CONNECTION_NETWORK_MAC, wrapper.mac)}
)

@property
def name(self) -> str:
"""Name of sensor."""
return self._name

@property
def device_info(self) -> DeviceInfo:
"""Device info."""
return {
"connections": {(device_registry.CONNECTION_NETWORK_MAC, self.wrapper.mac)}
}

@property
def entity_registry_enabled_default(self) -> bool:
"""Return if it should be enabled by default."""
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/shelly/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "Shelly",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/shelly",
"requirements": ["aioshelly==1.0.2"],
"requirements": ["aioshelly==1.0.4"],
"zeroconf": [
{
"type": "_http._tcp.local.",
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/shiftr/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"domain": "shiftr",
"name": "shiftr.io",
"documentation": "https://www.home-assistant.io/integrations/shiftr",
"requirements": ["paho-mqtt==1.5.1"],
"requirements": ["paho-mqtt==1.6.1"],
"codeowners": ["@fabaff"],
"iot_class": "cloud_push"
}
19 changes: 18 additions & 1 deletion homeassistant/components/simplisafe/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,11 @@

DEFAULT_ENTITY_MODEL = "alarm_control_panel"
DEFAULT_ENTITY_NAME = "Alarm Control Panel"
DEFAULT_REST_API_ERROR_COUNT = 2
DEFAULT_SCAN_INTERVAL = timedelta(seconds=30)
DEFAULT_SOCKET_MIN_RETRY = 15


DISPATCHER_TOPIC_WEBSOCKET_EVENT = "simplisafe_websocket_event_{0}"

EVENT_SIMPLISAFE_EVENT = "SIMPLISAFE_EVENT"
Expand Down Expand Up @@ -556,6 +558,8 @@ def __init__(
assert simplisafe.coordinator
super().__init__(simplisafe.coordinator)

self._rest_api_errors = 0

if device:
model = device.type.name
device_name = device.name
Expand Down Expand Up @@ -618,11 +622,24 @@ def available(self) -> bool:
else:
system_offline = False

return super().available and self._online and not system_offline
return (
self._rest_api_errors < DEFAULT_REST_API_ERROR_COUNT
and self._online
and not system_offline
)

@callback
def _handle_coordinator_update(self) -> None:
"""Update the entity with new REST API data."""
# SimpliSafe can incorrectly return an error state when there isn't any
# error. This can lead to the system having an unknown state frequently.
# To protect against that, we measure how many "error states" we receive
# and only alter the state if we detect a few in a row:
if self.coordinator.last_update_success:
self._rest_api_errors = 0
else:
self._rest_api_errors += 1

self.async_update_from_rest_api()
self.async_write_ha_state()

Expand Down
17 changes: 0 additions & 17 deletions homeassistant/components/simplisafe/alarm_control_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,6 @@
ATTR_WALL_POWER_LEVEL = "wall_power_level"
ATTR_WIFI_STRENGTH = "wifi_strength"

DEFAULT_ERRORS_TO_ACCOMMODATE = 2

VOLUME_STRING_MAP = {
VOLUME_HIGH: "high",
VOLUME_LOW: "low",
Expand Down Expand Up @@ -141,8 +139,6 @@ def __init__(self, simplisafe: SimpliSafe, system: SystemV2 | SystemV3) -> None:
additional_websocket_events=WEBSOCKET_EVENTS_TO_LISTEN_FOR,
)

self._errors = 0

if code := self._simplisafe.entry.options.get(CONF_CODE):
if code.isdigit():
self._attr_code_format = FORMAT_NUMBER
Expand Down Expand Up @@ -249,19 +245,6 @@ def async_update_from_rest_api(self) -> None:
}
)

# SimpliSafe can incorrectly return an error state when there isn't any
# error. This can lead to the system having an unknown state frequently.
# To protect against that, we measure how many "error states" we receive
# and only alter the state if we detect a few in a row:
if self._system.state == SystemStates.error:
if self._errors > DEFAULT_ERRORS_TO_ACCOMMODATE:
self._attr_state = None
else:
self._errors += 1
return

self._errors = 0

self._set_state_from_system_data()

@callback
Expand Down
18 changes: 9 additions & 9 deletions homeassistant/components/stream/worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,18 +102,18 @@ def make_new_av(
# The LL-HLS spec allows for a fragment's duration to be within the range [0.85x,1.0x]
# of the part target duration. We use the frag_duration option to tell ffmpeg to try to
# cut the fragments when they reach frag_duration. However, the resulting fragments can
# have variability in their durations and can end up being too short or too long. If
# there are two tracks, as in the case of a video feed with audio, the fragment cut seems
# to be done on the first track that crosses the desired threshold, and cutting on the
# audio track may result in a shorter video fragment than desired. Conversely, with a
# have variability in their durations and can end up being too short or too long. With a
# video track with no audio, the discrete nature of frames means that the frame at the
# end of a fragment will sometimes extend slightly beyond the desired frag_duration.
# Given this, our approach is to use a frag_duration near the upper end of the range for
# outputs with audio using a frag_duration at the lower end of the range for outputs with
# only video.
# If there are two tracks, as in the case of a video feed with audio, there is an added
# wrinkle as the fragment cut seems to be done on the first track that crosses the desired
# threshold, and cutting on the audio track may also result in a shorter video fragment
# than desired.
# Given this, our approach is to give ffmpeg a frag_duration somewhere in the middle
# 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
* (98e4 if add_audio else 9e5)
self._stream_settings.part_target_duration * 9e5
),
}
if self._stream_settings.ll_hls
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/synology_dsm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ async def async_coordinator_update_data_cameras() -> dict[
surveillance_station = api.surveillance_station

try:
async with async_timeout.timeout(10):
async with async_timeout.timeout(30):
await hass.async_add_executor_job(surveillance_station.update)
except SynologyDSMAPIErrorException as err:
raise UpdateFailed(f"Error communicating with API: {err}") from err
Expand Down
4 changes: 1 addition & 3 deletions homeassistant/components/totalconnect/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
TotalConnectClient, username, password, usercodes
)

if not client.is_valid_credentials():
if not client.is_logged_in():
raise ConfigEntryAuthFailed("TotalConnect authentication failed")

coordinator = TotalConnectDataUpdateCoordinator(hass, client)
Expand Down Expand Up @@ -88,5 +88,3 @@ def sync_update_data(self):
raise UpdateFailed(exception) from exception
except ValueError as exception:
raise UpdateFailed("Unknown state from TotalConnect") from exception

return True
4 changes: 2 additions & 2 deletions homeassistant/components/totalconnect/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ async def async_step_user(self, user_input=None):
TotalConnectClient, username, password, None
)

if client.is_valid_credentials():
if client.is_logged_in():
# username/password valid so show user locations
self.username = username
self.password = password
Expand Down Expand Up @@ -136,7 +136,7 @@ async def async_step_reauth_confirm(self, user_input=None):
self.usercodes,
)

if not client.is_valid_credentials():
if not client.is_logged_in():
errors["base"] = "invalid_auth"
return self.async_show_form(
step_id="reauth_confirm",
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/totalconnect/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"domain": "totalconnect",
"name": "Total Connect",
"documentation": "https://www.home-assistant.io/integrations/totalconnect",
"requirements": ["total_connect_client==2021.8.3"],
"requirements": ["total_connect_client==2021.11.2"],
"dependencies": [],
"codeowners": ["@austinmroczek"],
"config_flow": true,
Expand Down
Loading