Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .strict-typing
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,7 @@ homeassistant.components.ohme.*
homeassistant.components.onboarding.*
homeassistant.components.oncue.*
homeassistant.components.onedrive.*
homeassistant.components.onedrive_for_business.*
homeassistant.components.onewire.*
homeassistant.components.onkyo.*
homeassistant.components.open_meteo.*
Expand Down
2 changes: 2 additions & 0 deletions CODEOWNERS

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions homeassistant/brands/microsoft.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"microsoft",
"msteams",
"onedrive",
"onedrive_for_business",
"xbox"
]
}
2 changes: 1 addition & 1 deletion homeassistant/components/google_travel_time/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@
"name": "[%key:component::google_travel_time::options::step::init::data::avoid%]"
},
"config_entry_id": {
"description": "The config entry to use for the service call.",
"description": "The config entry to use for this action.",
"name": "Config entry"
},
"departure_time": {
Expand Down
86 changes: 18 additions & 68 deletions homeassistant/components/light/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,14 +363,12 @@ async def async_handle_light_on_service( # noqa: C901
):
profiles.apply_default(light.entity_id, light.is_on, params)

legacy_supported_color_modes = light._light_internal_supported_color_modes # noqa: SLF001
supported_color_modes = light.supported_color_modes
supported_color_modes = light._light_internal_supported_color_modes # noqa: SLF001

# If a color temperature is specified, emulate it if not supported by the light
if ATTR_COLOR_TEMP_KELVIN in params:
if (
supported_color_modes
and ColorMode.COLOR_TEMP not in supported_color_modes
ColorMode.COLOR_TEMP not in supported_color_modes
and ColorMode.RGBWW in supported_color_modes
):
color_temp = params.pop(ATTR_COLOR_TEMP_KELVIN)
Expand All @@ -381,35 +379,17 @@ async def async_handle_light_on_service( # noqa: C901
light.min_color_temp_kelvin,
light.max_color_temp_kelvin,
)
elif ColorMode.COLOR_TEMP not in legacy_supported_color_modes:
elif ColorMode.COLOR_TEMP not in supported_color_modes:
color_temp = params.pop(ATTR_COLOR_TEMP_KELVIN)
if color_supported(legacy_supported_color_modes):
if color_supported(supported_color_modes):
params[ATTR_HS_COLOR] = color_util.color_temperature_to_hs(
color_temp
)

# If a color is specified, convert to the color space supported by the light
# Backwards compatibility: Fall back to hs color if light.supported_color_modes
# is not implemented
rgb_color: tuple[int, int, int] | None
rgbww_color: tuple[int, int, int, int, int] | None
if not supported_color_modes:
if (rgb_color := params.pop(ATTR_RGB_COLOR, None)) is not None:
params[ATTR_HS_COLOR] = color_util.color_RGB_to_hs(*rgb_color)
elif (xy_color := params.pop(ATTR_XY_COLOR, None)) is not None:
params[ATTR_HS_COLOR] = color_util.color_xy_to_hs(*xy_color)
elif (rgbw_color := params.pop(ATTR_RGBW_COLOR, None)) is not None:
rgb_color = color_util.color_rgbw_to_rgb(*rgbw_color)
params[ATTR_HS_COLOR] = color_util.color_RGB_to_hs(*rgb_color)
elif (rgbww_color := params.pop(ATTR_RGBWW_COLOR, None)) is not None:
# https://github.com/python/mypy/issues/13673
rgb_color = color_util.color_rgbww_to_rgb( # type: ignore[call-arg]
*rgbww_color,
light.min_color_temp_kelvin,
light.max_color_temp_kelvin,
)
params[ATTR_HS_COLOR] = color_util.color_RGB_to_hs(*rgb_color)
elif ATTR_HS_COLOR in params and ColorMode.HS not in supported_color_modes:
if ATTR_HS_COLOR in params and ColorMode.HS not in supported_color_modes:
hs_color = params.pop(ATTR_HS_COLOR)
if ColorMode.RGB in supported_color_modes:
params[ATTR_RGB_COLOR] = color_util.color_hs_to_RGB(*hs_color)
Expand Down Expand Up @@ -517,11 +497,7 @@ async def async_handle_light_on_service( # noqa: C901
params[ATTR_WHITE] = light.brightness

# If both white and brightness are specified, override white
if (
supported_color_modes
and ATTR_WHITE in params
and ColorMode.WHITE in supported_color_modes
):
if ATTR_WHITE in params and ColorMode.WHITE in supported_color_modes:
params[ATTR_WHITE] = params.pop(ATTR_BRIGHTNESS, params[ATTR_WHITE])

# Remove deprecated white value if the light supports color mode
Expand Down Expand Up @@ -793,8 +769,6 @@ class LightEntity(ToggleEntity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
_attr_supported_features: LightEntityFeature = LightEntityFeature(0)
_attr_xy_color: tuple[float, float] | None = None

__color_mode_reported = False

@cached_property
def brightness(self) -> int | None:
"""Return the brightness of this light between 0..255."""
Expand Down Expand Up @@ -1007,10 +981,7 @@ def state_attributes(self) -> dict[str, Any] | None:
"""Return state attributes."""
data: dict[str, Any] = {}
supported_features = self.supported_features
supported_color_modes = self.supported_color_modes
legacy_supported_color_modes = (
supported_color_modes or self._light_internal_supported_color_modes
)
supported_color_modes = self._light_internal_supported_color_modes

_is_on = self.is_on
color_mode = self.color_mode if _is_on else None
Expand All @@ -1025,7 +996,7 @@ def state_attributes(self) -> dict[str, Any] | None:
effect = self.effect
data[ATTR_EFFECT] = effect

self.__validate_color_mode(color_mode, legacy_supported_color_modes, effect)
self.__validate_color_mode(color_mode, supported_color_modes, effect)

data[ATTR_COLOR_MODE] = color_mode

Expand All @@ -1041,15 +1012,15 @@ def state_attributes(self) -> dict[str, Any] | None:
else:
data[ATTR_COLOR_TEMP_KELVIN] = None

if color_supported(legacy_supported_color_modes) or color_temp_supported(
legacy_supported_color_modes
if color_supported(supported_color_modes) or color_temp_supported(
supported_color_modes
):
data[ATTR_HS_COLOR] = None
data[ATTR_RGB_COLOR] = None
data[ATTR_XY_COLOR] = None
if ColorMode.RGBW in legacy_supported_color_modes:
if ColorMode.RGBW in supported_color_modes:
data[ATTR_RGBW_COLOR] = None
if ColorMode.RGBWW in legacy_supported_color_modes:
if ColorMode.RGBWW in supported_color_modes:
data[ATTR_RGBWW_COLOR] = None
if color_mode:
data.update(self._light_internal_convert_color(color_mode))
Expand All @@ -1058,27 +1029,13 @@ def state_attributes(self) -> dict[str, Any] | None:

@property
def _light_internal_supported_color_modes(self) -> set[ColorMode]:
"""Calculate supported color modes with backwards compatibility."""
if (_supported_color_modes := self.supported_color_modes) is not None:
self.__validate_supported_color_modes(_supported_color_modes)
return _supported_color_modes

# Backwards compatibility for supported_color_modes added in 2021.4
# Warning added in 2024.3, remove in 2025.3
if not self.__color_mode_reported and self.__should_report_light_issue():
self.__color_mode_reported = True
report_issue = self._suggest_report_issue()
_LOGGER.warning(
(
"%s (%s) does not set supported color modes, this will stop working"
" in Home Assistant Core 2025.3, please %s"
),
self.entity_id,
type(self),
report_issue,
"""Get validated supported color modes."""
if (_supported_color_modes := self.supported_color_modes) is None:
raise HomeAssistantError(
f"{self.entity_id} ({type(self)}) does not set supported color modes"
)

return {ColorMode.ONOFF}
self.__validate_supported_color_modes(_supported_color_modes)
return _supported_color_modes

@cached_property
def supported_color_modes(self) -> set[ColorMode] | None:
Expand All @@ -1089,10 +1046,3 @@ def supported_color_modes(self) -> set[ColorMode] | None:
def supported_features(self) -> LightEntityFeature:
"""Flag supported features."""
return self._attr_supported_features

def __should_report_light_issue(self) -> bool:
"""Return if light color mode issues should be reported."""
if not self.platform:
return True
# philips_js has known issues, we don't need users to open issues
return self.platform.platform_name != "philips_js"
70 changes: 50 additions & 20 deletions homeassistant/components/miele/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,28 +177,30 @@ class ProgramPhaseTumbleDryer(MieleEnum, missing_to_none=True):

not_running = 0, 512, 535, 536, 537, 65535
program_running = 513
drying = 514
drying = 514, 11018
machine_iron = 515
hand_iron_2 = 516
normal = 517
normal_plus = 518
cooling_down = 519
hand_iron_1 = 520
anti_crease = 521
finished = 522
anti_crease = 521, 11029
finished = 522, 11012
extra_dry = 523
hand_iron = 524
moisten = 526
thermo_spin = 527
timed_drying = 528
warm_air = 529
steam_smoothing = 530
comfort_cooling = 531
comfort_cooling = 531, 11055
rinse_out_lint = 532
rinses = 533
smoothing = 534
slightly_dry = 538
safety_cooling = 539
automatic_start = 11044
perfect_dry_active = 11054


class ProgramPhaseWasherDryer(MieleEnum, missing_to_none=True):
Expand Down Expand Up @@ -509,30 +511,58 @@ class TumbleDryerProgramId(MieleEnum, missing_to_none=True):

no_program = 0, -1
automatic_plus = 1
cottons = 2, 20, 90
minimum_iron = 3, 30
woollens_handcare = 4, 40
delicates = 5, 50
warm_air = 6, 60
cool_air = 7, 70
express = 8, 80
cottons = 2, 20, 90, 10001
minimum_iron = 3, 30, 10016
woollens_handcare = 4, 40, 10081
woollens = 10040
delicates = 5, 50, 10022
warm_air = 6, 60, 10025
cool_air = 7, 70, 10027
express = 8, 80, 10028
cottons_eco = 9, 99003
proofing = 12, 120
denim = 13, 130
proofing = 12, 120, 10057
denim = 13, 130, 10039
shirts = 14, 99004
sportswear = 15, 150
outerwear = 16, 160
silks_handcare = 17, 170
sportswear = 15, 150, 10052
outerwear = 16, 160, 10049
silks_handcare = 17, 170, 10082
standard_pillows = 19, 190
basket_program = 22, 220
basket_program = 22, 220, 10072
cottons_hygiene = 11, 23
smoothing = 24, 240
bed_linen = 31, 99002
eco = 66
smoothing = 24, 240, 10073
bed_linen = 31, 99002, 10047
eco = 66, 10079
gentle_smoothing = 10, 100
gentle_denim = 131
steam_smoothing = 99001
large_pillows = 99005
downs_duvets = 10050
curtains = 10055
quick_power_dry = 10032
automatic = 10044
quick_hygiene = 10076
hygiene = 10080
pillows_sanitize = 10092
custom_program_1 = 13901
custom_program_2 = 13902
custom_program_3 = 13903
custom_program_4 = 13904
custom_program_5 = 13905
custom_program_6 = 13906
custom_program_7 = 13907
custom_program_8 = 13908
custom_program_9 = 13909
custom_program_10 = 13910
custom_program_11 = 13911
custom_program_12 = 13912
custom_program_13 = 13913
custom_program_14 = 13914
custom_program_15 = 13915
custom_program_16 = 13916
custom_program_17 = 13917
custom_program_18 = 13918
custom_program_19 = 13919
custom_program_20 = 13920


class OvenProgramId(MieleEnum, missing_to_none=True):
Expand Down
7 changes: 6 additions & 1 deletion homeassistant/components/miele/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,7 @@
"dissolve_gelatine": "Dissolve gelatine",
"down_duvets": "Down duvets",
"down_filled_items": "Down-filled items",
"downs_duvets": "Downs/Duvets",
"drain_spin": "Drain/spin",
"drop_cookies_1_tray": "Drop cookies (1 tray)",
"drop_cookies_2_trays": "Drop cookies (2 trays)",
Expand Down Expand Up @@ -665,6 +666,7 @@
"pike_fillet": "Pike (fillet)",
"pike_piece": "Pike (piece)",
"pillows": "Pillows",
"pillows_sanitize": "Pillows sanitize",
"pinto_beans": "Pinto beans",
"pizza_oil_cheese_dough_baking_tray": "Pizza, oil cheese dough (baking tray)",
"pizza_oil_cheese_dough_round_baking_tine": "Pizza, oil cheese dough (round baking tine)",
Expand Down Expand Up @@ -732,8 +734,8 @@
"potatoes_waxy_whole_small": "Potatoes (waxy, whole, small)",
"poularde_breast": "Poularde breast",
"poularde_whole": "Poularde (whole)",
"power_fresh": "PowerFresh",
"power_wash": "PowerWash",
"powerfresh": "PowerFresh",
"prawns": "Prawns",
"pre_ironing": "Pre-ironing",
"proofing": "Proofing",
Expand All @@ -746,7 +748,9 @@
"pumpkin_soup": "Pumpkin soup",
"pyrolytic": "Pyrolytic",
"quiche_lorraine": "Quiche Lorraine",
"quick_hygiene": "QuickHygiene",
"quick_mw": "Quick MW",
"quick_power_dry": "QuickPowerDry",
"quick_power_wash": "QuickPowerWash",
"quinces_diced": "Quinces (diced)",
"quinoa": "Quinoa",
Expand Down Expand Up @@ -1004,6 +1008,7 @@
"normal": "Normal",
"normal_plus": "Normal plus",
"not_running": "Not running",
"perfect_dry_active": "PerfectDry active",
"pre_brewing": "Pre-brewing",
"pre_dishwash": "Pre-cleaning",
"pre_heating": "Pre-heating",
Expand Down
Loading
Loading