├── CyberPowerSL700U.py ├── DellBadge-Eaton5PX.py ├── README.md └── getUpsData.py /CyberPowerSL700U.py: -------------------------------------------------------------------------------- 1 | # https://github.com/sa7mon/ups-telegraf 2 | from __future__ import print_function 3 | import subprocess 4 | 5 | cmd="upsc CyberPowerSL700U" 6 | output="" 7 | string_measurements=["battery.charge","battery.charge.low","battery.charge.warning","battery.mfr.date","battery.runtime","battery.runtime.low","battery.type","battery.voltage","battery.voltage.nominal","device.mfr","device.type","driver.parameter.bus","driver.parameter.lowbatt","driver.parameter.offdelay","driver.parameter.ondelay","driver.parameter.pollfreq","driver.parameter.pollinterval","driver.parameter.port","driver.parameter.productid","driver.parameter.synchronous","driver.parameter.vendor","driver.parameter.vendorid","driver.version.internal","input.transfer.high","input.transfer.low","input.voltage","input.voltage.nominal","output.voltage","ups.beeper.status","ups.delay.shutdown","ups.delay.start","ups.load","ups.mfr","ups.productid","ups.realpower.nominal","ups.status","ups.timer.shutdown","ups.timer.start","ups.vendorid"] 8 | 9 | p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) 10 | 11 | for line in p.stdout.readlines(): #read and store result in log file 12 | line = line.decode("utf-8").rstrip() 13 | key = line[:line.find(":")] 14 | value = line[line.find(":")+2:] 15 | 16 | if key in string_measurements: 17 | if value.isalpha(): 18 | value = '"' + value + '"' 19 | measurement = key + "=" + value 20 | if output != "": 21 | measurement = "," + measurement 22 | output += measurement 23 | 24 | output = "ups " + output.rstrip() 25 | print(output, end='') 26 | -------------------------------------------------------------------------------- /DellBadge-Eaton5PX.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import subprocess,sys 3 | 4 | if (len(sys.argv) == 2): 5 | 6 | arg = sys.argv[1] 7 | 8 | cmd="upsc "+arg+" > /dev/stdout 2> /dev/null" 9 | 10 | output="" 11 | 12 | string_measurements=["battery.charge", "battery.charge.low", "battery.current", "battery.runtime", "battery.runtime.low", "battery.temperature", "battery.voltage", "device.mfr", "device.model", "device.type", "driver.name", "driver.parameter.pollfreq", "driver.parameter.pollinterval", "driver.parameter.port", "driver.parameter.snmp_version", "driver.parameter.synchronous", "driver.version", "driver.version.data", "driver.version.internal", "input.bypass.phases", "input.current", "input.frequency", "input.frequency.nominal", "input.phases", "input.realpower", "input.transfer.high", "input.transfer.low", "input.voltage", "input.voltage.nominal", "output.current", "output.frequency", "output.frequency.nominal", "output.phases", "output.power.nominal", "output.realpower", "output.realpower.nominal", "output.voltage", "output.voltage.nominal", "ups.beeper.status", "ups.firmware", "ups.firmware.aux", "ups.load", "ups.mfr", "ups.model", "ups.status", "ups.test.result", "ups.timer.shutdown", "ups.timer.start"] 13 | 14 | p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) 15 | 16 | for line in p.stdout.readlines(): #read and store result in log file 17 | line = line.decode("utf-8").rstrip() 18 | key = line[:line.find(":")] 19 | value = line[line.find(":")+2:] 20 | 21 | if key in string_measurements: 22 | if not re.match(r'^(-?)(\d+|\d+\.\d+)$',value): 23 | value = '"' + value + '"' 24 | measurement = key + "=" + value 25 | if output != "": 26 | measurement = "," + measurement 27 | output += measurement 28 | 29 | output = "ups " + output.rstrip() 30 | print(output, end='') 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Description 2 | Get data from USB-connected UPS into InfluxDB using Telegraf 3 | 4 | Transforms `upsc` output like this: 5 | ``` 6 | battery.charge: 100 7 | battery.charge.low: 10 8 | battery.charge.warning: 20 9 | battery.mfr.date: CPS 10 | battery.runtime: 3133 11 | battery.runtime.low: 300 12 | battery.type: PbAcid 13 | battery.voltage: 13.1 14 | battery.voltage.nominal: 12 15 | ``` 16 | into InfluxDB Line Protocol like this: 17 | ``` 18 | ups battery.charge=100,battery.charge.low=10,battery.charge.warning=20,battery.mfr.date="CPS",battery.runtime=2970,battery.runtime.low=300,battery.type="PbAcid",battery.voltage=13.1,battery.voltage.nominal=12 19 | ``` 20 | 21 | ## Usage 22 | 23 | Edit the script `string_measurements` variable to reflect your setup. Specifically, add any additional measurement names that your UPS provides to the `string_measurements` array (in sorted order) so they will be included in the output. 24 | 25 | To see all the measurements your UPS provides, run this: 26 | 27 | ``` 28 | upsc YOUR_UPS_NAME_HERE 2>/dev/null | awk -F':' 'BEGIN {print "string_measurements=["} {print "\"" $1 "\", "} END {print "]"}' |tr -d '\n' 29 | ``` 30 | 31 | Call the script from `telegraf.conf` like this 32 | ``` 33 | [[inputs.exec]] 34 | 35 | commands = ["python /path/to/getUpsData.py "] 36 | timeout = "5s" 37 | data_format = "influx" 38 | ``` 39 | 40 | ## Compatibility 41 | Tested on: 42 | * Cyberpower CP1000AVRLCDa 43 | * CyberPower SL700U (`CyberPowerSL700U.py`) 44 | * Dell UPS 1000T/1920T/1920R HV (`DellBadge-Eaton5PX.py`) 45 | * MGE Pulsar 2200 46 | 47 | 48 | If you're using this with a different UPS, please let me know so I can add it to the list 49 | 50 | ## Contributors 51 | 52 | Thanks to the following for helping improve this repo. 53 | 54 | * @openincident 55 | * @mattster98 56 | * @Graffics 57 | -------------------------------------------------------------------------------- /getUpsData.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import subprocess,sys,re 3 | 4 | if (len(sys.argv) == 2): 5 | 6 | arg = sys.argv[1] 7 | 8 | cmd="upsc "+arg+" > /dev/stdout 2> /dev/null" 9 | 10 | output="" 11 | 12 | string_measurements=["battery.mfr.date", "battery.type", "device.mfr", "device.model","device.serial","device.type", 13 | "driver.name", "driver.paramter.port", "driver.parameter.synchronous", "driver.version", "driver.version.data", 14 | "ups.beeper.status", "ups.mfr","ups.model", "ups.serial", "ups.status", "ups.test.result", "driver.parameter.port", 15 | "driver.parameter.syncronous"] 16 | 17 | p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) 18 | 19 | for line in p.stdout.readlines(): #read and store result in log file 20 | line = line.decode("utf-8").rstrip() 21 | key = line[:line.find(":")] 22 | value = line[line.find(":")+2:] 23 | 24 | if key in string_measurements: 25 | if not re.match(r'^(-?)(\d+|\d+\.\d+)$',value): 26 | value = '"' + value + '"' 27 | measurement = key + "=" + value 28 | if output != "": 29 | measurement = "," + measurement 30 | output += measurement 31 | 32 | output = "ups " + output.rstrip() 33 | print(output, end='') 34 | --------------------------------------------------------------------------------