24
|
1 import colorsys
|
15
|
2 import logging
|
|
3 from dataclasses import dataclass
|
|
4
|
|
5 from color import Color
|
|
6
|
|
7 log = logging.getLogger('conv')
|
|
8
|
|
9
|
24
|
10 def inverseLerp(a, b, val) -> float:
|
|
11 return (val - a) / (b - a)
|
|
12
|
|
13
|
|
14 def clamped(x) -> float:
|
|
15 return min(1, max(0, x))
|
|
16
|
|
17
|
|
18 def simpleWhiteVal(r, g, b) -> float:
|
|
19 h, s, v = colorsys.rgb_to_hsv(r, g, b)
|
|
20 return (1 - s)**2 * clamped(inverseLerp(.5, 1, v))**2
|
|
21
|
|
22
|
15
|
23 @dataclass(frozen=True)
|
|
24 class DeviceColor:
|
|
25 """neutral representation of the adjusted color that we send to a device"""
|
|
26 r: float = 0
|
|
27 g: float = 0
|
|
28 b: float = 0
|
|
29 w: float = 0
|
|
30 x: float = 0
|
|
31 y: float = 0
|
20
|
32 cw: float = 0
|
|
33 ww: float = 0
|
15
|
34 brightness: float = 0
|
21
|
35 temp: float = 0
|
15
|
36
|
|
37 def summary(self) -> dict:
|
|
38 return dict([(k, round(v, 3)) for k, v in self.__dict__.items() if v > 0])
|
|
39
|
21
|
40
|
15
|
41 # fix this to send what z2m likes
|
|
42 def zbConv(c: Color) -> DeviceColor:
|
|
43 return DeviceColor(r=c.r, g=c.g, b=c.b, brightness=max(c.r, c.g, c.b))
|
20
|
44
|
21
|
45
|
|
46 def ikeaWhiteConv(c: Color) -> DeviceColor:
|
|
47 return DeviceColor(brightness=max(c.r, c.g, c.b), temp=454)
|
|
48
|
|
49
|
20
|
50 def oneWhiteConv(c: Color) -> DeviceColor:
|
24
|
51 return DeviceColor(r=c.r, g=c.g, b=c.b, w=simpleWhiteVal(c.r, c.g, c.b))
|
|
52
|
20
|
53
|
21
|
54 def brightnessConv(c: Color) -> DeviceColor:
|
|
55 return DeviceColor(brightness=max(c.r, c.g, c.b))
|
|
56
|
|
57
|
20
|
58 def twoWhitesConv(c: Color) -> DeviceColor:
|
24
|
59 return DeviceColor(r=c.r, g=c.g, b=c.b, cw=simpleWhiteVal(c.r, c.g, c.b), ww=simpleWhiteVal(c.r, c.g, c.b))
|
21
|
60
|
20
|
61
|
|
62 def relayConv(c: Color) -> DeviceColor:
|
21
|
63 return DeviceColor(brightness=1 if (max(c.r, c.g, c.b) > 0) else 0)
|