mirror of
https://github.com/basnijholt/adaptive-lighting.git
synced 2026-09-12 06:44:04 +02:00
Clarify accumulated diagnostics values
This commit is contained in:
parent
fe2fd8d195
commit
07a25aefce
4 changed files with 142 additions and 11 deletions
11
README.md
11
README.md
|
|
@ -585,9 +585,14 @@ logger:
|
|||
After the issue occurs, create a new issue report with the log (`/config/home-assistant.log`).
|
||||
|
||||
For support, use Home Assistant's **Download diagnostics** action on the
|
||||
Adaptive Lighting config entry. The download is an on-demand snapshot of that
|
||||
profile's current switch and effective-light facts. It does not create live
|
||||
sensors; existing switch attributes remain the interface for automations.
|
||||
Adaptive Lighting config entry. The download is an on-demand snapshot of the
|
||||
profile's current switches and currently tracked light targets. It does not
|
||||
refresh group membership or predict targets a disabled profile would use after
|
||||
being enabled. It does not create live sensors; existing switch attributes
|
||||
remain the interface for automations.
|
||||
The reported last adaptation values are the shared manager's latest retained
|
||||
value for each attribute. They can come from different commands and do not
|
||||
represent one sent command or the current desired state.
|
||||
<!-- SECTION:troubleshooting-intro:END -->
|
||||
|
||||
<!-- SECTION:common-problems:START -->
|
||||
|
|
|
|||
|
|
@ -37,11 +37,15 @@ _TARGET_ATTRIBUTES = (
|
|||
)
|
||||
|
||||
|
||||
def _last_sent_target(
|
||||
def _last_adaptation_values(
|
||||
manager: AdaptiveLightingManager,
|
||||
light: str,
|
||||
) -> dict[str, Any] | None:
|
||||
"""Return allowlisted target attributes from the last adaptation command."""
|
||||
"""Return latest retained value for each allowlisted adaptation attribute.
|
||||
|
||||
Values may come from different commands because the manager merges partial
|
||||
service data per attribute.
|
||||
"""
|
||||
service_data = manager.last_service_data.get(light)
|
||||
if service_data is None:
|
||||
return None
|
||||
|
|
@ -108,7 +112,10 @@ async def async_get_config_entry_diagnostics(
|
|||
"color": bool(manual_control & LightControlAttributes.COLOR),
|
||||
},
|
||||
"global_manager_autoreset_seconds": _autoreset_seconds(manager, light),
|
||||
"global_manager_last_sent_target": _last_sent_target(manager, light),
|
||||
"global_manager_last_adaptation_values": _last_adaptation_values(
|
||||
manager,
|
||||
light,
|
||||
),
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -26,9 +26,14 @@ logger:
|
|||
After the issue occurs, create a new issue report with the log (`/config/home-assistant.log`).
|
||||
|
||||
For support, use Home Assistant's **Download diagnostics** action on the
|
||||
Adaptive Lighting config entry. The download is an on-demand snapshot of that
|
||||
profile's current switch and effective-light facts. It does not create live
|
||||
sensors; existing switch attributes remain the interface for automations.
|
||||
Adaptive Lighting config entry. The download is an on-demand snapshot of the
|
||||
profile's current switches and currently tracked light targets. It does not
|
||||
refresh group membership or predict targets a disabled profile would use after
|
||||
being enabled. It does not create live sensors; existing switch attributes
|
||||
remain the interface for automations.
|
||||
The reported last adaptation values are the shared manager's latest retained
|
||||
value for each attribute. They can come from different commands and do not
|
||||
represent one sent command or the current desired state.
|
||||
|
||||
<!-- OUTPUT:END -->
|
||||
|
||||
|
|
|
|||
|
|
@ -2,10 +2,13 @@
|
|||
|
||||
import json
|
||||
from copy import deepcopy
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
from homeassistant.components.adaptive_lighting.adaptation_utils import (
|
||||
AdaptationData,
|
||||
LightControlAttributes,
|
||||
_create_service_call_data_iterator,
|
||||
)
|
||||
from homeassistant.components.adaptive_lighting.const import (
|
||||
ATTR_ADAPTIVE_LIGHTING_MANAGER,
|
||||
|
|
@ -23,11 +26,14 @@ from homeassistant.components.light import (
|
|||
ATTR_COLOR_TEMP_KELVIN,
|
||||
ATTR_RGB_COLOR,
|
||||
ATTR_TRANSITION,
|
||||
SERVICE_TURN_ON,
|
||||
)
|
||||
from homeassistant.components.light import DOMAIN as LIGHT_DOMAIN
|
||||
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
ATTR_SERVICE_DATA,
|
||||
CONF_LIGHTS,
|
||||
CONF_NAME,
|
||||
EVENT_CALL_SERVICE,
|
||||
|
|
@ -35,6 +41,7 @@ from homeassistant.const import (
|
|||
STATE_OFF,
|
||||
STATE_UNAVAILABLE,
|
||||
)
|
||||
from homeassistant.core import State
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
from tests.components.diagnostics import get_diagnostics_for_config_entry
|
||||
|
|
@ -162,7 +169,7 @@ async def test_config_entry_diagnostics_reports_allowlisted_current_facts(
|
|||
assert result["lights"]["light_1"][
|
||||
"global_manager_autoreset_seconds"
|
||||
] == pytest.approx(60, abs=2)
|
||||
assert result["lights"]["light_1"]["global_manager_last_sent_target"] == {
|
||||
assert result["lights"]["light_1"]["global_manager_last_adaptation_values"] == {
|
||||
ATTR_BRIGHTNESS: 123,
|
||||
ATTR_COLOR_TEMP_KELVIN: 3456,
|
||||
ATTR_RGB_COLOR: [12, 34, 56],
|
||||
|
|
@ -175,7 +182,7 @@ async def test_config_entry_diagnostics_reports_allowlisted_current_facts(
|
|||
"color": True,
|
||||
},
|
||||
"global_manager_autoreset_seconds": pytest.approx(60, abs=2),
|
||||
"global_manager_last_sent_target": None,
|
||||
"global_manager_last_adaptation_values": None,
|
||||
}
|
||||
|
||||
serialized = json.dumps(result, sort_keys=True)
|
||||
|
|
@ -194,6 +201,113 @@ async def test_config_entry_diagnostics_reports_allowlisted_current_facts(
|
|||
assert sensitive_value not in serialized
|
||||
|
||||
|
||||
async def test_diagnostics_labels_accumulated_partial_adaptation_values(
|
||||
hass,
|
||||
cleanup_diagnostics,
|
||||
):
|
||||
"""Diagnostics do not describe merged per-attribute history as one command."""
|
||||
await setup_lights(hass)
|
||||
entry, switch = await _setup_entry(
|
||||
hass,
|
||||
"Private Profile",
|
||||
[ENTITY_LIGHT_1],
|
||||
)
|
||||
commands = [
|
||||
{
|
||||
ATTR_ENTITY_ID: ENTITY_LIGHT_1,
|
||||
ATTR_BRIGHTNESS: 100,
|
||||
ATTR_RGB_COLOR: (12, 34, 56),
|
||||
ATTR_TRANSITION: 2,
|
||||
},
|
||||
{ATTR_ENTITY_ID: ENTITY_LIGHT_1, ATTR_BRIGHTNESS: 180},
|
||||
{ATTR_ENTITY_ID: ENTITY_LIGHT_1, ATTR_COLOR_TEMP_KELVIN: 3500},
|
||||
]
|
||||
call_events = []
|
||||
remove_listener = hass.bus.async_listen(EVENT_CALL_SERVICE, call_events.append)
|
||||
|
||||
await switch._execute_adaptation_calls(
|
||||
AdaptationData(
|
||||
entity_id=ENTITY_LIGHT_1,
|
||||
context=switch.create_context("diagnostics_test"),
|
||||
sleep_time=0,
|
||||
service_call_datas=_create_service_call_data_iterator(
|
||||
hass,
|
||||
commands,
|
||||
filter_by_state=False,
|
||||
),
|
||||
force=True,
|
||||
max_length=len(commands),
|
||||
attributes=LightControlAttributes.ALL,
|
||||
),
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
remove_listener()
|
||||
|
||||
actual_commands = [
|
||||
event.data[ATTR_SERVICE_DATA]
|
||||
for event in call_events
|
||||
if event.data["domain"] == LIGHT_DOMAIN
|
||||
and event.data["service"] == SERVICE_TURN_ON
|
||||
]
|
||||
assert actual_commands == commands
|
||||
|
||||
result = await async_get_config_entry_diagnostics(hass, entry)
|
||||
light = result["lights"]["light_1"]
|
||||
assert "global_manager_last_sent_target" not in light
|
||||
assert light["global_manager_last_adaptation_values"] == {
|
||||
ATTR_BRIGHTNESS: 180,
|
||||
ATTR_COLOR_TEMP_KELVIN: 3500,
|
||||
ATTR_RGB_COLOR: [12, 34, 56],
|
||||
ATTR_TRANSITION: 2,
|
||||
}
|
||||
|
||||
|
||||
async def test_diagnostics_preserves_restored_off_profile_tracked_group(hass):
|
||||
"""Diagnostics report tracked targets without refreshing late groups."""
|
||||
await setup_lights(hass)
|
||||
group = "light.private_late_group"
|
||||
members = [ENTITY_LIGHT_1, ENTITY_LIGHT_2]
|
||||
with patch(
|
||||
"homeassistant.helpers.restore_state.RestoreEntity.async_get_last_state",
|
||||
return_value=State("switch.restored", STATE_OFF),
|
||||
):
|
||||
entry, switch = await _setup_entry(
|
||||
hass,
|
||||
"Private Restored Profile",
|
||||
[group],
|
||||
)
|
||||
assert not switch.is_on
|
||||
assert switch.lights == [group]
|
||||
|
||||
hass.states.async_set(
|
||||
group,
|
||||
STATE_UNAVAILABLE,
|
||||
{ATTR_ENTITY_ID: members, "friendly_name": "Private Late Group"},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
manager = hass.data[DOMAIN][ATTR_ADAPTIVE_LIGHTING_MANAGER]
|
||||
manager_lights_before = set(manager.lights)
|
||||
reset_times_before = dict(manager.auto_reset_manual_control_times)
|
||||
|
||||
result = await async_get_config_entry_diagnostics(hass, entry)
|
||||
|
||||
assert result["lights"] == {
|
||||
"light_1": {
|
||||
"state": STATE_UNAVAILABLE,
|
||||
"global_manager_manual_control": {
|
||||
"brightness": False,
|
||||
"color": False,
|
||||
},
|
||||
"global_manager_autoreset_seconds": None,
|
||||
"global_manager_last_adaptation_values": None,
|
||||
},
|
||||
}
|
||||
assert switch.lights == [group]
|
||||
assert manager.lights == manager_lights_before
|
||||
assert manager.auto_reset_manual_control_times == reset_times_before
|
||||
assert group not in json.dumps(result)
|
||||
|
||||
|
||||
async def test_diagnostics_handles_missing_states_and_unload_without_side_effects(
|
||||
hass,
|
||||
):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue