Skip to content

Commit

Permalink
2024.12.4 (#133422)
Browse files Browse the repository at this point in the history
  • Loading branch information
frenck authored Dec 17, 2024
2 parents 46db396 + 517f3fa commit a5eb816
Show file tree
Hide file tree
Showing 40 changed files with 411 additions and 202 deletions.
8 changes: 7 additions & 1 deletion homeassistant/block_async_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ def _check_sleep_call_allowed(mapped_args: dict[str, Any]) -> bool:
return False


def _check_load_verify_locations_call_allowed(mapped_args: dict[str, Any]) -> bool:
# If only cadata is passed, we can ignore it
kwargs = mapped_args.get("kwargs")
return bool(kwargs and len(kwargs) == 1 and "cadata" in kwargs)


@dataclass(slots=True, frozen=True)
class BlockingCall:
"""Class to hold information about a blocking call."""
Expand Down Expand Up @@ -158,7 +164,7 @@ class BlockingCall:
original_func=SSLContext.load_verify_locations,
object=SSLContext,
function="load_verify_locations",
check_allowed=None,
check_allowed=_check_load_verify_locations_call_allowed,
strict=False,
strict_core=False,
skip_for_tests=True,
Expand Down
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==8.10.0", "yalexs-ble==2.5.2"]
"requirements": ["yalexs==8.10.0", "yalexs-ble==2.5.5"]
}
6 changes: 3 additions & 3 deletions homeassistant/components/fibaro/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,16 +274,16 @@ def hvac_mode(self) -> HVACMode | None:
if isinstance(fibaro_operation_mode, str):
with suppress(ValueError):
return HVACMode(fibaro_operation_mode.lower())
elif fibaro_operation_mode in OPMODES_HVAC:
# when the mode cannot be instantiated a preset_mode is selected
return HVACMode.AUTO
if fibaro_operation_mode in OPMODES_HVAC:
return OPMODES_HVAC[fibaro_operation_mode]
return None

def set_hvac_mode(self, hvac_mode: HVACMode) -> None:
"""Set new target operation mode."""
if not self._op_mode_device:
return
if self.preset_mode:
return

if "setOperatingMode" in self._op_mode_device.fibaro_device.actions:
self._op_mode_device.action("setOperatingMode", HA_OPMODES_HVAC[hvac_mode])
Expand Down
52 changes: 32 additions & 20 deletions homeassistant/components/flexit_bacnet/number.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ class FlexitNumberEntityDescription(NumberEntityDescription):
"""Describes a Flexit number entity."""

native_value_fn: Callable[[FlexitBACnet], float]
native_max_value_fn: Callable[[FlexitBACnet], int]
native_min_value_fn: Callable[[FlexitBACnet], int]
set_native_value_fn: Callable[[FlexitBACnet], Callable[[int], Awaitable[None]]]


Expand All @@ -37,121 +39,121 @@ class FlexitNumberEntityDescription(NumberEntityDescription):
key="away_extract_fan_setpoint",
translation_key="away_extract_fan_setpoint",
device_class=NumberDeviceClass.POWER_FACTOR,
native_min_value=0,
native_max_value=100,
native_step=1,
mode=NumberMode.SLIDER,
native_value_fn=lambda device: device.fan_setpoint_extract_air_away,
set_native_value_fn=lambda device: device.set_fan_setpoint_extract_air_away,
native_unit_of_measurement=PERCENTAGE,
native_max_value_fn=lambda device: int(device.fan_setpoint_extract_air_home),
native_min_value_fn=lambda _: 30,
),
FlexitNumberEntityDescription(
key="away_supply_fan_setpoint",
translation_key="away_supply_fan_setpoint",
device_class=NumberDeviceClass.POWER_FACTOR,
native_min_value=0,
native_max_value=100,
native_step=1,
mode=NumberMode.SLIDER,
native_value_fn=lambda device: device.fan_setpoint_supply_air_away,
set_native_value_fn=lambda device: device.set_fan_setpoint_supply_air_away,
native_unit_of_measurement=PERCENTAGE,
native_max_value_fn=lambda device: int(device.fan_setpoint_supply_air_home),
native_min_value_fn=lambda _: 30,
),
FlexitNumberEntityDescription(
key="cooker_hood_extract_fan_setpoint",
translation_key="cooker_hood_extract_fan_setpoint",
device_class=NumberDeviceClass.POWER_FACTOR,
native_min_value=0,
native_max_value=100,
native_step=1,
mode=NumberMode.SLIDER,
native_value_fn=lambda device: device.fan_setpoint_extract_air_cooker,
set_native_value_fn=lambda device: device.set_fan_setpoint_extract_air_cooker,
native_unit_of_measurement=PERCENTAGE,
native_max_value_fn=lambda _: 100,
native_min_value_fn=lambda _: 30,
),
FlexitNumberEntityDescription(
key="cooker_hood_supply_fan_setpoint",
translation_key="cooker_hood_supply_fan_setpoint",
device_class=NumberDeviceClass.POWER_FACTOR,
native_min_value=0,
native_max_value=100,
native_step=1,
mode=NumberMode.SLIDER,
native_value_fn=lambda device: device.fan_setpoint_supply_air_cooker,
set_native_value_fn=lambda device: device.set_fan_setpoint_supply_air_cooker,
native_unit_of_measurement=PERCENTAGE,
native_max_value_fn=lambda _: 100,
native_min_value_fn=lambda _: 30,
),
FlexitNumberEntityDescription(
key="fireplace_extract_fan_setpoint",
translation_key="fireplace_extract_fan_setpoint",
device_class=NumberDeviceClass.POWER_FACTOR,
native_min_value=0,
native_max_value=100,
native_step=1,
mode=NumberMode.SLIDER,
native_value_fn=lambda device: device.fan_setpoint_extract_air_fire,
set_native_value_fn=lambda device: device.set_fan_setpoint_extract_air_fire,
native_unit_of_measurement=PERCENTAGE,
native_max_value_fn=lambda _: 100,
native_min_value_fn=lambda _: 30,
),
FlexitNumberEntityDescription(
key="fireplace_supply_fan_setpoint",
translation_key="fireplace_supply_fan_setpoint",
device_class=NumberDeviceClass.POWER_FACTOR,
native_min_value=0,
native_max_value=100,
native_step=1,
mode=NumberMode.SLIDER,
native_value_fn=lambda device: device.fan_setpoint_supply_air_fire,
set_native_value_fn=lambda device: device.set_fan_setpoint_supply_air_fire,
native_unit_of_measurement=PERCENTAGE,
native_max_value_fn=lambda _: 100,
native_min_value_fn=lambda _: 30,
),
FlexitNumberEntityDescription(
key="high_extract_fan_setpoint",
translation_key="high_extract_fan_setpoint",
device_class=NumberDeviceClass.POWER_FACTOR,
native_min_value=0,
native_max_value=100,
native_step=1,
mode=NumberMode.SLIDER,
native_value_fn=lambda device: device.fan_setpoint_extract_air_high,
set_native_value_fn=lambda device: device.set_fan_setpoint_extract_air_high,
native_unit_of_measurement=PERCENTAGE,
native_max_value_fn=lambda _: 100,
native_min_value_fn=lambda device: int(device.fan_setpoint_extract_air_home),
),
FlexitNumberEntityDescription(
key="high_supply_fan_setpoint",
translation_key="high_supply_fan_setpoint",
device_class=NumberDeviceClass.POWER_FACTOR,
native_min_value=0,
native_max_value=100,
native_step=1,
mode=NumberMode.SLIDER,
native_value_fn=lambda device: device.fan_setpoint_supply_air_high,
set_native_value_fn=lambda device: device.set_fan_setpoint_supply_air_high,
native_unit_of_measurement=PERCENTAGE,
native_max_value_fn=lambda _: 100,
native_min_value_fn=lambda device: int(device.fan_setpoint_supply_air_home),
),
FlexitNumberEntityDescription(
key="home_extract_fan_setpoint",
translation_key="home_extract_fan_setpoint",
device_class=NumberDeviceClass.POWER_FACTOR,
native_min_value=0,
native_max_value=100,
native_step=1,
mode=NumberMode.SLIDER,
native_value_fn=lambda device: device.fan_setpoint_extract_air_home,
set_native_value_fn=lambda device: device.set_fan_setpoint_extract_air_home,
native_unit_of_measurement=PERCENTAGE,
native_max_value_fn=lambda _: 100,
native_min_value_fn=lambda device: int(device.fan_setpoint_extract_air_away),
),
FlexitNumberEntityDescription(
key="home_supply_fan_setpoint",
translation_key="home_supply_fan_setpoint",
device_class=NumberDeviceClass.POWER_FACTOR,
native_min_value=0,
native_max_value=100,
native_step=1,
mode=NumberMode.SLIDER,
native_value_fn=lambda device: device.fan_setpoint_supply_air_home,
set_native_value_fn=lambda device: device.set_fan_setpoint_supply_air_home,
native_unit_of_measurement=PERCENTAGE,
native_max_value_fn=lambda _: 100,
native_min_value_fn=lambda device: int(device.fan_setpoint_supply_air_away),
),
)

