Transceiver Support (#16165)

* Add transceivers module

Move os specific code to OS

Fix errors and updated connector names

Add RouterOS, a lot less data there.

Add Comware

Add Exa, required a transformer function (mw to dBm)

Add Junos, revision was too short

Just starting on ui

Graphs, and more ui
some polling fixes

collapse header for small screens

refactor a bit

Missed graphs

Transceivers icon inline

Use @once on popup javascript

update db_schema.yaml

Don't show transceivers in basic view
basic view could use a review

Apply fixes from StyleCI

API functions

Comware don't fail if port is missing

Apply fixes from StyleCI

Add alert rules to collection

Device Overview

Attempt to fix bad alert rule, probably needs more

Fix up Comware and remove old sensors

Mark transceiver metrics without thresholds as Unknown

Routeros cleanup

Exa cleanup

Handle missing port

Graph allow filter by channel

More translations

Add transceiver graphs to port graphs

Add Cisco support, use entPhyscial module data if available

Fix OcNos divisors

Labels on transceiver page

Show encoding if available

Hacky OcNos port mapping

Fix up Junos optics and remove old sensors

FS switch support
Metric casts to prevent thrashing
Extra transform_function support

Add link to transceivers page from overview

Change default sort to group by type, then channel
move some code out of overview blade template
Fix bad type ocnos

Apply fixes from StyleCI

Add scales to graphs

Add some test data

Default sort order for metrcis in SQL applied by default

Transceiver metrics threshold manual settings via WebUI and API

Fixes to channels verbiage

Fix severity calculations

Add cable field for SM/MM/Copper

Apply fixes from StyleCI

update test data

Show DDM

Update DB schema file

Extend serial field to 32, even though devices shouldn't be able to have one longer than 16

Missing import

Add status field to database, that way we can support snmp implementations that only return an enum

Add missing files

Fix db_schema

Fix style

Fixes

Style fix

Work around phpstan issue

Update transceivers.blade.php

Missed getStatus() call

Prevent extra dots when channels are not changed

Update module to match upstream

Save ocnos metrics as sensors

Move to regular sensors

add entity physical index

Update UI to sensors WIP

Apply fixes from StyleCI

Forgot one change

Update ui to use sensors

Remove transceiver metrics

Remove metric os discover code
fs-switch pending

Remove transceiver metrics for fs-centec

Exa link up

Revert all test data

Fix up transceiver module interface

Remove unused Convert class

comware cache and transceiver type

Fix some transceiver metrics filtering and formatting issues

Consolidate display formatting

Coalesce commare hh3cTransceiverTable walks to prevent double walk

Use group to identify transceiver sensors

Fixup routeros

Fix up cisco

update db_schema

Small addition to docs

Improve overview layout and add graph popup

Update Junos

update css files

ddm should be nullable

Increase the field length for type and model

Cisco Improve detection when there is an intermediary container

Add transceiver test data

Apply fixes from StyleCI

Fix incorrect test data

Improve display formatting

Fix test data

Apply fixes from StyleCI

Fix up more data

Fix up more data

Fix incorrect return type in routeros

Update ocnos data

* Remove some remaining references to transceiver_metrics table
This commit is contained in:
Tony Murray
2024-09-29 11:05:44 -05:00
committed by GitHub
parent 8d2bf6ceb0
commit e08571c38c
128 changed files with 80016 additions and 2810 deletions

View File

@@ -0,0 +1,39 @@
<?php
/*
* TransceiverDiscovery.php
*
* -Description-
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package LibreNMS
* @link http://librenms.org
* @copyright 2024 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace LibreNMS\Interfaces\Discovery;
use Illuminate\Support\Collection;
interface TransceiverDiscovery
{
/**
* Discover transceivers.
* Distance is in meters.
*
* @return Collection<\App\Models\Transceiver>
*/
public function discoverTransceivers(): Collection;
}

View File

@@ -84,6 +84,8 @@ interface Module
* You should always order the data by a non-transient column.
* Some id fields may need to be joined to tie back to non-transient data.
* Module may return null if testing is not supported or required.
*
* @param string $type Type is either discovery or poller
*/
public function dump(Device $device, string $type): ?array;
}

View File

@@ -0,0 +1,96 @@
<?php
/*
* Transceivers.php
*
* -Description-
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package LibreNMS
* @link http://librenms.org
* @copyright 2024 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace LibreNMS\Modules;
use App\Models\Device;
use App\Models\Transceiver;
use App\Observers\ModuleModelObserver;
use LibreNMS\DB\SyncsModels;
use LibreNMS\Interfaces\Data\DataStorageInterface;
use LibreNMS\Interfaces\Discovery\TransceiverDiscovery;
use LibreNMS\Interfaces\Module;
use LibreNMS\OS;
use LibreNMS\Polling\ModuleStatus;
class Transceivers implements Module
{
use SyncsModels;
public function dependencies(): array
{
return ['ports'];
}
public function shouldDiscover(OS $os, ModuleStatus $status): bool
{
return $status->isEnabledAndDeviceUp($os->getDevice()) && $os instanceof TransceiverDiscovery;
}
public function shouldPoll(OS $os, ModuleStatus $status): bool
{
return false;
}
public function discover(OS $os): void
{
if ($os instanceof TransceiverDiscovery) {
$discoveredTransceivers = $os->discoverTransceivers();
// save transceivers
ModuleModelObserver::observe(Transceiver::class);
$this->syncModels($os->getDevice(), 'transceivers', $discoveredTransceivers);
}
}
public function poll(OS $os, DataStorageInterface $datastore): void
{
// no polling
}
public function dataExists(Device $device): bool
{
return $device->transceivers()->exists();
}
public function cleanup(Device $device): int
{
return $device->transceivers()->delete();
}
public function dump(Device $device, string $type): ?array
{
if ($type == 'poller') {
return null;
}
return [
'transceivers' => $device->transceivers()->orderBy('index')
->leftJoin('ports', 'transceivers.port_id', 'ports.port_id')
->select(['transceivers.*', 'ifIndex'])
->get()->map->makeHidden(['id', 'created_at', 'updated_at', 'device_id', 'port_id']),
];
}
}

View File

@@ -27,13 +27,15 @@ namespace LibreNMS\OS;
use App\Models\Device;
use App\Models\Mempool;
use App\Models\Transceiver;
use Illuminate\Support\Collection;
use LibreNMS\Device\Processor;
use LibreNMS\Interfaces\Discovery\MempoolsDiscovery;
use LibreNMS\Interfaces\Discovery\ProcessorDiscovery;
use LibreNMS\Interfaces\Discovery\TransceiverDiscovery;
use LibreNMS\OS;
class Comware extends OS implements MempoolsDiscovery, ProcessorDiscovery
class Comware extends OS implements MempoolsDiscovery, ProcessorDiscovery, TransceiverDiscovery
{
public function discoverOS(Device $device): void
{
@@ -107,4 +109,27 @@ class Comware extends OS implements MempoolsDiscovery, ProcessorDiscovery
return $mempools;
}
public function discoverTransceivers(): Collection
{
$ifIndexToPortId = $this->getDevice()->ports()->pluck('port_id', 'ifIndex');
return \SnmpQuery::cache()->enumStrings()->walk('HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverInfoTable')->mapTable(function ($data, $ifIndex) use ($ifIndexToPortId) {
return new Transceiver([
'port_id' => $ifIndexToPortId->get($ifIndex, 0),
'index' => $ifIndex,
'type' => $data['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverType'] ?? null,
'vendor' => $data['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverVendorName'] ?? null,
'oui' => $data['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverVendorOUI'] ?? null,
'revision' => $data['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverRevisionNumber'] ?? null,
'model' => $data['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverPartNumber'] ?? null,
'serial' => $data['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverSerialNumber'] ?? null,
'ddm' => isset($data['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverDiagnostic']) && $data['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverDiagnostic'] == 'true',
'cable' => $data['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverHardwareType'] ?? null,
'distance' => $data['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverTransferDistance'] ?? null,
'wavelength' => isset($data['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverWaveLength']) && $data['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverWaveLength'] != 2147483647 ? $data['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverWaveLength'] : null,
'entity_physical_index' => $ifIndex,
]);
});
}
}

View File

@@ -26,10 +26,13 @@
namespace LibreNMS\OS;
use App\Models\Device;
use App\Models\Transceiver;
use Illuminate\Support\Collection;
use LibreNMS\Interfaces\Discovery\OSDiscovery;
use LibreNMS\Interfaces\Discovery\TransceiverDiscovery;
use LibreNMS\OS;
class Exa extends OS implements OSDiscovery
class Exa extends OS implements OSDiscovery, TransceiverDiscovery
{
public function discoverOS(Device $device): void
{
@@ -47,4 +50,34 @@ class Exa extends OS implements OSDiscovery
return ($card_count[$card] > 1 ? $card_count[$card] . 'x ' : '') . $card;
}, array_keys($card_count)));
}
public function discoverTransceivers(): Collection
{
$ifIndexToPortId = $this->getDevice()->ports()->pluck('port_id', 'ifIndex');
return \SnmpQuery::cache()->walk('E7-Calix-MIB::e7OltPonPortTable')->mapTable(function ($data, $shelf, $card, $port) use ($ifIndexToPortId) {
if ($data['E7-Calix-MIB::e7OltPonPortStatus'] == 0) {
return null;
}
$ifIndex = self::getIfIndex($shelf, $card, $port, 'gpon');
return new Transceiver([
'port_id' => $ifIndexToPortId->get($ifIndex),
'index' => "$shelf.$card.$port",
'entity_physical_index' => $ifIndex,
]);
})->filter();
}
public static function getIfIndex(int $chassis, int $slot, int $id, string $type): int
{
// doesn't work for stacked chassis, I don't have enough info to figure out how it works
$offset = match ($type) {
'gpon' => 20000,
default => 0,
};
return $offset + (10000 * $chassis) + ($slot * 100) + $id;
}
}

55
LibreNMS/OS/FsCentec.php Normal file
View File

@@ -0,0 +1,55 @@
<?php
namespace LibreNMS\OS;
use App\Models\Transceiver;
use Illuminate\Support\Collection;
use LibreNMS\Interfaces\Discovery\TransceiverDiscovery;
use LibreNMS\OS;
use SnmpQuery;
class FsCentec extends OS implements TransceiverDiscovery
{
public function discoverTransceivers(): Collection
{
$ifIndexToPortId = $this->getDevice()->ports()->pluck('port_id', 'ifIndex');
return SnmpQuery::cache()->walk('FS-SWITCH-V2-MIB::transbasicinformationTable')->mapTable(function ($data, $ifIndex) use ($ifIndexToPortId) {
if ($data['FS-SWITCH-V2-MIB::transceiveStatus'] == 'inactive') {
return null;
}
$distance = null;
$cable = null;
if (isset($data['FS-SWITCH-V2-MIB::link9SinglemodeLengthKm']) && $data['FS-SWITCH-V2-MIB::link9SinglemodeLengthKm'] != 0) {
$distance = $data['FS-SWITCH-V2-MIB::link9SinglemodeLengthKm'] * 1000;
$cable = 'SM';
} elseif (isset($data['FS-SWITCH-V2-MIB::link9SinglemodeLengthM']) && $data['FS-SWITCH-V2-MIB::link9SinglemodeLengthM'] != 0) {
$distance = $data['FS-SWITCH-V2-MIB::link9SinglemodeLengthM'];
$cable = 'SM';
} elseif (isset($data['FS-SWITCH-V2-MIB::link50MultimodeLength']) && $data['FS-SWITCH-V2-MIB::link50MultimodeLength'] != 0) {
$distance = $data['FS-SWITCH-V2-MIB::link50MultimodeLength'];
$cable = 'MM';
} elseif (isset($data['FS-SWITCH-V2-MIB::link62MultimodeLength']) && $data['FS-SWITCH-V2-MIB::link62MultimodeLength'] != 0) {
$distance = $data['FS-SWITCH-V2-MIB::link62MultimodeLength'];
$cable = 'MM';
} elseif (isset($data['FS-SWITCH-V2-MIB::linkCopperLength']) && $data['FS-SWITCH-V2-MIB::linkCopperLength'] != 0) {
$distance = $data['FS-SWITCH-V2-MIB::linkCopperLength'];
$cable = 'Copper';
}
return new Transceiver([
'port_id' => $ifIndexToPortId->get($ifIndex),
'index' => $ifIndex,
'vendor' => $data['FS-SWITCH-V2-MIB::transceiveVender'] ?? null,
'type' => $data['FS-SWITCH-V2-MIB::transceiveType'] ?? null,
'model' => $data['FS-SWITCH-V2-MIB::transceivePartNumber'] ?? null,
'serial' => $data['FS-SWITCH-V2-MIB::transceiveSerialNumber'] ?? null,
'cable' => $cable,
'distance' => $distance,
'wavelength' => $data['FS-SWITCH-V2-MIB::transceiveWaveLength'] ?? null,
'entity_physical_index' => $ifIndex,
]);
})->filter();
}
}

View File

@@ -26,10 +26,9 @@
namespace LibreNMS\OS;
use LibreNMS\Device\Processor;
use LibreNMS\Interfaces\Discovery\ProcessorDiscovery;
use LibreNMS\OS;
class FsSwitch extends OS implements ProcessorDiscovery
class FsSwitch extends OS
{
public static function normalizeTransceiverValues($value): float
{

View File

@@ -27,19 +27,22 @@ namespace LibreNMS\OS;
use App\Models\Device;
use App\Models\EntPhysical;
use App\Models\Port;
use App\Models\Sla;
use App\Models\Transceiver;
use Carbon\Carbon;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use LibreNMS\Interfaces\Data\DataStorageInterface;
use LibreNMS\Interfaces\Discovery\SlaDiscovery;
use LibreNMS\Interfaces\Discovery\TransceiverDiscovery;
use LibreNMS\Interfaces\Polling\OSPolling;
use LibreNMS\Interfaces\Polling\SlaPolling;
use LibreNMS\OS\Traits\EntityMib;
use LibreNMS\RRD\RrdDefinition;
use SnmpQuery;
class Junos extends \LibreNMS\OS implements SlaDiscovery, OSPolling, SlaPolling
class Junos extends \LibreNMS\OS implements SlaDiscovery, OSPolling, SlaPolling, TransceiverDiscovery
{
use EntityMib {
EntityMib::discoverEntityPhysical as discoverBaseEntityPhysical;
@@ -291,4 +294,58 @@ class Junos extends \LibreNMS\OS implements SlaDiscovery, OSPolling, SlaPolling
default => null,
};
}
public function discoverTransceivers(): Collection
{
$ifIndexToPortId = Port::query()->where('device_id', $this->getDeviceId())->select(['port_id', 'ifIndex', 'ifName'])->get()->keyBy('ifIndex');
$entPhysical = SnmpQuery::walk('ENTITY-MIB::entityPhysical')->table(1);
$jnxDomCurrentTable = SnmpQuery::cache()->walk('JUNIPER-DOM-MIB::jnxDomCurrentTable')->mapTable(function ($data, $ifIndex) use ($ifIndexToPortId, $entPhysical) {
$ent = $this->findTransceiverEntityByPortName($entPhysical, $ifIndexToPortId->get($ifIndex)?->ifName);
if (empty($ent)) {
return null; // no module
}
return new Transceiver([
'port_id' => $ifIndexToPortId->get($ifIndex)->port_id,
'index' => $ifIndex,
'type' => $ent['ENTITY-MIB::entPhysicalName'] ?? null,
'vendor' => $ent['ENTITY-MIB::entPhysicalMfgName'] ?? null,
'model' => $ent['ENTITY-MIB::entPhysicalModelName'] ?? null,
'revision' => $ent['ENTITY-MIB::entPhysicalHardwareRev'] ?? null,
'serial' => $ent['ENTITY-MIB::entPhysicalSerialNum'] ?? null,
'channels' => $data['JUNIPER-DOM-MIB::jnxDomCurrentModuleLaneCount'] ?? 0,
'entity_physical_index' => $ifIndex,
]);
})->filter();
if ($jnxDomCurrentTable->isNotEmpty()) {
return $jnxDomCurrentTable;
}
// could use improvement by mapping JUNIPER-IFOPTICS-MIB::jnxOpticsConfigTable for a tiny bit more info
return SnmpQuery::cache()->walk('JUNIPER-IFOPTICS-MIB::jnxOpticsPMCurrentTable')
->mapTable(function ($data, $ifIndex) use ($ifIndexToPortId) {
return new Transceiver([
'port_id' => $ifIndexToPortId->get($ifIndex)->port_id,
'index' => $ifIndex,
'entity_physical_index' => $ifIndex,
]);
});
}
private function findTransceiverEntityByPortName(array $entPhysical, string $ifName): array
{
if (preg_match('#-(\d+/\d+/\d+)#', $ifName, $matches)) {
$expected_tail = ' @ ' . $matches[1];
foreach ($entPhysical as $entity) {
if (isset($entity['ENTITY-MIB::entPhysicalDescr']) && str_ends_with($entity['ENTITY-MIB::entPhysicalDescr'], $expected_tail)) {
return $entity;
}
}
}
return [];
}
}

View File

@@ -3,14 +3,17 @@
namespace LibreNMS\OS;
use App\Models\EntPhysical;
use App\Models\Transceiver;
use Illuminate\Support\Collection;
use LibreNMS\Interfaces\Discovery\EntityPhysicalDiscovery;
use LibreNMS\Interfaces\Discovery\TransceiverDiscovery;
use LibreNMS\OS;
use SnmpQuery;
class Ocnos extends OS implements EntityPhysicalDiscovery
class Ocnos extends OS implements EntityPhysicalDiscovery, TransceiverDiscovery
{
private bool $sfpSeen = false;
private ?Collection $ifNamePortIdMap = null;
public function discoverEntityPhysical(): Collection
{
@@ -75,6 +78,12 @@ class Ocnos extends OS implements EntityPhysicalDiscovery
}
$transceivers = SnmpQuery::enumStrings()->walk('IPI-CMM-CHASSIS-MIB::cmmTransEEPROMTable')->table(2);
// load port name to port_id map
if (! empty($transceivers)) {
$ifNameToIndex = array_flip(SnmpQuery::cache()->walk('IF-MIB::ifName')->pluck());
}
foreach ($transceivers as $cmmStackUnitIndex => $chassisTransceivers) {
foreach ($chassisTransceivers as $cmmTransIndex => $transceiver) {
$inventory->push(new EntPhysical([
@@ -89,7 +98,7 @@ class Ocnos extends OS implements EntityPhysicalDiscovery
'entPhysicalParentRelPos' => $cmmTransIndex,
'entPhysicalHardwareRev' => $transceiver['IPI-CMM-CHASSIS-MIB::cmmTransVendorRevision'] ?? null,
'entPhysicalIsFRU' => 'true',
'ifIndex' => $this->guessPortId($cmmTransIndex, $transceiver['IPI-CMM-CHASSIS-MIB::cmmTransType'] ?? 'missing'),
'ifIndex' => $ifNameToIndex[$this->guessIfName($cmmTransIndex, $transceiver['IPI-CMM-CHASSIS-MIB::cmmTransType'] ?? 'missing')] ?? null,
]));
}
}
@@ -152,7 +161,7 @@ class Ocnos extends OS implements EntityPhysicalDiscovery
return $description;
}
private function guessPortId($cmmTransIndex, $cmmTransType): int
public function guessIfName($cmmTransIndex, $cmmTransType): ?string
{
// IP Infusion has no reliable way of mapping a transceiver to a port it varies by hardware
@@ -167,7 +176,7 @@ class Ocnos extends OS implements EntityPhysicalDiscovery
$this->sfpSeen = true;
}
$portName = match ($this->getDevice()->hardware) {
return match ($this->getDevice()->hardware) {
'Ufi Space S9600-32X-R' => $prefix . ($this->sfpSeen ? ($cmmTransType == 'qsfp' ? $cmmTransIndex - 5 : $cmmTransIndex - 2) : $cmmTransIndex - 1),
'Ufi Space S9510-28DC-B' => $prefix . ($cmmTransIndex - 1),
'Ufi Space S9500-30XS-P' => $prefix . ($cmmTransType == 'qsfp' ? $cmmTransIndex - 29 : $cmmTransIndex - 1),
@@ -176,14 +185,79 @@ class Ocnos extends OS implements EntityPhysicalDiscovery
'Edgecore 7712-32X-O-AC-F' => $prefix . $cmmTransIndex . '/1',
default => null, // no port map, so we can't guess
};
}
if ($portName === null) {
return 0; // give up
}
public function discoverTransceivers(): Collection
{
return SnmpQuery::enumStrings()->walk('IPI-CMM-CHASSIS-MIB::cmmTransEEPROMTable')->mapTable(function ($data, $cmmStackUnitIndex, $cmmTransIndex) {
$distance = 0;
if (! empty($data['IPI-CMM-CHASSIS-MIB::cmmTransLengthMtrs']) && $data['IPI-CMM-CHASSIS-MIB::cmmTransLengthMtrs'] !== '-100002') {
$distance = (int) $data['IPI-CMM-CHASSIS-MIB::cmmTransLengthMtrs'];
} elseif (! empty($data['IPI-CMM-CHASSIS-MIB::cmmTransLengthKmtrs']) && $data['IPI-CMM-CHASSIS-MIB::cmmTransLengthKmtrs'] !== '-100002') {
$distance = $data['IPI-CMM-CHASSIS-MIB::cmmTransLengthKmtrs'] * 1000;
} elseif (! empty($data['IPI-CMM-CHASSIS-MIB::cmmTransLengthOM4']) && $data['IPI-CMM-CHASSIS-MIB::cmmTransLengthOM4'] !== '-100002') {
$distance = (int) $data['IPI-CMM-CHASSIS-MIB::cmmTransLengthOM4'];
} elseif (! empty($data['IPI-CMM-CHASSIS-MIB::cmmTransLengthOM3']) && $data['IPI-CMM-CHASSIS-MIB::cmmTransLengthOM3'] !== '-100002') {
$distance = (int) $data['IPI-CMM-CHASSIS-MIB::cmmTransLengthOM3'];
} elseif (! empty($data['IPI-CMM-CHASSIS-MIB::cmmTransLengthOM2']) && $data['IPI-CMM-CHASSIS-MIB::cmmTransLengthOM2'] !== '-100002') {
$distance = (int) $data['IPI-CMM-CHASSIS-MIB::cmmTransLengthOM2'];
} elseif (! empty($data['IPI-CMM-CHASSIS-MIB::cmmTransLengthOM1']) && $data['IPI-CMM-CHASSIS-MIB::cmmTransLengthOM1'] !== '-100002') {
$distance = (int) $data['IPI-CMM-CHASSIS-MIB::cmmTransLengthOM1'];
}
// load port name to port_id map
$ifNameToIndex = array_flip(SnmpQuery::cache()->walk('IF-MIB::ifName')->pluck());
$connector = match ($data['IPI-CMM-CHASSIS-MIB::cmmTransconnectortype'] ?? null) {
'bayonet-or-threaded-neill-concelman' => 'ST',
'copper-pigtail' => 'DAC',
'fiber-jack' => 'FJ',
'fibrechannel-style1-copperconnector', 'fibrechannel-style2-copperconnector', 'fibrechannel-coaxheaders' => 'FC',
'hssdcii' => 'HSSDC',
'lucent-connector' => 'LC',
'mechanical-transfer-registeredjack' => 'MTRJ',
'multifiber-paralleloptic-1x12' => 'MPO-12',
'multifiber-paralleloptic-1x16' => 'MPO-16',
'multiple-optical' => 'MPO',
'mxc2-x16' => 'MXC2-X16',
'no-separable-connector' => 'None',
'optical-pigtail' => 'AOC',
'rj45' => 'RJ45',
'sg' => 'SG',
'subscriber-connector' => 'SC',
default => 'unknown',
};
return $ifNameToIndex[$portName] ?? 0;
$date = $data['IPI-CMM-CHASSIS-MIB::cmmTransDateCode'] ?? '0000-00-00';
if (preg_match('/^(\d{2,4})(\d{2})(\d{2})$/', $date, $date_matches)) {
$year = $date_matches[1];
if (strlen($year) == 2) {
$year = '20' . $year;
}
$date = $year . '-' . $date_matches[2] . '-' . $date_matches[3];
}
$cmmTransType = $data['IPI-CMM-CHASSIS-MIB::cmmTransType'] ?? 'missing';
if ($this->ifNamePortIdMap === null) {
$this->ifNamePortIdMap = $this->getDevice()->ports()->toBase()->pluck('port_id', 'ifName');
}
return new Transceiver([
'port_id' => $this->ifNamePortIdMap[$this->guessIfName($cmmTransIndex, $cmmTransType)] ?? 0,
'index' => "$cmmStackUnitIndex.$cmmTransIndex",
'type' => $cmmTransType,
'vendor' => $data['IPI-CMM-CHASSIS-MIB::cmmTransVendorName'] ?? 'missing',
'oui' => $data['IPI-CMM-CHASSIS-MIB::cmmTransVendorOUI'] ?? 'missing',
'model' => $data['IPI-CMM-CHASSIS-MIB::cmmTransVendorPartNumber'] ?? 'missing',
'revision' => $data['IPI-CMM-CHASSIS-MIB::cmmTransVendorRevision'] ?? 'missing',
'serial' => $data['IPI-CMM-CHASSIS-MIB::cmmTransVendorSerialNumber'] ?? 'missing',
'date' => $date,
'ddm' => isset($data['IPI-CMM-CHASSIS-MIB::cmmTransDDMSupport']) && $data['IPI-CMM-CHASSIS-MIB::cmmTransDDMSupport'] == 'yes',
'encoding' => $data['IPI-CMM-CHASSIS-MIB::cmmTransEncoding'] ?? 'missing',
'distance' => $distance,
'wavelength' => isset($data['IPI-CMM-CHASSIS-MIB::cmmTransWavelength']) && $data['IPI-CMM-CHASSIS-MIB::cmmTransWavelength'] !== '-100002' ? $data['IPI-CMM-CHASSIS-MIB::cmmTransWavelength'] : null,
'connector' => $connector,
'channels' => $data['IPI-CMM-CHASSIS-MIB::cmmTransNoOfChannels'] ?? 0,
'entity_physical_index' => $cmmStackUnitIndex * 10000 + $cmmTransIndex,
]);
});
}
}

View File

@@ -25,6 +25,8 @@
namespace LibreNMS\OS;
use App\Models\Transceiver;
use Illuminate\Support\Collection;
use LibreNMS\Device\WirelessSensor;
use LibreNMS\Interfaces\Data\DataStorageInterface;
use LibreNMS\Interfaces\Discovery\Sensors\WirelessCcqDiscovery;
@@ -38,12 +40,15 @@ use LibreNMS\Interfaces\Discovery\Sensors\WirelessRsrpDiscovery;
use LibreNMS\Interfaces\Discovery\Sensors\WirelessRsrqDiscovery;
use LibreNMS\Interfaces\Discovery\Sensors\WirelessRssiDiscovery;
use LibreNMS\Interfaces\Discovery\Sensors\WirelessSinrDiscovery;
use LibreNMS\Interfaces\Discovery\TransceiverDiscovery;
use LibreNMS\Interfaces\Polling\OSPolling;
use LibreNMS\OS;
use LibreNMS\RRD\RrdDefinition;
use LibreNMS\Util\Number;
class Routeros extends OS implements
OSPolling,
TransceiverDiscovery,
WirelessCcqDiscovery,
WirelessClientsDiscovery,
WirelessFrequencyDiscovery,
@@ -497,4 +502,22 @@ class Routeros extends OS implements
$this->enableGraph('routeros_pppoe_sessions');
}
}
public function discoverTransceivers(): Collection
{
$ifIndexToPortId = $this->getDevice()->ports()->pluck('port_id', 'ifIndex');
return \SnmpQuery::walk('MIKROTIK-MIB::mtxrOpticalTable')->mapTable(function ($data, $ifIndex) use ($ifIndexToPortId) {
$wavelength = isset($data['MIKROTIK-MIB::mtxrOpticalWavelength']) && $data['MIKROTIK-MIB::mtxrOpticalWavelength'] != '.00' ? Number::cast($data['MIKROTIK-MIB::mtxrOpticalWavelength']) : null;
return new Transceiver([
'port_id' => $ifIndexToPortId->get($ifIndex, 0),
'index' => $ifIndex,
'vendor' => $data['MIKROTIK-MIB::mtxrOpticalVendorName'] ?? null,
'serial' => $data['MIKROTIK-MIB::mtxrOpticalVendorSerial'] ?? null,
'wavelength' => $wavelength == 65535 ? null : $wavelength, // NA value = 65535.00
'entity_physical_index' => $ifIndex,
]);
});
}
}

View File

@@ -31,6 +31,7 @@ use App\Models\EntPhysical;
use App\Models\Mempool;
use App\Models\PortsNac;
use App\Models\Sla;
use App\Models\Transceiver;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
@@ -40,6 +41,7 @@ use LibreNMS\Interfaces\Discovery\OSDiscovery;
use LibreNMS\Interfaces\Discovery\ProcessorDiscovery;
use LibreNMS\Interfaces\Discovery\SlaDiscovery;
use LibreNMS\Interfaces\Discovery\StpInstanceDiscovery;
use LibreNMS\Interfaces\Discovery\TransceiverDiscovery;
use LibreNMS\Interfaces\Polling\NacPolling;
use LibreNMS\Interfaces\Polling\SlaPolling;
use LibreNMS\OS;
@@ -54,7 +56,8 @@ class Cisco extends OS implements
ProcessorDiscovery,
MempoolsDiscovery,
NacPolling,
SlaPolling
SlaPolling,
TransceiverDiscovery
{
use YamlOSDiscovery {
YamlOSDiscovery::discoverOS as discoverYamlOS;
@@ -622,4 +625,52 @@ class Cisco extends OS implements
return null;
}
public function discoverTransceivers(): Collection
{
// use data collected by entPhysical module if available
$dbSfpCages = $this->getDevice()->entityPhysical()->where('entPhysicalVendorType', 'cevContainerSFP')->pluck('ifIndex', 'entPhysicalIndex');
if ($dbSfpCages->isNotEmpty()) {
$data = $this->getDevice()->entityPhysical()->whereIn('entPhysicalContainedIn', $dbSfpCages->keys())->get()->map(function ($ent) use ($dbSfpCages) {
if (empty($ent->ifIndex) && $dbSfpCages->has($ent->entPhysicalContainedIn)) {
$ent->ifIndex = $dbSfpCages->get($ent->entPhysicalContainedIn);
}
return $ent;
})->keyBy('entPhysicalIndex');
} else {
// fetch data via snmp
$snmpData = \SnmpQuery::cache()->hideMib()->mibs(['CISCO-ENTITY-VENDORTYPE-OID-MIB'])->walk('ENTITY-MIB::entPhysicalTable')->table(1);
if (empty($snmpData)) {
return new Collection;
}
$snmpData = collect(\SnmpQuery::hideMib()->mibs(['IF-MIB'])->walk('ENTITY-MIB::entAliasMappingIdentifier')->table(1, $snmpData));
$sfpCages = $snmpData->filter(fn ($ent) => isset($ent['entPhysicalVendorType']) && $ent['entPhysicalVendorType'] == 'cevContainerSFP');
$data = $snmpData->filter(fn ($ent) => $sfpCages->has($ent['entPhysicalContainedIn'] ?? null))->map(function ($e) {
if (isset($e['entAliasMappingIdentifier'][0])) {
$e['ifIndex'] = preg_replace('/^.*ifIndex[.[](\d+).*$/', '$1', $e['entAliasMappingIdentifier'][0]);
}
return $e;
});
}
$ifIndexToPortId = $this->getDevice()->ports()->pluck('port_id', 'ifIndex');
return $data->map(function ($ent, $index) use ($ifIndexToPortId) {
$ifIndex = $ent['ifIndex'] ?? null;
return new Transceiver([
'port_id' => $ifIndexToPortId->get($ifIndex, 0),
'index' => $index,
'type' => $ent['entPhysicalDescr'] ?? null,
'vendor' => $ent['entPhysicalMfgName'] ?? null,
'revision' => $ent['entPhysicalHardwareRev'] ?? null,
'model' => $ent['entPhysicalModelName'] ?? null,
'serial' => $ent['entPhysicalSerialNum'] ?? null,
'entity_physical_index' => $ifIndex,
]);
});
}
}

View File

@@ -47,7 +47,8 @@ trait EntityMib
return $data->mapTable(function ($data, $entityPhysicalIndex) use ($entPhysicalToIfIndexMap) {
$entityPhysical = new EntPhysical($data);
$entityPhysical->entPhysicalIndex = $entityPhysicalIndex;
$entityPhysical->ifIndex = $entPhysicalToIfIndexMap[$entityPhysicalIndex] ?? null;
// get ifIndex. also if parent has an ifIndex, set it too
$entityPhysical->ifIndex = $entPhysicalToIfIndexMap[$entityPhysicalIndex] ?? $entPhysicalToIfIndexMap[$entityPhysical->entPhysicalContainedIn] ?? null;
return $entityPhysical;
});

View File

@@ -22,6 +22,7 @@
namespace LibreNMS\Util;
use Illuminate\Support\Str;
use LibreNMS\Exceptions\UserFunctionExistException;
class UserFuncHelper
@@ -42,4 +43,11 @@ class UserFuncHelper
{
return \LibreNMS\Util\Time::dateToDays($this->value_raw);
}
public function fsParseChannelValue(): float
{
$channel = Str::afterLast($this->sensor['sensor_index'], '.');
return Number::cast(explode(',', $this->value_raw)[$channel] ?? '');
}
}

View File

@@ -94,6 +94,7 @@ class PortsController implements DeviceTab
$this->detail = $tab == 'detail';
$data = match ($tab) {
'links' => $this->linksData($device),
'transceivers' => $this->transceiversData($device),
'xdsl' => $this->xdslData($device),
'graphs', 'mini_graphs' => $this->graphData($device, $request),
default => $this->portData($device, $request),
@@ -249,6 +250,15 @@ class PortsController implements DeviceTab
];
}
private function transceiversData(Device $device): array
{
$device->load(['transceivers.port']);
return [
'transceivers' => $device->transceivers,
];
}
private function xdslData(Device $device): array
{
$device->portsAdsl->load('port');
@@ -282,6 +292,10 @@ class PortsController implements DeviceTab
$tabs[] = ['name' => __('port.tabs.fdb'), 'url' => 'fdb'];
}
if ($device->transceivers()->exists()) {
$tabs[] = ['name' => __('port.tabs.transceivers'), 'url' => 'transceivers'];
}
if ($device->links()->exists()) {
$tabs[] = ['name' => __('port.tabs.links'), 'url' => 'links'];
}

View File

@@ -163,18 +163,21 @@ class DeviceController extends Controller
$title = __('Edit');
// check if metric has more specific edit page
if (preg_match('#health/metric=(\w+)#', \Request::path(), $matches)) {
$path = \Request::path();
if (preg_match('#health/metric=(\w+)#', $path, $matches)) {
if ($this->editTabExists($matches[1])) {
$current_tab = $matches[1];
} elseif ($this->editTabExists($matches[1] . 's')) {
$current_tab = $matches[1] . 's';
}
} elseif (preg_match('#device/\d+/ports/transceivers#', $path)) {
$current_tab = 'transceivers';
}
// check if edit page exists
if ($this->editTabExists($current_tab)) {
$suffix .= "/section=$current_tab";
$title .= ' ' . ucfirst($current_tab);
$title .= ' ' . __(ucfirst($current_tab));
}
$device_links['edit'] = [

View File

@@ -1045,6 +1045,11 @@ class Device extends BaseModel
return $this->hasMany(TnmsneInfo::class, 'device_id');
}
public function transceivers(): HasMany
{
return $this->hasMany(Transceiver::class, 'device_id');
}
public function users(): BelongsToMany
{
// FIXME does not include global read

View File

@@ -393,6 +393,11 @@ class Port extends DeviceRelatedModel
return $this->hasMany(PortStp::class, 'port_id');
}
public function transceivers(): HasMany
{
return $this->hasMany(Transceiver::class, 'port_id');
}
public function users(): BelongsToMany
{
// FIXME does not include global read

View File

@@ -6,7 +6,9 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasOneThrough;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use LibreNMS\Enum\Severity;
use LibreNMS\Interfaces\Models\Keyable;
use LibreNMS\Util\Number;
class Sensor extends DeviceRelatedModel implements Keyable
{
@@ -128,7 +130,42 @@ class Sensor extends DeviceRelatedModel implements Keyable
}
}
/**
* Format current value for user display including units.
*/
public function formatValue(): string
{
$units = __('sensors.' . $this->sensor_class . '.unit');
return match ($this->sensor_class) {
'current', 'power' => Number::formatSi($this->sensor_current, 3, 3, $units),
'dbm' => round($this->sensor_current, 3) . " $units",
default => "$this->sensor_current $units",
};
}
public function currentStatus(): Severity
{
if ($this->sensor_limit !== null && $this->sensor_current >= $this->sensor_limit) {
return Severity::Error;
}
if ($this->sensor_limit_low !== null && $this->sensor_current <= $this->sensor_limit_low) {
return Severity::Error;
}
if ($this->sensor_limit_warn !== null && $this->sensor_current >= $this->sensor_limit_warn) {
return Severity::Warning;
}
if ($this->sensor_limit_low_warn !== null && $this->sensor_current <= $this->sensor_limit_low_warn) {
return Severity::Warning;
}
return Severity::Ok;
}
// ---- Define Relationships ----
public function events(): MorphMany
{
return $this->morphMany(Eventlog::class, 'events', 'type', 'reference');

View File

@@ -0,0 +1,37 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use LibreNMS\Interfaces\Models\Keyable;
class Transceiver extends PortRelatedModel implements Keyable
{
use HasFactory;
protected $fillable = [
'device_id',
'port_id',
'index', // sfp index to identify this sfp uniquely by snmp data
'type', // module type sfp, xfp, sfp+, qsfp, sfp28, etc or more detailed info like 10G_BASE_SR_SFP
'entity_physical_index', // maps to inventory item, should be unique per port
'vendor', // vendor name
'oui', // vendor oui
'model', // model number or name
'revision', // hardware revision
'serial', // serial number
'date', // date of manufacture
'ddm', // if the module supports DDM or DOM
'encoding', // data encoding method
'cable', // SM, MM, Copper, etc
'distance', // Max distance or measured distance
'wavelength', // Middle Wavelength in nanometers
'connector', // LC, SM, RJ45, etc physical connector type, See Ocnos for some normalized connectors
'channels', // number of channels or lanes
];
public function getCompositeKey()
{
return $this->index;
}
}

View File

@@ -46,9 +46,17 @@ class Graph extends Component
*/
public $absolute_size;
/**
* @var bool|string
* @var bool
*/
private $link;
/**
* @var bool|string
*/
private $popup;
/**
* @var string
*/
public mixed $popupTitle;
/**
* Create a new component instance.
@@ -76,6 +84,8 @@ class Graph extends Component
?int $height = null,
int $absolute_size = 0,
$link = true,
$popup = false,
$popupTitle = '',
$device = null,
$port = null
) {
@@ -87,6 +97,8 @@ class Graph extends Component
$this->absolute_size = $absolute_size;
$this->width = $width ?: ($aspect == 'wide' ? self::DEFAULT_WIDE_WIDTH : self::DEFAULT_NORMAL_WIDTH);
$this->height = $height ?: ($aspect == 'wide' ? self::DEFAULT_WIDE_HEIGHT : self::DEFAULT_NORMAL_HEIGHT);
$this->popupTitle = $popupTitle;
$this->popup = filter_var($popup, FILTER_VALIDATE_BOOLEAN);
$this->link = $link;
// handle device and port ids/models for convenience could be set in $vars
@@ -108,16 +120,13 @@ class Graph extends Component
*/
public function render()
{
if ($this->link === false) {
return view('components.graph', [
'src' => $this->getSrc(),
]);
}
return view('components.linked-graph', [
$view = $this->popup ? 'components.graph-popup' : ($this->link === false ? 'components.graph' : 'components.linked-graph');
$data = [
'link' => $this->getLink(),
'src' => $this->getSrc(),
]);
];
return view($view, $data);
}
/**
@@ -149,20 +158,14 @@ class Graph extends Component
private function getLink(): string
{
if ($this->link === true) {
$url = url('graphs') . '/' . http_build_query($this->vars + [
return match ($this->link) {
true => url('graphs') . '/' . http_build_query($this->vars + [
'type' => $this->type,
'from' => $this->from,
'to' => $this->to,
], '', '/');
return $url;
}
if ($this->link === false) {
return '';
}
return $this->link;
], '', '/'),
false => '',
default => $this->link,
};
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace App\View\Components;
use Closure;
use Illuminate\Contracts\View\View;
use Illuminate\View\Component;
use LibreNMS\Enum\Severity;
class Label extends Component
{
public string $statusClass;
/**
* Create a new component instance.
*/
public function __construct(
public ?Severity $status = null
) {
$this->statusClass = match ($status) {
Severity::Ok => 'label-success',
Severity::Error => 'label-danger',
Severity::Info => 'label-info',
Severity::Notice => 'label-primary',
Severity::Warning => 'label-warning',
default => 'label-default',
};
}
/**
* Get the view / contents that represent the component.
*/
public function render(): View|Closure|string
{
return view('components.label');
}
}

