mirror of
https://github.com/basnijholt/adaptive-lighting.git
synced 2026-09-12 14:54:04 +02:00
Merge main into friendly_names_and_types and fix lint issues
This commit is contained in:
commit
4398ef4deb
31 changed files with 885 additions and 67 deletions
|
|
@ -1062,6 +1062,96 @@
|
|||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Tommatheussen",
|
||||
"name": "Tom Matheussen",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/13683094?v=4",
|
||||
"profile": "https://github.com/Tommatheussen",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "ams2990",
|
||||
"name": "ams2990",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/488907?v=4",
|
||||
"profile": "https://github.com/ams2990",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "DataGhost",
|
||||
"name": "DataGhost",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/3911340?v=4",
|
||||
"profile": "https://github.com/DataGhost",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Wijt",
|
||||
"name": "Furkan Kaya",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/23127261?v=4",
|
||||
"profile": "https://iamfurkan.com",
|
||||
"contributions": [
|
||||
"translation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Rafael4A",
|
||||
"name": "Rafael do Amaral Porciuncula",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/32150173?v=4",
|
||||
"profile": "https://github.com/Rafael4A",
|
||||
"contributions": [
|
||||
"translation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "hhjuhl",
|
||||
"name": "hhjuhl",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/84127693?v=4",
|
||||
"profile": "https://github.com/hhjuhl",
|
||||
"contributions": [
|
||||
"translation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Athishbalu",
|
||||
"name": "B.Athish",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/177029556?v=4",
|
||||
"profile": "https://github.com/Athishbalu",
|
||||
"contributions": [
|
||||
"translation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "maksim2005UKR",
|
||||
"name": "Горпиніч Максим Олександрович",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/233082001?v=4",
|
||||
"profile": "https://github.com/maksim2005UKR",
|
||||
"contributions": [
|
||||
"translation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "plageoj",
|
||||
"name": "Masayuki Sugahara",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/10688301?v=4",
|
||||
"profile": "https://plageoj.me",
|
||||
"contributions": [
|
||||
"translation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "therealmate",
|
||||
"name": "therealmate",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/61843503?v=4",
|
||||
"profile": "https://github.com/therealmate",
|
||||
"contributions": [
|
||||
"translation"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "basnijholt/adaptive_lighting",
|
||||
"image": "mcr.microsoft.com/devcontainers/python:1-3.13",
|
||||
"image": "mcr.microsoft.com/devcontainers/python:3-3.13",
|
||||
"postCreateCommand": "./scripts/setup-devcontainer && . .venv/bin/activate",
|
||||
"forwardPorts": [
|
||||
8123
|
||||
|
|
|
|||
6
.github/workflows/deploy-webapp.yml
vendored
6
.github/workflows/deploy-webapp.yml
vendored
|
|
@ -30,10 +30,10 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Set Up Python
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: 3.13.5
|
||||
|
||||
|
|
@ -53,7 +53,7 @@ jobs:
|
|||
uses: actions/configure-pages@v5
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
uses: actions/upload-pages-artifact@v4
|
||||
with:
|
||||
# Upload the 'site' directory, where your app has been built
|
||||
path: "site"
|
||||
|
|
|
|||
2
.github/workflows/hassfest.yaml
vendored
2
.github/workflows/hassfest.yaml
vendored
|
|
@ -11,5 +11,5 @@ jobs:
|
|||
validate_hassfest:
|
||||
runs-on: "ubuntu-latest"
|
||||
steps:
|
||||
- uses: "actions/checkout@v4.2.2"
|
||||
- uses: "actions/checkout@v6.0.0"
|
||||
- uses: home-assistant/actions/hassfest@master
|
||||
|
|
|
|||
|
|
@ -14,25 +14,25 @@ runs:
|
|||
using: "composite"
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
repository: ${{ github.repository }}
|
||||
ref: ${{ github.ref }}
|
||||
persist-credentials: false
|
||||
fetch-depth: 0
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
repository: home-assistant/core
|
||||
path: core
|
||||
ref: ${{ inputs.core-version }}
|
||||
- name: Set up Python ${{ inputs.python-version }}
|
||||
id: python
|
||||
uses: actions/setup-python@v5.6.0
|
||||
uses: actions/setup-python@v6.1.0
|
||||
with:
|
||||
python-version: ${{ inputs.python-version }}
|
||||
- name: Set up UV
|
||||
uses: astral-sh/setup-uv@v6
|
||||
uses: astral-sh/setup-uv@v7
|
||||
- name: Install dependencies
|
||||
shell: bash
|
||||
run: |
|
||||
|
|
|
|||
2
.github/workflows/main-to-master-sync.yml
vendored
2
.github/workflows/main-to-master-sync.yml
vendored
|
|
@ -11,7 +11,7 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: main
|
||||
fetch-depth: 0
|
||||
|
|
|
|||
4
.github/workflows/pre-commit.yaml
vendored
4
.github/workflows/pre-commit.yaml
vendored
|
|
@ -9,6 +9,6 @@ jobs:
|
|||
pre-commit:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-python@v6
|
||||
- uses: pre-commit/action@v3.0.1
|
||||
|
|
|
|||
14
.github/workflows/pytest.yaml
vendored
14
.github/workflows/pytest.yaml
vendored
|
|
@ -26,13 +26,23 @@ jobs:
|
|||
python-version: "3.13"
|
||||
- core-version: "2025.5.3"
|
||||
python-version: "3.13"
|
||||
- core-version: "2025.6.1"
|
||||
- core-version: "2025.6.3"
|
||||
python-version: "3.13"
|
||||
- core-version: "2025.7.4"
|
||||
python-version: "3.13"
|
||||
- core-version: "2025.8.3"
|
||||
python-version: "3.13"
|
||||
- core-version: "2025.9.4"
|
||||
python-version: "3.13"
|
||||
- core-version: "2025.10.4"
|
||||
python-version: "3.13"
|
||||
- core-version: "2025.11.3"
|
||||
python-version: "3.13"
|
||||
- core-version: "dev"
|
||||
python-version: "3.13"
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install Home Assistant
|
||||
uses: ./.github/workflows/install_dependencies
|
||||
|
|
|
|||
2
.github/workflows/update-readme.yml
vendored
2
.github/workflows/update-readme.yml
vendored
|
|
@ -15,7 +15,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install Home Assistant
|
||||
uses: ./.github/workflows/install_dependencies
|
||||
|
|
|
|||
2
.github/workflows/validate.yml
vendored
2
.github/workflows/validate.yml
vendored
|
|
@ -11,7 +11,7 @@ jobs:
|
|||
validate_hacs:
|
||||
runs-on: "ubuntu-latest"
|
||||
steps:
|
||||
- uses: "actions/checkout@v4"
|
||||
- uses: "actions/checkout@v6"
|
||||
- name: HACS validation
|
||||
uses: "hacs/action@main"
|
||||
with:
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@
|
|||
|
||||
FROM ghcr.io/astral-sh/uv:debian
|
||||
|
||||
# Install build dependencies for Python extensions
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
python3-dev \
|
||||
build-essential \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Clone home-assistant/core
|
||||
RUN git clone --depth 1 --branch dev https://github.com/home-assistant/core.git /core
|
||||
|
||||
|
|
|
|||
14
README.md
14
README.md
|
|
@ -1,7 +1,7 @@
|
|||
[](https://github.com/hacs/integration)
|
||||

|
||||
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
||||
[](#contributors-)
|
||||
[](#contributors-)
|
||||
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
||||
|
||||
# 🌞 Adaptive Lighting: Enhance Your Home's Atmosphere with Smart, Sun-Synchronized Lighting 🌙
|
||||
|
|
@ -616,6 +616,18 @@ Notice the values of `brightness_mode_time_light` and `brightness_mode_time_dark
|
|||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/bittin"><img src="https://avatars.githubusercontent.com/u/43197?v=4?s=100" width="100px;" alt="Luna Jernberg"/><br /><sub><b>Luna Jernberg</b></sub></a><br /><a href="#translation-bittin" title="Translation">🌍</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://jeffalwilson.com"><img src="https://avatars.githubusercontent.com/u/1368827?v=4?s=100" width="100px;" alt="Jeff Wilson"/><br /><sub><b>Jeff Wilson</b></sub></a><br /><a href="https://github.com/basnijholt/adaptive-lighting/commits?author=jawilson" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/TermeHansen"><img src="https://avatars.githubusercontent.com/u/6922018?v=4?s=100" width="100px;" alt="Rasmus Lundsgaard"/><br /><sub><b>Rasmus Lundsgaard</b></sub></a><br /><a href="https://github.com/basnijholt/adaptive-lighting/commits?author=TermeHansen" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Tommatheussen"><img src="https://avatars.githubusercontent.com/u/13683094?v=4?s=100" width="100px;" alt="Tom Matheussen"/><br /><sub><b>Tom Matheussen</b></sub></a><br /><a href="https://github.com/basnijholt/adaptive-lighting/commits?author=Tommatheussen" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ams2990"><img src="https://avatars.githubusercontent.com/u/488907?v=4?s=100" width="100px;" alt="ams2990"/><br /><sub><b>ams2990</b></sub></a><br /><a href="https://github.com/basnijholt/adaptive-lighting/commits?author=ams2990" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/DataGhost"><img src="https://avatars.githubusercontent.com/u/3911340?v=4?s=100" width="100px;" alt="DataGhost"/><br /><sub><b>DataGhost</b></sub></a><br /><a href="https://github.com/basnijholt/adaptive-lighting/commits?author=DataGhost" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://iamfurkan.com"><img src="https://avatars.githubusercontent.com/u/23127261?v=4?s=100" width="100px;" alt="Furkan Kaya"/><br /><sub><b>Furkan Kaya</b></sub></a><br /><a href="#translation-Wijt" title="Translation">🌍</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Rafael4A"><img src="https://avatars.githubusercontent.com/u/32150173?v=4?s=100" width="100px;" alt="Rafael do Amaral Porciuncula"/><br /><sub><b>Rafael do Amaral Porciuncula</b></sub></a><br /><a href="#translation-Rafael4A" title="Translation">🌍</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hhjuhl"><img src="https://avatars.githubusercontent.com/u/84127693?v=4?s=100" width="100px;" alt="hhjuhl"/><br /><sub><b>hhjuhl</b></sub></a><br /><a href="#translation-hhjuhl" title="Translation">🌍</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Athishbalu"><img src="https://avatars.githubusercontent.com/u/177029556?v=4?s=100" width="100px;" alt="B.Athish"/><br /><sub><b>B.Athish</b></sub></a><br /><a href="#translation-Athishbalu" title="Translation">🌍</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/maksim2005UKR"><img src="https://avatars.githubusercontent.com/u/233082001?v=4?s=100" width="100px;" alt="Горпиніч Максим Олександрович"/><br /><sub><b>Горпиніч Максим Олександрович</b></sub></a><br /><a href="#translation-maksim2005UKR" title="Translation">🌍</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://plageoj.me"><img src="https://avatars.githubusercontent.com/u/10688301?v=4?s=100" width="100px;" alt="Masayuki Sugahara"/><br /><sub><b>Masayuki Sugahara</b></sub></a><br /><a href="#translation-plageoj" title="Translation">🌍</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/therealmate"><img src="https://avatars.githubusercontent.com/u/61843503?v=4?s=100" width="100px;" alt="therealmate"/><br /><sub><b>therealmate</b></sub></a><br /><a href="#translation-therealmate" title="Translation">🌍</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
"""Adaptive Lighting integration in Home-Assistant."""
|
||||
|
||||
import logging
|
||||
from typing import Any, Optional
|
||||
from typing import Any
|
||||
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
import voluptuous as vol
|
||||
|
|
@ -38,7 +38,7 @@ CONFIG_SCHEMA = vol.Schema(
|
|||
|
||||
async def reload_configuration_yaml(event: Event) -> None:
|
||||
"""Reload configuration.yaml."""
|
||||
hass: HomeAssistant | None = event.data["hass"] if "hass" in event.data else None
|
||||
hass: HomeAssistant | None = event.data.get("hass")
|
||||
if hass is not None:
|
||||
await hass.services.async_call("homeassistant", "check_config", {})
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -57,8 +57,6 @@ def _type_to_str(type_: Any) -> str: # noqa: PLR0911
|
|||
|
||||
|
||||
def generate_config_markdown_table() -> str:
|
||||
import pandas as pd
|
||||
|
||||
rows: list[dict[str, str]] = []
|
||||
for k, default, type_ in VALIDATION_TUPLES:
|
||||
description = DOCS[k]
|
||||
|
|
@ -87,10 +85,7 @@ def _generate_service_markdown_table(
|
|||
schema: dict[str, tuple[Any, Any]] | vol.Schema,
|
||||
alternative_docs: dict[str, str] | None = None,
|
||||
) -> str:
|
||||
if isinstance(schema, vol.Schema):
|
||||
schema_dict = _schema_to_dict(schema)
|
||||
else:
|
||||
schema_dict = schema
|
||||
schema_dict = _schema_to_dict(schema) if isinstance(schema, vol.Schema) else schema
|
||||
rows: list[dict[str, str]] = []
|
||||
for k, (default, type_) in schema_dict.items():
|
||||
if alternative_docs is not None and k in alternative_docs:
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ async def _create_service_call_data_iterator(
|
|||
hass: HomeAssistant,
|
||||
service_datas: list[ServiceData],
|
||||
filter_by_state: bool,
|
||||
) -> AsyncGenerator[ServiceData, None]:
|
||||
) -> AsyncGenerator[ServiceData]:
|
||||
"""Enumerates and filters a list of service datas on the fly.
|
||||
|
||||
If filtering is enabled, every service data is filtered by the current state of
|
||||
|
|
@ -142,7 +142,7 @@ class AdaptationData:
|
|||
entity_id: str
|
||||
context: Context
|
||||
sleep_time: float
|
||||
service_call_datas: AsyncGenerator[ServiceData, None]
|
||||
service_call_datas: AsyncGenerator[ServiceData]
|
||||
force: bool
|
||||
max_length: int
|
||||
which: Literal["brightness", "color", "both"]
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import datetime
|
|||
import logging
|
||||
import math
|
||||
from dataclasses import dataclass
|
||||
from datetime import timedelta
|
||||
from functools import cached_property, partial
|
||||
from datetime import UTC, timedelta
|
||||
from functools import partial
|
||||
from typing import TYPE_CHECKING, Any, Literal, cast
|
||||
|
||||
from homeassistant.util.color import (
|
||||
|
|
@ -17,9 +17,10 @@ from homeassistant.util.color import (
|
|||
color_temperature_to_rgb,
|
||||
color_xy_to_hs,
|
||||
)
|
||||
from propcache.api import cached_property
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import astral
|
||||
import astral.location
|
||||
|
||||
# Same as homeassistant.const.SUN_EVENT_SUNRISE and homeassistant.const.SUN_EVENT_SUNSET
|
||||
# We re-define them here to not depend on homeassistant in this file.
|
||||
|
|
@ -32,7 +33,6 @@ SUN_EVENT_MIDNIGHT = "solar_midnight"
|
|||
_ORDER = (SUN_EVENT_SUNRISE, SUN_EVENT_NOON, SUN_EVENT_SUNSET, SUN_EVENT_MIDNIGHT)
|
||||
_ALLOWED_ORDERS = {_ORDER[i:] + _ORDER[:i] for i in range(len(_ORDER))}
|
||||
|
||||
UTC = datetime.timezone.utc
|
||||
utcnow: partial[datetime.datetime] = partial(datetime.datetime.now, UTC)
|
||||
utcnow.__doc__ = "Get now in UTC time."
|
||||
|
||||
|
|
@ -44,7 +44,7 @@ class SunEvents:
|
|||
"""Track the state of the sun and associated light settings."""
|
||||
|
||||
name: str
|
||||
astral_location: astral.Location
|
||||
astral_location: astral.location.Location
|
||||
sunrise_time: datetime.time | None
|
||||
min_sunrise_time: datetime.time | None
|
||||
max_sunrise_time: datetime.time | None
|
||||
|
|
@ -198,7 +198,7 @@ class SunLightSettings:
|
|||
"""Track the state of the sun and associated light settings."""
|
||||
|
||||
name: str
|
||||
astral_location: astral.Location
|
||||
astral_location: astral.location.Location
|
||||
adapt_until_sleep: bool
|
||||
max_brightness: int
|
||||
max_color_temp: int
|
||||
|
|
@ -296,7 +296,7 @@ class SunLightSettings:
|
|||
)
|
||||
return clamp(brightness, self.min_brightness, self.max_brightness)
|
||||
|
||||
def brightness_pct(self, dt: datetime.datetime, is_sleep: bool) -> float:
|
||||
def brightness_pct(self, dt: datetime.datetime, is_sleep: bool) -> float | None:
|
||||
"""Calculate the brightness in %."""
|
||||
if is_sleep:
|
||||
return self.sleep_brightness
|
||||
|
|
@ -331,7 +331,7 @@ class SunLightSettings:
|
|||
) -> dict[str, Any]:
|
||||
"""Calculate the brightness and color."""
|
||||
sun_position = self.sun.sun_position(dt)
|
||||
rgb_color: tuple[float, float, float]
|
||||
rgb_color: tuple[int, int, int]
|
||||
# Variable `force_rgb_color` is needed for RGB color after sunset (if enabled)
|
||||
force_rgb_color = False
|
||||
brightness_pct = self.brightness_pct(dt, is_sleep)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import logging
|
|||
from collections.abc import Awaitable, Callable
|
||||
|
||||
from homeassistant.core import HomeAssistant, ServiceCall
|
||||
from homeassistant.helpers import device_registry, entity_registry
|
||||
from homeassistant.util.read_only_dict import ReadOnlyDict
|
||||
|
||||
from .adaptation_utils import ServiceData
|
||||
|
|
@ -11,6 +12,25 @@ from .adaptation_utils import ServiceData
|
|||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def area_entities(hass: HomeAssistant, area_id: str):
|
||||
"""Get all entities linked to an area."""
|
||||
ent_reg = entity_registry.async_get(hass)
|
||||
entity_ids = [
|
||||
entry.entity_id
|
||||
for entry in entity_registry.async_entries_for_area(ent_reg, area_id)
|
||||
]
|
||||
dev_reg = device_registry.async_get(hass)
|
||||
entity_ids.extend(
|
||||
[
|
||||
entity.entity_id
|
||||
for device in device_registry.async_entries_for_area(dev_reg, area_id)
|
||||
for entity in entity_registry.async_entries_for_device(ent_reg, device.id)
|
||||
if entity.area_id is None
|
||||
],
|
||||
)
|
||||
return entity_ids
|
||||
|
||||
|
||||
def setup_service_call_interceptor(
|
||||
hass: HomeAssistant,
|
||||
domain: str,
|
||||
|
|
@ -27,7 +47,7 @@ def setup_service_call_interceptor(
|
|||
# This is necessary to replace a registered service handler with our
|
||||
# proxy handler to intercept calls.
|
||||
registered_services = (
|
||||
hass.services._services # pylint: disable=protected-access # type: ignore
|
||||
hass.services._services # pylint: disable=protected-access # type: ignore[attr-defined]
|
||||
)
|
||||
except AttributeError as error:
|
||||
msg = (
|
||||
|
|
|
|||
|
|
@ -8,5 +8,5 @@
|
|||
"iot_class": "calculated",
|
||||
"issue_tracker": "https://github.com/basnijholt/adaptive-lighting/issues",
|
||||
"requirements": ["ulid-transform"],
|
||||
"version": "1.26.0"
|
||||
"version": "1.27.0"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,7 +75,6 @@ from homeassistant.helpers.event import (
|
|||
)
|
||||
from homeassistant.helpers.restore_state import RestoreEntity
|
||||
from homeassistant.helpers.sun import get_astral_location
|
||||
from homeassistant.helpers.template import area_entities
|
||||
from homeassistant.util import slugify
|
||||
from homeassistant.util.color import (
|
||||
color_temperature_to_rgb,
|
||||
|
|
@ -153,7 +152,7 @@ from .const import (
|
|||
apply_service_schema,
|
||||
replace_none_str,
|
||||
)
|
||||
from .hass_utils import setup_service_call_interceptor
|
||||
from .hass_utils import area_entities, setup_service_call_interceptor
|
||||
from .helpers import (
|
||||
clamp,
|
||||
color_difference_redmean,
|
||||
|
|
@ -626,7 +625,7 @@ def _is_light_group(state: State) -> bool:
|
|||
def _supported_features(hass: HomeAssistant, light: str) -> set[str]:
|
||||
state = hass.states.get(light)
|
||||
assert state is not None
|
||||
supported_features = int(state.attributes.get(ATTR_SUPPORTED_FEATURES, 0)) # type: ignore
|
||||
supported_features = int(state.attributes.get(ATTR_SUPPORTED_FEATURES, 0)) # type: ignore[arg-type]
|
||||
assert isinstance(supported_features, int)
|
||||
|
||||
supported: set[str] = set()
|
||||
|
|
@ -634,7 +633,7 @@ def _supported_features(hass: HomeAssistant, light: str) -> set[str]:
|
|||
if supported_features & LightEntityFeature.TRANSITION:
|
||||
supported.add("transition")
|
||||
|
||||
supported_color_modes = state.attributes.get(ATTR_SUPPORTED_COLOR_MODES, set()) # type: ignore
|
||||
supported_color_modes = state.attributes.get(ATTR_SUPPORTED_COLOR_MODES, set()) # type: ignore[arg-type]
|
||||
color_modes = {
|
||||
ColorMode.RGB,
|
||||
ColorMode.RGBW,
|
||||
|
|
@ -695,6 +694,58 @@ def _add_missing_attributes(
|
|||
return old_attributes, new_attributes
|
||||
|
||||
|
||||
def _has_color_mode_changed(
|
||||
light: str,
|
||||
old_attributes: dict[str, Any],
|
||||
new_attributes: dict[str, Any],
|
||||
context: Context,
|
||||
) -> bool:
|
||||
"""Check if the light's color mode changed (e.g., color_temp to RGB or vice versa).
|
||||
|
||||
This must be called BEFORE _add_missing_attributes() to detect mode changes
|
||||
using the original attributes. See issue #1275.
|
||||
"""
|
||||
old_has_color_temp = old_attributes.get(ATTR_COLOR_TEMP_KELVIN) is not None
|
||||
old_has_rgb = old_attributes.get(ATTR_RGB_COLOR) is not None
|
||||
old_has_xy = old_attributes.get(ATTR_XY_COLOR) is not None
|
||||
|
||||
new_has_color_temp = new_attributes.get(ATTR_COLOR_TEMP_KELVIN) is not None
|
||||
new_has_rgb = new_attributes.get(ATTR_RGB_COLOR) is not None
|
||||
new_has_xy = new_attributes.get(ATTR_XY_COLOR) is not None
|
||||
|
||||
# Determine old and new color modes
|
||||
# Priority: color_temp > rgb > xy (matching typical light behavior)
|
||||
if old_has_color_temp:
|
||||
old_mode = "color_temp"
|
||||
elif old_has_rgb:
|
||||
old_mode = "rgb"
|
||||
elif old_has_xy:
|
||||
old_mode = "xy"
|
||||
else:
|
||||
old_mode = None
|
||||
|
||||
if new_has_color_temp:
|
||||
new_mode = "color_temp"
|
||||
elif new_has_rgb:
|
||||
new_mode = "rgb"
|
||||
elif new_has_xy:
|
||||
new_mode = "xy"
|
||||
else:
|
||||
new_mode = None
|
||||
|
||||
# Check if mode changed
|
||||
if old_mode is not None and new_mode is not None and old_mode != new_mode:
|
||||
_LOGGER.debug(
|
||||
"Light mode of %s changed from %s to %s with context.id='%s'",
|
||||
light,
|
||||
old_mode,
|
||||
new_mode,
|
||||
context.id,
|
||||
)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def _attributes_have_changed(
|
||||
light: str,
|
||||
old_attributes: dict[str, Any],
|
||||
|
|
@ -707,6 +758,17 @@ def _attributes_have_changed(
|
|||
# so we must protect for `None` here
|
||||
# see https://github.com/home-assistant/core/pull/101946
|
||||
|
||||
# Check for color mode changes BEFORE attribute conversion
|
||||
# This detects external changes like Hue scenes switching from color_temp to RGB
|
||||
# See: https://github.com/basnijholt/adaptive-lighting/issues/1275
|
||||
if adapt_color and _has_color_mode_changed(
|
||||
light,
|
||||
old_attributes,
|
||||
new_attributes,
|
||||
context,
|
||||
):
|
||||
return True
|
||||
|
||||
if adapt_color:
|
||||
old_attributes, new_attributes = _add_missing_attributes(
|
||||
old_attributes,
|
||||
|
|
@ -767,6 +829,7 @@ def _attributes_have_changed(
|
|||
context.id,
|
||||
)
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
|
|
@ -1133,8 +1196,9 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity):
|
|||
self.manager.reset(*self.lights)
|
||||
|
||||
async def _async_update_at_interval_action(
|
||||
self, now: Any = None
|
||||
) -> None: # noqa: ARG002
|
||||
self,
|
||||
now: Any = None, # noqa: ARG002
|
||||
) -> None:
|
||||
"""Update the attributes and maybe adapt the lights."""
|
||||
await self._update_attrs_and_maybe_adapt_lights(
|
||||
context=self.create_context("interval"),
|
||||
|
|
@ -1566,7 +1630,7 @@ class SimpleSwitch(SwitchEntity, RestoreEntity):
|
|||
self.hass = hass
|
||||
data = validate(config_entry)
|
||||
self._icon = icon
|
||||
self._state: bool | None = None
|
||||
self._state: bool = initial_state
|
||||
self._which = which
|
||||
self._config_name = data[CONF_NAME]
|
||||
self._unique_id = f"{self._config_name}_{slugify(self._which)}"
|
||||
|
|
@ -2118,7 +2182,9 @@ class AdaptiveLightingManager:
|
|||
self._handle_timer(light, self.transition_timers, last_transition, reset)
|
||||
|
||||
def set_auto_reset_manual_control_times(
|
||||
self, lights: list[str], time: float
|
||||
self,
|
||||
lights: list[str],
|
||||
time: float,
|
||||
) -> None:
|
||||
"""Set the time after which the lights are automatically reset."""
|
||||
if time == 0:
|
||||
|
|
@ -2685,7 +2751,6 @@ class _AsyncSingleShotTimer:
|
|||
|
||||
async def _run(self) -> None:
|
||||
"""Run the timer. Don't call this directly, use start() instead."""
|
||||
self.start_time = dt_util.utcnow()
|
||||
await asyncio.sleep(self.delay)
|
||||
if self.callback:
|
||||
if asyncio.iscoroutinefunction(self.callback):
|
||||
|
|
@ -2701,6 +2766,10 @@ class _AsyncSingleShotTimer:
|
|||
"""Start the timer."""
|
||||
if self.task is not None and not self.task.done():
|
||||
self.task.cancel()
|
||||
# Set start_time before creating task to avoid race condition
|
||||
# where is_running() returns True but start_time is still None
|
||||
# See: https://github.com/basnijholt/adaptive-lighting/issues/1272
|
||||
self.start_time = dt_util.utcnow()
|
||||
self.task = asyncio.create_task(self._run())
|
||||
|
||||
def cancel(self) -> None:
|
||||
|
|
|
|||
|
|
@ -40,7 +40,8 @@
|
|||
"detect_non_ha_changes": "detect_non_ha_changes: Registrer alle ændringer på >10% på et lys (også udenfor HA), kræver at 'take_over_control' er slået til (kalder 'homeassistant.update_entity' hvert 'interval'!)",
|
||||
"transition": "Overgangsperiode når en ændring i lyset udføres (i sekunder)",
|
||||
"transition_until_sleep": "overgang_til_sove: Når aktiveret, vil adaptiv belysning behandle søvnindstillinger som minimum, og overgår til disse værdier efter solnedgang. 🌙",
|
||||
"adapt_only_on_bare_turn_on": "tilpas_kun_ved_enkelt_tænd: Når du tænder lys for første gang. Hvis indstillet til 'true', tilpasser AL kun, hvis 'lys.tænd' er kaldt uden at angive farve eller lysstyrke. ❌🌈 Dette forhindrer f.eks. tilpasning, når du aktiverer en scene. Hvis indstillet til 'false' tilpasser AL sig uanset tilstanden af farve eller lysstyrke i den oprindelige 'service_data'. Har brug for at 'take_over_control' er aktiveret. 🕵️ "
|
||||
"adapt_only_on_bare_turn_on": "tilpas_kun_ved_enkelt_tænd: Når du tænder lys for første gang. Hvis indstillet til 'true', tilpasser AL kun, hvis 'lys.tænd' er kaldt uden at angive farve eller lysstyrke. ❌🌈 Dette forhindrer f.eks. tilpasning, når du aktiverer en scene. Hvis indstillet til 'false' tilpasser AL sig uanset tilstanden af farve eller lysstyrke i den oprindelige 'service_data'. Har brug for at 'take_over_control' er aktiveret. 🕵️",
|
||||
"include_config_in_attributes": "include_config_in_attributes: Vis alle indstillinger som attributter for kontakten når dette er sat til »true«. 📝"
|
||||
},
|
||||
"data_description": {
|
||||
"interval": "Frekvens til at tilpasse lysene, i sekunder. 🔄",
|
||||
|
|
@ -59,7 +60,9 @@
|
|||
"sunrise_offset": "Juster solopgangstiden med en positiv eller negativ offset på få sekunder. ⏰",
|
||||
"max_sunset_time": "Indstil den seneste virtuelle solnedgangstid (HH:MM:SS), hvilket giver mulighed for tidligere solnedgange. 🌇",
|
||||
"sleep_color_temp": "Farvetemperatur i søvntilstand (bruges når `sleep_rgb_or_color_temp` er `color_temp`) i Kelvin. 😴",
|
||||
"brightness_mode": "Lysstyrketilstand til brug. Mulige værdier er \"default\", \"linear\" og \"tanh\" (bruger \"brightness_mode_time_dark\" og \"brightness_mode_time_light\"). 📈"
|
||||
"brightness_mode": "Lysstyrketilstand til brug. Mulige værdier er \"default\", \"linear\" og \"tanh\" (bruger \"brightness_mode_time_dark\" og \"brightness_mode_time_light\"). 📈",
|
||||
"send_split_delay": "Forsinkelse (ms) mellem »separate_turn_on_commands« for lyskilder som ikke understøtter simultane styrke- og farveindstillinger. ⏲️",
|
||||
"initial_transition": "Den første overgangs varighed når lysene ændres fra »off« til »on« i sekunder. ⏲️"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -153,12 +156,26 @@
|
|||
},
|
||||
"sleep_color_temp": {
|
||||
"description": "Farvetemperatur i søvntilstand (bruges når `sleep_rgb_or_color_temp` er `color_temp`) i Kelvin. 😴"
|
||||
},
|
||||
"send_split_delay": {
|
||||
"description": "Forsinkelse (ms) mellem »separate_turn_on_commands« for lyskilder som ikke understøtter simultane styrke- og farveindstillinger. ⏲️"
|
||||
},
|
||||
"detect_non_ha_changes": {
|
||||
"description": "Opdager og stopper tilpasningen ved tilstandsændringer, som ikke er udløst af »light.turn_on«. Indstillingen »take_over_control« skal være aktiveret. 🕵️ Advarsel: ⚠️ Nogle lyskilder kan rapportere en falsk tændt-tilstand, hvilket kan medføre af lyskilden tændes når det ikke er meningen. Slå denne funktion fra, hvis du oplever dette problem."
|
||||
},
|
||||
"initial_transition": {
|
||||
"description": "Den første overgangs varighed når lysene ændres fra »off« til »on« i sekunder. ⏲️"
|
||||
}
|
||||
},
|
||||
"description": "Skift de indstillinger du ønsker i kontakten. Alle muligheder her er de samme som i konfigurationsflowet."
|
||||
},
|
||||
"set_manual_control": {
|
||||
"description": "Markér om et lys er 'manuelt kontrolleret'."
|
||||
"description": "Markér om et lys er 'manuelt kontrolleret'.",
|
||||
"fields": {
|
||||
"lights": {
|
||||
"description": "entity_id(er) af lys, hvis ikke specificeret, vil alle lys i kontakten være valgt. 💡"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,11 @@
|
|||
"step": {
|
||||
"init": {
|
||||
"data_description": {
|
||||
"sleep_brightness": "Porcentaxe de brillo das luces en modo durmir. 😴"
|
||||
"sleep_brightness": "Porcentaxe de brillo das luces en modo durmir. 😴",
|
||||
"send_split_delay": "Retraso (ms) entre `separate_turn_on_commands`",
|
||||
"sunrise_offset": "Axusta a hora do amencer cun desfasamento positivo ou negativo en segundos. ⏰",
|
||||
"sunset_offset": "Axusta a hora da posta de sol cun desfasamento positivo ou negativo en segundos. ⏰",
|
||||
"interval": "Frecuencia para adaptar as luces, en segundos. 🔄"
|
||||
},
|
||||
"title": "Configuración de Iluminación Adaptativa"
|
||||
}
|
||||
|
|
@ -18,6 +22,15 @@
|
|||
},
|
||||
"only_once": {
|
||||
"description": "Adaptar luces só cando estean acesas (`true`) ou mantelas adaptándose (`false`). 🔄"
|
||||
},
|
||||
"sunrise_offset": {
|
||||
"description": "Axusta a hora do amencer cun desfasamento positivo ou negativo en segundos. ⏰"
|
||||
},
|
||||
"sunset_offset": {
|
||||
"description": "Axusta a hora da posta de sol cun desfasamento positivo ou negativo en segundos. ⏰"
|
||||
},
|
||||
"transition": {
|
||||
"description": "Duración da transición cando as luces cambian, en segundos. 🕑"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
"max_brightness": "max_brightness: Maximális fényerő százalékban megadva. 💡",
|
||||
"detect_non_ha_changes": "detect_non_ha_changes: `Világítás: Bekapcsolás`- szolgáltatás meghívástól eltérő állapotváltozások esetén észleli és leállítja az illesztéseket. A `take_over_control` beállítás engedélyezése szükséges. 🕵️ Vigyázat: ⚠️ Egyes lights tévesen jelezhetik a \"bekapcsolt\" állapotot, ami váratlanul bekapcsolódó lámpákhoz vezethet. Ha ilyen problémákat tapasztal, tiltsa le ezt a funkciót.",
|
||||
"multi_light_intercept": "multi_light_intercept: `Világítás: Bekapcsolás` szolgáltatás hívások elfogása és adaptálása, amelyek több fényt céloznak meg. ➗⚠️ Ez azt eredményezheti, hogy egyetlen `Világítás: Bekapcsolás` szolgáltatás hívás több hívásra oszlik fel, pl. ha a lights különböző kapcsolókban vannak. Az `elfogás` engedélyezése szükséges.",
|
||||
"adapt_only_on_bare_turn_on": "adapt_only_on_bare_turn_on: Kizárólag a bekapcsoláskor érvényes. A beállítást \"igaz\"-ra állítva, az AL csak akkor végzi az illesztést, amennyiben a \"Világítás: Bekapcsolás\" szolgáltatás meghívása a szín és fényerő paraméterek megadása nélkül történik.❌🌈 Ez pl. alkalmas az illesztés felfüggesztésére egy jelenet aktiválásakor. \"Hamis\" beállítás esetén az AL elvégzi a kezdeti illesztést a szín és fényerő paraméterek meghívásától függetlenül. A használatához engedélyezve kell lennie a \"take_over_control\" beállításnak. 🕵️ ",
|
||||
"adapt_only_on_bare_turn_on": "adapt_only_on_bare_turn_on: Kizárólag a bekapcsoláskor érvényes. A beállítást \"igaz\"-ra állítva, az AL csak akkor végzi az illesztést, amennyiben a \"Világítás: Bekapcsolás\" szolgáltatás meghívása a szín és fényerő paraméterek megadása nélkül történik.❌🌈 Ez pl. alkalmas az illesztés felfüggesztésére egy jelenet aktiválásakor. \"Hamis\" beállítás esetén az AL elvégzi a kezdeti illesztést a szín és fényerő paraméterek meghívásától függetlenül. A használatához engedélyezve kell lennie a \"take_over_control\" beállításnak. 🕵️",
|
||||
"skip_redundant_commands": "skip_redundant_commands: Az olyan adaptációs parancsok küldésének kihagyása, amelyek célállapota már megegyezik a fény ismert állapotával. Minimalizálja a hálózati forgalmat, és bizonyos helyzetekben javítja az adaptációs reakciókészséget. 📉Kapcsolja ki, ha a fizikai fényállapotok nem szinkronizálódnak a HA rögzített állapotával.",
|
||||
"separate_turn_on_commands": "separate_turn_on_commands: Elkülönített `Világítás: Bekapcsolás` hívásokat használ a szín és a fényerő beállításához, ami néhány világítás típusnál szükséges. 🔀",
|
||||
"max_color_temp": "max_color_temp: A leghidegebb színhőmérséklet kelvinben. ❄️",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"title": "適応型照明",
|
||||
"title": "明るさの自動調整",
|
||||
"services": {
|
||||
"change_switch_settings": {
|
||||
"fields": {
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
"description": "日の出時間を基準に秒単位で正値もしくは負値で調整する。⏰"
|
||||
},
|
||||
"only_once": {
|
||||
"description": "適応型照明を照明がオンになっているときのみ(`true`)それとも適応し続ける場合は(`false`)。"
|
||||
"description": "一度だけ明るさを自動調整するには(`true`)、常に自動調整し続ける場合は(`false`)。"
|
||||
},
|
||||
"sunset_offset": {
|
||||
"description": "日の入時間を基準に秒単位で正値もしくは負値で調整する。⏰"
|
||||
|
|
@ -35,7 +35,7 @@
|
|||
"sunrise_offset": "日の出時間を基準に秒単位で正値もしくは負値で調整する。⏰",
|
||||
"sunset_offset": "日の入時間を基準に秒単位で正値もしくは負値で調整する。⏰"
|
||||
},
|
||||
"title": "適応型照明オプション"
|
||||
"title": "明るさの自動調整オプション"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,11 @@
|
|||
"sunset_time": "sunset_time: substituição manual do horário do pôr do sol, se 'Nenhum', ele usa o horário real do nascer do sol em sua localização (HH:MM:SS)",
|
||||
"take_over_control": "take_over_control: Se qualquer coisa, exceto Adaptive Lighting, chamar 'light.turn_on' quando uma luz já estiver acesa, pare de adaptar essa luz até que ela (ou o interruptor) desligue -> ligue.",
|
||||
"detect_non_ha_changes": "detect_non_ha_changes: detecta todas as alterações > 10% feitas nas luzes (também fora do HA), requer que 'take_over_control' seja ativado (chama 'homeassistant.update_entity' a cada 'intervalo'!)",
|
||||
"transition": "Tempo de transição ao aplicar uma mudança nas luzes (segundos)"
|
||||
"transition": "Tempo de transição ao aplicar uma mudança nas luzes (segundos)",
|
||||
"skip_redundant_commands": "skip_redundant_commands: Deixar de enviar comandos de adaptação cujo estado alvo já seja igual ao estado atual da luz. Minimiza o tráfego de rede e melhora a responsividade da adaptação em algumas situações. 📉Desative se os estados físicos das luzes podem ficar diferentes do estado registrado no HA.",
|
||||
"transition_until_sleep": "transition_until_sleep: Quando ativada, a Iluminação Adaptativa considerará as configurações de sono como o valor mínimo, transicionando para esses valores após o pôr do sol. 🌙",
|
||||
"adapt_only_on_bare_turn_on": "adapt_only_on_bare_turn_on: Ao ligar as luzes inicialmente. Se definido como `true`, a Iluminação Adaptativa se adapta somente se o comando `light.turn_on` for chamado sem especificar cor ou brilho. ❌🌈 Isso, por exemplo, impede a adaptação ao ativar uma cena. Se false, a Iluminação Adaptativa se adapta independentemente da presença de cor ou brilho nos dados iniciais do `service_data`. Precisa de `take_over_control` ativado. 🕵️",
|
||||
"intercept": "intercept: Interceptar e adaptar os chamados `light.turn_on` para ativar a adaptação instantânea de cor e brilho. 🏎️ Desative para luzes que não suportam `light.turn_on` com cor e brilho."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
"transition": "Время перехода при применении изменения к источникам света. (секунды)",
|
||||
"adapt_delay": "Время ожидания между включением света и применением адаптации. Может помочь избежать мерцания. (секунды)",
|
||||
"multi_light_intercept": "multi_light_intercept: перехватывает и адаптирует вызовы `light.turn_on`, нацеленные на несколько источников света. ➗⚠️ Это может привести к разделению одного вызова `light.turn_on` на несколько вызовов, например, когда освещение включено в разные выключатели. Требуется, чтобы `перехват` был включен.",
|
||||
"adapt_only_on_bare_turn_on": "Adapt_only_on_bare_turn_on: При первоначальном включении света. Если установлено значение «true», AL адаптируется только в том случае, если «light.turn_on» вызывается без указания цвета или яркости. ❌🌈 Это, например, предотвращает адаптацию при активации сцены. Если false, AL адаптируется независимо от наличия цвета или яркости в исходных service_data. Требуется включить take_over_control. 🕵️ ",
|
||||
"adapt_only_on_bare_turn_on": "Adapt_only_on_bare_turn_on: При первоначальном включении света. Если установлено значение «true», AL адаптируется только в том случае, если «light.turn_on» вызывается без указания цвета или яркости. ❌🌈 Это, например, предотвращает адаптацию при активации сцены. Если false, AL адаптируется независимо от наличия цвета или яркости в исходных service_data. Требуется включить take_over_control. 🕵️",
|
||||
"skip_redundant_commands": "Skip_redundant_commands: Пропустить отправку команд адаптации, целевое состояние которых уже равно известному состоянию источника света. Минимизирует сетевой трафик и улучшает скорость адаптации в некоторых ситуациях. 📉Отключите, если физические состояния освещения не синхронизируются с записанным состоянием HA.",
|
||||
"intercept": "intercept: перехватывать и адаптировать вызовы `light.turn_on` для обеспечения мгновенной адаптации цвета и яркости. 🏎️ Отключите источники света, которые не поддерживают `light.turn_on` с цветом и яркостью.",
|
||||
"include_config_in_attributes": "include_config_in_attributes: отображать все параметры в качестве атрибутов на переключателе в Home Assistant, если установлено значение `true`. 📝",
|
||||
|
|
|
|||
75
custom_components/adaptive_lighting/translations/sl.json
Normal file
75
custom_components/adaptive_lighting/translations/sl.json
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
{
|
||||
"options": {
|
||||
"step": {
|
||||
"init": {
|
||||
"data": {
|
||||
"prefer_rgb_color": "prefer_rgb_color: Ali v primeru možnosti raje uporabiti prilagoditev RGB barve kot barvno temperaturo luči. 🌈",
|
||||
"transition_until_sleep": "transition_until_sleep: Če je omogočeno, bo Adaptive Lighting obravnaval nastavitve spanja kot minimalne vrednosti in bo po zahodu sonca prehajal na te vrednosti. 🌙",
|
||||
"take_over_control": "take_over_control: Onemogoči Adaptive Lighting, če drug vir pokliče \"light.turn_on\", ko so luči prižgane in se prilagajajo. Opozorilo: to ob vsakem intervalu kliče \"homeassistant.update_entity\"! 🔒",
|
||||
"detect_non_ha_changes": "„detect_non_ha_changes: Zazna in ustavi prilagoditve za spremembe stanja, ki niso posledica \"light.turn_on\". Zahteva omogočeno \"take_over_control\". 🕵️ Pozor: ⚠️ Nekatere luči lahko nepravilno poročajo, da so prižgane, kar lahko povzroči nepričakovano vklapljanje. Onemogočite to funkcijo, če naletite na takšne težave.",
|
||||
"lights": "lights: Seznam entity_id-jev luči za nadzor (lahko je prazen). 🌟",
|
||||
"min_brightness": "min_brightness: Odstotek najmanjše svetlosti. 💡",
|
||||
"max_brightness": "max_brightness: Odstotek največeje svetlosti. 💡",
|
||||
"min_color_temp": "min_color_temp: Najtoplejša barvna temperatura v Kelvinih. 🔥",
|
||||
"max_color_temp": "max_color_temp: Najhladnejša barvna temperatura v kelvinih. ❄️",
|
||||
"separate_turn_on_commands": "separate_turn_on_commands: Uporabi ločene klice \"light.turn_on\" za barvo in jakost, kar je potrebno za nekatere tipe luči. 🔀",
|
||||
"skip_redundant_commands": "skip_redundant_commands: Preskoči pošiljanje prilagoditvenih ukazov, če je ciljano stanje že enako poznanemu stanju luči. Zmanjšuje omrežni promet in izboljšuje odzivnost prilagajanja v določenih situacijah. 📉 Onemogočite, če se fizična stanja luči ne ujemajo z zabeleženim stanjem v HA.",
|
||||
"intercept": "intercept: Prestreza in prilagaja klice \"light.turn_on\" za takojšnjo prilagoditev barve in jakosti. 🏎️ Onemogočite za luči, ki ne podpirajo \"light.turn_on\" z barvo in svetlostjo.",
|
||||
"multi_light_intercept": "multi_light_intercept: Prestreza in prilagaja klice \"light.turn_on\", ki ciljajo več luči. ➗⚠️ To lahko privede do razdelitve enega klica \"light.turn_on\" v več klicev, npr. ko so luči na različnih stikalih. Zahteva omogočeno \"intercept\".",
|
||||
"include_config_in_attributes": "include_config_in_attributes: Ko je nastavljeno na \"true\", prikaže vse možnosti kot atribute stikala v Home Assistantu. 📝",
|
||||
"only_once": "only_once: Prilagodi luči samo ob vklopu (true) ali pa jih še naprej prilagajaj (false). 🔄",
|
||||
"adapt_only_on_bare_turn_on": "adapt_only_on_bare_turn_on: Ob začetnem vklopu luči. Če je nastavljeno na \"true\", AL prilagodi samo, če je \"light.turn_on\" klic brez podanih parametrov barve ali jakosti. ❌🌈 S tem se npr. prepreči prilagajanje pri aktivaciji scene. Če je \"false\", AL prilagodi ne glede na prisotnost barve ali jakosti v začetnih \"service_data\". Zahteva omogočeno \"take_over_control\". 🕵️"
|
||||
},
|
||||
"data_description": {
|
||||
"sunrise_offset": "Prilagodite čas sončnega vzhoda z pozitivnim ali negativnim zamikom v sekundah. ⏰",
|
||||
"send_split_delay": "Zamik (ms) med \"separate_turn_on_commands\" za luči, ki ne podpirajo hkratne nastavitve jakosti in barve. ⏲️",
|
||||
"transition": "Trajanje prehoda pri spreminjanju luči, v sekundah. 🕑",
|
||||
"interval": "Pogostost prilagajanja luči, v sekundah. 🔄",
|
||||
"sleep_brightness": "Odstotek svetlosti luči v načinu spanja. 😴",
|
||||
"sleep_rgb_or_color_temp": "V načinu spanja uporabi \"rgb_color\" ali \"color_temp\". 🌙",
|
||||
"sleep_color_temp": "Barvna temperatura v načinu spanja (uporabljena, ko je \"sleep_rgb_or_color_temp\" nastavljena na \"color_temp\") v Kelvinih. 😴",
|
||||
"sleep_transition": "Trajanje prehoda, ko se preklopi način spanja, v sekundah. 😴",
|
||||
"sunrise_time": "Nastavi fiksni čas (HH:MM:SS) sončnega vzhoda. 🌅",
|
||||
"min_sunrise_time": "Nastavi najzgodnejši navidezni sončni vzhod (HH:MM:SS), dovoljuje kasnejše vzhode. 🌅",
|
||||
"sunset_time": "Nastavite fiksni čas (HH:MM:SS) za sončni zahod. 🌇",
|
||||
"min_sunset_time": "Nastavite najzgodnejši navidezni čas sončnega zahoda (HH:MM:SS), dovoljuje kasnejše sončne zahode. 🌇",
|
||||
"sunset_offset": "Prilagodite čas sončnega zahoda s pozitivnim ali negativnim zamikom v sekundah. ⏰",
|
||||
"brightness_mode_time_dark": "(Prezrto, če je \"brightness_mode='default'\") Trajanje v sekundah za postopno povečanje ali zmanjšanje svetlosti pred/po sončnem vzhodu/zahodu. 📈📉",
|
||||
"brightness_mode_time_light": "(Prezrto, če je \"brightness_mode='default'\") Trajanje v sekundah za postopno povečanje ali zmanjšanje svetlosti po/pred sončnem vzhodu/zahodu. 📈📉",
|
||||
"autoreset_control_seconds": "Samodejno ponastavi ročni nadzor po določenem številu sekund. Nastavite na 0, da onemogočite. ⏲️",
|
||||
"max_sunrise_time": "Nastavi najkasnejši virtualni sončni vzhod (HH:MM:SS), dovoljuje zgodnejše vzhode. 🌅",
|
||||
"max_sunset_time": "Nastavite najpoznejši navidezni čas sončnega zahoda (HH:MM:SS), dovoljuje zgodnejše sončne zahode. 🌇",
|
||||
"brightness_mode": "Način upravljanja svetlosti. Možne vrednosti so \"default\", \"linear\" in \"tanh\" (uporablja \"brightness_mode_time_dark\" in \"brightness_mode_time_light\"). 📈",
|
||||
"initial_transition": "Trajanje prvega prehoda, ko se luči prižgejo (iz \"off\" v \"on\"), v sekundah. ⏲️",
|
||||
"sleep_rgb_color": "RGB barva v načinu spanja (uporabljena, ko je \"sleep_rgb_or_color_temp\" nastavljeno na \"rgb_color\"). 🌈"
|
||||
},
|
||||
"title": "Nastavitve prilagodljive osvetlitve",
|
||||
"description": "Konfigurirajte komponento Adaptive Lighting. Imena možnosti so usklajena z nastavitvami v YAML. Če ste ta vnos definirali v YAML, tukaj ne bodo prikazane nobene možnosti. Za interaktivne grafe, ki ponazarjajo učinke parametrov, obiščite to [spletno aplikacijo](https://basnijholt.github.io/adaptive-lighting). Za dodatne podrobnosti glejte [uradno dokumentacijo](https://github.com/basnijholt/adaptive-lighting#readme)."
|
||||
}
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"step": {
|
||||
"user": {
|
||||
"title": "Izberite ime za instanco Adaptive Lighting",
|
||||
"description": "Vsaka instanca lahko vsebuje več luči!"
|
||||
}
|
||||
},
|
||||
"abort": {
|
||||
"already_configured": "Naprava je že konfigurirana"
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"change_switch_settings": {
|
||||
"fields": {
|
||||
"only_once": {
|
||||
"description": "Prilagajaj luči samo kadar so prižgane (\"true\") ali konstantno jih prilagajaj (\"false\")"
|
||||
},
|
||||
"max_sunrise_time": {
|
||||
"description": "Nastavite najpoznejši navidezni čas sončnega vzhoda (HH:MM:SS), dovoljuje zgodnejše sončne vzhode. 🌅"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "Prilagodljiva osvetlitev"
|
||||
}
|
||||
202
custom_components/adaptive_lighting/translations/tr.json
Normal file
202
custom_components/adaptive_lighting/translations/tr.json
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
{
|
||||
"title": "Akıllı Aydınlatma",
|
||||
"options": {
|
||||
"step": {
|
||||
"init": {
|
||||
"title": "Akıllı Aydınlatma seçenekleri",
|
||||
"data": {
|
||||
"adapt_only_on_bare_turn_on": "Işıklar açıldığında geçerlidir. `true` olarak ayarlanırsa, eklenti yalnızca `light.turn_on` işlemi renk veya parlaklık belirtilmeden çağrıldığında uyarlama yapar (örneğin sahne etkinleştirmelerinde uyarlama yapılmaz). ❌🌈\n`false` olarak ayarlanırsa, renk veya parlaklık belirtilmiş olsa bile uyarlama yapılır. Bu ayarın çalışması için `take_over_control` etkin olmalıdır. 🕵️",
|
||||
"detect_non_ha_changes": "`detect_non_ha_changes`: `light.turn_on` dışındaki durum değişikliklerini algılar ve uyarlamayı durdurur. Bu ayarın çalışması için `take_over_control` etkin olmalıdır. 🕵️\nDikkat: ⚠️ Bazı ışıklar yanlışlıkla “açık” durumunu bildirebilir, bu da ışıkların beklenmedik şekilde açılmasına yol açabilir. Böyle bir durumla karşılaşırsanız bu özelliği devre dışı bırakın.",
|
||||
"include_config_in_attributes": "`include_config_in_attributes`: `true` olarak ayarlandığında, tüm seçenekleri Home Assistant’ta anahtarın attribute’ları olarak gösterir. 📝",
|
||||
"intercept": "`intercept`: `light.turn_on` çağrılarını yakalar ve renk ile parlaklığın anında uyarlanmasını sağlar. 🏎️ Renk ve parlaklığı desteklemeyen ışıklar için devre dışı bırakın.",
|
||||
"lights": "`lights`: Kontrol edilecek ışıkların entity_id listesi (boş bırakılabilir). 🌟",
|
||||
"max_brightness": "`max_brightness`: Maksimum parlaklık yüzdesi. 💡",
|
||||
"max_color_temp": "`max_color_temp`: En düşük renk sıcaklığı (Kelvin cinsinden). ❄️",
|
||||
"min_brightness": "min_brightness: Minimum parlaklık yüzdesi.💡",
|
||||
"min_color_temp": "`min_color_temp`: En yüksek (sıcak) renk sıcaklığı (Kelvin cinsinden). 🔥",
|
||||
"multi_light_intercept": "`multi_light_intercept`: Birden fazla ışığı hedefleyen `light.turn_on` çağrılarını yakalar ve uyarlama yapar. ➗⚠️ Bu, örneğin ışıklar farklı anahtarlardaysa tek bir `light.turn_on` çağrısının birden fazla çağrıya bölünmesine yol açabilir. `intercept` etkin olmalıdır.",
|
||||
"only_once": "`only_once`: Işıkları yalnızca açıldıklarında mı uyarlasın (`true`), yoksa sürekli uyarlamaya devam mı etsin (`false`). 🔄",
|
||||
"prefer_rgb_color": "`prefer_rgb_color`: Mümkünse ışık renk sıcaklığı yerine RGB renk ayarını tercih edip etmeyeceğini belirler. 🌈",
|
||||
"separate_turn_on_commands": "`separate_turn_on_commands`: Renk ve parlaklık için ayrı `light.turn_on` çağrıları kullanır; bazı ışık türleri için gereklidir. 🔀",
|
||||
"skip_redundant_commands": "`skip_redundant_commands`: Hedef durumu ışığın bilinen durumu ile aynı olan uyarlama komutlarını atlar. Ağ trafiğini azaltır ve bazı durumlarda uyarlamanın yanıt hızını artırır. 📉 \nFiziksel ışık durumları HA’daki kaydedilen durumla senkronize değilse devre dışı bırakın.",
|
||||
"take_over_control": "`take_over_control`: Işıklar açıkken ve uyarlanırken başka bir kaynaktan `light.turn_on` çağrılırsa Adaptive Lighting’i devre dışı bırakır. Dikkat: Bu işlem her `interval` süresinde `homeassistant.update_entity` çağrısı yapar! 🔒",
|
||||
"transition_until_sleep": "`transition_until_sleep`: Etkinleştirildiğinde, Adaptive Lighting uyku ayarlarını minimum değer olarak kabul eder ve gün batımından sonra bu değerlere geçiş yapar. 🌙"
|
||||
},
|
||||
"data_description": {
|
||||
"sunrise_offset": "Gün doğumu saatini, saniye cinsinden pozitif veya negatif bir kaydırma ile ayarlayın. ⏰",
|
||||
"sunset_offset": "Gün batımı saatini, saniye cinsinden pozitif veya negatif bir kaydırma ile ayarlayın. ⏰",
|
||||
"autoreset_control_seconds": "Manuel kontrolü belirtilen saniye sonunda otomatik olarak sıfırlar. Devre dışı bırakmak için 0 olarak ayarlayın. ⏲️",
|
||||
"brightness_mode": "Kullanılacak parlaklık modunu belirtir. Olası değerler: `default`, `linear` ve `tanh` (`brightness_mode_time_dark` ve `brightness_mode_time_light` ayarlarını kullanır). 📈",
|
||||
"sleep_brightness": "Uyku modundayken ışıkların parlaklık yüzdesi 😴",
|
||||
"sleep_color_temp": "Uyku modunda renk sıcaklığı ( `sleep_rgb_or_color_temp` `color_temp` olarak ayarlandığında kullanılır) Kelvin cinsinden. 😴",
|
||||
"send_split_delay": "Parlaklık ve renk ayarını aynı anda desteklemeyen ışıklar için `separate_turn_on_commands` arasındaki gecikme (ms). ⏲️",
|
||||
"initial_transition": "Işıklar `off` durumundan `on` durumuna geçerken ilk geçişin süresi (saniye cinsinden). ⏲️",
|
||||
"transition": "Işıklar değişirken geçiş süresi (saniye cinsinden). 🕑",
|
||||
"sleep_transition": "“Uyku modu” açılıp kapatıldığında geçiş süresi (saniye cinsinden). 😴",
|
||||
"interval": "Işıkların uyarlanma sıklığı (saniye cinsinden). 🔄",
|
||||
"brightness_mode_time_light": "(`brightness_mode='default'` ise göz ardı edilir) Gün doğumu/gün batımı öncesi/sonrası parlaklığı kademeli olarak artırma/azaltma süresi (saniye cinsinden). 📈📉",
|
||||
"brightness_mode_time_dark": "(`brightness_mode='default'` ise göz ardı edilir) Gün doğumu/gün batımı öncesi/sonrası parlaklığı kademeli olarak artırma/azaltma süresi (saniye cinsinden). 📈📉",
|
||||
"sleep_rgb_color": "Uyku modunda RGB renk ( `sleep_rgb_or_color_temp` \"rgb_color\" olarak ayarlandığında kullanılır). 🌈",
|
||||
"sunrise_time": "Gün doğumu için sabit bir saat (SS:DD:YY) belirleyin. 🌅",
|
||||
"sunset_time": "Gün batımı için sabit bir saat (SS:DD:YY) belirleyin. 🌇",
|
||||
"min_sunrise_time": "En erken sanal gün doğumu saatini (SS:DD:YY) belirleyin; daha geç gün doğumlarına izin verir. 🌅",
|
||||
"min_sunset_time": "En erken sanal gün batımı saatini (SS:DD:YY) belirleyin; daha geç gün batımlarına izin verir. 🌇",
|
||||
"max_sunrise_time": "En geç sanal gün doğumu saatini (SS:DD:YY) belirleyin; daha erken gün doğumlarına izin verir. 🌅",
|
||||
"max_sunset_time": "En geç sanal gün batımı saatini (SS:DD:YY) belirleyin; daha erken gün batımlarına izin verir. 🌇",
|
||||
"sleep_rgb_or_color_temp": "Uyku modunda `\"rgb_color\"` veya `\"color_temp\"` kullanın. 🌙",
|
||||
"adapt_delay": "Işık açıldıktan sonra Adaptive Lighting’in değişiklikleri uygulamasına kadar bekleme süresi (saniye cinsinden). Titremeyi önlemeye yardımcı olabilir. ⏲️"
|
||||
},
|
||||
"description": "Bir Adaptive Lighting bileşenini yapılandırın. Seçenek adları YAML ayarlarıyla uyumludur. Eğer bu girdiyi YAML’da tanımladıysanız, burada seçenekler görünmez. \nParametrelerin etkilerini gösteren etkileşimli grafikler için [bu web uygulamasını](https://basnijholt.github.io/adaptive-lighting) ziyaret edebilirsiniz. Daha fazla bilgi için [resmi dokümantasyona](https://github.com/basnijholt/adaptive-lighting#readme) bakın."
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"option_error": "Geçersiz seçenek",
|
||||
"entity_missing": "Seçilen bir veya birden fazla ışık entity’si Home Assistant’ta bulunamadı."
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"change_switch_settings": {
|
||||
"fields": {
|
||||
"only_once": {
|
||||
"description": "Işıkları yalnızca açıkken (`true`) uyarla, veya sürekli olarak uyarlamaya devam et (`false`).🔄"
|
||||
},
|
||||
"sunrise_offset": {
|
||||
"description": "Gün doğumu saatini, saniye cinsinden pozitif veya negatif bir kaydırma ile ayarlayın. ⏰"
|
||||
},
|
||||
"sunset_offset": {
|
||||
"description": "Gün batımı saatini, saniye cinsinden pozitif veya negatif bir kaydırma ile ayarlayın. ⏰"
|
||||
},
|
||||
"autoreset_control_seconds": {
|
||||
"description": "Manuel kontrolü belirtilen saniye sonunda otomatik olarak sıfırlar. Devre dışı bırakmak için 0 olarak ayarlayın. ⏲️"
|
||||
},
|
||||
"sleep_brightness": {
|
||||
"description": "Uyku modundayken ışıkların parlaklık yüzdesi 😴"
|
||||
},
|
||||
"max_color_temp": {
|
||||
"description": "Kelvin cinsinden en düşük renk sıcaklığı. ❄️"
|
||||
},
|
||||
"sleep_color_temp": {
|
||||
"description": "Uyku modunda renk sıcaklığı ( `sleep_rgb_or_color_temp` `color_temp` olarak ayarlandığında kullanılır) Kelvin cinsinden. 😴"
|
||||
},
|
||||
"send_split_delay": {
|
||||
"description": "Parlaklık ve renk ayarını aynı anda desteklemeyen ışıklar için `separate_turn_on_commands` arasındaki gecikme (ms). ⏲️"
|
||||
},
|
||||
"detect_non_ha_changes": {
|
||||
"description": "`light.turn_on` dışındaki durum değişikliklerini algılar ve uyarlamayı durdurur. Bu ayarın çalışması için `take_over_control` etkin olmalıdır. 🕵️ \nDikkat: ⚠️ Bazı ışıklar yanlışlıkla “açık” durumunu bildirebilir, bu da ışıkların beklenmedik şekilde açılmasına neden olabilir. Böyle bir durumda bu özelliği devre dışı bırakın."
|
||||
},
|
||||
"take_over_control": {
|
||||
"description": "Işıklar açıkken ve uyarlanırken başka bir kaynaktan `light.turn_on` çağrılırsa Adaptive Lighting’i devre dışı bırakır. Dikkat: Bu işlem her `interval` süresinde `homeassistant.update_entity` çağrısı yapar! 🔒"
|
||||
},
|
||||
"initial_transition": {
|
||||
"description": "Işıklar `off` durumundan `on` durumuna geçerken ilk geçişin süresi (saniye cinsinden). ⏲️"
|
||||
},
|
||||
"transition": {
|
||||
"description": "Işıklar değişirken geçiş süresi (saniye cinsinden). 🕑"
|
||||
},
|
||||
"sleep_transition": {
|
||||
"description": "“Uyku modu” açılıp kapatıldığında geçiş süresi (saniye cinsinden). 😴"
|
||||
},
|
||||
"entity_id": {
|
||||
"description": "Anahtarın Entity ID’si. 📝"
|
||||
},
|
||||
"max_brightness": {
|
||||
"description": "Maksimum parlaklık yüzdesi.💡"
|
||||
},
|
||||
"min_brightness": {
|
||||
"description": "Minimum parlaklık yüzdesi.💡"
|
||||
},
|
||||
"sleep_rgb_color": {
|
||||
"description": "Uyku modunda RGB renk ( `sleep_rgb_or_color_temp` \"rgb_color\" olarak ayarlandığında kullanılır). 🌈"
|
||||
},
|
||||
"sunrise_time": {
|
||||
"description": "Gün doğumu için sabit bir saat (SS:DD:YY) belirleyin. 🌅"
|
||||
},
|
||||
"sunset_time": {
|
||||
"description": "Gün batımı için sabit bir saat (SS:DD:YY) belirleyin. 🌇"
|
||||
},
|
||||
"use_defaults": {
|
||||
"description": "Bu servis çağrısında belirtilmeyen varsayılan değerleri ayarlar. Seçenekler: \n- `current` (varsayılan, mevcut değerleri korur) \n- `factory` (belgelendirilmiş varsayılanlara sıfırlar) \n- `configuration` (anahtar yapılandırma varsayılanlarına döner) ⚙️"
|
||||
},
|
||||
"min_sunset_time": {
|
||||
"description": "En erken sanal gün batımı saatini (SS:DD:YY) belirleyin; daha geç gün batımlarına izin verir. 🌇"
|
||||
},
|
||||
"max_sunrise_time": {
|
||||
"description": "En geç sanal gün doğumu saatini (SS:DD:YY) belirleyin; daha erken gün doğumlarına izin verir. 🌅"
|
||||
},
|
||||
"include_config_in_attributes": {
|
||||
"description": "`true` olarak ayarlandığında, tüm seçenekleri Home Assistant’ta anahtarın attribute’ları olarak gösterir. 📝"
|
||||
},
|
||||
"sleep_rgb_or_color_temp": {
|
||||
"description": "Uyku modunda `\"rgb_color\"` veya `\"color_temp\"` kullanın. 🌙"
|
||||
},
|
||||
"separate_turn_on_commands": {
|
||||
"description": "Renk ve parlaklık için ayrı `light.turn_on` çağrıları kullanın; bazı ışık türleri için gereklidir. 🔀"
|
||||
},
|
||||
"min_color_temp": {
|
||||
"description": "En yüksek (sıcak) renk sıcaklığı (Kelvin cinsinden). 🔥"
|
||||
},
|
||||
"prefer_rgb_color": {
|
||||
"description": "Mümkün olduğunda ışık renk sıcaklığı yerine RGB renk ayarını tercih edip etmeyeceğini belirler. 🌈"
|
||||
},
|
||||
"turn_on_lights": {
|
||||
"description": "Şu anda kapalı olan ışıkların açılıp açılmayacağını belirler. 🔆"
|
||||
},
|
||||
"adapt_delay": {
|
||||
"description": "Işık açıldıktan sonra Adaptive Lighting’in değişiklikleri uygulamasına kadar bekleme süresi (saniye cinsinden). Titremeyi önlemeye yardımcı olabilir. ⏲️"
|
||||
}
|
||||
},
|
||||
"description": "Anahtardaki tüm ayarları dilediğiniz gibi değiştirebilirsiniz. Buradaki seçeneklerin hepsi, yapılandırma akışındakilerle aynıdır."
|
||||
},
|
||||
"apply": {
|
||||
"fields": {
|
||||
"lights": {
|
||||
"description": "Ayarları bir veya birden fazla ışığa uygula.💡"
|
||||
},
|
||||
"transition": {
|
||||
"description": "Işıklar değişirken geçiş süresi (saniye cinsinden). 🕑"
|
||||
},
|
||||
"entity_id": {
|
||||
"description": "Uygulanacak ayarların bulunduğu anahtarın `entity_id`’si. 📝"
|
||||
},
|
||||
"adapt_brightness": {
|
||||
"description": "Işığın parlaklığının uyarlanıp uyarlanmayacağını belirler. 🌞"
|
||||
},
|
||||
"adapt_color": {
|
||||
"description": "Destekleyen ışıklarda rengin uyarlanıp uyarlanmayacağını belirler. 🌈"
|
||||
},
|
||||
"prefer_rgb_color": {
|
||||
"description": "Mümkün olduğunda ışık renk sıcaklığı yerine RGB renk ayarını tercih edip etmeyeceğini belirler. 🌈"
|
||||
},
|
||||
"turn_on_lights": {
|
||||
"description": "Şu anda kapalı olan ışıkların açılıp açılmayacağını belirler. 🔆"
|
||||
}
|
||||
},
|
||||
"description": "Şu anki Akıllı Işıklandırma ayarlarını ışıklara uygular."
|
||||
},
|
||||
"set_manual_control": {
|
||||
"fields": {
|
||||
"lights": {
|
||||
"description": "Işıkların entity_id(leri). Belirtilmezse, anahtardaki tüm ışıklar seçilir. 💡"
|
||||
},
|
||||
"entity_id": {
|
||||
"description": "Işığın “manuel olarak kontrol edildiğini” işaretlemek veya kaldırmak için kullanılacak anahtarın `entity_id`’si. 📝"
|
||||
},
|
||||
"manual_control": {
|
||||
"description": "Işığı “manuel kontrol” listesinden eklemek (`true`) veya çıkarmak (`false`) için kullanılır. 🔒"
|
||||
}
|
||||
},
|
||||
"description": "Bir ışığın 'manuel olarak kontrol' edilip edilmediğini işaretleyin."
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"step": {
|
||||
"user": {
|
||||
"title": "Akıllı ışıklandırma örneği için bir ad seçin.",
|
||||
"description": "Her örnek birden fazla ışık içerebilir!"
|
||||
}
|
||||
},
|
||||
"abort": {
|
||||
"already_configured": "Bu cihaz zaten ayarlanmış."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -42,7 +42,9 @@
|
|||
"adapt_only_on_bare_turn_on": "adapt_only_on_bare_turn_on: На початку вмикання світла. Якщо `true`, освітлення адаптується лише якщо `light.turn_on` викликано без вказання кольору чи яскравості. ❌🌈 Це, наприклад, запобігає адаптації, коли сцена активується. Якщо `false`, освітлення адаптується незалежно від наявності кольору чи яскравості у початковому `service_data`. Потребує ввімкнення `take_over_control`. 🕵️",
|
||||
"transition_until_sleep": "transition_until_sleep: Коли активовано, адаптивне освітлення буде ставитись до налаштування сну як мінімум, переходячи до цих значень після заходу сонця. 🌙",
|
||||
"intercept": "intercept: Перехоплювати та адаптувати виклики увімкнення світла (`light.turn_on`), щоб увімкнути миттєву адаптацію кольору та яскравості. 🏎️ Вимкніть для світла, що не підтримує увімкнення світла (`light.turn_on`) з кольором та яскравістю.",
|
||||
"include_config_in_attributes": "Включити конфігурацію в атрибути (`include_config_in_attributes`): Показувати всі опції як атрибути на перемикачі в Home Assistant, якщо встановлено значення `true`. 📝"
|
||||
"include_config_in_attributes": "Включити конфігурацію в атрибути (`include_config_in_attributes`): Показувати всі опції як атрибути на перемикачі в Home Assistant, якщо встановлено значення `true`. 📝",
|
||||
"multi_light_intercept": "multi_light_intercept: Перехоплення та адаптація викликів `light.turn_on`, які спрямовані на кілька світильників. ➗⚠️ Це може призвести до розділення одного виклику `light.turn_on` на кілька викликів, наприклад, коли світильники підключені до різних вимикачів. Потрібно ввімкнути `intercept`.",
|
||||
"skip_redundant_commands": "skip_redundant_commands: Пропускати надсилання команд адаптації, цільовий стан яких вже дорівнює відомому стану освітлення. Мінімізує мережевий трафік і покращує швидкість реагування адаптації в деяких ситуаціях. 📉Вимкнути, якщо фізичний стан освітлення не синхронізується із записаним станом HA."
|
||||
},
|
||||
"data_description": {
|
||||
"sunrise_offset": "Змінити час сходу сонця на +/- секунд. ⏰",
|
||||
|
|
@ -57,7 +59,16 @@
|
|||
"interval": "Частота адаптації освітлення, у секундах. 🔄",
|
||||
"sleep_brightness": "Відсоток яскравості світла в режимі сну. 😴",
|
||||
"sleep_color_temp": "Колірна температура в режимі сну (використовується, коли `sleep_rgb_or_color_temp` має значення `color_temp`) у Кельвінах. 😴",
|
||||
"sleep_transition": "Тривалість переходу, коли режим сну \"sleep mode\" увімкнено, у секундах. 😴"
|
||||
"sleep_transition": "Тривалість переходу, коли режим сну \"sleep mode\" увімкнено, у секундах. 😴",
|
||||
"sleep_rgb_color": "Колір RGB у режимі сну (використовується, коли `sleep_rgb_or_color_temp` має значення \"rgb_color\"). 🌈",
|
||||
"sunrise_time": "Встановіть фіксований час (ГГ:ХХ:СС) для сходу сонця. 🌅",
|
||||
"sunset_time": "Встановіть фіксований час (ГГ:ХХ:СС) для заходу сонця. 🌇",
|
||||
"min_sunrise_time": "Встановіть найраніший час віртуального сходу сонця (ГГ:ХХ:СС), враховуючи пізніші сходи. 🌅",
|
||||
"min_sunset_time": "Встановіть найраніший час віртуального заходу сонця (ГГ:ХХ:СС), враховуючи пізніші заходи сонця. 🌇",
|
||||
"max_sunrise_time": "Встановіть найпізніший час віртуального сходу сонця (ГГ:ХХ:СС), враховуючи більш ранні сходи сонця. 🌅",
|
||||
"max_sunset_time": "Встановіть найновіший час віртуального заходу сонця (ГГ:ХХ:СС), враховуючи більш ранні заходи сонця. 🌇",
|
||||
"sleep_rgb_or_color_temp": "Використовуйте `\"rgb_color\"` або `\"color_temp\"` у режимі сну. 🌙",
|
||||
"adapt_delay": "Час очікування (секунди) між увімкненням світла та застосуванням змін системою адаптивного освітлення. Може допомогти уникнути мерехтіння. ⏲️"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -75,6 +86,21 @@
|
|||
},
|
||||
"transition": {
|
||||
"description": "Тривалість переходу, коли світло змінюється, у секундах. 🕑"
|
||||
},
|
||||
"entity_id": {
|
||||
"description": "`entity_id` перемикача з налаштуваннями, які потрібно застосувати. 📝"
|
||||
},
|
||||
"adapt_brightness": {
|
||||
"description": "Чи потрібно адаптувати яскравість світла. 🌞"
|
||||
},
|
||||
"adapt_color": {
|
||||
"description": "Чи адаптувати колір допоміжних ламп. 🌈"
|
||||
},
|
||||
"prefer_rgb_color": {
|
||||
"description": "Чи надавати перевагу налаштуванню кольору RGB над температурою кольору світла, коли це можливо. 🌈"
|
||||
},
|
||||
"turn_on_lights": {
|
||||
"description": "Чи вмикати світло, яке наразі вимкнене. 🔆"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -127,6 +153,45 @@
|
|||
},
|
||||
"transition": {
|
||||
"description": "Тривалість переходу, коли світло змінюється, у секундах. 🕑"
|
||||
},
|
||||
"sleep_rgb_color": {
|
||||
"description": "Колір RGB у режимі сну (використовується, коли `sleep_rgb_or_color_temp` має значення \"rgb_color\"). 🌈"
|
||||
},
|
||||
"sunrise_time": {
|
||||
"description": "Встановіть фіксований час (ГГ:ХХ:СС) для сходу сонця. 🌅"
|
||||
},
|
||||
"sunset_time": {
|
||||
"description": "Встановіть фіксований час (ГГ:ХХ:СС) для заходу сонця. 🌇"
|
||||
},
|
||||
"use_defaults": {
|
||||
"description": "Встановлює значення за замовчуванням, не вказані в цьому виклику служби. Параметри: «current» (за замовчуванням, зберігає поточні значення), «factory» (скидає до задокументованих значень за замовчуванням) або «configuration» (повертає до значень за замовчуванням конфігурації комутатора). ⚙️"
|
||||
},
|
||||
"min_sunset_time": {
|
||||
"description": "Встановіть найраніший час віртуального заходу сонця (ГГ:ХХ:СС), враховуючи пізніші заходи сонця. 🌇"
|
||||
},
|
||||
"max_sunrise_time": {
|
||||
"description": "Встановіть найпізніший час віртуального сходу сонця (ГГ:ХХ:СС), враховуючи більш ранні сходи сонця. 🌅"
|
||||
},
|
||||
"include_config_in_attributes": {
|
||||
"description": "Показувати всі опції як атрибути перемикача в Домашньому помічнику, якщо встановлено значення `true`. 📝"
|
||||
},
|
||||
"sleep_rgb_or_color_temp": {
|
||||
"description": "Використовуйте `\"rgb_color\"` або `\"color_temp\"` у режимі сну. 🌙"
|
||||
},
|
||||
"separate_turn_on_commands": {
|
||||
"description": "Використовуйте окремі виклики `light.turn_on` для кольору та яскравості, що необхідно для деяких типів освітлення. 🔀"
|
||||
},
|
||||
"adapt_delay": {
|
||||
"description": "Час очікування (секунди) між увімкненням світла та застосуванням змін системою адаптивного освітлення. Може допомогти уникнути мерехтіння. ⏲️"
|
||||
},
|
||||
"min_color_temp": {
|
||||
"description": "Найтепліша колірна температура в Кельвінах. 🔥"
|
||||
},
|
||||
"prefer_rgb_color": {
|
||||
"description": "Чи надавати перевагу налаштуванню кольору RGB над температурою кольору світла, коли це можливо. 🌈"
|
||||
},
|
||||
"turn_on_lights": {
|
||||
"description": "Чи вмикати світло, яке наразі вимкнене. 🔆"
|
||||
}
|
||||
},
|
||||
"description": "Змініть будь-які налаштування, які ви бажаєте, у цьому перемикачі. Усі опції тут такі ж, як і в поточному конфігураційному файлі."
|
||||
|
|
@ -136,6 +201,12 @@
|
|||
"fields": {
|
||||
"lights": {
|
||||
"description": "Ідентифікатор(и) світла (entity_id(s) of lights). Якщо не вказано, вибираються всі лампи у перемикачі. 💡"
|
||||
},
|
||||
"entity_id": {
|
||||
"description": "`entity_id` перемикача, в якому потрібно (зняти) позначку світла як `керованого вручну`. 📝"
|
||||
},
|
||||
"manual_control": {
|
||||
"description": "Додавати (\"true\") чи видаляти (\"false\") світло зі списку \"manual_control\". 🔒"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,22 @@ if grep -q 'mypy-dev==1.14.0a3' core/requirements_test.txt; then
|
|||
# mypy-dev==1.14.0a3 seems to not be available anymore, HA 2024.12 is affected
|
||||
sed -i 's/mypy-dev==1.14.0a3/mypy-dev==1.14.0a7/' core/requirements_test.txt
|
||||
fi
|
||||
if grep -q 'mypy-dev==1.16.0a1' core/requirements_test.txt; then
|
||||
# mypy-dev==1.16.0a1 seems to not be available anymore, HA 2025.2 is affected
|
||||
sed -i 's/mypy-dev==1.16.0a1/mypy-dev==1.16.0a9/' core/requirements_test.txt
|
||||
fi
|
||||
if grep -q 'mypy-dev==1.16.0a3' core/requirements_test.txt; then
|
||||
# mypy-dev==1.16.0a3 seems to not be available anymore, HA 2025.3 is affected
|
||||
sed -i 's/mypy-dev==1.16.0a3/mypy-dev==1.16.0a9/' core/requirements_test.txt
|
||||
fi
|
||||
if grep -q 'mypy-dev==1.16.0a7' core/requirements_test.txt; then
|
||||
# mypy-dev==1.16.0a7 seems to not be available anymore, HA 2025.4 is affected
|
||||
sed -i 's/mypy-dev==1.16.0a7/mypy-dev==1.16.0a9/' core/requirements_test.txt
|
||||
fi
|
||||
if grep -q 'mypy-dev==1.16.0a8' core/requirements_test.txt; then
|
||||
# mypy-dev==1.16.0a8 seems to not be available anymore, HA 2025.5 and 2025.6 is affected
|
||||
sed -i 's/mypy-dev==1.16.0a8/mypy-dev==1.16.0a9/' core/requirements_test.txt
|
||||
fi
|
||||
|
||||
uv pip install -r core/requirements.txt
|
||||
uv pip install -r core/requirements_test.txt
|
||||
|
|
|
|||
26
tests/conftest.py
Normal file
26
tests/conftest.py
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
"""Pytest configuration for adaptive-lighting tests."""
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def mock_template_deprecation_issue():
|
||||
"""Mock the template deprecation issue creation.
|
||||
|
||||
The template component's legacy platform syntax creates deprecation
|
||||
issues that require translations. Since adaptive-lighting tests use
|
||||
template lights as test fixtures (not testing the template integration
|
||||
itself), we mock the issue creation to avoid translation validation errors.
|
||||
"""
|
||||
# Patch the create_legacy_template_issue function in the template helpers
|
||||
# to be a no-op when called for the deprecated_legacy_templates issue
|
||||
try:
|
||||
with patch(
|
||||
"homeassistant.components.template.helpers.create_legacy_template_issue",
|
||||
):
|
||||
yield
|
||||
except (ImportError, ModuleNotFoundError, AttributeError):
|
||||
# Older HA versions don't have this function
|
||||
yield
|
||||
|
|
@ -65,6 +65,7 @@ from homeassistant.components.adaptive_lighting.switch import (
|
|||
CONF_INTERCEPT,
|
||||
AdaptiveLightingManager,
|
||||
AdaptiveSwitch,
|
||||
SimpleSwitch,
|
||||
_attributes_have_changed,
|
||||
color_difference_redmean,
|
||||
create_context,
|
||||
|
|
@ -82,7 +83,16 @@ from homeassistant.components.light import (
|
|||
)
|
||||
from homeassistant.components.light import DOMAIN as LIGHT_DOMAIN
|
||||
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
|
||||
from homeassistant.components.template.light import LightTemplate
|
||||
|
||||
try:
|
||||
# HA >= 2025.8
|
||||
from homeassistant.components.template.light import (
|
||||
StateLightEntity as LightTemplate,
|
||||
)
|
||||
except ImportError:
|
||||
# HA < 2025.8
|
||||
from homeassistant.components.template.light import LightTemplate
|
||||
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.const import (
|
||||
ATTR_AREA_ID,
|
||||
|
|
@ -1000,26 +1010,36 @@ def test_attributes_have_changed():
|
|||
new_attributes=attrs,
|
||||
**kwargs,
|
||||
)
|
||||
_LOGGER.debug("Test switch from color_temp to rgb_color")
|
||||
assert not _attributes_have_changed(
|
||||
# Test color mode switches - feature added to detect external changes
|
||||
# (e.g., when Hue scenes change light from color_temp to RGB mode)
|
||||
# See: https://github.com/basnijholt/adaptive-lighting/issues/1275
|
||||
#
|
||||
# All mode switches are now detected bidirectionally by checking original
|
||||
# attributes BEFORE conversion in _has_color_mode_changed().
|
||||
_LOGGER.debug(
|
||||
"Test switch from color_temp to rgb_color - should detect mode change",
|
||||
)
|
||||
assert _attributes_have_changed(
|
||||
old_attributes={ATTR_BRIGHTNESS: 1, ATTR_COLOR_TEMP_KELVIN: 2702},
|
||||
new_attributes={ATTR_BRIGHTNESS: 1, ATTR_RGB_COLOR: (255, 166, 87)},
|
||||
**kwargs,
|
||||
)
|
||||
_LOGGER.debug("Test switch from rgb_color to color_temp")
|
||||
assert not _attributes_have_changed(
|
||||
_LOGGER.debug(
|
||||
"Test switch from rgb_color to color_temp - should detect mode change",
|
||||
)
|
||||
assert _attributes_have_changed(
|
||||
old_attributes={ATTR_BRIGHTNESS: 1, ATTR_RGB_COLOR: (255, 166, 87)},
|
||||
new_attributes={ATTR_BRIGHTNESS: 1, ATTR_COLOR_TEMP_KELVIN: 2702},
|
||||
**kwargs,
|
||||
)
|
||||
_LOGGER.debug("Test switch from color_temp to color_xy")
|
||||
assert not _attributes_have_changed(
|
||||
_LOGGER.debug("Test switch from color_temp to color_xy - should detect mode change")
|
||||
assert _attributes_have_changed(
|
||||
old_attributes={ATTR_BRIGHTNESS: 1, ATTR_COLOR_TEMP_KELVIN: 2702},
|
||||
new_attributes={ATTR_BRIGHTNESS: 1, ATTR_XY_COLOR: (0.526, 0.387)},
|
||||
**kwargs,
|
||||
)
|
||||
_LOGGER.debug("Test switch from color_xy to color_temp")
|
||||
assert not _attributes_have_changed(
|
||||
_LOGGER.debug("Test switch from color_xy to color_temp - should detect mode change")
|
||||
assert _attributes_have_changed(
|
||||
old_attributes={ATTR_BRIGHTNESS: 1, ATTR_XY_COLOR: (0.526, 0.387)},
|
||||
new_attributes={ATTR_BRIGHTNESS: 1, ATTR_COLOR_TEMP_KELVIN: 2702},
|
||||
**kwargs,
|
||||
|
|
@ -2266,3 +2286,175 @@ async def test_brightness_mode(hass, brightness_mode, dark, light):
|
|||
# After sunrise the brightness should be light_brightness
|
||||
await patch_time_and_update(after_sunrise)
|
||||
assert is_approx_equal(switch._settings[ATTR_BRIGHTNESS_PCT], light_brightness)
|
||||
|
||||
|
||||
async def test_simple_switch_initial_state_not_none(hass):
|
||||
"""Test that SimpleSwitch._state is not None after __init__.
|
||||
|
||||
Regression test for https://github.com/basnijholt/adaptive-lighting/issues/1264
|
||||
|
||||
When an entity is disabled in Home Assistant, async_added_to_hass() is never
|
||||
called. Previously, SimpleSwitch._state was initialized to None and only set
|
||||
to True/False in async_added_to_hass(). This caused an infinite loop in
|
||||
AdaptiveSwitch._setup_listeners() which waits for all SimpleSwitch._state
|
||||
to be not None.
|
||||
|
||||
The fix is to initialize _state to the initial_state value in __init__.
|
||||
"""
|
||||
entry = MockConfigEntry(domain=DOMAIN, data={CONF_NAME: DEFAULT_NAME})
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
# Create a SimpleSwitch without calling async_added_to_hass
|
||||
# (simulating a disabled entity)
|
||||
switch = SimpleSwitch(
|
||||
which="Test",
|
||||
initial_state=True,
|
||||
hass=hass,
|
||||
config_entry=entry,
|
||||
icon="mdi:test",
|
||||
)
|
||||
|
||||
# Before the fix: _state would be None, causing infinite loop
|
||||
# After the fix: _state should be the initial_state value
|
||||
assert switch._state is not None, (
|
||||
"SimpleSwitch._state should not be None after __init__. "
|
||||
"This would cause an infinite loop in _setup_listeners when the entity is disabled."
|
||||
)
|
||||
assert switch._state is True # Should be the initial_state value
|
||||
|
||||
|
||||
async def test_simple_switch_state_after_async_added_to_hass(hass):
|
||||
"""Test that SimpleSwitch._state is properly set after async_added_to_hass.
|
||||
|
||||
This ensures the fix for #1264 doesn't break normal entity initialization.
|
||||
"""
|
||||
entry = MockConfigEntry(domain=DOMAIN, data={CONF_NAME: DEFAULT_NAME})
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
# Create switches with different initial states
|
||||
switch_true = SimpleSwitch(
|
||||
which="Test True",
|
||||
initial_state=True,
|
||||
hass=hass,
|
||||
config_entry=entry,
|
||||
icon="mdi:test",
|
||||
)
|
||||
switch_false = SimpleSwitch(
|
||||
which="Test False",
|
||||
initial_state=False,
|
||||
hass=hass,
|
||||
config_entry=entry,
|
||||
icon="mdi:test",
|
||||
)
|
||||
|
||||
# Verify initial state is set correctly
|
||||
assert switch_true._state is True
|
||||
assert switch_false._state is False
|
||||
|
||||
# Call async_added_to_hass (simulating normal entity setup)
|
||||
# Since there's no last state, it should use the initial_state
|
||||
await switch_true.async_added_to_hass()
|
||||
await switch_false.async_added_to_hass()
|
||||
|
||||
# State should still be correct after async_added_to_hass
|
||||
assert switch_true._state is True
|
||||
assert switch_false._state is False
|
||||
|
||||
|
||||
def test_attributes_have_changed_light_mode_switch():
|
||||
"""Test detection of external light mode changes (color_temp vs rgb vs xy).
|
||||
|
||||
Regression test for https://github.com/basnijholt/adaptive-lighting/issues/1275
|
||||
|
||||
When a user activates a Hue Scene (or similar) via an external app, the light
|
||||
may switch from color_temp mode to RGB/XY mode (or vice versa). This should be
|
||||
detected as an external change so AL doesn't immediately override it.
|
||||
|
||||
The _has_color_mode_changed() function checks the original attributes BEFORE
|
||||
any conversion, enabling bidirectional mode change detection.
|
||||
"""
|
||||
context = Context()
|
||||
base_kwargs = {
|
||||
"light": "light.test",
|
||||
"adapt_brightness": True,
|
||||
"context": context,
|
||||
}
|
||||
|
||||
# Test 1: adapt_color=True - all mode changes should be detected
|
||||
kwargs_adapt_color = {**base_kwargs, "adapt_color": True}
|
||||
|
||||
# color_temp → RGB
|
||||
assert _attributes_have_changed(
|
||||
old_attributes={ATTR_BRIGHTNESS: 128, ATTR_COLOR_TEMP_KELVIN: 4000},
|
||||
new_attributes={ATTR_BRIGHTNESS: 128, ATTR_RGB_COLOR: (255, 0, 0)},
|
||||
**kwargs_adapt_color,
|
||||
), "Should detect color_temp → RGB mode switch"
|
||||
|
||||
# color_temp → XY
|
||||
assert _attributes_have_changed(
|
||||
old_attributes={ATTR_BRIGHTNESS: 128, ATTR_COLOR_TEMP_KELVIN: 4000},
|
||||
new_attributes={ATTR_BRIGHTNESS: 128, ATTR_XY_COLOR: (0.64, 0.33)},
|
||||
**kwargs_adapt_color,
|
||||
), "Should detect color_temp → XY mode switch"
|
||||
|
||||
# RGB → color_temp
|
||||
assert _attributes_have_changed(
|
||||
old_attributes={ATTR_BRIGHTNESS: 128, ATTR_RGB_COLOR: (255, 0, 0)},
|
||||
new_attributes={ATTR_BRIGHTNESS: 128, ATTR_COLOR_TEMP_KELVIN: 4000},
|
||||
**kwargs_adapt_color,
|
||||
), "Should detect RGB → color_temp mode switch"
|
||||
|
||||
# RGB → XY
|
||||
assert _attributes_have_changed(
|
||||
old_attributes={ATTR_BRIGHTNESS: 128, ATTR_RGB_COLOR: (255, 0, 0)},
|
||||
new_attributes={ATTR_BRIGHTNESS: 128, ATTR_XY_COLOR: (0.64, 0.33)},
|
||||
**kwargs_adapt_color,
|
||||
), "Should detect RGB → XY mode switch"
|
||||
|
||||
# XY → color_temp
|
||||
assert _attributes_have_changed(
|
||||
old_attributes={ATTR_BRIGHTNESS: 128, ATTR_XY_COLOR: (0.64, 0.33)},
|
||||
new_attributes={ATTR_BRIGHTNESS: 128, ATTR_COLOR_TEMP_KELVIN: 4000},
|
||||
**kwargs_adapt_color,
|
||||
), "Should detect XY → color_temp mode switch"
|
||||
|
||||
# XY → RGB
|
||||
assert _attributes_have_changed(
|
||||
old_attributes={ATTR_BRIGHTNESS: 128, ATTR_XY_COLOR: (0.64, 0.33)},
|
||||
new_attributes={ATTR_BRIGHTNESS: 128, ATTR_RGB_COLOR: (255, 0, 0)},
|
||||
**kwargs_adapt_color,
|
||||
), "Should detect XY → RGB mode switch"
|
||||
|
||||
# No mode change - same type with same values shouldn't be detected
|
||||
assert not _attributes_have_changed(
|
||||
old_attributes={ATTR_BRIGHTNESS: 128, ATTR_COLOR_TEMP_KELVIN: 4000},
|
||||
new_attributes={ATTR_BRIGHTNESS: 128, ATTR_COLOR_TEMP_KELVIN: 4000},
|
||||
**kwargs_adapt_color,
|
||||
), "Same color_temp should not be detected as change"
|
||||
|
||||
assert not _attributes_have_changed(
|
||||
old_attributes={ATTR_BRIGHTNESS: 128, ATTR_RGB_COLOR: (255, 0, 0)},
|
||||
new_attributes={ATTR_BRIGHTNESS: 128, ATTR_RGB_COLOR: (255, 0, 0)},
|
||||
**kwargs_adapt_color,
|
||||
), "Same RGB should not be detected as change"
|
||||
|
||||
assert not _attributes_have_changed(
|
||||
old_attributes={ATTR_BRIGHTNESS: 128, ATTR_XY_COLOR: (0.64, 0.33)},
|
||||
new_attributes={ATTR_BRIGHTNESS: 128, ATTR_XY_COLOR: (0.64, 0.33)},
|
||||
**kwargs_adapt_color,
|
||||
), "Same XY should not be detected as change"
|
||||
|
||||
# Test 2: adapt_color=False - mode changes should NOT be detected
|
||||
kwargs_no_adapt = {**base_kwargs, "adapt_color": False}
|
||||
|
||||
assert not _attributes_have_changed(
|
||||
old_attributes={ATTR_BRIGHTNESS: 128, ATTR_COLOR_TEMP_KELVIN: 4000},
|
||||
new_attributes={ATTR_BRIGHTNESS: 128, ATTR_RGB_COLOR: (255, 0, 0)},
|
||||
**kwargs_no_adapt,
|
||||
), "Mode change should not be detected when adapt_color=False"
|
||||
|
||||
assert not _attributes_have_changed(
|
||||
old_attributes={ATTR_BRIGHTNESS: 128, ATTR_RGB_COLOR: (255, 0, 0)},
|
||||
new_attributes={ATTR_BRIGHTNESS: 128, ATTR_COLOR_TEMP_KELVIN: 4000},
|
||||
**kwargs_no_adapt,
|
||||
), "RGB → color_temp should not be detected when adapt_color=False"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue