rework color system and make it work with drivers.
continuous-integration/drone/push Build is passing
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -40,7 +40,7 @@ func (s *hueLightState) Update(state models.DeviceState) {
|
||||
if state.Power {
|
||||
input.On = ptrBool(true)
|
||||
if state.Color.IsKelvin() {
|
||||
input.CT = ptrInt(1000000 / state.Color.Kelvin)
|
||||
input.CT = ptrInt(1000000 / *state.Color.K)
|
||||
if *input.CT < s.info.Capabilities.Control.CT.Min {
|
||||
*input.CT = s.info.Capabilities.Control.CT.Min
|
||||
}
|
||||
@@ -51,13 +51,13 @@ func (s *hueLightState) Update(state models.DeviceState) {
|
||||
if s.input.CT == nil || *s.input.CT != *input.CT {
|
||||
s.stale = true
|
||||
}
|
||||
} else {
|
||||
input.Hue = ptrInt(int(state.Color.Hue*(65536/360)) % 65536)
|
||||
} else if color, ok := state.Color.ToHS(); ok {
|
||||
input.Hue = ptrInt(int(color.HS.Hue*(65536/360)) % 65536)
|
||||
if s.input.Hue == nil || *s.input.Hue != *input.Hue {
|
||||
s.stale = true
|
||||
}
|
||||
|
||||
input.Sat = ptrInt(int(state.Color.Saturation * 255))
|
||||
input.Sat = ptrInt(int(color.HS.Sat * 255))
|
||||
if *input.Sat > 254 {
|
||||
*input.Sat = 254
|
||||
}
|
||||
|
||||
@@ -269,7 +269,7 @@ func (b *Bridge) MakeCongruent(ctx context.Context) (int, error) {
|
||||
lightsOut := light.Power != nil && !device.State.Power
|
||||
if !lightsOut {
|
||||
if light.ColorTemperature != nil && device.State.Color.IsKelvin() {
|
||||
mirek := 1000000 / device.State.Color.Kelvin
|
||||
mirek := 1000000 / *device.State.Color.K
|
||||
if mirek < light.ColorTemperature.MirekSchema.MirekMinimum {
|
||||
mirek = light.ColorTemperature.MirekSchema.MirekMinimum
|
||||
}
|
||||
@@ -280,9 +280,10 @@ func (b *Bridge) MakeCongruent(ctx context.Context) (int, error) {
|
||||
update.Mirek = &mirek
|
||||
changed = true
|
||||
}
|
||||
} else if xy, ok := device.State.Color.ToXY(); ok && light.Color != nil {
|
||||
xy = light.Color.Gamut.Conform(xy).Round()
|
||||
} else if xyColor, ok := device.State.Color.ToXY(); ok && light.Color != nil {
|
||||
xy := light.Color.Gamut.Conform(*xyColor.XY).Round()
|
||||
if xy.DistanceTo(light.Color.XY) > 0.0009 || (light.ColorTemperature != nil && light.ColorTemperature.Mirek != nil) {
|
||||
log.Println(xyColor.String(), device.State.Color.String())
|
||||
update.ColorXY = &xy
|
||||
changed = true
|
||||
}
|
||||
@@ -419,9 +420,7 @@ func (b *Bridge) GenerateDevices() []models.Device {
|
||||
}
|
||||
if light.ColorTemperature != nil {
|
||||
if light.ColorTemperature.Mirek != nil {
|
||||
device.State.Color = models.ColorValue{
|
||||
Kelvin: int(1000000 / *light.ColorTemperature.Mirek),
|
||||
}
|
||||
device.State.Color.SetK(1000000 / *light.ColorTemperature.Mirek)
|
||||
}
|
||||
device.Capabilities = append(device.Capabilities, models.DCColorKelvin)
|
||||
device.DriverProperties["maxTemperature"] = 1000000 / light.ColorTemperature.MirekSchema.MirekMinimum
|
||||
@@ -530,9 +529,11 @@ func (b *Bridge) applyPatches(patches []ResourceData) {
|
||||
resCopy.Color = &cp
|
||||
resCopy.Color.XY = patch.Color.XY
|
||||
|
||||
cp2 := *resCopy.ColorTemperature
|
||||
resCopy.ColorTemperature = &cp2
|
||||
resCopy.ColorTemperature.Mirek = nil
|
||||
if resCopy.ColorTemperature != nil {
|
||||
cp2 := *resCopy.ColorTemperature
|
||||
resCopy.ColorTemperature = &cp2
|
||||
resCopy.ColorTemperature.Mirek = nil
|
||||
}
|
||||
}
|
||||
if patch.ColorTemperature != nil && resCopy.ColorTemperature != nil {
|
||||
cp := *resCopy.ColorTemperature
|
||||
|
||||
@@ -169,9 +169,11 @@ func (b *Bridge) Run(ctx context.Context, debug bool) error {
|
||||
state.deviceState = &models.DeviceState{
|
||||
Power: p.On,
|
||||
Color: models.ColorValue{
|
||||
Hue: p.Hue,
|
||||
Saturation: p.Sat,
|
||||
Kelvin: p.Kelvin,
|
||||
HS: &models.ColorHS{
|
||||
Hue: p.Hue,
|
||||
Sat: p.Sat,
|
||||
},
|
||||
K: &p.Kelvin,
|
||||
},
|
||||
Intensity: p.Bri,
|
||||
}
|
||||
@@ -204,7 +206,7 @@ func (b *Bridge) Run(ctx context.Context, debug bool) error {
|
||||
b.checkAndUpdateState(state)
|
||||
}
|
||||
|
||||
if time.Since(state.discoveredTime) > time.Second*10 && time.Since(state.fwSpamTime) > time.Second * 30 {
|
||||
if time.Since(state.discoveredTime) > time.Second*10 && time.Since(state.fwSpamTime) > time.Second*30 {
|
||||
state.fwSpamTime = time.Now()
|
||||
|
||||
if state.firmware == nil {
|
||||
|
||||
@@ -36,17 +36,21 @@ func (s *State) generateUpdate() []Payload {
|
||||
return results
|
||||
}
|
||||
|
||||
c := s.deviceState.Color
|
||||
c, ok := s.deviceState.Color.ToHSK()
|
||||
if !ok {
|
||||
c, _ = models.ParseColorValue("hsk:0,0,4000")
|
||||
}
|
||||
|
||||
l := s.lightState
|
||||
di := s.deviceState.Intensity
|
||||
k := c.Kelvin
|
||||
k := *c.K
|
||||
if k == 0 {
|
||||
k = 4000
|
||||
}
|
||||
if !equalish(c.Hue, l.Hue) || !equalish(c.Saturation, l.Sat) || !equalish(di, l.Bri) || k != l.Kelvin {
|
||||
if !equalish(c.HS.Hue, l.Hue) || !equalish(c.HS.Sat, l.Sat) || !equalish(di, l.Bri) || k != l.Kelvin {
|
||||
results = append(results, &SetColor{
|
||||
Hue: c.Hue,
|
||||
Sat: c.Saturation,
|
||||
Hue: c.HS.Hue,
|
||||
Sat: c.HS.Sat,
|
||||
Bri: di,
|
||||
Kelvin: k,
|
||||
TransitionTime: time.Millisecond * 150,
|
||||
@@ -72,11 +76,16 @@ func (s *State) handleAck(seq uint8) {
|
||||
prevLabel = s.lightState.Label
|
||||
}
|
||||
|
||||
color, ok := s.deviceState.Color.ToHSK()
|
||||
if !ok {
|
||||
color, _ = models.ParseColorValue("hsk:0,0,4000")
|
||||
}
|
||||
|
||||
s.lightState = &LightState{
|
||||
Hue: s.deviceState.Color.Hue,
|
||||
Sat: s.deviceState.Color.Saturation,
|
||||
Hue: color.HS.Hue,
|
||||
Sat: color.HS.Sat,
|
||||
Bri: s.deviceState.Intensity,
|
||||
Kelvin: s.deviceState.Color.Kelvin,
|
||||
Kelvin: *color.K,
|
||||
On: s.deviceState.Power,
|
||||
Label: prevLabel,
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math"
|
||||
"net"
|
||||
"net/http"
|
||||
"strconv"
|
||||
@@ -31,11 +30,12 @@ type bridge struct {
|
||||
func (b *bridge) Devices() []models.Device {
|
||||
results := make([]models.Device, 0, len(b.panels))
|
||||
for i, panel := range b.panels {
|
||||
// Find normalized RGB and intensity
|
||||
red := float64(panel.ColorRGBA[0]) / 255.0
|
||||
green := float64(panel.ColorRGBA[1]) / 255.0
|
||||
blue := float64(panel.ColorRGBA[2]) / 255.0
|
||||
|
||||
hue, sat, value := colorful.LinearRgb(red, green, blue).Hsv()
|
||||
hue, sat, value := colorful.Color{R: red, G: green, B: blue}.Hsv()
|
||||
rgb := colorful.Hsv(hue, sat, 1)
|
||||
|
||||
shapeType, shapeTypeOK := shapeTypeMap[panel.ShapeType]
|
||||
if !shapeTypeOK {
|
||||
@@ -70,10 +70,11 @@ func (b *bridge) Devices() []models.Device {
|
||||
UserProperties: nil,
|
||||
State: models.DeviceState{
|
||||
Power: panel.ColorRGBA[3] == 0,
|
||||
Color: models.ColorValue{
|
||||
Hue: math.Mod(hue, 360),
|
||||
Saturation: sat,
|
||||
},
|
||||
Color: models.ColorValue{RGB: &models.ColorRGB{
|
||||
Red: rgb.R,
|
||||
Green: rgb.G,
|
||||
Blue: rgb.B,
|
||||
}},
|
||||
Intensity: value,
|
||||
Temperature: 0,
|
||||
},
|
||||
@@ -172,9 +173,20 @@ func (b *bridge) Update(devices []models.Device) {
|
||||
for _, panel := range b.panels {
|
||||
if panel.ID == uint16(id) {
|
||||
if device.State.Power {
|
||||
color := colorful.Hsv(device.State.Color.Hue, device.State.Color.Saturation, device.State.Intensity)
|
||||
rgbColor, ok := device.State.Color.ToRGB()
|
||||
if !ok {
|
||||
newColor := [4]byte{255, 255, 255, 255}
|
||||
if newColor != panel.ColorRGBA {
|
||||
panel.update(newColor, time.Now().Add(time.Millisecond*220))
|
||||
}
|
||||
|
||||
red, green, blue := color.RGB255()
|
||||
continue
|
||||
}
|
||||
|
||||
rgb := rgbColor.RGB.AtIntensity(device.State.Intensity)
|
||||
red := byte(rgb.Red * 255.9)
|
||||
green := byte(rgb.Green * 255.9)
|
||||
blue := byte(rgb.Blue * 255.9)
|
||||
newColor := [4]byte{red, green, blue, 255}
|
||||
if newColor != panel.ColorRGBA {
|
||||
panel.update(newColor, time.Now().Add(time.Millisecond*220))
|
||||
|
||||
Reference in New Issue
Block a user