Support power calculation and CSV header line.
If --header is specified, then a header line is generated for the CSV
output.
If --resistance is set to a positive number (should be the shunt
resistance for the zedmon unit), then power is calculated and included
in the output.
Change-Id: Id84cf6d38e7d90e3eab02046ffaa1a4ce24af703
diff --git a/cmd/zedmon/record.go b/cmd/zedmon/record.go
index bc383b6..df3f51e 100644
--- a/cmd/zedmon/record.go
+++ b/cmd/zedmon/record.go
@@ -43,7 +43,10 @@
type recordCmd struct{}
+// Flag-controlled values.
var out string
+var writeHeader bool
+var resistance float64
func (*recordCmd) Name() string { return "record" }
func (*recordCmd) Synopsis() string {
@@ -57,6 +60,34 @@
func (*recordCmd) SetFlags(flags *flag.FlagSet) {
setCommonFlags(flags)
flags.StringVar(&out, "out", "zedmon.csv", "Output file. Specify \"-\" for stdout.")
+ flags.BoolVar(&writeHeader, "header", false, "Whether to include a header line in the output.")
+ flags.Float64Var(&resistance, "resistance", -1.0,
+ "Shunt resistance in Ohms. If set to a positive value, power will be included in the output.")
+}
+
+// If a positive resistance and field names including "v_bus" and "v_shunt" are provided, returns a
+// function that calculates power from zedmon-provided values. Returns nil otherwise.
+func getPowerCalculator(resistance float64, fieldNames []string) func(values []float64) float64 {
+ if resistance <= 0.0 {
+ return nil
+ }
+
+ vBusIndex := -1
+ vShuntIndex := -1
+ for i, name := range fieldNames {
+ if name == "v_bus" {
+ vBusIndex = i
+ } else if name == "v_shunt" {
+ vShuntIndex = i
+ }
+ }
+ if vBusIndex < 0 || vShuntIndex < 0 {
+ return nil
+ }
+
+ return func(values []float64) float64 {
+ return values[vShuntIndex] * values[vBusIndex] / resistance
+ }
}
func (*recordCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
@@ -95,6 +126,20 @@
log.Println("Starting report recording. Send ^C to stop.")
zedmon.EnableReporting()
+ fieldNames := zedmon.GetFieldNames()
+
+ calculatePower := getPowerCalculator(resistance, fieldNames)
+ if calculatePower != nil {
+ fieldNames = append(fieldNames, "power")
+ }
+
+ if writeHeader {
+ header := make([]string, 1+len(fieldNames))
+ header[0] = "timestamp"
+ copy(header[1:], fieldNames)
+ writer.Write(header)
+ }
+
RecordSampling:
for {
reports, err := zedmon.ReadReports()
@@ -103,11 +148,15 @@
continue
}
for _, report := range reports {
- record := make([]string, 0, len(report.Values))
+ record := make([]string, 0, len(fieldNames))
record = append(record, strconv.FormatUint(report.Timestamp, 10))
for _, value := range report.Values {
record = append(record, strconv.FormatFloat(value, 'g', -1, 64))
}
+ if calculatePower != nil {
+ power := calculatePower(report.Values)
+ record = append(record, strconv.FormatFloat(power, 'g', -1, 64))
+ }
writer.Write(record)
}
diff --git a/lib/zedmon.go b/lib/zedmon.go
index cf68a17..c429a62 100644
--- a/lib/zedmon.go
+++ b/lib/zedmon.go
@@ -72,6 +72,16 @@
fields []*Field
}
+func (z *Zedmon) GetFieldNames() []string {
+ names := make([]string, len(z.fields))
+
+ for i, field := range z.fields {
+ names[i] = field.Name
+ }
+
+ return names
+}
+
func (z *Zedmon) Close() {
if z.reportingEnabled {
z.DisableReporting()