Compare commits

...

20 Commits

Author SHA1 Message Date
Paulus Schoutsen
83d617737f 2022.10.5 (#80691) 2022-10-20 16:58:45 -04:00
Paulus Schoutsen
c2dff8fb7e Bumped version to 2022.10.5 2022-10-20 14:49:21 -04:00
J. Nick Koston
44d35fc8e4 Fix bluetooth calls from automations in esphome (#80683) 2022-10-20 14:49:15 -04:00
Franck Nijhof
799f776956 Pin uamqp==1.6.0 (#80678) 2022-10-20 14:49:14 -04:00
J. Nick Koston
fb35896b16 Bump bluetooth-auto-recovery to 0.3.6 (#80643)
* Bump bluetooth-auto-recovery to 0.3.5

changelog: https://github.com/Bluetooth-Devices/bluetooth-auto-recovery/compare/v0.3.4...v0.3.5

* bump again for more rfkill fixes
2022-10-20 14:46:39 -04:00
Maciej Bieniek
8378b768d0 Save last target temperature in Shelly climate platform (#80561)
Save last target temp
2022-10-20 14:43:56 -04:00
Jan Bouwhuis
605abe5882 Add missed write state request for MQTT cover (#80540)
Missed write state request for MQTT cover
2022-10-20 14:37:06 -04:00
Aaron Bach
69a698d97a Don't add RainMachine restriction switches if underlying data is missing (#80502) 2022-10-20 14:37:05 -04:00
David F. Mulcahey
c76d0f18c8 Bump ZHA quirks to 0.0.83 (#80489) 2022-10-20 14:37:04 -04:00
J. Nick Koston
0c3d4f2e57 Bump aiohomekit to 2.0.2 (#80402) 2022-10-20 14:37:03 -04:00
J. Nick Koston
7e3abd9db5 Handle TimeoutError during HKC setup attempts (#80399)
closes https://github.com/Jc2k/aiohomekit/issues/188
2022-10-20 14:37:02 -04:00
definitio
8c811ef16e Fix "Unknown power_off command" for Samsung H6410 (#80386) 2022-10-20 14:37:01 -04:00
Ivan Puddu
b2e0d76145 Skip webostv trigger validation before the domain is setup (#80372)
* Skip trigger validation before the domain is setup

* Included None as return type

* Keep function signature intact. Check at the source
2022-10-20 14:37:00 -04:00
uvjustin
c73162e5ea Fix stream recorder with orientation transforms (#80370)
Find moov instead of using fixed location
2022-10-20 14:36:59 -04:00
Sean Vig
df75346dca Fix updating Amcrest binary sensors (#80365)
* Fix updating Amcrest binary sensors

As detailed in https://bugs.python.org/issue32113, a generator
expression cannot be used with asynchronous components, even that the
resulting elements of the generator are normal objects.  Manually
iterate over the event codes and check if the events have happened.
Escape early on the first event that is triggered such that this is
functionally equivalent to using `any`.

* Update homeassistant/components/amcrest/binary_sensor.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2022-10-20 14:36:59 -04:00
Shay Levy
a0eade7632 Fix Shelly EM negative power factor (#80348) 2022-10-20 14:36:58 -04:00
rozie
b203411885 Fix solaredge missing data value (#80321)
* Fix issue #80263: use get to fetch dict value

* use None instead -1 for unknown value

* Update homeassistant/components/solaredge/coordinator.py

Co-authored-by: Franck Nijhof <frenck@frenck.nl>

* Add guards for not multipling None

* Missing if added

Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2022-10-20 14:36:57 -04:00
Jeef
15def40784 Fix Intellifire UDP timeout (#80204) 2022-10-20 14:36:56 -04:00
Bouwe Westerdijk
b3612b430b Bump plugwise to v0.21.4 (#79831) 2022-10-20 14:36:55 -04:00
Jan Jedelský
291d366933 Handle ReadTimeout during wolflink setup (#78135)
* Handle ReadTimeout during wolflink setup

* Reorder imports

Co-authored-by: Yevhenii Vaskivskyi <yevhenii.vaskivskyi@gmail.com>

* Reorder exceptions

Co-authored-by: Yevhenii Vaskivskyi <yevhenii.vaskivskyi@gmail.com>

* Use RequestError instead of ConnectError, ReadTimeout, and ConnectTimeout

Co-authored-by: Yevhenii Vaskivskyi <yevhenii.vaskivskyi@gmail.com>
2022-10-20 14:36:54 -04:00
28 changed files with 93 additions and 45 deletions

View File

@@ -215,10 +215,12 @@ class AmcrestBinarySensor(BinarySensorEntity):
raise ValueError(f"Binary sensor {self.name} event codes not set")
try:
self._attr_is_on = any( # type: ignore[arg-type]
len(await self._api.async_event_channels_happened(event_code)) > 0
for event_code in event_codes
)
for event_code in event_codes:
if await self._api.async_event_channels_happened(event_code):
self._attr_is_on = True
break
else:
self._attr_is_on = False
except AmcrestError as error:
log_update_error(_LOGGER, "update", self.name, "binary sensor", error)
return

View File

@@ -9,7 +9,7 @@
"bleak==0.18.1",
"bleak-retry-connector==2.1.3",
"bluetooth-adapters==0.6.0",
"bluetooth-auto-recovery==0.3.4",
"bluetooth-auto-recovery==0.3.6",
"dbus-fast==1.24.0"
],
"codeowners": ["@bdraco"],

View File

@@ -279,6 +279,7 @@ class HaBleakClientWrapper(BleakClient):
async def connect(self, **kwargs: Any) -> bool:
"""Connect to the specified GATT server."""
if not self._backend:
assert MANAGER is not None
wrapped_backend = (
self._async_get_backend() or await self._async_get_fallback_backend()
)
@@ -287,6 +288,7 @@ class HaBleakClientWrapper(BleakClient):
or wrapped_backend.device,
disconnected_callback=self.__disconnected_callback,
timeout=self.__timeout,
hass=MANAGER.hass,
)
return await super().connect(**kwargs)

View File

@@ -15,7 +15,7 @@ from bleak.backends.device import BLEDevice
from bleak.backends.service import BleakGATTServiceCollection
from bleak.exc import BleakError
from homeassistant.core import CALLBACK_TYPE, async_get_hass
from homeassistant.core import CALLBACK_TYPE
from ..domain_data import DomainData
from .characteristic import BleakGATTCharacteristicESPHome
@@ -83,7 +83,7 @@ class ESPHomeClient(BaseBleakClient):
self._address_as_int = mac_to_int(self._ble_device.address)
assert self._ble_device.details is not None
self._source = self._ble_device.details["source"]
self.domain_data = DomainData.get(async_get_hass())
self.domain_data = DomainData.get(kwargs["hass"])
config_entry = self.domain_data.get_by_unique_id(self._source)
self.entry_data = self.domain_data.get_entry_data(config_entry)
self._client = self.entry_data.client

View File

@@ -40,7 +40,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
try:
await conn.async_setup()
except (AccessoryNotFoundError, EncryptionError, AccessoryDisconnectedError) as ex:
except (
asyncio.TimeoutError,
AccessoryNotFoundError,
EncryptionError,
AccessoryDisconnectedError,
) as ex:
del hass.data[KNOWN_DEVICES][conn.unique_id]
with contextlib.suppress(asyncio.TimeoutError):
await conn.pairing.close()

View File

@@ -3,7 +3,7 @@
"name": "HomeKit Controller",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/homekit_controller",
"requirements": ["aiohomekit==2.0.1"],
"requirements": ["aiohomekit==2.0.2"],
"zeroconf": ["_hap._tcp.local.", "_hap._udp.local."],
"bluetooth": [{ "manufacturer_id": 76, "manufacturer_data_start": [6] }],
"dependencies": ["bluetooth", "zeroconf"],

View File

@@ -38,7 +38,7 @@ async def validate_host_input(host: str, dhcp_mode: bool = False) -> str:
"""
LOGGER.debug("Instantiating IntellifireAPI with host: [%s]", host)
api = IntellifireAPILocal(fireplace_ip=host)
await api.poll(supress_warnings=dhcp_mode)
await api.poll(suppress_warnings=dhcp_mode)
serial = api.data.serial
LOGGER.debug("Found a fireplace: %s", serial)
@@ -62,7 +62,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
async def _find_fireplaces(self):
"""Perform UDP discovery."""
fireplace_finder = AsyncUDPFireplaceFinder()
discovered_hosts = await fireplace_finder.search_fireplace(timeout=1)
discovered_hosts = await fireplace_finder.search_fireplace(timeout=12)
configured_hosts = {
entry.data[CONF_HOST]
for entry in self._async_current_entries(include_ignore=False)

View File

@@ -3,9 +3,13 @@
"name": "IntelliFire",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/intellifire",
"requirements": ["intellifire4py==2.0.1"],
"requirements": ["intellifire4py==2.2.1"],
"codeowners": ["@jeeftor"],
"iot_class": "local_polling",
"loggers": ["intellifire4py"],
"dhcp": [{ "hostname": "zentrios-*" }]
"dhcp": [
{
"hostname": "zentrios-*"
}
]
}

View File

@@ -767,6 +767,7 @@ class MqttCover(MqttEntity, CoverEntity):
return position
@callback
def tilt_payload_received(self, _payload):
"""Set the tilt value."""
@@ -784,7 +785,7 @@ class MqttCover(MqttEntity, CoverEntity):
):
level = self.find_percentage_in_range(payload)
self._tilt_value = level
self.async_write_ha_state()
get_mqtt_data(self.hass).state_write_requests.write_state_request(self)
else:
_LOGGER.warning(
"Payload '%s' is out of range, must be between '%s' and '%s' inclusive",

View File

@@ -2,7 +2,7 @@
"domain": "plugwise",
"name": "Plugwise",
"documentation": "https://www.home-assistant.io/integrations/plugwise",
"requirements": ["plugwise==0.21.3"],
"requirements": ["plugwise==0.21.4"],
"codeowners": ["@CoMPaTech", "@bouwew", "@brefra", "@frenck"],
"zeroconf": ["_plugwise._tcp.local."],
"config_flow": true,

View File

@@ -34,7 +34,7 @@ from .model import (
RainMachineEntityDescriptionMixinDataKey,
RainMachineEntityDescriptionMixinUid,
)
from .util import RUN_STATE_MAP
from .util import RUN_STATE_MAP, key_exists
ATTR_AREA = "area"
ATTR_CS_ON = "cs_on"
@@ -237,6 +237,8 @@ async def async_setup_entry(
# Add switches to control restrictions:
for description in RESTRICTIONS_SWITCH_DESCRIPTIONS:
if not key_exists(coordinator.data, description.data_key):
continue
entities.append(RainMachineRestrictionSwitch(entry, data, description))
async_add_entities(entities)

View File

@@ -69,7 +69,7 @@ from .const import (
KEY_PRESS_TIMEOUT = 1.2
ENCRYPTED_MODEL_USES_POWER_OFF = {"H6400"}
ENCRYPTED_MODEL_USES_POWER_OFF = {"H6400", "H6410"}
ENCRYPTED_MODEL_USES_POWER = {"JU6400", "JU641D"}
REST_EXCEPTIONS = (HttpApiError, AsyncioTimeoutError, ResponseError)

View File

@@ -140,6 +140,7 @@ class BlockSleepingClimate(
self.last_state: State | None = None
self.last_state_attributes: Mapping[str, Any]
self._preset_modes: list[str] = []
self._last_target_temp = 20.0
if self.block is not None and self.device_block is not None:
self._unique_id = f"{self.wrapper.mac}-{self.block.description}"
@@ -266,9 +267,15 @@ class BlockSleepingClimate(
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
"""Set hvac mode."""
if hvac_mode == HVACMode.OFF:
if isinstance(self.target_temperature, float):
self._last_target_temp = self.target_temperature
await self.set_state_full_path(
target_t_enabled=1, target_t=f"{self._attr_min_temp}"
)
if hvac_mode == HVACMode.HEAT:
await self.set_state_full_path(
target_t_enabled=1, target_t=self._last_target_temp
)
async def async_set_preset_mode(self, preset_mode: str) -> None:
"""Set preset mode."""

View File

@@ -144,7 +144,7 @@ SENSORS: Final = {
key="emeter|powerFactor",
name="Power Factor",
native_unit_of_measurement=PERCENTAGE,
value=lambda value: round(value * 100, 1),
value=lambda value: abs(round(value * 100, 1)),
device_class=SensorDeviceClass.POWER_FACTOR,
state_class=SensorStateClass.MEASUREMENT,
),

View File

@@ -276,17 +276,19 @@ class SolarEdgePowerFlowDataService(SolarEdgeDataService):
for key, value in power_flow.items():
if key in ["LOAD", "PV", "GRID", "STORAGE"]:
self.data[key] = value["currentPower"]
self.data[key] = value.get("currentPower")
self.attributes[key] = {"status": value["status"]}
if key in ["GRID"]:
export = key.lower() in power_to
self.data[key] *= -1 if export else 1
if self.data[key]:
self.data[key] *= -1 if export else 1
self.attributes[key]["flow"] = "export" if export else "import"
if key in ["STORAGE"]:
charge = key.lower() in power_to
self.data[key] *= -1 if charge else 1
if self.data[key]:
self.data[key] *= -1 if charge else 1
self.attributes[key]["flow"] = "charge" if charge else "discharge"
self.attributes[key]["soc"] = value["chargeLevel"]

View File

@@ -4,6 +4,8 @@ from __future__ import annotations
from collections.abc import Generator
from typing import TYPE_CHECKING
from homeassistant.exceptions import HomeAssistantError
if TYPE_CHECKING:
from io import BufferedIOBase
@@ -11,7 +13,7 @@ if TYPE_CHECKING:
def find_box(
mp4_bytes: bytes, target_type: bytes, box_start: int = 0
) -> Generator[int, None, None]:
"""Find location of first box (or sub_box if box_start provided) of given type."""
"""Find location of first box (or sub box if box_start provided) of given type."""
if box_start == 0:
index = 0
box_end = len(mp4_bytes)
@@ -141,12 +143,26 @@ def get_codec_string(mp4_bytes: bytes) -> str:
return ",".join(codecs)
def find_moov(mp4_io: BufferedIOBase) -> int:
"""Find location of moov atom in a BufferedIOBase mp4."""
index = 0
while 1:
mp4_io.seek(index)
box_header = mp4_io.read(8)
if len(box_header) != 8:
raise HomeAssistantError("moov atom not found")
if box_header[4:8] == b"moov":
return index
index += int.from_bytes(box_header[0:4], byteorder="big")
def read_init(bytes_io: BufferedIOBase) -> bytes:
"""Read the init from a mp4 file."""
bytes_io.seek(24)
moov_loc = find_moov(bytes_io)
bytes_io.seek(moov_loc)
moov_len = int.from_bytes(bytes_io.read(4), byteorder="big")
bytes_io.seek(0)
return bytes_io.read(24 + moov_len)
return bytes_io.read(moov_loc + moov_len)
ZERO32 = b"\x00\x00\x00\x00"

View File

@@ -46,7 +46,8 @@ async def async_validate_trigger_config(
device_id = config[CONF_DEVICE_ID]
try:
device = async_get_device_entry_by_device_id(hass, device_id)
async_get_client_wrapper_by_device_entry(hass, device)
if DOMAIN in hass.data:
async_get_client_wrapper_by_device_entry(hass, device)
except ValueError as err:
raise InvalidDeviceAutomationConfig(err) from err

View File

@@ -2,7 +2,7 @@
from datetime import timedelta
import logging
from httpx import ConnectError, ConnectTimeout
from httpx import RequestError
from wolf_smartset.token_auth import InvalidAuth
from wolf_smartset.wolf_client import FetchFailed, ParameterReadError, WolfClient
@@ -74,7 +74,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
for parameter in parameters
if parameter.value_id in values
}
except ConnectError as exception:
except RequestError as exception:
raise UpdateFailed(
f"Error communicating with API: {exception}"
) from exception
@@ -134,7 +134,7 @@ async def fetch_parameters_init(client: WolfClient, gateway_id: int, device_id:
"""Fetch all available parameters with usage of WolfClient but handles all exceptions and results in ConfigEntryNotReady."""
try:
return await fetch_parameters(client, gateway_id, device_id)
except (ConnectError, ConnectTimeout, FetchFailed) as exception:
except (FetchFailed, RequestError) as exception:
raise ConfigEntryNotReady(
f"Error communicating with API: {exception}"
) from exception

View File

@@ -7,7 +7,7 @@
"bellows==0.34.2",
"pyserial==3.5",
"pyserial-asyncio==0.6",
"zha-quirks==0.0.82",
"zha-quirks==0.0.83",
"zigpy-deconz==0.19.0",
"zigpy==0.51.3",
"zigpy-xbee==0.16.2",

View File

@@ -8,7 +8,7 @@ from .backports.enum import StrEnum
APPLICATION_NAME: Final = "HomeAssistant"
MAJOR_VERSION: Final = 2022
MINOR_VERSION: Final = 10
PATCH_VERSION: Final = "4"
PATCH_VERSION: Final = "5"
__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

@@ -13,7 +13,7 @@ bcrypt==3.1.7
bleak-retry-connector==2.1.3
bleak==0.18.1
bluetooth-adapters==0.6.0
bluetooth-auto-recovery==0.3.4
bluetooth-auto-recovery==0.3.6
certifi>=2021.5.30
ciso8601==2.2.0
cryptography==38.0.1
@@ -132,3 +132,6 @@ iso4217!=1.10.20220401
# Pandas 1.4.4 has issues with wheels om armhf + Py3.10
pandas==1.4.3
# uamqp 1.6.1, has 1 failing test during built on armv7/armhf
uamqp==1.6.0

View File

@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "homeassistant"
version = "2022.10.4"
version = "2022.10.5"
license = {text = "Apache-2.0"}
description = "Open-source home automation platform running on Python 3."
readme = "README.rst"

View File

@@ -171,7 +171,7 @@ aioguardian==2022.07.0
aioharmony==0.2.9
# homeassistant.components.homekit_controller
aiohomekit==2.0.1
aiohomekit==2.0.2
# homeassistant.components.emulated_hue
# homeassistant.components.http
@@ -435,7 +435,7 @@ bluemaestro-ble==0.2.0
bluetooth-adapters==0.6.0
# homeassistant.components.bluetooth
bluetooth-auto-recovery==0.3.4
bluetooth-auto-recovery==0.3.6
# homeassistant.components.bond
bond-async==0.1.22
@@ -934,7 +934,7 @@ inkbird-ble==0.5.5
insteon-frontend-home-assistant==0.2.0
# homeassistant.components.intellifire
intellifire4py==2.0.1
intellifire4py==2.2.1
# homeassistant.components.iotawatt
iotawattpy==0.1.0
@@ -1306,7 +1306,7 @@ plexauth==0.0.6
plexwebsocket==0.0.13
# homeassistant.components.plugwise
plugwise==0.21.3
plugwise==0.21.4
# homeassistant.components.plum_lightpad
plumlightpad==0.0.11
@@ -2592,7 +2592,7 @@ zengge==0.2
zeroconf==0.39.1
# homeassistant.components.zha
zha-quirks==0.0.82
zha-quirks==0.0.83
# homeassistant.components.zhong_hong
zhong_hong_hvac==1.0.9

View File

@@ -155,7 +155,7 @@ aioguardian==2022.07.0
aioharmony==0.2.9
# homeassistant.components.homekit_controller
aiohomekit==2.0.1
aiohomekit==2.0.2
# homeassistant.components.emulated_hue
# homeassistant.components.http
@@ -349,7 +349,7 @@ bluemaestro-ble==0.2.0
bluetooth-adapters==0.6.0
# homeassistant.components.bluetooth
bluetooth-auto-recovery==0.3.4
bluetooth-auto-recovery==0.3.6
# homeassistant.components.bond
bond-async==0.1.22
@@ -690,7 +690,7 @@ inkbird-ble==0.5.5
insteon-frontend-home-assistant==0.2.0
# homeassistant.components.intellifire
intellifire4py==2.0.1
intellifire4py==2.2.1
# homeassistant.components.iotawatt
iotawattpy==0.1.0
@@ -933,7 +933,7 @@ plexauth==0.0.6
plexwebsocket==0.0.13
# homeassistant.components.plugwise
plugwise==0.21.3
plugwise==0.21.4
# homeassistant.components.plum_lightpad
plumlightpad==0.0.11
@@ -1793,7 +1793,7 @@ youless-api==0.16
zeroconf==0.39.1
# homeassistant.components.zha
zha-quirks==0.0.82
zha-quirks==0.0.83
# homeassistant.components.zha
zigpy-deconz==0.19.0

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
# uamqp 1.6.1, has 1 failing test during built on armv7/armhf
uamqp==1.6.0
"""
IGNORE_PRE_COMMIT_HOOK_ID = (

View File

@@ -29,7 +29,7 @@ from .common import (
from tests.common import async_fire_time_changed
STREAM_SOURCE = "some-stream-source"
INIT_BYTES = b"init"
INIT_BYTES = b"\x00\x00\x00\x08moov"
FAKE_PAYLOAD = b"fake-payload"
SEGMENT_DURATION = 10
TEST_TIMEOUT = 5.0 # Lower than 9s home assistant timeout

View File

@@ -30,7 +30,7 @@ TEST_PART_DURATION = 0.75
NUM_PART_SEGMENTS = int(-(-SEGMENT_DURATION // TEST_PART_DURATION))
PART_INDEPENDENT_PERIOD = int(1 / TEST_PART_DURATION) or 1
BYTERANGE_LENGTH = 1
INIT_BYTES = b"init"
INIT_BYTES = b"\x00\x00\x00\x08moov"
SEQUENCE_BYTES = bytearray(range(NUM_PART_SEGMENTS * BYTERANGE_LENGTH))
ALT_SEQUENCE_BYTES = bytearray(range(20, 20 + NUM_PART_SEGMENTS * BYTERANGE_LENGTH))
VERY_LARGE_LAST_BYTE_POS = 9007199254740991

View File

@@ -242,7 +242,7 @@ class FakePyAvBuffer:
# Forward to appropriate FakeStream
packet.stream.mux(packet)
# Make new init/part data available to the worker
self.memory_file.write(b"0")
self.memory_file.write(b"\x00\x00\x00\x00moov")
def close(self):
"""Close the buffer."""