package lifx import ( "git.aiterp.net/lucifer/new-server/internal/color" "git.aiterp.net/lucifer/new-server/models" "math" "time" ) type State struct { target string externalId int lightState *LightState firmware *StateHostFirmware version *StateVersion deviceState *models.DeviceState discoveredTime time.Time lightStateTime time.Time requestTime time.Time updateTime time.Time fwSpamTime time.Time acksPending []uint8 } func (s *State) generateUpdate() []Payload { if s.deviceState == nil || s.lightState == nil { return nil } results := make([]Payload, 0, 0) if s.deviceState.Power != s.lightState.On { results = append(results, &SetLightPower{On: s.deviceState.Power, TransitionTime: time.Millisecond * 100}) } if !s.deviceState.Power { return results } c, ok := s.deviceState.Color.ToHSK() if !ok { c, _ = color.Parse("hsk:0,0,4000") } l := s.lightState di := s.deviceState.Intensity k := *c.K if k == 0 { k = 4000 } 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.HS.Hue, Sat: c.HS.Sat, Bri: di, Kelvin: k, TransitionTime: time.Millisecond * 150, }) } return results } func (s *State) handleAck(seq uint8) { for i, pendingAck := range s.acksPending { if pendingAck == seq { s.acksPending = append(s.acksPending[:i], s.acksPending[i+1:]...) break } } if len(s.acksPending) == 0 { s.lightStateTime = time.Now() prevLabel := "" if s.lightState != nil { prevLabel = s.lightState.Label } c, ok := s.deviceState.Color.ToHSK() if !ok { c, _ = color.Parse("hsk:0,0,4000") } s.lightState = &LightState{ Hue: c.HS.Hue, Sat: c.HS.Sat, Bri: s.deviceState.Intensity, Kelvin: *c.K, On: s.deviceState.Power, Label: prevLabel, } } } func equalish(a, b float64) bool { return math.Abs(a-b) < 0.005 }