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.

142 lines
4.2 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.Variables != nil {
  76. pa.Variables = gentools.CopyMap(patch.Assignment.Variables)
  77. }
  78. if patch.Assignment.Delete {
  79. delete(newData.Assignments, pa.ID)
  80. } else {
  81. newData.Assignments[pa.ID] = pa
  82. }
  83. }
  84. }
  85. return newData
  86. }
  87. func (d *Data) Copy() Data {
  88. return Data{
  89. Devices: gentools.CopyMap(d.Devices),
  90. Assignments: gentools.CopyMap(d.Assignments),
  91. }
  92. }
  93. func (d *Data) ensureDevice(id string) Device {
  94. if device, ok := d.Devices[id]; ok {
  95. return device
  96. } else {
  97. return Device{ID: id}
  98. }
  99. }
  100. func (d *Data) ensureAssignment(id uuid.UUID) Assignment {
  101. if assignment, ok := d.Assignments[id]; ok {
  102. return assignment
  103. } else {
  104. return Assignment{ID: id}
  105. }
  106. }
  107. type Device struct {
  108. ID string `json:"id"`
  109. Name string `json:"name"`
  110. HWMetadata *events.HardwareMetadata `json:"hwMetadata"`
  111. HWState *events.HardwareState `json:"hwState"`
  112. ActiveColorRGB *color.RGB `json:"activeColorRgb"`
  113. DesiredState *device.State `json:"desiredState"`
  114. Aliases []string `json:"aliases"`
  115. Assignment *uuid.UUID `json:"assignment"`
  116. Sensors DeviceSensors `json:"sensors"`
  117. }
  118. type DeviceSensors struct {
  119. LastMotion *float64 `json:"lastMotion,omitempty"`
  120. Temperature *float64 `json:"temperature,omitempty"`
  121. }
  122. type Assignment struct {
  123. ID uuid.UUID `json:"id"`
  124. DeviceIDs []string `json:"deviceIds"`
  125. Effect *effects.Serializable `json:"effect"`
  126. Variables map[string]float64 `json:"variables"`
  127. }