mirror of
https://github.com/basnijholt/adaptive-lighting.git
synced 2026-09-11 22:34:04 +02:00
redmean
This commit is contained in:
parent
6a1bb180b5
commit
3c1312f0f8
1 changed files with 30 additions and 12 deletions
|
|
@ -10,6 +10,7 @@ from datetime import timedelta
|
|||
import functools
|
||||
import hashlib
|
||||
import logging
|
||||
import math
|
||||
from typing import Any, Dict, List, Optional, Tuple, Union
|
||||
|
||||
import astral
|
||||
|
|
@ -119,7 +120,7 @@ SCAN_INTERVAL = timedelta(seconds=10)
|
|||
# Consider it a significant change when attribute changes more than
|
||||
BRIGHTNESS_CHANGE = 25 # ≈10% of total range
|
||||
COLOR_TEMP_CHANGE = 20 # ≈5% of total range
|
||||
RGB_CHANGE = 30 # ≈12% of total range per component
|
||||
RGB_REDMEAN_CHANGE = 80 # ≈10% of total range
|
||||
|
||||
# Keep a short domain version for the context instances (which can only be 36 chars)
|
||||
_DOMAIN_SHORT = "adapt_lgt"
|
||||
|
|
@ -253,6 +254,23 @@ def _supported_features(hass: HomeAssistant, light: str):
|
|||
return {key for key, value in _SUPPORT_OPTS.items() if supported_features & value}
|
||||
|
||||
|
||||
def color_difference_redmean(rgb1, rgb2):
|
||||
"""The distance between colors in RGB space, known as redmean.
|
||||
|
||||
The maximal distance between (255, 255, 255) and (0, 0, 0) ≈ 765.
|
||||
|
||||
Sources:
|
||||
- https://en.wikipedia.org/wiki/Color_difference#Euclidean
|
||||
- https://www.compuphase.com/cmetric.htm
|
||||
"""
|
||||
r_hat = (rgb1[0] + rgb2[0]) / 2
|
||||
delta_r, delta_g, delta_b = [(col1 - col2) for col1, col2 in zip(rgb1, rgb2)]
|
||||
red_term = (2 + r_hat / 256) * delta_r ** 2
|
||||
green_term = 4 * delta_g ** 2
|
||||
blue_term = (2 + (255 - r_hat) / 256) * delta_b ** 2
|
||||
return math.sqrt(red_term + green_term + blue_term)
|
||||
|
||||
|
||||
def _attributes_have_changed(
|
||||
light: str,
|
||||
old_attributes: Dict[str, Any],
|
||||
|
|
@ -305,17 +323,17 @@ def _attributes_have_changed(
|
|||
):
|
||||
last_rgb_color = old_attributes[ATTR_RGB_COLOR]
|
||||
current_rgb_color = new_attributes[ATTR_RGB_COLOR]
|
||||
for last_col, current_col in zip(last_rgb_color, current_rgb_color):
|
||||
if abs(last_col - current_col) > RGB_CHANGE:
|
||||
_LOGGER.debug(
|
||||
"color RGB of '%s' significantly changed from %s to %s with"
|
||||
" context.id='%s'",
|
||||
light,
|
||||
last_rgb_color,
|
||||
current_rgb_color,
|
||||
context.id,
|
||||
)
|
||||
return True
|
||||
redmean_change = color_difference_redmean(last_rgb_color, current_rgb_color)
|
||||
if redmean_change > RGB_REDMEAN_CHANGE:
|
||||
_LOGGER.debug(
|
||||
"color RGB of '%s' significantly changed from %s to %s with"
|
||||
" context.id='%s'",
|
||||
light,
|
||||
last_rgb_color,
|
||||
current_rgb_color,
|
||||
context.id,
|
||||
)
|
||||
return True
|
||||
|
||||
switched_color_temp = (
|
||||
ATTR_RGB_COLOR in old_attributes and ATTR_RGB_COLOR not in new_attributes
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue