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.

147 lines
3.8 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. package models
  2. import (
  3. "context"
  4. "strings"
  5. )
  6. type Device struct {
  7. ID int `json:"id"`
  8. BridgeID int `json:"bridgeID"`
  9. InternalID string `json:"internalId"`
  10. Icon string `json:"icon"`
  11. Name string `json:"name"`
  12. Capabilities []DeviceCapability `json:"capabilities"`
  13. ButtonNames []string `json:"buttonNames"`
  14. DriverProperties map[string]interface{} `json:"driverProperties"`
  15. UserProperties map[string]string `json:"userProperties"`
  16. State DeviceState `json:"state"`
  17. Tags []string `json:"tags"`
  18. }
  19. // DeviceState contains optional state values that
  20. // - Power: Whether the device is powered on
  21. // - Color: Color value, if a color setting can be set on the device
  22. // - Intensity: e.g. brightness, range 0..=1
  23. // - Temperature: e.g. for thermostats
  24. type DeviceState struct {
  25. Power bool `json:"power"`
  26. Color ColorValue `json:"color,omitempty"`
  27. Intensity float64 `json:"intensity,omitempty"`
  28. Temperature float64 `json:"temperature"`
  29. }
  30. type NewDeviceState struct {
  31. Power *bool `json:"power"`
  32. Color *string `json:"color"`
  33. Intensity *float64 `json:"intensity"`
  34. Temperature int `json:"temperature"`
  35. }
  36. type DeviceCapability string
  37. type DeviceRepository interface {
  38. Find(ctx context.Context, id int) (*Device, error)
  39. FetchByReference(ctx context.Context, kind ReferenceKind, value string) ([]Device, error)
  40. Save(ctx context.Context, device *Device) error
  41. Delete(ctx context.Context, device *Device) error
  42. }
  43. func DeviceCapabilitiesToStrings(caps []DeviceCapability) []string {
  44. res := make([]string, 0, len(caps))
  45. for _, cap := range caps {
  46. res = append(res, string(cap))
  47. }
  48. return res
  49. }
  50. var (
  51. DCPower DeviceCapability = "Power"
  52. DCColorHS DeviceCapability = "ColorHS"
  53. DCColorHSK DeviceCapability = "ColorHSK"
  54. DCColorKelvin DeviceCapability = "ColorKelvin"
  55. DCButtons DeviceCapability = "Buttons"
  56. DCPresence DeviceCapability = "Presence"
  57. DCIntensity DeviceCapability = "Intensity"
  58. DCTemperatureControl DeviceCapability = "TemperatureControl"
  59. DCTemperatureSensor DeviceCapability = "TemperatureSensor"
  60. )
  61. var Capabilities = []DeviceCapability{
  62. DCPower,
  63. DCColorHS,
  64. DCColorKelvin,
  65. DCButtons,
  66. DCPresence,
  67. DCIntensity,
  68. DCTemperatureControl,
  69. DCTemperatureSensor,
  70. }
  71. func (d *Device) Validate() error {
  72. d.Name = strings.Trim(d.Name, " \t\n ")
  73. if d.Name == "" {
  74. return ErrInvalidName
  75. }
  76. newCaps := make([]DeviceCapability, 0, len(d.Capabilities))
  77. for _, currCap := range d.Capabilities {
  78. for _, validCap := range Capabilities {
  79. if currCap == validCap {
  80. newCaps = append(newCaps, currCap)
  81. break
  82. }
  83. }
  84. }
  85. d.Capabilities = newCaps
  86. return nil
  87. }
  88. func (d *Device) HasTag(tags ...string) bool {
  89. for _, c := range d.Tags {
  90. for _, c2 := range tags {
  91. if c == c2 {
  92. return true
  93. }
  94. }
  95. }
  96. return false
  97. }
  98. func (d *Device) HasCapability(capabilities ...DeviceCapability) bool {
  99. for _, c := range d.Capabilities {
  100. for _, c2 := range capabilities {
  101. if c == c2 {
  102. return true
  103. }
  104. }
  105. }
  106. return false
  107. }
  108. func (d *Device) SetState(newState NewDeviceState) error {
  109. if newState.Power != nil && d.HasCapability(DCPower) {
  110. d.State.Power = *newState.Power
  111. }
  112. if newState.Color != nil {
  113. parsed, err := ParseColorValue(*newState.Color)
  114. if err != nil {
  115. return err
  116. }
  117. if (parsed.IsKelvin() && d.HasCapability(DCColorKelvin, DCColorHSK)) || (parsed.IsHueSat() && d.HasCapability(DCColorHS)) {
  118. d.State.Color = parsed
  119. }
  120. }
  121. if newState.Intensity != nil && d.HasCapability(DCIntensity) {
  122. d.State.Intensity = *newState.Intensity
  123. }
  124. return nil
  125. }