mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
Add pwrstatd application (#14365)
* Add pwrstatd application * Adding pwrstatd test json and correcting pwrstatd snmprec file. Pwrstatd tests pass.
This commit is contained in:
@@ -1778,6 +1778,38 @@ systemctl reload snmpd
|
||||
7. You're now ready to enable the application in LibreNMS.
|
||||
|
||||
|
||||
## Pwrstatd
|
||||
|
||||
Pwrstatd (commonly known as powerpanel) is an application/service available from CyberPower to monitor their PSUs over USB. It is currently capable of reading the status of only one PSU connected via USB at a time. The powerpanel software is available here:
|
||||
https://www.cyberpowersystems.com/products/software/power-panel-personal/
|
||||
|
||||
### SNMP Extend
|
||||
|
||||
1. Copy the python script, pwrstatd.py, to the desired host
|
||||
```
|
||||
wget https://github.com/librenms/librenms-agent/raw/master/snmp/pwrstatd.py -O /etc/snmp/pwrstatd.py
|
||||
```
|
||||
|
||||
2. Make the script executable
|
||||
```
|
||||
chmod +x /etc/snmp/pwrstatd.py
|
||||
```
|
||||
|
||||
3. Edit your snmpd.conf file and add:
|
||||
```
|
||||
extend pwrstatd /etc/snmp/pwrstatd.py
|
||||
```
|
||||
|
||||
4. (Optional) Create a /etc/snmp/pwrstatd.json file and specify the path to the pwrstat executable [the default path is /sbin/pwrstat]:
|
||||
```
|
||||
{
|
||||
"pwrstat_cmd": "/sbin/pwrstat"
|
||||
}
|
||||
```
|
||||
|
||||
5. Restart snmpd.
|
||||
|
||||
|
||||
## Proxmox
|
||||
|
||||
1. For Proxmox 4.4+ install the libpve-apiclient-perl package
|
||||
|
36
includes/html/graphs/application/pwrstatd-common.inc.php
Normal file
36
includes/html/graphs/application/pwrstatd-common.inc.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
$name = 'pwrstatd';
|
||||
$colours = 'mega';
|
||||
$dostack = 0;
|
||||
$printtotal = 0;
|
||||
$addarea = 1;
|
||||
$transparency = 15;
|
||||
$scale_min = 0;
|
||||
|
||||
if (isset($vars['sn'])) {
|
||||
$sn_list = [$vars['sn']];
|
||||
} else {
|
||||
$sn_list = Rrd::getRrdApplicationArrays($device, $app->app_id, $name);
|
||||
}
|
||||
|
||||
$rrd_list = [];
|
||||
|
||||
$i = 0;
|
||||
while (isset($sn_list[$i])) {
|
||||
$sn = $sn_list[$i];
|
||||
$rrd_filename = Rrd::name($device['hostname'], ['app', $name, $app->app_id, $sn]);
|
||||
|
||||
$j = 0;
|
||||
if (Rrd::checkRrdExists($rrd_filename)) {
|
||||
foreach ($rrdArray as $ds => $var) {
|
||||
$rrd_list[$j]['filename'] = $rrd_filename;
|
||||
$rrd_list[$j]['descr'] = $var['descr'];
|
||||
$rrd_list[$j]['ds'] = $ds;
|
||||
$j++;
|
||||
}
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
|
||||
require 'includes/html/graphs/generic_multi_line_exact_numbers.inc.php';
|
12
includes/html/graphs/application/pwrstatd_minutes.inc.php
Normal file
12
includes/html/graphs/application/pwrstatd_minutes.inc.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
$unit_text = 'Minutes';
|
||||
$unitlen = 20;
|
||||
$bigdescrlen = 25;
|
||||
$smalldescrlen = 25;
|
||||
|
||||
$rrdArray = [
|
||||
'mruntime' => ['descr' => 'PSU Battery Runtime'],
|
||||
];
|
||||
|
||||
require 'pwrstatd-common.inc.php';
|
13
includes/html/graphs/application/pwrstatd_percentage.inc.php
Normal file
13
includes/html/graphs/application/pwrstatd_percentage.inc.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
$unit_text = 'Percent';
|
||||
$unitlen = 20;
|
||||
$bigdescrlen = 25;
|
||||
$smalldescrlen = 25;
|
||||
|
||||
$rrdArray = [
|
||||
'pcapacity' => ['descr' => 'PSU Battery Charge'],
|
||||
'pload' => ['descr' => 'PSU Load'],
|
||||
];
|
||||
|
||||
require 'pwrstatd-common.inc.php';
|
14
includes/html/graphs/application/pwrstatd_voltage.inc.php
Normal file
14
includes/html/graphs/application/pwrstatd_voltage.inc.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
$unit_text = 'Volts';
|
||||
$unitlen = 20;
|
||||
$bigdescrlen = 25;
|
||||
$smalldescrlen = 25;
|
||||
|
||||
$rrdArray = [
|
||||
'voutput' => ['descr' => 'PSU Output'],
|
||||
'vrating' => ['descr' => 'PSU Rating'],
|
||||
'vutility' => ['descr' => 'Utility Output'],
|
||||
];
|
||||
|
||||
require 'pwrstatd-common.inc.php';
|
13
includes/html/graphs/application/pwrstatd_wattage.inc.php
Normal file
13
includes/html/graphs/application/pwrstatd_wattage.inc.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
$unit_text = 'Watts';
|
||||
$unitlen = 20;
|
||||
$bigdescrlen = 25;
|
||||
$smalldescrlen = 25;
|
||||
|
||||
$rrdArray = [
|
||||
'wload' => ['descr' => 'PSU Load'],
|
||||
'wrating' => ['descr' => 'PSU Rating'],
|
||||
];
|
||||
|
||||
require 'pwrstatd-common.inc.php';
|
@@ -417,6 +417,12 @@ $graphs['sagan'] = [
|
||||
'uptime',
|
||||
'alert',
|
||||
];
|
||||
$graphs['pwrstatd'] = [
|
||||
'wattage',
|
||||
'voltage',
|
||||
'percentage',
|
||||
'minutes',
|
||||
];
|
||||
|
||||
echo '<div class="panel panel-default">';
|
||||
echo '<div class="panel-heading">';
|
||||
|
59
includes/html/pages/device/apps/pwrstatd.inc.php
Normal file
59
includes/html/pages/device/apps/pwrstatd.inc.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
$psu_list = Rrd::getRrdApplicationArrays($device, $app['app_id'], 'pwrstatd');
|
||||
|
||||
print_optionbar_start();
|
||||
|
||||
$link_array = [
|
||||
'page' => 'device',
|
||||
'device' => $device['device_id'],
|
||||
'tab' => 'apps',
|
||||
'app' => 'pwrstatd',
|
||||
];
|
||||
|
||||
$sn_list = [];
|
||||
|
||||
foreach ($psu_list as $label) {
|
||||
$sn = $label;
|
||||
|
||||
if ($vars['sn'] == $sn) {
|
||||
$label = '<span class="pagemenu-selected">' . $label . '</span>';
|
||||
}
|
||||
|
||||
array_push($sn_list, generate_link($label, $link_array, ['sn' => $sn]));
|
||||
}
|
||||
|
||||
printf('%s | PSUs: %s', generate_link('All PSUs', $link_array), implode(', ', $sn_list));
|
||||
|
||||
print_optionbar_end();
|
||||
|
||||
$graphs = [
|
||||
'pwrstatd_minutes' => 'Battery Runtime Remaining',
|
||||
'pwrstatd_percentage' => 'Percentage Readings',
|
||||
'pwrstatd_voltage' => 'Voltage Readings',
|
||||
'pwrstatd_wattage' => 'Power Readings',
|
||||
];
|
||||
|
||||
foreach ($graphs as $key => $text) {
|
||||
$graph_type = $key;
|
||||
$graph_array['height'] = '100';
|
||||
$graph_array['width'] = '215';
|
||||
$graph_array['to'] = time();
|
||||
$graph_array['id'] = $app['app_id'];
|
||||
$graph_array['type'] = 'application_' . $key;
|
||||
|
||||
if (isset($vars['sn'])) {
|
||||
$graph_array['sn'] = $vars['sn'];
|
||||
}
|
||||
|
||||
echo '<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">' . $text . '</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="row">';
|
||||
include 'includes/html/print-graphrow.inc.php';
|
||||
echo '</div>';
|
||||
echo '</div>';
|
||||
echo '</div>';
|
||||
}
|
62
includes/polling/applications/pwrstatd.inc.php
Normal file
62
includes/polling/applications/pwrstatd.inc.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
use LibreNMS\Exceptions\JsonAppException;
|
||||
use LibreNMS\Exceptions\JsonAppMissingKeysException;
|
||||
use LibreNMS\RRD\RrdDefinition;
|
||||
|
||||
$name = 'pwrstatd';
|
||||
$output = 'OK';
|
||||
|
||||
try {
|
||||
$pwrstatd_data = json_app_get($device, $name, 1)['data'];
|
||||
} catch (JsonAppMissingKeysException $e) {
|
||||
$pwrstatd_data = $e->getParsedJson();
|
||||
} catch (JsonAppException $e) {
|
||||
echo PHP_EOL . $name . ':' . $e->getCode() . ':' . $e->getMessage() . PHP_EOL;
|
||||
update_application($app, $e->getCode() . ':' . $e->getMessage(), []); // Set empty metrics and error message
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$rrd_name = ['app', $name, $app->app_id];
|
||||
$rrd_def = RrdDefinition::make()
|
||||
->addDataset('mruntime', 'GAUGE', 0)
|
||||
->addDataset('pcapacity', 'GAUGE', 0, 100)
|
||||
->addDataset('pload', 'GAUGE', 0, 100)
|
||||
->addDataset('voutput', 'GAUGE', 0)
|
||||
->addDataset('vrating', 'GAUGE', 0)
|
||||
->addDataset('vutility', 'GAUGE', 0)
|
||||
->addDataset('wload', 'GAUGE', 0)
|
||||
->addDataset('wrating', 'GAUGE', 0);
|
||||
|
||||
$metrics = [];
|
||||
foreach ($pwrstatd_data as $data) {
|
||||
$sn = $data['sn'];
|
||||
$mruntime = $data['mruntime'];
|
||||
$pcapacity = $data['pcapacity'];
|
||||
$pload = $data['pload'];
|
||||
$voutput = $data['voutput'];
|
||||
$vrating = $data['vrating'];
|
||||
$vutility = $data['vutility'];
|
||||
$wload = $data['wload'];
|
||||
$wrating = $data['wrating'];
|
||||
|
||||
$rrd_name = ['app', $name, $app->app_id, $sn];
|
||||
|
||||
$fields = [
|
||||
'mruntime' => $mruntime,
|
||||
'pcapacity' => $pcapacity,
|
||||
'pload' => $pload,
|
||||
'voutput' => $voutput,
|
||||
'vrating' => $vrating,
|
||||
'vutility' => $vutility,
|
||||
'wload' => $wload,
|
||||
'wrating' => $wrating,
|
||||
];
|
||||
|
||||
$metrics[$sn] = $fields;
|
||||
$tags = ['name' => $sn, 'app_id' => $app->app_id, 'rrd_def' => $rrd_def, 'rrd_name' => $rrd_name];
|
||||
data_update($device, 'app', $tags, $fields);
|
||||
}
|
||||
|
||||
update_application($app, $output, $metrics);
|
101
tests/data/linux_pwrstatd-v1.json
Normal file
101
tests/data/linux_pwrstatd-v1.json
Normal file
@@ -0,0 +1,101 @@
|
||||
{
|
||||
"applications": {
|
||||
"discovery": {
|
||||
"applications": [
|
||||
{
|
||||
"app_type": "pwrstatd",
|
||||
"app_state": "UNKNOWN",
|
||||
"discovered": 1,
|
||||
"app_state_prev": null,
|
||||
"app_status": "",
|
||||
"app_instance": "",
|
||||
"data": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"poller": {
|
||||
"applications": [
|
||||
{
|
||||
"app_type": "pwrstatd",
|
||||
"app_state": "OK",
|
||||
"discovered": 1,
|
||||
"app_state_prev": "UNKNOWN",
|
||||
"app_status": "",
|
||||
"app_instance": "",
|
||||
"data": null
|
||||
}
|
||||
],
|
||||
"application_metrics": [
|
||||
{
|
||||
"metric": "BF01512BA31_mruntime",
|
||||
"value": 56,
|
||||
"value_prev": null,
|
||||
"app_type": "pwrstatd"
|
||||
},
|
||||
{
|
||||
"metric": "BF01512BA31_pcapacity",
|
||||
"value": 100,
|
||||
"value_prev": null,
|
||||
"app_type": "pwrstatd"
|
||||
},
|
||||
{
|
||||
"metric": "BF01512BA31_pload",
|
||||
"value": 17,
|
||||
"value_prev": null,
|
||||
"app_type": "pwrstatd"
|
||||
},
|
||||
{
|
||||
"metric": "BF01512BA31_voutput",
|
||||
"value": 122,
|
||||
"value_prev": null,
|
||||
"app_type": "pwrstatd"
|
||||
},
|
||||
{
|
||||
"metric": "BF01512BA31_vrating",
|
||||
"value": 120,
|
||||
"value_prev": null,
|
||||
"app_type": "pwrstatd"
|
||||
},
|
||||
{
|
||||
"metric": "BF01512BA31_vutility",
|
||||
"value": 122,
|
||||
"value_prev": null,
|
||||
"app_type": "pwrstatd"
|
||||
},
|
||||
{
|
||||
"metric": "BF01512BA31_wload",
|
||||
"value": 153,
|
||||
"value_prev": null,
|
||||
"app_type": "pwrstatd"
|
||||
},
|
||||
{
|
||||
"metric": "BF01512BA31_wrating",
|
||||
"value": 900,
|
||||
"value_prev": null,
|
||||
"app_type": "pwrstatd"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"os": {
|
||||
"discovery": {
|
||||
"devices": [
|
||||
{
|
||||
"sysName": "<private>",
|
||||
"sysObjectID": ".1.3.6.1.4.1.8072.3.2.10",
|
||||
"sysDescr": "Linux wiii 4.18.0-408.el8.ath_hack.x86_64 #1 SMP Fri Jul 22 10:19:59 PDT 2022 x86_64",
|
||||
"sysContact": "<private>",
|
||||
"version": "4.18.0-408.el8.ath_hack.x86_64",
|
||||
"hardware": "Generic x86 64-bit",
|
||||
"features": null,
|
||||
"location": "<private>",
|
||||
"os": "linux",
|
||||
"type": "server",
|
||||
"serial": null,
|
||||
"icon": "linux.svg"
|
||||
}
|
||||
]
|
||||
},
|
||||
"poller": "matches discovery"
|
||||
}
|
||||
}
|
9
tests/snmpsim/linux_pwrstatd-v1.snmprec
Normal file
9
tests/snmpsim/linux_pwrstatd-v1.snmprec
Normal file
@@ -0,0 +1,9 @@
|
||||
1.3.6.1.2.1.1.1.0|4|Linux wiii 4.18.0-408.el8.ath_hack.x86_64 #1 SMP Fri Jul 22 10:19:59 PDT 2022 x86_64
|
||||
1.3.6.1.2.1.1.2.0|6|1.3.6.1.4.1.8072.3.2.10
|
||||
1.3.6.1.2.1.1.3.0|67|77550514
|
||||
1.3.6.1.2.1.1.4.0|4|<private>
|
||||
1.3.6.1.2.1.1.5.0|4|<private>
|
||||
1.3.6.1.2.1.1.6.0|4|<private>
|
||||
1.3.6.1.2.1.25.1.1.0|67|77552962
|
||||
1.3.6.1.4.1.8072.1.3.2.2.1.21.8.112.119.114.115.116.97.116.100|2|1
|
||||
1.3.6.1.4.1.8072.1.3.2.3.1.2.8.112.119.114.115.116.97.116.100|4x|7b2276657273696f6e223a20312c202264617461223a205b7b22706c6f6164223a2031372c2022706361706163697479223a203130302c2022766f7574707574223a203132322c202277726174696e67223a203930302c2022767574696c697479223a203132322c20226d72756e74696d65223a2035362c2022776c6f6164223a203135332c202276726174696e67223a203132302c2022736e223a20224246303135313242413331227d5d2c20226572726f72537472696e67223a2022222c20226572726f72223a20307d0a
|
Reference in New Issue
Block a user