Expand Down Expand Up @@ -192,6 +194,16 @@ def native_value(self) -> float:
"""Return the state of the number."""
return self.entity_description.native_value_fn(self.coordinator.device)

@property
def native_max_value(self) -> float:
"""Return the native max value of the number."""
return self.entity_description.native_max_value_fn(self.coordinator.device)

@property
def native_min_value(self) -> float:
"""Return the native min value of the number."""
return self.entity_description.native_min_value_fn(self.coordinator.device)

async def async_set_native_value(self, value: float) -> None:
"""Update the current value."""
set_native_value_fn = self.entity_description.set_native_value_fn(
Expand Down
7 changes: 2 additions & 5 deletions homeassistant/components/history/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

from . import websocket_api
from .const import DOMAIN
from .helpers import entities_may_have_state_changes_after, has_states_before
from .helpers import entities_may_have_state_changes_after, has_recorder_run_after

CONF_ORDER = "use_include_order"

Expand Down Expand Up @@ -107,10 +107,7 @@ async def get(
no_attributes = "no_attributes" in request.query

if (
# has_states_before will return True if there are states older than
# end_time. If it's false, we know there are no states in the
# database up until end_time.
(end_time and not has_states_before(hass, end_time))
(end_time and not has_recorder_run_after(hass, end_time))
or not include_start_time_state
and entity_ids
and not entities_may_have_state_changes_after(
Expand Down
13 changes: 6 additions & 7 deletions homeassistant/components/history/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from datetime import datetime as dt

from homeassistant.components.recorder import get_instance
from homeassistant.components.recorder.models import process_timestamp
from homeassistant.core import HomeAssistant


Expand All @@ -25,10 +26,8 @@ def entities_may_have_state_changes_after(
return False


def has_states_before(hass: HomeAssistant, run_time: dt) -> bool:
"""Check if the recorder has states as old or older than run_time.
Returns True if there may be such states.
"""
oldest_ts = get_instance(hass).states_manager.oldest_ts
return oldest_ts is not None and run_time.timestamp() >= oldest_ts
def has_recorder_run_after(hass: HomeAssistant, run_time: dt) -> bool:
"""Check if the recorder has any runs after a specific time."""
return run_time >= process_timestamp(
get_instance(hass).recorder_runs_manager.first.start
)
7 changes: 2 additions & 5 deletions homeassistant/components/history/websocket_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
import homeassistant.util.dt as dt_util

from .const import EVENT_COALESCE_TIME, MAX_PENDING_HISTORY_STATES
from .helpers import entities_may_have_state_changes_after, has_states_before
from .helpers import entities_may_have_state_changes_after, has_recorder_run_after

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -142,10 +142,7 @@ async def ws_get_history_during_period(
no_attributes = msg["no_attributes"]

if (
# has_states_before will return True if there are states older than
# end_time. If it's false, we know there are no states in the
# database up until end_time.
(end_time and not has_states_before(hass, end_time))
(end_time and not has_recorder_run_after(hass, end_time))
or not include_start_time_state
and entity_ids
and not entities_may_have_state_changes_after(
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/holiday/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/holiday",
"iot_class": "local_polling",
"requirements": ["holidays==0.62", "babel==2.15.0"]
"requirements": ["holidays==0.63", "babel==2.15.0"]
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class HomeKitAlarmControlPanelEntity(HomeKitEntity, AlarmControlPanelEntity):
| AlarmControlPanelEntityFeature.ARM_AWAY
| AlarmControlPanelEntityFeature.ARM_NIGHT
)
_attr_code_arm_required = False

def get_characteristic_types(self) -> list[str]:
"""Define the homekit characteristics the entity cares about."""
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/imgw_pib/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/imgw_pib",
"iot_class": "cloud_polling",
"requirements": ["imgw_pib==1.0.6"]
"requirements": ["imgw_pib==1.0.7"]
}
2 changes: 1 addition & 1 deletion homeassistant/components/incomfort/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/incomfort",
"iot_class": "local_polling",
"loggers": ["incomfortclient"],
"requirements": ["incomfort-client==0.6.3-1"]
"requirements": ["incomfort-client==0.6.4"]
}
5 changes: 4 additions & 1 deletion homeassistant/components/lifx/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"LIFX Ceiling",
"LIFX Clean",
"LIFX Color",
"LIFX Colour",
"LIFX DLCOL",
"LIFX Dlight",
"LIFX DLWW",
Expand All @@ -35,20 +36,22 @@
"LIFX Neon",
"LIFX Nightvision",
"LIFX PAR38",
"LIFX Permanent Outdoor",
"LIFX Pls",
"LIFX Plus",
"LIFX Round",
"LIFX Square",
"LIFX String",
"LIFX Tile",
"LIFX Tube",
"LIFX White",
"LIFX Z"
]
},
"iot_class": "local_polling",
"loggers": ["aiolifx", "aiolifx_effects", "bitstring"],
"requirements": [
"aiolifx==1.1.1",
"aiolifx==1.1.2",
"aiolifx-effects==0.3.2",
"aiolifx-themes==0.5.5"
]
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/media_extractor/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
"iot_class": "calculated",
"loggers": ["yt_dlp"],
"quality_scale": "internal",
"requirements": ["yt-dlp[default]==2024.12.06"],
"requirements": ["yt-dlp[default]==2024.12.13"],
"single_config_entry": true
}
17 changes: 17 additions & 0 deletions homeassistant/components/python_script/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
"""Component to allow running Python scripts."""

from collections.abc import Mapping, Sequence
import datetime
import glob
import logging
from numbers import Number
import operator
import os
import time
import types
from typing import Any

from RestrictedPython import (
Expand Down Expand Up @@ -167,6 +169,20 @@ def python_script_service_handler(call: ServiceCall) -> ServiceResponse:
}


def guarded_import(
name: str,
globals: Mapping[str, object] | None = None,
locals: Mapping[str, object] | None = None,
fromlist: Sequence[str] = (),
level: int = 0,
) -> types.ModuleType:
"""Guard imports."""
# Allow import of _strptime needed by datetime.datetime.strptime
if name == "_strptime":
return __import__(name, globals, locals, fromlist, level)
raise ScriptError(f"Not allowed to import {name}")


def guarded_inplacevar(op: str, target: Any, operand: Any) -> Any:
"""Implement augmented-assign (+=, -=, etc.) operators for restricted code.
Expand Down Expand Up @@ -232,6 +248,7 @@ def protected_getattr(obj, name, default=None):
return getattr(obj, name, default)

extra_builtins = {
"__import__": guarded_import,
"datetime": datetime,
"sorted": sorted,
"time": TimeWrapper(),
Expand Down
Loading

0 comments on commit a5eb816

Please sign in to comment.