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.

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