123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- package productconfig
- import (
- "encoding/json"
- "errors"
- "fmt"
- "sparrow/pkg/protocol"
- "sparrow/pkg/tlv"
- )
- // CommandOrEventParam command or a event param struct
- type CommandOrEventParam struct {
- ValueType int32 `json:"value_type"`
- Name string
- }
- // ProductCommandOrEvent ``
- type ProductCommandOrEvent struct {
- No int
- Part int
- Name string
- Priority int
- Params []CommandOrEventParam
- }
- // StatusParam 上报类型的参数
- type StatusParam struct {
- ValueType int32 `json:"value_type"`
- Name string `json:"name"`
- ID uint `json:"pid"` //protocal id 与后台对应
- }
- // ProductObject 产品对象
- type ProductObject struct {
- Id int
- No int
- Label string
- Part int
- Status []StatusParam
- }
- // ProductConfig product config parses the JSON product config string.
- type ProductConfig struct {
- Objects []ProductObject `json:"objects"`
- Commands []ProductCommandOrEvent `json:"commands"`
- Events []ProductCommandOrEvent `json:"events"`
- }
- // New create a new productConfig
- func New(config string) (*ProductConfig, error) {
- v := &ProductConfig{}
- err := json.Unmarshal([]byte(config), v)
- if err != nil {
- return nil, err
- }
- return v, nil
- }
- // ValidateStatus validate the status
- func (config *ProductConfig) ValidateStatus(label string, params []interface{}) (*ProductObject, []interface{}, error) {
- // search for status name
- var paramInfo []StatusParam
- var status *ProductObject
- found := false
- for _, obj := range config.Objects {
- if obj.Label == label {
- paramInfo = obj.Status
- status = &obj
- found = true
- break
- }
- }
- if found == false {
- return nil, []interface{}{}, errors.New("object not found.")
- }
- if len(paramInfo) != len(params) {
- return nil, []interface{}{}, errors.New("wrong status parameters.")
- }
- realParams := make([]interface{}, len(params))
- for idx, para := range paramInfo {
- realParams[idx] = tlv.CastTLV(params[idx], para.ValueType)
- }
- return status, realParams, nil
- }
- // ValidateCommandOrEvent validate command or event
- func (config *ProductConfig) ValidateCommandOrEvent(name string, params []interface{}, typ string) (*ProductCommandOrEvent, []interface{}, error) {
- var target []ProductCommandOrEvent
- if typ == "command" {
- target = config.Commands
- } else if typ == "event" {
- target = config.Events
- } else {
- return nil, []interface{}{}, errors.New("wrong target type.")
- }
- // search for name
- var paramInfo []CommandOrEventParam
- var coe *ProductCommandOrEvent
- found := false
- for _, one := range target {
- if one.Name == name {
- paramInfo = one.Params
- coe = &one
- found = true
- break
- }
- }
- if found == false {
- return nil, []interface{}{}, errors.New("command or event not found.")
- }
- if len(paramInfo) != len(params) {
- return nil, []interface{}{}, errors.New("wrong parameters.")
- }
- realParams := make([]interface{}, len(params))
- for idx, para := range paramInfo {
- realParams[idx] = tlv.CastTLV(params[idx], para.ValueType)
- }
- return coe, realParams, nil
- }
- // StatusToMap struct to map
- func (config *ProductConfig) StatusToMap(status []protocol.SubData) (map[string]interface{}, error) {
- result := make(map[string]interface{})
- for _, sub := range status {
- val, err := tlv.ReadTLVs(sub.Params)
- if err != nil {
- return nil, err
- }
- label := ""
- values := make(map[string]interface{})
- for _, obj := range config.Objects {
- if obj.No == int(sub.Head.PropertyNum) {
- label = obj.Label
- for k, v := range obj.Status {
- values[v.Name] = val[k]
- }
- }
- }
- result[label] = values
- result["sub_device_id"] = sub.Head.SubDeviceid
- }
- return result, nil
- }
- // EventToMap event ot map
- func (config *ProductConfig) EventToMap(event *protocol.Event) (map[string]interface{}, error) {
- result := make(map[string]interface{})
- val, err := tlv.ReadTLVs(event.Params)
- if err != nil {
- return nil, err
- }
- label := ""
- values := make(map[string]interface{})
- for _, obj := range config.Events {
- if obj.No == int(event.Head.No) {
- label = obj.Name
- for k, v := range obj.Params {
- values[v.Name] = val[k]
- }
- }
- }
- result[label] = values
- result["device_id"] = event.Head.SubDeviceid
- return result, nil
- }
- // MapToStatus map to status
- func (config *ProductConfig) MapToStatus(data map[string]interface{}) ([]protocol.SubData, error) {
- var result []protocol.SubData
- for label, one := range data {
- params, ok := one.([]interface{})
- if !ok {
- return nil, fmt.Errorf("status format error: %v", one)
- }
- obj, realParams, err := config.ValidateStatus(label, params)
- if err != nil {
- return nil, err
- }
- tlvs, err := tlv.MakeTLVs(realParams)
- if err != nil {
- return nil, err
- }
- result = append(result, protocol.SubData{
- Head: protocol.SubDataHead{
- SubDeviceid: uint16(obj.Part),
- PropertyNum: uint16(obj.No),
- ParamsCount: uint16(len(realParams)),
- },
- Params: tlvs,
- })
- }
- return result, nil
- }
- func (config *ProductConfig) MapToCommand(cmd map[string]interface{}) (*protocol.Command, error) {
- result := &protocol.Command{}
- for name, one := range cmd {
- params, ok := one.([]interface{})
- if !ok {
- return nil, fmt.Errorf("command format error: %v", one)
- }
- c, realParams, err := config.ValidateCommandOrEvent(name, params, "command")
- if err != nil {
- return nil, err
- }
- tlvs, err := tlv.MakeTLVs(realParams)
- if err != nil {
- return nil, err
- }
- result.Head.No = uint16(c.No)
- result.Head.Priority = uint16(c.Priority)
- result.Head.SubDeviceid = uint16(c.Part)
- result.Head.ParamsCount = uint16(len(realParams))
- result.Params = tlvs
- }
- return result, nil
- }
|