From 44c2850e32028c61536c5f8033f03f8b76e31028 Mon Sep 17 00:00:00 2001 From: Bas Nijholt Date: Sat, 19 Dec 2020 13:56:38 +0100 Subject: [PATCH 01/23] add switch entity_id to adaptive_lighting.manual_control event --- custom_components/adaptive_lighting/switch.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/custom_components/adaptive_lighting/switch.py b/custom_components/adaptive_lighting/switch.py index bb1c5cda..3c373782 100755 --- a/custom_components/adaptive_lighting/switch.py +++ b/custom_components/adaptive_lighting/switch.py @@ -239,7 +239,7 @@ async def handle_set_manual_control(switch: AdaptiveSwitch, service_call: Servic if service_call.data[CONF_MANUAL_CONTROL]: for light in all_lights: switch.turn_on_off_listener.manual_control[light] = True - _fire_manual_control_event(switch.hass, light, service_call.context) + _fire_manual_control_event(switch, light, service_call.context) else: switch.turn_on_off_listener.reset(*all_lights) # pylint: disable=protected-access @@ -253,11 +253,16 @@ async def handle_set_manual_control(switch: AdaptiveSwitch, service_call: Servic @callback def _fire_manual_control_event( - hass: HomeAssistant, light: str, context: Context, is_async=True + switch: AdaptiveSwitch, light: str, context: Context, is_async=True ): """Fire an event that 'light' is marked as manual_control.""" + hass = switch.hass fire = hass.bus.async_fire if is_async else hass.bus.fire - fire(f"{DOMAIN}.manual_control", {ATTR_ENTITY_ID: light}, context=context) + fire( + f"{DOMAIN}.manual_control", + {ATTR_ENTITY_ID: light, SWITCH_DOMAIN: switch.entity_id}, + context=context, + ) async def async_setup_entry( @@ -756,6 +761,7 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): and self._detect_non_ha_changes and not force and await self.turn_on_off_listener.significant_change( + self, light, adapt_brightness, adapt_color, @@ -830,6 +836,7 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): if ( self._take_over_control and self.turn_on_off_listener.is_manually_controlled( + self, light, force, self.adapt_brightness_switch.is_on, @@ -1236,6 +1243,7 @@ class TurnOnOffListener: def is_manually_controlled( self, + switch: AdaptiveSwitch, light: str, force: bool, adapt_brightness: bool, @@ -1260,7 +1268,7 @@ class TurnOnOffListener: # Light was already on and 'light.turn_on' was not called by # the adaptive_lighting integration. manual_control = self.manual_control[light] = True - _fire_manual_control_event(self.hass, light, turn_on_event.context) + _fire_manual_control_event(switch, light, turn_on_event.context) _LOGGER.debug( "'%s' was already on and 'light.turn_on' was not called by the" " adaptive_lighting integration (context.id='%s'), the Adaptive" @@ -1273,6 +1281,7 @@ class TurnOnOffListener: async def significant_change( self, + switch: AdaptiveSwitch, light: str, adapt_brightness: bool, adapt_color: bool, @@ -1331,7 +1340,7 @@ class TurnOnOffListener: # N times in a row. We do this because sometimes a state changes # happens only *after* a new update interval has already started. self.manual_control[light] = True - _fire_manual_control_event(self.hass, light, context, is_async=False) + _fire_manual_control_event(switch, light, context, is_async=False) else: if n_changes > 1: _LOGGER.debug( From ff2321ece9790abff7256cb0a26528f42c763575 Mon Sep 17 00:00:00 2001 From: Bas Nijholt Date: Sat, 19 Dec 2020 14:06:48 +0100 Subject: [PATCH 02/23] simplify _split_service_data --- custom_components/adaptive_lighting/switch.py | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/custom_components/adaptive_lighting/switch.py b/custom_components/adaptive_lighting/switch.py index 3c373782..921a228a 100755 --- a/custom_components/adaptive_lighting/switch.py +++ b/custom_components/adaptive_lighting/switch.py @@ -184,25 +184,19 @@ def is_our_context(context: Optional[Context]) -> bool: return context.id.startswith(_DOMAIN_SHORT) -def _copy_and_pop(dct, keys): - """Copy a dictionary and remove 'keys' if they exist.""" - copy = dct.copy() - for key in keys: - copy.pop(key, None) - return copy - - def _split_service_data(service_data, adapt_brightness, adapt_color): """Split service_data into two dictionaries (for color and brightness).""" service_datas = [] if adapt_color: - service_datas.append( - _copy_and_pop(service_data, (ATTR_WHITE_VALUE, ATTR_BRIGHTNESS)) - ) + service_data_color = service_data.copy() + service_data_color.pop(ATTR_WHITE_VALUE, None) + service_data_color.pop(ATTR_BRIGHTNESS, None) + service_datas.append(service_data_color) if adapt_brightness: - service_datas.append( - _copy_and_pop(service_data, (ATTR_RGB_COLOR, ATTR_COLOR_TEMP)) - ) + service_data_brightness = service_data.copy() + service_data_brightness.pop(ATTR_RGB_COLOR, None) + service_data_brightness.pop(ATTR_COLOR_TEMP, None) + service_datas.append(service_data_brightness) return service_datas From b9ec138c7db7f2ebacbe0119d309126ac2e55519 Mon Sep 17 00:00:00 2001 From: Bas Nijholt Date: Sat, 19 Dec 2020 14:09:26 +0100 Subject: [PATCH 03/23] log fire adaptive_lighting.manual_control event --- custom_components/adaptive_lighting/switch.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/custom_components/adaptive_lighting/switch.py b/custom_components/adaptive_lighting/switch.py index 921a228a..4fd2bf89 100755 --- a/custom_components/adaptive_lighting/switch.py +++ b/custom_components/adaptive_lighting/switch.py @@ -252,6 +252,11 @@ def _fire_manual_control_event( """Fire an event that 'light' is marked as manual_control.""" hass = switch.hass fire = hass.bus.async_fire if is_async else hass.bus.fire + _LOGGER.debug( + "'adaptive_lighting.manual_control' event fired for %s for light %s", + switch.entity_id, + light, + ) fire( f"{DOMAIN}.manual_control", {ATTR_ENTITY_ID: light, SWITCH_DOMAIN: switch.entity_id}, From 91b27490ef16fa85ddaccbc5223e33cd8e4c205f Mon Sep 17 00:00:00 2001 From: Bas Nijholt Date: Sat, 19 Dec 2020 14:34:47 +0100 Subject: [PATCH 04/23] wait between turn_on commands for transition/2 if separate_turn_on_commands is used See #49 --- custom_components/adaptive_lighting/switch.py | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/custom_components/adaptive_lighting/switch.py b/custom_components/adaptive_lighting/switch.py index 4fd2bf89..2575a3e5 100755 --- a/custom_components/adaptive_lighting/switch.py +++ b/custom_components/adaptive_lighting/switch.py @@ -186,6 +186,10 @@ def is_our_context(context: Optional[Context]) -> bool: def _split_service_data(service_data, adapt_brightness, adapt_color): """Split service_data into two dictionaries (for color and brightness).""" + transition = service_data.get(ATTR_TRANSITION) + if transition is not None: + # Split the transition over both commands + service_data[ATTR_TRANSITION] /= 2 service_datas = [] if adapt_color: service_data_color = service_data.copy() @@ -769,12 +773,8 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): ): return self.turn_on_off_listener.last_service_data[light] = service_data - service_datas = ( - _split_service_data(service_data, adapt_brightness, adapt_color) - if self._separate_turn_on_commands - else [service_data] - ) - for service_data in service_datas: + + async def turn_on(service_data): _LOGGER.debug( "%s: Scheduling 'light.turn_on' with the following 'service_data': %s" " with context.id='%s'", @@ -789,6 +789,18 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): context=context, ) + if not self._separate_turn_on_commands: + await turn_on(service_data) + else: + service_data_color, service_data_brightness = _split_service_data( + service_data, adapt_brightness, adapt_color + ) + await turn_on(service_data_color) + transition = service_data_color.get(ATTR_TRANSITION) + if transition is not None: + await asyncio.sleep(transition) + await turn_on(service_data_brightness) + async def _update_attrs_and_maybe_adapt_lights( self, lights: Optional[List[str]] = None, From 8a97480672cfff6f1c0bd948eba92fa04e022ac1 Mon Sep 17 00:00:00 2001 From: Bas Nijholt Date: Sat, 19 Dec 2020 15:14:35 +0100 Subject: [PATCH 05/23] README update with documentation --- README.md | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 162 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 91615e11..46d45d02 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,167 @@ -# Adaptive Lighting component +# Adaptive Lighting component for Home Assistant -Try out this code by adding https://github.com/basnijholt/adaptive-lighting to your custom repos in HACS and install it! +![](https://github.com/home-assistant/brands/raw/b4a168b9af282ef916e120d31091ecd5e3c35e66/core_integrations/adaptive_lighting/icon.png) -See the documentation at https://deploy-preview-14877--home-assistant-docs.netlify.app/integrations/adaptive_lighting/ +_Try out this code by adding https://github.com/basnijholt/adaptive-lighting to your custom repos in HACS and install it!_ +*This `custom_component` is also being added to `core`, see [this PR](https://github.com/home-assistant/core/pull/40626), although it might take months before it makes it in.* -See [this video on Reddit](https://www.reddit.com/r/homeassistant/comments/jabhso/ha_has_it_before_apple_has_even_finished_it_i/) to see how to add the integration and set the options. +The `adaptive_lighting` platform changes the settings of your lights throughout the day. +It uses the position of the sun to calculate the color temperature and brightness that is most fitting for that time of the day. +Scientific research has shown that this helps to maintain your natural circadian rhythm (your biological clock) and might lead to improved sleep, mood, and general well-being. + +In practical terms, this means that after the sun sets, the brightness of your lights will decrease to a certain minimum brightness, while the color temperature will be at its coolest color temperature at noon, after which it will decrease and reach its warmest color at sunset. +Around sunrise, the opposite will happen. + +Additionally, the integration provides a way to define and set your lights in "sleep mode". +When "sleep mode" is enabled, the lights will be at a minimal brightness and have a very warm color. + +The integration creates 4 switches (in this example the component's name is `"living_room"`): +1. `switch.adaptive_lighting_living_room`, which turns the Adaptive Lighting integration on or off. It has several attributes that show the current light settings. +2. `switch.adaptive_lighting_sleep_mode_living_room`, which when activated, turns on "sleep mode" (you can set a specific `sleep_brightness` and `sleep_color_temp`). +3. `switch.adaptive_lighting_adapt_brightness_living_room`, which sets whether the integration should adapt the brightness of the lights (if supported by the light). +4. `switch.adaptive_lighting_adapt_color_living_room`, which sets whether the integration should adapt the color of the lights (if supported by the light). + +## Taking back control + +Although having your lights automatically adapt is great most of the time, there might be times at which you want to set the lights to a different color/brightness and keep it that way. +For this purpose, the integration (when `take_over_control` is enabled) automatically detects whether someone (e.g., person toggling the light switch) or something (automation) changes the lights. +If this happens *and* the light is already on, the light that was changed gets marked as "manually controlled" and the Adaptive Lighting component will stop adapting that light until it turns off and on again (or if you use the service call `adaptive_lighting.set_manual_control`). +This mechanism works by listening to all `light.turn_on` calls that change the color or brightness and by noting that the component did not make the call. +Additionally, there is an option to detect all state changes (when `detect_non_ha_changes` is enabled), so also changes to the lights that were not made by a `light.turn_on` call (e.g., through an app or via something outside of Home Assistant.) +It does this by comparing a light's state to Adaptive Lighting's previously used settings. +Whenever a light gets marked as "manually controlled", an `adaptive_lighting.manual_control` event is fired, such that one can use this information in automations. + +## Configuration + +This integration is both fully configurable through YAML _and_ the frontend. (**Configuration** -> **Integrations** -> **Adaptive Lighting**, **Adaptive Lighting** -> **Options**) +Here, the options in the frontend and in YAML have the same names. + +```yaml +# Example configuration.yaml entry +adaptive_lighting: + lights: + - light.living_room_lights +``` + +### Options +| option | description | required | default | type | +|-----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|-----------|---------| +| name | The name to use when displaying this switch. | False | default | string | +| lights | List of light entities for Adaptive Lighting to control (may be empty). | False | list | [] | +| prefer_rgb_color | Whether to use RGB color adjustment instead of native light color temperature. | False | False | boolean | +| initial_transition | How long the first transition is when the lights go from `off` to `on` (or when "sleep mode" is toggled). | False | 1 | time | +| transition | How long the transition is when the lights change, in seconds. | False | 45 | integer | +| interval | How often to adapt the lights, in seconds. | False | 90 | integer | +| min_brightness | The minimum percent of brightness to set the lights to. | False | 1 | integer | +| max_brightness | The maximum percent of brightness to set the lights to. | False | 100 | integer | +| min_color_temp | The warmest color temperature to set the lights to, in Kelvin. | False | 2000 | integer | +| max_color_temp | The coldest color temperature to set the lights to, in Kelvin. | False | 5500 | integer | +| sleep_brightness | Brightness of lights while the sleep mode is enabled. | False | 1 | integer | +| sleep_color_temp | Color temperature of lights while the sleep mode is enabled. | False | 1000 | integer | +| sunrise_time | Override the sunrise time with a fixed time. | False | time | | +| sunrise_offset | Change the sunrise time with a positive or negative offset. | False | 0 | time | +| sunset_time | Override the sunset time with a fixed time. | False | time | | +| sunset_offset | Change the sunset time with a positive or negative offset. | False | 0 | time | +| only_once | Whether to keep adapting the lights (false) or to only adapt the lights as soon as they are turned on (true). | False | False | boolean | +| take_over_control | If another source calls `light.turn_on` while the lights are on and being adapted, disable Adaptive Lighting. | False | True | boolean | +| detect_non_ha_changes | Whether to detect state changes and stop adapting lights, even not from `light.turn_on`. Needs `take_over_control` to be enabled. Note that by enabling this option, it calls 'homeassistant.update_entity' every 'interval'! | inclusive | False | boolean | + +Full example: + +```yaml +# Example configuration.yaml entry +adaptive_lighting: +- name: "default" + lights: [] + prefer_rgb_color: false + transition: 45 + initial_transition: 1 + interval: 90 + min_brightness: 1 + max_brightness: 100 + min_color_temp: 2000 + max_color_temp: 5500 + sleep_brightness: 1 + sleep_color_temp: 1000 + sunrise_time: "08:00:00" # override the sunrise time + sunrise_offset: + sunset_time: + sunset_offset: 1800 # in seconds or '00:15:00' + take_over_control: true + detect_non_ha_changes: false + only_once: false + +``` + +### Services + +`adaptive_lighting.apply` applies Adaptive Lighting settings to lights on demand. + +| Service data attribute | Optional | Description | +|---------------------------|----------|-------------------------------------------------------------------------| +| `entity_id` | no | The `entity_id` of the switch with the settings to apply. | +| `lights` | no | A light (or list of lights) to apply the settings to. | +| `transition` | yes | The number of seconds for the transition. | +| `adapt_brightness` | yes | Whether to change the brightness of the light or not. | +| `adapt_color` | yes | Whether to adapt the color on supporting lights. | +| `prefer_rgb_color` | yes | Whether to prefer RGB color adjustment over of native light color temperature when possible. | +| `turn_on_lights` | yes | Whether to turn on lights that are currently off. | + +`adaptive_lighting.set_manual_control` can mark (or unmark) whether a light is "manually controlled", meaning that when a light has `manual_control`, the light is not adapted. + +| Service data attribute | Optional | Description | +|------------------------|----------|--------------------------------------------------------------------------------------------------------------------------------------| +| `entity_id` | no | The `entity_id` of the switch in which to (un)mark the light as being "manually controlled". | +| `lights` | no | A light (or list of lights) to apply the settings to. | +| `manual_control` | no | Whether to mark (true) or unmark (false) the light as "manually controlled", when not specified it selects all lights in the switch. | + + +## Automation examples + +Reset the `manual_control` status of a light after an hour. +```yaml +- alias: "Adaptive lighting: reset manual_control after 1 hour" + mode: parallel + trigger: + platform: event + event_type: adaptive_lighting.manual_control + variables: + light: "{{ trigger.event.data.entity_id }}" + switch: "{{ trigger.event.data.switch }}" + action: + - delay: "01:00:00" + - condition: template + value_template: "{{ light in state_attr(switch, 'manual_control') }}" + - service: adaptive_lighting.set_manual_control + data: + entity_id: "{{ switch }}" + lights: "{{ light }}" + manual_control: false +``` + +Toggle multiple Adaptive Lighting switches to "sleep mode" using an `input_boolean.sleep_mode`. + +```yaml +- alias: "Adaptive lighting: toggle 'sleep mode'" + trigger: + - platform: state + entity_id: input_boolean.sleep_mode + - platform: homeassistant + event: start # in case the states aren't properly restored + variables: + sleep_mode: "{{ states('input_boolean.sleep_mode') }}" + action: + service: "switch.turn_{{ sleep_mode }}" + entity_id: + - switch.adaptive_lighting_sleep_mode_living_room + - switch.adaptive_lighting_sleep_mode_bedroom +``` + +# Other + +See the documentation of the PR at https://deploy-preview-14877--home-assistant-docs.netlify.app/integrations/adaptive_lighting/ and [this video on Reddit](https://www.reddit.com/r/homeassistant/comments/jabhso/ha_has_it_before_apple_has_even_finished_it_i/) to see how to add the integration and set the options. + +This integration was originally based of the great work of @claytonjn https://github.com/claytonjn/hass-circadian_lighting, but has been 100% rewritten and extended with new features. # Having problems? Please enable debug logging by putting this in `configuration.yaml`: @@ -14,7 +171,7 @@ logger: logs: custom_components.adaptive_lighting: debug ``` -and after the problem occurs please create an issue with the log. +and after the problem occurs please create an issue with the log (`/config/home-assistant.log`). ### Graphs! From fa9ad171a5a42a7aea45b82126f93d51506e408d Mon Sep 17 00:00:00 2001 From: Bas Nijholt Date: Sat, 19 Dec 2020 15:41:03 +0100 Subject: [PATCH 06/23] remove info.md --- info.md | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 info.md diff --git a/info.md b/info.md deleted file mode 100644 index 564c61b7..00000000 --- a/info.md +++ /dev/null @@ -1,7 +0,0 @@ -## Stay healthier and sleep better by syncing your lights with natural daylight to maintain your circadian rhythm! - - - -Circadian Lighting slowly synchronizes your color changing lights with the regular naturally occurring color temperature of the sky throughout the day. This gives your environment a more natural feel, with cooler hues during the midday and warmer tints near twilight and dawn. - -In addition, Circadian Lighting can set your lights to a nice cool white at 1% in “Sleep” mode, which is far brighter than starlight but won’t reset your circadian rhythm or break down too much rhodopsin in your eyes. \ No newline at end of file From 4257d27deeffeb2f9be9acb287f23c5be6c2a296 Mon Sep 17 00:00:00 2001 From: Bas Nijholt Date: Sat, 19 Dec 2020 16:33:33 +0100 Subject: [PATCH 07/23] deal with 'light.turn_on' with multiple lights, which appear as csv list Solves the bug reported in #39 (https://github.com/basnijholt/adaptive-lighting/issues/39) --- custom_components/adaptive_lighting/switch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/adaptive_lighting/switch.py b/custom_components/adaptive_lighting/switch.py index 2575a3e5..597928f3 100755 --- a/custom_components/adaptive_lighting/switch.py +++ b/custom_components/adaptive_lighting/switch.py @@ -1175,7 +1175,7 @@ class TurnOnOffListener: service = event.data[ATTR_SERVICE] service_data = event.data[ATTR_SERVICE_DATA] - entity_ids = cv.ensure_list(service_data[ATTR_ENTITY_ID]) + entity_ids = cv.ensure_list_csv(service_data[ATTR_ENTITY_ID]) if not any(eid in self.lights for eid in entity_ids): return From 008c5e444da8b27951d49e85d82b6401a4d9b449 Mon Sep 17 00:00:00 2001 From: Bas Nijholt Date: Sat, 19 Dec 2020 19:11:11 +0100 Subject: [PATCH 08/23] add separate_turn_on_commands to README --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 46d45d02..6d4aa685 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,8 @@ adaptive_lighting: | sunset_offset | Change the sunset time with a positive or negative offset. | False | 0 | time | | only_once | Whether to keep adapting the lights (false) or to only adapt the lights as soon as they are turned on (true). | False | False | boolean | | take_over_control | If another source calls `light.turn_on` while the lights are on and being adapted, disable Adaptive Lighting. | False | True | boolean | -| detect_non_ha_changes | Whether to detect state changes and stop adapting lights, even not from `light.turn_on`. Needs `take_over_control` to be enabled. Note that by enabling this option, it calls 'homeassistant.update_entity' every 'interval'! | inclusive | False | boolean | +| detect_non_ha_changes | Whether to detect state changes and stop adapting lights, even not from `light.turn_on`. Needs `take_over_control` to be enabled. Note that by enabling this option, it calls 'homeassistant.update_entity' every 'interval'! | False | False | boolean | +| separate_turn_on_commands | Whether to use separate `light.turn_on` calls for color and brightness, needed for some types of lights | False | False | boolean | Full example: From 1ec6866189f80ac17715527799341ade7b9e08f1 Mon Sep 17 00:00:00 2001 From: Bas Nijholt Date: Sun, 27 Dec 2020 13:05:05 +0100 Subject: [PATCH 09/23] fix bug when resetting switch and it's off --- custom_components/adaptive_lighting/switch.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/custom_components/adaptive_lighting/switch.py b/custom_components/adaptive_lighting/switch.py index 597928f3..0869accf 100755 --- a/custom_components/adaptive_lighting/switch.py +++ b/custom_components/adaptive_lighting/switch.py @@ -241,12 +241,13 @@ async def handle_set_manual_control(switch: AdaptiveSwitch, service_call: Servic else: switch.turn_on_off_listener.reset(*all_lights) # pylint: disable=protected-access - await switch._adapt_lights( - all_lights, - transition=switch._initial_transition, - force=True, - context=switch.create_context("service"), - ) + if switch.is_on: + await switch._update_attrs_and_maybe_adapt_lights( + all_lights, + transition=switch._initial_transition, + force=True, + context=switch.create_context("service"), + ) @callback From 73ce5f15431a21b9a8fc0e7b5b616c8a40f0a674 Mon Sep 17 00:00:00 2001 From: Bas Nijholt Date: Sun, 27 Dec 2020 13:35:43 +0100 Subject: [PATCH 10/23] separate_turn_on_commands fix when _split_service_data returns 1 item --- custom_components/adaptive_lighting/switch.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/custom_components/adaptive_lighting/switch.py b/custom_components/adaptive_lighting/switch.py index 0869accf..03ad8d93 100755 --- a/custom_components/adaptive_lighting/switch.py +++ b/custom_components/adaptive_lighting/switch.py @@ -793,14 +793,16 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): if not self._separate_turn_on_commands: await turn_on(service_data) else: - service_data_color, service_data_brightness = _split_service_data( + # Could be a list of length 1 or 2 + service_datas = _split_service_data( service_data, adapt_brightness, adapt_color ) - await turn_on(service_data_color) - transition = service_data_color.get(ATTR_TRANSITION) - if transition is not None: - await asyncio.sleep(transition) - await turn_on(service_data_brightness) + await turn_on(service_datas[0]) + if len(service_datas) == 2: + transition = service_datas[0].get(ATTR_TRANSITION) + if transition is not None: + await asyncio.sleep(transition) + await turn_on(service_datas[1]) async def _update_attrs_and_maybe_adapt_lights( self, From 36c10075224699d9e9e8b84acd50b541fccd5c31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCri=20Rebane?= <46962963+Repsionu@users.noreply.github.com> Date: Thu, 3 Dec 2020 13:12:49 +0200 Subject: [PATCH 11/23] Create et.json Made Estonian (et-EE) translation. Best, JR --- .../adaptive_lighting/translations/et.json | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 custom_components/adaptive_lighting/translations/et.json diff --git a/custom_components/adaptive_lighting/translations/et.json b/custom_components/adaptive_lighting/translations/et.json new file mode 100644 index 00000000..7c9af5d2 --- /dev/null +++ b/custom_components/adaptive_lighting/translations/et.json @@ -0,0 +1,49 @@ +{ + "title": "Kohanduv valgus", + "config": { + "step": { + "user": { + "title": "Vali kohanduva valguse üksuse nimi", + "description": "Igas üksuses võib olla mitu valgustit!", + "data": { + "name": "Nimi" + } + } + }, + "abort": { + "already_configured": "Üksus on juba seadistatud" + } + }, + "options": { + "step": { + "init": { + "title": "Kohanduva valguse suvandid", + "description": "Kohanduva valguse suvandid. Valikute nimetused ühtuvad YAML kirjes olevatega. Valikuid ei kuvata kui seadistus on tehtud YAML kirjes.", + "data": { + "lights": "valgustid", + "initial_transition": "Algne üleminek kui valgustid lülituvad sisse/välja või unerežiim muutub", + "interval": "Intervall, aeg muutuste vahel sekundites", + "max_brightness": "Suurim heledus %", + "max_color_temp": "Suurim värvustemperatuur Kelvinites", + "min_brightness": "Vähim heledus %", + "min_color_temp": "Vähim värvustemperatuur Kelvinites", + "only_once": "Ainult üks kord, rakendub ainult valgusti sisselülitamisel", + "prefer_rgb_color": "Eelista RGB värve, võimalusel kasuta RGB sätteid värvustemperatuuri asemel", + "separate_turn_on_commands": "Eraldi lülitused iga valiku (värvus, heledus jne.) sisselülitamiseks, mõned valgustid vajavad seda.", + "sleep_brightness": "Unerežiimi heledus %", + "sleep_color_temp": "Uneržiimi värvus Kelvinites", + "sunrise_offset": "Nihe päikesetõusust, +/- sekundit", + "sunrise_time": "Päikesetõusu aeg 'HH:MM:SS' vormingus. (Kui jätta tühjaks kasutatakse asukohajärgset)", + "sunset_offset": "Nihe päikeseloojangust, +/- sekundit", + "sunset_time": "Päikeseloojangu aeg 'HH:MM:SS' vormingus. (Kui jätta tühjaks kasutatakse asukohajärgset)", + "take_over_control": "Käsitsi juhtimine: kui miski peale kohanduva valguse enda lültiab valgusti sisse ja see juba põleb, katkesta kohandamine kuni järgmise välise lülitamiseni.", + "detect_non_ha_changes": "Märka väliseid lülitusi: kui mõni säte muutub üle 10% (isegi väljaspoolt HA juhituna) siis peab käsitsi juhtimine olema lubatud (kutsutakse 'homeassistant.update_entity')'interval'!)", + "transition": "Üleminekud, sekundites" + } + } + }, + "error": { + "option_error": "Vigane suvand" + } + } +} From 1eaca9fc36f82067a41de506439acba01d4466b2 Mon Sep 17 00:00:00 2001 From: Travis Pew Date: Fri, 1 Jan 2021 14:44:11 -0500 Subject: [PATCH 12/23] Update README.md set_manual_control I'd been scratching my head over this for a little bit when I realized that the optional value column had not been updated to reflect the description which clearly states it is optional. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6d4aa685..f477ffd5 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ adaptive_lighting: |------------------------|----------|--------------------------------------------------------------------------------------------------------------------------------------| | `entity_id` | no | The `entity_id` of the switch in which to (un)mark the light as being "manually controlled". | | `lights` | no | A light (or list of lights) to apply the settings to. | -| `manual_control` | no | Whether to mark (true) or unmark (false) the light as "manually controlled", when not specified it selects all lights in the switch. | +| `manual_control` | yes | Whether to mark (true) or unmark (false) the light as "manually controlled", when not specified it selects all lights in the switch. | ## Automation examples From 90b1837c7f7e03b43061be5fb255329a18b86591 Mon Sep 17 00:00:00 2001 From: Will Puckett Date: Mon, 4 Jan 2021 10:16:42 -0800 Subject: [PATCH 13/23] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6d4aa685..0835b5a4 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ![](https://github.com/home-assistant/brands/raw/b4a168b9af282ef916e120d31091ecd5e3c35e66/core_integrations/adaptive_lighting/icon.png) -_Try out this code by adding https://github.com/basnijholt/adaptive-lighting to your custom repos in HACS and install it!_ +_Try out this code by adding https://github.com/basnijholt/adaptive-lighting to your custom repos in [HACS (Home Assistant Community Store)](https://hacs.xyz/) and install it!_ *This `custom_component` is also being added to `core`, see [this PR](https://github.com/home-assistant/core/pull/40626), although it might take months before it makes it in.* The `adaptive_lighting` platform changes the settings of your lights throughout the day. From 30d85e3ae7f69d1dbe98eceabdaaf724dcf060b4 Mon Sep 17 00:00:00 2001 From: Bas Nijholt Date: Mon, 1 Mar 2021 19:20:18 +0100 Subject: [PATCH 14/23] add version string in manifest.json --- custom_components/adaptive_lighting/manifest.json | 1 + 1 file changed, 1 insertion(+) diff --git a/custom_components/adaptive_lighting/manifest.json b/custom_components/adaptive_lighting/manifest.json index 13461584..ee4c828b 100644 --- a/custom_components/adaptive_lighting/manifest.json +++ b/custom_components/adaptive_lighting/manifest.json @@ -5,5 +5,6 @@ "config_flow": true, "dependencies": [], "codeowners": ["@basnijholt"], + "version": "1.0.0", "requirements": [] } From b5eed585caf1264d47bea2af574803b7935b811e Mon Sep 17 00:00:00 2001 From: Bas Nijholt Date: Fri, 30 Apr 2021 10:46:14 +0200 Subject: [PATCH 15/23] support Astral v2 --- custom_components/adaptive_lighting/switch.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/custom_components/adaptive_lighting/switch.py b/custom_components/adaptive_lighting/switch.py index 03ad8d93..6fa23bf2 100755 --- a/custom_components/adaptive_lighting/switch.py +++ b/custom_components/adaptive_lighting/switch.py @@ -529,10 +529,17 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): self._transition = min( data[CONF_TRANSITION], self._interval.total_seconds() // 2 ) + _loc = get_astral_location(self.hass) + if isinstance(_loc, tuple): + # Astral v2.2 + location, _ = _loc + else: + # Astral v1 + location = _loc self._sun_light_settings = SunLightSettings( name=self._name, - astral_location=get_astral_location(self.hass), + astral_location=location, max_brightness=data[CONF_MAX_BRIGHTNESS], max_color_temp=data[CONF_MAX_COLOR_TEMP], min_brightness=data[CONF_MIN_BRIGHTNESS], From 20a37b41035fc38c470ea611777fe7d962a05512 Mon Sep 17 00:00:00 2001 From: Bas Nijholt Date: Fri, 30 Apr 2021 11:00:06 +0200 Subject: [PATCH 16/23] fix 'AttributeError: 'Location' object has no attribute 'solar_noon'' --- custom_components/adaptive_lighting/switch.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/custom_components/adaptive_lighting/switch.py b/custom_components/adaptive_lighting/switch.py index 6fa23bf2..45783ee8 100755 --- a/custom_components/adaptive_lighting/switch.py +++ b/custom_components/adaptive_lighting/switch.py @@ -1036,8 +1036,14 @@ class SunLightSettings: ) + self.sunset_offset if self.sunrise_time is None and self.sunset_time is None: - solar_noon = location.solar_noon(date, local=False) - solar_midnight = location.solar_midnight(date, local=False) + try: + # Astral v1 + solar_noon = location.solar_noon(date, local=False) + solar_midnight = location.solar_midnight(date, local=False) + except AttributeError: + # Astral v2 + solar_noon = location.noon(date, local=False) + solar_midnight = location.midnight(date, local=False) else: solar_noon = sunrise + (sunset - sunrise) / 2 solar_midnight = sunset + ((sunrise + timedelta(days=1)) - sunset) / 2 From 99049415dcbe1a427890871ed715d1eb25e6fd51 Mon Sep 17 00:00:00 2001 From: Bas Nijholt Date: Mon, 10 May 2021 18:26:26 +0200 Subject: [PATCH 17/23] support ATTR_SUPPORTED_COLOR_MODES --- custom_components/adaptive_lighting/switch.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/custom_components/adaptive_lighting/switch.py b/custom_components/adaptive_lighting/switch.py index 45783ee8..841e9d3f 100755 --- a/custom_components/adaptive_lighting/switch.py +++ b/custom_components/adaptive_lighting/switch.py @@ -38,7 +38,13 @@ from homeassistant.components.light import ( SUPPORT_WHITE_VALUE, VALID_TRANSITION, is_on, + COLOR_MODE_RGB, + COLOR_MODE_RGBW, + COLOR_MODE_COLOR_TEMP, + COLOR_MODE_BRIGHTNESS, + ATTR_SUPPORTED_COLOR_MODES, ) + from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN, SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( @@ -377,7 +383,17 @@ def _expand_light_groups(hass: HomeAssistant, lights: List[str]) -> List[str]: def _supported_features(hass: HomeAssistant, light: str): state = hass.states.get(light) supported_features = state.attributes[ATTR_SUPPORTED_FEATURES] - return {key for key, value in _SUPPORT_OPTS.items() if supported_features & value} + supported = {key for key, value in _SUPPORT_OPTS.items() if supported_features & value} + supported_color_modes = state.attributes.get(ATTR_SUPPORTED_COLOR_MODES, set()) + if COLOR_MODE_RGB in supported_color_modes: + supported.add("color") + if COLOR_MODE_RGBW in supported_color_modes: + supported.add("color") + if COLOR_MODE_COLOR_TEMP in supported_color_modes: + supported.add("color_temp") + if COLOR_MODE_BRIGHTNESS in supported_color_modes: + supported.add("brightness") + return supported def color_difference_redmean( From 41d149d9bb34cd785caa26129fefdc62071a1d17 Mon Sep 17 00:00:00 2001 From: Bas Nijholt Date: Mon, 10 May 2021 20:19:47 +0200 Subject: [PATCH 18/23] always add brightness when color is supported, see comment by @DigitalFeonix https://github.com/basnijholt/adaptive-lighting/issues/112#issuecomment-836944011 --- custom_components/adaptive_lighting/switch.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/custom_components/adaptive_lighting/switch.py b/custom_components/adaptive_lighting/switch.py index 841e9d3f..8eb86f8c 100755 --- a/custom_components/adaptive_lighting/switch.py +++ b/custom_components/adaptive_lighting/switch.py @@ -383,14 +383,21 @@ def _expand_light_groups(hass: HomeAssistant, lights: List[str]) -> List[str]: def _supported_features(hass: HomeAssistant, light: str): state = hass.states.get(light) supported_features = state.attributes[ATTR_SUPPORTED_FEATURES] - supported = {key for key, value in _SUPPORT_OPTS.items() if supported_features & value} + supported = { + key for key, value in _SUPPORT_OPTS.items() if supported_features & value + } supported_color_modes = state.attributes.get(ATTR_SUPPORTED_COLOR_MODES, set()) if COLOR_MODE_RGB in supported_color_modes: supported.add("color") + # Adding brightness here, see + # comment https://github.com/basnijholt/adaptive-lighting/issues/112#issuecomment-836944011 + supported.add("brightness") if COLOR_MODE_RGBW in supported_color_modes: supported.add("color") + supported.add("brightness") # see above url if COLOR_MODE_COLOR_TEMP in supported_color_modes: supported.add("color_temp") + supported.add("brightness") # see above url if COLOR_MODE_BRIGHTNESS in supported_color_modes: supported.add("brightness") return supported From deb348a535425ed3f6b8a06ec163b7bf19b42810 Mon Sep 17 00:00:00 2001 From: David Stenbeck Date: Thu, 27 May 2021 15:30:11 +0200 Subject: [PATCH 19/23] Improvements to setting descriptions. --- .../adaptive_lighting/translations/en.json | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/custom_components/adaptive_lighting/translations/en.json b/custom_components/adaptive_lighting/translations/en.json index ed1d205b..2689d56d 100644 --- a/custom_components/adaptive_lighting/translations/en.json +++ b/custom_components/adaptive_lighting/translations/en.json @@ -3,42 +3,42 @@ "config": { "step": { "user": { - "title": "Choose a name for the Adaptive Lighting", - "description": "Every instance can contain multiple lights!", + "title": "Choose a name for the Adaptive Lighting instance", + "description": "Pick a name this instance. You can run several instances of Adaptive lighting, each of these can contain multiple lights!", "data": { "name": "Name" } } }, "abort": { - "already_configured": "Device is already configured" + "already_configured": "This device is already configured" } }, "options": { "step": { "init": { "title": "Adaptive Lighting options", - "description": "All settings for a Adaptive Lighting component. The option names correspond with the YAML settings. No options are shown if you have this entry defined in YAML.", + "description": "All settings for a Adaptive Lighting component. The option names correspond with the YAML settings. No options are shown if you have the adaptive_lighting entry defined in your YAML configuration.", "data": { "lights": "lights", - "initial_transition": "initial_transition, when lights go 'off' to 'on' or when 'sleep_state' changes", - "interval": "interval, time between switch updates in seconds", - "max_brightness": "max_brightness, in %", - "max_color_temp": "max_color_temp, in Kelvin", - "min_brightness": "min_brightness, in %", - "min_color_temp": "min_color_temp, in Kelvin", - "only_once": "only_once, only adapt the lights when turning them on", - "prefer_rgb_color": "prefer_rgb_color, use 'rgb_color' over 'color_temp' when possible", - "separate_turn_on_commands": "separate_turn_on_commands, for each attribute (color, brightness, etc.) in 'light.turn_on', required for some lights.", - "sleep_brightness": "sleep_brightness, in %", - "sleep_color_temp": "sleep_color_temp, in Kelvin", - "sunrise_offset": "sunrise_offset, in +/- seconds", - "sunrise_time": "sunrise_time, in 'HH:MM:SS' format (if 'None', it uses the actual sunrise time at your location)", - "sunset_offset": "sunset_offset, in +/- seconds", - "sunset_time": "sunset_time, in 'HH:MM:SS' format (if 'None', it uses the actual sunset time at your location)", - "take_over_control": "take_over_control, if anything but Adaptive Lighting calls 'light.turn_on' when a light is already on, stop adapting that light until it (or the switch) toggles off -> on.", - "detect_non_ha_changes": "detect_non_ha_changes, detects all >10% changes made to the lights (also outside of HA), requires 'take_over_control' to be enabled (calls 'homeassistant.update_entity' every 'interval'!)", - "transition": "transition, in seconds" + "initial_transition": "initial_transition: When lights turn 'off' to 'on' or when 'sleep_state' changes. (seconds)", + "interval": "interval: Time between switch updates. (seconds)", + "max_brightness": "max_brightness: Highest brightness of lights during a cycle. (%)", + "max_color_temp": "max_color_temp: Coldest hue of the color temperature cycle. (Kelvin)", + "min_brightness": "min_brightness: Lowest brightness of lights during a cycle. (%)", + "min_color_temp": "min_color_temp, Warmest hue of the color temperature cycle. (%)", + "only_once": "only_once: Only adapt the lights when turning them on.", + "prefer_rgb_color": "prefer_rgb_color: Use 'rgb_color' rather than 'color_temp' when possible.", + "separate_turn_on_commands": "separate_turn_on_commands: Separate the commands for each attribute (color, brightness, etc.) in 'light.turn_on' (required for some lights).", + "sleep_brightness": "sleep_brightness, Brightness setting for Sleep Mode. (%)", + "sleep_color_temp": "sleep_color_temp: Color temperature setting for Sleep Mode. (Kelvin)", + "sunrise_offset": "sunrise_offset: How long before(-) or after(+) to define the sunrise point of the cycle (+/- seconds)", + "sunrise_time": "sunrise_time: Manual override of the sunrise time, if 'None', it uses the actual sunrise time at your location (HH:MM:SS)", + "sunset_offset": "sunset_offset: How long before(-) or after(+) to define the sunset point of the cycle (+/- seconds)", + "sunset_time": "sunset_time: Manual override of the sunset time, if 'None', it uses the actual sunrise time at your location (HH:MM:SS)", + "take_over_control": "take_over_control: If anything but Adaptive Lighting calls 'light.turn_on' when a light is already on, stop adapting that light until it (or the switch) toggles off -> on.", + "detect_non_ha_changes": "detect_non_ha_changes: detects all >10% changes made to the lights (also outside of HA), requires 'take_over_control' to be enabled (calls 'homeassistant.update_entity' every 'interval'!)", + "transition": "Transition time when applying a change to the lights (seconds)" } } }, From b45f8d7f32cbe438f8ec39919cfc96c08b31b5bf Mon Sep 17 00:00:00 2001 From: David Stenbeck Date: Thu, 27 May 2021 15:33:46 +0200 Subject: [PATCH 20/23] Spelling error --- custom_components/adaptive_lighting/translations/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/adaptive_lighting/translations/en.json b/custom_components/adaptive_lighting/translations/en.json index 2689d56d..e66b6769 100644 --- a/custom_components/adaptive_lighting/translations/en.json +++ b/custom_components/adaptive_lighting/translations/en.json @@ -4,7 +4,7 @@ "step": { "user": { "title": "Choose a name for the Adaptive Lighting instance", - "description": "Pick a name this instance. You can run several instances of Adaptive lighting, each of these can contain multiple lights!", + "description": "Pick a name for this instance. You can run several instances of Adaptive lighting, each of these can contain multiple lights!", "data": { "name": "Name" } From 40bc5dad17045facfa2bb5f384591aeea0256e9e Mon Sep 17 00:00:00 2001 From: Bas Nijholt Date: Thu, 3 Jun 2021 09:56:38 +0200 Subject: [PATCH 21/23] fix time_zone AttributeError, fixes #128 Thanks @yurnih! --- custom_components/adaptive_lighting/switch.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/custom_components/adaptive_lighting/switch.py b/custom_components/adaptive_lighting/switch.py index 8eb86f8c..cfe073c1 100755 --- a/custom_components/adaptive_lighting/switch.py +++ b/custom_components/adaptive_lighting/switch.py @@ -1042,7 +1042,10 @@ class SunLightSettings: def _replace_time(date: datetime.datetime, key: str) -> datetime.datetime: time = getattr(self, f"{key}_time") date_time = datetime.datetime.combine(date, time) - utc_time = self.time_zone.localize(date_time).astimezone(dt_util.UTC) + try: # HA ≤2021.05, https://github.com/basnijholt/adaptive-lighting/issues/128 + utc_time = self.time_zone.localize(date_time).astimezone(dt_util.UTC) + except AttributeError: # HA ≥2021.06 + utc_time = date_time.replace(tzinfo=dt_util.DEFAULT_TIME_ZONE).astimezone(dt_util.UTC) return utc_time location = self.astral_location From 18e057fd423d25fc54212324887abc046dd1bae7 Mon Sep 17 00:00:00 2001 From: Nicholai Nissen Date: Sun, 20 Jun 2021 13:06:42 +0200 Subject: [PATCH 22/23] i18n: Add Danish translation --- .../adaptive_lighting/translations/da.json | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 custom_components/adaptive_lighting/translations/da.json diff --git a/custom_components/adaptive_lighting/translations/da.json b/custom_components/adaptive_lighting/translations/da.json new file mode 100644 index 00000000..2a881e5d --- /dev/null +++ b/custom_components/adaptive_lighting/translations/da.json @@ -0,0 +1,49 @@ +{ + "title": "Adaptiv Belysning", + "config": { + "step": { + "user": { + "title": "Vælg et navn for denne Adaptive Belysning", + "description": "Vælg et navn til denne konfiguration. Du kan køre flere konfigurationer af Adaptiv Belysning, og hver af dem kan indeholde flere lys!", + "data": { + "name": "Navn" + } + } + }, + "abort": { + "already_configured": "Denne enhed er allerede konfigureret" + } + }, + "options": { + "step": { + "init": { + "title": "Adaptiv Belysnings indstillinger", + "description": "Alle indstillinger tilhørende en Adaptiv Belysnings komponent. Indstillingernes navne svarer til YAML indstillingernes. Ingen indstillinger vises hvis du allerede har konfigureret den i YAML.", + "data": { + "lights": "lights: lyskilder", + "initial_transition": "initial_transition: Hvor lang overgang når lyset går fra 'off' til 'on' eller når 'sleep_state' skiftes. (i sekunder)", + "interval": "interval: Tid imellem opdateringer (i sekunder)", + "max_brightness": "max_brightness: Højeste lysstyrke i cyklussen. (%)", + "max_color_temp": "max_color_temp: Koldeste lystemperatur i cyklussen. (Kelvin)", + "min_brightness": "min_brightness: Laveste lysstyrke i cyklussen. (%)", + "min_color_temp": "min_color_temp: Varmeste lystemperatur i cyklussen. (Kelvin)", + "only_once": "only_once: Juster udelukkende lysene adaptivt i øjeblikket de tændes.", + "prefer_rgb_color": "prefer_rgb_color: Brug 'rgb_color' istedet for 'color_temp' når muligt.", + "separate_turn_on_commands": "separate_turn_on_commands: Adskil kommandoerne for hver attribut (color, brightness, etc.) ved 'light.turn_on' (nødvendigt for bestemte lys).", + "sleep_brightness": "sleep_brightness, Lysstyrke for Sleep Mode. (%)", + "sleep_color_temp": "sleep_color_temp: Farvetemperatur under Sleep Mode. (Kelvin)", + "sunrise_offset": "sunrise_offset: Hvor længe før (-) eller efter (+) at definere solopgangen i cyklussen (+/- sekunder)", + "sunrise_time": "sunrise_time: Manuel overstyring af solopgangstidspunktet, hvis 'None', bruges det egentlige tidspunkt din lokation. (HH:MM:SS)", + "sunset_offset": "sunset_offset: Hvor længe før (-) eller efter (+) at definere solnedgangen i cyklussen (+/- sekunder)", + "sunset_time": "sunset_time: Manuel overstyring af solnedgangstidspunktet, hvis 'None', bruges det egentlige tidspunkt for din lokation. (HH:MM:SS)", + "take_over_control": "take_over_control: Hvis andet end Adaptiv Belysning kalder 'light.turn_on' på et lys der allerede er tændt, afbryd adaptering af lyset indtil at det tændes igen.", + "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)" + } + } + }, + "error": { + "option_error": "Ugyldig indstilling" + } + } +} From cd439ea58fe158b56317e76df760a5640a2e7356 Mon Sep 17 00:00:00 2001 From: Denys Dovhan Date: Sun, 20 Jun 2021 16:51:33 +0300 Subject: [PATCH 23/23] Add Ukrainian --- .../adaptive_lighting/translations/uk.json | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 custom_components/adaptive_lighting/translations/uk.json diff --git a/custom_components/adaptive_lighting/translations/uk.json b/custom_components/adaptive_lighting/translations/uk.json new file mode 100644 index 00000000..c71d5e63 --- /dev/null +++ b/custom_components/adaptive_lighting/translations/uk.json @@ -0,0 +1,49 @@ +{ + "title": "Адаптивне освітлення", + "config": { + "step": { + "user": { + "title": "Оберіть ім’я для екземпляра адаптивного освітлення", + "description": "Оберіть ім’я для цього екземпляра. Ви можете мати декілька екземплярів адаптивного освітлення, кожен може містити декілька приладів!", + "data": { + "name": "Ім’я" + } + } + }, + "abort": { + "already_configured": "Цей пристрій вже налаштовано" + } + }, + "options": { + "step": { + "init": { + "title": "Опції адаптивного освітлення", + "description": "Всі налаштування компонента адаптивного освітлення. Назви опцій відповідають налаштуванням у YAML. Опції не відображаються, якщо ви вже визначили їх у компоненті adaptive_lighting вашої YAML-конфігурації.", + "data": { + "lights": "прилади", + "initial_transition": "initial_transition: Коли прилад вимикається (off), вмикається (on), або змінює 'sleep_state'. (секунди)", + "interval": "interval: Час між оновленнями перемикача. (секунди)", + "max_brightness": "max_brightness: Найвища яскравість світла під час циклу. (%)", + "max_color_temp": "max_color_temp: Найхолодніший відтінок циклу кольорової температури. (Кельвін)", + "min_brightness": "min_brightness: Найнижча яскравість світла під час циклу. (%)", + "min_color_temp": "min_color_temp: Найтепліший відтінок циклу кольорової температури. (%)", + "only_once": "only_once: Адаптувати світло лише після початкового увімкнення.", + "prefer_rgb_color": "prefer_rgb_color: Використовувати 'rgb_color' замість 'color_temp', коли можливо.", + "separate_turn_on_commands": "separate_turn_on_commands: Окремі команди для кожного атрибута (колір, яскравість, тощо.) в 'light.turn_on' (необхідні для деяких приладів).", + "sleep_brightness": "sleep_brightness: Налаштування яскравості для Режиму сну. (%)", + "sleep_color_temp": "sleep_color_temp: Температура кольору для Режиму сну. (Кельвін)", + "sunrise_offset": "sunrise_offset: Як за довго до(-) або після(+) визначати точку сходу сонця для циклу (+/- секунд)", + "sunrise_time": "sunrise_time: Ручний перезапис часу сходу сонця, якщо 'None', тоді використовується час сходу сонця у вашій локації (HH:MM:SS)", + "sunset_offset": "sunset_offset: Як за довго до(-) або після(+) визначати точку заходу сонця для циклу (+/- секунд)", + "sunset_time": "sunset_time: Ручний перезапис часу заходу сонця, якщо 'None', тоді використовується час заходу сонця у вашій локації (HH:MM:SS)", + "take_over_control": "take_over_control: Якщо що-небудь, окрім Адаптивного освітлення, викликає 'light.turn_on', коли світло вже увімкнено, чи адаптувати освітлення допоки світло (або перемикач) перемкнеться (off -> on).", + "detect_non_ha_changes": "detect_non_ha_changes: виявляти всі зміни >10% до освітлення (включаючи ті, що зроблені поза HA), вимагає, щоб 'take_over_control' був включений (виклик 'homeassistant.update_entity' кожного оновлення 'interval'!)", + "transition": "Час переходу, який застосовується до освітлення (секунди)" + } + } + }, + "error": { + "option_error": "Хибна опція" + } + } +}