Skip to content
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

2023.11.1 #103301

Merged
merged 25 commits into from
Nov 4, 2023
Merged

2023.11.1 #103301

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
acd98e9
Bump python-holidays to 0.35 (#103092)
gjohansson-ST Nov 1, 2023
0c8074b
Bump aiowaqi to 3.0.0 (#103166)
joostlek Nov 1, 2023
355b51d
Catch unexpected response in Honeywell (#103169)
mkmer Nov 1, 2023
5b4df0f
Fix roomba translation key mismatch (#103191)
Xitee1 Nov 1, 2023
2be229c
Fix roomba error if battery stats are not available (#103196)
Xitee1 Nov 1, 2023
239fa04
Fix mqtt config validation error handling (#103210)
jbouwh Nov 2, 2023
dc30ddc
Fix Fronius entity initialisation (#103211)
farmio Nov 2, 2023
c811e0d
Bump pyenphase to 1.14.1 (#103239)
cgarwood Nov 2, 2023
1dcd66d
Remove measurement flag from timestamp in gardena bluetooth (#103245)
elupus Nov 2, 2023
06d26b7
Fix Plugwise Schedule selection (#103262)
CoMPaTech Nov 3, 2023
92486b1
Bump yalexs-ble to 2.3.2 (#103267)
bdraco Nov 3, 2023
ba634ac
add library logger info on ecoforest integration manifest (#103274)
pjanuario Nov 2, 2023
1a82337
Fix Matter 1.2 locks with specific unlatch/unbolt support (#103275)
marcelveldt Nov 3, 2023
910654b
Fix firmware update failure (#103277)
raman325 Nov 3, 2023
4a56d0e
Bump opower to 0.0.39 (#103292)
tronikos Nov 3, 2023
0b0f099
Bumped version to 2023.11.1
frenck Nov 3, 2023
810681b
Bump reolink-aio to 0.7.14 and improve typing of Reolink (#103129)
starkillerOG Nov 3, 2023
67ce518
Bump py_nextbusnext to v1.0.2 to fix TypeError (#103214)
ViViDboarder Nov 3, 2023
d95d4d0
Add script to convert zwave_js device diagnostics to fixture (#102799)
raman325 Oct 25, 2023
718901d
Fix typo in Todoist config flow (#103317)
jpbede Nov 3, 2023
730a3f7
Remove extra from traccar webhook (#103319)
ludeeus Nov 3, 2023
8a07c10
Report correct weather condition at night for Met (#103334)
jrieger Nov 4, 2023
42243f1
Handle UniFi traffic rules not supported on older versions (#103346)
Kane610 Nov 4, 2023
1ef460c
Fix sensor unique id in Islamic prayer times (#103356)
engrbm87 Nov 4, 2023
9eff9ee
Fix zwave_js cover bug for Window Covering CC values (#103289)
raman325 Nov 3, 2023
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/august/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@
"documentation": "https://www.home-assistant.io/integrations/august",
"iot_class": "cloud_push",
"loggers": ["pubnub", "yalexs"],
"requirements": ["yalexs==1.10.0", "yalexs-ble==2.3.1"]
"requirements": ["yalexs==1.10.0", "yalexs-ble==2.3.2"]
}
1 change: 1 addition & 0 deletions homeassistant/components/ecoforest/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/ecoforest",
"iot_class": "local_polling",
"loggers": ["pyecoforest"],
"requirements": ["pyecoforest==0.3.0"]
}
2 changes: 1 addition & 1 deletion homeassistant/components/enphase_envoy/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"documentation": "https://www.home-assistant.io/integrations/enphase_envoy",
"iot_class": "local_polling",
"loggers": ["pyenphase"],
"requirements": ["pyenphase==1.13.1"],
"requirements": ["pyenphase==1.14.1"],
"zeroconf": [
{
"type": "_enphase-envoy._tcp.local."
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/fronius/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.dispatcher import dispatcher_send
from homeassistant.helpers.dispatcher import async_dispatcher_send
from homeassistant.helpers.event import async_track_time_interval

from .const import (
Expand Down Expand Up @@ -204,7 +204,7 @@ async def _init_devices_inverter(self, _now: datetime | None = None) -> None:

# Only for re-scans. Initial setup adds entities through sensor.async_setup_entry
if self.config_entry.state == ConfigEntryState.LOADED:
dispatcher_send(self.hass, SOLAR_NET_DISCOVERY_NEW, _coordinator)
async_dispatcher_send(self.hass, SOLAR_NET_DISCOVERY_NEW, _coordinator)

_LOGGER.debug(
"New inverter added (UID: %s)",
Expand Down
5 changes: 2 additions & 3 deletions homeassistant/components/fronius/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,7 @@ def _get_entity_value(self) -> Any:
if new_value is None:
return self.entity_description.default_value
if self.entity_description.invalid_when_falsy and not new_value:
raise ValueError(f"Ignoring zero value for {self.entity_id}.")
return None
if isinstance(new_value, float):
return round(new_value, 4)
return new_value
Expand All @@ -671,10 +671,9 @@ def _handle_coordinator_update(self) -> None:
"""Handle updated data from the coordinator."""
try:
self._attr_native_value = self._get_entity_value()
except (KeyError, ValueError):
except KeyError:
# sets state to `None` if no default_value is defined in entity description
# KeyError: raised when omitted in response - eg. at night when no production
# ValueError: raised when invalid zero value received
self._attr_native_value = self.entity_description.default_value
self.async_write_ha_state()

Expand Down
1 change: 0 additions & 1 deletion homeassistant/components/gardena_bluetooth/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ def context(self) -> set[str]:
GardenaBluetoothSensorEntityDescription(
key=Sensor.measurement_timestamp.uuid,
translation_key="sensor_measurement_timestamp",
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.TIMESTAMP,
entity_category=EntityCategory.DIAGNOSTIC,
char=Sensor.measurement_timestamp,
Expand Down
10 changes: 10 additions & 0 deletions homeassistant/components/honeywell/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,11 @@ async def _set_temperature(self, **kwargs) -> None:
if mode == "heat":
await self._device.set_setpoint_heat(temperature)

except UnexpectedResponse as err:
raise HomeAssistantError(
"Honeywell set temperature failed: Invalid Response"
) from err

except SomeComfortError as err:
_LOGGER.error("Invalid temperature %.1f: %s", temperature, err)
raise ValueError(
Expand All @@ -369,6 +374,11 @@ async def async_set_temperature(self, **kwargs: Any) -> None:
if temperature := kwargs.get(ATTR_TARGET_TEMP_LOW):
await self._device.set_setpoint_heat(temperature)

except UnexpectedResponse as err:
raise HomeAssistantError(
"Honeywell set temperature failed: Invalid Response"
) from err

except SomeComfortError as err:
_LOGGER.error("Invalid temperature %.1f: %s", temperature, err)
raise ValueError(
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/islamic_prayer_times/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def __init__(
"""Initialize the Islamic prayer time sensor."""
super().__init__(coordinator)
self.entity_description = description
self._attr_unique_id = description.key
self._attr_unique_id = f"{coordinator.config_entry.entry_id}-{description.key}"
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, coordinator.config_entry.entry_id)},
name=NAME,
Expand Down
58 changes: 36 additions & 22 deletions homeassistant/components/matter/lock.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
"""Matter lock."""
from __future__ import annotations

from enum import IntFlag
from typing import Any

from chip.clusters import Objects as clusters

from homeassistant.components.lock import LockEntity, LockEntityDescription
from homeassistant.components.lock import (
LockEntity,
LockEntityDescription,
LockEntityFeature,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_CODE, Platform
from homeassistant.core import HomeAssistant, callback
Expand All @@ -17,6 +20,8 @@
from .helpers import get_matter
from .models import MatterDiscoverySchema

DoorLockFeature = clusters.DoorLock.Bitmaps.Feature


async def async_setup_entry(
hass: HomeAssistant,
Expand Down Expand Up @@ -61,6 +66,14 @@

return bool(self.features & DoorLockFeature.kDoorPositionSensor)

@property
def supports_unbolt(self) -> bool:
"""Return True if the lock supports unbolt."""
if self.features is None:
return False

Check warning on line 73 in homeassistant/components/matter/lock.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/matter/lock.py#L73

Added line #L73 was not covered by tests

return bool(self.features & DoorLockFeature.kUnbolt)

async def send_device_command(
self,
command: clusters.ClusterCommand,
Expand Down Expand Up @@ -92,6 +105,25 @@
self._lock_option_default_code,
)
code_bytes = code.encode() if code else None
if self.supports_unbolt:
# if the lock reports it has separate unbolt support,
# the unlock command should unbolt only on the unlock command
# and unlatch on the HA 'open' command.
await self.send_device_command(
command=clusters.DoorLock.Commands.UnboltDoor(code_bytes)
)
else:
await self.send_device_command(
command=clusters.DoorLock.Commands.UnlockDoor(code_bytes)
)

async def async_open(self, **kwargs: Any) -> None:
"""Open the door latch."""
code: str = kwargs.get(
ATTR_CODE,
self._lock_option_default_code,
)
code_bytes = code.encode() if code else None
await self.send_device_command(
command=clusters.DoorLock.Commands.UnlockDoor(code_bytes)
)
Expand All @@ -104,6 +136,8 @@
self.features = int(
self.get_matter_attribute_value(clusters.DoorLock.Attributes.FeatureMap)
)
if self.supports_unbolt:
self._attr_supported_features = LockEntityFeature.OPEN

lock_state = self.get_matter_attribute_value(
clusters.DoorLock.Attributes.LockState
Expand Down Expand Up @@ -144,26 +178,6 @@
)


class DoorLockFeature(IntFlag):
"""Temp enum that represents the features of a door lock.

Should be replaced by the library provided one once that is released.
"""

kPinCredential = 0x1 # noqa: N815
kRfidCredential = 0x2 # noqa: N815
kFingerCredentials = 0x4 # noqa: N815
kLogging = 0x8 # noqa: N815
kWeekDayAccessSchedules = 0x10 # noqa: N815
kDoorPositionSensor = 0x20 # noqa: N815
kFaceCredentials = 0x40 # noqa: N815
kCredentialsOverTheAirAccess = 0x80 # noqa: N815
kUser = 0x100 # noqa: N815
kNotification = 0x200 # noqa: N815
kYearDayAccessSchedules = 0x400 # noqa: N815
kHolidaySchedules = 0x800 # noqa: N815


DISCOVERY_SCHEMAS = [
MatterDiscoverySchema(
platform=Platform.LOCK,
Expand Down
16 changes: 14 additions & 2 deletions homeassistant/components/met/weather.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,21 @@
UnitOfTemperature,
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers import entity_registry as er, sun
from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.util.unit_system import METRIC_SYSTEM

from . import MetDataUpdateCoordinator
from .const import ATTR_MAP, CONDITIONS_MAP, CONF_TRACK_HOME, DOMAIN, FORECAST_MAP
from .const import (
ATTR_CONDITION_CLEAR_NIGHT,
ATTR_CONDITION_SUNNY,
ATTR_MAP,
CONDITIONS_MAP,
CONF_TRACK_HOME,
DOMAIN,
FORECAST_MAP,
)

DEFAULT_NAME = "Met.no"

Expand Down Expand Up @@ -141,6 +149,10 @@ def condition(self) -> str | None:
condition = self.coordinator.data.current_weather_data.get("condition")
if condition is None:
return None

if condition == ATTR_CONDITION_SUNNY and not sun.is_up(self.hass):
condition = ATTR_CONDITION_CLEAR_NIGHT

return format_condition(condition)

@property
Expand Down
10 changes: 8 additions & 2 deletions homeassistant/components/mqtt/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
MqttAvailability,
MqttEntity,
async_setup_entity_entry_helper,
validate_sensor_entity_category,
write_state_on_attr_change,
)
from .models import MqttValueTemplate, ReceiveMessage
Expand All @@ -55,7 +56,7 @@
DEFAULT_FORCE_UPDATE = False
CONF_EXPIRE_AFTER = "expire_after"

PLATFORM_SCHEMA_MODERN = MQTT_RO_SCHEMA.extend(
_PLATFORM_SCHEMA_BASE = MQTT_RO_SCHEMA.extend(
{
vol.Optional(CONF_DEVICE_CLASS): vol.Any(DEVICE_CLASSES_SCHEMA, None),
vol.Optional(CONF_EXPIRE_AFTER): cv.positive_int,
Expand All @@ -67,7 +68,12 @@
}
).extend(MQTT_ENTITY_COMMON_SCHEMA.schema)

DISCOVERY_SCHEMA = PLATFORM_SCHEMA_MODERN.extend({}, extra=vol.REMOVE_EXTRA)
DISCOVERY_SCHEMA = vol.All(
validate_sensor_entity_category,
_PLATFORM_SCHEMA_BASE.extend({}, extra=vol.REMOVE_EXTRA),
)

PLATFORM_SCHEMA_MODERN = vol.All(validate_sensor_entity_category, _PLATFORM_SCHEMA_BASE)


async def async_setup_entry(
Expand Down
6 changes: 3 additions & 3 deletions homeassistant/components/mqtt/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,16 +232,16 @@
def valid_preset_mode_configuration(config: ConfigType) -> ConfigType:
"""Validate that the preset mode reset payload is not one of the preset modes."""
if PRESET_NONE in config[CONF_PRESET_MODES_LIST]:
raise ValueError("preset_modes must not include preset mode 'none'")
raise vol.Invalid("preset_modes must not include preset mode 'none'")
return config


def valid_humidity_range_configuration(config: ConfigType) -> ConfigType:
"""Validate a target_humidity range configuration, throws otherwise."""
if config[CONF_HUMIDITY_MIN] >= config[CONF_HUMIDITY_MAX]:
raise ValueError("target_humidity_max must be > target_humidity_min")
raise vol.Invalid("target_humidity_max must be > target_humidity_min")
if config[CONF_HUMIDITY_MAX] > 100:
raise ValueError("max_humidity must be <= 100")
raise vol.Invalid("max_humidity must be <= 100")

return config

Expand Down
6 changes: 3 additions & 3 deletions homeassistant/components/mqtt/fan.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,16 +116,16 @@
def valid_speed_range_configuration(config: ConfigType) -> ConfigType:
"""Validate that the fan speed_range configuration is valid, throws if it isn't."""
if config[CONF_SPEED_RANGE_MIN] == 0:
raise ValueError("speed_range_min must be > 0")
raise vol.Invalid("speed_range_min must be > 0")
if config[CONF_SPEED_RANGE_MIN] >= config[CONF_SPEED_RANGE_MAX]:
raise ValueError("speed_range_max must be > speed_range_min")
raise vol.Invalid("speed_range_max must be > speed_range_min")
return config


def valid_preset_mode_configuration(config: ConfigType) -> ConfigType:
"""Validate that the preset mode reset payload is not one of the preset modes."""
if config[CONF_PAYLOAD_RESET_PRESET_MODE] in config[CONF_PRESET_MODES_LIST]:
raise ValueError("preset_modes must not contain payload_reset_preset_mode")
raise vol.Invalid("preset_modes must not contain payload_reset_preset_mode")
return config


Expand Down
6 changes: 3 additions & 3 deletions homeassistant/components/mqtt/humidifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@
def valid_mode_configuration(config: ConfigType) -> ConfigType:
"""Validate that the mode reset payload is not one of the available modes."""
if config[CONF_PAYLOAD_RESET_MODE] in config[CONF_AVAILABLE_MODES_LIST]:
raise ValueError("modes must not contain payload_reset_mode")
raise vol.Invalid("modes must not contain payload_reset_mode")
return config


Expand All @@ -113,9 +113,9 @@ def valid_humidity_range_configuration(config: ConfigType) -> ConfigType:
throws if it isn't.
"""
if config[CONF_TARGET_HUMIDITY_MIN] >= config[CONF_TARGET_HUMIDITY_MAX]:
raise ValueError("target_humidity_max must be > target_humidity_min")
raise vol.Invalid("target_humidity_max must be > target_humidity_min")
if config[CONF_TARGET_HUMIDITY_MAX] > 100:
raise ValueError("max_humidity must be <= 100")
raise vol.Invalid("max_humidity must be <= 100")

return config

Expand Down
19 changes: 15 additions & 4 deletions homeassistant/components/mqtt/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from typing import TYPE_CHECKING, Any, Protocol, cast, final

import voluptuous as vol
import yaml

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
Expand All @@ -28,6 +27,7 @@
CONF_NAME,
CONF_UNIQUE_ID,
CONF_VALUE_TEMPLATE,
EntityCategory,
)
from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback
from homeassistant.helpers import (
Expand Down Expand Up @@ -63,6 +63,7 @@
UndefinedType,
)
from homeassistant.util.json import json_loads
from homeassistant.util.yaml import dump as yaml_dump

from . import debug_info, subscription
from .client import async_publish
Expand Down Expand Up @@ -207,6 +208,16 @@ def validate_device_has_at_least_one_identifier(value: ConfigType) -> ConfigType
)


def validate_sensor_entity_category(config: ConfigType) -> ConfigType:
"""Check the sensor's entity category is not set to `config` which is invalid for sensors."""
if (
CONF_ENTITY_CATEGORY in config
and config[CONF_ENTITY_CATEGORY] == EntityCategory.CONFIG
):
raise vol.Invalid("Entity category `config` is invalid")
return config


MQTT_ENTITY_DEVICE_INFO_SCHEMA = vol.All(
cv.deprecated(CONF_DEPRECATED_VIA_HUB, CONF_VIA_DEVICE),
vol.Schema(
Expand Down Expand Up @@ -404,8 +415,8 @@ def _async_setup_entities() -> None:
error = str(ex)
config_file = getattr(yaml_config, "__config_file__", "?")
line = getattr(yaml_config, "__line__", "?")
issue_id = hex(hash(frozenset(yaml_config.items())))
yaml_config_str = yaml.dump(dict(yaml_config))
issue_id = hex(hash(frozenset(yaml_config)))
yaml_config_str = yaml_dump(yaml_config)
learn_more_url = (
f"https://www.home-assistant.io/integrations/{domain}.mqtt/"
)
Expand All @@ -427,7 +438,7 @@ def _async_setup_entities() -> None:
translation_key="invalid_platform_config",
)
_LOGGER.error(
"%s for manual configured MQTT %s item, in %s, line %s Got %s",
"%s for manually configured MQTT %s item, in %s, line %s Got %s",
error,
domain,
config_file,
Expand Down
Loading
Loading