Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions plugins/inputs/upsd/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@ plugin ordering. See [CONFIGURATION.md][CONFIGURATION.md] for more details.
## parsed as integers and others as floats.
# force_float = false

## Force vendor/product IDs to always be emitted as strings to avoid type
## conflicts between UPS devices with numeric-looking IDs (e.g. "0764",
## auto-converted to int64 by the NUT client library) and UPS devices with
## non-numeric IDs (e.g. "ABCD"). Affected fields: ups_vendorid, ups_productid,
## driver_parameter_vendorid, driver_parameter_productid.
## Note: leading zeros are lost on the wire (e.g. "0764" becomes "764").
## If left unset, a warning is logged. The default will change to true in a
## future release.
# stringify_ids = false

## Collect additional fields if they are available for the UPS
## The fields need to be specified as NUT variable names, see
## https://networkupstools.org/docs/developer-guide.chunked/apas02.html
Expand Down Expand Up @@ -71,6 +81,24 @@ Alternatively, you can also map the non-binary value to a `boolean`.

[enum_processor]: /plugins/processors/enum/README.md

### Vendor/Product ID types (`stringify_ids`)

The underlying NUT client library (`go.nut`) auto-detects numeric-looking values
and converts them to `int64`. This means a `vendorid` like `"0764"` becomes
`int64(764)` while a non-numeric `vendorid` like `"ABCD"` stays a string. When
multiple UPS devices of different vendors write to the same InfluxDB bucket,
this causes field type conflicts on `ups_vendorid`, `ups_productid`,
`driver_parameter_vendorid` and `driver_parameter_productid`.

Set `stringify_ids = true` to force these four fields to always be emitted as
strings. The default is currently `false` to preserve backwards-compatible
behavior, but will flip to `true` in a future release. If the option is left
unset, a warning is logged on startup.

> **Note:** the NUT library parses `"0764"` into `int64(764)` before Telegraf
Comment thread
skartikey marked this conversation as resolved.
Outdated
> sees it, so the stringified value will be `"764"` — leading zeros are lost
Comment thread
skartikey marked this conversation as resolved.
Outdated
> and cannot be recovered at this layer.

## Metrics

This implementation tries to maintain compatibility with the apcupsd metrics:
Expand Down
10 changes: 10 additions & 0 deletions plugins/inputs/upsd/sample.conf
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@
## parsed as integers and others as floats.
# force_float = false

## Force vendor/product IDs to always be emitted as strings to avoid type
## conflicts between UPS devices with numeric-looking IDs (e.g. "0764",
## auto-converted to int64 by the NUT client library) and UPS devices with
## non-numeric IDs (e.g. "ABCD"). Affected fields: ups_vendorid, ups_productid,
## driver_parameter_vendorid, driver_parameter_productid.
## Note: leading zeros are lost on the wire (e.g. "0764" becomes "764").
## If left unset, a warning is logged. The default will change to true in a
## future release.
# stringify_ids = false
Comment thread
skartikey marked this conversation as resolved.
Outdated

