banshee is under active development: collectors will keep changing, and a version you publish will likely need adjustments. For stable use, wait for version 1.0.0.

Hardware

banshee/hardware-collection/hardware/pdu/apc/snmp/

outlets

The load state, current and power of each outlet of an APC rack PDU metered by outlet by SNMP.

  • hardware
  • pdu
  • apc
  • schneider
  • powernet
  • rack
  • outlet
  • power
  • snmp

by banshee0 installations1 version

v1Latest

Published on October 28, 2026. First version.

Keen 1.0.0 · 59 lines
// The metered outlets of an APC rack PDU, by SNMP (PowerNet-MIB, rPDU2): for each outlet a PDU metered by
// outlet measures, the load state it judges against the outlet's own thresholds, the current and the power
// of the device plugged in. An outlet is named by its PDU and its number, which do not change; the name an
// administrator gives it on the PDU is an output. Only the PDUs metered by outlet serve this table.
need('protocol:snmp');

per('outlet', 'Outlets');
output('label', 'text', array('label' => 'Outlet name', 'per' => 'outlet'));
output('load-state', 'text', array('label' => 'Load state', 'per' => 'outlet'));
output('current', 'number', array('label' => 'Current', 'unit' => 'A', 'per' => 'outlet'));
output('power', 'number', array('label' => 'Power', 'unit' => 'W', 'per' => 'outlet'));

watch.state('load-state', 'Outlet near overload or overloaded', 'load-state', array('warning' => array('near-overload'), 'critical' => array('overload')));
watch.below('unplugged', 'Outlet draws nothing', 'power', array(
    'help'    => 'Raises when an outlet draws less than the power set on the probe, in watts: the device plugged in is off or unplugged.',
    'enabled' => false,
));
watch.above('power', 'Outlet draws too much', 'power', array(
    'help'    => 'Raises above the power set on the probe, in watts, for each outlet.',
    'enabled' => false,
));
watch.missing('missing', 'Outlet missing', 'load-state', array('enabled' => false));

// rPDU2OutletMeteredStatusTable (1.3.6.1.4.1.318.1.1.26.9.4.3.1): rPDU2OutletMeteredStatusModule, the PDU's
// number in its group; rPDU2OutletMeteredStatusName; rPDU2OutletMeteredStatusNumber;
// rPDU2OutletMeteredStatusState, lowLoad (1), normal (2), nearOverload (3), overload (4);
// rPDU2OutletMeteredStatusCurrent, in tenths of A; rPDU2OutletMeteredStatusPower, in W.
$outlets = snmp.table(array(
    'module'  => '1.3.6.1.4.1.318.1.1.26.9.4.3.1.2',
    'name'    => '1.3.6.1.4.1.318.1.1.26.9.4.3.1.3',
    'number'  => '1.3.6.1.4.1.318.1.1.26.9.4.3.1.4',
    'state'   => '1.3.6.1.4.1.318.1.1.26.9.4.3.1.5',
    'current' => '1.3.6.1.4.1.318.1.1.26.9.4.3.1.6',
    'power'   => '1.3.6.1.4.1.318.1.1.26.9.4.3.1.7',
));

$states = array(1 => 'low', 2 => 'normal', 3 => 'near-overload', 4 => 'overload');
$read = 0;
foreach ($outlets as $row) {
    if (!list.has($row, 'module') || !list.has($row, 'number') || !list.has($row, 'state')) {
        continue;
    }
    $name = 'pdu ' . $row['module'] . ' outlet ' . $row['number'];
    value('load-state', list.get($states, $row['state'], 'state ' . $row['state']), $name);
    if (list.get($row, 'name', '') != '') {
        value('label', $row['name'], $name);
    }
    if (list.has($row, 'current')) {
        value('current', $row['current'] / 10, $name);
    }
    if (list.has($row, 'power')) {
        value('power', $row['power'], $name);
    }
    $read = $read + 1;
}
if ($read == 0) {
    fail('misconfigured', 'The agent serves no metered outlet (rPDU2OutletMeteredStatusTable, PowerNet-MIB)',
        'Not an APC rack PDU metered by outlet, or a view that does not include 1.3.6.1.4.1.318.1.1.26.');
}