View File

@@ -20,23 +20,15 @@ class Panel extends Component
*/
public $body_class;
/**
* The Panel footer class.
*
* @var string
*/
public $footer_class;
/**
* Create a new component instance.
*
* @return void
*/
public function __construct($title = null, $bodyClass = null, $footerClass = null)
public function __construct($title = null, $bodyClass = null)
{
$this->title = $title;
$this->body_class = $bodyClass;
$this->footer_class = $footerClass;
}
/**

View File

@@ -0,0 +1,37 @@
<?php
namespace App\View\Components;
use App\Models\Sensor;
use App\Models\Transceiver;
use Closure;
use Illuminate\Contracts\View\View;
use Illuminate\Support\Collection;
use Illuminate\View\Component;
class TransceiverSensors extends Component
{
public Collection $groupedSensors;
/**
* Create a new component instance.
*/
public function __construct(
public Transceiver $transceiver,
) {
$this->groupedSensors = Sensor::where('device_id', $this->transceiver->device_id)
->whereNotNull('entPhysicalIndex')
->where('entPhysicalIndex', $this->transceiver->entity_physical_index)
->where('group', 'transceiver')
->get()
->groupBy('sensor_class');
}
/**
* Get the view / contents that represent the component.
*/
public function render(): View|Closure|string
{
return view('components.transceiver-sensors');
}
}

View File

@@ -0,0 +1,46 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('transceivers', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->bigInteger('device_id');
$table->bigInteger('port_id');
$table->string('index');
$table->integer('entity_physical_index')->nullable();
$table->string('type', 128)->nullable();
$table->string('vendor', 16)->nullable();
$table->string('oui', 16)->nullable();
$table->string('model', 32)->nullable();
$table->string('revision', 16)->nullable();
$table->string('serial', 32)->nullable();
$table->date('date')->nullable();
$table->boolean('ddm')->nullable();
$table->string('encoding', 16)->nullable();
$table->string('cable', 16)->nullable();
$table->integer('distance')->nullable();
$table->integer('wavelength')->nullable();
$table->string('connector', 16)->nullable();
$table->smallInteger('channels')->default(1);
$table->index(['device_id', 'entity_physical_index']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('transceivers');
}
};

View File

@@ -743,6 +743,75 @@ Output:
}
```
### `get_device_transceivers`
Get a list of FDB entries associated with a device.
Route: `/api/v0/devices/:hostname/transceivers`
- hostname can be either the device hostname or id
Example:
```curl
curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/transceivers
```
Output:
```json
{
"status": "ok",
"transceivers": [
{
"id": 12,
"created_at": "2024-06-26T23:46:06.000000Z",
"updated_at": "2024-06-26T23:46:57.000000Z",
"device_id": 3138,
"port_id": 50735,
"index": "50",
"type": "10G_BASE_LR_SFP",
"vendor": "FS",
"oui": "00 00 00",
"model": null,
"revision": "",
"serial": "G000999AA",
"date": null,
"ddm": true,
"encoding": null,
"cable": "SM",
"distance": 20000,
"wavelength": 1330,
"connector": "LC",
"channels": 1
},
{
"id": 13,
"created_at": "2024-06-26T23:46:06.000000Z",
"updated_at": "2024-06-27T00:00:07.000000Z",
"device_id": 3138,
"port_id": 50736,
"index": "51",
"type": "10G_BASE_SR_SFP",
"vendor": "HPE",
"oui": "64 9D 99",
"model": null,
"revision": "1",
"serial": "AAAA0000AAA",
"date": null,
"ddm": true,
"encoding": null,
"cable": "SM",
"distance": 300,
"wavelength": 850,
"connector": "LC",
"channels": 1
}
]
}
```
### `get_components`
Get a list of components for a particular device.

View File

@@ -380,6 +380,52 @@ Output:
}
```
### `get_port_transceiver`
Get transceiver info with metrics
Route: `/api/v0/ports/:portid/transceiver`
- portid must be an integer
Example:
```curl
curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/ports/50736/transceiver
```
Output:
```json
{
"status": "ok",
"transceivers": [
{
"id": 13,
"created_at": "2024-06-26T23:46:06.000000Z",
"updated_at": "2024-06-27T00:00:07.000000Z",
"device_id": 3138,
"port_id": 50736,
"index": "51",
"type": "10G_BASE_SR_SFP",
"vendor": "HPE",
"oui": "64 9D 99",
"model": null,
"revision": "1",
"serial": "AAA0000AAA00",
"date": null,
"ddm": true,
"encoding": null,
"cable": "MM",
"distance": 300,
"wavelength": 850,
"connector": "LC",
"channels": 1
}
]
}
```
### `get_port_description`
Get the description (`ifAlias`) for a given port id.
@@ -424,4 +470,4 @@ Output:
"status": "ok",
"message": "Port description updated."
}
```
```

View File

