Skip to content

Commit c449de1

Browse files
dot-mikelaf
andauthored
Updated support for eltek enexus devices (librenms#18269)
* better support for eltek enexus * apply ci styling fix * fix null check for location * fix null check * fix php stan error for null check of location * refactor enexus.yaml to hardcode SP2-MIB OID for clarity. Also add overall rectifiersStatus * refactor enexus.inc.php to remove pre-cache and use snmquery class for batterytest * enexus remove debug statement * fix enexus to use SP2-MIB in variable for descriptions * enexus style ci * enexus: add batteryTestDuration * fix: update entPhysicalIndex for rectifiers to ensure correct indexing * fix: add entPhysicalIndex for chassis and introduce loadCurrent sensor * fix: add entPhysicalIndex for battery banks and load fuses in Enexus * fix: add battery quality and capacity metrics to Enexus MIB * style ci * fix: update state_name for power system mode * fix: replace snmp_get with SnmpQuery for battery test duration retrieval * Updated tests data and moved count sensor to yaml * Removed invalid limits * Renamed high_warn_limit --------- Co-authored-by: Neil Lathwood <gh+n@laf.io>
1 parent 465bc1e commit c449de1

File tree

14 files changed

+20982
-535
lines changed

14 files changed

+20982
-535
lines changed

LibreNMS/OS/Enexus.php

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
<?php
2+
3+
namespace LibreNMS\OS;
4+
5+
use App\Models\Device;
6+
use App\Models\EntPhysical;
7+
use App\Models\Location;
8+
use Illuminate\Support\Collection;
9+
use LibreNMS\Interfaces\Discovery\OSDiscovery;
10+
use LibreNMS\OS;
11+
use SnmpQuery;
12+
13+
class Enexus extends OS implements OSDiscovery
14+
{
15+
public function discoverOS(Device $device): void
16+
{
17+
parent::discoverOS($device); // yaml
18+
}
19+
20+
public function fetchLocation(): Location
21+
{
22+
$location = parent::fetchLocation();
23+
24+
$latIntRaw = SnmpQuery::get('SP2-MIB::powerSystemLatitude.0')->value();
25+
$latFracRaw = SnmpQuery::get('SP2-MIB::powerSystemLatitudeDecimal.0')->value();
26+
$longIntRaw = SnmpQuery::get('SP2-MIB::powerSystemLongitude.0')->value();
27+
$longFracRaw = SnmpQuery::get('SP2-MIB::powerSystemLongitudeDecimal.0')->value();
28+
29+
$lat = null;
30+
$long = null;
31+
32+
if ($latIntRaw !== '' && $latFracRaw !== '') {
33+
$latInt = (int) $latIntRaw;
34+
$latFrac = (int) $latFracRaw;
35+
$lat = $latInt + ($latFrac / 1000000);
36+
}
37+
38+
if ($longIntRaw !== '' && $longFracRaw !== '') {
39+
$longInt = (int) $longIntRaw;
40+
$longFrac = (int) $longFracRaw;
41+
$long = $longInt + ($longFrac / 1000000);
42+
}
43+
44+
$location->lng = $long !== null ? (float) $long : null;
45+
$location->lat = $lat !== null ? (float) $lat : null;
46+
47+
return $location;
48+
}
49+
50+
public function discoverEntityPhysical(): Collection
51+
{
52+
$inventory = new Collection;
53+
// Create a fake Chassis to host the modules we discover
54+
$inventory->push(new EntPhysical([
55+
'entPhysicalIndex' => 10,
56+
'entPhysicalDescr' => 'Chassis',
57+
'entPhysicalClass' => 'chassis',
58+
'entPhysicalName' => 'Chassis',
59+
'entPhysicalModelName' => 'Eltek',
60+
'entPhysicalSerialNum' => SnmpQuery::get('SP2-MIB::powerSystemSerialNumber.0')->value(),
61+
'entPhysicalContainedIn' => 0,
62+
'entPhysicalParentRelPos' => 0,
63+
'entPhysicalMfgName' => 'Eltek',
64+
'entPhysicalIsFRU' => 'false',
65+
]));
66+
67+
$controlUnits = SnmpQuery::walk('SP2-MIB::controlUnitTable')->table(1);
68+
foreach ($controlUnits as $controlUnitIndex => $controlUnit) {
69+
$inventory->push(new EntPhysical([
70+
'entPhysicalIndex' => $controlUnitIndex + 1000,
71+
'entPhysicalDescr' => 'Front Panel',
72+
'entPhysicalClass' => 'module',
73+
'entPhysicalName' => $controlUnit['SP2-MIB::controlUnitDescription'] ?? null,
74+
'entPhysicalModelName' => $controlUnit['SP2-MIB::controlUnitHwPartNumber'] ?? null,
75+
'entPhysicalSerialNum' => $controlUnit['SP2-MIB::controlUnitSerialNumber'] ?? null,
76+
'entPhysicalContainedIn' => 10,
77+
'entPhysicalMfgName' => 'Eltek',
78+
'entPhysicalParentRelPos' => $controlUnitIndex,
79+
'entPhysicalHardwareRev' => $controlUnit['SP2-MIB::controlUnitHwVersion'] ?? null,
80+
'entPhysicalSoftwareRev' => $controlUnit['SP2-MIB::controlUnitSwVersion'] ?? null,
81+
'entPhysicalFirmwareRev' => null,
82+
'entPhysicalIsFRU' => 'true',
83+
]));
84+
}
85+
86+
$rectifiers = SnmpQuery::walk('SP2-MIB::rectifierTable')->table(1);
87+
foreach ($rectifiers as $rectifierIndex => $rectifier) {
88+
$inventory->push(new EntPhysical([
89+
'entPhysicalIndex' => (int) ('2' . $rectifierIndex),
90+
'entPhysicalDescr' => 'Rectifier ' . ($rectifier['SP2-MIB::rectifierType'] ?? $rectifierIndex),
91+
'entPhysicalClass' => 'module',
92+
'entPhysicalName' => $rectifier['SP2-MIB::rectifierType'] ?? null,
93+
'entPhysicalModelName' => $rectifier['SP2-MIB::rectifierHwPartNumber'] ?? null,
94+
'entPhysicalSerialNum' => $rectifier['SP2-MIB::rectifierEntry.10'] ?? null, // rectifierSerialNumber missing in SP2-MIB
95+
'entPhysicalContainedIn' => 10,
96+
'entPhysicalMfgName' => 'Eltek',
97+
'entPhysicalParentRelPos' => $rectifierIndex,
98+
'entPhysicalHardwareRev' => $rectifier['SP2-MIB::rectifierHwVersion'] ?? null,
99+
'entPhysicalSoftwareRev' => $rectifier['SP2-MIB::rectifierSwVersion'] ?? null,
100+
'entPhysicalFirmwareRev' => null,
101+
'entPhysicalIsFRU' => 'true',
102+
]));
103+
}
104+
105+
$batteryInstalledType = SnmpQuery::get('SP2-MIB::batteryDescription.0')->value();
106+
$inventory->push(new EntPhysical([
107+
'entPhysicalIndex' => 100,
108+
'entPhysicalDescr' => 'Battery',
109+
'entPhysicalClass' => 'module',
110+
'entPhysicalName' => $batteryInstalledType,
111+
'entPhysicalModelName' => $batteryInstalledType,
112+
'entPhysicalSerialNum' => SnmpQuery::get('SP2-MIB::batterySerialNumber.0')->value(),
113+
'entPhysicalContainedIn' => 10,
114+
'entPhysicalMfgName' => 'Eltek',
115+
'entPhysicalParentRelPos' => 100,
116+
'entPhysicalHardwareRev' => null,
117+
'entPhysicalSoftwareRev' => null,
118+
'entPhysicalFirmwareRev' => null,
119+
'entPhysicalIsFRU' => 'true',
120+
]));
121+
122+
$batteryBanks = SnmpQuery::walk('SP2-MIB::batteryBankTable')->table(1);
123+
foreach ($batteryBanks as $batteryBankIndex => $batteryBank) {
124+
$inventory->push(new EntPhysical([
125+
'entPhysicalIndex' => (int) ('3' . $batteryBankIndex),
126+
'entPhysicalDescr' => 'Battery Bank ' . $batteryBankIndex,
127+
'entPhysicalClass' => 'module',
128+
'entPhysicalName' => 'Battery Bank ' . $batteryBankIndex,
129+
'entPhysicalModelName' => $batteryInstalledType,
130+
'entPhysicalSerialNum' => null,
131+
'entPhysicalContainedIn' => 100, // Contained in main Battery module
132+
'entPhysicalMfgName' => 'Eltek',
133+
'entPhysicalParentRelPos' => $batteryBankIndex,
134+
'entPhysicalHardwareRev' => null,
135+
'entPhysicalSoftwareRev' => null,
136+
'entPhysicalFirmwareRev' => null,
137+
'entPhysicalIsFRU' => 'true',
138+
]));
139+
}
140+
141+
$loadFuses = SnmpQuery::walk('SP2-MIB::loadFuseTable')->table(1);
142+
foreach ($loadFuses as $loadFuseIndex => $loadFuse) {
143+
$inventory->push(new EntPhysical([
144+
'entPhysicalIndex' => (int) ('4' . $loadFuseIndex),
145+
'entPhysicalDescr' => $loadFuse['SP2-MIB::loadFuseDescription'] ?? 'Load Fuse ' . $loadFuseIndex,
146+
'entPhysicalClass' => 'module',
147+
'entPhysicalName' => $loadFuse['SP2-MIB::loadFuseDescription'] ?? 'Load Fuse ' . $loadFuseIndex,
148+
'entPhysicalModelName' => 'Load Fuse',
149+
'entPhysicalSerialNum' => null,
150+
'entPhysicalContainedIn' => 10, // Contained in Chassis
151+
'entPhysicalMfgName' => 'Eltek',
152+
'entPhysicalParentRelPos' => $loadFuseIndex,
153+
'entPhysicalHardwareRev' => null,
154+
'entPhysicalSoftwareRev' => null,
155+
'entPhysicalFirmwareRev' => null,
156+
'entPhysicalIsFRU' => 'true',
157+
]));
158+
}
159+
160+
return $inventory;
161+
}
162+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
$battery_test_result_table = SnmpQuery::walk('batteryTestResultTable')->table(1);
4+
if (! empty($battery_test_result_table)) {
5+
$numeric_results = array_filter($battery_test_result_table, function ($key) {
6+
return is_int($key);
7+
}, ARRAY_FILTER_USE_KEY);
8+
if (empty($numeric_results)) {
9+
return;
10+
}
11+
$last_index = max(array_keys($numeric_results));
12+
$batteryQualityResult = $numeric_results[$last_index]['batteryTestResultQuality'];
13+
discover_sensor(
14+
null,
15+
'percent',
16+
$device,
17+
'.1.3.6.1.4.1.12148.10.10.16.4.1.5',
18+
'batteryTestResultQuality',
19+
'batteryTestQuality',
20+
'Battery Test Quality',
21+
1,
22+
1,
23+
null,
24+
null,
25+
null,
26+
null,
27+
$batteryQualityResult,
28+
'snmp',
29+
null,
30+
null,
31+
null,
32+
null,
33+
'gauge'
34+
);
35+
36+
unset($numeric_results, $last_index, $batteryQualityResult);
37+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
$battery_test_result_table = SnmpQuery::walk('batteryTestResultTable')->table(1);
4+
if (! empty($battery_test_result_table)) {
5+
$numeric_results = array_filter($battery_test_result_table, function ($key) {
6+
return is_int($key);
7+
}, ARRAY_FILTER_USE_KEY);
8+
if (empty($numeric_results)) {
9+
return;
10+
}
11+
$last_index = max(array_keys($numeric_results));
12+
$batteryResultDuration = $numeric_results[$last_index]['batteryTestResultDuration'];
13+
discover_sensor(
14+
null,
15+
'runtime',
16+
$device,
17+
'.1.3.6.1.4.1.12148.10.10.16.4.1.3',
18+
'batteryTestResultDuration',
19+
'batteryTestDuration',
20+
'Battery Test Duration',
21+
1,
22+
1,
23+
null,
24+
null,
25+
null,
26+
null,
27+
$batteryResultDuration,
28+
'snmp',
29+
null,
30+
null,
31+
null,
32+
null,
33+
'gauge'
34+
);
35+
36+
unset($numeric_results, $last_index, $batteryResultDuration);
37+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
use Illuminate\Support\Arr;
4+
5+
if ($sensor['sensor_type'] === 'batteryTestQuality') {
6+
$raw = SnmpQuery::walk($sensor['sensor_oid'])->values();
7+
$sensor_value = Arr::last($raw);
8+
unset($raw);
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
use Illuminate\Support\Arr;
4+
5+
if ($sensor['sensor_type'] === 'batteryTestDuration') {
6+
$raw = SnmpQuery::walk($sensor['sensor_oid'])->values();
7+
$sensor_value = Arr::last($raw);
8+
unset($raw);
9+
}

resources/definitions/os_detection/enexus.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ discovery:
2020
op: '!='
2121
value: false
2222
poller_modules:
23-
entity-physical: false
23+
entity-physical: true
2424
hr-mib: false
2525
ipSystemStats: false
2626
netstats: false
@@ -30,7 +30,7 @@ poller_modules:
3030
stp: false
3131
discovery_modules:
3232
ports-stack: false
33-
entity-physical: false
33+
entity-physical: true
3434
processors: false
3535
mempools: false
3636
cisco-vrf-lite: false

0 commit comments

Comments
 (0)