Closed mcindea closed 2 years ago
This would be nice to have. I looked very briefly at the NUT documentation, do you think the plugin would operate similar to the upsc
command?
Yes, as a matter of fact the python script I built uses the same uspc
command.
Would be nice to get an idea of how some actual data looks, could you show the output of your script?
I believe this is the documentation for connecting to upsd
: https://networkupstools.org/docs/developer-guide.chunked/ar01s09.html
Sure, but it's it's not fully relevant since currently I just adapted a python script that was built for APCUPCd, so currently the fields match what APC would output:
[{'fields': {'STATUS': u'OL', 'WATTS': 90.0, 'TIMELEFT': 3570.0, 'BCHARGE': 100.0, 'LOADPCT': 10.0, 'BATTV': 24.0, 'OUTPUTV': 260.0, 'NOMPOWER': 900.0}, 'tags': {'ups_alias': 'ups', 'host': 'Tower', 'serial': u'CRMJP2000104'}, 'measurement': 'ups_status'}]
Just for reference, BCHARGE
is actually battery.charge
on UPS Cyberpower and similar BATTV
is battery.voltage
.
Since I can't test other UPS equipments, I would want to make it dynamic, just output the fields it gets. Of course, after proper filtering so we make sure nothing malicious gets stored in the DB.
Thinking about it I think it's better if I just show you the upsc
output:
root@Tower:~# upsc ups@localhost
battery.charge: 100
battery.charge.low: 10
battery.charge.warning: 20
battery.mfr.date: CPS
battery.runtime: 3720
battery.runtime.low: 300
battery.type: PbAcid
battery.voltage: 24.0
battery.voltage.nominal: 24
device.mfr: CPS
device.model: CP1500EPFCLCD
device.serial: CRMJP2000104
device.type: ups
driver.name: usbhid-ups
driver.parameter.pollfreq: 30
driver.parameter.pollinterval: 2
driver.parameter.port: auto
driver.parameter.synchronous: no
driver.version: 2.7.4.1
driver.version.data: CyberPower HID 0.5
driver.version.internal: 0.53
driver.version.usb: libusb-1.0.22 (API: 0x1000106)
input.transfer.high: 260
input.transfer.low: 170
input.voltage: 225.0
input.voltage.nominal: 230
output.voltage: 260.0
ups.beeper.status: enabled
ups.delay.shutdown: 20
ups.delay.start: 30
ups.load: 10
ups.mfr: CPS
ups.model: CP1500EPFCLCD
ups.productid: 0501
ups.realpower.nominal: 900
ups.serial: CRMJP2000104
ups.status: OL
ups.test.result: No test initiated
ups.timer.shutdown: -60
ups.timer.start: -60
ups.vendorid: 0764
root@Tower:~#
I wonder how standardized these stats are, is there a list of possible stats? Likely we would want a plugin to connect to upsd and list all stats and then for each stat we would check a list of known stats to determine if the stat should be saved as a tag/field.
If a stat is unknown we could either ignore the stat or add it based on the observed type:
If we find the use of a decimal point is not consistent, we may want to always store as float. I would think that the memcached
plugin is the closest in style to what we would want here.
That's a very good idea. I'll have to dig into this a bit more. I found upsrw
, which does something like that, but only for config variables that can be changed by the user and not actual log data.
[battery.charge.low]
Remaining battery level when UPS switches to LB (percent)
Type: STRING
Maximum length: 10
Value: 10
[battery.runtime.low]
Remaining battery runtime when UPS switches to LB (seconds)
Type: STRING
Maximum length: 10
Value: 300
[input.transfer.high]
High voltage transfer point (V)
Type: STRING
Maximum length: 10
Value: 260
[input.transfer.low]
Low voltage transfer point (V)
Type: STRING
Maximum length: 10
Value: 170
[ups.delay.shutdown]
Interval to wait after shutdown with delay command (seconds)
Type: STRING
Maximum length: 10
Value: 20
[ups.delay.start]
Interval to wait before (re)starting the load (seconds)
Type: STRING
Maximum length: 10
Value: 30
root@Tower:~#
Also found something we could use to replace upsc
which polls every 30 seconds by default, but unfortunately it doesn't say anything about types. The format appears to be universal, so I don't think it's tied to the vendor type. Especially if you look at the last 2 columns, ups.temperature
and input.frequency
. They're NA because I don't have those sensors.
root@Tower:~# upslog -s ups@localhost -l - -f "%TIME @Y@m@d @H@M@S% %VAR battery.charge% %VAR battery.runtime% %VAR ups.realpower.nominal% %VAR battery.voltage% %VAR output.voltage% %VAR input.voltage% %VAR ups.load% [%VAR ups.status%] %VAR ups.temperature% %VAR input.frequency%"
Network UPS Tools upslog 2.7.4.1
logging status of ups@localhost to - (30s intervals)
20190829 073621 100 3480 900 24.0 260.0 225.0 11 [OL] NA NA
20190829 073651 100 3330 900 24.0 260.0 224.0 11 [OL] NA NA
EDIT: I looked into it and they have quite complex documentation about this: https://networkupstools.org/docs/developer-guide.chunked/apas01.html
To be honest there are more than I expected and I'm curious how much of them my UPS actually supports so I can actually test them.
Thanks for the tip about memcached, I''ll look into that.
Hi @kiwimato, just checking if you have any update in looking into referencing thememcached
plugin for the NUT plugin you're working on. Just looking into prioritizing plugins for future feature releases. Please respond if you have any questions!
Hello @sjwang90, unfortunately I didn't enough time to start work on it and my server where I had this setup crashed in the meantime, so I won't be able to work on it until I will fix it. I did however write a python script which I planned to use as PoC before I planned to work on this. If you guys have more time than me or might find it useful you can find it here - it's fully tested and it works. Please keep me updated. I find it really awesome that you are guys are interested in it!
Hello @kiwimato , do you still plan to create this nut plugin for telegraf ?
I too am using nut for my UPS management and monitoring, and I would love to be able to send the metrics to influxdb/grafana using telegraf.
Hey @Styx13, to be honest I didn't have time to yet and for my use case i created a workaround: https://github.com/kiwimato/nut-influxdb-exporter
I still plan to work on it at some point, but don't have an ETA at this point.
Just wanted to say it would be great if there was a NUT telegraf input!
Is there any known update on this? Would like to have Telegram scraping data from the NUT instance running on another server. Not planning to switch over to apcupcd.
Is there any known update on this? Would like to have Telegram scraping data from the NUT instance running on another server. Not planning to switch over to apcupcd.
Yeah, you can always use "inputs_exec" and run upsc. It's what I'm currently doing and it works fine.
[[inputs.exec]]
commands = ["sh -c 'upsc cyberpower@localhost ups.realpower.nominal'"]
name_override = "ups_power"
timeout = "5s"
data_format = "value"
data_type = "integer"
[inputs.exec.tags]
ups = "ups0"
[[inputs.exec]]
commands = ["sh -c 'upsc cyberpower@localhost ups.load'"]
name_override = "ups_load"
timeout = "5s"
data_format = "value"
data_type = "integer"
[inputs.exec.tags]
ups = "ups0"
I came across the issue and whipped up a script. Figured I'd share it for others.
#!/bin/sh
if [ $# -lt 1 ]; then
echo "usage: $0 field [...field]" >&2
exit 1
fi
fields="$1"
shift
while [ $# -ne 0 ]; do
fields="$fields|$1"
shift
done
list=$(upsc -l 2>/dev/null)
safe_fields="$(echo "${fields}" | sed 's/\./\\\./g')"
for name in $list; do
props=$(upsc "$name" 2>/dev/null | sed -nE "/^($safe_fields):/p" | sed -nE 's/([^0-9])\.([^0-9])/\1_\2/g;s/^(.*): ([0-9.]+)$/\1=\2/p' | tr '\n' ',')
echo "ups,name=${name} ${props%,}"
done
In my case I have that script at /etc/telegraf/ups
and added the following to my config:
[[inputs.exec]]
commands = ["/etc/telegraf/ups battery.charge battery.runtime battery.voltage battery.voltage.nominal input.voltage output.voltage ups.load ups.realpower.nominal"]
data_format = "influx"
@kiwimato @samuelkadolph Would either of your scripts be able list as an external plugin. If you would you be willing to submit this plugin as an external plugin that can be used with execd
to run seamlessly with Telegraf?
collecting the non-numeric ups.status value would also useful. Not entirely sure how to adapt the regexp so it becomes an accepted property for the script above. perhaps even transforming the abbreviated code for full-text status descriptions?
e.g. 'OL': 'Online', 'OB': 'On Battery', 'LB': 'Low Battery', 'HB': 'High Battery', 'RB': 'Battery Needs Replaced', 'CHRG': 'Battery Charging', 'DISCHRG': 'Battery Discharging', 'BYPASS': 'Bypass Active', 'CAL': 'Runtime Calibration', 'OFF': 'Offline', 'OVER': 'Overloaded', 'TRIM': 'Trimming Voltage', 'BOOST': 'Boosting Voltage', 'FSD': 'Forced Shutdown', 'ALARM': 'Alarm'
Hi,
Sorry if this is a dumb question, but ... as there is an official plugin for apcupsd, why not align with that => meaning, save the same parameter set with NUT?
Thanks!
I wrote this for myself, but then i found this comment, so I put it up on github/dockerhub -- maybe others will find it useful?
https://github.com/midzelis/nut-ups-logger
This will connect to NUT remotely, list all the UPS, and then send ALL the variables over a remote server. This can be telegraf running with the HTTP Listener plugin.
By default, I send all the variables I find. If there is something you don't want, looks like telegraf can filter things out: https://docs.influxdata.com/telegraf/v1.19/administration/configuration/#measurement-filtering
docker-compose.yml
version: "3"
services:
nut-ups-logger:
image: midzelis/nut-ups-logger
environment:
- NUT_HOST=${NUT_HOST}
- NUT_PORT=${NUT_PORT}
- LOGGING_URL=${LOGGING_URL}
container_name: nut-ups-logger
depends_on:
- telegraf
restart: always
telegraf.conf snippet
[[inputs.http_listener_v2]]
# ## Address and port to host HTTP listener on
service_address = ":10800"
#
# ## Path to listen to.
path = "/telegraf"
data_format = "json"
json_name_key = "UPS_NAME"
A very quick implementation of NUT client using github.com/robbiet480/go.nut
can be found here - https://github.com/Malinskiy/telegraf/tree/feature/upsd/plugins/inputs/upsd
It produces an almost identical set of metrics as apcupsd
input with a couple of exceptions. Dashboards that work for apcupsd work almost out of the box:
A very quick implementation of NUT client using
github.com/robbiet480/go.nut
can be found here - https://github.com/Malinskiy/telegraf/tree/feature/upsd/plugins/inputs/upsd
This looks perfect. But how do I use this? I run telegraf as docker container. Will this be adopted as a standard plugin? Right now it is not included.
A very quick implementation of NUT client using
github.com/robbiet480/go.nut
can be found here - https://github.com/Malinskiy/telegraf/tree/feature/upsd/plugins/inputs/upsdThis looks perfect. But how do I use this? I run telegraf as docker container. Will this be adopted as a standard plugin? Right now it is not included.
I may work on submitting this as a PR to the main repo next month depending on my availability
Looking forward to the upsd support in the next release.
Thank you @Malinskiy, @AdamLeyshon and @srebhan !
Feature Request
Hello guys,
I'm just curious if you have any plans in creating a plugin for NUT ? Similar to what you did for https://github.com/influxdata/telegraf/issues/2877
Proposal:
I volunteer to create it myself, but I'm new to Go, so I would need your support reviewing the code and most possibly also share the procedures you have for this kind of situations? i.e. Best practices or some docs about writing plugins. Thanks!
Current behavior:
Currently only a plugin for APCUPCd exists.
Desired behavior:
Would be nice if a plugin for NUT exists, which offers a broader compatibility with UPS hardware.
Use case:
Currently I use Telegraf for my UnRaid setup, which monitors everything, and built a custom Docker container script which gathers data and sends it to InfluxDB. Another solution is to use an Exec, but that also requires having NUT installed in the Alpine container where Telegraf is. Therefore I would like a plugin, which doesn't have any external dependencies.