| 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["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
 
- }
 
 
  |