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.

135 lines
3.7 KiB

  1. package uistate
  2. import (
  3. lucifer3 "git.aiterp.net/lucifer3/server"
  4. "git.aiterp.net/lucifer3/server/commands"
  5. "git.aiterp.net/lucifer3/server/effects"
  6. "git.aiterp.net/lucifer3/server/events"
  7. "git.aiterp.net/lucifer3/server/internal/gentools"
  8. "sync"
  9. )
  10. func NewService() lucifer3.ActiveService {
  11. return &service{}
  12. }
  13. type service struct {
  14. mu sync.Mutex
  15. data Data
  16. listener []chan Patch
  17. }
  18. func (s *service) Active() bool {
  19. return true
  20. }
  21. func (s *service) HandleCommand(bus *lucifer3.EventBus, command lucifer3.Command) {
  22. var patches []Patch
  23. switch command := command.(type) {
  24. case commands.SetState:
  25. patches = []Patch{{Device: &DevicePatch{ID: command.ID, DesiredState: &command.State}}}
  26. case commands.SetStateBatch:
  27. for id, state := range command {
  28. patches = append(patches, Patch{
  29. Device: &DevicePatch{ID: id, DesiredState: gentools.ShallowCopy(&state)},
  30. })
  31. }
  32. }
  33. if len(patches) > 0 {
  34. s.mu.Lock()
  35. s.data = s.data.WithPatch(patches...)
  36. s.mu.Unlock()
  37. for _, patch := range patches {
  38. bus.RunEvent(patch)
  39. }
  40. }
  41. }
  42. func (s *service) HandleEvent(bus *lucifer3.EventBus, event lucifer3.Event) {
  43. var patches []Patch
  44. switch event := event.(type) {
  45. case events.AliasAdded:
  46. patches = []Patch{{Device: &DevicePatch{ID: event.ID, AddAlias: &event.Alias}}}
  47. case events.AliasRemoved:
  48. patches = []Patch{{Device: &DevicePatch{ID: event.ID, RemoveAlias: &event.Alias}}}
  49. case events.HardwareState:
  50. patches = []Patch{{Device: &DevicePatch{ID: event.ID, HWState: &event}}}
  51. if event.State.Color != nil {
  52. rgb, _ := event.State.Color.ToRGB()
  53. patches = append(patches, Patch{Device: &DevicePatch{
  54. ID: event.ID,
  55. ActiveColorRGB: gentools.Ptr(rgb.RGB.Round()),
  56. }})
  57. } else {
  58. patches = append(patches, Patch{Device: &DevicePatch{
  59. ID: event.ID,
  60. ClearActiveColorRGB: false,
  61. }})
  62. }
  63. case events.HardwareMetadata:
  64. patches = []Patch{{Device: &DevicePatch{ID: event.ID, HWMetadata: &event}}}
  65. case events.AssignmentCreated:
  66. patches = []Patch{{Assignment: &AssignmentPatch{
  67. ID: event.ID,
  68. Effect: &effects.Serializable{Effect: event.Effect},
  69. }}}
  70. case events.AssignmentRemoved:
  71. patches = []Patch{{Assignment: &AssignmentPatch{
  72. ID: event.ID,
  73. Delete: true,
  74. }}}
  75. case events.MotionSensed:
  76. patches = []Patch{{Device: &DevicePatch{
  77. ID: event.ID,
  78. Sensors: &DeviceSensors{LastMotion: gentools.Ptr(event.SecondsSince)},
  79. }}}
  80. case events.TemperatureChanged:
  81. patches = []Patch{{Device: &DevicePatch{
  82. ID: event.ID,
  83. Sensors: &DeviceSensors{Temperature: gentools.Ptr(event.Temperature)},
  84. }}}
  85. case events.DeviceAssigned:
  86. // Un-assign from current assignment (if any)
  87. if d, ok := s.data.Devices[event.DeviceID]; ok && d.Assignment != nil {
  88. patches = append(patches, Patch{Assignment: &AssignmentPatch{
  89. ID: *d.Assignment,
  90. RemoveDeviceID: &d.ID,
  91. }})
  92. }
  93. // Assign to current assignment (if it's not cleared)
  94. if event.AssignmentID != nil {
  95. patches = append(patches, Patch{Assignment: &AssignmentPatch{
  96. ID: *event.AssignmentID,
  97. AddDeviceID: &event.DeviceID,
  98. }})
  99. }
  100. // Always set the assignment
  101. patches = append(patches, Patch{Device: &DevicePatch{
  102. ID: event.DeviceID,
  103. Assignment: gentools.ShallowCopy(event.AssignmentID),
  104. ClearAssignment: event.AssignmentID == nil,
  105. }})
  106. case events.AssignmentVariables:
  107. // Always set the assignment
  108. patches = append(patches, Patch{Assignment: &AssignmentPatch{
  109. ID: event.ID,
  110. Variables: event.Map,
  111. }})
  112. }
  113. if len(patches) > 0 {
  114. s.mu.Lock()
  115. s.data = s.data.WithPatch(patches...)
  116. s.mu.Unlock()
  117. for _, patch := range patches {
  118. bus.RunEvent(patch)
  119. }
  120. }
  121. }