## Collect additional fields if they are available for the UPS
## The fields need to be specified as NUT variable names, see
## https://networkupstools.org/docs/developer-guide.chunked/apas02.html
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
upsd,model=CP900EPFCLCD,serial=0,status_OL=true,ups_name=fake battery_charge_low=10i,battery_charge_percent=100i,battery_charge_warning=20i,battery_mfr_date="CPS",battery_runtime=4020i,battery_runtime_low=300i,battery_type="PbAcid",battery_voltage=24,device_mfr="CPS",device_model="CP900EPFCLCD",device_serial=0i,device_type="ups",driver_debug=0i,driver_flag_allow_killpower=0i,driver_name="usbhid-ups",driver_parameter_pollfreq=30i,driver_parameter_pollinterval=2i,driver_parameter_port="auto",driver_parameter_product="CP900EPFCLCD",driver_parameter_productid="ABCD",driver_parameter_serial=0i,driver_parameter_synchronous="auto",driver_parameter_vendor="CPS",driver_parameter_vendorid="EFGH",driver_state="quiet",driver_version="2.8.1",driver_version_data="CyberPower HID 0.8",driver_version_internal=0.52,driver_version_usb="libusb-1.0.26 (API: 0x1000109)",firmware="",input_transfer_high=260i,input_transfer_low=170i,input_voltage=228,load_percent=13i,nominal_battery_voltage=24i,nominal_input_voltage=230i,nominal_power=540i,output_voltage=228,status_flags=8u,time_left_ns=4020000000000i,ups_beeper_status=true,ups_delay_shutdown=20i,ups_delay_start=30i,ups_mfr="CPS",ups_model="CP900EPFCLCD",ups_productid="WXYZ",ups_serial=0i,ups_status="OL",ups_test_result="No test initiated",ups_timer_shutdown=-60i,ups_timer_start=-60i,ups_vendorid="IJKL"
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[[inputs.upsd]]
additional_fields = ["*"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
battery.charge: NUMBER
battery.charge.low: STRING
battery.charge.warning: NUMBER
battery.mfr.date: NUMBER
battery.runtime: NUMBER
battery.runtime.low: STRING
battery.type: NUMBER
battery.voltage: NUMBER
battery.voltage.nominal: NUMBER
device.mfr: NUMBER
device.model: NUMBER
device.serial: NUMBER
device.type: NUMBER
driver.debug: NUMBER
driver.flag.allow_killpower: NUMBER
driver.name: NUMBER
driver.parameter.pollfreq: NUMBER
driver.parameter.pollinterval: NUMBER
driver.parameter.port: NUMBER
driver.parameter.product: NUMBER
driver.parameter.productid: NUMBER
driver.parameter.serial: NUMBER
driver.parameter.synchronous: NUMBER
driver.parameter.vendor: NUMBER
driver.parameter.vendorid: NUMBER
driver.state: NUMBER
driver.version:
Comment thread
skartikey marked this conversation as resolved.
Outdated
driver.version.data: NUMBER
driver.version.internal: NUMBER
driver.version.usb: NUMBER
input.transfer.high: STRING
input.transfer.low: STRING
input.voltage: NUMBER
input.voltage.nominal: NUMBER
output.voltage: NUMBER
ups.beeper.status: NUMBER
ups.delay.shutdown: STRING
ups.delay.start: STRING
ups.load: NUMBER
ups.mfr: NUMBER
ups.model: NUMBER
ups.productid: NUMBER
ups.realpower.nominal: NUMBER
ups.serial: NUMBER
ups.status: NUMBER
ups.test.result: NUMBER
ups.timer.shutdown: NUMBER
ups.timer.start: NUMBER
ups.vendorid: NUMBER
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
battery.charge: 100
battery.charge.low: 10
battery.charge.warning: 20
battery.mfr.date: CPS
battery.runtime: 4020
battery.runtime.low: 300
battery.type: PbAcid
battery.voltage: 24.0
battery.voltage.nominal: 24
device.mfr: CPS
device.model: CP900EPFCLCD
device.serial: 000000000000
device.type: ups
driver.debug: 0
driver.flag.allow_killpower: 0
driver.name: usbhid-ups
driver.parameter.pollfreq: 30
driver.parameter.pollinterval: 2
driver.parameter.port: auto
driver.parameter.product: CP900EPFCLCD
driver.parameter.productid: ABCD
driver.parameter.serial: 000000000000
driver.parameter.synchronous: auto
driver.parameter.vendor: CPS
driver.parameter.vendorid: EFGH
driver.state: quiet
driver.version: 2.8.1
driver.version.data: CyberPower HID 0.8
driver.version.internal: 0.52
driver.version.usb: libusb-1.0.26 (API: 0x1000109)
input.transfer.high: 260
input.transfer.low: 170
input.voltage: 228.0
input.voltage.nominal: 230
output.voltage: 228.0
ups.beeper.status: enabled
ups.delay.shutdown: 20
ups.delay.start: 30
ups.load: 13
ups.mfr: CPS
ups.model: CP900EPFCLCD
ups.productid: WXYZ
ups.realpower.nominal: 540
ups.serial: 000000000000
ups.status: OL
ups.test.result: No test initiated
ups.timer.shutdown: -60
ups.timer.start: -60
ups.vendorid: IJKL
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
upsd,model=CP900EPFCLCD,serial=0,status_OL=true,ups_name=fake battery_charge_low=10i,battery_charge_percent=100i,battery_charge_warning=20i,battery_mfr_date="CPS",battery_runtime=4020i,battery_runtime_low=300i,battery_type="PbAcid",battery_voltage=24,device_mfr="CPS",device_model="CP900EPFCLCD",device_serial=0i,device_type="ups",driver_debug=0i,driver_flag_allow_killpower=0i,driver_name="usbhid-ups",driver_parameter_pollfreq=30i,driver_parameter_pollinterval=2i,driver_parameter_port="auto",driver_parameter_product="CP900EPFCLCD",driver_parameter_productid="501",driver_parameter_serial=0i,driver_parameter_synchronous="auto",driver_parameter_vendor="CPS",driver_parameter_vendorid="764",driver_state="quiet",driver_version="2.8.1",driver_version_data="CyberPower HID 0.8",driver_version_internal=0.52,driver_version_usb="libusb-1.0.26 (API: 0x1000109)",firmware="",input_transfer_high=260i,input_transfer_low=170i,input_voltage=228,load_percent=13i,nominal_battery_voltage=24i,nominal_input_voltage=230i,nominal_power=540i,output_voltage=228,status_flags=8u,time_left_ns=4020000000000i,ups_beeper_status=true,ups_delay_shutdown=20i,ups_delay_start=30i,ups_mfr="CPS",ups_model="CP900EPFCLCD",ups_productid="501",ups_serial=0i,ups_status="OL",ups_test_result="No test initiated",ups_timer_shutdown=-60i,ups_timer_start=-60i,ups_vendorid="764"
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[[inputs.upsd]]
additional_fields = ["*"]
stringify_ids = true
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
battery.charge: NUMBER
battery.charge.low: STRING
battery.charge.warning: NUMBER
battery.mfr.date: NUMBER
battery.runtime: NUMBER
battery.runtime.low: STRING
battery.type: NUMBER
battery.voltage: NUMBER
battery.voltage.nominal: NUMBER
device.mfr: NUMBER
device.model: NUMBER
device.serial: NUMBER
device.type: NUMBER
driver.debug: NUMBER
driver.flag.allow_killpower: NUMBER
driver.name: NUMBER
driver.parameter.pollfreq: NUMBER
driver.parameter.pollinterval: NUMBER
driver.parameter.port: NUMBER
driver.parameter.product: NUMBER
driver.parameter.productid: NUMBER
driver.parameter.serial: NUMBER
driver.parameter.synchronous: NUMBER
driver.parameter.vendor: NUMBER
driver.parameter.vendorid: NUMBER
driver.state: NUMBER
driver.version:
driver.version.data: NUMBER
driver.version.internal: NUMBER
driver.version.usb: NUMBER
input.transfer.high: STRING
input.transfer.low: STRING
input.voltage: NUMBER
input.voltage.nominal: NUMBER
output.voltage: NUMBER
ups.beeper.status: NUMBER
ups.delay.shutdown: STRING
ups.delay.start: STRING
ups.load: NUMBER
ups.mfr: NUMBER
ups.model: NUMBER
ups.productid: NUMBER
ups.realpower.nominal: NUMBER
ups.serial: NUMBER
ups.status: NUMBER
ups.test.result: NUMBER
ups.timer.shutdown: NUMBER
ups.timer.start: NUMBER
ups.vendorid: NUMBER
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
battery.charge: 100
battery.charge.low: 10
battery.charge.warning: 20
battery.mfr.date: CPS
battery.runtime: 4020
battery.runtime.low: 300
battery.type: PbAcid
battery.voltage: 24.0
battery.voltage.nominal: 24
device.mfr: CPS
device.model: CP900EPFCLCD
device.serial: 000000000000
device.type: ups
driver.debug: 0
driver.flag.allow_killpower: 0
driver.name: usbhid-ups
driver.parameter.pollfreq: 30
driver.parameter.pollinterval: 2
driver.parameter.port: auto
driver.parameter.product: CP900EPFCLCD
driver.parameter.productid: 0501
driver.parameter.serial: 000000000000
driver.parameter.synchronous: auto
driver.parameter.vendor: CPS
driver.parameter.vendorid: 0764
driver.state: quiet
driver.version: 2.8.1
driver.version.data: CyberPower HID 0.8
driver.version.internal: 0.52
driver.version.usb: libusb-1.0.26 (API: 0x1000109)
input.transfer.high: 260
input.transfer.low: 170
input.voltage: 228.0
input.voltage.nominal: 230
output.voltage: 228.0
ups.beeper.status: enabled
ups.delay.shutdown: 20
ups.delay.start: 30
ups.load: 13
ups.mfr: CPS
ups.model: CP900EPFCLCD
ups.productid: 0501
ups.realpower.nominal: 540
ups.serial: 000000000000
ups.status: OL
ups.test.result: No test initiated
ups.timer.shutdown: -60
ups.timer.start: -60
ups.vendorid: 0764
47 changes: 37 additions & 10 deletions plugins/inputs/upsd/upsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@ import (
var sampleConfig string

var (
// Fields that must always be emitted as strings to avoid type conflicts.
// The go.nut library auto-detects numeric-looking values (e.g. "0764")
// and converts them to int64, but IDs like vendorid/productid should
// remain strings regardless of their content.
stringFieldSet = map[string]bool{
"ups.vendorid": true,
"ups.productid": true,
"driver.parameter.vendorid": true,
"driver.parameter.productid": true,
}

// Define the default field set to add if existing
defaultFieldSet = map[string]string{
"battery.charge": "battery_charge_percent",
Expand Down Expand Up @@ -46,14 +57,15 @@ const (
)

type Upsd struct {
Server string `toml:"server"`
Port int `toml:"port"`
Username string `toml:"username"`
Password string `toml:"password"`
ForceFloat bool `toml:"force_float"`
Additional []string `toml:"additional_fields"`
DumpRaw bool `toml:"dump_raw_variables" deprecated:"1.35.0;use 'log_level' 'trace' instead"`
Log telegraf.Logger `toml:"-"`
Server string `toml:"server"`
Port int `toml:"port"`
Username string `toml:"username"`
Password string `toml:"password"`
ForceFloat bool `toml:"force_float"`
StringifyIDs *bool `toml:"stringify_ids"`
Additional []string `toml:"additional_fields"`
DumpRaw bool `toml:"dump_raw_variables" deprecated:"1.35.0;use 'log_level' 'trace' instead"`
Log telegraf.Logger `toml:"-"`

filter filter.Filter
dumped map[string]bool
Expand All @@ -73,6 +85,13 @@ func (u *Upsd) Init() error {

u.dumped = make(map[string]bool)

if u.StringifyIDs == nil {
u.Log.Warn("'stringify_ids' is not set explicitly; vendor/product IDs may be emitted as int64 " +
Comment thread
skartikey marked this conversation as resolved.
Outdated
"when the underlying value looks numeric, causing type conflicts between UPS devices. " +
"The default will change to 'true' in a future release. " +
"Set 'stringify_ids = true' to opt into the new behavior now, or 'stringify_ids = false' to keep the legacy behavior and silence this warning.")
Comment thread
skartikey marked this conversation as resolved.
Outdated
}

return nil
}

Expand Down Expand Up @@ -168,8 +187,16 @@ func (u *Upsd) gatherUps(acc telegraf.Accumulator, upsname string, variables []n
continue
}

// Force expected float values to actually being float (e.g. if delivered as int)
if u.ForceFloat {
// Force ID fields to always be strings to avoid type conflicts
// between UPS devices with numeric-looking IDs (auto-converted to
// int64 by go.nut) and devices with non-numeric IDs.
if u.StringifyIDs != nil && *u.StringifyIDs && stringFieldSet[varname] {
str, err := internal.ToString(v)
if err == nil {
v = str
}
} else if u.ForceFloat {
Comment thread
skartikey marked this conversation as resolved.
Outdated
// Force expected float values to actually being float (e.g. if delivered as int)
float, err := internal.ToFloat64(v)
if err == nil {
v = float
Expand Down
1 change: 1 addition & 0 deletions plugins/inputs/upsd/upsd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ func TestBadServer(t *testing.T) {
plugin := &Upsd{
Server: addr.IP.String(),
Port: addr.Port,
Log: testutil.Logger{},
}
require.NoError(t, plugin.Init())

Expand Down
Loading