feature: Added ability specify options for sensors yaml discovery (#6985)

* feature: Added ability specify options for sensors yaml discovery

* travis fix for new line + skip_values_* -> skip_value_*
This commit is contained in:
Neil Lathwood
2017-07-10 22:27:46 +01:00
committed by Tony Murray
parent 431d15aad9
commit d30e5660f9
6 changed files with 194 additions and 138 deletions

View File

@@ -40,23 +40,28 @@ mib: NETBOTZV2-MIB
modules:
sensors:
airflow:
-
oid: airFlowSensorTable
value: airFlowSensorValue
divisor: 10
num_oid: .1.3.6.1.4.1.5528.100.4.1.5.1.2.
descr: airFlowSensorLabel
index: 'airFlowSensorValue.{{ $index }}'
options:
skip_values_lt: 0
data:
-
oid: airFlowSensorTable
value: airFlowSensorValue
divisor: 10
num_oid: .1.3.6.1.4.1.5528.100.4.1.5.1.2.
descr: airFlowSensorLabel
index: 'airFlowSensorValue.{{ $index }}'
```
At the top you can define one or more mibs to be used in the lookup of data:
`mib: NETBOTZV2-MIB`
For `data:` you have the following options:
The only sensor we have defined here is airflow. The available options are as follows:
- `oid` (required): This is the name of the table you want to do the snmp walk on.
- `value` (required): This is the key within the table that contains the value.
- `value` (optional): This is the key within the table that contains the value. If not provided will use `oid`
- `num_oid` (required): This is the numerical OID that contains `value`. This should always be without the appended `index`.
- `divisor` (optional): This is the divisor to use against the returned `value`.
- `multiplier` (optional): This is the multiplier to use against the returned `value`.
@@ -67,6 +72,16 @@ The only sensor we have defined here is airflow. The available options are as fo
- `descr` (required): The visible label for this sensor. It can be a key with in the table or a static string, optionally using `{{ index }}`
- `index` (optional): This is the index value we use to uniquely identify this sensor. `{{ $index }}` will be replaced by the `index` from the snmp walk.
- `skip_values` (optional): This is an array of values we should skip over.
- `skip_value_lt` (optional): If sensor value is less than this, skip the discovery.
- `skip_value_gt` (optional): If sensor value is greater than this, skip the discovery.
For `options:` you have the following available:
- `divisor`: This is the divisor to use against the returned `value`.
- `multiplier`: This is the multiplier to use against the returned `value`.
- `skip_values`: This is an array of values we should skip over.
- `skip_value_lt`: If sensor value is less than this, skip the discovery.
- `skip_value_gt`: If sensor value is greater than this, skip the discovery.
If you aren't able to use yaml to perform the sensor discovery, you will most likely need to use Advanced health discovery.
@@ -103,4 +118,4 @@ For the majority of devices, this is all that's required to add support for a se
If custom polling is needed then the file format is similar to discovery: `includes/polling/sensors/$class/$os.inc.php`. Whilst it's possible to perform additional
snmp queries within polling this should be avoided where possible. The value for the OID is already available as `$sensor_value`.
Graphing is performed automatically for sensors, no custom graphing is required or supported.
Graphing is performed automatically for sensors, no custom graphing is required or supported.

View File

@@ -2,33 +2,34 @@ mib: PowerNet-MIB
modules:
sensors:
state:
-
oid: upsBasicOutputStatus
value: upsBasicOutputStatus
num_oid: .1.3.6.1.4.1.318.1.1.1.4.1.1.
descr: Output Status
index: '{{ $index }}'
state_name: upsBasicOutputStatus
states:
- { descr: unknown, graph: 0, value: 1, generic: 3 }
- { descr: onLine, graph: 0, value: 2, generic: 0 }
- { descr: onBattery, graph: 0, value: 3, generic: 1 }
- { descr: onSmartBoost, graph: 0, value: 4, generic: 0 }
- { descr: timedSleeping, graph: 0, value: 5, generic: 0 }
- { descr: softwareBypass, graph: 0, value: 6, generic: 1 }
- { descr: off, graph: 0, value: 7, generic: 2 }
- { descr: rebooting, graph: 0, value: 8, generic: 1 }
- { descr: switchedBypass, graph: 0, value: 9, generic: 1 }
- { descr: hardwareFailureBypass, graph: 0, value: 10, generic: 2 }
- { descr: sleepingUntilPowerReturn, graph: 0, value: 11, generic: 1 }
- { descr: onSmartTrim, graph: 0, value: 12, generic: 1 }
- { descr: ecoMode, graph: 0, value: 13, generic: 0 }
- { descr: hotStandby, graph: 0, value: 14, generic: 0 }
- { descr: onBatteryTest, graph: 0, value: 15, generic: 1 }
- { descr: emergencyStaticBypass, graph: 0, value: 16, generic: 2 }
- { descr: staticBypassStandby, graph: 0, value: 17, generic: 1 }
- { descr: powerSavingMode, graph: 0, value: 18, generic: 0 }
- { descr: spotMode, graph: 0, value: 19, generic: 0 }
- { descr: eConversion, graph: 0, value: 20, generic: 0 }
- { descr: chargerSpotmode, graph: 0, value: 21, generic: 0 }
- { descr: inverterSpotmode, graph: 0, value: 22, generic: 0 }
data:
-
oid: upsBasicOutputStatus
value: upsBasicOutputStatus
num_oid: .1.3.6.1.4.1.318.1.1.1.4.1.1.
descr: Output Status
index: '{{ $index }}'
state_name: upsBasicOutputStatus
states:
- { descr: unknown, graph: 0, value: 1, generic: 3 }
- { descr: onLine, graph: 0, value: 2, generic: 0 }
- { descr: onBattery, graph: 0, value: 3, generic: 1 }
- { descr: onSmartBoost, graph: 0, value: 4, generic: 0 }
- { descr: timedSleeping, graph: 0, value: 5, generic: 0 }
- { descr: softwareBypass, graph: 0, value: 6, generic: 1 }
- { descr: off, graph: 0, value: 7, generic: 2 }
- { descr: rebooting, graph: 0, value: 8, generic: 1 }
- { descr: switchedBypass, graph: 0, value: 9, generic: 1 }
- { descr: hardwareFailureBypass, graph: 0, value: 10, generic: 2 }
- { descr: sleepingUntilPowerReturn, graph: 0, value: 11, generic: 1 }
- { descr: onSmartTrim, graph: 0, value: 12, generic: 1 }
- { descr: ecoMode, graph: 0, value: 13, generic: 0 }
- { descr: hotStandby, graph: 0, value: 14, generic: 0 }
- { descr: onBatteryTest, graph: 0, value: 15, generic: 1 }
- { descr: emergencyStaticBypass, graph: 0, value: 16, generic: 2 }
- { descr: staticBypassStandby, graph: 0, value: 17, generic: 1 }
- { descr: powerSavingMode, graph: 0, value: 18, generic: 0 }
- { descr: spotMode, graph: 0, value: 19, generic: 0 }
- { descr: eConversion, graph: 0, value: 20, generic: 0 }
- { descr: chargerSpotmode, graph: 0, value: 21, generic: 0 }
- { descr: inverterSpotmode, graph: 0, value: 22, generic: 0 }

View File

@@ -2,79 +2,83 @@ mib: NETBOTZV2-MIB
modules:
sensors:
airflow:
-
oid: airFlowSensorTable
value: airFlowSensorValue
divisor: 10
num_oid: .1.3.6.1.4.1.5528.100.4.1.5.1.2.
descr: airFlowSensorLabel
index: 'airFlowSensorValue.{{ $index }}'
data:
-
oid: airFlowSensorTable
value: airFlowSensorValue
divisor: 10
num_oid: .1.3.6.1.4.1.5528.100.4.1.5.1.2.
descr: airFlowSensorLabel
index: 'airFlowSensorValue.{{ $index }}'
temperature:
-
oid: dewPointSensorTable
value: dewPointSensorValue
divisor: 10
num_oid: .1.3.6.1.4.1.5528.100.4.1.3.1.2.
descr: dewPointSensorLabel
index: 'dewPointSensorValue.{{ $index }}'
-
oid: tempSensorTable
value: tempSensorValueInt
num_oid: .1.3.6.1.4.1.5528.100.4.1.1.1.8.
descr: tempSensorLabel
index: '{{ $index }}'
data:
-
oid: dewPointSensorTable
value: dewPointSensorValue
divisor: 10
num_oid: .1.3.6.1.4.1.5528.100.4.1.3.1.2.
descr: dewPointSensorLabel
index: 'dewPointSensorValue.{{ $index }}'
-
oid: tempSensorTable
value: tempSensorValueInt
num_oid: .1.3.6.1.4.1.5528.100.4.1.1.1.8.
descr: tempSensorLabel
index: '{{ $index }}'
humidity:
-
oid: humiSensorTable
value: humiSensorValue
num_oid: .1.3.6.1.4.1.5528.100.4.1.2.1.8.
descr: humiSensorLabel
index: '{{ $index }}'
data:
-
oid: humiSensorTable
value: humiSensorValue
num_oid: .1.3.6.1.4.1.5528.100.4.1.2.1.8.
descr: humiSensorLabel
index: '{{ $index }}'
state:
-
oid: dryContactSensorTable
value: dryContactSensorValue
num_oid: .1.3.6.1.4.1.5528.100.4.2.1.1.2.
descr: dryContactSensorLabel
index: 'dryContactSensor.{{ $index }}'
state_name: dryContactSensor
states:
- { descr: 'null', graph: 0, value: -1, generic: 3 }
- { descr: open, graph: 0, value: 0, generic: 0 }
- { descr: closed, graph: 0, value: 1, generic: 2 }
-
oid: doorSwitchSensorTable
value: doorSwitchSensorValue
num_oid: .1.3.6.1.4.1.5528.100.4.2.2.1.2.
descr: doorSwitchSensorLabel
index: 'doorSwitchSensor.{{ $index }}'
state_name: doorSwitchSensor
states:
- { descr: 'null', graph: 0, value: -1, generic: 3 }
- { descr: open, graph: 0, value: 0, generic: 0 }
- { descr: closed, graph: 0, value: 1, generic: 2 }
-
oid: cameraMotionSensorTable
value: cameraMotionSensorValue
num_oid: .1.3.6.1.4.1.5528.100.4.2.3.1.2.
descr: cameraMotionSensorLabel
index: 'cameraMotionSensor.{{ $index }}'
state_name: cameraMotionSensor
states:
- { descr: 'null', graph: 0, value: -1, generic: 3 }
- { descr: noMotion, graph: 0, value: 0, generic: 0 }
- { descr: motionDetected, graph: 0, value: 1, generic: 2 }
-
oid: otherStateSensorTable
value: otherStateSensorErrorStatus
num_oid: .1.3.6.1.4.1.5528.100.4.2.10.1.3.
descr: otherStateSensorLabel
index: '{{ $index }}'
state_name: otherStateSensorErrorStatus
states:
- { descr: normal, graph: 0, value: 0, generic: 0 }
- { descr: info, graph: 0, value: 1, generic: 1 }
- { descr: warning, graph: 0, value: 2, generic: 1 }
- { descr: error, graph: 0, value: 3, generic: 2 }
- { descr: critical, graph: 0, value: 4, generic: 2 }
- { descr: failure, graph: 0, value: 5, generic: 2 }
data:
-
oid: dryContactSensorTable
value: dryContactSensorValue
num_oid: .1.3.6.1.4.1.5528.100.4.2.1.1.2.
descr: dryContactSensorLabel
index: 'dryContactSensor.{{ $index }}'
state_name: dryContactSensor
states:
- { descr: 'null', graph: 0, value: -1, generic: 3 }
- { descr: open, graph: 0, value: 0, generic: 0 }
- { descr: closed, graph: 0, value: 1, generic: 2 }
-
oid: doorSwitchSensorTable
value: doorSwitchSensorValue
num_oid: .1.3.6.1.4.1.5528.100.4.2.2.1.2.
descr: doorSwitchSensorLabel
index: 'doorSwitchSensor.{{ $index }}'
state_name: doorSwitchSensor
states:
- { descr: 'null', graph: 0, value: -1, generic: 3 }
- { descr: open, graph: 0, value: 0, generic: 0 }
- { descr: closed, graph: 0, value: 1, generic: 2 }
-
oid: cameraMotionSensorTable
value: cameraMotionSensorValue
num_oid: .1.3.6.1.4.1.5528.100.4.2.3.1.2.
descr: cameraMotionSensorLabel
index: 'cameraMotionSensor.{{ $index }}'
state_name: cameraMotionSensor
states:
- { descr: 'null', graph: 0, value: -1, generic: 3 }
- { descr: noMotion, graph: 0, value: 0, generic: 0 }
- { descr: motionDetected, graph: 0, value: 1, generic: 2 }
-
oid: otherStateSensorTable
value: otherStateSensorErrorStatus
num_oid: .1.3.6.1.4.1.5528.100.4.2.10.1.3.
descr: otherStateSensorLabel
index: '{{ $index }}'
state_name: otherStateSensorErrorStatus
states:
- { descr: normal, graph: 0, value: 0, generic: 0 }
- { descr: info, graph: 0, value: 1, generic: 1 }
- { descr: warning, graph: 0, value: 2, generic: 1 }
- { descr: error, graph: 0, value: 3, generic: 2 }
- { descr: critical, graph: 0, value: 4, generic: 2 }
- { descr: failure, graph: 0, value: 5, generic: 2 }

View File

@@ -2,14 +2,15 @@ mib: RITTAL-CMC-III-MIB
modules:
sensors:
state:
-
oid: cmcIIIUnitStatus
value: cmcIIIUnitStatus
state_name: cmcIIIUnitStatus
num_oid: .1.3.6.1.4.1.2606.7.2.1.
index: 'cmcIIIUnitStatus.{{ $index }}'
descr: Unit Status
states:
- { descr: OK, graph: 1, value: 1, generic: 0 }
- { descr: Failed, graph: 1, value: 2, generic: 2 }
- { descr: Overload, graph: 1, value: 3, generic: 1 }
data:
-
oid: cmcIIIUnitStatus
value: cmcIIIUnitStatus
state_name: cmcIIIUnitStatus
num_oid: .1.3.6.1.4.1.2606.7.2.1.
index: 'cmcIIIUnitStatus.{{ $index }}'
descr: Unit Status
states:
- { descr: OK, graph: 1, value: 1, generic: 0 }
- { descr: Failed, graph: 1, value: 2, generic: 2 }
- { descr: Overload, graph: 1, value: 3, generic: 1 }

View File

@@ -1049,30 +1049,65 @@ function ignore_storage($descr)
return $deny;
}
/**
* @param $value
* @param $data
* @param $group
* @return bool
*/
function can_skip_sensor($value, $data, $group)
{
$skip_values = array_replace((array)$group['skip_values'], (array)$data['skip_values']);
foreach ($skip_values as $skip_value) {
if ($value == $skip_value) {
return true;
}
}
$skip_values_lt = array_replace((array)$group['skip_value_lt'], (array)$data['skip_value_lt']);
foreach ($skip_value_lt as $skip_value) {
if ($value < $skip_value) {
return true;
}
}
$skip_values_gt = array_reduce((array)$group['skip_value_gt'], (array)$data['skip_value_gt']);
foreach ($skip_value_gt as $skip_value) {
if ($value > $skip_value) {
return true;
}
}
return false;
}
/**
* @param $valid
* @param $device
* @param $sensor_type
* @param $pre_cache
*/
function discovery_process(&$valid, $device, $sensor_type, $pre_cache)
{
if ($device['dynamic_discovery']['modules']['sensors'][$sensor_type]) {
foreach ($device['dynamic_discovery']['modules']['sensors'][$sensor_type] as $data) {
$sensor_options = array();
if (isset($device['dynamic_discovery']['modules']['sensors'][$sensor_type]['options'])) {
$sensor_options = $device['dynamic_discovery']['modules']['sensors'][$sensor_type]['options'];
}
foreach ($device['dynamic_discovery']['modules']['sensors'][$sensor_type]['data'] as $data) {
$tmp_name = $data['oid'];
$raw_data = $pre_cache[$tmp_name];
foreach ($raw_data as $index => $snmp_data) {
$skip = false;
$value = $snmp_data[$data['value']];
foreach ((array)$data['skip_values'] as $skip_value) {
echo "Here $value and $skip_value END\n";
if ($value == $skip_value) {
$skip = true;
}
}
if ($skip === false && is_numeric($value)) {
$value = $snmp_data[$data['value']] ?: $snmp_data[$data['oid']];
if (can_skip_sensor($value, $data, $sensor_options) === false && is_numeric($value)) {
$oid = $data['num_oid'] . $index;
if (isset($snmp_data[$data['descr']])) {
$descr = $snmp_data[$data['descr']];
} else {
$descr = str_replace('{{ $index }}', $index, $data['descr']);
}
$divisor = $data['divisor'] ?: 1;
$multiplier = $data['multiplier'] ?: 1;
$divisor = $data['divisor'] ?: $sensor_options['divisor'] ?: 1;
$multiplier = $data['multiplier'] ?: $sensor_options['multiplier'] ?: 1;
$low_limit = $data['low_limit'] ?: 'null';
$low_warn_limit = $data['low_warn_limit'] ?: 'null';
$warn_limit = $data['warn_limit'] ?: 'null';
@@ -1086,7 +1121,7 @@ function discovery_process(&$valid, $device, $sensor_type, $pre_cache)
$value = $value * $multiplier;
}
} else {
$state_name = $data['state_name'];
$state_name = $data['state_name'] ?: $data['oid'];
$state_index_id = create_state_index($state_name);
if ($state_index_id != null) {
foreach ($data['states'] as $state) {

View File

@@ -64,10 +64,10 @@ class YamlTest extends \PHPUnit_Framework_TestCase
foreach ($data['modules'] as $module => $sub_modules) {
foreach ($sub_modules as $sub_module) {
foreach ($sub_module as $sensor) {
foreach ($sub_module['data'] as $sensor) {
$this->assertArrayHasKey('oid', $sensor, $file);
$this->assertArrayHasKey('num_oid', $sensor, $file);
$this->assertArrayHasKey('value', $sensor, $file);
$this->assertArrayHasKey('descr', $sensor, $file);
}
}
}