Merge branch 'main' into alt_detect_method

This commit is contained in:
Bas Nijholt 2023-04-27 13:01:47 -07:00 committed by GitHub
commit 9fe25f06df
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 112 additions and 19 deletions

View file

@ -36,6 +36,8 @@ runs:
run: |
echo "::warning::### WARNING! Deprecation warnings muted with option '--use-pep517' please address this at some point in pytest.yaml. ###"
pip install -r core/requirements.txt --use-pep517
# because they decided to pull codecov the package from PyPI...
sed -i '/codecov/d' core/requirements_test.txt
pip install -r core/requirements_test.txt --use-pep517
pip install -e core/ --use-pep517
pip install ulid-transform # this is in Adaptive-lighting's manifest.json

View file

@ -14,7 +14,7 @@ jobs:
fail-fast: false
matrix:
python-version: ["3.10"]
core-version: ["2023.2.5", "2023.3.6", "2023.4.0", "dev"]
core-version: ["2023.2.5", "2023.3.6", "2023.4.6", "dev"]
steps:
- name: Check out code from GitHub
uses: actions/checkout@v3

View file

@ -6,7 +6,6 @@ from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
from homeassistant.const import CONF_SOURCE
from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.reload import async_setup_reload_service
import voluptuous as vol
from .const import (
@ -36,10 +35,13 @@ CONFIG_SCHEMA = vol.Schema(
)
async def reload_configuration_yaml(event: dict, hass: HomeAssistant):
"""Reload configuration.yaml."""
await hass.services.async_call("homeassistant", "check_config", {})
async def async_setup(hass: HomeAssistant, config: dict[str, Any]):
"""Import integration from config."""
# This will reload any changes the user made to any YAML configurations.
await async_setup_reload_service(hass, DOMAIN, PLATFORMS)
if DOMAIN in config:
for entry in config[DOMAIN]:
@ -55,6 +57,10 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry):
"""Set up the component."""
data = hass.data.setdefault(DOMAIN, {})
# This will reload any changes the user made to any YAML configurations.
# Called during 'quick reload' or hass.reload_config_entry
hass.bus.async_listen("hass.config.entry_updated", reload_configuration_yaml)
undo_listener = config_entry.add_update_listener(async_update_options)
data[config_entry.entry_id] = {UNDO_UPDATE_LISTENER: undo_listener}
for platform in PLATFORMS:

View file

