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.

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