src.dualinventive.com/go/influxdb-logger/internal/device/fieldinfo.go

98 lines
2.6 KiB
Go

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
}