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.

157 lines
4.3 KiB

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "git.aiterp.net/lucifer/new-server/models"
  6. "io"
  7. "sort"
  8. "strings"
  9. "time"
  10. )
  11. func WriteDeviceInfo(w io.Writer, devices []models.Device, fields []string) {
  12. if len(fields) == 1 && fields[0] == "all" {
  13. fields = allFields
  14. } else {
  15. fields = append(fields[:0:0], fields...)
  16. for i, field := range fields {
  17. if aliased, ok := fieldAliases[field]; ok {
  18. fields[i] = aliased
  19. }
  20. }
  21. }
  22. length := 0
  23. for _, field := range fields {
  24. if mlFields[field] {
  25. continue
  26. }
  27. if len(field) > length {
  28. length = len(field)
  29. }
  30. }
  31. for i, device := range devices {
  32. if i > 0 {
  33. fmt.Println()
  34. }
  35. for _, field := range fields {
  36. if formatter, ok := fieldFormatters[field]; ok {
  37. _, _ = fmt.Fprintf(w, "%-*s %s\n", length+1, field+":", formatter(&device))
  38. } else {
  39. _, _ = fmt.Fprintf(w, "%-*s (unknown field)\n", length+1, field+":")
  40. }
  41. }
  42. }
  43. }
  44. var allFields = []string{
  45. "id", "name", "icon", "bridgeId", "tags", "buttonNames",
  46. "power", "color", "intensity", "temperature",
  47. "internalId", "sceneAssignment", "userProperties", "driverProperties",
  48. }
  49. var mlFields = map[string]bool{
  50. "sceneAssignment": true,
  51. "userProperties": true,
  52. "driverProperties": true,
  53. }
  54. var fieldFormatters = map[string]func(d *models.Device) string{
  55. "id": func(d *models.Device) string { return fmt.Sprint(d.ID) },
  56. "internalId": func(d *models.Device) string { return d.InternalID },
  57. "name": func(d *models.Device) string { return d.Name },
  58. "icon": func(d *models.Device) string { return d.Icon },
  59. "bridgeId": func(d *models.Device) string { return fmt.Sprint(d.BridgeID) },
  60. "tags": func(d *models.Device) string { return strings.Join(d.Tags, ", ") },
  61. "buttonNames": func(d *models.Device) string { return strings.Join(d.ButtonNames, ", ") },
  62. "power": func(d *models.Device) string { return fmt.Sprint(d.State.Power) },
  63. "color": func(d *models.Device) string { return d.State.Color.String() },
  64. "intensity": func(d *models.Device) string { return fmt.Sprint(d.State.Intensity) },
  65. "temperature": func(d *models.Device) string { return fmt.Sprint(d.State.Temperature) },
  66. "sceneAssignment": func(d *models.Device) string {
  67. str := &strings.Builder{}
  68. str.Grow(64)
  69. for _, scene := range d.SceneAssignments {
  70. _, _ = fmt.Fprintf(str, "\n - id: %d\n", scene.SceneID)
  71. _, _ = fmt.Fprintf(str, " duration: %d\n", scene.DurationMS)
  72. _, _ = fmt.Fprintf(str, " group: %s\n", scene.Group)
  73. _, _ = fmt.Fprintf(str, " startTime: %s", scene.StartTime.Format(time.RFC3339))
  74. }
  75. if len(d.SceneAssignments) == 0 {
  76. str.Reset()
  77. str.WriteString("(none)")
  78. }
  79. return str.String()
  80. },
  81. "userProperties": func(d *models.Device) string {
  82. str := &strings.Builder{}
  83. str.Grow(64)
  84. str.WriteString("\n")
  85. keys := make([]string, 0, len(d.UserProperties))
  86. for key := range d.UserProperties {
  87. keys = append(keys, key)
  88. }
  89. sort.Strings(keys)
  90. for _, key := range keys {
  91. _, _ = fmt.Fprintf(str, " %s: %s\n", key, d.UserProperties[key])
  92. }
  93. if len(d.UserProperties) == 0 {
  94. str.Reset()
  95. str.WriteString("(none)")
  96. }
  97. return str.String()
  98. },
  99. "driverProperties": func(d *models.Device) string {
  100. str := &strings.Builder{}
  101. str.Grow(256)
  102. str.WriteString("\n")
  103. keys := make([]string, 0, len(d.DriverProperties))
  104. for key := range d.DriverProperties {
  105. keys = append(keys, key)
  106. }
  107. sort.Strings(keys)
  108. for _, key := range keys {
  109. j, _ := json.Marshal(d.DriverProperties[key])
  110. _, _ = fmt.Fprintf(str, " %s: %s\n", key, string(j))
  111. }
  112. if len(d.DriverProperties) == 0 {
  113. str.Reset()
  114. str.WriteString("(none)")
  115. }
  116. return str.String()
  117. },
  118. "capabilities": func(d *models.Device) string {
  119. capStr := make([]string, len(d.Capabilities))
  120. for i := range d.Capabilities {
  121. capStr[i] = string(d.Capabilities[i])
  122. }
  123. return strings.Join(capStr, ", ")
  124. },
  125. }
  126. var fieldAliases = map[string]string{
  127. "bridge": "bridgeId",
  128. "buttons": "buttonNames",
  129. "internal": "internalId",
  130. "caps": "capabilities",
  131. "cap": "capabilities",
  132. "userprops": "userProperties",
  133. "uprops": "userProperties",
  134. "driverprops": "driverProperties",
  135. "dprops": "driverProperties",
  136. "internalid": "internalId",
  137. "bridgeid": "bridgeId",
  138. "buttonnames": "buttonNames",
  139. "scene": "sceneAssignment",
  140. }