diff --git a/doc/API/API-Docs.md b/doc/API/API-Docs.md
index 76641e24cd..a332e3a221 100644
--- a/doc/API/API-Docs.md
+++ b/doc/API/API-Docs.md
@@ -12,6 +12,8 @@ source: API/API-Docs.md
- [`del_device`](#api-route-2)
- [`get_device`](#api-route-3)
- [`get_graphs`](#api-route-5)
+ - [`list_available_health_graphs`](#api-route-list_available_health_graphs)
+ - [`get_health_graph`](#api-route-get_health_graph)
- [`get_graph_generic_by_hostname`](#api-route-6)
- [`get_port_graphs`](#api-route-7)
- [`get_port_stack`](#api-route-29)
@@ -29,6 +31,8 @@ source: API/API-Docs.md
- [`devicegroups`](#api-devicegroups)
- [`get_devicegroups`](#api-route-get_devicegroups)
- [`get_devices_by_group`](#api-route-get_devices_by_group)
+ - [`portgroups`](#api-portgroups)
+ - [`get_graph_by_portgroup`](#api-route-get_graph_by_portgroup)
- [`routing`](#api-routing)
- [`list_bgp`](#api-route-1)
- [`list_ipsec`](#list_ipsec)
@@ -221,6 +225,146 @@ Output:
}
```
+### Function: `list_available_health_graphs` [`top`](#top)
+This function allows to do three things:
+
+ - Get a list of overall health graphs available.
+ - Get a list of health graphs based on provided class.
+ - Get the health sensors information based on ID.
+
+Route: /api/v0/devices/:hostname/health(/:type)(/:sensor_id)
+
+ - hostname can be either the device hostname or id
+ - type (optional) is health type / sensor class
+ - sensor_id (optional) is the sensor id to retreive specific information.
+
+Input:
+
+ -
+
+Example:
+```curl
+curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/health
+```
+
+Output:
+```
+{
+ "status": "ok",
+ "err-msg": "",
+ "count": 2,
+ "graphs": [
+ {
+ "desc": "Airflow",
+ "name": "device_airflow"
+ },
+ {
+ "desc": "Voltage",
+ "name": "device_voltage"
+ }
+ ]
+}
+```
+
+Example:
+```curl
+curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/health/device_voltage
+```
+
+Output:
+```
+{
+ "status": "ok",
+ "err-msg": "",
+ "count": 2,
+ "graphs": [
+ {
+ "sensor_id": "1",
+ "desc": "Input Feed A"
+ },
+ {
+ "sensor_id": "2",
+ "desc": "Output Feed"
+ }
+ ]
+}
+```
+
+Example:
+```curl
+curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/health/device_voltage/1
+```
+
+Output:
+```
+{
+ "status": "ok",
+ "err-msg": "",
+ "count": 1,
+ "graphs": [
+ {
+ "sensor_id": "1",
+ "sensor_deleted": "0",
+ "sensor_class": "voltage",
+ "device_id": "1",
+ "poller_type": "snmp",
+ "sensor_oid": ".1.3.6.1.4.1.318.1.1.27.1.1.0",
+ "sensor_index": "1",
+ "sensor_type": "apc",
+ "sensor_descr": "Input",
+ "sensor_divisor": "1",
+ "sensor_multiplier": "1",
+ "sensor_current": "1",
+ "sensor_limit": "1.15",
+ "sensor_limit_warn": null,
+ "sensor_limit_low": "0.85",
+ "sensor_limit_low_warn": null,
+ "sensor_alert": "1",
+ "sensor_custom": "No",
+ "entPhysicalIndex": null,
+ "entPhysicalIndex_measured": null,
+ "lastupdate": "2017-01-13 13:50:26",
+ "sensor_prev": "1"
+ }
+ ]
+}
+```
+
+### Function: `get_health_graph` [`top`](#top)
+
+Get a particular health class graph for a device, if you provide a sensor_id as well then a single sensor graph
+will be provided. If no sensor_id value is provided then you will be sent a stacked sensor graph.
+
+Route: /api/v0/devices/:hostname/graphs/health/:type(/:sensor_id)
+
+ - hostname can be either the device hostname or id
+ - type is the name of the health graph as returned by [`list_available_health_graphs`](#api-route-list_available_health_graphs)
+ - sensor_id (optional) restricts the graph to return a particular health sensor graph.
+
+Input:
+
+ -
+
+Example:
+```curl
+curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/graphs/health/device_voltage
+```
+
+Output:
+
+Output is a stacked graph for the health type provided.
+
+Example:
+```curl
+curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/graphs/health/device_voltage/1
+```
+
+Output:
+
+Output is the graph of the particular health type sensor provided.
+
+
+
### Function: `get_graph_generic_by_hostname` [`top`](#top)
Get a specific graph for a device, this does not include ports.
@@ -823,6 +967,32 @@ Output:
]
```
+## `Port Groups` [`top`](#top)
+
+### Function: `get_graph_by_portgroup` [`top`](#top)
+
+Get the graph based on the group type.
+
+Route: /api/v0/devices/portgroups/:group
+
+ - group is the type of port group graph you want, I.e Transit, Peering, etc. You can specify multiple types comma separated.
+
+Input:
+
+ - from: This is the date you would like the graph to start - See http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html for more information.
+ - to: This is the date you would like the graph to end - See http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html for more information.
+ - width: The graph width, defaults to 1075.
+ - height: The graph height, defaults to 300.
+
+Example:
+```curl
+curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/portgroups/transit,peering
+```
+
+Output:
+
+Output is an image.
+
## `Routing` [`top`](#top)
### Function: `list_bgp` [`top`](#top)
diff --git a/html/api_v0.php b/html/api_v0.php
index 0c4b43f70e..e22fdf1086 100644
--- a/html/api_v0.php
+++ b/html/api_v0.php
@@ -40,6 +40,8 @@ $app->group(
// api/v0/devices/$hostname/vlans
$app->get('/:hostname/graphs', 'authToken', 'get_graphs')->name('get_graphs');
// api/v0/devices/$hostname/graphs
+ $app->get('/:hostname/health(/:type)(/:sensor_id)', 'authToken', 'list_available_health_graphs')->name('list_available_health_graphs');
+ // api/v0/devices/$hostname/health
$app->get('/:hostname/ports', 'authToken', 'get_port_graphs')->name('get_port_graphs');
$app->get('/:hostname/port_stack', 'authToken', 'get_port_stack')->name('get_port_stack');
// api/v0/devices/$hostname/ports
@@ -48,6 +50,7 @@ $app->group(
$app->put('/:hostname/components', 'authToken', 'edit_components')->name('edit_components');
$app->delete('/:hostname/components/:component', 'authToken', 'delete_components')->name('delete_components');
$app->get('/:hostname/groups', 'authToken', 'get_device_groups')->name('get_device_groups');
+ $app->get('/:hostname/graphs/health/:type(/:sensor_id)', 'authToken', 'get_graph_generic_by_hostname')->name('get_health_graph');
$app->get('/:hostname/:type', 'authToken', 'get_graph_generic_by_hostname')->name('get_graph_generic_by_hostname');
// api/v0/devices/$hostname/$type
$app->get('/:hostname/ports/:ifname', 'authToken', 'get_port_stats_by_port_hostname')->name('get_port_stats_by_port_hostname');
diff --git a/html/includes/api_functions.inc.php b/html/includes/api_functions.inc.php
index fb2dd1b085..44ddb584f5 100644
--- a/html/includes/api_functions.inc.php
+++ b/html/includes/api_functions.inc.php
@@ -123,8 +123,13 @@ function get_graph_generic_by_hostname()
$app = \Slim\Slim::getInstance();
$router = $app->router()->getCurrentRoute()->getParams();
$hostname = $router['hostname'];
+ $sensor_id = $router['sensor_id'] ?: null;
$vars = array();
$vars['type'] = $router['type'] ?: 'device_uptime';
+ if (isset($sensor_id)) {
+ $vars['id'] = $sensor_id;
+ $vars['type'] = str_replace('device_', 'sensor_', $vars['type']);
+ }
// use hostname as device_id if it's all digits
$device_id = ctype_digit($hostname) ? $hostname : getidbyname($hostname);
@@ -678,6 +683,53 @@ function get_graphs()
echo _json_encode($output);
}
+function list_available_health_graphs()
+{
+ global $config;
+ $code = 200;
+ $status = 'ok';
+ $message = '';
+ $app = \Slim\Slim::getInstance();
+ $router = $app->router()->getCurrentRoute()->getParams();
+ $hostname = $router['hostname'];
+ $device_id = ctype_digit($hostname) ? $hostname : getidbyname($hostname);
+ if (isset($router['type'])) {
+ list($dump, $type) = explode('_', $router['type']);
+ }
+ $sensor_id = $router['sensor_id'] ?: null;
+ $graphs = array();
+
+ if (isset($type)) {
+ if (isset($sensor_id)) {
+ $graphs = dbFetchRows('SELECT * FROM `sensors` WHERE `sensor_id` = ?', array($sensor_id));
+ } else {
+ foreach (dbFetchRows('SELECT `sensor_id`, `sensor_descr` FROM `sensors` WHERE `device_id` = ? AND `sensor_class` = ? AND `sensor_deleted` = 0', array($device_id, $type)) as $graph) {
+ $graphs[] = array(
+ 'sensor_id' => $graph['sensor_id'],
+ 'desc' => $graph['sensor_descr'],
+ );
+ }
+ }
+ } else {
+ foreach (dbFetchRows('SELECT `sensor_class` FROM `sensors` WHERE `device_id` = ? AND `sensor_deleted` = 0 GROUP BY `sensor_class`', array($device_id)) as $graph) {
+ $graphs[] = array(
+ 'desc' => ucfirst($graph['sensor_class']),
+ 'name' => 'device_'.$graph['sensor_class'],
+ );
+ }
+ }
+
+ $total_graphs = count($graphs);
+ $output = array(
+ 'status' => "$status",
+ 'err-msg' => $message,
+ 'count' => $total_graphs,
+ 'graphs' => $graphs,
+ );
+ $app->response->setStatus($code);
+ $app->response->headers->set('Content-Type', 'application/json');
+ echo _json_encode($output);
+}
function get_port_graphs()
{