package nanoleaf import ( "encoding/binary" "time" ) type panel struct { ID uint16 ColorRGBA [4]byte TransitionAt time.Time O int X int Y int ShapeType int Stale bool SlowUpdates int TicksUntilSlowUpdate int } func (p *panel) message() (message [8]byte) { transitionTime := p.TransitionAt.Sub(time.Now()).Round(time.Millisecond * 100) if transitionTime > maxTransitionTime { transitionTime = maxTransitionTime } else if transitionTime < 0 { transitionTime = 0 } binary.BigEndian.PutUint16(message[0:], p.ID) copy(message[2:], p.ColorRGBA[:]) binary.BigEndian.PutUint16(message[6:], uint16(transitionTime/(time.Millisecond*100))) return } func (p *panel) update(colorRGBA [4]byte, transitionAt time.Time) { if p.ColorRGBA != colorRGBA { p.ColorRGBA = colorRGBA p.Stale = true p.SlowUpdates = 3 p.TicksUntilSlowUpdate = 10 } p.TransitionAt = transitionAt } type panelUpdate []byte func (u *panelUpdate) Add(message [8]byte) { if len(*u) < 2 { *u = make([]byte, 2, 10) } binary.BigEndian.PutUint16(*u, binary.BigEndian.Uint16(*u)+1) *u = append(*u, message[:]...) } func (u *panelUpdate) Len() int { if len(*u) < 2 { return 0 } return int(binary.BigEndian.Uint16(*u)) } const maxTransitionTime = time.Minute * 109