@ -156,12 +156,13 @@ from .const import (
)
_SUPPORT_OPTS = {
"brightness": SUPPORT_BRIGHTNESS,
"color_temp": SUPPORT_COLOR_TEMP,
"color": SUPPORT_COLOR,
"transition": SUPPORT_TRANSITION,
COLOR_MODE_BRIGHTNESS: SUPPORT_BRIGHTNESS,
COLOR_MODE_COLOR_TEMP: SUPPORT_COLOR_TEMP,
CONST_COLOR: SUPPORT_COLOR,
ATTR_TRANSITION: SUPPORT_TRANSITION,
}
VALID_COLOR_MODES = {
COLOR_MODE_BRIGHTNESS: ATTR_BRIGHTNESS,
COLOR_MODE_COLOR_TEMP: ATTR_COLOR_TEMP_KELVIN,
@ -643,16 +644,18 @@ def _expand_light_groups(hass: HomeAssistant, lights: list[str]) -> list[str]:
def _supported_to_attributes(supported):
supported_attributes = {}
supports_colors = False
for mode, attr in VALID_COLOR_MODES.items():
if mode not in supported:
continue
supported_attributes[attr] = True
if (
not supports_colors
and mode != COLOR_MODE_BRIGHTNESS
and mode != COLOR_MODE_COLOR_TEMP
):
supports_colors = True
for mode in supported:
attr = VALID_COLOR_MODES.get(mode)
if attr:
supported_attributes[attr] = True
if attr in COLOR_ATTRS:
supports_colors = True
# ATTR_SUPPORTED_FEATURES only
elif mode in _SUPPORT_OPTS:
supported_attributes[mode] = True
if CONST_COLOR in supported_attributes:
supports_colors = True
supported_attributes.pop(CONST_COLOR)
return supported_attributes, supports_colors

View file

@ -3,9 +3,10 @@
import asyncio
from copy import deepcopy
import datetime
import itertools
import logging
from random import randint
from unittest.mock import patch
from unittest.mock import MagicMock, patch
from homeassistant.components.adaptive_lighting.const import (
ADAPT_BRIGHTNESS_SWITCH,
@ -27,6 +28,7 @@ from homeassistant.components.adaptive_lighting.const import (
CONF_TRANSITION,
CONF_TURN_ON_LIGHTS,
CONF_USE_DEFAULTS,
CONST_COLOR,
DEFAULT_MAX_BRIGHTNESS,
DEFAULT_NAME,
DEFAULT_SLEEP_BRIGHTNESS,
@ -39,7 +41,10 @@ from homeassistant.components.adaptive_lighting.const import (
UNDO_UPDATE_LISTENER,
)
from homeassistant.components.adaptive_lighting.switch import (
_SUPPORT_OPTS,
VALID_COLOR_MODES,
_attributes_have_changed,
_supported_features,
color_difference_redmean,
create_context,
is_our_context,
@ -49,9 +54,13 @@ from homeassistant.components.light import (
ATTR_BRIGHTNESS,
ATTR_BRIGHTNESS_PCT,
ATTR_COLOR_TEMP_KELVIN,
ATTR_MAX_COLOR_TEMP_KELVIN,
ATTR_MIN_COLOR_TEMP_KELVIN,
ATTR_RGB_COLOR,
ATTR_SUPPORTED_COLOR_MODES,
ATTR_TRANSITION,
ATTR_XY_COLOR,
COLOR_MODE_BRIGHTNESS,
)
from homeassistant.components.light import DOMAIN as LIGHT_DOMAIN
from homeassistant.components.light import SERVICE_TURN_OFF
@ -519,6 +528,79 @@ async def test_turn_on_off_listener_not_tracking_untracked_lights(hass):
assert light not in switch.turn_on_off_listener.lights
def test_supported_features(hass): # noqa: C901
"""Test the supported features of a light."""
possible_legacy_features = {}
MAX_COMBINATIONS = 4 # maximum number of elements that can be combined
for i in range(1, min(MAX_COMBINATIONS, len(_SUPPORT_OPTS)) + 1):
for combination in itertools.combinations(_SUPPORT_OPTS.keys(), i):
key = "_".join(combination)
value = [v for k, v in _SUPPORT_OPTS.items() if k in combination]
possible_legacy_features[key] = value
possible_color_modes = {}
for i in range(1, len(VALID_COLOR_MODES) + 1):
for combination in itertools.combinations(VALID_COLOR_MODES.keys(), i):
key = "_".join(combination)
value = [v for k, v in VALID_COLOR_MODES.items() if k in combination]
possible_color_modes[key] = value
# create a mock HomeAssistant object
hass = MagicMock()
# iterate over possible legacy features
for feature_key, feature_values in possible_legacy_features.items():
# _LOGGER.debug(feature_values)
# set the attributes of the mock state object to the possible legacy feature values
state_attrs = {ATTR_SUPPORTED_FEATURES: sum(feature_values)}
hass.states.get.return_value.attributes = state_attrs
# iterate over possible color modes
for mode_key, mode_values in possible_color_modes.items():
# _LOGGER.debug(mode_values)
# set the attributes of the mock state object to the possible color mode values
state_attrs[ATTR_SUPPORTED_COLOR_MODES] = set(mode_values)
hass.states.get.return_value.attributes = state_attrs
# Handle both the new and the old _supported_features.
result = _supported_features(hass, ENTITY_LIGHT)
supported, supports_colors = (
result if isinstance(result, tuple) else (result, None)
)
expected_supported = {} if supports_colors is not None else set()
for mode, attr in VALID_COLOR_MODES.items():
if mode in mode_values:
if supports_colors is None:
expected_supported.add(mode)
else:
expected_supported[attr] = True
if supports_colors is True:
expected_supported[COLOR_MODE_BRIGHTNESS] = True
for opt, value in _SUPPORT_OPTS.items():
if value in feature_values:
if supports_colors is None:
expected_supported.add(opt)
else:
if supports_colors is True:
expected_supported[COLOR_MODE_BRIGHTNESS] = True
if opt in VALID_COLOR_MODES:
expected_supported[VALID_COLOR_MODES[opt]] = True
elif opt != CONST_COLOR:
expected_supported[opt] = True
if ATTR_MIN_COLOR_TEMP_KELVIN in supported:
supported.pop(ATTR_MIN_COLOR_TEMP_KELVIN)
if ATTR_MAX_COLOR_TEMP_KELVIN in supported:
supported.pop(ATTR_MAX_COLOR_TEMP_KELVIN)
assert supported == expected_supported, (
f"\nExpected supported: {expected_supported}\n"
f"Actual supported: {supported}\n"
f"feature_values: {feature_values}\n"
f"mode_values: {mode_values}\n"
f"supports_colors: {supports_colors}\n"
)
@pytest.mark.dependency(depends=GLOBAL_TEST_DEPENDENCIES)
async def test_manual_control(hass):
"""Test the 'manual control' tracking."""