Skip to content

Commit

Permalink
2024.1.4 (#108379)
Browse files Browse the repository at this point in the history
  • Loading branch information
frenck authored Jan 19, 2024
2 parents 99ee57a + 43f1c09 commit 6e6a5ff
Show file tree
Hide file tree
Showing 52 changed files with 686 additions and 306 deletions.
2 changes: 1 addition & 1 deletion homeassistant/components/enigma2/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
"documentation": "https://www.home-assistant.io/integrations/enigma2",
"iot_class": "local_polling",
"loggers": ["openwebif"],
"requirements": ["openwebifpy==4.0.4"]
"requirements": ["openwebifpy==4.2.1"]
}
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.15.2"],
"requirements": ["pyenphase==1.17.0"],
"zeroconf": [
{
"type": "_enphase-envoy._tcp.local."
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/flipr/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
"documentation": "https://www.home-assistant.io/integrations/flipr",
"iot_class": "cloud_polling",
"loggers": ["flipr_api"],
"requirements": ["flipr-api==1.5.0"]
"requirements": ["flipr-api==1.5.1"]
}
2 changes: 1 addition & 1 deletion homeassistant/components/homekit_controller/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@
"documentation": "https://www.home-assistant.io/integrations/homekit_controller",
"iot_class": "local_push",
"loggers": ["aiohomekit", "commentjson"],
"requirements": ["aiohomekit==3.1.2"],
"requirements": ["aiohomekit==3.1.3"],
"zeroconf": ["_hap._tcp.local.", "_hap._udp.local."]
}
7 changes: 5 additions & 2 deletions homeassistant/components/matrix/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,9 +223,12 @@ async def handle_startup(event: HassEvent) -> None:
def _load_commands(self, commands: list[ConfigCommand]) -> None:
for command in commands:
# Set the command for all listening_rooms, unless otherwise specified.
command.setdefault(CONF_ROOMS, list(self._listening_rooms.values()))
if rooms := command.get(CONF_ROOMS):
command[CONF_ROOMS] = [self._listening_rooms[room] for room in rooms]
else:
command[CONF_ROOMS] = list(self._listening_rooms.values())

# COMMAND_SCHEMA guarantees that exactly one of CONF_WORD and CONF_expression are set.
# COMMAND_SCHEMA guarantees that exactly one of CONF_WORD and CONF_EXPRESSION are set.
if (word_command := command.get(CONF_WORD)) is not None:
for room_id in command[CONF_ROOMS]:
self._word_commands.setdefault(room_id, {})
Expand Down
12 changes: 12 additions & 0 deletions homeassistant/components/matter/light.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ async def _set_xy_color(self, xy_color: tuple[float, float]) -> None:
colorY=int(matter_xy[1]),
# It's required in TLV. We don't implement transition time yet.
transitionTime=0,
# allow setting the color while the light is off,
# by setting the optionsMask to 1 (=ExecuteIfOff)
optionsMask=1,
optionsOverride=1,
)
)

Expand All @@ -103,6 +107,10 @@ async def _set_hs_color(self, hs_color: tuple[float, float]) -> None:
saturation=int(matter_hs[1]),
# It's required in TLV. We don't implement transition time yet.
transitionTime=0,
# allow setting the color while the light is off,
# by setting the optionsMask to 1 (=ExecuteIfOff)
optionsMask=1,
optionsOverride=1,
)
)

