productconfig.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. package productconfig
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "sparrow/pkg/protocol"
  7. "sparrow/pkg/tlv"
  8. )
  9. type CommandOrEventParam struct {
  10. ValueType int32 `json:"value_type"`
  11. Name string
  12. }
  13. type ProductCommandOrEvent struct {
  14. No int
  15. Part int
  16. Name string
  17. Priority int
  18. Params []CommandOrEventParam
  19. }
  20. type StatusParam struct {
  21. ValueType int32 `json:"value_type"`
  22. Name string
  23. }
  24. type ProductObject struct {
  25. Id int
  26. No int
  27. Label string
  28. Part int
  29. Status []StatusParam
  30. }
  31. // product config parses the JSON product config string.
  32. type ProductConfig struct {
  33. Objects []ProductObject
  34. Commands []ProductCommandOrEvent
  35. Events []ProductCommandOrEvent
  36. }
  37. func New(config string) (*ProductConfig, error) {
  38. v := &ProductConfig{}
  39. err := json.Unmarshal([]byte(config), v)
  40. if err != nil {
  41. return nil, err
  42. }
  43. return v, nil
  44. }
  45. func (config *ProductConfig) ValidateStatus(label string, params []interface{}) (*ProductObject, []interface{}, error) {
  46. // search for status name
  47. var paramInfo []StatusParam
  48. var status *ProductObject
  49. found := false
  50. for _, obj := range config.Objects {
  51. if obj.Label == label {
  52. paramInfo = obj.Status
  53. status = &obj
  54. found = true
  55. break
  56. }
  57. }
  58. if found == false {
  59. return nil, []interface{}{}, errors.New("object not found.")
  60. }
  61. if len(paramInfo) != len(params) {
  62. return nil, []interface{}{}, errors.New("wrong status parameters.")
  63. }
  64. realParams := make([]interface{}, len(params))
  65. for idx, para := range paramInfo {
  66. realParams[idx] = tlv.CastTLV(params[idx], para.ValueType)
  67. }
  68. return status, realParams, nil
  69. }
  70. func (config *ProductConfig) ValidateCommandOrEvent(name string, params []interface{}, typ string) (*ProductCommandOrEvent, []interface{}, error) {
  71. var target []ProductCommandOrEvent
  72. if typ == "command" {
  73. target = config.Commands
  74. } else if typ == "event" {
  75. target = config.Events
  76. } else {
  77. return nil, []interface{}{}, errors.New("wrong target type.")
  78. }
  79. // search for name
  80. var paramInfo []CommandOrEventParam
  81. var coe *ProductCommandOrEvent
  82. found := false
  83. for _, one := range target {
  84. if one.Name == name {
  85. paramInfo = one.Params
  86. coe = &one
  87. found = true
  88. break
  89. }
  90. }
  91. if found == false {
  92. return nil, []interface{}{}, errors.New("command or event not found.")
  93. }
  94. if len(paramInfo) != len(params) {
  95. return nil, []interface{}{}, errors.New("wrong parameters.")
  96. }
  97. realParams := make([]interface{}, len(params))
  98. for idx, para := range paramInfo {
  99. realParams[idx] = tlv.CastTLV(params[idx], para.ValueType)
  100. }
  101. return coe, realParams, nil
  102. }
  103. func (config *ProductConfig) StatusToMap(status []protocol.SubData) (map[string][]interface{}, error) {
  104. result := make(map[string][]interface{})
  105. for _, sub := range status {
  106. val, err := tlv.ReadTLVs(sub.Params)
  107. if err != nil {
  108. return nil, err
  109. }
  110. label := ""
  111. for _, obj := range config.Objects {
  112. if obj.No == int(sub.Head.PropertyNum) {
  113. label = obj.Label
  114. }
  115. }
  116. result[label] = val
  117. }
  118. return result, nil
  119. }
  120. func (config *ProductConfig) EventToMap(event *protocol.Event) (map[string][]interface{}, error) {
  121. result := make(map[string][]interface{})
  122. name := ""
  123. for _, ev := range config.Events {
  124. if ev.No == int(event.Head.No) {
  125. name = ev.Name
  126. }
  127. }
  128. val, err := tlv.ReadTLVs(event.Params)
  129. if err != nil {
  130. return nil, err
  131. }
  132. result[name] = val
  133. return result, nil
  134. }
  135. func (config *ProductConfig) MapToStatus(data map[string]interface{}) ([]protocol.SubData, error) {
  136. result := []protocol.SubData{}
  137. for label, one := range data {
  138. params, ok := one.([]interface{})
  139. if !ok {
  140. return nil, fmt.Errorf("status format error: %v", one)
  141. }
  142. obj, realParams, err := config.ValidateStatus(label, params)
  143. if err != nil {
  144. return nil, err
  145. }
  146. tlvs, err := tlv.MakeTLVs(realParams)
  147. if err != nil {
  148. return nil, err
  149. }
  150. result = append(result, protocol.SubData{
  151. Head: protocol.SubDataHead{
  152. SubDeviceid: uint16(obj.Part),
  153. PropertyNum: uint16(obj.No),
  154. ParamsCount: uint16(len(realParams)),
  155. },
  156. Params: tlvs,
  157. })
  158. }
  159. return result, nil
  160. }
  161. func (config *ProductConfig) MapToCommand(cmd map[string]interface{}) (*protocol.Command, error) {
  162. result := &protocol.Command{}
  163. for name, one := range cmd {
  164. params, ok := one.([]interface{})
  165. if !ok {
  166. return nil, fmt.Errorf("command format error: %v", one)
  167. }
  168. c, realParams, err := config.ValidateCommandOrEvent(name, params, "command")
  169. if err != nil {
  170. return nil, err
  171. }
  172. tlvs, err := tlv.MakeTLVs(realParams)
  173. if err != nil {
  174. return nil, err
  175. }
  176. result.Head.No = uint16(c.No)
  177. result.Head.Priority = uint16(c.Priority)
  178. result.Head.SubDeviceid = uint16(c.Part)
  179. result.Head.ParamsCount = uint16(len(realParams))
  180. result.Params = tlvs
  181. }
  182. return result, nil
  183. }