This commit is contained in:
+57
-40
@@ -436,6 +436,8 @@ func (b *Bridge) Run(ctx context.Context, bus *lucifer3.EventBus) interface{} {
|
||||
}
|
||||
|
||||
func (b *Bridge) makeCongruentLoop(ctx context.Context) {
|
||||
hadFirst := make(map[string]bool, 16)
|
||||
|
||||
for range b.triggerCongruenceCheckCh {
|
||||
// I hate that I have to do this, but the SSE is not being reliable.
|
||||
_, _ = b.RefreshAll()
|
||||
@@ -473,52 +475,50 @@ func (b *Bridge) makeCongruentLoop(ctx context.Context) {
|
||||
update := ResourceUpdate{}
|
||||
|
||||
// Handle power first
|
||||
if desired.Power != nil && active.Power != nil && *desired.Power != *active.Power {
|
||||
if desired.Power != nil && active.Power != nil && (!hadFirst[*lightID] || *desired.Power != *active.Power) {
|
||||
update.Power = gentools.Ptr(*desired.Power)
|
||||
updated = true
|
||||
}
|
||||
|
||||
// Only do the rest if there's power.
|
||||
if desired.Power == nil || *desired.Power {
|
||||
if active.Color != nil && desired.Color != nil {
|
||||
ac := *active.Color
|
||||
dc := *desired.Color
|
||||
if active.Color != nil && desired.Color != nil {
|
||||
ac := *active.Color
|
||||
dc := *desired.Color
|
||||
|
||||
if !dc.IsKelvin() || !colorFlags[id].IsWarmWhite() {
|
||||
dc, _ = dc.ToXY()
|
||||
dc.XY = gentools.Ptr(light.Color.Gamut.Conform(*dc.XY))
|
||||
if !dc.IsKelvin() || !colorFlags[id].IsWarmWhite() {
|
||||
dc, _ = dc.ToXY()
|
||||
dc.XY = gentools.Ptr(light.Color.Gamut.Conform(*dc.XY))
|
||||
}
|
||||
|
||||
if dc.XY != nil {
|
||||
if ac.K != nil {
|
||||
ac.K = gentools.Ptr(1000000 / (1000000 / *ac.K))
|
||||
}
|
||||
|
||||
if dc.XY != nil {
|
||||
if ac.K != nil {
|
||||
ac.K = gentools.Ptr(1000000 / (1000000 / *ac.K))
|
||||
}
|
||||
|
||||
acXY, _ := ac.ToXY()
|
||||
dist := dc.XY.DistanceTo(*acXY.XY)
|
||||
if dist > 0.0002 {
|
||||
update.ColorXY = gentools.Ptr(*dc.XY)
|
||||
updated = true
|
||||
}
|
||||
} else {
|
||||
dcMirek := 1000000 / *dc.K
|
||||
if dcMirek < light.ColorTemperature.MirekSchema.MirekMinimum {
|
||||
dcMirek = light.ColorTemperature.MirekSchema.MirekMinimum
|
||||
} else if dcMirek > light.ColorTemperature.MirekSchema.MirekMaximum {
|
||||
dcMirek = light.ColorTemperature.MirekSchema.MirekMaximum
|
||||
}
|
||||
acMirek := 0
|
||||
if ac.K != nil {
|
||||
acMirek = 1000000 / *ac.K
|
||||
}
|
||||
if acMirek != dcMirek {
|
||||
update.Mirek = &dcMirek
|
||||
updated = true
|
||||
}
|
||||
acXY, _ := ac.ToXY()
|
||||
dist := dc.XY.DistanceTo(*acXY.XY)
|
||||
if dist > 0.0002 || !hadFirst[*lightID] {
|
||||
update.ColorXY = gentools.Ptr(*dc.XY)
|
||||
updated = true
|
||||
}
|
||||
} else {
|
||||
dcMirek := 1000000 / *dc.K
|
||||
if dcMirek < light.ColorTemperature.MirekSchema.MirekMinimum {
|
||||
dcMirek = light.ColorTemperature.MirekSchema.MirekMinimum
|
||||
} else if dcMirek > light.ColorTemperature.MirekSchema.MirekMaximum {
|
||||
dcMirek = light.ColorTemperature.MirekSchema.MirekMaximum
|
||||
}
|
||||
acMirek := 0
|
||||
if ac.K != nil {
|
||||
acMirek = 1000000 / *ac.K
|
||||
}
|
||||
if acMirek != dcMirek || !hadFirst[*lightID] {
|
||||
update.Mirek = &dcMirek
|
||||
updated = true
|
||||
}
|
||||
}
|
||||
|
||||
if active.Intensity != nil && desired.Intensity != nil {
|
||||
if active.Intensity != nil && desired.Intensity != nil || !hadFirst[*lightID] {
|
||||
if math.Abs(*active.Intensity-*desired.Intensity) >= 0.01 {
|
||||
update.Brightness = gentools.Ptr(*desired.Intensity * 100)
|
||||
updated = true
|
||||
@@ -529,11 +529,13 @@ func (b *Bridge) makeCongruentLoop(ctx context.Context) {
|
||||
if updated {
|
||||
update.TransitionDuration = gentools.Ptr(time.Millisecond * 101)
|
||||
updates["light/"+*lightID] = update
|
||||
hadFirst[*lightID] = true
|
||||
}
|
||||
}
|
||||
|
||||
if len(updates) > 0 {
|
||||
timeout, cancel := context.WithTimeout(ctx, time.Millisecond*500*time.Duration(len(updates)))
|
||||
timeout, cancel := context.WithTimeout(ctx, time.Second*60)
|
||||
hadPower := false
|
||||
|
||||
eg, ctx := errgroup.WithContext(timeout)
|
||||
for key := range updates {
|
||||
@@ -541,8 +543,19 @@ func (b *Bridge) makeCongruentLoop(ctx context.Context) {
|
||||
split := strings.SplitN(key, "/", 2)
|
||||
link := ResourceLink{Kind: split[0], ID: split[1]}
|
||||
|
||||
if update.Power != nil {
|
||||
hadPower = true
|
||||
}
|
||||
|
||||
eg.Go(func() error {
|
||||
return b.client.UpdateResource(ctx, link, update)
|
||||
if update.Power != nil {
|
||||
return b.client.UpdateResource(ctx, link, ResourceUpdate{
|
||||
Power: update.Power,
|
||||
TransitionDuration: update.TransitionDuration,
|
||||
})
|
||||
} else {
|
||||
return b.client.UpdateResource(ctx, link, update)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -551,11 +564,15 @@ func (b *Bridge) makeCongruentLoop(ctx context.Context) {
|
||||
log.Println("Failed to run update", err)
|
||||
}
|
||||
|
||||
cancel()
|
||||
if hadPower {
|
||||
b.triggerCongruenceCheck()
|
||||
}
|
||||
|
||||
// Wait the remaining time for the rate limit
|
||||
<-rateLimit
|
||||
cancel()
|
||||
}
|
||||
|
||||
// Wait the remaining time for the rate limit
|
||||
<-rateLimit
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ func (d *Data) ensureDevice(id string) Device {
|
||||
if device, ok := d.Devices[id]; ok {
|
||||
return device
|
||||
} else {
|
||||
return Device{ID: id}
|
||||
return Device{ID: id, Aliases: make([]string, 0)}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user