banshee est en développement actif : les collecteurs vont encore changer, et une version que vous publiez demandera sans doute des ajustements. Pour un usage stable, attendez la version 1.0.0.

Network

banshee/network-collection/network/snmp/

sensors

The hardware sensors of a network device by SNMP (ENTITY-SENSOR-MIB): temperatures, fans, voltages, currents, power, and their state.

  • network
  • snmp
  • entity-sensor-mib
  • temperature
  • fan
  • voltage
  • hardware

par banshee1 installation2 versions

v2Dernière

Publiée le 28 octobre 2026. One naming convention across collections; documentation completed.

Keen 1.0.0 · 91 lignes
// The hardware sensors of a network device, by SNMP (ENTITY-SENSOR-MIB, RFC 3433): temperatures, fan
// speeds, voltages, currents and power, each in its unit, and the state the agent gives each sensor. A
// sensor is named by entPhysicalName (ENTITY-MIB), the name the device gives the part it measures.
// Any brand whose agent serves entPhySensorTable; a device that serves none stops the collector, rather
// than stay green on nothing.
need('protocol:snmp');

per('sensor', 'Sensors');
output('temperature', 'number', array('label' => 'Temperature', 'unit' => '°C', 'per' => 'sensor'));
output('fan-speed', 'number', array('label' => 'Fan speed', 'unit' => 'rpm', 'per' => 'sensor'));
output('voltage', 'number', array('label' => 'Voltage', 'unit' => 'V', 'per' => 'sensor'));
output('current', 'number', array('label' => 'Current', 'unit' => 'A', 'per' => 'sensor'));
output('power', 'number', array('label' => 'Power', 'unit' => 'W', 'per' => 'sensor'));
output('status', 'text', array('label' => 'Sensor state', 'per' => 'sensor'));

watch.above('hot', 'High temperature', 'temperature', array('warning' => 70, 'critical' => 85, 'for' => '3 runs'));
watch.below('fan-stopped', 'Fan stopped', 'fan-speed', array('critical' => 1, 'for' => '2 runs'));
watch.state('failed', 'Sensor failed', 'status', array('critical' => array('nonoperational')));
watch.below('voltage-low', 'Low voltage', 'voltage', array(
    'help'    => 'Raises below the voltages set on the probe: each rail has its own, which no default fits.',
    'enabled' => false,
));
watch.missing('missing', 'Sensor missing', 'status', array('enabled' => false));

// entPhySensorTable, by entPhysicalIndex: entPhySensorType, entPhySensorScale, entPhySensorPrecision,
// entPhySensorValue and entPhySensorOperStatus.
$sensors = snmp.table(array(
    'type'      => '1.3.6.1.2.1.99.1.1.1.1',
    'scale'     => '1.3.6.1.2.1.99.1.1.1.2',
    'precision' => '1.3.6.1.2.1.99.1.1.1.3',
    'value'     => '1.3.6.1.2.1.99.1.1.1.4',
    'state'     => '1.3.6.1.2.1.99.1.1.1.5',
));
// ENTITY-MIB, entPhysicalName, by entPhysicalIndex: the same index as entPhySensorTable.
$names = snmp.walk('1.3.6.1.2.1.47.1.1.1.1.7');

// EntitySensorStatus in words. EntitySensorDataScale as a factor, from micro (7) to mega (11): the scales
// a device uses for these units; a sensor in another scale returns its state only.
$states = array(1 => 'ok', 2 => 'unavailable', 3 => 'nonoperational');
$factors = array(7 => 0.000001, 8 => 0.001, 9 => 1, 10 => 1000, 11 => 1000000);

$read = 0;
$seen = array();
foreach ($sensors as $index => $row) {
    if (!list.has($row, 'state')) {
        continue;
    }
    // A sensor without a name takes its index; two sensors of the same name each keep their own, the
    // second carrying its index.
    $name = list.get($names, $index, '');
    if ($name == '') {
        $name = 'sensor ' . $index;
    }
    if (list.has($seen, $name)) {
        $name = $name . ' #' . $index;
    }
    $seen[$name] = true;
    $read = $read + 1;

    $state = list.get($states, $row['state'], 'unknown');
    value('status', $state, $name);

    // The value of a sensor that is not ok means nothing.
    if ($state != 'ok' || !list.has($row, 'value') || !list.has($factors, list.get($row, 'scale', 0))) {
        continue;
    }
    // entPhySensorPrecision from 1 to 9 is the number of decimals of the value; 0 or below, none.
    $divisor = 1;
    for ($i = 1; $i <= list.get($row, 'precision', 0); $i = $i + 1) {
        $divisor = $divisor * 10;
    }
    $measure = number.round($row['value'] * $factors[$row['scale']] / $divisor, 2);

    // EntitySensorDataType: voltsAC (3), voltsDC (4), amperes (5), watts (6), celsius (8), rpm (10).
    $type = list.get($row, 'type', 0);
    if ($type == 8) {
        value('temperature', $measure, $name);
    } elseif ($type == 10) {
        value('fan-speed', $measure, $name);
    } elseif ($type == 3 || $type == 4) {
        value('voltage', $measure, $name);
    } elseif ($type == 5) {
        value('current', $measure, $name);
    } elseif ($type == 6) {
        value('power', $measure, $name);
    }
}
if ($read == 0) {
    fail('misconfigured', 'The agent serves no sensor (entPhySensorTable, ENTITY-SENSOR-MIB)',
        'A device whose agent does not implement ENTITY-SENSOR-MIB, or a view that does not grant it to the poller.');
}