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.

138 lines
4.0 KiB

  1. package uistate
  2. import (
  3. "git.aiterp.net/lucifer3/server/device"
  4. "git.aiterp.net/lucifer3/server/effects"
  5. "git.aiterp.net/lucifer3/server/events"
  6. "git.aiterp.net/lucifer3/server/internal/color"
  7. "git.aiterp.net/lucifer3/server/internal/gentools"
  8. "github.com/google/uuid"
  9. )
  10. type Data struct {
  11. Devices map[string]Device `json:"devices"`
  12. Assignments map[uuid.UUID]Assignment `json:"assignments"`
  13. }
  14. func (d *Data) WithPatch(patches ...Patch) Data {
  15. newData := d.Copy()
  16. for _, patch := range patches {
  17. if patch.Device != nil {
  18. pd := d.ensureDevice(patch.Device.ID)
  19. gentools.ApplyUpdateSlice(&pd.Aliases, patch.Device.SetAliases)
  20. gentools.ApplyUpdate(&pd.Name, patch.Device.Name)
  21. gentools.ApplyUpdatePtr(&pd.HWState, patch.Device.HWState)
  22. gentools.ApplyUpdatePtr(&pd.HWMetadata, patch.Device.HWMetadata)
  23. gentools.ApplyUpdatePtr(&pd.DesiredState, patch.Device.DesiredState)
  24. gentools.ApplyUpdatePtr(&pd.Assignment, patch.Device.Assignment)
  25. gentools.ApplyUpdatePtr(&pd.ActiveColorRGB, patch.Device.ActiveColorRGB)
  26. if patch.Device.AddAlias != nil {
  27. pd.Aliases = append(pd.Aliases[:0:0], pd.Aliases...)
  28. pd.Aliases = append(pd.Aliases, *patch.Device.AddAlias)
  29. }
  30. if patch.Device.RemoveAlias != nil {
  31. for i, alias := range pd.Aliases {
  32. if alias == *patch.Device.RemoveAlias {
  33. pd.Aliases = append(pd.Aliases[:0:0], pd.Aliases...)
  34. pd.Aliases = append(pd.Aliases[:i], pd.Aliases[i+1:]...)
  35. break
  36. }
  37. }
  38. }
  39. if patch.Device.ClearAssignment {
  40. pd.Assignment = nil
  41. }
  42. if patch.Device.ClearActiveColorRGB {
  43. pd.ActiveColorRGB = nil
  44. }
  45. if patch.Device.Sensors != nil {
  46. if patch.Device.Sensors.LastMotion != nil {
  47. pd.Sensors.LastMotion = gentools.ShallowCopy(patch.Device.Sensors.LastMotion)
  48. }
  49. if patch.Device.Sensors.Temperature != nil {
  50. pd.Sensors.Temperature = gentools.ShallowCopy(patch.Device.Sensors.Temperature)
  51. }
  52. }
  53. if patch.Device.Delete {
  54. delete(newData.Devices, pd.ID)
  55. } else {
  56. newData.Devices[pd.ID] = pd
  57. }
  58. }
  59. if patch.Assignment != nil {
  60. pa := d.ensureAssignment(patch.Assignment.ID)
  61. gentools.ApplyUpdatePtr(&pa.Effect, patch.Assignment.Effect)
  62. if patch.Assignment.AddDeviceID != nil {
  63. pa.DeviceIDs = append(pa.DeviceIDs[:0:0], pa.DeviceIDs...)
  64. pa.DeviceIDs = append(pa.DeviceIDs, *patch.Assignment.AddDeviceID)
  65. }
  66. if patch.Assignment.RemoveDeviceID != nil {
  67. for i, id := range pa.DeviceIDs {
  68. if id == *patch.Assignment.RemoveDeviceID {
  69. pa.DeviceIDs = append(pa.DeviceIDs[:0:0], pa.DeviceIDs...)
  70. pa.DeviceIDs[i] = ""
  71. break
  72. }
  73. }
  74. }
  75. if patch.Assignment.Delete {
  76. delete(newData.Assignments, pa.ID)
  77. } else {
  78. newData.Assignments[pa.ID] = pa
  79. }
  80. }
  81. }
  82. return newData
  83. }
  84. func (d *Data) Copy() Data {
  85. return Data{
  86. Devices: gentools.CopyMap(d.Devices),
  87. Assignments: gentools.CopyMap(d.Assignments),
  88. }
  89. }
  90. func (d *Data) ensureDevice(id string) Device {
  91. if device, ok := d.Devices[id]; ok {
  92. return device
  93. } else {
  94. return Device{ID: id}
  95. }
  96. }
  97. func (d *Data) ensureAssignment(id uuid.UUID) Assignment {
  98. if assignment, ok := d.Assignments[id]; ok {
  99. return assignment
  100. } else {
  101. return Assignment{ID: id}
  102. }
  103. }
  104. type Device struct {
  105. ID string `json:"id"`
  106. Name string `json:"name"`
  107. HWMetadata *events.HardwareMetadata `json:"hwMetadata"`
  108. HWState *events.HardwareState `json:"hwState"`
  109. ActiveColorRGB *color.RGB `json:"activeColorRgb"`
  110. DesiredState *device.State `json:"desiredState"`
  111. Aliases []string `json:"aliases"`
  112. Assignment *uuid.UUID `json:"assignment"`
  113. Sensors DeviceSensors `json:"sensors"`
  114. }
  115. type DeviceSensors struct {
  116. LastMotion *float64 `json:"lastMotion,omitempty"`
  117. Temperature *float64 `json:"temperature,omitempty"`
  118. }
  119. type Assignment struct {
  120. ID uuid.UUID `json:"id"`
  121. DeviceIDs []string `json:"deviceIds"`
  122. Effect *effects.Serializable `json:"effect"`
  123. }