Expand All @@ -114,6 +122,10 @@ async def _set_color_temp(self, color_temp: int) -> None:
colorTemperatureMireds=color_temp,
# It's required in TLV. We don't implement transition time yet.
transitionTime=0,
# allow setting the color while the light is off,
# by setting the optionsMask to 1 (=ExecuteIfOff)
optionsMask=1,
optionsOverride=1,
)
)

Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/media_player/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1295,7 +1295,7 @@ async def websocket_browse_media(
connection.send_error(msg["id"], "entity_not_found", "Entity not found")
return

if MediaPlayerEntityFeature.BROWSE_MEDIA not in player.supported_features:
if MediaPlayerEntityFeature.BROWSE_MEDIA not in player.supported_features_compat:
connection.send_message(
websocket_api.error_message(
msg["id"], ERR_NOT_SUPPORTED, "Player does not support browsing media"
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/mjpeg/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def async_get_schema(

if show_name:
schema = {
vol.Optional(CONF_NAME, default=defaults.get(CONF_NAME)): str,
vol.Required(CONF_NAME, default=defaults.get(CONF_NAME)): str,
**schema,
}

Expand Down
6 changes: 4 additions & 2 deletions homeassistant/components/motion_blinds/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from socket import timeout
from typing import Any

from motionblinds import ParseException
from motionblinds import DEVICE_TYPES_WIFI, ParseException

from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
Expand Down Expand Up @@ -59,7 +59,9 @@ def update_gateway(self):
def update_blind(self, blind):
"""Fetch data from a blind."""
try:
if self._wait_for_push:
if blind.device_type in DEVICE_TYPES_WIFI:
blind.Update_from_cache()
elif self._wait_for_push:
blind.Update()
else:
blind.Update_trigger()
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/reolink/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@
"documentation": "https://www.home-assistant.io/integrations/reolink",
"iot_class": "local_push",
"loggers": ["reolink_aio"],
"requirements": ["reolink-aio==0.8.6"]
"requirements": ["reolink-aio==0.8.7"]
}
2 changes: 1 addition & 1 deletion homeassistant/components/ridwell/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
"integration_type": "service",
"iot_class": "cloud_polling",
"loggers": ["aioridwell"],
"requirements": ["aioridwell==2023.07.0"]
"requirements": ["aioridwell==2024.01.0"]
}
19 changes: 19 additions & 0 deletions homeassistant/components/shelly/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,15 @@
from homeassistant.helpers.typing import ConfigType

from .const import (
BLOCK_EXPECTED_SLEEP_PERIOD,
BLOCK_WRONG_SLEEP_PERIOD,
CONF_COAP_PORT,
CONF_SLEEP_PERIOD,
DATA_CONFIG_ENTRY,
DEFAULT_COAP_PORT,
DOMAIN,
LOGGER,
MODELS_WITH_WRONG_SLEEP_PERIOD,
PUSH_UPDATE_ISSUE_ID,
)
from .coordinator import (
Expand Down Expand Up @@ -162,6 +165,22 @@ async def _async_setup_block_entry(hass: HomeAssistant, entry: ConfigEntry) -> b
sleep_period = entry.data.get(CONF_SLEEP_PERIOD)
shelly_entry_data = get_entry_data(hass)[entry.entry_id]

# Some old firmware have a wrong sleep period hardcoded value.
# Following code block will force the right value for affected devices
if (
sleep_period == BLOCK_WRONG_SLEEP_PERIOD
and entry.data["model"] in MODELS_WITH_WRONG_SLEEP_PERIOD
):
LOGGER.warning(
"Updating stored sleep period for %s: from %s to %s",
entry.title,
sleep_period,
BLOCK_EXPECTED_SLEEP_PERIOD,
)
data = {**entry.data}
data[CONF_SLEEP_PERIOD] = sleep_period = BLOCK_EXPECTED_SLEEP_PERIOD
hass.config_entries.async_update_entry(entry, data=data)

async def _async_block_device_setup() -> None:
"""Set up a block based device that is online."""
shelly_entry_data.block = ShellyBlockCoordinator(hass, entry, device)
Expand Down
13 changes: 0 additions & 13 deletions homeassistant/components/shelly/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
from homeassistant.const import STATE_ON, EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.entity_registry import RegistryEntry
from homeassistant.helpers.restore_state import RestoreEntity

from .const import CONF_SLEEP_PERIOD
Expand Down Expand Up @@ -210,16 +209,6 @@ class RestBinarySensorDescription(RestEntityDescription, BinarySensorEntityDescr
}


def _build_block_description(entry: RegistryEntry) -> BlockBinarySensorDescription:
"""Build description when restoring block attribute entities."""
return BlockBinarySensorDescription(
key="",
name="",
icon=entry.original_icon,
device_class=entry.original_device_class,
)


async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
Expand Down Expand Up @@ -248,7 +237,6 @@ async def async_setup_entry(
async_add_entities,
SENSORS,
BlockSleepingBinarySensor,
_build_block_description,
)
else:
async_setup_entry_attribute_entities(
Expand All @@ -257,7 +245,6 @@ async def async_setup_entry(
async_add_entities,
SENSORS,
BlockBinarySensor,
_build_block_description,
)
async_setup_entry_rest(
hass,
Expand Down
15 changes: 15 additions & 0 deletions homeassistant/components/shelly/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,21 @@ async def async_set_temperature(self, **kwargs: Any) -> None:
"""Set new target temperature."""
if (current_temp := kwargs.get(ATTR_TEMPERATURE)) is None:
return

# Shelly TRV accepts target_t in Fahrenheit or Celsius, but you must
# send the units that the device expects
if self.block is not None and self.block.channel is not None:
therm = self.coordinator.device.settings["thermostats"][
int(self.block.channel)
]
LOGGER.debug("Themostat settings: %s", therm)
if therm.get("target_t", {}).get("units", "C") == "F":
current_temp = TemperatureConverter.convert(
cast(float, current_temp),
UnitOfTemperature.CELSIUS,
UnitOfTemperature.FAHRENHEIT,
)

await self.set_state_full_path(target_t_enabled=1, target_t=f"{current_temp}")

async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
Expand Down
13 changes: 13 additions & 0 deletions homeassistant/components/shelly/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
MODEL_DIMMER,
MODEL_DIMMER_2,
MODEL_DUO,
MODEL_DW,
MODEL_DW_2,
MODEL_GAS,
MODEL_HT,
MODEL_MOTION,
MODEL_MOTION_2,
MODEL_RGBW2,
Expand Down Expand Up @@ -55,6 +58,12 @@
MODEL_RGBW2,
)

MODELS_WITH_WRONG_SLEEP_PERIOD: Final = (
MODEL_DW,
MODEL_DW_2,
MODEL_HT,
)

# Bulbs that support white & color modes
DUAL_MODE_LIGHT_MODELS: Final = (
MODEL_BULB,
Expand Down Expand Up @@ -176,6 +185,10 @@
KELVIN_MIN_VALUE_WHITE: Final = 2700
KELVIN_MIN_VALUE_COLOR: Final = 3000

# Sleep period
BLOCK_WRONG_SLEEP_PERIOD = 21600
BLOCK_EXPECTED_SLEEP_PERIOD = 43200

UPTIME_DEVIATION: Final = 5

# Time to wait before reloading entry upon device config change
Expand Down
28 changes: 7 additions & 21 deletions homeassistant/components/shelly/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ def async_setup_entry_attribute_entities(
async_add_entities: AddEntitiesCallback,
sensors: Mapping[tuple[str, str], BlockEntityDescription],
sensor_class: Callable,
description_class: Callable[[RegistryEntry], BlockEntityDescription],
) -> None:
"""Set up entities for attributes."""
coordinator = get_entry_data(hass)[config_entry.entry_id].block
Expand All @@ -56,7 +55,6 @@ def async_setup_entry_attribute_entities(
coordinator,
sensors,
sensor_class,
description_class,
)


Expand Down Expand Up @@ -113,7 +111,6 @@ def async_restore_block_attribute_entities(
coordinator: ShellyBlockCoordinator,
sensors: Mapping[tuple[str, str], BlockEntityDescription],
sensor_class: Callable,
description_class: Callable[[RegistryEntry], BlockEntityDescription],
) -> None:
"""Restore block attributes entities."""
entities = []
Expand All @@ -128,11 +125,12 @@ def async_restore_block_attribute_entities(
continue

attribute = entry.unique_id.split("-")[-1]
description = description_class(entry)
block_type = entry.unique_id.split("-")[-2].split("_")[0]

entities.append(
sensor_class(coordinator, None, attribute, description, entry, sensors)
)
if description := sensors.get((block_type, attribute)):
entities.append(
sensor_class(coordinator, None, attribute, description, entry)
)

if not entities:
return
Expand Down Expand Up @@ -444,7 +442,7 @@ def available(self) -> bool:
"""Available."""
available = super().available

if not available or not self.entity_description.available:
if not available or not self.entity_description.available or self.block is None:
return available

return self.entity_description.available(self.block)
Expand Down Expand Up @@ -559,10 +557,8 @@ def __init__(
attribute: str,
description: BlockEntityDescription,
entry: RegistryEntry | None = None,
sensors: Mapping[tuple[str, str], BlockEntityDescription] | None = None,
) -> None:
"""Initialize the sleeping sensor."""
self.sensors = sensors
self.last_state: State | None = None
self.coordinator = coordinator
self.attribute = attribute
Expand All @@ -587,11 +583,7 @@ def __init__(
@callback
def _update_callback(self) -> None:
"""Handle device update."""
if (
self.block is not None
or not self.coordinator.device.initialized
or self.sensors is None
):
if self.block is not None or not self.coordinator.device.initialized:
super()._update_callback()
return

Expand All @@ -607,13 +599,7 @@ def _update_callback(self) -> None:
if sensor_id != entity_sensor:
continue

description = self.sensors.get((block.type, sensor_id))
if description is None:
continue

self.block = block
self.entity_description = description

LOGGER.debug("Entity %s attached to block", self.name)
super()._update_callback()
return
Expand Down
Loading

0 comments on commit 6e6a5ff

Please sign in to comment.