telegraf/plugins/parsers/phasor_binary/parser_test.go

169 lines
3.8 KiB
Go

package binary_phasor
import (
"encoding/binary"
"errors"
"math"
"strconv"
"strings"
"testing"
"time"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/metric"
"github.com/influxdata/telegraf/testutil"
)
func generatePhasorBinary(iou byte, pf int, ts uint32) ([]byte, error) {
var data []byte
var chanNum byte
switch iou {
case 1:
data = make([]byte, 0, 11306)
chanNum = 14
case 2:
data = make([]byte, 0, 14106)
chanNum = 15
default:
return nil, errors.New("not supported type")
}
data = binary.LittleEndian.AppendUint32(data, ts)
data = append(data, iou)
data = append(data, chanNum)
for i := range 8 {
for range pf {
data = binary.LittleEndian.AppendUint64(data, math.Float64bits(float64(i)))
data = binary.LittleEndian.AppendUint64(data, math.Float64bits(float64(i)))
data = binary.LittleEndian.AppendUint64(data, math.Float64bits(float64(i)))
}
}
for range pf {
data = append(data, 0xAA) // like 1010 1010
}
for range pf {
data = append(data, 0x55) // like 0101 0101
}
switch iou {
case 1:
for i := range 4 {
for range pf {
data = binary.LittleEndian.AppendUint64(data, math.Float64bits(float64(i+8)))
}
}
case 2:
for i := range 2 {
for range pf {
data = binary.LittleEndian.AppendUint64(data, math.Float64bits(float64(i+8)))
}
}
for i := range 3 {
for range pf {
data = binary.LittleEndian.AppendUint64(data, math.Float64bits(float64(i+10)))
data = binary.LittleEndian.AppendUint64(data, math.Float64bits(float64(i+10)))
data = binary.LittleEndian.AppendUint64(data, math.Float64bits(float64(i+10)))
}
}
default:
return nil, errors.New("not supported type")
}
return data, nil
}
func generateExpectedMetrics(device string, iou byte, pf int, ts uint32) ([]telegraf.Metric, error) {
metrics := make([]telegraf.Metric, pf)
var fields map[string]interface{}
measurement := ""
switch iou {
case 1:
measurement = "current"
fields = make(map[string]interface{}, 44)
case 2:
measurement = "voltage"
fields = make(map[string]interface{}, 51)
default:
return nil, errors.New("not supported type")
}
for i := range metrics {
m := metric.New(
measurement,
map[string]string{"device": device},
fields,
time.Unix(int64(ts), int64(i*1e9/pf)),
)
for cj := range 8 {
chanNo := strconv.Itoa(cj + 1)
m.AddField("c"+chanNo+"_amp", float64(cj))
m.AddField("c"+chanNo+"_pa", float64(cj))
m.AddField("c"+chanNo+"_rms", float64(cj))
}
for cj := range 8 {
chanNo := strconv.Itoa(cj + 1)
m.AddField("i"+chanNo, uint8((1+math.Pow(-1, float64(cj+1)))/2))
}
for cj := range 8 {
chanNo := strconv.Itoa(cj + 1 + 8)
m.AddField("i"+chanNo, uint8((1+math.Pow(-1, float64(cj)))/2))
}
switch iou {
case 1:
for cj, channel := range []string{"p", "q", "s", "pf"} {
m.AddField(channel, float64(cj+8))
}
case 2:
for cj, channel := range []string{"f", "df"} {
m.AddField(channel, float64(cj+8))
}
for cj, channel := range []string{"uab", "ubc", "uca"} {
m.AddField(channel+"_amp", float64(cj+10))
m.AddField(channel+"_pa", float64(cj+10))
m.AddField(channel+"_rms", float64(cj+10))
}
default:
return nil, errors.New("not supported type")
}
metrics[i] = m
}
return metrics, nil
}
func TestParse(t *testing.T) {
topic := "ssu001_Phasor"
device, _ := strings.CutSuffix(topic, "_Phasor")
for iou := range 2 {
ts := uint32(time.Now().Unix())
data, err := generatePhasorBinary(byte(iou+1), 50, ts)
if err != nil {
t.FailNow()
}
expected, err := generateExpectedMetrics(device, byte(iou+1), 50, ts)
if err != nil {
t.FailNow()
}
parser := new(Parser)
parser.Init()
actual, err := parser.Parse(data, topic)
if err != nil {
t.FailNow()
}
testutil.RequireMetricsEqual(t, expected, actual, testutil.IgnoreTime(), testutil.SortMetrics())
}
}