mirror of
https://github.com/basnijholt/adaptive-lighting.git
synced 2026-09-16 16:54:04 +02:00
Fix new-group defaults + tidy section collapse defaults
Thread 2 (bug): runtime range number entities seeded from native_min on a fresh profile (only a name stored at setup), so new groups ran at max_brightness=1% and a 1000-1000K color-temp range until the options dialog was saved once. Each RANGE_ENTITIES row now carries a sensible DEFAULT_* and _options_value() falls back to it. Adds a regression test. Thread 3: collapse 'Sun schedule' and 'Light control' by default (now 2 open / 5 closed): Targets + Daytime curve expanded, the rest collapsed. Existing profiles unaffected (their options are already saved); only newly-created groups get the corrected seed. Bump 2.3.0 -> 2.3.1-cdit.1.
This commit is contained in:
parent
a6b0a1bc95
commit
61be07c179
5 changed files with 55 additions and 5 deletions
|
|
@ -234,7 +234,7 @@ def _build_options_schema(
|
|||
): _sun_event_selector(),
|
||||
},
|
||||
),
|
||||
{"collapsed": False},
|
||||
{"collapsed": True},
|
||||
)
|
||||
|
||||
# An illuminance EntitySelector rejects an empty string, so we must NOT
|
||||
|
|
@ -278,7 +278,7 @@ def _build_options_schema(
|
|||
): BooleanSelector(),
|
||||
},
|
||||
),
|
||||
{"collapsed": False},
|
||||
{"collapsed": True},
|
||||
)
|
||||
|
||||
advanced_schema: dict[Any, Any] = {
|
||||
|
|
|
|||
|
|
@ -169,6 +169,7 @@ RANGE_ENTITIES: list[dict[str, Any]] = [
|
|||
{
|
||||
"field_key": "min_brightness",
|
||||
"conf_key": CONF_MIN_BRIGHTNESS,
|
||||
"default": DEFAULT_MIN_BRIGHTNESS,
|
||||
"name": "Min brightness",
|
||||
"native_min": 1,
|
||||
"native_max": 100,
|
||||
|
|
@ -179,6 +180,7 @@ RANGE_ENTITIES: list[dict[str, Any]] = [
|
|||
{
|
||||
"field_key": "max_brightness",
|
||||
"conf_key": CONF_MAX_BRIGHTNESS,
|
||||
"default": DEFAULT_MAX_BRIGHTNESS,
|
||||
"name": "Max brightness",
|
||||
"native_min": 1,
|
||||
"native_max": 100,
|
||||
|
|
@ -189,6 +191,7 @@ RANGE_ENTITIES: list[dict[str, Any]] = [
|
|||
{
|
||||
"field_key": "min_color_temp",
|
||||
"conf_key": CONF_MIN_COLOR_TEMP,
|
||||
"default": DEFAULT_MIN_COLOR_TEMP,
|
||||
"name": "Min color temp",
|
||||
"native_min": 1000,
|
||||
"native_max": 10000,
|
||||
|
|
@ -199,6 +202,7 @@ RANGE_ENTITIES: list[dict[str, Any]] = [
|
|||
{
|
||||
"field_key": "max_color_temp",
|
||||
"conf_key": CONF_MAX_COLOR_TEMP,
|
||||
"default": DEFAULT_MAX_COLOR_TEMP,
|
||||
"name": "Max color temp",
|
||||
"native_min": 1000,
|
||||
"native_max": 10000,
|
||||
|
|
|
|||
|
|
@ -9,5 +9,5 @@
|
|||
"iot_class": "calculated",
|
||||
"issue_tracker": "https://github.com/CaseyRo/adaptive-lighting/issues",
|
||||
"requirements": ["ulid-transform"],
|
||||
"version": "2.3.0-cdit.1"
|
||||
"version": "2.3.1-cdit.1"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ async def async_setup_entry(
|
|||
entry=config_entry,
|
||||
field_key=row["field_key"],
|
||||
conf_key=row["conf_key"],
|
||||
default=row["default"],
|
||||
display_name=row["name"],
|
||||
native_min=row["native_min"],
|
||||
native_max=row["native_max"],
|
||||
|
|
@ -74,6 +75,7 @@ class AdaptiveRangeNumber(RestoreNumber):
|
|||
entry: ConfigEntry,
|
||||
field_key: str,
|
||||
conf_key: str,
|
||||
default: float,
|
||||
display_name: str,
|
||||
native_min: float,
|
||||
native_max: float,
|
||||
|
|
@ -85,6 +87,7 @@ class AdaptiveRangeNumber(RestoreNumber):
|
|||
self._entry = entry
|
||||
self._field_key = field_key
|
||||
self._conf_key = conf_key
|
||||
self._default = default
|
||||
self._attr_name = display_name
|
||||
self._attr_translation_key = field_key
|
||||
self._attr_unique_id = f"{entry.entry_id}_{field_key}"
|
||||
|
|
@ -108,10 +111,17 @@ class AdaptiveRangeNumber(RestoreNumber):
|
|||
)
|
||||
|
||||
def _options_value(self) -> float:
|
||||
"""Read the seed value from entry.options (typed cast)."""
|
||||
"""Read the seed value from entry.options (typed cast).
|
||||
|
||||
On a freshly-created profile neither ``entry.options`` nor
|
||||
``entry.data`` carries the range keys (setup only stores the name),
|
||||
so fall back to the field's sensible ``DEFAULT_*`` rather than the
|
||||
slider's ``native_min`` — otherwise a new group would come up at
|
||||
max_brightness=1% and a 1000-1000K color-temp range.
|
||||
"""
|
||||
raw = self._entry.options.get(self._conf_key)
|
||||
if raw is None:
|
||||
raw = self._entry.data.get(self._conf_key, self._attr_native_min_value)
|
||||
raw = self._entry.data.get(self._conf_key, self._default)
|
||||
return float(raw)
|
||||
|
||||
async def async_added_to_hass(self) -> None:
|
||||
|
|
|
|||
|
|
@ -25,6 +25,10 @@ from custom_components.adaptive_lighting.const import (
|
|||
CONF_MIN_BRIGHTNESS,
|
||||
CONF_MIN_COLOR_TEMP,
|
||||
CONFIG_ENTRY_VERSION,
|
||||
DEFAULT_MAX_BRIGHTNESS,
|
||||
DEFAULT_MAX_COLOR_TEMP,
|
||||
DEFAULT_MIN_BRIGHTNESS,
|
||||
DEFAULT_MIN_COLOR_TEMP,
|
||||
DOMAIN,
|
||||
)
|
||||
|
||||
|
|
@ -126,6 +130,38 @@ async def test_number_entity_attributes(hass, field_key, expected) -> None:
|
|||
assert attrs["mode"] == NumberMode.SLIDER
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 7.4b — Fresh profile (only a name) seeds sensible DEFAULT_*, not native_min
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("field_key", "expected_default"),
|
||||
[
|
||||
("min_brightness", DEFAULT_MIN_BRIGHTNESS),
|
||||
("max_brightness", DEFAULT_MAX_BRIGHTNESS),
|
||||
("min_color_temp", DEFAULT_MIN_COLOR_TEMP),
|
||||
("max_color_temp", DEFAULT_MAX_COLOR_TEMP),
|
||||
],
|
||||
)
|
||||
async def test_new_profile_seeds_sensible_defaults(
|
||||
hass,
|
||||
field_key,
|
||||
expected_default,
|
||||
) -> None:
|
||||
"""A profile created with only a name must come up at DEFAULT_*.
|
||||
|
||||
Regression: the seed previously fell back to the slider's native_min,
|
||||
so a brand-new group ran at max_brightness=1% and a collapsed
|
||||
1000-1000K color-temp range until the options dialog was saved once.
|
||||
"""
|
||||
entry = await _setup_entry(hass) # data={name}, options={}
|
||||
eid = _resolve_entity_id(hass, entry, field_key)
|
||||
state = hass.states.get(eid)
|
||||
assert state is not None
|
||||
assert float(state.state) == float(expected_default)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 7.5 — async_set_native_value does NOT write to entry.options
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue