You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

98 lines
2.0 KiB

  1. package lifx
  2. import (
  3. "git.aiterp.net/lucifer/new-server/internal/color"
  4. "git.aiterp.net/lucifer/new-server/models"
  5. "math"
  6. "time"
  7. )
  8. type State struct {
  9. target string
  10. externalId int
  11. lightState *LightState
  12. firmware *StateHostFirmware
  13. version *StateVersion
  14. deviceState *models.DeviceState
  15. discoveredTime time.Time
  16. lightStateTime time.Time
  17. requestTime time.Time
  18. updateTime time.Time
  19. fwSpamTime time.Time
  20. acksPending []uint8
  21. }
  22. func (s *State) generateUpdate() []Payload {
  23. if s.deviceState == nil || s.lightState == nil {
  24. return nil
  25. }
  26. results := make([]Payload, 0, 0)
  27. if s.deviceState.Power != s.lightState.On {
  28. results = append(results, &SetLightPower{On: s.deviceState.Power, TransitionTime: time.Millisecond * 100})
  29. }
  30. if !s.deviceState.Power {
  31. return results
  32. }
  33. c, ok := s.deviceState.Color.ToHSK()
  34. if !ok {
  35. c, _ = color.Parse("hsk:0,0,4000")
  36. }
  37. l := s.lightState
  38. di := s.deviceState.Intensity
  39. k := *c.K
  40. if k == 0 {
  41. k = 4000
  42. }
  43. if !equalish(c.HS.Hue, l.Hue) || !equalish(c.HS.Sat, l.Sat) || !equalish(di, l.Bri) || k != l.Kelvin {
  44. results = append(results, &SetColor{
  45. Hue: c.HS.Hue,
  46. Sat: c.HS.Sat,
  47. Bri: di,
  48. Kelvin: k,
  49. TransitionTime: time.Millisecond * 150,
  50. })
  51. }
  52. return results
  53. }
  54. func (s *State) handleAck(seq uint8) {
  55. for i, pendingAck := range s.acksPending {
  56. if pendingAck == seq {
  57. s.acksPending = append(s.acksPending[:i], s.acksPending[i+1:]...)
  58. break
  59. }
  60. }
  61. if len(s.acksPending) == 0 {
  62. s.lightStateTime = time.Now()
  63. prevLabel := ""
  64. if s.lightState != nil {
  65. prevLabel = s.lightState.Label
  66. }
  67. c, ok := s.deviceState.Color.ToHSK()
  68. if !ok {
  69. c, _ = color.Parse("hsk:0,0,4000")
  70. }
  71. s.lightState = &LightState{
  72. Hue: c.HS.Hue,
  73. Sat: c.HS.Sat,
  74. Bri: s.deviceState.Intensity,
  75. Kelvin: *c.K,
  76. On: s.deviceState.Power,
  77. Label: prevLabel,
  78. }
  79. }
  80. }
  81. func equalish(a, b float64) bool {
  82. return math.Abs(a-b) < 0.005
  83. }