118 lines
2.9 KiB
Go
118 lines
2.9 KiB
Go
|
//go:generate ../../../tools/readme_config_includer/generator
|
||
|
package apcupsd
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
_ "embed"
|
||
|
"net/url"
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
"time"
|
||
|
|
||
|
"github.com/mdlayher/apcupsd"
|
||
|
|
||
|
"github.com/influxdata/telegraf"
|
||
|
"github.com/influxdata/telegraf/config"
|
||
|
"github.com/influxdata/telegraf/plugins/inputs"
|
||
|
)
|
||
|
|
||
|
//go:embed sample.conf
|
||
|
var sampleConfig string
|
||
|
|
||
|
const defaultAddress = "tcp://127.0.0.1:3551"
|
||
|
|
||
|
var defaultTimeout = config.Duration(5 * time.Second)
|
||
|
|
||
|
type ApcUpsd struct {
|
||
|
Servers []string
|
||
|
Timeout config.Duration
|
||
|
}
|
||
|
|
||
|
func (*ApcUpsd) SampleConfig() string {
|
||
|
return sampleConfig
|
||
|
}
|
||
|
|
||
|
func (h *ApcUpsd) Gather(acc telegraf.Accumulator) error {
|
||
|
ctx := context.Background()
|
||
|
|
||
|
for _, server := range h.Servers {
|
||
|
err := func(address string) error {
|
||
|
addrBits, err := url.Parse(address)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
if addrBits.Scheme == "" {
|
||
|
addrBits.Scheme = "tcp"
|
||
|
}
|
||
|
|
||
|
ctx, cancel := context.WithTimeout(ctx, time.Duration(h.Timeout))
|
||
|
defer cancel()
|
||
|
|
||
|
status, err := fetchStatus(ctx, addrBits)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
tags := map[string]string{
|
||
|
"serial": status.SerialNumber,
|
||
|
"ups_name": status.UPSName,
|
||
|
"status": status.Status,
|
||
|
"model": status.Model,
|
||
|
}
|
||
|
|
||
|
flags, err := strconv.ParseUint(strings.Fields(status.StatusFlags)[0], 0, 64)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
fields := map[string]interface{}{
|
||
|
"status_flags": flags,
|
||
|
"input_voltage": status.LineVoltage,
|
||
|
"load_percent": status.LoadPercent,
|
||
|
"battery_charge_percent": status.BatteryChargePercent,
|
||
|
"time_left_ns": status.TimeLeft.Nanoseconds(),
|
||
|
"output_voltage": status.OutputVoltage,
|
||
|
"internal_temp": status.InternalTemp,
|
||
|
"battery_voltage": status.BatteryVoltage,
|
||
|
"input_frequency": status.LineFrequency,
|
||
|
"time_on_battery_ns": status.TimeOnBattery.Nanoseconds(),
|
||
|
"cumulative_time_on_battery_ns": status.CumulativeTimeOnBattery.Nanoseconds(),
|
||
|
"nominal_input_voltage": status.NominalInputVoltage,
|
||
|
"nominal_battery_voltage": status.NominalBatteryVoltage,
|
||
|
"nominal_power": status.NominalPower,
|
||
|
"firmware": status.Firmware,
|
||
|
"battery_date": status.BatteryDate,
|
||
|
"last_transfer": status.LastTransfer,
|
||
|
"number_transfers": status.NumberTransfers,
|
||
|
}
|
||
|
|
||
|
acc.AddFields("apcupsd", fields, tags)
|
||
|
return nil
|
||
|
}(server)
|
||
|
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func fetchStatus(ctx context.Context, addr *url.URL) (*apcupsd.Status, error) {
|
||
|
client, err := apcupsd.DialContext(ctx, addr.Scheme, addr.Host)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
defer client.Close()
|
||
|
|
||
|
return client.Status()
|
||
|
}
|
||
|
|
||
|
func init() {
|
||
|
inputs.Add("apcupsd", func() telegraf.Input {
|
||
|
return &ApcUpsd{
|
||
|
Servers: []string{defaultAddress},
|
||
|
Timeout: defaultTimeout,
|
||
|
}
|
||
|
})
|
||
|
}
|