package device import ( "fmt" "src.dualinventive.com/go/dinet/rpc" ) // FieldInfo contains the information about a specific device class field type FieldInfo struct { // Label is the class with the RPC label of the field Label string // Type is the RPC type of the field Type string } // Parse converts a interface value to influxdb fields with valid datatypes according to the RPC func (c *FieldInfo) Parse(val *rpc.ResultValueItem) (map[string]interface{}, error) { // We support a limit number of RPC types switch c.Type { case "enum": return c.parseEnum(val) case "number": return c.parseNumber(val) case "bool": return c.parseBool(val) case "gps": return c.parseGPS(val) case "struct": return c.parseStruct(val) default: return nil, ErrInvalidType } } // parseEnum parses the interface value to an influxdb field with as key the label and as value an integer func (c *FieldInfo) parseEnum(rvi *rpc.ResultValueItem) (map[string]interface{}, error) { var val int err := rvi.GetValue(&val) if err != nil { return nil, ErrInvalidType } return map[string]interface{}{c.Label: val}, nil } // parseNumber parses the interface value to an influxdb field with as key the label and as value an float64 func (c *FieldInfo) parseNumber(rvi *rpc.ResultValueItem) (map[string]interface{}, error) { var val float64 err := rvi.GetValue(&val) if err != nil { return nil, ErrInvalidType } return map[string]interface{}{c.Label: val}, nil } // parseBool parses the interface value to an influxdb field with as key the label and as value an boolean func (c *FieldInfo) parseBool(rvi *rpc.ResultValueItem) (map[string]interface{}, error) { var val bool err := rvi.GetValue(&val) if err != nil { return nil, ErrInvalidType } return map[string]interface{}{c.Label: val}, nil } // parseGPS parses the interface value to multiple influxdb fields with as key the GPS keys and as value the GPS values func (c *FieldInfo) parseGPS(rvi *rpc.ResultValueItem) (map[string]interface{}, error) { var val rpc.GPSSensorData err := rvi.GetValue(&val) if err != nil { return nil, ErrInvalidType } return map[string]interface{}{ c.Label + "_hdop": val.HDOP, c.Label + "_latitude": val.Latitude, c.Label + "_longitude": val.Longitude, }, nil } func (c *FieldInfo) parseStruct(rvi *rpc.ResultValueItem) (map[string]interface{}, error) { var val map[string]interface{} err := rvi.GetValue(&val) if err != nil { return nil, ErrInvalidType } r := make(map[string]interface{}, len(val)) for k, v := range val { r[fmt.Sprintf("%s_%s", c.Label, k)] = v } return r, nil }