@@ -110,7 +110,8 @@ the string to the equivalent OID representation.
key with in the table or a static string, optionally using `{{ index }}`.
- `group` (optional): Groups sensors together under in the webui,
displaying this text. Not specifying this will put the sensors in
the default group.
the default group. If group is set to `transceiver` it will be shown with the port
instead of in with all the generic sensors (You must also set `entPhysicalIndex` to ifIndex)
- `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.

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><path style="fill:currentColor;stroke-linecap:round" d="m49.74.22-5.42 5.42-1.1-1.11a4.47 4.47 0 0 0-6.26 0L1.54 39.94a4.47 4.47 0 0 0 0 6.26l16.34 16.33a4.47 4.47 0 0 0 6.25 0l35.41-35.41a4.47 4.47 0 0 0 0-6.26l-1.1-1.11 5.41-5.42zM40.08 8.6 55.48 24 21 58.47l-1.98-1.98 2.62-2.62-3.91-3.9-2.62 2.61-3.62-3.62 2.62-2.62-3.9-3.9-2.62 2.62-1.98-1.99z"/><path style="stroke:currentColor;stroke-width:3.50264;stroke-linecap:round" d="m40.26 17.46-1.69 1.68M46.62 23.82l-1.69 1.68"/></svg>

After

Width:  |  Height:  |  Size: 546 B

File diff suppressed because one or more lines are too long

View File

@@ -1,16 +1,17 @@
{
"/js/app.js": "/js/app.js?id=bb76b20e21827b0ac5b7af4420a43f2a",
"/js/app.js": "/js/app.js?id=eb2bdde63ce2ff449be654729ed0136b",
"/js/manifest.js": "/js/manifest.js?id=2eb19d92c19953027907b72ff5963ebb",
"/css/vendor.css": "/css/vendor.css?id=d520734ded0ec75b0a572aa8db1c2161",
"/css/app.css": "/css/app.css?id=db28893a6aa5f44dd522b8c13dd58477",
"/css/app.css": "/css/app.css?id=dcc1cfc548f711f258651833d592f7fb",
"/js/vendor.js": "/js/vendor.js?id=9c1ce1964559bbafd2c87384ac2f9058",
"/js/lang/de.js": "/js/lang/de.js?id=9a6f9c23a4b209504cce12ce85315a3c",
"/js/lang/en.js": "/js/lang/en.js?id=f12bfe73df71cf300bdd25637bfde760",
"/js/lang/fr.js": "/js/lang/fr.js?id=d9dd782bb64e09dcca29d784c0417779",
"/js/lang/it.js": "/js/lang/it.js?id=40ad82368018e52347e3808571866e69",
"/js/lang/de.js": "/js/lang/de.js?id=f80b2c49bd4d1587d4747d189c566ffa",
"/js/lang/en.js": "/js/lang/en.js?id=af40282f2c5b7a9dc50d9ee9547048cc",
"/js/lang/fr.js": "/js/lang/fr.js?id=7e43fd1965beef315f0b416fd8607231",
"/js/lang/it.js": "/js/lang/it.js?id=7827375adf92766a477291c48fa1b360",
"/js/lang/pt-BR.js": "/js/lang/pt-BR.js?id=c6ee987c64a83b078c9bc654fc780092",
"/js/lang/ru.js": "/js/lang/ru.js?id=f6b7c078755312a0907c4f983991cc52",
"/js/lang/sr.js": "/js/lang/sr.js?id=388e38b41f63e35175061e849bf0d8e5",
"/js/lang/uk.js": "/js/lang/uk.js?id=c56728028de7bd48f65235f7cb40438c",
"/js/lang/zh-CN.js": "/js/lang/zh-CN.js?id=6fdbd03cdf6b4868de1d3b5b557e5e13",
"/js/lang/zh-TW.js": "/js/lang/zh-TW.js?id=1c01d96b1e284ac502863fe53c569820"
"/js/lang/uk.js": "/js/lang/uk.js?id=85ef43c7afe57a42b774f3cbae5a77e5",
"/js/lang/zh-CN.js": "/js/lang/zh-CN.js?id=a178770f41a54f7b000eeb973e388936",
"/js/lang/zh-TW.js": "/js/lang/zh-TW.js?id=2cf0d871ec12cbd5ccb746b983d127df"
}

View File

@@ -1,98 +0,0 @@
modules:
sensors:
state:
data:
- oid: E7-Calix-MIB::e7OltPonPortTable
value: E7-Calix-MIB::e7OltPonPortStatus
num_oid: '.1.3.6.1.4.1.6321.1.2.2.2.1.6.2.1.4.{{ $index }}'
descr: '{{ $subindex0 }}/{{ $subindex1 }}/{{ $subindex2 }} Status'
index: 'ponStatus.{{ $index }}'
state_name: E7-Calix-MIB::e7OltPonPortStatus
states:
- { value: 0, descr: invalid, graph: 1, generic: 3 }
- { value: 1, descr: linkUp, graph: 1, generic: 0 }
- { value: 2, descr: linkDown, graph: 1, generic: 2 }
temperature:
data:
- oid: E7-Calix-MIB::e7OltPonPortTable
value: E7-Calix-MIB::e7OltPonPortTemperature
num_oid: '.1.3.6.1.4.1.6321.1.2.2.2.1.6.2.1.5.{{ $index }}'
descr: '{{ $subindex0 }}/{{ $subindex1 }}/{{ $subindex2 }} Temperature'
group: PON
low_limit: -40
low_warn_limit: -25
warn_limit: 70
high_limit: 85
skip_values:
-
oid: E7-Calix-MIB::e7OltPonPortStatus
op: '!='
value: 1
dbm:
data:
- oid: E7-Calix-MIB::e7OltPonPortTable
value: E7-Calix-MIB::e7OltPonPortTxPower
num_oid: '.1.3.6.1.4.1.6321.1.2.2.2.1.6.2.1.7.{{ $index }}'
descr: '{{ $subindex0 }}/{{ $subindex1 }}/{{ $subindex2 }} TX Power'
group: PON
divisor: 10000
user_func: mw_to_dbm
low_limit: 0
low_warn_limit: 0.2
warn_limit: 5.8
high_limit: 6
index: 'tx.{{ $index }}'
skip_values:
- oid: E7-Calix-MIB::e7OltPonPortStatus
op: '!='
value: 1
- oid: E7-Calix-MIB::e7OltPonPortTable
value: E7-Calix-MIB::e7OltPonPortRxPower
num_oid: '.1.3.6.1.4.1.6321.1.2.2.2.1.6.2.1.8.{{ $index }}'
descr: '{{ $subindex0 }}/{{ $subindex1 }}/{{ $subindex2 }} RX Power'
group: PON
divisor: 10000
user_func: mw_to_dbm
low_limit: -28
low_warn_limit: -27
warn_limit: -7
high_limit: -8
index: 'rx.{{ $index }}'
skip_values:
-
oid: E7-Calix-MIB::e7OltPonPortStatus
op: '!='
value: 1
voltage:
data:
- oid: E7-Calix-MIB::e7OltPonPortTable
value: E7-Calix-MIB::e7OltPonPortVoltage
num_oid: '.1.3.6.1.4.1.6321.1.2.2.2.1.6.2.1.9.{{ $index }}'
descr: '{{ $subindex0 }}/{{ $subindex1 }}/{{ $subindex2 }} Voltage'
group: PON
divisor: 1000
low_limit: 3
low_warn_limit: 3.1
warn_limit: 3.5
high_limit: 3.6
skip_values:
-
oid: E7-Calix-MIB::e7OltPonPortStatus
op: '!='
value: 1
current:
data:
- oid: E7-Calix-MIB::e7OltPonPortTable
value: E7-Calix-MIB::e7OltPonPortTxBias
num_oid: '.1.3.6.1.4.1.6321.1.2.2.2.1.6.2.1.6.{{ $index }}'
descr: '{{ $subindex0 }}/{{ $subindex1 }}/{{ $subindex2 }} TX Bias'
group: PON
divisor: 1000000
warn_limit: 80
high_limit: 100
skip_values:
-
oid: E7-Calix-MIB::e7OltPonPortStatus
op: '!='
value: 1

View File

@@ -60,6 +60,7 @@ modules:
descr: '{{ ifDescr:0 }} preFEC BER'
entPhysicalIndex: '{{ $subindex0 }}'
entPhysicalIndex_measured: 'ports'
group: transceiver
chromatic_dispersion:
data:
-
@@ -69,6 +70,7 @@ modules:
entPhysicalIndex: '{{ $index }}'
entPhysicalIndex_measured: 'ports'
descr: '{{ $ifDescr }} CD'
group: transceiver
index: 'jnxPMCurChromaticDispersion.{{ $index }}'
delay:
data:
@@ -80,6 +82,7 @@ modules:
entPhysicalIndex_measured: 'ports'
divisor: 1000000000000
descr: '{{ $ifDescr }} DGD'
group: transceiver
index: 'jnxPMCurDiffGroupDelay.{{ $index }}'
dbm:
data:
@@ -97,7 +100,7 @@ modules:
entPhysicalIndex: '{{ $index }}'
entPhysicalIndex_measured: 'ports'
index: 'rx-{{ $index }}'
group: 'Modules'
group: transceiver
-
oid: JUNIPER-DOM-MIB::jnxDomCurrentTable
value: JUNIPER-DOM-MIB::jnxDomCurrentTxLaserOutputPower
@@ -112,7 +115,7 @@ modules:
entPhysicalIndex: '{{ $index }}'
entPhysicalIndex_measured: 'ports'
index: 'tx-{{ $index }}'
group: 'Modules'
group: transceiver
-
oid: JUNIPER-DOM-MIB::jnxDomModuleLaneTable
value: JUNIPER-DOM-MIB::jnxDomCurrentLaneRxLaserPower
@@ -127,7 +130,7 @@ modules:
entPhysicalIndex: '{{ $subindex0 }}'
entPhysicalIndex_measured: 'ports'
index: 'rx-{{ $index }}'
group: 'Modules'
group: transceiver
-
oid: JUNIPER-DOM-MIB::jnxDomModuleLaneTable
value: JUNIPER-DOM-MIB::jnxDomCurrentLaneTxLaserOutputPower
@@ -142,7 +145,7 @@ modules:
entPhysicalIndex: '{{ $subindex0 }}'
entPhysicalIndex_measured: 'ports'
index: 'tx-{{ $index }}'
group: 'Modules'
group: transceiver
-
oid: jnxOpticsPMCurrentTable
value: jnxPMCurRxInputPower
@@ -151,6 +154,7 @@ modules:
entPhysicalIndex_measured: 'ports'
divisor: 100
descr: '{{ $ifDescr }} Rx Power'
group: transceiver
index: 'jnxPMCurRxInputPower.{{ $index }}'
-
oid: jnxOpticsPMCurrentTable
@@ -160,6 +164,7 @@ modules:
entPhysicalIndex_measured: 'ports'
divisor: 100
descr: '{{ $ifDescr }} Tx Power'
group: transceiver
index: 'jnxPMCurTxOutputPower.{{ $index }}'
quality_factor:
data:
@@ -171,6 +176,7 @@ modules:
entPhysicalIndex_measured: 'ports'
divisor: 10
descr: '{{ $ifDescr }} Q2-factor'
group: transceiver
index: 'jnxPMCurQ.{{ $index }}'
snr:
data:
@@ -182,6 +188,7 @@ modules:
entPhysicalIndex_measured: 'ports'
divisor: 10
descr: '{{ $ifDescr }} electrical SNR'
group: transceiver
index: 'jnxPMCurSNR.{{ $index }}'
frequency:
data:
@@ -193,6 +200,7 @@ modules:
entPhysicalIndex_measured: 'ports'
multiplier: 1000000
descr: '{{ $ifDescr }} Carrier Freq Offset'
group: transceiver
index: 'jnxPMCurCarFreqOffset.{{ $index }}'
temperature:
data:
@@ -215,7 +223,7 @@ modules:
entPhysicalIndex: '{{ $index }}'
entPhysicalIndex_measured: 'ports'
index: 'rx-{{ $index }}' # match old php discovery
group: 'Modules'
group: transceiver
-
oid: jnxOpticsPMCurrentTable
value: jnxPMCurTemperature
@@ -224,7 +232,7 @@ modules:
entPhysicalIndex_measured: 'ports'
descr: '{{ $ifDescr }} Temperature'
index: 'jnxPMCurTemperature.{{ $index }}'
group: 'Modules'
group: transceiver
current:
data:
-
@@ -241,7 +249,7 @@ modules:
entPhysicalIndex: '{{ $index }}'
entPhysicalIndex_measured: 'ports'
index: 'rx-{{ $index }}'
group: 'Modules'
group: transceiver
-
oid: jnxOpticsPMCurrentTable
value: jnxPMCurTxLaserBiasCurrent
@@ -250,6 +258,7 @@ modules:
entPhysicalIndex_measured: 'ports'
divisor: 1000
descr: '{{ $ifDescr }} Tx Bias'
group: transceiver
index: 'jnxPMCurTxLaserBiasCurrent.{{ $index }}'
loss:
data:

View File

@@ -18,7 +18,9 @@ modules:
value: MIKROTIK-MIB::mtxrOpticalTemperature
num_oid: '.1.3.6.1.4.1.14988.1.1.19.1.1.6.{{ $index }}'
descr: MIKROTIK-MIB::mtxrOpticalName
group: Ports
entPhysicalIndex: '{{ $index }}'
entPhysicalIndex_measured: 'ports'
group: transceiver
index: 'mtxrOpticalTemperature.{{ $index }}'
-
oid: MIKROTIK-MIB::mtxrGaugeTable
@@ -39,7 +41,9 @@ modules:
num_oid: '.1.3.6.1.4.1.14988.1.1.19.1.1.7.{{ $index }}'
divisor: 1000
descr: MIKROTIK-MIB::mtxrOpticalName
group: Ports
entPhysicalIndex: '{{ $index }}'
entPhysicalIndex_measured: 'ports'
group: transceiver
index: 'mtxrOpticalSupplyVoltage.{{ $index }}'
-
oid: MIKROTIK-MIB::mtxrPOETable
@@ -67,8 +71,10 @@ modules:
oid: MIKROTIK-MIB::mtxrOpticalTable
value: MIKROTIK-MIB::mtxrOpticalTxBiasCurrent
num_oid: '.1.3.6.1.4.1.14988.1.1.19.1.1.8.{{ $index }}'
descr: '{{ MIKROTIK-MIB::mtxrOpticalName }} Tx'
group: Ports
descr: '{{ MIKROTIK-MIB::mtxrOpticalName }} Tx Bias'
entPhysicalIndex: '{{ $index }}'
entPhysicalIndex_measured: 'ports'
group: transceiver
divisor: 1000
index: 'mtxrOpticalTxBiasCurrent.{{ $index }}'
-
@@ -99,7 +105,9 @@ modules:
value: MIKROTIK-MIB::mtxrOpticalTxPower
num_oid: '.1.3.6.1.4.1.14988.1.1.19.1.1.9.{{ $index }}'
descr: '{{ MIKROTIK-MIB::mtxrOpticalName }} Tx'
group: Ports
entPhysicalIndex: '{{ $index }}'
entPhysicalIndex_measured: 'ports'
group: transceiver
divisor: 1000
index: 'mtxrOpticalTxPower.{{ $index }}'
-
@@ -107,7 +115,9 @@ modules:
value: MIKROTIK-MIB::mtxrOpticalRxPower
num_oid: '.1.3.6.1.4.1.14988.1.1.19.1.1.10.{{ $index }}'
descr: '{{ MIKROTIK-MIB::mtxrOpticalName }} Rx'
group: Ports
entPhysicalIndex: '{{ $index }}'
entPhysicalIndex_measured: 'ports'
group: transceiver
divisor: 1000
index: 'mtxrOpticalRxPower.{{ $index }}'
state:

View File

@@ -2,7 +2,7 @@ os: fs-centec
text: 'Fiberstore (Centec CNOS)'
type: network
icon: fs
group: fs-centec
group: fs
mib_dir: fs/centec
over:
- { graph: device_bits, text: 'Device Traffic' }

View File

@@ -64,6 +64,7 @@ if ($device['os_group'] == 'cisco') {
foreach ($oids as $index => $entry) {
// echo("[" . $entry['entSensorType'] . "|" . $entry['entSensorValue']. "|" . $index . "]");
if ($entitysensor[$entry['entSensorType']] && is_numeric($entry['entSensorValue']) && is_numeric($index)) {
$group = null;
$entPhysicalIndex = $index;
if ($entity_array[$index]['entPhysicalName'] || $device['os'] == 'iosxr') {
$descr = rewrite_entity_descr($entity_array[$index]['entPhysicalName']);
@@ -219,10 +220,11 @@ if ($device['os_group'] == 'cisco') {
if (is_array($tmp_port)) {
$entPhysicalIndex = $tmp_ifindex;
$entry['entSensorMeasuredEntity'] = 'ports';
$group = 'transceiver';
}
}
discover_sensor(null, $type, $device, $oid, $index, 'cisco-entity-sensor', ucwords($descr), $divisor, $multiplier, $limit_low, $warn_limit_low, $warn_limit, $limit, $current, 'snmp', $entPhysicalIndex, $entry['entSensorMeasuredEntity'], null);
discover_sensor(null, $type, $device, $oid, $index, 'cisco-entity-sensor', ucwords($descr), $divisor, $multiplier, $limit_low, $warn_limit_low, $warn_limit, $limit, $current, 'snmp', $entPhysicalIndex, $entry['entSensorMeasuredEntity'], null, $group);
//Cisco IOS-XR : add a fake sensor to graph as dbm
if ($type == 'power' and $device['os'] == 'iosxr' and (preg_match('/power (R|T)x/i', $descr) or preg_match('/(R|T)x Power/i', $descr) or preg_match('/(R|T)x Lane/i', $descr))) {
// convert Watts to dbm
@@ -235,7 +237,7 @@ if ($device['os_group'] == 'cisco') {
$limit = isset($limit_low) ? round(mw_to_dbm($limit * $multiplier), 3) : null;
$current = mw_to_dbm($current * $multiplier);
//echo("\n".$valid['sensor'].", $type, $device, $oid, $index, 'cisco-entity-sensor', $descr, $divisor, $multiplier, $limit_low, $warn_limit_low, $warn_limit, $limit, $current, $user_func");
discover_sensor(null, $type, $device, $oid, $index, 'cisco-entity-sensor', $descr, $divisor, $multiplier, $limit_low, $warn_limit_low, $warn_limit, $limit, $current, 'snmp', $entPhysicalIndex, $entry['entSensorMeasuredEntity'], $user_func);
discover_sensor(null, $type, $device, $oid, $index, 'cisco-entity-sensor', $descr, $divisor, $multiplier, $limit_low, $warn_limit_low, $warn_limit, $limit, $current, 'snmp', $entPhysicalIndex, $entry['entSensorMeasuredEntity'], $user_func, $group);
}
}

View File

@@ -16,23 +16,24 @@ echo 'Comware ';
$multiplier = 1;
$divisor = 100000;
$divisor_alarm = 1000000;
foreach ($pre_cache['comware_oids'] as $index => $entry) {
if (is_numeric($entry['hh3cTransceiverBiasCurrent']) && $entry['hh3cTransceiverBiasCurrent'] != 2147483647 && isset($entry['hh3cTransceiverDiagnostic'])) {
$hh3cTransceiverInfoTable = SnmpQuery::cache()->enumStrings()->walk('HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverInfoTable')->table(1);
foreach ($hh3cTransceiverInfoTable as $index => $entry) {
if (is_numeric($entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverBiasCurrent']) && $entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverBiasCurrent'] != 2147483647 && isset($entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverDiagnostic'])) {
$interface = get_port_by_index_cache($device['device_id'], $index);
if ($interface['ifAdminStatus'] != 'up') {
continue;
}
$oid = '.1.3.6.1.4.1.25506.2.70.1.1.1.17.' . $index;
$limit_low = $entry['hh3cTransceiverBiasLoAlarm'] / $divisor_alarm;
$warn_limit_low = $entry['hh3cTransceiverBiasLoWarn'] / $divisor_alarm;
$limit = $entry['hh3cTransceiverBiasHiAlarm'] / $divisor_alarm;
$warn_limit = $entry['hh3cTransceiverBiasHiWarn'] / $divisor_alarm;
$current = $entry['hh3cTransceiverBiasCurrent'] / $divisor;
$limit_low = $entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverBiasLoAlarm'] / $divisor_alarm;
$warn_limit_low = $entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverBiasLoWarn'] / $divisor_alarm;
$limit = $entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverBiasHiAlarm'] / $divisor_alarm;
$warn_limit = $entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverBiasHiWarn'] / $divisor_alarm;
$current = $entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverBiasCurrent'] / $divisor;
$entPhysicalIndex = $index;
$entPhysicalIndex_measured = 'ports';
$descr = makeshortif($interface['ifDescr']) . ' Bias Current';
discover_sensor(null, 'current', $device, $oid, 'bias-' . $index, 'comware', $descr, $divisor, $multiplier, $limit_low, $warn_limit_low, $warn_limit, $limit, $current, 'snmp', $entPhysicalIndex, $entPhysicalIndex_measured);
discover_sensor(null, 'current', $device, $oid, 'bias-' . $index, 'comware', $descr, $divisor, $multiplier, $limit_low, $warn_limit_low, $warn_limit, $limit, $current, 'snmp', $entPhysicalIndex, $entPhysicalIndex_measured, group: 'transceiver');
}
}

View File

@@ -0,0 +1,32 @@
<?php
$ponTable = SnmpQuery::cache()->walk('E7-Calix-MIB::e7OltPonPortTable')->table(3);
foreach ($ponTable as $e7OltPonPortShelf => $ponShelf) {
foreach ($ponShelf as $e7OltPonPortSlot => $ponSlot) {
foreach ($ponSlot as $e7OltPonPortId => $ponPort) {
if ($ponPort['E7-Calix-MIB::e7OltPonPortStatus'] != 0) {
$ifIndex = \LibreNMS\OS\Exa::getIfIndex($e7OltPonPortShelf, $e7OltPonPortSlot, $e7OltPonPortId, 'gpon'); // we know these are GPON, so we can infer the ifIndex
$index = "$e7OltPonPortShelf.$e7OltPonPortSlot.$e7OltPonPortId";
$name = "$e7OltPonPortShelf/$e7OltPonPortSlot/$e7OltPonPortId";
app('sensor-discovery')->discover(new \App\Models\Sensor([
'poller_type' => 'snmp',
'sensor_class' => 'current',
'sensor_oid' => ".1.3.6.1.4.1.6321.1.2.2.2.1.6.2.1.6.$index",
'sensor_index' => $index,
'sensor_type' => 'exa',
'sensor_descr' => "$name xcvr bias",
'sensor_divisor' => 1000000,
'sensor_multiplier' => 1,
'sensor_limit_warn' => 80,
'sensor_limit' => 100,
'sensor_current' => $ponPort['E7-Calix-MIB::e7OltPonPortTxBias'] / 1000000,
'entPhysicalIndex' => $ifIndex,
'entPhysicalIndex_measured' => 'port',
'group' => 'transceiver',
]));
}
}
}
}

View File

@@ -0,0 +1,38 @@
<?php
use LibreNMS\Util\Number;
$biasTable = SnmpQuery::walk('FS-SWITCH-V2-MIB::transBiasinformationTable')->table(1);
$ifIndexToName = SnmpQuery::cache()->walk('IF-MIB::ifName')->pluck();
foreach ($biasTable as $ifIndex => $current) {
$ifName = $ifIndexToName[$ifIndex] ?? $ifIndex;
if (! empty($current['FS-SWITCH-V2-MIB::biasCurrent']) && $current['FS-SWITCH-V2-MIB::biasCurrent'] !== '0.00') {
foreach (explode(',', $current['FS-SWITCH-V2-MIB::biasCurrent']) as $channel => $value) {
$divisor = 1000;
app('sensor-discovery')->discover(new \App\Models\Sensor([
'poller_type' => 'snmp',
'sensor_class' => 'current',
'sensor_oid' => ".1.3.6.1.4.1.52642.1.37.1.10.4.1.5.$ifIndex",
'sensor_index' => "$ifIndex.$channel",
'sensor_type' => 'fs-centec',
'sensor_descr' => "$ifName:$channel xcvr bias",
'sensor_divisor' => $divisor,
'sensor_multiplier' => 1,
'sensor_limit_low' => $current['FS-SWITCH-V2-MIB::biasLowAlarmThreshold'] ?? null,
'sensor_limit_low_warn' => $current['FS-SWITCH-V2-MIB::biasLowWarnThreshold'] ?? null,
'sensor_limit_warn' => $current['FS-SWITCH-V2-MIB::biasHighWarnThreshold'] ?? null,
'sensor_limit' => $current['FS-SWITCH-V2-MIB::biasHighAlarmThreshold'] ?? null,
'sensor_current' => Number::cast($value) / $divisor,
'entPhysicalIndex' => $ifIndex,
'entPhysicalIndex_measured' => 'port',
'user_func' => 'fsParseChannelValue',
'group' => 'transceiver',
]));
}
}
}
unset($biasTable, $current);

View File

@@ -0,0 +1,42 @@
<?php
if (empty($os)) {
$os = OS::make($device);
}
if ($os instanceof \LibreNMS\OS\Ocnos) {
$metric_data = \SnmpQuery::cache()->enumStrings()->walk(['IPI-CMM-CHASSIS-MIB::cmmTransDDMTable', 'IPI-CMM-CHASSIS-MIB::cmmTransType'])->table(3);
$divisor = 1000;
foreach ($metric_data as $cmmStackUnitIndex => $chassis_data) {
foreach ($chassis_data as $cmmTransIndex => $module_data) {
$ifName = $os->guessIfName($cmmTransIndex, $module_data['IPI-CMM-CHASSIS-MIB::cmmTransType'] ?? 'unknown');
foreach ($module_data as $cmmTransChannelIndex => $channel_data) {
if (isset($channel_data['IPI-CMM-CHASSIS-MIB::cmmTransLaserBiasCurrent']) && $channel_data['IPI-CMM-CHASSIS-MIB::cmmTransLaserBiasCurrent'] != '-100001') {
$channelDescr = count($module_data) > 2 ? " Channel $cmmTransChannelIndex" : '';
app('sensor-discovery')->discover(new \App\Models\Sensor([
'poller_type' => 'snmp',
'sensor_class' => 'current',
'sensor_oid' => ".1.3.6.1.4.1.36673.100.1.2.3.1.12.$cmmStackUnitIndex.$cmmTransIndex.$cmmTransChannelIndex",
'sensor_index' => "$cmmStackUnitIndex.$cmmTransIndex.$cmmTransChannelIndex",
'sensor_type' => 'ocnos',
'sensor_descr' => "$ifName$channelDescr xcvr bias",
'sensor_divisor' => $divisor,
'sensor_multiplier' => 1,
'sensor_limit' => isset($channel_data['IPI-CMM-CHASSIS-MIB::cmmTransLaserBiasCurrCriticalThresholdMax']) ? $channel_data['IPI-CMM-CHASSIS-MIB::cmmTransLaserBiasCurrCriticalThresholdMax'] / $divisor : null,
'sensor_limit_warn' => isset($channel_data['IPI-CMM-CHASSIS-MIB::cmmTransLaserBiasCurrAlertThresholdMax']) ? $channel_data['IPI-CMM-CHASSIS-MIB::cmmTransLaserBiasCurrAlertThresholdMax'] / $divisor : null,
'sensor_limit_low' => isset($channel_data['IPI-CMM-CHASSIS-MIB::cmmTransLaserBiasCurrCriticalThresholdMin']) ? $channel_data['IPI-CMM-CHASSIS-MIB::cmmTransLaserBiasCurrCriticalThresholdMin'] / $divisor : null,
'sensor_limit_low_warn' => isset($channel_data['IPI-CMM-CHASSIS-MIB::cmmTransLaserBiasCurrAlertThresholdMin']) ? $channel_data['IPI-CMM-CHASSIS-MIB::cmmTransLaserBiasCurrAlertThresholdMin'] / $divisor : null,
'sensor_current' => isset($channel_data['IPI-CMM-CHASSIS-MIB::cmmTransLaserBiasCurrent']) ? $channel_data['IPI-CMM-CHASSIS-MIB::cmmTransLaserBiasCurrent'] / $divisor : null,
'entPhysicalIndex' => $cmmStackUnitIndex * 10000 + $cmmTransIndex,
'entPhysicalIndex_measured' => 'port',
'user_func' => null,
'group' => 'transceiver',
]));
}
}
}
}
}

View File

@@ -15,38 +15,39 @@ echo 'Comware ';
$multiplier = 1;
$divisor = 100;
foreach ($pre_cache['comware_oids'] as $index => $entry) {
if (is_numeric($entry['hh3cTransceiverCurRXPower']) && $entry['hh3cTransceiverCurRXPower'] != 2147483647 && isset($entry['hh3cTransceiverDiagnostic'])) {
$hh3cTransceiverInfoTable = SnmpQuery::cache()->enumStrings()->walk('HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverInfoTable')->table(1);
foreach ($hh3cTransceiverInfoTable as $index => $entry) {
if (is_numeric($entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverCurRXPower']) && $entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverCurRXPower'] != 2147483647 && isset($entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverDiagnostic'])) {
$interface = get_port_by_index_cache($device['device_id'], $index);
if ($interface['ifAdminStatus'] != 'up') {
continue;
}
$oid = '.1.3.6.1.4.1.25506.2.70.1.1.1.12.' . $index;
$limit_low = round(uw_to_dbm($entry['hh3cTransceiverRcvPwrLoAlarm'] / 10), 2);
$warn_limit_low = round(uw_to_dbm($entry['hh3cTransceiverRcvPwrLoWarn'] / 10), 2);
$limit = round(uw_to_dbm($entry['hh3cTransceiverRcvPwrHiAlarm'] / 10), 2);
$warn_limit = round(uw_to_dbm($entry['hh3cTransceiverRcvPwrHiWarn'] / 10), 2);
$current = $entry['hh3cTransceiverCurRXPower'] / $divisor;
$limit_low = round(uw_to_dbm($entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverRcvPwrLoAlarm'] / 10), 2);
$warn_limit_low = round(uw_to_dbm($entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverRcvPwrLoWarn'] / 10), 2);
$limit = round(uw_to_dbm($entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverRcvPwrHiAlarm'] / 10), 2);
$warn_limit = round(uw_to_dbm($entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverRcvPwrHiWarn'] / 10), 2);
$current = $entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverCurRXPower'] / $divisor;
$entPhysicalIndex = $index;
$entPhysicalIndex_measured = 'ports';
$descr = makeshortif($interface['ifDescr']) . ' Receive Power';
discover_sensor(null, 'dbm', $device, $oid, 'rx-' . $index, 'comware', $descr, $divisor, $multiplier, $limit_low, $warn_limit_low, $warn_limit, $limit, $current, 'snmp', $entPhysicalIndex, $entPhysicalIndex_measured);
discover_sensor(null, 'dbm', $device, $oid, 'rx-' . $index, 'comware', $descr, $divisor, $multiplier, $limit_low, $warn_limit_low, $warn_limit, $limit, $current, 'snmp', $entPhysicalIndex, $entPhysicalIndex_measured, group: 'transceiver');
}
if (is_numeric($entry['hh3cTransceiverCurTXPower']) && $entry['hh3cTransceiverCurTXPower'] != 2147483647 && isset($entry['hh3cTransceiverDiagnostic'])) {
if (is_numeric($entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverCurTXPower']) && $entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverCurTXPower'] != 2147483647 && isset($entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverDiagnostic'])) {
$oid = '.1.3.6.1.4.1.25506.2.70.1.1.1.9.' . $index;
$limit_low = round(uw_to_dbm($entry['hh3cTransceiverPwrOutLoAlarm'] / 10), 2);
$warn_limit_low = round(uw_to_dbm($entry['hh3cTransceiverPwrOutLoWarn'] / 10), 2);
$limit = round(uw_to_dbm($entry['hh3cTransceiverPwrOutHiAlarm'] / 10), 2);
$warn_limit = round(uw_to_dbm($entry['hh3cTransceiverPwrOutHiWarn'] / 10), 2);
$current = $entry['hh3cTransceiverCurTXPower'] / $divisor;
$limit_low = round(uw_to_dbm($entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverPwrOutLoAlarm'] / 10), 2);
$warn_limit_low = round(uw_to_dbm($entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverPwrOutLoWarn'] / 10), 2);
$limit = round(uw_to_dbm($entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverPwrOutHiAlarm'] / 10), 2);
$warn_limit = round(uw_to_dbm($entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverPwrOutHiWarn'] / 10), 2);
$current = $entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverCurTXPower'] / $divisor;
$entPhysicalIndex = $index;
$entPhysicalIndex_measured = 'ports';
$interface = get_port_by_index_cache($device['device_id'], $index);
if ($interface['ifAdminStatus'] == 'up') {
$descr = makeshortif($interface['ifDescr']) . ' Transmit Power';
discover_sensor(null, 'dbm', $device, $oid, 'tx-' . $index, 'comware', $descr, $divisor, $multiplier, $limit_low, $warn_limit_low, $warn_limit, $limit, $current, 'snmp', $entPhysicalIndex, $entPhysicalIndex_measured);
discover_sensor(null, 'dbm', $device, $oid, 'tx-' . $index, 'comware', $descr, $divisor, $multiplier, $limit_low, $warn_limit_low, $warn_limit, $limit, $current, 'snmp', $entPhysicalIndex, $entPhysicalIndex_measured, group: 'transceiver');
}
}
}

View File

@@ -0,0 +1,55 @@
<?php
$ponTable = SnmpQuery::cache()->walk('E7-Calix-MIB::e7OltPonPortTable')->table(3);
foreach ($ponTable as $e7OltPonPortShelf => $ponShelf) {
foreach ($ponShelf as $e7OltPonPortSlot => $ponSlot) {
foreach ($ponSlot as $e7OltPonPortId => $ponPort) {
if ($ponPort['E7-Calix-MIB::e7OltPonPortStatus'] != 0) {
$ifIndex = \LibreNMS\OS\Exa::getIfIndex($e7OltPonPortShelf, $e7OltPonPortSlot, $e7OltPonPortId, 'gpon'); // we know these are GPON, so we can infer the ifIndex
$index = "$e7OltPonPortShelf.$e7OltPonPortSlot.$e7OltPonPortId";
$name = "$e7OltPonPortShelf/$e7OltPonPortSlot/$e7OltPonPortId";
app('sensor-discovery')->discover(new \App\Models\Sensor([
'poller_type' => 'snmp',
'sensor_class' => 'dbm',
'sensor_oid' => ".1.3.6.1.4.1.6321.1.2.2.2.1.6.2.1.7.$index",
'sensor_index' => 'tx.' . $index,
'sensor_type' => 'exa',
'sensor_descr' => "$name xcvr TX power",
'sensor_divisor' => 1,
'sensor_multiplier' => 1,
'sensor_limit_low' => 0,
'sensor_limit_low_warn' => 0.2,
'sensor_limit_warn' => 5.8,
'sensor_limit' => 6,
'sensor_current' => mw_to_dbm($ponPort['E7-Calix-MIB::e7OltPonPortTxPower']),
'entPhysicalIndex' => $ifIndex,
'entPhysicalIndex_measured' => 'port',
'group' => 'transceiver',
'user_func' => 'mw_to_dbm',
]));
app('sensor-discovery')->discover(new \App\Models\Sensor([
'poller_type' => 'snmp',
'sensor_class' => 'dbm',
'sensor_oid' => ".1.3.6.1.4.1.6321.1.2.2.2.1.6.2.1.8.$index",
'sensor_index' => 'rx.' . $index,
'sensor_type' => 'exa',
'sensor_descr' => "$name xcvr RX power",
'sensor_divisor' => 1,
'sensor_multiplier' => 1,
'sensor_limit_low' => -28,
'sensor_limit_low_warn' => -27,
'sensor_limit_warn' => -8,
'sensor_limit' => -7,
'sensor_current' => mw_to_dbm($ponPort['E7-Calix-MIB::e7OltPonPortRxPower']),
'entPhysicalIndex' => $ifIndex,
'entPhysicalIndex_measured' => 'port',
'group' => 'transceiver',
'user_func' => 'mw_to_dbm',
]));
}
}
}
}

View File

@@ -0,0 +1,67 @@
<?php
use LibreNMS\Util\Number;
$powerTables = SnmpQuery::walk('FS-SWITCH-V2-MIB::transReceivePowerTable')->table(1);
if (! empty($powerTables)) {
SnmpQuery::walk('FS-SWITCH-V2-MIB::transTransmitPowerTable')->table(1, $powerTables);
}
$ifIndexToName = SnmpQuery::cache()->walk('IF-MIB::ifName')->pluck();
foreach ($powerTables as $ifIndex => $current) {
$ifName = $ifIndexToName[$ifIndex] ?? $ifIndex;
// power-rx
if (! empty($current['FS-SWITCH-V2-MIB::receivepowerCurrent']) && $current['FS-SWITCH-V2-MIB::receivepowerCurrent'] !== '0.00') {
foreach (explode(',', $current['FS-SWITCH-V2-MIB::receivepowerCurrent']) as $channel => $value) {
app('sensor-discovery')->discover(new \App\Models\Sensor([
'poller_type' => 'snmp',
'sensor_class' => 'dbm',
'sensor_oid' => ".1.3.6.1.4.1.52642.1.37.1.10.6.1.5.$ifIndex",
'sensor_index' => "rx-$ifIndex.$channel",
'sensor_type' => 'fs-centec',
'sensor_descr' => "$ifName:$channel xcvr TX power",
'sensor_divisor' => 1,
'sensor_multiplier' => 1,
'sensor_limit_low' => $current['FS-SWITCH-V2-MIB::receivepowerLowAlarmThreshold'] ?? null,
'sensor_limit_low_warn' => $current['FS-SWITCH-V2-MIB::receivepowerLowWarnThreshold'] ?? null,
'sensor_limit_warn' => $current['FS-SWITCH-V2-MIB::receivepowerHighWarnThreshold'] ?? null,
'sensor_limit' => $current['FS-SWITCH-V2-MIB::receivepowerHighAlarmThreshold'] ?? null,
'sensor_current' => Number::cast($value),
'entPhysicalIndex' => $ifIndex,
'entPhysicalIndex_measured' => 'port',
'user_func' => 'fsParseChannelValue',
'group' => 'transceiver',
]));
}
}
// power-tx
if (! empty($current['FS-SWITCH-V2-MIB::transpowerCurrent']) && $current['FS-SWITCH-V2-MIB::transpowerCurrent'] !== '0.00') {
foreach (explode(',', $current['FS-SWITCH-V2-MIB::transpowerCurrent']) as $channel => $value) {
app('sensor-discovery')->discover(new \App\Models\Sensor([
'poller_type' => 'snmp',
'sensor_class' => 'dbm',
'sensor_oid' => ".1.3.6.1.4.1.52642.1.37.1.10.5.1.5.$ifIndex",
'sensor_index' => "tx-$ifIndex.$channel",
'sensor_type' => 'fs-centec',
'sensor_descr' => "$ifName:$channel xcvr RX power",
'sensor_divisor' => 1,
'sensor_multiplier' => 1,
'sensor_limit_low' => $current['FS-SWITCH-V2-MIB::transpowerLowAlarmThreshold'] ?? null,
'sensor_limit_low_warn' => $current['FS-SWITCH-V2-MIB::transpowerLowWarnThreshold'] ?? null,
'sensor_limit_warn' => $current['FS-SWITCH-V2-MIB::transpowerHighWarnThreshold'] ?? null,
'sensor_limit' => $current['FS-SWITCH-V2-MIB::transpowerHighAlarmThreshold'] ?? null,
'sensor_current' => Number::cast($value),
'entPhysicalIndex' => $ifIndex,
'entPhysicalIndex_measured' => 'port',
'user_func' => 'fsParseChannelValue',
'group' => 'transceiver',
]));
}
}
}
unset($powerTables, $current);

View File

@@ -0,0 +1,66 @@
<?php
if (empty($os)) {
$os = OS::make($device);
}
if ($os instanceof \LibreNMS\OS\Ocnos) {
$metric_data = \SnmpQuery::cache()->enumStrings()->walk(['IPI-CMM-CHASSIS-MIB::cmmTransDDMTable', 'IPI-CMM-CHASSIS-MIB::cmmTransType'])->table(3);
$divisor = 1000;
foreach ($metric_data as $cmmStackUnitIndex => $chassis_data) {
foreach ($chassis_data as $cmmTransIndex => $module_data) {
$ifName = $os->guessIfName($cmmTransIndex, $module_data['IPI-CMM-CHASSIS-MIB::cmmTransType'] ?? 'unknown');
foreach ($module_data as $cmmTransChannelIndex => $channel_data) {
$channelDescr = count($module_data) > 2 ? " Channel $cmmTransChannelIndex" : '';
// power-tx
if (isset($channel_data['IPI-CMM-CHASSIS-MIB::cmmTransTxPowerSupported']) && $channel_data['IPI-CMM-CHASSIS-MIB::cmmTransTxPowerSupported'] == 'supported') {
app('sensor-discovery')->discover(new \App\Models\Sensor([
'poller_type' => 'snmp',
'sensor_class' => 'dbm',
'sensor_oid' => ".1.3.6.1.4.1.36673.100.1.2.3.1.17.$cmmStackUnitIndex.$cmmTransIndex.$cmmTransChannelIndex",
'sensor_index' => "tx-$cmmStackUnitIndex.$cmmTransIndex.$cmmTransChannelIndex",
'sensor_type' => 'ocnos',
'sensor_descr' => "$ifName$channelDescr xcvr TX power",
'sensor_divisor' => $divisor,
'sensor_multiplier' => 1,
'sensor_limit' => isset($channel_data['IPI-CMM-CHASSIS-MIB::cmmTransTxPowerCriticalThresholdMax']) ? $channel_data['IPI-CMM-CHASSIS-MIB::cmmTransTxPowerCriticalThresholdMax'] / $divisor : null,
'sensor_limit_warn' => isset($channel_data['IPI-CMM-CHASSIS-MIB::cmmTransTxPowerAlertThresholdMax']) ? $channel_data['IPI-CMM-CHASSIS-MIB::cmmTransTxPowerAlertThresholdMax'] / $divisor : null,
'sensor_limit_low' => isset($channel_data['IPI-CMM-CHASSIS-MIB::cmmTransTxPowerCriticalThresholdMin']) ? $channel_data['IPI-CMM-CHASSIS-MIB::cmmTransTxPowerCriticalThresholdMin'] / $divisor : null,
'sensor_limit_low_warn' => isset($channel_data['IPI-CMM-CHASSIS-MIB::cmmTransTxPowerAlertThresholdMin']) ? $channel_data['IPI-CMM-CHASSIS-MIB::cmmTransTxPowerAlertThresholdMin'] / $divisor : null,
'sensor_current' => isset($channel_data['IPI-CMM-CHASSIS-MIB::cmmTransTxPower']) ? $channel_data['IPI-CMM-CHASSIS-MIB::cmmTransTxPower'] / $divisor : null,
'entPhysicalIndex' => null, // TODO
'entPhysicalIndex_measured' => 'port',
'user_func' => null,
'group' => 'transceiver',
]));
}
// power-rx
if (isset($channel_data['IPI-CMM-CHASSIS-MIB::cmmTransRxPowerSupported']) && $channel_data['IPI-CMM-CHASSIS-MIB::cmmTransRxPowerSupported'] == 'supported') {
app('sensor-discovery')->discover(new \App\Models\Sensor([
'poller_type' => 'snmp',
'sensor_class' => 'dbm',
'sensor_oid' => ".1.3.6.1.4.1.36673.100.1.2.3.1.22.$cmmStackUnitIndex.$cmmTransIndex.$cmmTransChannelIndex",
'sensor_index' => "rx-$cmmStackUnitIndex.$cmmTransIndex.$cmmTransChannelIndex",
'sensor_type' => 'ocnos',
'sensor_descr' => "$ifName$channelDescr xcvr RX power",
'sensor_divisor' => $divisor,
'sensor_multiplier' => 1,
'sensor_limit' => isset($channel_data['IPI-CMM-CHASSIS-MIB::cmmTransRxPowerCriticalThresholdMax']) ? $channel_data['IPI-CMM-CHASSIS-MIB::cmmTransRxPowerCriticalThresholdMax'] / $divisor : null,
'sensor_limit_warn' => isset($channel_data['IPI-CMM-CHASSIS-MIB::cmmTransRxPowerAlertThresholdMax']) ? $channel_data['IPI-CMM-CHASSIS-MIB::cmmTransRxPowerAlertThresholdMax'] / $divisor : null,
'sensor_limit_low' => isset($channel_data['IPI-CMM-CHASSIS-MIB::cmmTransRxPowerCriticalThresholdMin']) ? $channel_data['IPI-CMM-CHASSIS-MIB::cmmTransRxPowerCriticalThresholdMin'] / $divisor : null,
'sensor_limit_low_warn' => isset($channel_data['IPI-CMM-CHASSIS-MIB::cmmTransRxPowerAlertThresholdMin']) ? $channel_data['IPI-CMM-CHASSIS-MIB::cmmTransRxPowerAlertThresholdMin'] / $divisor : null,
'sensor_current' => isset($channel_data['IPI-CMM-CHASSIS-MIB::cmmTransRxPower']) ? $channel_data['IPI-CMM-CHASSIS-MIB::cmmTransRxPower'] / $divisor : null,
'entPhysicalIndex' => $cmmStackUnitIndex * 10000 + $cmmTransIndex,
'entPhysicalIndex_measured' => 'port',
'user_func' => null,
'group' => 'transceiver',
]));
}
}
}
}
}

View File

@@ -1,14 +0,0 @@
<?php
/*
* LibreNMS
*
* Copyright (c) 2016 Søren Friis Rosiak <sorenrosiak@gmail.com>
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version. Please see LICENSE.txt at the top level of
* the source code distribution for details.
*/
echo 'hh3cTransceiverInfoTable ';
$pre_cache['comware_oids'] = snmpwalk_cache_multi_oid($device, 'hh3cTransceiverInfoTable', [], 'HH3C-TRANSCEIVER-INFO-MIB');

View File

@@ -0,0 +1,36 @@
<?php
$ponTable = SnmpQuery::cache()->walk('E7-Calix-MIB::e7OltPonPortTable')->table(3);
foreach ($ponTable as $e7OltPonPortShelf => $ponShelf) {
foreach ($ponShelf as $e7OltPonPortSlot => $ponSlot) {
foreach ($ponSlot as $e7OltPonPortId => $ponPort) {
if ($ponPort['E7-Calix-MIB::e7OltPonPortStatus'] != 0) {
$ifIndex = \LibreNMS\OS\Exa::getIfIndex($e7OltPonPortShelf, $e7OltPonPortSlot, $e7OltPonPortId, 'gpon'); // we know these are GPON, so we can infer the ifIndex
$index = "$e7OltPonPortShelf.$e7OltPonPortSlot.$e7OltPonPortId";
$name = "$e7OltPonPortShelf/$e7OltPonPortSlot/$e7OltPonPortId";
app('sensor-discovery')->discover(new \App\Models\Sensor([
'poller_type' => 'snmp',
'sensor_class' => 'state',
'sensor_oid' => ".1.3.6.1.4.1.6321.1.2.2.2.1.6.2.1.4.$index",
'sensor_index' => 'ponStatus.' . $index,
'sensor_type' => 'E7-Calix-MIB::e7OltPonPortStatus',
'sensor_descr' => "$name Status",
'sensor_divisor' => 1,
'sensor_multiplier' => 1,
'sensor_current' => $ponPort['E7-Calix-MIB::e7OltPonPortStatus'],
'entPhysicalIndex' => $ifIndex,
'entPhysicalIndex_measured' => 'port',
'group' => $name,
]));
// FIXME
// ->withStateTranslations('E7-Calix-MIB::e7OltPonPortStatus', [
// ['value' => 0, 'generic' => 3, 'graph' => 1, 'descr' => 'invalid'],
// ['value' => 1, 'generic' => 0, 'graph' => 1, 'descr' => 'linkUp'],
// ['value' => 2, 'generic' => 2, 'graph' => 1, 'descr' => 'linkDown'],
// ]);
}
}
}
}

View File

@@ -57,23 +57,24 @@ if (! empty($entphydata)) {
$multiplier = 1;
$divisor = 1;
$divisor_alarm = 1000;
foreach ($pre_cache['comware_oids'] as $index => $entry) {
if (is_numeric($entry['hh3cTransceiverTemperature']) && $entry['hh3cTransceiverTemperature'] != 2147483647 && isset($entry['hh3cTransceiverDiagnostic'])) {
$hh3cTransceiverInfoTable = SnmpQuery::cache()->enumStrings()->walk('HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverInfoTable')->table(1);
foreach ($hh3cTransceiverInfoTable as $index => $entry) {
if (is_numeric($entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverTemperature']) && $entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverTemperature'] != 2147483647 && isset($entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverDiagnostic'])) {
$interface = get_port_by_index_cache($device['device_id'], $index);
if ($interface['ifAdminStatus'] != 'up') {
continue;
}
$oid = '.1.3.6.1.4.1.25506.2.70.1.1.1.15.' . $index;
$limit_low = $entry['hh3cTransceiverTempLoAlarm'] / $divisor_alarm;
$warn_limit_low = $entry['hh3cTransceiverTempLoWarn'] / $divisor_alarm;
$limit = $entry['hh3cTransceiverTempHiAlarm'] / $divisor_alarm;
$warn_limit = $entry['hh3cTransceiverTempHiWarn'] / $divisor_alarm;
$current = $entry['hh3cTransceiverTemperature'];
$limit_low = $entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverTempLoAlarm'] / $divisor_alarm;
$warn_limit_low = $entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverTempLoWarn'] / $divisor_alarm;
$limit = $entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverTempHiAlarm'] / $divisor_alarm;
$warn_limit = $entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverTempHiWarn'] / $divisor_alarm;
$current = $entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverTemperature'];
$entPhysicalIndex = $index;
$entPhysicalIndex_measured = 'ports';
$descr = makeshortif($interface['ifDescr']) . ' Module';
discover_sensor(null, 'temperature', $device, $oid, 'temp-trans-' . $index, 'comware', $descr, $divisor, $multiplier, $limit_low, $warn_limit_low, $warn_limit, $limit, $current, 'snmp', $entPhysicalIndex, $entPhysicalIndex_measured);
discover_sensor(null, 'temperature', $device, $oid, 'temp-trans-' . $index, 'comware', $descr, $divisor, $multiplier, $limit_low, $warn_limit_low, $warn_limit, $limit, $current, 'snmp', $entPhysicalIndex, $entPhysicalIndex_measured, group: 'transceiver');
}
}

View File

@@ -0,0 +1,34 @@
<?php
$ponTable = SnmpQuery::cache()->walk('E7-Calix-MIB::e7OltPonPortTable')->table(3);
foreach ($ponTable as $e7OltPonPortShelf => $ponShelf) {
foreach ($ponShelf as $e7OltPonPortSlot => $ponSlot) {
foreach ($ponSlot as $e7OltPonPortId => $ponPort) {
if ($ponPort['E7-Calix-MIB::e7OltPonPortStatus'] != 0) {
$ifIndex = \LibreNMS\OS\Exa::getIfIndex($e7OltPonPortShelf, $e7OltPonPortSlot, $e7OltPonPortId, 'gpon'); // we know these are GPON, so we can infer the ifIndex
$index = "$e7OltPonPortShelf.$e7OltPonPortSlot.$e7OltPonPortId";
$name = "$e7OltPonPortShelf/$e7OltPonPortSlot/$e7OltPonPortId";
app('sensor-discovery')->discover(new \App\Models\Sensor([
'poller_type' => 'snmp',
'sensor_class' => 'temperature',
'sensor_oid' => ".1.3.6.1.4.1.6321.1.2.2.2.1.6.2.1.5.$index",
'sensor_index' => $index,
'sensor_type' => 'transceiver',
'sensor_descr' => "$name xcvr temperature",
'sensor_divisor' => 1,
'sensor_multiplier' => 1,
'sensor_limit_low' => -40,
'sensor_limit_low_warn' => -25,
'sensor_limit_warn' => 70,
'sensor_limit' => 85,
'sensor_current' => $ponPort['E7-Calix-MIB::e7OltPonPortTemperature'] ?? null,
'entPhysicalIndex' => $ifIndex,
'entPhysicalIndex_measured' => 'port',
'group' => $name,
]));
}
}
}
}

View File

@@ -0,0 +1,38 @@
<?php
use LibreNMS\Util\Number;
$tempTable = SnmpQuery::walk('FS-SWITCH-V2-MIB::transTemperinformationTable')->table(1);
$ifIndexToName = SnmpQuery::cache()->walk('IF-MIB::ifName')->pluck();
foreach ($tempTable as $ifIndex => $current) {
$ifName = $ifIndexToName[$ifIndex] ?? $ifIndex;
if (! empty($current['FS-SWITCH-V2-MIB::temperCurrent']) && $current['FS-SWITCH-V2-MIB::temperCurrent'] !== '0.00') {
foreach (explode(',', $current['FS-SWITCH-V2-MIB::temperCurrent']) as $channel => $value) {
app('sensor-discovery')->discover(new \App\Models\Sensor([
'poller_type' => 'snmp',
'sensor_class' => 'temperature',
'sensor_oid' => ".1.3.6.1.4.1.52642.1.37.1.10.2.1.5.$ifIndex",
'sensor_index' => "$ifIndex.$channel",
'sensor_type' => 'transceiver',
'sensor_descr' => "$ifName xcvr temperature",
'sensor_divisor' => 1,
'sensor_multiplier' => 1,
'sensor_limit_low' => $current['FS-SWITCH-V2-MIB::temperLowAlarmThreshold'] ?? null,
'sensor_limit_low_warn' => $current['FS-SWITCH-V2-MIB::temperLowWarnThreshold'] ?? null,
'sensor_limit_warn' => $current['FS-SWITCH-V2-MIB::temperHighWarnThreshold'] ?? null,
'sensor_limit' => $current['FS-SWITCH-V2-MIB::temperHighAlarmThreshold'] ?? null,
'sensor_current' => Number::cast($value),
'entPhysicalIndex' => $ifIndex,
'entPhysicalIndex_measured' => 'port',
'user_func' => 'fsParseChannelValue',
'group' => $ifName,
]));
break; // only discover one sensor
}
}
}
unset($tempTable, $current);

View File

@@ -0,0 +1,42 @@
<?php
if (empty($os)) {
$os = OS::make($device);
}
if ($os instanceof \LibreNMS\OS\Ocnos) {
$metric_data = \SnmpQuery::cache()->enumStrings()->walk(['IPI-CMM-CHASSIS-MIB::cmmTransDDMTable', 'IPI-CMM-CHASSIS-MIB::cmmTransType'])->table(3);
$divisor = 100;
foreach ($metric_data as $cmmStackUnitIndex => $chassis_data) {
foreach ($chassis_data as $cmmTransIndex => $module_data) {
$ifName = $os->guessIfName($cmmTransIndex, $module_data['IPI-CMM-CHASSIS-MIB::cmmTransType'] ?? 'unknown');
foreach ($module_data as $cmmTransChannelIndex => $channel_data) {
if (isset($channel_data['IPI-CMM-CHASSIS-MIB::cmmTransTemperature']) && $channel_data['IPI-CMM-CHASSIS-MIB::cmmTransTemperature'] != '-100001') {
app('sensor-discovery')->discover(new \App\Models\Sensor([
'poller_type' => 'snmp',
'sensor_class' => 'temperature',
'sensor_oid' => ".1.3.6.1.4.1.36673.100.1.2.3.1.2.$cmmStackUnitIndex.$cmmTransIndex.$cmmTransChannelIndex",
'sensor_index' => "$cmmStackUnitIndex.$cmmTransIndex",
'sensor_type' => 'transceiver',
'sensor_descr' => "$ifName xcvr temperature",
'sensor_divisor' => $divisor,
'sensor_multiplier' => 1,
'sensor_limit' => isset($channel_data['IPI-CMM-CHASSIS-MIB::cmmTransTempCriticalThresholdMax']) ? $channel_data['IPI-CMM-CHASSIS-MIB::cmmTransTempCriticalThresholdMax'] / $divisor : null,
'sensor_limit_warn' => isset($channel_data['IPI-CMM-CHASSIS-MIB::cmmTransTempAlertThresholdMax']) ? $channel_data['IPI-CMM-CHASSIS-MIB::cmmTransTempAlertThresholdMax'] / $divisor : null,
'sensor_limit_low' => isset($channel_data['IPI-CMM-CHASSIS-MIB::cmmTransTempCriticalThresholdMin']) ? $channel_data['IPI-CMM-CHASSIS-MIB::cmmTransTempCriticalThresholdMin'] / $divisor : null,
'sensor_limit_low_warn' => isset($channel_data['IPI-CMM-CHASSIS-MIB::cmmTransTempAlertThresholdMin']) ? $channel_data['IPI-CMM-CHASSIS-MIB::cmmTransTempAlertThresholdMin'] / $divisor : null,
'sensor_current' => isset($channel_data['IPI-CMM-CHASSIS-MIB::cmmTransTemperature']) ? $channel_data['IPI-CMM-CHASSIS-MIB::cmmTransTemperature'] / $divisor : null,
'entPhysicalIndex' => $cmmStackUnitIndex * 10000 + $cmmTransIndex,
'entPhysicalIndex_measured' => 'port',
'user_func' => null,
'group' => $ifName,
]));
continue 2; // common across channels
}
}
}
}
}

View File

@@ -16,23 +16,24 @@ echo 'Comware ';
$multiplier = 1;
$divisor = 100;
$divisor_alarm = 10000;
foreach ($pre_cache['comware_oids'] as $index => $entry) {
if (is_numeric($entry['hh3cTransceiverVoltage']) && $entry['hh3cTransceiverVoltage'] != 2147483647 && isset($entry['hh3cTransceiverDiagnostic'])) {
$hh3cTransceiverInfoTable = SnmpQuery::cache()->enumStrings()->walk('HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverInfoTable')->table(1);
foreach ($hh3cTransceiverInfoTable as $index => $entry) {
if (is_numeric($entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverVoltage']) && $entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverVoltage'] != 2147483647 && isset($entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverDiagnostic'])) {
$interface = get_port_by_index_cache($device['device_id'], $index);
if ($interface['ifAdminStatus'] != 'up') {
continue;
}
$oid = '.1.3.6.1.4.1.25506.2.70.1.1.1.16.' . $index;
$limit_low = $entry['hh3cTransceiverVccLoAlarm'] / $divisor_alarm;
$warn_limit_low = $entry['hh3cTransceiverVccLoWarn'] / $divisor_alarm;
$limit = $entry['hh3cTransceiverVccHiAlarm'] / $divisor_alarm;
$warn_limit = $entry['hh3cTransceiverVccHiWarn'] / $divisor_alarm;
$current = $entry['hh3cTransceiverVoltage'] / $divisor;
$limit_low = $entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverVccLoAlarm'] / $divisor_alarm;
$warn_limit_low = $entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverVccLoWarn'] / $divisor_alarm;
$limit = $entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverVccHiAlarm'] / $divisor_alarm;
$warn_limit = $entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverVccHiWarn'] / $divisor_alarm;
$current = $entry['HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverVoltage'] / $divisor;
$entPhysicalIndex = $index;
$entPhysicalIndex_measured = 'ports';
$descr = makeshortif($interface['ifDescr']) . ' Supply Voltage';
discover_sensor(null, 'voltage', $device, $oid, 'volt-' . $index, 'comware', $descr, $divisor, $multiplier, $limit_low, $warn_limit_low, $warn_limit, $limit, $current, 'snmp', $entPhysicalIndex, $entPhysicalIndex_measured);
discover_sensor(null, 'voltage', $device, $oid, 'volt-' . $index, 'comware', $descr, $divisor, $multiplier, $limit_low, $warn_limit_low, $warn_limit, $limit, $current, 'snmp', $entPhysicalIndex, $entPhysicalIndex_measured, group: 'transceiver');
}
}

View File

@@ -0,0 +1,34 @@
<?php
$ponTable = SnmpQuery::cache()->walk('E7-Calix-MIB::e7OltPonPortTable')->table(3);
foreach ($ponTable as $e7OltPonPortShelf => $ponShelf) {
foreach ($ponShelf as $e7OltPonPortSlot => $ponSlot) {
foreach ($ponSlot as $e7OltPonPortId => $ponPort) {
if ($ponPort['E7-Calix-MIB::e7OltPonPortStatus'] != 0) {
$ifIndex = \LibreNMS\OS\Exa::getIfIndex($e7OltPonPortShelf, $e7OltPonPortSlot, $e7OltPonPortId, 'gpon'); // we know these are GPON, so we can infer the ifIndex
$index = "$e7OltPonPortShelf.$e7OltPonPortSlot.$e7OltPonPortId";
$name = "$e7OltPonPortShelf/$e7OltPonPortSlot/$e7OltPonPortId";
app('sensor-discovery')->discover(new \App\Models\Sensor([
'poller_type' => 'snmp',
'sensor_class' => 'voltage',
'sensor_oid' => ".1.3.6.1.4.1.6321.1.2.2.2.1.6.2.1.9.$index",
'sensor_index' => $index,
'sensor_type' => 'exa',
'sensor_descr' => "$name xcvr voltage",
'sensor_divisor' => 1000,
'sensor_multiplier' => 1,
'sensor_limit_low' => 3,
'sensor_limit_low_warn' => 3.1,
'sensor_limit_warn' => 3.5,
'sensor_limit' => 3.6,
'sensor_current' => $ponPort['E7-Calix-MIB::e7OltPonPortVoltage'] / 1000,
'entPhysicalIndex' => $ifIndex,
'entPhysicalIndex_measured' => 'port',
'group' => 'transceiver',
]));
}
}
}
}

View File

@@ -0,0 +1,38 @@
<?php
use LibreNMS\Util\Number;
$voltageTable = SnmpQuery::walk('FS-SWITCH-V2-MIB::transVoltageinformationTable')->table(1);
$ifIndexToName = SnmpQuery::cache()->walk('IF-MIB::ifName')->pluck();
foreach ($voltageTable as $ifIndex => $current) {
$ifName = $ifIndexToName[$ifIndex] ?? $ifIndex;
if (! empty($current['FS-SWITCH-V2-MIB::voltageCurrent']) && $current['FS-SWITCH-V2-MIB::voltageCurrent'] !== '0.00') {
foreach (explode(',', $current['FS-SWITCH-V2-MIB::voltageCurrent']) as $channel => $value) {
app('sensor-discovery')->discover(new \App\Models\Sensor([
'poller_type' => 'snmp',
'sensor_class' => 'voltage',
'sensor_oid' => ".1.3.6.1.4.1.52642.1.37.1.10.3.1.5.$ifIndex",
'sensor_index' => "$ifIndex.$channel",
'sensor_type' => 'fs-centec',
'sensor_descr' => "$ifName xcvr voltage",
'sensor_divisor' => 1,
'sensor_multiplier' => 1,
'sensor_limit_low' => $current['FS-SWITCH-V2-MIB::voltageLowAlarmThreshold'] ?? null,
'sensor_limit_low_warn' => $current['FS-SWITCH-V2-MIB::voltageLowWarnThreshold'] ?? null,
'sensor_limit_warn' => $current['FS-SWITCH-V2-MIB::voltageHighWarnThreshold'] ?? null,
'sensor_limit' => $current['FS-SWITCH-V2-MIB::voltageHighAlarmThreshold'] ?? null,
'sensor_current' => Number::cast($value),
'entPhysicalIndex' => $ifIndex,
'entPhysicalIndex_measured' => 'port',
'user_func' => 'fsParseChannelValue',
'group' => 'transceiver',
]));
break; // only discover one sensor
}
}
}
unset($voltageTable, $current);

View File

@@ -0,0 +1,42 @@
<?php
if (empty($os)) {
$os = OS::make($device);
}
if ($os instanceof \LibreNMS\OS\Ocnos) {
$metric_data = \SnmpQuery::cache()->enumStrings()->walk(['IPI-CMM-CHASSIS-MIB::cmmTransDDMTable', 'IPI-CMM-CHASSIS-MIB::cmmTransType'])->table(3);
$divisor = 1000;
foreach ($metric_data as $cmmStackUnitIndex => $chassis_data) {
foreach ($chassis_data as $cmmTransIndex => $module_data) {
$ifName = $os->guessIfName($cmmTransIndex, $module_data['IPI-CMM-CHASSIS-MIB::cmmTransType'] ?? 'unknown');
foreach ($module_data as $cmmTransChannelIndex => $channel_data) {
if (isset($channel_data['IPI-CMM-CHASSIS-MIB::cmmTransVoltage']) && $channel_data['IPI-CMM-CHASSIS-MIB::cmmTransVoltage'] != '-100001') {
app('sensor-discovery')->discover(new \App\Models\Sensor([
'poller_type' => 'snmp',
'sensor_class' => 'voltage',
'sensor_oid' => ".1.3.6.1.4.1.36673.100.1.2.3.1.7.$cmmStackUnitIndex.$cmmTransIndex.$cmmTransChannelIndex",
'sensor_index' => "$cmmStackUnitIndex.$cmmTransIndex",
'sensor_type' => 'ocnos',
'sensor_descr' => "$ifName xcvr voltage",
'sensor_divisor' => $divisor,
'sensor_multiplier' => 1,
'sensor_limit' => isset($channel_data['IPI-CMM-CHASSIS-MIB::cmmTransVoltCriticalThresholdMax']) ? $channel_data['IPI-CMM-CHASSIS-MIB::cmmTransVoltCriticalThresholdMax'] / $divisor : null,
'sensor_limit_warn' => isset($channel_data['IPI-CMM-CHASSIS-MIB::cmmTransVoltAlertThresholdMax']) ? $channel_data['IPI-CMM-CHASSIS-MIB::cmmTransVoltAlertThresholdMax'] / $divisor : null,
'sensor_limit_low' => isset($channel_data['IPI-CMM-CHASSIS-MIB::cmmTransVoltCriticalThresholdMin']) ? $channel_data['IPI-CMM-CHASSIS-MIB::cmmTransVoltCriticalThresholdMin'] / $divisor : null,
'sensor_limit_low_warn' => isset($channel_data['IPI-CMM-CHASSIS-MIB::cmmTransVoltAlertThresholdMin']) ? $channel_data['IPI-CMM-CHASSIS-MIB::cmmTransVoltAlertThresholdMin'] / $divisor : null,
'sensor_current' => isset($channel_data['IPI-CMM-CHASSIS-MIB::cmmTransVoltage']) ? $channel_data['IPI-CMM-CHASSIS-MIB::cmmTransVoltage'] / $divisor : null,
'entPhysicalIndex' => $cmmStackUnitIndex * 10000 + $cmmTransIndex,
'entPhysicalIndex_measured' => 'port',
'user_func' => null,
'group' => 'transceiver',
]));
continue 2; // common across channels
}
}
}
}
}

View File

@@ -0,0 +1,32 @@
<?php
/*
* transceivers.inc.php
*
* -Description-
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package LibreNMS
* @link http://librenms.org
* @copyright 2024 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
use LibreNMS\OS;
if (! isset($os) || ! $os instanceof OS) {
$os = OS::make($device);
}
(new \LibreNMS\Modules\Transceivers())->discover($os);

View File

@@ -1129,6 +1129,17 @@ function get_network_ip_addresses(Illuminate\Http\Request $request)
return api_success(array_merge($ipv4, $ipv6), 'addresses');
}
function get_port_transceiver(Illuminate\Http\Request $request)
{
$port_id = $request->route('portid');
return check_port_permission($port_id, null, function ($port_id) {
$transceivers = Port::find($port_id)->transceivers()->get();
return api_success($transceivers, 'transceivers');
});
}
function get_port_info(Illuminate\Http\Request $request)
{
$port_id = $request->route('portid');
@@ -2710,6 +2721,23 @@ function get_fdb(Illuminate\Http\Request $request)
});
}
function get_transceivers(Illuminate\Http\Request $request)
{
$hostname = $request->route('hostname');
if (empty($hostname)) {
return api_error(500, 'No hostname has been provided');
}
$device = DeviceCache::get($hostname);
if (! $device) {
return api_error(404, "Device $hostname not found");
}
return api_success($device->transceivers()->hasAccess($request->user())->get(), 'transceivers');
}
function list_fdb(Illuminate\Http\Request $request)
{
$mac = $request->route('mac');

View File

@@ -25,7 +25,7 @@ if ($width > '500') {
$rrd_options .= " COMMENT:'" . substr(str_pad($unit_text, $descr_len + 10), 0, $descr_len + 10) . "Now Min Max Avg\l'";
}
foreach ($rrd_list as $rrd) {
foreach ($rrd_list as $i => $rrd) {
if ($rrd['colour']) {
$colour = $rrd['colour'];
} else {

View File

@@ -0,0 +1,7 @@
<?php
$metric_type = 'bias';
$scale_max = 100;
$scale_min = 0;
include 'transceiver.inc.php';

View File

@@ -0,0 +1,7 @@
<?php
$metric_type = 'power-rx';
$scale_max = 0;
$scale_min = -60;
include 'transceiver.inc.php';

View File

@@ -0,0 +1,7 @@
<?php
$metric_type = 'power-tx';
$scale_max = 0;
$scale_min = -60;
include 'transceiver.inc.php';

View File

@@ -0,0 +1,7 @@
<?php
$metric_type = 'temperature';
$scale_min = -40;
$scale_max = 85;
include 'transceiver.inc.php';

View File

@@ -0,0 +1,7 @@
<?php
$metric_type = 'voltage';
$scale_min = 3;
$scale_max = 4;
include 'transceiver.inc.php';

View File

@@ -25,6 +25,7 @@ foreach (PluginManager::call(DeviceOverviewHook::class, ['device' => DeviceCache
}
require 'overview/ports.inc.php';
require 'overview/transceivers.inc.php';
if ($device['os'] == 'ping') {
require 'overview/ping.inc.php';

View File

@@ -1,8 +1,8 @@
<?php
$sensors = dbFetchRows('SELECT * FROM `sensors` WHERE `sensor_class` = ? AND device_id = ? ORDER BY `group`, `sensor_descr`, `sensor_oid`, `sensor_index`', [$sensor_class, $device['device_id']]);
$sensors = DeviceCache::getPrimary()->sensors->where('sensor_class', $sensor_class)->where('group', '!=', 'transceiver'); // cache all sensors on device and exclude transceivers
if (count($sensors)) {
if ($sensors->isNotEmpty()) {
$icons = \App\Models\Sensor::getIconMap();
$sensor_fa_icon = 'fa-' . (isset($icons[$sensor_class]) ? $icons[$sensor_class] : 'delicious');
@@ -16,12 +16,12 @@ if (count($sensors)) {
<table class="table table-hover table-condensed table-striped">';
$group = '';
foreach ($sensors as $sensor) {
if (! isset($sensor['sensor_current'])) {
$sensor['sensor_current'] = 'NaN';
if (! isset($sensor->sensor_current)) {
$sensor->sensor_current = 'NaN';
}
if ($group != $sensor['group']) {
$group = $sensor['group'];
if ($group != $sensor->group) {
$group = $sensor->group;
echo "<tr><td colspan='3'><strong>$group</strong></td></tr>";
}
@@ -32,7 +32,7 @@ if (count($sensors)) {
$graph_array['height'] = '100';
$graph_array['width'] = '210';
$graph_array['to'] = \LibreNMS\Config::get('time.now');
$graph_array['id'] = $sensor['sensor_id'];
$graph_array['id'] = $sensor->sensor_id;
$graph_array['type'] = $graph_type;
$graph_array['from'] = \LibreNMS\Config::get('time.day');
$graph_array['legend'] = 'no';
@@ -42,13 +42,13 @@ if (count($sensors)) {
unset($link_array['height'], $link_array['width'], $link_array['legend']);
$link = \LibreNMS\Util\Url::generate($link_array);
if ($sensor['poller_type'] == 'ipmi') {
$sensor['sensor_descr'] = substr(ipmiSensorName($device['hardware'], $sensor['sensor_descr']), 0, 48);
if ($sensor->poller_type == 'ipmi') {
$sensor->sensor_descr = substr(ipmiSensorName($device['hardware'], $sensor->sensor_descr), 0, 48);
} else {
$sensor['sensor_descr'] = substr($sensor['sensor_descr'], 0, 48);
$sensor->sensor_descr = substr($sensor->sensor_descr, 0, 48);
}
$overlib_content = '<div class=overlib><span class=overlib-text>' . $device['hostname'] . ' - ' . $sensor['sensor_descr'] . '</span><br />';
$overlib_content = '<div class=overlib><span class=overlib-text>' . $device['hostname'] . ' - ' . $sensor->sensor_descr . '</span><br />';
foreach (['day', 'week', 'month', 'year'] as $period) {
$graph_array['from'] = \LibreNMS\Config::get("time.$period");
$overlib_content .= str_replace('"', "\'", \LibreNMS\Util\Url::graphTag($graph_array));
@@ -65,11 +65,11 @@ if (count($sensors)) {
$sensor_current = $graph_type == 'sensor_state' ? get_state_label($sensor) : get_sensor_label_color($sensor);
echo '<tr>
<td class="col-md-4">' . \LibreNMS\Util\Url::overlibLink($link, \LibreNMS\Util\Rewrite::shortenIfType($sensor['sensor_descr']), $overlib_content, $sensor_class) . '</td>
<td class="col-md-4">' . \LibreNMS\Util\Url::overlibLink($link, $sensor_minigraph, $overlib_content, $sensor_class) . '</td>
<td class="col-md-4">' . \LibreNMS\Util\Url::overlibLink($link, $sensor_current, $overlib_content, $sensor_class) . '</td>
</tr>';
echo '<tr><td><div style="display: grid; grid-gap: 10px; grid-template-columns: 3fr 1fr 1fr;">
<div>' . \LibreNMS\Util\Url::overlibLink($link, \LibreNMS\Util\Rewrite::shortenIfType($sensor->sensor_descr), $overlib_content, $sensor_class) . '</div>
<div>' . \LibreNMS\Util\Url::overlibLink($link, $sensor_minigraph, $overlib_content, $sensor_class) . '</div>
<div>' . \LibreNMS\Util\Url::overlibLink($link, $sensor_current, $overlib_content, $sensor_class) . '</div>
</div></td></tr>';
}//end foreach
echo '</table>';

View File

@@ -0,0 +1,46 @@
<?php
/**
* transceivers.inc.php
*
* -Description-
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* @link https://www.librenms.org
*
* @copyright 2024 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
if (DeviceCache::getPrimary()->transceivers->isNotEmpty()) {
DeviceCache::getPrimary()->transceivers->load(['port']);
echo view('device.overview.transceivers', [
'transceivers' => DeviceCache::getPrimary()->transceivers,
'transceivers_link' => route('device', ['device' => DeviceCache::getPrimary()->device_id, 'tab' => 'ports', 'vars' => 'transceivers']),
'sensors' => DeviceCache::getPrimary()->sensors->where('group', 'transceiver'),
// only temp and rx power to reduce information overload, click through to see all
'filterSensors' => function (\App\Models\Sensor $sensor) {
if ($sensor->sensor_class == 'temperature') {
return true;
}
if ($sensor->sensor_class == 'dbm') {
$haystack = strtolower($sensor->sensor_descr);
return str_contains($haystack, 'rx') || str_contains($haystack, 'receive');
}
return false;
},
]);
}

View File

@@ -97,6 +97,10 @@ if ($port->fdbEntries()->exists()) {
$menu_options['events'] = 'Eventlog';
$menu_options['notes'] = (get_dev_attrib($device, 'port_id_notes:' . $port->port_id) ?? '') == '' ? 'Notes' : 'Notes*';
if ($port->transceivers()->exists()) {
$menu_options['transceiver'] = __('port.transceiver');
}
if (dbFetchCell("SELECT COUNT(*) FROM `sensors` WHERE `device_id` = ? AND `entPhysicalIndex` = ? AND entPhysicalIndex_measured = 'ports'", [$device['device_id'], $port->ifIndex])) {
$menu_options['sensors'] = 'Health';
}

View File

@@ -0,0 +1,5 @@
<?php
echo view('device.tabs.ports.transceivers', [
'data' => ['transceivers' => $port->transceivers],
]);

View File

@@ -23,8 +23,39 @@ return [
'arp' => 'ARP Table',
'fdb' => 'FDB Table',
'links' => 'Neighbors',
'transceivers' => 'Transceivers',
'xdsl' => 'xDSL',
],
'transceiver' => 'Transceiver',
'transceivers' => [
'fields' => [
'model' => 'PN: :model',
'serial' => 'SN: :serial',
'revision' => 'Rev: :revision',
'date' => 'Date: :date',
'distance' => 'Distance: :distance',
'encoding' => 'Encoding: :encoding',
'cable' => 'Cable: :cable',
'ddm' => 'DDM: :ddm',
'wavelength' => 'Wavelength: :wavelength',
'connector' => 'Connector: :connector',
'channels' => 'Channels: :channels',
],
'metrics' => [
'power-tx' => 'Tx Power|Channel :channel Tx Power',
'power-rx' => 'Rx Power|Channel :channel Rx Power',
'bias' => 'Bias|Channel :channel Bias',
'temperature' => 'Temperature|Channel :channel Temperature',
'voltage' => 'Voltage|Channel :channel Voltage',
],
'units' => [
'power-tx' => 'dBm',
'power-rx' => 'dBm',
'bias' => 'mA',
'temperature' => '°C',
'voltage' => 'V',
],
],
'unknown_port' => 'Unknown Port',
'vlan_count' => 'VLANs: :count',
'vlan_label' => 'VLAN: :label',

View File

@@ -1,9 +1,9 @@
--===========================================================
-- Copyright (c) 2004-2015 Hangzhou H3C Tech. Co., Ltd. All rights reserved.
-- ===========================================================
-- Copyright (c) 2004-2022 New H3C Tech. Co., Ltd. All rights reserved.
--
-- Description: Transceiver MIB
-- Reference: IF-MIB
-- Version: V1.5
-- Version: V2.3
-- History:
-- V1.0 created by liuhongxu and zoudian.
-- Initial version 2006-01-10
@@ -27,30 +27,100 @@
-- Add hh3cTransceiverChannelTable to transceiver channel statistics.
-- V1.5 2014-08-11 Updated by SongHao
-- Add hh3cTransceiverVendorOUI and hh3cTransceiverRevisionNumber.
--=================================================================
-- V1.6 2015-12-25 Updated by zhouliping
-- Added hh3cTransceiverFrequency and hh3cTransceiverActiveITUChannel to hh3cTransceiverInfoTable.
-- Added hh3cTransceiverITUChanTable for ITU channel information.
-- V1.7 2016-03-09 Updated by zhouliping
-- Added hh3cTransceiverCurWaveErr, hh3cTransceiverWaveErrHiAlarm, hh3cTransceiverWaveErrLoAlarm,
-- hh3cTransceiverCurFreqErr, hh3cTransceiverFreqErrHiAlarm and hh3cTransceiverFreqErrLoAlarm
-- to hh3cTransceiverInfoTable.
-- 2018-01-03 Updated by zhouliping
-- Added hh3cTransceiverChannelBiasHiAm, hh3cTransceiverChannelBiasLoAm,
-- hh3cTransceiverChannelTXPwrHiAm, hh3cTransceiverChannelTXPwrLoAm
-- to hh3cTransceiverChannelTable.
-- V1.8 2019-01-03 Updated by luozelei
-- Added hh3cTransceiverPartNumber and hh3cTransceiverProductCode
-- to hh3cTransceiverInfoTable.
-- V1.9 2019-08-09 Updated by yuhaiyan
-- Added hh3cTransceiverOriginalSN to hh3cTransceiverInfoTable.
-- V2.0 2021-03-18 Updated by hezheng
-- Add the objects of hh3cTransceiverPwrOutHiAlarmDbm, hh3cTransceiverPwrOutLoAlarmDbm,
-- hh3cTransceiverPwrOutHiWarnDbm, hh3cTransceiverPwrOutLoWarnDbm, hh3cTransceiverRcvPwrHiAlarmDbm,
-- hh3cTransceiverRcvPwrLoAlarmDbm, hh3cTransceiverRcvPwrHiWarnDbm, hh3cTransceiverRcvPwrLoWarnDbm.
-- Added hh3cTransceiverChanTXPwrHiAmDbm, hh3cTransceiverChanTXPwrLoAmDbm
-- to hh3cTransceiverChannelTable.
-- V2.1 2021-12-02 Updated by fangliwen
-- Added hh3cTransceiverExtrAlarmEnable and hh3cTransceiverMaybeFake.
-- V2.2 2022-2-22 Updated by liziyi
-- Add the hh3cTransceiverLaneTable.
-- Added hh3cTransceiverLaneCurRxPower、hh3cTransceiverLaneCurTxPower and hh3cTransceiverLaneBiasCurrent
-- to hh3cTransceiverLaneTable.
-- V2.3 2022-05-12 Updated by fangliwen
-- Add hh3cTransceiverRelySlotMfgName and hh3cTransceiverRelySlotMfgDate
-- to hh3cTransceiverInfoTable.
-- =================================================================
HH3C-TRANSCEIVER-INFO-MIB DEFINITIONS ::= BEGIN
IMPORTS
MODULE-IDENTITY, OBJECT-TYPE, Integer32
MODULE-IDENTITY, OBJECT-TYPE, Integer32, Unsigned32, NOTIFICATION-TYPE
FROM SNMPv2-SMI
TruthValue
TruthValue, DateAndTime
FROM SNMPv2-TC
ifIndex
ifIndex, ifName
FROM IF-MIB
hh3cCommon
FROM HH3C-OID-MIB;
hh3cTransceiver MODULE-IDENTITY
LAST-UPDATED "201408111050Z"
LAST-UPDATED "202205120000Z"
ORGANIZATION
"Hangzhou H3C Technologies Co., Ltd."
"New H3C Technologies Co., Ltd."
CONTACT-INFO
"Platform Team Hangzhou H3C Technologies Co., Ltd.
"Platform Team New H3C Technologies Co., Ltd.
Hai-Dian District Beijing P.R. China
http://www.h3c.com
Zip:100085"
DESCRIPTION
"The objects in this MIB module are used to display the
information of transceiver on interface."
REVISION "202205120000Z"
DESCRIPTION
"Add hh3cTransceiverRelySlotMfgName and hh3cTransceiverRelySlotMfgDate
to hh3cTransceiverInfoTable."
REVISION "202202220000Z"
DESCRIPTION
"Add the hh3cTransceiverLaneTable. Added hh3cTransceiverLaneCurRxPower,
hh3cTransceiverLaneCurTxPower and hh3cTransceiverLaneBiasCurrent to hh3cTransceiverLaneTable."
REVISION "202112020000Z"
DESCRIPTION
"Add the objects of hh3cTransceiverExtrAlarmEnable and hh3cTransceiverMaybeFake."
REVISION "202103180000Z"
DESCRIPTION
"Add the objects of hh3cTransceiverPwrOutHiAlarmDbm, hh3cTransceiverPwrOutLoAlarmDbm,
hh3cTransceiverPwrOutHiWarnDbm, hh3cTransceiverPwrOutLoWarnDbm, hh3cTransceiverRcvPwrHiAlarmDbm,
hh3cTransceiverRcvPwrLoAlarmDbm, hh3cTransceiverRcvPwrHiWarnDbm, hh3cTransceiverRcvPwrLoWarnDbm.
Added hh3cTransceiverChanTXPwrHiAmDbm, hh3cTransceiverChanTXPwrLoAmDbm
to hh3cTransceiverChannelTable."
REVISION "201908090000Z"
DESCRIPTION
"Added hh3cTransceiverOriginalSN to hh3cTransceiverInfoTable."
REVISION "201901030000Z"
DESCRIPTION
"Added hh3cTransceiverPartNumber and hh3cTransceiverProductCode
to hh3cTransceiverInfoTable."
REVISION "201801030000Z"
DESCRIPTION
"Added hh3cTransceiverChannelBiasHiAm, hh3cTransceiverChannelBiasLoAm,
hh3cTransceiverChannelTXPwrHiAm, hh3cTransceiverChannelTXPwrLoAm
to hh3cTransceiverChannelTable."
REVISION "201603090000Z"
DESCRIPTION
"Added hh3cTransceiverCurWaveErr, hh3cTransceiverWaveErrHiAlarm, hh3cTransceiverWaveErrLoAlarm,
hh3cTransceiverCurFreqErr, hh3cTransceiverFreqErrHiAlarm and hh3cTransceiverFreqErrLoAlarm
to hh3cTransceiverInfoTable."
REVISION "201512250000Z"
DESCRIPTION
"Added hh3cTransceiverFrequency and hh3cTransceiverActiveITUChannel to hh3cTransceiverInfoTable.
Added hh3cTransceiverITUChanTable for ITU channel information."
REVISION "201408111050Z"
DESCRIPTION
"Add hh3cTransceiverVendorOUI and hh3cTransceiverRevisionNumber."
@@ -141,7 +211,28 @@ IMPORTS
hh3cTransceiverRcvPwrLoWarn Integer32,
hh3cTransceiverErrors BITS,
hh3cTransceiverVendorOUI OCTET STRING,
hh3cTransceiverRevisionNumber OCTET STRING
hh3cTransceiverRevisionNumber OCTET STRING,
hh3cTransceiverFrequency Integer32,
hh3cTransceiverActiveITUChannel Unsigned32,
hh3cTransceiverCurWaveErr Integer32,
hh3cTransceiverWaveErrHiAlarm Integer32,
hh3cTransceiverWaveErrLoAlarm Integer32,
hh3cTransceiverCurFreqErr Integer32,
hh3cTransceiverFreqErrHiAlarm Integer32,
hh3cTransceiverFreqErrLoAlarm Integer32,
hh3cTransceiverPartNumber OCTET STRING,
hh3cTransceiverProductCode OCTET STRING,
hh3cTransceiverOriginalSN OCTET STRING,
hh3cTransceiverPwrOutHiAlarmDbm Integer32,
hh3cTransceiverPwrOutLoAlarmDbm Integer32,
hh3cTransceiverPwrOutHiWarnDbm Integer32,
hh3cTransceiverPwrOutLoWarnDbm Integer32,
hh3cTransceiverRcvPwrHiAlarmDbm Integer32,
hh3cTransceiverRcvPwrLoAlarmDbm Integer32,
hh3cTransceiverRcvPwrHiWarnDbm Integer32,
hh3cTransceiverRcvPwrLoWarnDbm Integer32,
hh3cTransceiverRelySlotMfgName OCTET STRING,
hh3cTransceiverRelySlotMfgDate DateAndTime
}
hh3cTransceiverHardwareType OBJECT-TYPE
@@ -165,7 +256,8 @@ IMPORTS
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Wave length of the interface, measured in nanometer."
"Wave length of the interface, measured in nanometer.
The unit is nm."
::= { hh3cTransceiverInfoEntry 3 }
hh3cTransceiverVendorName OBJECT-TYPE
@@ -226,7 +318,7 @@ IMPORTS
STATUS current
DESCRIPTION
"Indicating the current transmitted power.
The unit is in hundredths of dBM."
The unit is in hundredths of dBm."
::= { hh3cTransceiverInfoEntry 9 }
hh3cTransceiverMaxTXPower OBJECT-TYPE
@@ -235,7 +327,7 @@ IMPORTS
STATUS current
DESCRIPTION
"Indicating the maximum transmitted power.
The unit is in hundredths of dBM."
The unit is in hundredths of dBm."
::= { hh3cTransceiverInfoEntry 10 }
hh3cTransceiverMinTXPower OBJECT-TYPE
@@ -244,7 +336,7 @@ IMPORTS
STATUS current
DESCRIPTION
"Indicating the minimum transmitted power.
The unit is in hundredths of dBM."
The unit is in hundredths of dBm."
::= { hh3cTransceiverInfoEntry 11 }
hh3cTransceiverCurRXPower OBJECT-TYPE
@@ -253,7 +345,7 @@ IMPORTS
STATUS current
DESCRIPTION
"Indicating the current received power.
The unit is in hundredths of dBM."
The unit is in hundredths of dBm."
::= { hh3cTransceiverInfoEntry 12 }
hh3cTransceiverMaxRXPower OBJECT-TYPE
@@ -262,7 +354,7 @@ IMPORTS
STATUS current
DESCRIPTION
"Indicating the maximum received power.
The unit is in hundredths of dBM."
The unit is in hundredths of dBm."
::= { hh3cTransceiverInfoEntry 13 }
hh3cTransceiverMinRXPower OBJECT-TYPE
@@ -271,7 +363,7 @@ IMPORTS
STATUS current
DESCRIPTION
"Indicating the minimum received power.
The unit is in hundredths of dBM."
The unit is in hundredths of dBm."
::= { hh3cTransceiverInfoEntry 14 }
hh3cTransceiverTemperature OBJECT-TYPE
@@ -307,7 +399,7 @@ IMPORTS
STATUS current
DESCRIPTION
"Transceiver temperature high alarm threshold
limit in thousandths of degrees Celsius.
in thousandths of degrees Celsius.
As an example: 49120 is 49.120 degrees Celsius."
::= { hh3cTransceiverInfoEntry 18 }
@@ -317,7 +409,7 @@ IMPORTS
STATUS current
DESCRIPTION
"Transceiver temperature low alarm threshold
limit in thousandths of degrees Celsius.
in thousandths of degrees Celsius.
As an example: 49120 is 49.120 degrees Celsius."
::= { hh3cTransceiverInfoEntry 19 }
@@ -327,7 +419,7 @@ IMPORTS
STATUS current
DESCRIPTION
"Transceiver temperature high warning threshold
limit in thousandths of degrees Celsius.
in thousandths of degrees Celsius.
As an example: 49120 is 49.120 degrees Celsius."
::= { hh3cTransceiverInfoEntry 20 }
@@ -337,7 +429,7 @@ IMPORTS
STATUS current
DESCRIPTION
"Transceiver temperature low warning threshold
limit in thousandths of degrees Celsius.
in thousandths of degrees Celsius.
As an example: 49120 is 49.120 degrees Celsius."
::= { hh3cTransceiverInfoEntry 21 }
@@ -347,7 +439,7 @@ IMPORTS
STATUS current
DESCRIPTION
"Transceiver VCC high alarm threshold
limit in hundreds of microvolts.
in hundreds of microvolts.
As an example: 32928 is 3.2928 volts.
Returns zero if not supported on the transceiver."
::= { hh3cTransceiverInfoEntry 22 }
@@ -358,7 +450,7 @@ IMPORTS
STATUS current
DESCRIPTION
"Transceiver VCC low alarm threshold
limit in hundreds of microvolts.
in hundreds of microvolts.
As an example: 32928 is 3.2928 volts.
Returns zero if not supported on the transceiver."
::= { hh3cTransceiverInfoEntry 23 }
@@ -369,7 +461,7 @@ IMPORTS
STATUS current
DESCRIPTION
"Transceiver VCC high warning threshold
limit in hundreds of microvolts.
in hundreds of microvolts.
As an example: 32928 is 3.2928 volts.
Returns zero if not supported on the transceiver."
::= { hh3cTransceiverInfoEntry 24 }
@@ -380,7 +472,7 @@ IMPORTS
STATUS current
DESCRIPTION
"Transceiver VCC low warning threshold
limit in hundreds of microvolts.
in hundreds of microvolts.
As an example: 32928 is 3.2928 volts.
Returns zero if not supported on the transceiver."
::= { hh3cTransceiverInfoEntry 25 }
@@ -390,7 +482,7 @@ IMPORTS
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Transceiver bias high alarm threshold limit in microamps."
"Transceiver bias high alarm threshold in microamps."
::= { hh3cTransceiverInfoEntry 26 }
hh3cTransceiverBiasLoAlarm OBJECT-TYPE
@@ -398,7 +490,7 @@ IMPORTS
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Transceiver bias low alarm threshold limit in microamps."
"Transceiver bias low alarm threshold in microamps."
::= { hh3cTransceiverInfoEntry 27 }
hh3cTransceiverBiasHiWarn OBJECT-TYPE
@@ -406,7 +498,7 @@ IMPORTS
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Transceiver bias high warning threshold limit in microamps."
"Transceiver bias high warning threshold in microamps."
::= { hh3cTransceiverInfoEntry 28 }
hh3cTransceiverBiasLoWarn OBJECT-TYPE
@@ -414,7 +506,7 @@ IMPORTS
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Transceiver bias low warning threshold limit in microamps."
"Transceiver bias low warning threshold in microamps."
::= { hh3cTransceiverInfoEntry 29 }
hh3cTransceiverPwrOutHiAlarm OBJECT-TYPE
@@ -423,7 +515,7 @@ IMPORTS
STATUS current
DESCRIPTION
"Transceiver transmit power high alarm
threshold limit in tenths of microwatts.
threshold in tenths of microwatts.
As an example: 10000 is 1 milliwatt."
::= { hh3cTransceiverInfoEntry 30 }
@@ -433,7 +525,7 @@ IMPORTS
STATUS current
DESCRIPTION
"Transceiver transmit power low alarm
threshold limit in tenths of microwatts.
threshold in tenths of microwatts.
As an example: 10000 is 1 milliwatt."
::= { hh3cTransceiverInfoEntry 31 }
@@ -443,7 +535,7 @@ IMPORTS
STATUS current
DESCRIPTION
"Transceiver transmit power high warning
threshold limit in tenths of microwatts
threshold in tenths of microwatts
As an example: 10000 is 1 milliwatt."
::= { hh3cTransceiverInfoEntry 32 }
@@ -453,7 +545,7 @@ IMPORTS
STATUS current
DESCRIPTION
"Transceiver transmit power low warning
threshold limit in tenths of microwatts.
threshold in tenths of microwatts.
As an example: 10000 is 1 milliwatt."
::= { hh3cTransceiverInfoEntry 33 }
@@ -463,7 +555,7 @@ IMPORTS
STATUS current
DESCRIPTION
"Transceiver receive power high alarm
threshold limit in tenths of microwatts.
threshold in tenths of microwatts.
As an example: 10000 is 1 milliwatt."
::= { hh3cTransceiverInfoEntry 34 }
@@ -473,7 +565,7 @@ IMPORTS
STATUS current
DESCRIPTION
"Transceiver receive power low alarm
threshold limit in tenths of microwatts.
threshold in tenths of microwatts.
As an example: 10000 is 1 milliwatt."
::= { hh3cTransceiverInfoEntry 35 }
@@ -483,7 +575,7 @@ IMPORTS
STATUS current
DESCRIPTION
"Transceiver receive power high warning
threshold limit in tenths of microwatts.
threshold in tenths of microwatts.
As an example: 10000 is 1 milliwatt."
::= { hh3cTransceiverInfoEntry 36 }
@@ -493,7 +585,7 @@ IMPORTS
STATUS current
DESCRIPTION
"Transceiver receive power low warning
threshold limit in tenths of microwatts.
threshold in tenths of microwatts.
As an example: 10000 is 1 milliwatt."
::= { hh3cTransceiverInfoEntry 37 }
@@ -516,7 +608,10 @@ IMPORTS
pmapmdTransmitterLocalFault(13),
pcsTransmitLocalFault(14),
phyXSTransmitLocalFault(15),
rxLossOfSignal(16)
rxLossOfSignal(16),
tecError(17),
wavelengthUnlocked(18),
txIsNotReadyDueToTuning(19)
}
MAX-ACCESS read-only
STATUS current
@@ -539,7 +634,10 @@ IMPORTS
PCS transmit local fault(14)
PHY XS Transmit Local Fault(15)
RX loss of signal(16)
Unused(17-31)"
TEC error(17)
Wavelength unlocked(18)
Tx is not ready due to tuning(19)
Unused(20-31)"
::= { hh3cTransceiverInfoEntry 38 }
hh3cTransceiverVendorOUI OBJECT-TYPE
@@ -558,6 +656,207 @@ IMPORTS
"Revision number of the interface."
::= { hh3cTransceiverInfoEntry 40 }
hh3cTransceiverFrequency OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The frequency of the current ITU channel on the connected transceiver.
The unit is hundredths of THz."
::= { hh3cTransceiverInfoEntry 41 }
hh3cTransceiverActiveITUChannel OBJECT-TYPE
SYNTAX Unsigned32 (1..4294967295)
MAX-ACCESS read-write
STATUS current
DESCRIPTION
"The index of the current ITU channel on the connected transceiver.
The maximum index number for the ITU channel might vary by transceiver model.
The value of this node depends on the hh3cTransceiverITUChanIdx node of hh3cTransceiverITUChanTable.
The value of this node affects the frequency or wavelength."
::= { hh3cTransceiverInfoEntry 42 }
hh3cTransceiverCurWaveErr OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The current wavelength error of the current ITU channel
on the connected transceiver.
The unit is thousandths of nm."
::= { hh3cTransceiverInfoEntry 43 }
hh3cTransceiverWaveErrHiAlarm OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The high wavelength error alarm threshold of the
current ITU channel on the connected transceiver.
The unit is thousandths of nm."
::= { hh3cTransceiverInfoEntry 44 }
hh3cTransceiverWaveErrLoAlarm OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The low wavelength error alarm threshold of the
current ITU channel on the connected transceiver.
The unit is thousandths of nm."
::= { hh3cTransceiverInfoEntry 45 }
hh3cTransceiverCurFreqErr OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The current frequency error of the current ITU channel
on the connected transceiver.
The unit is tenths of GHz."
::= { hh3cTransceiverInfoEntry 46 }
hh3cTransceiverFreqErrHiAlarm OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The high frequency error alarm threshold of the current
ITU channel on the connected transceiver.
The unit is tenths of GHz."
::= { hh3cTransceiverInfoEntry 47 }
hh3cTransceiverFreqErrLoAlarm OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The low frequency error alarm threshold of the current
ITU channel on the connected transceiver.
The unit is tenths of GHz."
::= { hh3cTransceiverInfoEntry 48 }
hh3cTransceiverPartNumber OBJECT-TYPE
SYNTAX OCTET STRING
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"PartNumber of the interface.
As an example: 1110409083."
::= { hh3cTransceiverInfoEntry 49 }
hh3cTransceiverProductCode OBJECT-TYPE
SYNTAX OCTET STRING
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Product Code of the interface.
As an example: MRC00CD."
::= { hh3cTransceiverInfoEntry 50 }
hh3cTransceiverOriginalSN OBJECT-TYPE
SYNTAX OCTET STRING
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Orginal serial number of the interface."
::= { hh3cTransceiverInfoEntry 51 }
hh3cTransceiverPwrOutHiAlarmDbm OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Transceiver transmit power high alarm
threshold in hundredths of dBm.
As an example: 100 milliwatts is 20 dBms."
::= { hh3cTransceiverInfoEntry 52 }
hh3cTransceiverPwrOutLoAlarmDbm OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Transceiver transmit power low alarm
threshold in hundredths of dBm.
As an example: 100 milliwatts is 20 dBms."
::= { hh3cTransceiverInfoEntry 53 }
hh3cTransceiverPwrOutHiWarnDbm OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Transceiver transmit power high warning
threshold in hundredths of dBm.
As an example: 100 milliwatts is 20 dBms."
::= { hh3cTransceiverInfoEntry 54 }
hh3cTransceiverPwrOutLoWarnDbm OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Transceiver transmit power low warning
threshold in hundredths of dBm.
As an example: 100 milliwatts is 20 dBms."
::= { hh3cTransceiverInfoEntry 55 }
hh3cTransceiverRcvPwrHiAlarmDbm OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Transceiver receive power high alarm
threshold in hundredths of dBm.
As an example: 100 milliwatts is 20 dBms."
::= { hh3cTransceiverInfoEntry 56 }
hh3cTransceiverRcvPwrLoAlarmDbm OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Transceiver receive power low alarm
threshold in hundredths of dBm.
As an example: 100 milliwatts is 20 dBms."
::= { hh3cTransceiverInfoEntry 57 }
hh3cTransceiverRcvPwrHiWarnDbm OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Transceiver receive power high warning
threshold in hundredths of dBm.
As an example: 100 milliwatts is 20 dBms."
::= { hh3cTransceiverInfoEntry 58 }
hh3cTransceiverRcvPwrLoWarnDbm OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Transceiver receive power low warning
threshold in hundredths of dBm.
As an example: 100 milliwatts is 20 dBms."
::= { hh3cTransceiverInfoEntry 59 }
hh3cTransceiverRelySlotMfgName OBJECT-TYPE
SYNTAX OCTET STRING
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Vendor name of the card on which the transceiver is installed."
::= { hh3cTransceiverInfoEntry 60 }
hh3cTransceiverRelySlotMfgDate OBJECT-TYPE
SYNTAX DateAndTime
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Manufacturing date of the card on which the transceiver is installed."
::= { hh3cTransceiverInfoEntry 61 }
-- Transceiver Channel Table
@@ -584,7 +883,13 @@ IMPORTS
hh3cTransceiverChannelCurTXPower Integer32,
hh3cTransceiverChannelCurRXPower Integer32,
hh3cTransceiverChannelTemperature Integer32,
hh3cTransceiverChannelBiasCurrent Integer32
hh3cTransceiverChannelBiasCurrent Integer32,
hh3cTransceiverChannelBiasHiAm Integer32,
hh3cTransceiverChannelBiasLoAm Integer32,
hh3cTransceiverChannelTXPwrHiAm Integer32,
hh3cTransceiverChannelTXPwrLoAm Integer32,
hh3cTransceiverChanTXPwrHiAmDbm Integer32,
hh3cTransceiverChanTXPwrLoAmDbm Integer32
}
hh3cTransceiverChannelIndex OBJECT-TYPE
@@ -602,7 +907,7 @@ IMPORTS
STATUS current
DESCRIPTION
"Indicating the current transmission power.
The unit is in hundredths of dBM."
The unit is in hundredths of dBm."
::= { hh3cTransceiverChannelEntry 2 }
hh3cTransceiverChannelCurRXPower OBJECT-TYPE
@@ -611,7 +916,7 @@ IMPORTS
STATUS current
DESCRIPTION
"Indicating the current received power.
The unit is in hundredths of dBM."
The unit is in hundredths of dBm."
::= { hh3cTransceiverChannelEntry 3 }
hh3cTransceiverChannelTemperature OBJECT-TYPE
@@ -632,4 +937,182 @@ IMPORTS
The unit is in hundredths of mA."
::= { hh3cTransceiverChannelEntry 5 }
hh3cTransceiverChannelBiasHiAm OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Transceiver bias high alarm threshold in microamps."
::= { hh3cTransceiverChannelEntry 6 }
hh3cTransceiverChannelBiasLoAm OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Transceiver bias low alarm threshold in microamps."
::= { hh3cTransceiverChannelEntry 7 }
hh3cTransceiverChannelTXPwrHiAm OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Transceiver transmit power high alarm threshold in tenths of microwatts."
::= { hh3cTransceiverChannelEntry 8 }
hh3cTransceiverChannelTXPwrLoAm OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Transceiver transmit power low alarm threshold in tenths of microwatts."
::= { hh3cTransceiverChannelEntry 9 }
hh3cTransceiverChanTXPwrHiAmDbm OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Transceiver transmit power high alarm threshold in hundredths of dBm."
::= { hh3cTransceiverChannelEntry 10 }
hh3cTransceiverChanTXPwrLoAmDbm OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Transceiver transmit power low alarm threshold in hundredths of dBm."
::= { hh3cTransceiverChannelEntry 11 }
-- Transceiver ITUChannel Table
hh3cTransceiverITUChanTable OBJECT-TYPE
SYNTAX SEQUENCE OF Hh3cTransceiverITUChanEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"This table provides information about ITU channels supported on the transceiver that is connected to this interface."
::= { hh3cTransceiverInfoAdm 3 }
hh3cTransceiverITUChanEntry OBJECT-TYPE
SYNTAX Hh3cTransceiverITUChanEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"The entry of the hh3cTransceiverITUChanTable."
INDEX { ifIndex, hh3cTransceiverITUChanIdx }
::= { hh3cTransceiverITUChanTable 1 }
Hh3cTransceiverITUChanEntry ::=
SEQUENCE {
hh3cTransceiverITUChanIdx Unsigned32,
hh3cTransceiverITUChanFreq Integer32,
hh3cTransceiverITUChanWaveLth Integer32
}
hh3cTransceiverITUChanIdx OBJECT-TYPE
SYNTAX Unsigned32 (1..4294967295)
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"The index of the specified ITU channel on the transceiver that is connected to this interface."
::= { hh3cTransceiverITUChanEntry 1 }
hh3cTransceiverITUChanFreq OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The frequency of the specified ITU channel on the transceiver that is connected to this interface.
The unit is hundredths of THz."
::= { hh3cTransceiverITUChanEntry 2 }
hh3cTransceiverITUChanWaveLth OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The wave length of the specified ITU channel on the transceiver that is connected to this interface.
The unit is pm."
::= { hh3cTransceiverITUChanEntry 3 }
hh3cTransceiverSystemPara OBJECT IDENTIFIER ::= { hh3cTransceiver 2 }
-- ==================================================================
hh3cTransceiverExtrAlarmEnable OBJECT-TYPE
SYNTAX TruthValue
MAX-ACCESS read-write
STATUS current
DESCRIPTION
"Enable alarming upon detection of a third-party transceiver."
DEFVAL { true }
::= { hh3cTransceiverSystemPara 1 }
hh3cTransceiverTrap OBJECT IDENTIFIER ::= { hh3cTransceiver 3 }
hh3cTransceiverTrapPrefix OBJECT IDENTIFIER ::= { hh3cTransceiverTrap 0 }
-- ==================================================================
hh3cTransceiverMaybeFake NOTIFICATION-TYPE
OBJECTS { ifName, hh3cTransceiverType, hh3cTransceiverSerialNumber }
STATUS current
DESCRIPTION
"The transceiver is suspected to be a counterfeit/pirated/unauthorized transceiver."
::= { hh3cTransceiverTrapPrefix 1 }
-- ==================================================================
hh3cTransceiverLaneTable OBJECT-TYPE
SYNTAX SEQUENCE OF Hh3cTransceiverLaneEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"This table provides statistics about transceiver ."
::= { hh3cTransceiverInfoAdm 4 }
hh3cTransceiverLaneEntry OBJECT-TYPE
SYNTAX Hh3cTransceiverLaneEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"The entry of the hh3cTransceiverLaneTable."
INDEX { ifIndex }
::= { hh3cTransceiverLaneTable 1 }
Hh3cTransceiverLaneEntry ::=
SEQUENCE {
hh3cTransceiverLaneCurTxPower OCTET STRING,
hh3cTransceiverLaneCurRxPower OCTET STRING,
hh3cTransceiverLaneBiasCurrent OCTET STRING
}
hh3cTransceiverLaneCurTxPower OBJECT-TYPE
SYNTAX OCTET STRING
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Indicating the current transmitted power.
The unit is in hundredths of dBm."
::= { hh3cTransceiverLaneEntry 1 }
hh3cTransceiverLaneCurRxPower OBJECT-TYPE
SYNTAX OCTET STRING
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Indicating the current received power.
The unit is in hundredths of dBm."
::= { hh3cTransceiverLaneEntry 2 }
hh3cTransceiverLaneBiasCurrent OBJECT-TYPE
SYNTAX OCTET STRING
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Indicating the current bias electric current.
The unit is in hundredths of mA."
::= { hh3cTransceiverLaneEntry 3 }
END

65225
mibs/fs/FS-SIWTCH-V2-MIB Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -663,7 +663,8 @@ JnxOpticsConfigEntry ::=
5 - CFP
6 - CFP+
7 - Non pluggable
8 - QSFP DWDM"
8 - QSFP DWDM
9 - QSFP56DD"
::= { jnxOpticsConfigEntry 5 }

View File

@@ -1391,6 +1391,13 @@
"default": false,
"type": "boolean"
},
"discovery_modules.transceivers": {
"order": 322,
"group": "discovery",
"section": "discovery_modules",
"default": true,
"type": "boolean"
},
"discovery_modules.entity-physical": {
"order": 110,
"group": "discovery",
@@ -5190,6 +5197,13 @@
"default": false,
"type": "boolean"
},
"poller_modules.transceivers": {
"order": 322,
"group": "poller",
"section": "poller_modules",
"default": true,
"type": "boolean"
},
"poller_modules.customoid": {
"default": true,
"type": "boolean"

View File

@@ -536,8 +536,8 @@ custom_maps:
- { Field: created_at, Type: timestamp, 'Null': true, Extra: '' }
- { Field: updated_at, Type: timestamp, 'Null': true, Extra: '' }
- { Field: menu_group, Type: varchar(100), 'Null': true, Extra: '' }
- { Field: background_type, Type: varchar(16), 'Null': false, Extra: '', Default: 'none' }
- { Field: background_data, Type: 'text', 'Null': true, Extra: '' }
- { Field: background_type, Type: varchar(16), 'Null': false, Extra: '', Default: none }
- { Field: background_data, Type: text, 'Null': true, Extra: '' }
Indexes:
PRIMARY: { Name: PRIMARY, Columns: [custom_map_id], Unique: true, Type: BTREE }
custom_map_backgrounds:
@@ -2179,6 +2179,32 @@ tnmsneinfo:
PRIMARY: { Name: PRIMARY, Columns: [id], Unique: true, Type: BTREE }
tnmsneinfo_device_id_index: { Name: tnmsneinfo_device_id_index, Columns: [device_id], Unique: false, Type: BTREE }
tnmsneinfo_neid_index: { Name: tnmsneinfo_neid_index, Columns: [neID], Unique: false, Type: BTREE }
transceivers:
Columns:
- { Field: id, Type: 'bigint unsigned', 'Null': false, Extra: auto_increment }
- { Field: created_at, Type: timestamp, 'Null': true, Extra: '' }
- { Field: updated_at, Type: timestamp, 'Null': true, Extra: '' }
- { Field: device_id, Type: bigint, 'Null': false, Extra: '' }
- { Field: port_id, Type: bigint, 'Null': false, Extra: '' }
- { Field: index, Type: varchar(255), 'Null': false, Extra: '' }
- { Field: entity_physical_index, Type: int, 'Null': true, Extra: '' }
- { Field: type, Type: varchar(128), 'Null': true, Extra: '' }
- { Field: vendor, Type: varchar(16), 'Null': true, Extra: '' }
- { Field: oui, Type: varchar(16), 'Null': true, Extra: '' }
- { Field: model, Type: varchar(32), 'Null': true, Extra: '' }
- { Field: revision, Type: varchar(16), 'Null': true, Extra: '' }
- { Field: serial, Type: varchar(32), 'Null': true, Extra: '' }
- { Field: date, Type: date, 'Null': true, Extra: '' }
- { Field: ddm, Type: tinyint, 'Null': true, Extra: '' }
- { Field: encoding, Type: varchar(16), 'Null': true, Extra: '' }
- { Field: cable, Type: varchar(16), 'Null': true, Extra: '' }
- { Field: distance, Type: int, 'Null': true, Extra: '' }
- { Field: wavelength, Type: int, 'Null': true, Extra: '' }
- { Field: connector, Type: varchar(16), 'Null': true, Extra: '' }
- { Field: channels, Type: smallint, 'Null': false, Extra: '', Default: '1' }
Indexes:
PRIMARY: { Name: PRIMARY, Columns: [id], Unique: true, Type: BTREE }
transceivers_device_id_entity_physical_index_index: { Name: transceivers_device_id_entity_physical_index_index, Columns: [device_id, entity_physical_index], Unique: false, Type: BTREE }
transport_group_transport:
Columns:
- { Field: id, Type: 'bigint unsigned', 'Null': false, Extra: auto_increment }

View File

@@ -1,10 +1,10 @@
<x-panel footer-class="text-center">
<x-panel>
<x-slot name="title">
<img class="logon-logo img-responsive" src="{{ asset(\LibreNMS\Config::get('title_image', 'images/librenms_logo_light.svg')) }}">
</x-slot>
@config('login_message')
<x-slot name="footer">
<x-slot name="footer" class="text-center">
<div class="logon-message">{{ \LibreNMS\Config::get('login_message') }}</div>
</x-slot>
@endconfig

View File

@@ -1,5 +1,5 @@
<x-popup>
<a class="tw-font-bold @if($status=='disabled') tw-text-gray-400 visited:tw-text-gray-400 @elseif($status=='down') tw-text-red-600 visited:tw-text-red-600 @else tw-text-blue-900 visited:tw-text-blue-900 dark:tw-text-dark-white-100 dark:visited:tw-text-dark-white-100 @endif" href="{{ route('device', ['device' => $device->device_id, 'tab' => $tab, 'section' => $section]) }}">
<a class="tw-font-bold @if($status=='disabled') tw-text-gray-400 visited:tw-text-gray-400 @elseif($status=='down') tw-text-red-600 visited:tw-text-red-600 @else tw-text-blue-900 visited:tw-text-blue-900 dark:tw-text-dark-white-100 dark:visited:tw-text-dark-white-100 @endif" href="{{ route('device', ['device' => $device->device_id ?? 1, 'tab' => $tab, 'section' => $section]) }}">
{{ $slot->isNotEmpty() ? $slot : $device->displayName() }}
</a>
<x-slot name="title">

View File

@@ -0,0 +1,11 @@
@aware(['popupTitle'])
<x-popup>
@includeWhen($link, 'components.linked-graph')
@includeUnless($link, 'components.graph')
@if($popupTitle)
<x-slot name="title">{{ $popupTitle }}</x-slot>
@endif
<x-slot name="body">
<x-graph-row loading="lazy" :$type :$vars :$legend></x-graph-row>
</x-slot>
</x-popup>

View File

@@ -3,7 +3,7 @@
{{ $title }}
</div>
@endisset
<div class="tw-flex tw-flex-wrap" @if(! $responsive) style="width: {{ $rowWidth }}px;" @endif {{ $attributes }}>
<div class="tw-flex tw-flex-wrap" @if(! $responsive) style="width: {{ $rowWidth }}px;" @endif {{ $attributes->filter(fn ($value) => ! is_array($value)) }}>
@foreach($graphs as $graph)
<x-graph
:type="$type"
@@ -13,7 +13,7 @@
:device="$device"
:legend="$attributes->get('legend', 'no')"
:height="$attributes->get('height', 150)"
:vars="$graph"
:vars="array_merge($graph, $attributes->get('vars', []))"
{{ $attributes->class(['lg:tw-w-1/4 sm:tw-w-1/2 tw-w-full' => $responsive]) }}></x-graph>
@endforeach
</div>

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" style="line-height:1;height:1em;width:1em;display:inline-block;"><path style="fill:currentColor" d="m49.74.22-5.42 5.42-1.1-1.11a4.47 4.47 0 0 0-6.26 0L1.54 39.94a4.47 4.47 0 0 0 0 6.26l16.34 16.33a4.47 4.47 0 0 0 6.25 0l35.41-35.41a4.47 4.47 0 0 0 0-6.26l-1.1-1.11 5.41-5.42zM40.08 8.6 55.48 24 21 58.47l-1.98-1.98 2.62-2.62-3.91-3.9-2.62 2.61-3.62-3.62 2.62-2.62-3.9-3.9-2.62 2.62-1.98-1.99z"/><path style="stroke:currentColor;stroke-width:3.50264;stroke-linecap:round" d="m40.26 17.46-1.69 1.68M46.62 23.82l-1.69 1.68"/></svg>

After

Width:  |  Height:  |  Size: 590 B

View File

@@ -1,12 +1,10 @@
@props([
'id',
'label' => null,
'value' => null,
'type' => 'text',
])
<label for="{{ $id }}" class="tw-block tw-mb-1 tw-mt-2 tw-font-medium tw-text-gray-900 dark:tw-text-white">{{ $label }}</label>
@if($label)<label for="{{ $id }}" class="tw-block tw-mb-1 tw-mt-2 tw-font-medium tw-text-gray-900 dark:tw-text-white">{{ $label }}</label>@endif
<input type="{{ $type }}"
id="{{ $id }}"
{{ $attributes->merge(['class' => 'tw-mb-2 tw-bg-gray-50 tw-border tw-border-gray-300 tw-text-gray-900 tw-rounded-lg focus:tw-ring-blue-500 focus:tw-border-blue-500 tw-block tw-w-full tw-p-2.5 dark:tw-bg-gray-700 dark:tw-border-gray-600 dark:tw-placeholder-gray-400 dark:tw-text-white dark:tw-focus:ring-blue-500 dark:tw-focus:border-blue-500']) }}
/>
{{ $attributes->merge(['id' => $id, 'class' => 'tw-mb-2 tw-bg-gray-50 tw-border tw-border-gray-300 tw-text-gray-900 tw-rounded-lg tw-block tw-w-full tw-p-2.5 dark:tw-bg-gray-700 dark:tw-border-gray-600 dark:tw-placeholder-gray-400 dark:tw-text-white dark:tw-focus:border-blue-500']) }}
>

View File

@@ -0,0 +1,6 @@
<span {{ $attributes->class(['label', $statusClass]) }}>
{{ $slot }}
@isset($badge)
<span {{ $badge->attributes->class('badge') }}>{{ $badge }}</span>
@endisset
</span>

View File

@@ -1 +1 @@
<a href="{{ $link }}" {{ $attributes->filter($filterAttributes) }}><img width="{{ $width }}" height="{{ $height }}" src="{{ $src }}" alt="{{ $type }}" class="graph-image" {{ $attributes->only('loading') }}></a>
<a href="{{ $link }}" {{ $attributes->filter($filterAttributes) }}>@include('components.graph')</a>

View File

@@ -1,6 +1,6 @@
<div {{ $attributes->merge(['class' => 'panel panel-default']) }}>
@if (isset($heading))
<div class="panel-heading">
<div {{ $heading->attributes->class('panel-heading') }}>
{{ $heading }}
</div>
@elseif (isset($title))
@@ -20,7 +20,7 @@
@endisset
@isset($footer)
<div class="panel-footer {{ $footer_class }}">
<div {{ $footer->attributes->class('panel-footer') }}>
{{ $footer }}
</div>
@endisset

View File

@@ -1,39 +1,13 @@
<div {{ $attributes->merge(['class' => 'tw-inline-block']) }} x-data="{
popupShow: false,
showTimeout: null,
hideTimeout: null,
ignoreNextShownEvent: false,
delay: 300,
show(timeout) {
clearTimeout(this.hideTimeout);
this.showTimeout = setTimeout(() => {
this.popupShow = true;
Popper.createPopper(this.$refs.targetRef, this.$refs.popupRef, {
padding: 8
});
// close other popups, except this one
this.ignoreNextShownEvent = true;
this.$dispatch('librenms-popup-shown', this.$el);
}, timeout);
},
hide(timeout) {
if (this.ignoreNextShownEvent) {
this.ignoreNextShownEvent = false;
return;
}
clearTimeout(this.showTimeout);
this.hideTimeout = setTimeout(() => this.popupShow = false, timeout)
}
}"
<div {{ $attributes->merge(['class' => 'tw-inline-block']) }}
x-data="popup"
x-on:click.away="hide(0)"
x-on:librenms-popup-shown.window="() => hide(0)"
>
<div class="tw-inline-block" x-ref="targetRef" x-on:mouseenter='show(100)' x-on:mouseleave="hide(delay)">
<span x-ref="targetRef" x-on:mouseenter='show(100)' x-on:mouseleave="hide(delay)">
{{ $slot }}
</div>
<div x-ref="popupRef"
</span>
<div x-cloak
x-ref="popupRef"
x-on:mouseenter="clearTimeout(hideTimeout)"
x-on:mouseleave="hide(delay)"
x-bind:class="{'tw-hidden': !popupShow, 'tw-block': popupShow}"
@@ -46,9 +20,44 @@
</div>
@endisset
@isset($body)
<div class="tw-p-3">
<div {{ $body->attributes->class(['tw-p-3' => $body->attributes->isEmpty()]) }}>
{{ $body }}
</div>
@endisset
</div>
</div>
@once
<script>
document.addEventListener("alpine:init", () => {
Alpine.data("popup", () => ({
popupShow: false,
showTimeout: null,
hideTimeout: null,
ignoreNextShownEvent: false,
delay: 300,
show(timeout) {
clearTimeout(this.hideTimeout);
this.showTimeout = setTimeout(() => {
this.popupShow = true;
Popper.createPopper(this.$refs.targetRef, this.$refs.popupRef, {
padding: 8
});
// close other popups, except this one
this.ignoreNextShownEvent = true;
this.$dispatch('librenms-popup-shown', this.$el);
}, timeout);
},
hide(timeout) {
if (this.ignoreNextShownEvent) {
this.ignoreNextShownEvent = false;
return;
}
clearTimeout(this.showTimeout);
this.hideTimeout = setTimeout(() => this.popupShow = false, timeout)
}
}));
});
</script>
@endonce

View File

@@ -1,4 +1,4 @@
<x-popup>
<x-popup {{ $attributes }}>
@include('components.port-link_basic')
<x-slot name="title">
<div class="tw-text-xl tw-font-bold">{{ $port->device?->displayName() }} - {{ $label }}</div>

View File

@@ -0,0 +1,29 @@
@props(['transceiver'])
@foreach($groupedSensors as $class => $sensors)
@if($loop->first)
<div {{ $attributes->merge(['class' => 'tw-grid tw-grid-cols-[min-content_min-content_1fr] tw-gap-x-4']) }}>
@endif
@foreach($sensors as $sensor)
<div class="tw-whitespace-nowrap tw-text-right">
{{ $sensor->sensor_descr }}
</div>
<div>
<x-label :status="$sensor->currentStatus()">{{ $sensor->formatValue() }}</x-label>
</div>
<div style="height: 26px;">
<x-popup>
<div class="tw-border-2">
<x-graph :type="'sensor_' . $class" :vars="['id' => $sensor->sensor_id]" legend="yes" width="100" height="20"></x-graph>
</div>
<x-slot name="title">{{ $transceiver->port?->getLabel() }}</x-slot>
<x-slot name="body">
<x-graph-row loading="lazy" :type="'sensor_' . $class" :vars="['id' => $sensor->sensor_id]" legend="yes"></x-graph-row>
</x-slot>
</x-popup>
</div>
@endforeach
@if($loop->last)
</div>
@endif
@endforeach

View File

@@ -0,0 +1,20 @@
@props(['transceiver', 'portlink' => true])
<div class="tw-flex sm:tw-flex-row tw-flex-col" {{ $attributes }}>
<div class="tw-pr-8">
@if($portlink && $transceiver->port)<x-port-link :port="$transceiver->port"></x-port-link>@endif
@if($transceiver->vendor || $transceiver->type)<p class="tw-text-2xl tw-font-bold">{{ $transceiver->vendor }} {{ $transceiver->type }}</p>@endif
@if($transceiver->model)<p>{{ __('port.transceivers.fields.model', $transceiver->only('model')) }}</p>@endif
@if($transceiver->serial)<p>{{ __('port.transceivers.fields.serial', $transceiver->only('serial')) }}</p>@endif
<p>@if($transceiver->revision){{ __('port.transceivers.fields.revision', $transceiver->only('revision')) }}@endif @if($transceiver->date){{ __('port.transceivers.fields.date', $transceiver->only('date')) }}@endif</p>
@if($transceiver->ddm !== null){{ __('port.transceivers.fields.ddm', ['ddm' => $transceiver->ddm ? __('Yes') : __('No')]) }}@endif
</div>
<div>
@if($transceiver->cable)<p>{{ __('port.transceivers.fields.cable', $transceiver->only('cable')) }}</p>@endif
@if($transceiver->distance)<p>{{ __('port.transceivers.fields.distance', ['distance' => \LibreNMS\Util\Number::formatSi($transceiver->distance, suffix: 'm')]) }}</p>@endif
@if($transceiver->wavelength)<p>{{ __('port.transceivers.fields.wavelength', ['wavelength' => $transceiver->wavelength . 'nm']) }}</p>@endif
@if($transceiver->encoding)<p>{{ __('port.transceivers.fields.encoding', $transceiver->only('encoding')) }}</p>@endif
@if($transceiver->connector)<p>{{ __('port.transceivers.fields.connector', $transceiver->only('connector')) }}</p>@endif
@if($transceiver->channels > 1)<p>{{ __('port.transceivers.fields.channels', $transceiver->only('channels')) }}</p>@endif
</div>
</div>

View File

@@ -10,8 +10,10 @@
@foreach($tabs as $tab)
@if($tab->visible($device))
<li role="presentation" @if( $current_tab == $tab->slug() ) class="active" @endif>
<a href="{{ route('device', [$device_id, $tab->slug()]) }}">
<i class="fa {{ $tab->icon() }} fa-lg icon-theme" aria-hidden="true"></i>&nbsp;{{ $tab->name() }}&nbsp;</a>
<a href="{{ route('device', [$device_id, $tab->slug()]) }}" class="tw-whitespace-nowrap">
<i class="fa {{ $tab->icon() }} fa-lg icon-theme" aria-hidden="true"></i>
{{ $tab->name() }}
</a>
</li>
@endif
@endforeach

View File

@@ -0,0 +1,36 @@
<div class="row">
<div class="col-md-12">
<x-panel class="device-overview panel-condensed">
<x-slot name="heading" class="tw-mb-6">
<x-icons.transceiver></x-icons.transceiver>
<strong><a href="{{ $transceivers_link }}">{{ __('port.tabs.transceivers') }}</a></strong>
</x-slot>
@foreach($transceivers as $transceiver)
<x-panel body-class="!tw-p-0">
<x-slot name="heading">
@if($transceiver->port)
<x-port-link :port="$transceiver->port"></x-port-link>
@endif
<x-icons.transceiver></x-icons.transceiver> {{ $transceiver->vendor }} {{ $transceiver->type }}
</x-slot>
<table class="table table-hover table-condensed table-striped !tw-mb-0">
@foreach($sensors as $sensor)
@if($sensor->entPhysicalIndex !== null && $sensor->entPhysicalIndex == $transceiver->entity_physical_index && $filterSensors($sensor))
<tr>
<td>
<div style="display: grid; grid-gap: 10px; grid-template-columns: 3fr 1fr 1fr;">
<div>{{ $sensor->sensor_descr }}</div>
<div><x-graph loading="lazy" popup="true" :popup-title="DeviceCache::getPrimary()->displayName() . ' - ' . $sensor->sensor_descr" type="sensor_{{ $sensor->sensor_class }}" width="100" height="24" :vars="['id' => $sensor->sensor_id]"></x-graph></div>
<div><x-label :status="$sensor->currentStatus()">{{ $sensor->formatValue() }}</x-label></div>
</div>
</td>
</tr>
@endif
@endforeach
</table>
</x-panel>
@endforeach
</x-panel>
</div>
</div>

View File

@@ -1,8 +1,30 @@
<tr>
<td>
<x-port-link :port="$port">
<span class="tw-text-3xl tw-font-bold"><i class="fa fa-tag" aria-hidden='true'></i> {{ $port->getLabel() }}</span>
</x-port-link>
<div>
<x-port-link :port="$port" class="tw-inline">
<span class="tw-text-3xl tw-font-bold"><i class="fa fa-tag" aria-hidden='true'></i> {{ $port->getLabel() }}</span>
</x-port-link>
@if($data['tab'] != 'basic')
@foreach($port->transceivers as $transceiver)
@php
$transceiver->setRelation('port', $port); // save a query
@endphp
<x-popup>
<a href="{{ \LibreNMS\Util\Url::generate(['page' => 'device', 'device' => $port->device_id, 'tab' => 'port','port' => $port->port_id], ['view' => 'transceiver']) }}" class="tw-text-current">
<span class="tw-ml-3 tw-text-3xl"><x-icons.transceiver/></span>
</a>
<x-slot name="body" class="tw-p-0">
@if(array_filter($transceiver->only(['type', 'vendor', 'model', 'revision', 'serial', 'data', 'ddm', 'encoding', 'cable', 'distance', 'wavelength', 'connector'])))
<div class="tw-opacity-90 tw-p-4 tw-border-b-2 tw-border-solid tw-border-gray-200 dark:tw-border-dark-gray-200 tw-rounded-t-lg">
<x-transceiver :transceiver="$transceiver" :portlink="false"></x-transceiver>
</div>
@endif
<x-transceiver-sensors :transceiver="$transceiver" class="tw-p-3"></x-transceiver-sensors>
</x-slot>
</x-popup>
@endforeach
@endif
</div>
<div>
@if($port->ifInErrors_delta > 0 || $port->ifOutErrors_delta > 0)
<a href="{{ route('device', ['device' => $port->device_id, 'tab' => 'port', 'vars' => 'port=' . $port->port_id]) }}"><i class="fa fa-flag fa-lg tw-text-red-600"></i></a>

View File

@@ -0,0 +1,8 @@
@foreach($data['transceivers'] as $transceiver)
<x-panel>
<x-slot name="heading">
<x-transceiver :transceiver="$transceiver"></x-transceiver>
</x-slot>
<x-transceiver-sensors :transceiver="$transceiver"></x-transceiver-sensors>
</x-panel>
@endforeach

View File

@@ -0,0 +1,6 @@
<x-panel>
<x-slot name="heading">
<x-transceiver :transceiver="$transceiver"></x-transceiver>
</x-slot>
<x-transceiver-sensors :transceiver="$transceiver"></x-transceiver-sensors>
</x-panel>

View File

@@ -121,6 +121,7 @@ Route::prefix('v0')->namespace('\App\Api\Controllers')->group(function () {
Route::get('{hostname}/ports', 'LegacyApiController@get_port_graphs')->name('get_port_graphs');
Route::get('{hostname}/ip', 'LegacyApiController@get_device_ip_addresses')->name('get_ip_addresses');
Route::get('{hostname}/port_stack', 'LegacyApiController@get_port_stack')->name('get_port_stack');
Route::get('{hostname}/transceivers', 'LegacyApiController@get_transceivers')->name('get_transceivers');
Route::get('{hostname}/components', 'LegacyApiController@get_components')->name('get_components');
Route::get('{hostname}/groups', 'LegacyApiController@get_device_groups')->name('get_device_groups_device');
Route::get('{hostname}/maintenance', 'LegacyApiController@device_under_maintenance')->name('device_under_maintenance');
@@ -136,6 +137,8 @@ Route::prefix('v0')->namespace('\App\Api\Controllers')->group(function () {
Route::prefix('ports')->group(function () {
Route::get('{portid}', 'LegacyApiController@get_port_info')->name('get_port_info');
Route::get('{portid}/ip', 'LegacyApiController@get_port_ip_addresses')->name('get_port_ip_info');
Route::get('{portid}/transceiver', 'LegacyApiController@get_port_transceiver')->name('get_port_transceiver');
Route::patch('transceiver/metric/{metric}', 'LegacyApiController@update_transceiver_metric_thresholds')->name('update_transceiver_metric_thresholds');
Route::get('search/{field}/{search?}', 'LegacyApiController@search_ports')->name('search_ports')->where('search', '.*');
Route::get('mac/{search}', 'LegacyApiController@search_by_mac')->name('search_mac');
Route::get('', 'LegacyApiController@get_all_ports')->name('get_all_ports');

View File

@@ -25,6 +25,9 @@ module.exports = {
},
borderWidth: {
'0.5': '0.5px',
},
boxShadow: {
'inner-glow': 'inset 0 0 11px rgba(0, 0, 0, 0.1)',
}
},
screens: {

View File

@@ -23318,8 +23318,8 @@
"ifName": "M-GigabitEthernet0/0/0",
"portName": null,
"ifIndex": 1,
"ifSpeed": 0,
"ifSpeed_prev": null,
"ifSpeed": null,
"ifSpeed_prev": 0,
"ifConnectorPresent": "true",
"ifOperStatus": "down",
"ifOperStatus_prev": "down",
@@ -23418,8 +23418,8 @@
"ifName": "NULL0",
"portName": null,
"ifIndex": 2,
"ifSpeed": 0,
"ifSpeed_prev": null,
"ifSpeed": null,
"ifSpeed_prev": 0,
"ifConnectorPresent": "false",
"ifOperStatus": "up",
"ifOperStatus_prev": "up",
@@ -23518,8 +23518,8 @@
"ifName": "Vlan-interface1",
"portName": null,
"ifIndex": 3,
"ifSpeed": 0,
"ifSpeed_prev": null,
"ifSpeed": null,
"ifSpeed_prev": 0,
"ifConnectorPresent": "false",
"ifOperStatus": "up",
"ifOperStatus_prev": "up",
@@ -44518,8 +44518,8 @@
"ifName": "LoopBack0",
"portName": null,
"ifIndex": 214,
"ifSpeed": 0,
"ifSpeed_prev": null,
"ifSpeed": null,
"ifSpeed_prev": 0,
"ifConnectorPresent": "false",
"ifOperStatus": "up",
"ifOperStatus_prev": "up",
@@ -44618,8 +44618,8 @@
"ifName": "Vlan-interface500",
"portName": null,
"ifIndex": 221,
"ifSpeed": 0,
"ifSpeed_prev": null,
"ifSpeed": null,
"ifSpeed_prev": 0,
"ifConnectorPresent": "false",
"ifOperStatus": "up",
"ifOperStatus_prev": "up",
@@ -44718,8 +44718,8 @@
"ifName": "Route-Aggregation13",
"portName": null,
"ifIndex": 222,
"ifSpeed": 0,
"ifSpeed_prev": null,
"ifSpeed": null,
"ifSpeed_prev": 0,
"ifConnectorPresent": "false",
"ifOperStatus": "down",
"ifOperStatus_prev": "down",
@@ -46018,8 +46018,8 @@
"ifName": "Vlan-interface27",
"portName": null,
"ifIndex": 236,
"ifSpeed": 0,
"ifSpeed_prev": null,
"ifSpeed": null,
"ifSpeed_prev": 0,
"ifConnectorPresent": "false",
"ifOperStatus": "down",
"ifOperStatus_prev": "down",
@@ -46118,8 +46118,8 @@
"ifName": "Vlan-interface100",
"portName": null,
"ifIndex": 237,
"ifSpeed": 0,
"ifSpeed_prev": null,
"ifSpeed": null,
"ifSpeed_prev": 0,
"ifConnectorPresent": "false",
"ifOperStatus": "down",
"ifOperStatus_prev": "down",
@@ -46318,8 +46318,8 @@
"ifName": "Vlan-interface501",
"portName": null,
"ifIndex": 257,
"ifSpeed": 0,
"ifSpeed_prev": null,
"ifSpeed": null,
"ifSpeed_prev": 0,
"ifConnectorPresent": "false",
"ifOperStatus": "up",
"ifOperStatus_prev": "up",
@@ -46418,8 +46418,8 @@
"ifName": "Vlan-interface505",
"portName": null,
"ifIndex": 258,
"ifSpeed": 0,
"ifSpeed_prev": null,
"ifSpeed": null,
"ifSpeed_prev": 0,
"ifConnectorPresent": "false",
"ifOperStatus": "up",
"ifOperStatus_prev": "up",
@@ -57540,5 +57540,524 @@
]
},
"poller": "matches discovery"
},
"transceivers": {
"discovery": {
"transceivers": [
{
"index": "13",
"entity_physical_index": 13,
"type": "1000_BASE_LX_SFP",
"vendor": "HP",
"oui": null,
"model": null,
"revision": null,
"serial": "CN2AFSQ331",
"date": null,
"ddm": 1,
"encoding": null,
"cable": "SM",
"distance": 10000,
"wavelength": 1310,
"connector": null,
"channels": 1,
"ifIndex": 13
},
{
"index": "14",
"entity_physical_index": 14,
"type": "1000_BASE_LX_SFP",
"vendor": "HP",
"oui": null,
"model": null,
"revision": null,
"serial": "CN2AFSQ3RC",
"date": null,
"ddm": 1,
"encoding": null,
"cable": "SM",
"distance": 10000,
"wavelength": 1310,
"connector": null,
"channels": 1,
"ifIndex": 14
},
{
"index": "15",
"entity_physical_index": 15,
"type": "1000_BASE_LX_SFP",
"vendor": "HP",
"oui": null,
"model": null,
"revision": null,
"serial": "CN2AFSQ3Q6",
"date": null,
"ddm": 1,
"encoding": null,
"cable": "SM",
"distance": 10000,
"wavelength": 1310,
"connector": null,
"channels": 1,
"ifIndex": 15
},
{
"index": "17",
"entity_physical_index": 17,
"type": "1000_BASE_LX_SFP",
"vendor": "HP",
"oui": null,
"model": null,
"revision": null,
"serial": "CN2AFSQ0HR",
"date": null,
"ddm": 1,
"encoding": null,
"cable": "SM",
"distance": 10000,
"wavelength": 1310,
"connector": null,
"channels": 1,
"ifIndex": 17
},
{
"index": "18",
"entity_physical_index": 18,
"type": "1000_BASE_LX_SFP",
"vendor": "HP",
"oui": null,
"model": null,
"revision": null,
"serial": "CN29FSQ5V0",
"date": null,
"ddm": 1,
"encoding": null,
"cable": "SM",
"distance": 10000,
"wavelength": 1310,
"connector": null,
"channels": 1,
"ifIndex": 18
},
{
"index": "19",
"entity_physical_index": 19,
"type": "1000_BASE_LX_SFP",
"vendor": "FINISAR CORP.",
"oui": null,
"model": null,
"revision": null,
"serial": "",
"date": null,
"ddm": 0,
"encoding": null,
"cable": "SM",
"distance": 4000,
"wavelength": 1310,
"connector": null,
"channels": 1,
"ifIndex": 19
},
{
"index": "20",
"entity_physical_index": 20,
"type": "1000_BASE_LX_SFP",
"vendor": "HP",
"oui": null,
"model": null,
"revision": null,
"serial": "CN2AFSQ0HW",
"date": null,
"ddm": 1,
"encoding": null,
"cable": "SM",
"distance": 10000,
"wavelength": 1310,
"connector": null,
"channels": 1,
"ifIndex": 20
},
{
"index": "21",
"entity_physical_index": 21,
"type": "1000_BASE_LX_SFP",
"vendor": "HP",
"oui": null,
"model": null,
"revision": null,
"serial": "CN29FSQ5Z6",
"date": null,
"ddm": 1,
"encoding": null,
"cable": "SM",
"distance": 10000,
"wavelength": 1310,
"connector": null,
"channels": 1,
"ifIndex": 21
},
{
"index": "22",
"entity_physical_index": 22,
"type": "1000_BASE_LX_SFP",
"vendor": "HP",
"oui": null,
"model": null,
"revision": null,
"serial": "CN2AFSQ47M",
"date": null,
"ddm": 1,
"encoding": null,
"cable": "SM",
"distance": 10000,
"wavelength": 1310,
"connector": null,
"channels": 1,
"ifIndex": 22
},
{
"index": "23",
"entity_physical_index": 23,
"type": "1000_BASE_LX_SFP",
"vendor": "HP",
"oui": null,
"model": null,
"revision": null,
"serial": "CN2AFSQ3NW",
"date": null,
"ddm": 1,
"encoding": null,
"cable": "SM",
"distance": 10000,
"wavelength": 1310,
"connector": null,
"channels": 1,
"ifIndex": 23
},
{
"index": "24",
"entity_physical_index": 24,
"type": "1000_BASE_LX_SFP",
"vendor": "HP",
"oui": null,
"model": null,
"revision": null,
"serial": "CN2AFSQ3KX",
"date": null,
"ddm": 1,
"encoding": null,
"cable": "SM",
"distance": 10000,
"wavelength": 1310,
"connector": null,
"channels": 1,
"ifIndex": 24
},
{
"index": "27",
"entity_physical_index": 27,
"type": "1000_BASE_LX_SFP",
"vendor": "FINISAR CORP.",
"oui": null,
"model": null,
"revision": null,
"serial": "",
"date": null,
"ddm": 0,
"encoding": null,
"cable": "SM",
"distance": 4000,
"wavelength": 1310,
"connector": null,
"channels": 1,
"ifIndex": 27
},
{
"index": "42",
"entity_physical_index": 42,
"type": "1000_BASE_LX_SFP",
"vendor": "HP",
"oui": null,
"model": null,
"revision": null,
"serial": "CN2AFSQ3KZ",
"date": null,
"ddm": 1,
"encoding": null,
"cable": "SM",
"distance": 10000,
"wavelength": 1310,
"connector": null,
"channels": 1,
"ifIndex": 42
},
{
"index": "44",
"entity_physical_index": 44,
"type": "1000_BASE_LX_SFP",
"vendor": "FINISAR CORP.",
"oui": null,
"model": null,
"revision": null,
"serial": "",
"date": null,
"ddm": 0,
"encoding": null,
"cable": "SM",
"distance": 4000,
"wavelength": 1310,
"connector": null,
"channels": 1,
"ifIndex": 44
},
{
"index": "45",
"entity_physical_index": 45,
"type": "1000_BASE_LX_SFP",
"vendor": "HP",
"oui": null,
"model": null,
"revision": null,
"serial": "CN2AFSQ11J",
"date": null,
"ddm": 1,
"encoding": null,
"cable": "SM",
"distance": 10000,
"wavelength": 1310,
"connector": null,
"channels": 1,
"ifIndex": 45
},
{
"index": "46",
"entity_physical_index": 46,
"type": "1000_BASE_LX_SFP",
"vendor": "HP",
"oui": null,
"model": null,
"revision": null,
"serial": "CN2AFSQ05Y",
"date": null,
"ddm": 1,
"encoding": null,
"cable": "SM",
"distance": 10000,
"wavelength": 1310,
"connector": null,
"channels": 1,
"ifIndex": 46
},
{
"index": "47",
"entity_physical_index": 47,
"type": "1000_BASE_LX_SFP",
"vendor": "HP",
"oui": null,
"model": null,
"revision": null,
"serial": "CN2AFSQ0HS",
"date": null,
"ddm": 1,
"encoding": null,
"cable": "SM",
"distance": 10000,
"wavelength": 1310,
"connector": null,
"channels": 1,
"ifIndex": 47
},
{
"index": "49",
"entity_physical_index": 49,
"type": "1000_BASE_LX_SFP",
"vendor": "HP",
"oui": null,
"model": null,
"revision": null,
"serial": "CN2AFSQ0FV",
"date": null,
"ddm": 1,
"encoding": null,
"cable": "SM",
"distance": 10000,
"wavelength": 1310,
"connector": null,
"channels": 1,
"ifIndex": 49
},
{
"index": "50",
"entity_physical_index": 50,
"type": "1000_BASE_LX_SFP",
"vendor": "HP",
"oui": null,
"model": null,
"revision": null,
"serial": "CN2AFSQ0T9",
"date": null,
"ddm": 1,
"encoding": null,
"cable": "SM",
"distance": 10000,
"wavelength": 1310,
"connector": null,
"channels": 1,
"ifIndex": 50
},
{
"index": "51",
"entity_physical_index": 51,
"type": "1000_BASE_LX_SFP",
"vendor": "HP",
"oui": null,
"model": null,
"revision": null,
"serial": "CN2AFSQ0N6",
"date": null,
"ddm": 1,
"encoding": null,
"cable": "SM",
"distance": 10000,
"wavelength": 1310,
"connector": null,
"channels": 1,
"ifIndex": 51
},
{
"index": "52",
"entity_physical_index": 52,
"type": "1000_BASE_LX_SFP",
"vendor": "HP",
"oui": null,
"model": null,
"revision": null,
"serial": "CN2AFSQ3PV",
"date": null,
"ddm": 1,
"encoding": null,
"cable": "SM",
"distance": 10000,
"wavelength": 1310,
"connector": null,
"channels": 1,
"ifIndex": 52
},
{
"index": "53",
"entity_physical_index": 53,
"type": "1000_BASE_LX_SFP",
"vendor": "HP",
"oui": null,
"model": null,
"revision": null,
"serial": "CN2AFSQ18Y",
"date": null,
"ddm": 1,
"encoding": null,
"cable": "SM",
"distance": 10000,
"wavelength": 1310,
"connector": null,
"channels": 1,
"ifIndex": 53
},
{
"index": "54",
"entity_physical_index": 54,
"type": "1000_BASE_LX_SFP",
"vendor": "HP",
"oui": null,
"model": null,
"revision": null,
"serial": "CN2AFSQ341",
"date": null,
"ddm": 1,
"encoding": null,
"cable": "SM",
"distance": 10000,
"wavelength": 1310,
"connector": null,
"channels": 1,
"ifIndex": 54
},
{
"index": "55",
"entity_physical_index": 55,
"type": "1000_BASE_LX_SFP",
"vendor": "HP",
"oui": null,
"model": null,
"revision": null,
"serial": "CN2AFSQ0HZ",
"date": null,
"ddm": 1,
"encoding": null,
"cable": "SM",
"distance": 10000,
"wavelength": 1310,
"connector": null,
"channels": 1,
"ifIndex": 55
},
{
"index": "56",
"entity_physical_index": 56,
"type": "1000_BASE_LX_SFP",
"vendor": "HP",
"oui": null,
"model": null,
"revision": null,
"serial": "CN29FSQ66R",
"date": null,
"ddm": 1,
"encoding": null,
"cable": "SM",
"distance": 10000,
"wavelength": 1310,
"connector": null,
"channels": 1,
"ifIndex": 56
},
{
"index": "64",
"entity_physical_index": 64,
"type": "1000_BASE_SX_SFP",
"vendor": "PROLINE",
"oui": null,
"model": null,
"revision": null,
"serial": "",
"date": null,
"ddm": 1,
"encoding": null,
"cable": "MM",
"distance": 550,
"wavelength": 850,
"connector": null,
"channels": 1,
"ifIndex": 64
},
{
"index": "66",
"entity_physical_index": 66,
"type": "1000_BASE_SX_SFP",
"vendor": "Ligent Photonic",
"oui": null,
"model": null,
"revision": null,
"serial": "",
"date": null,
"ddm": 1,
"encoding": null,
"cable": "MM",
"distance": 550,
"wavelength": 850,
"connector": null,
"channels": 1,
"ifIndex": 66
}
]
}
}
}

View File

@@ -5837,8 +5837,8 @@
"ifName": "NULL0",
"portName": null,
"ifIndex": 29,
"ifSpeed": 0,
"ifSpeed_prev": null,
"ifSpeed": null,
"ifSpeed_prev": 0,
"ifConnectorPresent": "false",
"ifOperStatus": "up",
"ifOperStatus_prev": "up",
@@ -5937,8 +5937,8 @@
"ifName": "Vlan-interface10",
"portName": null,
"ifIndex": 33,
"ifSpeed": 0,
"ifSpeed_prev": null,
"ifSpeed": null,
"ifSpeed_prev": 0,
"ifConnectorPresent": "false",
"ifOperStatus": "up",
"ifOperStatus_prev": "up",
@@ -8107,5 +8107,30 @@
]
},
"poller": "matches discovery"
},
"transceivers": {
"discovery": {
"transceivers": [
{
"index": "26",
"entity_physical_index": 26,
"type": "1000_BASE_LX_SFP",
"vendor": "HPE",
"oui": null,
"model": null,
"revision": null,
"serial": "210231A0LSX10B000123",
"date": null,
"ddm": 1,
"encoding": null,
"cable": "SM",
"distance": 10000,
"wavelength": 1310,
"connector": null,
"channels": 1,
"ifIndex": 26
}
]
}
}
}

View File

@@ -2047,5 +2047,49 @@
]
},
"poller": "matches discovery"
},
"transceivers": {
"discovery": {
"transceivers": [
{
"index": "49",
"entity_physical_index": 49,
"type": "10G_BASE_SR_SFP",
"vendor": "UVUUU ** *******",
"oui": "00 00 7F",
"model": null,
"revision": "U***",
"serial": "UU**U4U**Q******",
"date": null,
"ddm": 1,
"encoding": null,
"cable": "MM",
"distance": 300,
"wavelength": 0,
"connector": null,
"channels": 1,
"ifIndex": null
},
{
"index": "50",
"entity_physical_index": 50,
"type": "10G_BASE_SR_SFP",
"vendor": "AVAGO",
"oui": "00 17 6A",
"model": null,
"revision": "G2.3",
"serial": "CN292K3425",
"date": null,
"ddm": 1,
"encoding": null,
"cable": "MM",
"distance": 300,
"wavelength": 850,
"connector": null,
"channels": 1,
"ifIndex": null
}
]
}
}
}

View File

@@ -37943,7 +37943,7 @@
"entPhysicalContainedIn": 77,
"entPhysicalParentRelPos": 1,
"entPhysicalMfgName": "",
"ifIndex": null
"ifIndex": 2106382
},
{
"entPhysicalIndex": 79,
@@ -37962,7 +37962,7 @@
"entPhysicalContainedIn": 77,
"entPhysicalParentRelPos": 2,
"entPhysicalMfgName": "",
"ifIndex": null
"ifIndex": 2106382
},
{
"entPhysicalIndex": 80,
@@ -38171,7 +38171,7 @@
"entPhysicalContainedIn": 89,
"entPhysicalParentRelPos": 1,
"entPhysicalMfgName": "",
"ifIndex": null
"ifIndex": 2107918
},
{
"entPhysicalIndex": 91,

File diff suppressed because it is too large Load Diff

View File

@@ -29351,7 +29351,7 @@
"sensor_index": "1065",
"sensor_type": "cisco-entity-sensor",
"sensor_descr": "Gi1/0/52 Bias Current",
"group": null,
"group": "transceiver",
"sensor_divisor": 10000,
"sensor_multiplier": 1,
"sensor_current": 0.0061,
@@ -29376,7 +29376,7 @@
"sensor_index": "3065",
"sensor_type": "cisco-entity-sensor",
"sensor_descr": "Gi3/0/52 Bias Current",
"group": null,
"group": "transceiver",
"sensor_divisor": 10000,
"sensor_multiplier": 1,
"sensor_current": 0.0057,
@@ -29401,7 +29401,7 @@
"sensor_index": "1066",
"sensor_type": "cisco-entity-sensor",
"sensor_descr": "Gi1/0/52 Transmit Power",
"group": null,
"group": "transceiver",
"sensor_divisor": 10,
"sensor_multiplier": 1,
"sensor_current": -5,
@@ -29426,7 +29426,7 @@
"sensor_index": "1067",
"sensor_type": "cisco-entity-sensor",
"sensor_descr": "Gi1/0/52 Receive Power",
"group": null,
"group": "transceiver",
"sensor_divisor": 10,
"sensor_multiplier": 1,
"sensor_current": -4.7,
@@ -29451,7 +29451,7 @@
"sensor_index": "3066",
"sensor_type": "cisco-entity-sensor",
"sensor_descr": "Gi3/0/52 Transmit Power",
"group": null,
"group": "transceiver",
"sensor_divisor": 10,
"sensor_multiplier": 1,
"sensor_current": -5,
@@ -29476,7 +29476,7 @@
"sensor_index": "3067",
"sensor_type": "cisco-entity-sensor",
"sensor_descr": "Gi3/0/52 Receive Power",
"group": null,
"group": "transceiver",
"sensor_divisor": 10,
"sensor_multiplier": 1,
"sensor_current": -7.3,
@@ -30176,7 +30176,7 @@
"sensor_index": "1063",
"sensor_type": "cisco-entity-sensor",
"sensor_descr": "Gi1/0/52 Module",
"group": null,
"group": "transceiver",
"sensor_divisor": 10,
"sensor_multiplier": 1,
"sensor_current": 34.6,
@@ -30201,7 +30201,7 @@
"sensor_index": "3063",
"sensor_type": "cisco-entity-sensor",
"sensor_descr": "Gi3/0/52 Module",
"group": null,
"group": "transceiver",
"sensor_divisor": 10,
"sensor_multiplier": 1,
"sensor_current": 31,
@@ -30226,7 +30226,7 @@
"sensor_index": "1064",
"sensor_type": "cisco-entity-sensor",
"sensor_descr": "Gi1/0/52 Supply Voltage",
"group": null,
"group": "transceiver",
"sensor_divisor": 100,
"sensor_multiplier": 1,
"sensor_current": 3.32,
@@ -30251,7 +30251,7 @@
"sensor_index": "3064",
"sensor_type": "cisco-entity-sensor",
"sensor_descr": "Gi3/0/52 Supply Voltage",
"group": null,
"group": "transceiver",
"sensor_divisor": 100,
"sensor_multiplier": 1,
"sensor_current": 3.32,
@@ -32052,7 +32052,7 @@
"entPhysicalContainedIn": 1062,
"entPhysicalParentRelPos": 1,
"entPhysicalMfgName": "",
"ifIndex": null
"ifIndex": 10152
},
{
"entPhysicalIndex": 1064,
@@ -32071,7 +32071,7 @@
"entPhysicalContainedIn": 1062,
"entPhysicalParentRelPos": 2,
"entPhysicalMfgName": "",
"ifIndex": null
"ifIndex": 10152
},
{
"entPhysicalIndex": 1065,
@@ -32090,7 +32090,7 @@
"entPhysicalContainedIn": 1062,
"entPhysicalParentRelPos": 3,
"entPhysicalMfgName": "",
"ifIndex": null
"ifIndex": 10152
},
{
"entPhysicalIndex": 1066,
@@ -32109,7 +32109,7 @@
"entPhysicalContainedIn": 1062,
"entPhysicalParentRelPos": 4,
"entPhysicalMfgName": "",
"ifIndex": null
"ifIndex": 10152
},
{
"entPhysicalIndex": 1067,
@@ -32128,7 +32128,7 @@
"entPhysicalContainedIn": 1062,
"entPhysicalParentRelPos": 5,
"entPhysicalMfgName": "",
"ifIndex": null
"ifIndex": 10152
},
{
"entPhysicalIndex": 2001,
@@ -34028,7 +34028,7 @@
"entPhysicalContainedIn": 3062,
"entPhysicalParentRelPos": 1,
"entPhysicalMfgName": "",
"ifIndex": null
"ifIndex": 11152
},
{
"entPhysicalIndex": 3064,
@@ -34047,7 +34047,7 @@
"entPhysicalContainedIn": 3062,
"entPhysicalParentRelPos": 2,
"entPhysicalMfgName": "",
"ifIndex": null
"ifIndex": 11152
},
{
"entPhysicalIndex": 3065,
@@ -34066,7 +34066,7 @@
"entPhysicalContainedIn": 3062,
"entPhysicalParentRelPos": 3,
"entPhysicalMfgName": "",
"ifIndex": null
"ifIndex": 11152
},
{
"entPhysicalIndex": 3066,
@@ -34085,7 +34085,7 @@
"entPhysicalContainedIn": 3062,
"entPhysicalParentRelPos": 4,
"entPhysicalMfgName": "",
"ifIndex": null
"ifIndex": 11152
},
{
"entPhysicalIndex": 3067,
@@ -34104,7 +34104,7 @@
"entPhysicalContainedIn": 3062,
"entPhysicalParentRelPos": 5,
"entPhysicalMfgName": "",
"ifIndex": null
"ifIndex": 11152
}
]
},
@@ -34238,5 +34238,49 @@
}
]
}
},
"transceivers": {
"discovery": {
"transceivers": [
{
"index": "1062",
"entity_physical_index": 10152,
"type": "1000BaseSX SFP",
"vendor": "",
"oui": null,
"model": "GLC-SX-MMD",
"revision": "V01",
"serial": "FNS192717K1",
"date": null,
"ddm": null,
"encoding": null,
"cable": null,
"distance": null,
"wavelength": null,
"connector": null,
"channels": 1,
"ifIndex": 10152
},
{
"index": "3062",
"entity_physical_index": 11152,
"type": "1000BaseSX SFP",
"vendor": "",
"oui": null,
"model": "GLC-SX-MMD",
"revision": "V01",
"serial": "FNS192717QJ",
"date": null,
"ddm": null,
"encoding": null,
"cable": null,
"distance": null,
"wavelength": null,
"connector": null,
"channels": 1,
"ifIndex": 11152
}
]
}
}
}

View File

@@ -2909,7 +2909,7 @@
"entPhysicalContainedIn": 10,
"entPhysicalParentRelPos": 0,
"entPhysicalMfgName": "Sierra Wireless",
"ifIndex": null
"ifIndex": 8
},
{
"entPhysicalIndex": 15,

Some files were not shown because too many files have changed in this diff Show More