func (l *Light) SetColor(color common.Color, duration time.Duration) error { if common.ColorEqual(color, l.CachedColor()) { return nil } common.Log.Debugf("Setting color on %d", l.id) if duration < shared.RateLimit { duration = shared.RateLimit } p := &payloadColor{ Color: color, Duration: uint32(duration / time.Millisecond), } pkt := packet.New(l.address, l.requestSocket) pkt.SetType(SetColor) if err := pkt.SetPayload(p); err != nil { return err } req, err := l.Send(pkt, l.reliable, false) if err != nil { return err } if l.reliable { // Wait for ack <-req common.Log.Debugf("Setting color on %d acknowledged", l.id) } l.Lock() l.color = color l.Unlock() return l.publish(common.EventUpdateColor{Color: l.color}) }
// getColor returns the average color for lights in the group, or error if any // light returns an error. func (g *Group) getColor(cached bool) (common.Color, error) { var err error g.RLock() lastColor := g.color g.RUnlock() lights := g.Lights() if len(lights) == 0 { return lastColor, nil } colors := make([]common.Color, len(lights)) for i, light := range lights { var c common.Color if cached { c = light.CachedColor() } else { c, err = light.GetColor() if err != nil { return lastColor, err } } colors[i] = c } g.Lock() g.color = common.AverageColor(colors...) g.Unlock() g.RLock() defer g.RUnlock() if !common.ColorEqual(lastColor, g.color) { err = g.publish(common.EventUpdateColor{Color: g.color}) if err != nil { return g.color, err } } return g.color, nil }
func (l *Light) SetState(pkt *packet.Packet) error { s := &state{} if err := pkt.DecodePayload(s); err != nil { return err } common.Log.Debugf("Got light state (%d): %+v", l.id, s) if !common.ColorEqual(s.Color, l.CachedColor()) { l.Lock() l.color = s.Color l.Unlock() if err := l.publish(common.EventUpdateColor{Color: l.color}); err != nil { return err } } if s.Power > 0 != l.CachedPower() { l.Lock() l.power = s.Power l.Unlock() if err := l.publish(common.EventUpdatePower{Power: l.power > 0}); err != nil { return err } } newLabel := stripNull(string(s.Label[:])) if newLabel != l.CachedLabel() { l.Lock() l.label = newLabel l.Unlock() if err := l.publish(common.EventUpdateLabel{Label: l.label}); err != nil { return err } } return nil }