nut.chart.sh 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. # shellcheck shell=bash
  2. # no need for shebang - this file is loaded from charts.d.plugin
  3. # SPDX-License-Identifier: GPL-3.0-or-later
  4. # netdata
  5. # real-time performance and health monitoring, done right!
  6. # (C) 2016-2017 Costa Tsaousis <costa@tsaousis.gr>
  7. #
  8. # a space separated list of UPS names
  9. # if empty, the list returned by 'upsc -l' will be used
  10. nut_ups=
  11. # how frequently to collect UPS data
  12. nut_update_every=2
  13. # how much time in seconds, to wait for nut to respond
  14. nut_timeout=2
  15. # set this to 1, to enable another chart showing the number
  16. # of UPS clients connected to upsd
  17. nut_clients_chart=0
  18. # the priority of nut related to other charts
  19. nut_priority=90000
  20. declare -A nut_ids=()
  21. declare -A nut_names=()
  22. nut_get_all() {
  23. run -t $nut_timeout upsc -l
  24. }
  25. nut_get() {
  26. run -t $nut_timeout upsc "$1"
  27. if [ "${nut_clients_chart}" -eq "1" ]; then
  28. printf "ups.connected_clients: "
  29. run -t $nut_timeout upsc -c "$1" | wc -l
  30. fi
  31. }
  32. nut_check() {
  33. # this should return:
  34. # - 0 to enable the chart
  35. # - 1 to disable the chart
  36. local x
  37. require_cmd upsc || return 1
  38. [ -z "$nut_ups" ] && nut_ups="$(nut_get_all)"
  39. for x in $nut_ups; do
  40. nut_get "$x" > /dev/null
  41. # shellcheck disable=SC2181
  42. if [ $? -eq 0 ]; then
  43. if [ -n "${nut_names[${x}]}" ]; then
  44. nut_ids[$x]="$(fixid "${nut_names[${x}]}")"
  45. else
  46. nut_ids[$x]="$(fixid "$x")"
  47. fi
  48. continue
  49. fi
  50. error "cannot get information for NUT UPS '$x'."
  51. done
  52. if [ ${#nut_ids[@]} -eq 0 ]; then
  53. # shellcheck disable=SC2154
  54. error "Cannot find UPSes - please set nut_ups='ups_name' in $confd/nut.conf"
  55. return 1
  56. fi
  57. return 0
  58. }
  59. nut_create() {
  60. # create the charts
  61. local x
  62. for x in "${nut_ids[@]}"; do
  63. cat << EOF
  64. CHART nut_$x.charge '' "UPS Charge" "percentage" ups nut.charge area $((nut_priority + 2)) $nut_update_every
  65. DIMENSION battery_charge charge absolute 1 100
  66. CHART nut_$x.runtime '' "UPS Runtime" "seconds" ups nut.runtime area $((nut_priority + 3)) $nut_update_every
  67. DIMENSION battery_runtime runtime absolute 1 100
  68. CHART nut_$x.battery_voltage '' "UPS Battery Voltage" "Volts" ups nut.battery.voltage line $((nut_priority + 4)) $nut_update_every
  69. DIMENSION battery_voltage voltage absolute 1 100
  70. DIMENSION battery_voltage_high high absolute 1 100
  71. DIMENSION battery_voltage_low low absolute 1 100
  72. DIMENSION battery_voltage_nominal nominal absolute 1 100
  73. CHART nut_$x.input_voltage '' "UPS Input Voltage" "Volts" input nut.input.voltage line $((nut_priority + 5)) $nut_update_every
  74. DIMENSION input_voltage voltage absolute 1 100
  75. DIMENSION input_voltage_fault fault absolute 1 100
  76. DIMENSION input_voltage_nominal nominal absolute 1 100
  77. CHART nut_$x.input_current '' "UPS Input Current" "Ampere" input nut.input.current line $((nut_priority + 6)) $nut_update_every
  78. DIMENSION input_current_nominal nominal absolute 1 100
  79. CHART nut_$x.input_frequency '' "UPS Input Frequency" "Hz" input nut.input.frequency line $((nut_priority + 7)) $nut_update_every
  80. DIMENSION input_frequency frequency absolute 1 100
  81. DIMENSION input_frequency_nominal nominal absolute 1 100
  82. CHART nut_$x.output_voltage '' "UPS Output Voltage" "Volts" output nut.output.voltage line $((nut_priority + 8)) $nut_update_every
  83. DIMENSION output_voltage voltage absolute 1 100
  84. CHART nut_$x.load '' "UPS Load" "percentage" ups nut.load area $((nut_priority)) $nut_update_every
  85. DIMENSION load load absolute 1 100
  86. CHART nut_$x.load_usage '' "UPS Load Usage" "Watts" ups nut.load_usage area $((nut_priority + 1)) $nut_update_every
  87. DIMENSION load_usage load_usage absolute 1 100
  88. CHART nut_$x.temp '' "UPS Temperature" "temperature" ups nut.temperature line $((nut_priority + 9)) $nut_update_every
  89. DIMENSION temp temp absolute 1 100
  90. EOF
  91. if [ "${nut_clients_chart}" = "1" ]; then
  92. cat << EOF2
  93. CHART nut_$x.clients '' "UPS Connected Clients" "clients" ups nut.clients area $((nut_priority + 10)) $nut_update_every
  94. DIMENSION clients '' absolute 1 1
  95. EOF2
  96. fi
  97. done
  98. return 0
  99. }
  100. nut_update() {
  101. # the first argument to this function is the microseconds since last update
  102. # pass this parameter to the BEGIN statement (see below).
  103. # do all the work to collect / calculate the values
  104. # for each dimension
  105. # remember: KEEP IT SIMPLE AND SHORT
  106. local i x
  107. for i in "${!nut_ids[@]}"; do
  108. x="${nut_ids[$i]}"
  109. nut_get "$i" | awk "
  110. BEGIN {
  111. battery_charge = 0;
  112. battery_runtime = 0;
  113. battery_voltage = 0;
  114. battery_voltage_high = 0;
  115. battery_voltage_low = 0;
  116. battery_voltage_nominal = 0;
  117. input_voltage = 0;
  118. input_voltage_fault = 0;
  119. input_voltage_nominal = 0;
  120. input_current_nominal = 0;
  121. input_frequency = 0;
  122. input_frequency_nominal = 0;
  123. output_voltage = 0;
  124. load = 0;
  125. load_usage = 0;
  126. nompower = 0;
  127. temp = 0;
  128. client = 0;
  129. do_clients = ${nut_clients_chart};
  130. }
  131. /^battery.charge: .*/ { battery_charge = \$2 * 100 };
  132. /^battery.runtime: .*/ { battery_runtime = \$2 * 100 };
  133. /^battery.voltage: .*/ { battery_voltage = \$2 * 100 };
  134. /^battery.voltage.high: .*/ { battery_voltage_high = \$2 * 100 };
  135. /^battery.voltage.low: .*/ { battery_voltage_low = \$2 * 100 };
  136. /^battery.voltage.nominal: .*/ { battery_voltage_nominal = \$2 * 100 };
  137. /^input.voltage: .*/ { input_voltage = \$2 * 100 };
  138. /^input.voltage.fault: .*/ { input_voltage_fault = \$2 * 100 };
  139. /^input.voltage.nominal: .*/ { input_voltage_nominal = \$2 * 100 };
  140. /^input.current.nominal: .*/ { input_current_nominal = \$2 * 100 };
  141. /^input.frequency: .*/ { input_frequency = \$2 * 100 };
  142. /^input.frequency.nominal: .*/ { input_frequency_nominal = \$2 * 100 };
  143. /^output.voltage: .*/ { output_voltage = \$2 * 100 };
  144. /^ups.load: .*/ { load = \$2 * 100 };
  145. /^ups.realpower.nominal: .*/ { nompower = \$2 };
  146. /^ups.temperature: .*/ { temp = \$2 * 100 };
  147. /^ups.connected_clients: .*/ { clients = \$2 };
  148. END {
  149. { load_usage = nompower * load / 100 };
  150. print \"BEGIN nut_$x.charge $1\";
  151. print \"SET battery_charge = \" battery_charge;
  152. print \"END\"
  153. print \"BEGIN nut_$x.runtime $1\";
  154. print \"SET battery_runtime = \" battery_runtime;
  155. print \"END\"
  156. print \"BEGIN nut_$x.battery_voltage $1\";
  157. print \"SET battery_voltage = \" battery_voltage;
  158. print \"SET battery_voltage_high = \" battery_voltage_high;
  159. print \"SET battery_voltage_low = \" battery_voltage_low;
  160. print \"SET battery_voltage_nominal = \" battery_voltage_nominal;
  161. print \"END\"
  162. print \"BEGIN nut_$x.input_voltage $1\";
  163. print \"SET input_voltage = \" input_voltage;
  164. print \"SET input_voltage_fault = \" input_voltage_fault;
  165. print \"SET input_voltage_nominal = \" input_voltage_nominal;
  166. print \"END\"
  167. print \"BEGIN nut_$x.input_current $1\";
  168. print \"SET input_current_nominal = \" input_current_nominal;
  169. print \"END\"
  170. print \"BEGIN nut_$x.input_frequency $1\";
  171. print \"SET input_frequency = \" input_frequency;
  172. print \"SET input_frequency_nominal = \" input_frequency_nominal;
  173. print \"END\"
  174. print \"BEGIN nut_$x.output_voltage $1\";
  175. print \"SET output_voltage = \" output_voltage;
  176. print \"END\"
  177. print \"BEGIN nut_$x.load $1\";
  178. print \"SET load = \" load;
  179. print \"END\"
  180. print \"BEGIN nut_$x.load_usage $1\";
  181. print \"SET load_usage = \" load_usage;
  182. print \"END\"
  183. print \"BEGIN nut_$x.temp $1\";
  184. print \"SET temp = \" temp;
  185. print \"END\"
  186. if(do_clients) {
  187. print \"BEGIN nut_$x.clients $1\";
  188. print \"SET clients = \" clients;
  189. print \"END\"
  190. }
  191. }"
  192. # shellcheck disable=2181
  193. [ $? -ne 0 ] && unset "nut_ids[$i]" && error "failed to get values for '$i', disabling it."
  194. done
  195. [ ${#nut_ids[@]} -eq 0 ] && error "no UPSes left active." && return 1
  196. return 0
  197. }