chore(release): beta-1.03
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
86
src/util/brightness_combine.py
Normal file
86
src/util/brightness_combine.py
Normal file
@@ -0,0 +1,86 @@
|
||||
"""
|
||||
Combine global, group, device (and optional zone) brightness into one 0–255 wire value.
|
||||
|
||||
Formula: ``(f1/255) * (f2/255) * ... * (fn/255) * 255`` with integer rounding — one ``b`` sent to the driver.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from models.device import normalize_mac
|
||||
|
||||
|
||||
def clamp255(value) -> int:
|
||||
try:
|
||||
v = int(value)
|
||||
except (TypeError, ValueError):
|
||||
return 255
|
||||
return max(0, min(255, v))
|
||||
|
||||
|
||||
def multiply_brightness_factors(factors: list) -> int:
|
||||
"""Product ``(f1/255)*(f2/255)*...*255``; each factor clamped to 0..255."""
|
||||
if not factors:
|
||||
return 255
|
||||
fs = [clamp255(f) for f in factors]
|
||||
if len(fs) == 1:
|
||||
return fs[0]
|
||||
num = 1
|
||||
for f in fs:
|
||||
num *= f
|
||||
den = 255 ** (len(fs) - 1)
|
||||
return max(0, min(255, (num + den // 2) // den))
|
||||
|
||||
|
||||
def _mac_in_device_list(raw_list, target_mac: str) -> bool:
|
||||
tm = normalize_mac(target_mac)
|
||||
if not tm:
|
||||
return False
|
||||
if not isinstance(raw_list, list):
|
||||
return False
|
||||
for raw in raw_list:
|
||||
if normalize_mac(str(raw)) == tm:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def effective_brightness_for_mac(
|
||||
settings_obj,
|
||||
groups_model,
|
||||
devices_model,
|
||||
mac: str,
|
||||
*,
|
||||
zone_brightness=None,
|
||||
) -> int:
|
||||
"""
|
||||
Factors (each 0..255): Pi **global_brightness**, each group's **output_brightness**
|
||||
(neutral 255 if the device is in no group), device **output_brightness** (default 255),
|
||||
optional **zone_brightness** from the zone slider when applying live.
|
||||
"""
|
||||
m = normalize_mac(mac)
|
||||
if not m:
|
||||
return 255
|
||||
|
||||
g_global = clamp255(settings_obj.get("global_brightness", 255))
|
||||
|
||||
dev_doc = devices_model.read(m)
|
||||
if dev_doc is not None and dev_doc.get("output_brightness") is not None:
|
||||
d_b = clamp255(dev_doc.get("output_brightness"))
|
||||
else:
|
||||
d_b = 255
|
||||
|
||||
group_factors = []
|
||||
for _gid, gdoc in groups_model.items():
|
||||
if not isinstance(gdoc, dict):
|
||||
continue
|
||||
if not _mac_in_device_list(gdoc.get("devices"), m):
|
||||
continue
|
||||
group_factors.append(clamp255(gdoc.get("output_brightness", 255)))
|
||||
|
||||
if not group_factors:
|
||||
group_factors = [255]
|
||||
|
||||
factors = [g_global, *group_factors, d_b]
|
||||
if zone_brightness is not None:
|
||||
factors.append(clamp255(zone_brightness))
|
||||
|
||||
return multiply_brightness_factors(factors)
|
||||
Reference in New Issue
Block a user