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.

242 lines
4.4 KiB

  1. package main
  2. import (
  3. "git.aiterp.net/lucifer/new-server/models"
  4. "log"
  5. "strconv"
  6. "strings"
  7. )
  8. type Param struct {
  9. Index int
  10. Key string
  11. Value string
  12. Operator string
  13. }
  14. func (p *Param) String() *string {
  15. if p == nil {
  16. return nil
  17. }
  18. return &p.Value
  19. }
  20. func (p *Param) StringOr(fallback string) string {
  21. if p == nil {
  22. return fallback
  23. }
  24. return p.Value
  25. }
  26. func (p *Param) Int() *int {
  27. if p == nil {
  28. return nil
  29. }
  30. n, err := strconv.Atoi(p.Value)
  31. if err != nil {
  32. return nil
  33. }
  34. return &n
  35. }
  36. func (p *Param) IntOr(other int) int {
  37. val := p.Int()
  38. if val == nil {
  39. return other
  40. }
  41. return *val
  42. }
  43. func (p *Param) Float() *float64 {
  44. if p == nil {
  45. return nil
  46. }
  47. n, err := strconv.ParseFloat(p.Value, 64)
  48. if err != nil {
  49. return nil
  50. }
  51. return &n
  52. }
  53. func (p *Param) Bool() *bool {
  54. if p == nil {
  55. return nil
  56. }
  57. v := strings.ToLower(p.Value)
  58. if v == "yes" || v == "true" || v == "on" {
  59. r := true
  60. return &r
  61. } else if v == "no" || v == "false" || v == "off" {
  62. r := false
  63. return &r
  64. }
  65. return nil
  66. }
  67. type Params []Param
  68. func (p Params) Get(key interface{}) *Param {
  69. switch key := key.(type) {
  70. case string:
  71. for _, p := range p {
  72. if p.Key == key {
  73. return &p
  74. }
  75. }
  76. case int:
  77. for _, p := range p {
  78. if p.Index == key {
  79. return &p
  80. }
  81. }
  82. default:
  83. log.Panicf("Incorrect key type %T", key)
  84. }
  85. return nil
  86. }
  87. func (p Params) Subset(prefix string) Params {
  88. if len(p) == 0 {
  89. return Params{}
  90. }
  91. if len(prefix) > 0 && !strings.HasSuffix(prefix, ".") {
  92. prefix += "."
  93. }
  94. res := make(Params, 0, len(p))
  95. for _, param := range p {
  96. if param.Index == -1 && strings.HasPrefix(param.Key, prefix) {
  97. res = append(res, Param{Index: -1, Key: param.Key[len(prefix):], Value: param.Value, Operator: param.Operator})
  98. }
  99. }
  100. return res
  101. }
  102. func (p Params) StringMap() map[string]string {
  103. res := make(map[string]string)
  104. for _, param := range p {
  105. if param.Index == -1 {
  106. res[param.Key] = param.Value
  107. }
  108. }
  109. return res
  110. }
  111. func (p Params) StringPtrMap() map[string]*string {
  112. res := make(map[string]*string)
  113. for _, param := range p {
  114. if param.Index == -1 {
  115. if param.Value == "NULL" {
  116. res[param.Key] = nil
  117. } else {
  118. res[param.Key] = &param.Value
  119. }
  120. }
  121. }
  122. return res
  123. }
  124. func (p Params) Strings(minIndex int) []string {
  125. res := make([]string, 0, len(p))
  126. for _, param := range p {
  127. if param.Index >= minIndex {
  128. res = append(res, param.Value)
  129. }
  130. }
  131. return res
  132. }
  133. func (p Params) EventConditions() map[string]models.EventCondition {
  134. ecMap := make(map[string]models.EventCondition, len(p))
  135. for _, param := range p {
  136. element, ok := ecMap[param.Key]
  137. if !ok {
  138. element = models.EventCondition{}
  139. }
  140. switch param.Operator {
  141. case "<":
  142. element.LT = param.Value
  143. case "<=":
  144. element.LTE = param.Value
  145. case ">=":
  146. element.GTE = param.Value
  147. case ">":
  148. element.GT = param.Value
  149. default:
  150. element.EQ = param.Value
  151. }
  152. ecMap[param.Key] = element
  153. }
  154. return ecMap
  155. }
  156. type Command struct {
  157. Name string
  158. Params Params
  159. }
  160. func parseCommand(args []string) Command {
  161. if len(args) == 0 {
  162. return Command{Name: "help"}
  163. }
  164. cmd := Command{
  165. Name: args[0],
  166. Params: make(Params, 0, len(args)-1),
  167. }
  168. nextIndex := 0
  169. for _, arg := range args[1:] {
  170. kvle := strings.SplitN(arg, "<=", 2)
  171. kvge := strings.SplitN(arg, ">=", 2)
  172. kvl := strings.SplitN(arg, "<", 2)
  173. kvg := strings.SplitN(arg, ">", 2)
  174. kve := strings.SplitN(arg, "=", 2)
  175. if len(kvle) == 2 {
  176. cmd.Params = append(cmd.Params, Param{Index: -1, Key: kvle[0], Value: kvle[1], Operator: "<="})
  177. } else if len(kvge) == 2 {
  178. cmd.Params = append(cmd.Params, Param{Index: -1, Key: kvge[0], Value: kvge[1], Operator: ">="})
  179. } else if len(kvl) == 2 {
  180. cmd.Params = append(cmd.Params, Param{Index: -1, Key: kvl[0], Value: kvl[1], Operator: "<"})
  181. } else if len(kvg) == 2 {
  182. cmd.Params = append(cmd.Params, Param{Index: -1, Key: kvg[0], Value: kvg[1], Operator: ">"})
  183. } else if len(kve) == 2 {
  184. cmd.Params = append(cmd.Params, Param{Index: -1, Key: kve[0], Value: kve[1], Operator: "="})
  185. } else {
  186. cmd.Params = append(cmd.Params, Param{Index: nextIndex, Value: arg})
  187. nextIndex += 1
  188. }
  189. }
  190. return cmd
  191. }
  192. func (cmd Command) NewDeviceState(prefix string) models.NewDeviceState {
  193. return models.NewDeviceState{
  194. Power: cmd.Params.Get(prefix + "power").Bool(),
  195. Color: cmd.Params.Get(prefix + "color").String(),
  196. Intensity: cmd.Params.Get(prefix + "intensity").Float(),
  197. Temperature: cmd.Params.Get(prefix + "temperature").Int(),
  198. }
  199. }