diff --git a/LibreNMS/Util/Url.php b/LibreNMS/Util/Url.php
index d60f6284a6..061ed2f43a 100644
--- a/LibreNMS/Util/Url.php
+++ b/LibreNMS/Util/Url.php
@@ -171,6 +171,53 @@ class Url
return Rewrite::normalizeIfName($text);
}
+ /**
+ * @param Sensor $sensor
+ * @param string $text
+ * @param string $type
+ * @param boolean $overlib
+ * @param boolean $single_graph
+ * @return mixed|string
+ */
+ public static function sensorLink($sensor, $text = null, $type = null, $overlib = true, $single_graph = false)
+ {
+
+ $label = $sensor->sensor_descr;
+ if (!$text) {
+ $text = $label;
+ }
+
+ $content = '
' . addslashes(htmlentities($sensor->device->displayName() . ' - ' . $label)) . '
';
+
+ $content .= "";
+ $graph_array = [
+ 'type' => $type ?: 'sensor_' . $sensor->sensor_class,
+ 'legend' => 'yes',
+ 'height' => 100,
+ 'width' => 340,
+ 'to' => Carbon::now()->timestamp,
+ 'from' => Carbon::now()->subDay()->timestamp,
+ 'id' => $sensor->sensor_id,
+ ];
+
+ $content .= self::graphTag($graph_array);
+ if (!$single_graph) {
+ $graph_array['from'] = Carbon::now()->subWeek()->timestamp;
+ $content .= self::graphTag($graph_array);
+ $graph_array['from'] = Carbon::now()->subMonth()->timestamp;
+ $content .= self::graphTag($graph_array);
+ $graph_array['from'] = Carbon::now()->subYear()->timestamp;
+ $content .= self::graphTag($graph_array);
+ }
+
+ $content .= '
';
+
+ if (!$overlib) {
+ return $content;
+ }
+ return self::overlibLink(self::sensorUrl($sensor), $text, $content, self::sensorLinkDisplayClass($sensor));
+ }
+
public static function deviceUrl($device, $vars = [])
{
return self::generate(['page' => 'device', 'device' => $device->device_id], $vars);
@@ -181,6 +228,11 @@ class Url
return self::generate(['page' => 'device', 'device' => $port->device_id, 'tab' => 'port', 'port' => $port->port_id], $vars);
}
+ public static function sensorUrl($sensor, $vars = [])
+ {
+ return self::generate(['page' => 'device', 'device' => $sensor->device_id, 'tab' => 'health' , 'metric' => $sensor->sensor_class], $vars);
+ }
+
/**
* @param Port $port
* @return string
@@ -369,6 +421,25 @@ class Url
return "interface-upup";
}
+ /**
+ * Get html class for a sensor
+ *
+ * @param Sensor $sensor
+ * @return string
+ */
+ public static function sensorLinkDisplayClass($sensor)
+ {
+ if ($sensor->sensor_current >> $sensor->sensor_limit) {
+ return "sensor-high";
+ }
+
+ if ($sensor->sensor_current << $sensor->sensor_limit_low) {
+ return "sensor-low";
+ }
+
+ return 'sensor-ok';
+ }
+
/**
* @param string $os
* @param string $feature
diff --git a/app/Http/Controllers/Table/EventlogController.php b/app/Http/Controllers/Table/EventlogController.php
index c58041ff40..c42fcef457 100644
--- a/app/Http/Controllers/Table/EventlogController.php
+++ b/app/Http/Controllers/Table/EventlogController.php
@@ -89,6 +89,13 @@ class EventlogController extends TableController
return '' . Url::portLink($port, $port->getShortLabel()) . '';
}
}
+ } elseif (in_array(strtolower($eventlog->type), \App\Models\Sensor::getTypes())) {
+ if (is_numeric($eventlog->reference)) {
+ $sensor = $eventlog->related;
+ if (isset($sensor)) {
+ return '' . Url::sensorLink($sensor, $sensor->sensor_descr) . '';
+ }
+ }
}
return $eventlog->type;
diff --git a/app/Models/Sensor.php b/app/Models/Sensor.php
index b763b5ef44..5a5ca21404 100644
--- a/app/Models/Sensor.php
+++ b/app/Models/Sensor.php
@@ -54,6 +54,36 @@ class Sensor extends DeviceRelatedModel
return collect(self::$icons)->get($this->sensor_class, 'delicius');
}
+ public static function getTypes()
+ {
+ return ['airflow',
+ 'ber',
+ 'chromatic_dispersion',
+ 'cooling',
+ 'count',
+ 'current',
+ 'dbm',
+ 'delay',
+ 'eer',
+ 'fanspeed',
+ 'frequency',
+ 'humidity',
+ 'load',
+ 'power_consumed',
+ 'power_factor',
+ 'power',
+ 'pressure',
+ 'quality_factor',
+ 'runtime',
+ 'signal',
+ 'snr',
+ 'state',
+ 'temperature',
+ 'voltage',
+ 'waterflow',
+ ];
+ }
+
// for the legacy menu
public static function getIconMap()
{
diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php
index d3b8bb9293..e194634226 100644
--- a/app/Providers/AppServiceProvider.php
+++ b/app/Providers/AppServiceProvider.php
@@ -6,6 +6,7 @@ use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\ServiceProvider;
+use App\Models\Sensor;
use LibreNMS\Config;
use LibreNMS\Permissions;
use LibreNMS\Util\IP;
@@ -74,12 +75,16 @@ class AppServiceProvider extends ServiceProvider
private function configureMorphAliases()
{
- Relation::morphMap([
+ $sensor_types = [];
+ foreach (Sensor::getTypes() as $type) {
+ $sensor_types[ucwords($type)] = \App\Models\Sensor::class;
+ };
+ Relation::morphMap(array_merge([
'interface' => \App\Models\Port::class,
'sensor' => \App\Models\Sensor::class,
'device' => \App\Models\Device::class,
'device_group' => \App\Models\DeviceGroup::class,
- ]);
+ ], $sensor_types));
}
private function registerFacades()
diff --git a/html/css/styles.css b/html/css/styles.css
index 285a90d67c..73aee95d52 100644
--- a/html/css/styles.css
+++ b/html/css/styles.css
@@ -822,6 +822,22 @@ a.interface-upup:hover, a.interface-updown:hover, a.interface-admindown:hover {
color: #999999;
}
+.sensor-low, a.sensor-low, a.sensor-low:visited {
+ color: #c11;
+}
+
+.sensor-high, a.sensor-high, a.sensor-high:visited {
+ color: #c11;
+}
+
+.sensor-ok, a.sensor-ok, a.sensor-ok:visited {
+ color: #11a;
+}
+
+a.sensor-ok:hover, a.sensor-low:hover, a.sensor-high:hover {
+ color: #990099;
+}
+
#top {
height:17px;
padding:2px 21px 0px 21px;
diff --git a/includes/polling/functions.inc.php b/includes/polling/functions.inc.php
index b879387efb..f5ab7598f3 100644
--- a/includes/polling/functions.inc.php
+++ b/includes/polling/functions.inc.php
@@ -199,10 +199,10 @@ function record_sensor_data($device, $all_sensors)
// FIXME also warn when crossing WARN level!
if ($sensor['sensor_limit_low'] != '' && $prev_sensor_value > $sensor['sensor_limit_low'] && $sensor_value < $sensor['sensor_limit_low'] && $sensor['sensor_alert'] == 1) {
echo 'Alerting for '.$device['hostname'].' '.$sensor['sensor_descr']."\n";
- log_event("$class {$sensor['sensor_descr']} under threshold: $sensor_value $unit (< {$sensor['sensor_limit_low']} $unit)", $device, $class, 4, $sensor['sensor_id']);
+ log_event("$class under threshold: $sensor_value $unit (< {$sensor['sensor_limit_low']} $unit)", $device, $class, 4, $sensor['sensor_id']);
} elseif ($sensor['sensor_limit'] != '' && $prev_sensor_value < $sensor['sensor_limit'] && $sensor_value > $sensor['sensor_limit'] && $sensor['sensor_alert'] == 1) {
echo 'Alerting for '.$device['hostname'].' '.$sensor['sensor_descr']."\n";
- log_event("$class {$sensor['sensor_descr']} above threshold: $sensor_value $unit (> {$sensor['sensor_limit']} $unit)", $device, $class, 4, $sensor['sensor_id']);
+ log_event("$class above threshold: $sensor_value $unit (> {$sensor['sensor_limit']} $unit)", $device, $class, 4, $sensor['sensor_id']);
}
if ($sensor['sensor_class'] == 'state' && $prev_sensor_value != $sensor_value) {
$trans = array_column(