diff --git a/integrations/inputunifi/.gitignore b/integrations/inputunifi/.gitignore
index 913e8eb4..2c836bd0 100644
--- a/integrations/inputunifi/.gitignore
+++ b/integrations/inputunifi/.gitignore
@@ -3,3 +3,5 @@
/*.1.gz
/*.1
/vendor
+.DS_Store
+*~
diff --git a/integrations/inputunifi/README.md b/integrations/inputunifi/README.md
index 8e850026..7981c6e9 100644
--- a/integrations/inputunifi/README.md
+++ b/integrations/inputunifi/README.md
@@ -1,12 +1,104 @@
# Unifi
-Collect your Unifi Controller Client data and send it to an InfluxDB instance. Grafana dashboard included.
-
-
+Collect your Unifi Controller Data and send it to an InfluxDB instance.
+Grafana dashboards included.
## Installation
[See the Wiki!](https://github.com/davidnewhall/unifi-poller/wiki/Installation)
+# Backstory
+
+Okay, so here's the deal. I found a simple piece of code on github that
+sorta did what I needed; we all know that story. I wanted more data, so
+I added more data collection. I believe I've completely rewritten every
+piece of original code, except the copyright/license file and that's fine
+by me. I probably wouldn't have made it this far if
+[Garrett](https://github.com/dewski/unifi) hadn't written the original
+code I started with. Many props my man.
+
+The original code pulled only the client data. This app now pulls data
+for clients, access points, security gateways and switches. I currently
+own two UAP-AC-PROs, one USG-3 and one US-24-250W. If your devices differ
+this app may miss some data. I'm willing to help and make it better.
+Open an [Issue](https://github.com/davidnewhall/unifi-poller/issues) and
+we'll figure out how to get things working for you.
+
+# What's this data good for?
+
+I've been trying to get my UAP data into Grafana. Sure, google search that.
+You'll find [this](https://community.ubnt.com/t5/UniFi-Wireless/Grafana-dashboard-for-UniFi-APs-now-available/td-p/1833532).
+And that's all you'll find. What if you don't want to deal with SNMP?
+Well, here you go. I've replicated 90% of what you see on those SNMP-powered
+dashboards with this Go app running on the same mac as my Unifi controller.
+All without enabling SNMP nor trying to understand those OIDs. Mad props
+to [waterside](https://community.ubnt.com/t5/user/viewprofilepage/user-id/303058)
+for making this dashboard; it gave me a fantastic start to making my own.
+
+# What now...
+
+- I probably suck at InfluxDB.
+
+I don't know what should be a tag and what should be a field. I think
+I did my best, but there's certainly room for improvements in both
+the data input and the Grafana graphs (output).
+
+
+- The USW and USG code needs love.
+
+Up to this point, my focus has been on UAP. I have only included dashboards
+that focus on UAP. I am still working on the other two, but it may be a while
+before I get around to publishing them. Help is appreciated.
+
+
+- Are there other devices that need to be included?
+
+I have: switch, router, access point. Three total, and the type structs are
+likely missing data for variants of these devices. e.g. Some UAPs have more
+radios, I probably didn't properly account for that. Some gateways have more
+ports, some switches have 10Gb, etc. These are things I do not have data on
+to write code for. If you have these devices, and want them graphed, open an
+Issue and lets discuss.
+
+
+- Better Installation instructions.
+
+If you're a nerd you can probably figure it out. I'd still like some pretty
+pictures and maybe even a Twitch VOD.
+
+
+- Sanity Checking
+
+Did I actually graph the right data in the right way? Some validation would
+be nice.
+
+
+- Radios, Frequencies, Interfaces, vAPs
+
+My access points only seem to have two radios, one interface and vAP per radio.
+I'm not sure if the graphs, as-is, provide enough insight into APs with other
+configurations. Help me figure that out?
+
+# What's it look like?
+
+Here's a picture of the Client dashboard.
+
+
+
+Here's a picture of the UAP dashboard. This only shows one device, but you can
+select multiple to put specific stats side-by-side.
+
+
+
+# Woah, there's a library in here.
+
+Sure is. If you want to write your own code around unifi data, you can import
+the `unidev` library and easily poll your controller. If you have interest in
+how to use the library, or need more features, open an Issue. I'm not committed
+to documenting it unless it seems useful.
+
+
## Copyright & License
-Copyright © 2016 Garrett Bjerkhoel. See [MIT-LICENSE](MIT-LICENSE) for details.
+- Copyright © 2016 Garrett Bjerkhoel.
+- Copyright © 2018 David Newhall II.
+- See [MIT-LICENSE](MIT-LICENSE) for license information.
diff --git a/integrations/inputunifi/cmd/unifi-poller/config.go b/integrations/inputunifi/cmd/unifi-poller/config.go
index a04de1d4..56fbbdde 100644
--- a/integrations/inputunifi/cmd/unifi-poller/config.go
+++ b/integrations/inputunifi/cmd/unifi-poller/config.go
@@ -4,7 +4,7 @@ import "time"
// Version will be injected at build time.
var (
- Version = "v0.1"
+ Version = "v0.2"
Debug = false
)
diff --git a/integrations/inputunifi/cmd/unifi-poller/main.go b/integrations/inputunifi/cmd/unifi-poller/main.go
index cdfa86af..e8adb3b6 100644
--- a/integrations/inputunifi/cmd/unifi-poller/main.go
+++ b/integrations/inputunifi/cmd/unifi-poller/main.go
@@ -83,14 +83,14 @@ func GetConfig(configFile string) (Config, error) {
func (c *Config) PollUnifiController(infdb influx.Client, unifi *unidev.AuthedReq) {
ticker := time.NewTicker(c.Interval.value)
for range ticker.C {
- clients, err := unifi.GetUnifiClients()
+ clients, err := unifi.GetUnifiClientAssets()
if err != nil {
- log.Println("unifi.GetUnifiClients():", err)
+ log.Println("unifi.GetUnifiClientsAssets():", err)
continue
}
- devices, err := unifi.GetUnifiDevices()
+ devices, err := unifi.GetUnifiDeviceAssets()
if err != nil {
- log.Println("unifi.GetUnifiDevices():", err)
+ log.Println("unifi.GetUnifiDeviceAssets():", err)
continue
}
bp, err := influx.NewBatchPoints(influx.BatchPointsConfig{
@@ -102,10 +102,10 @@ func (c *Config) PollUnifiController(infdb influx.Client, unifi *unidev.AuthedRe
}
for _, asset := range append(clients, devices...) {
- if pt, errr := asset.Point(); errr != nil {
- log.Println("asset.Point():", errr)
+ if pt, errr := asset.Points(); errr != nil {
+ log.Println("asset.Points():", errr)
} else {
- bp.AddPoint(pt)
+ bp.AddPoints(pt)
}
}
diff --git a/integrations/inputunifi/grafana-dashboards/README.md b/integrations/inputunifi/grafana-dashboards/README.md
new file mode 100644
index 00000000..565178b7
--- /dev/null
+++ b/integrations/inputunifi/grafana-dashboards/README.md
@@ -0,0 +1,5 @@
+# Grafana Dashboards
+
+Import these into Grafana to quickly visualize data from your devices.
+
+They may/do use a few plugins: Clock, Discrete, Singlestat, Table
diff --git a/integrations/inputunifi/unifi-poller-grafana-dashboard.json b/integrations/inputunifi/grafana-dashboards/unifi-clients-grafana-dash.json
similarity index 100%
rename from integrations/inputunifi/unifi-poller-grafana-dashboard.json
rename to integrations/inputunifi/grafana-dashboards/unifi-clients-grafana-dash.json
diff --git a/integrations/inputunifi/grafana-dashboards/unifi-uap-grafana-dash.json b/integrations/inputunifi/grafana-dashboards/unifi-uap-grafana-dash.json
new file mode 100644
index 00000000..3fdf2626
--- /dev/null
+++ b/integrations/inputunifi/grafana-dashboards/unifi-uap-grafana-dash.json
@@ -0,0 +1,3577 @@
+{
+ "__inputs": [
+ {
+ "name": "DS_UNIFI",
+ "label": "Unifi",
+ "description": "",
+ "type": "datasource",
+ "pluginId": "influxdb",
+ "pluginName": "InfluxDB"
+ }
+ ],
+ "__requires": [
+ {
+ "type": "grafana",
+ "id": "grafana",
+ "name": "Grafana",
+ "version": "5.0.4"
+ },
+ {
+ "type": "panel",
+ "id": "grafana-clock-panel",
+ "name": "Clock",
+ "version": "0.0.9"
+ },
+ {
+ "type": "panel",
+ "id": "graph",
+ "name": "Graph",
+ "version": "5.0.0"
+ },
+ {
+ "type": "datasource",
+ "id": "influxdb",
+ "name": "InfluxDB",
+ "version": "5.0.0"
+ },
+ {
+ "type": "panel",
+ "id": "singlestat",
+ "name": "Singlestat",
+ "version": "5.0.0"
+ },
+ {
+ "type": "panel",
+ "id": "table",
+ "name": "Table",
+ "version": "5.0.0"
+ },
+ {
+ "type": "panel",
+ "id": "text",
+ "name": "Text",
+ "version": "5.0.0"
+ }
+ ],
+ "annotations": {
+ "list": [
+ {
+ "builtIn": 1,
+ "datasource": "-- Grafana --",
+ "enable": true,
+ "hide": true,
+ "iconColor": "rgba(0, 211, 255, 1)",
+ "name": "Annotations & Alerts",
+ "type": "dashboard"
+ }
+ ]
+ },
+ "description": "",
+ "editable": true,
+ "gnetId": 1486,
+ "graphTooltip": 1,
+ "id": null,
+ "iteration": 1524957396402,
+ "links": [],
+ "panels": [
+ {
+ "columns": [],
+ "datasource": "${DS_UNIFI}",
+ "editable": true,
+ "error": false,
+ "fontSize": "100%",
+ "gridPos": {
+ "h": 6,
+ "w": 21,
+ "x": 0,
+ "y": 0
+ },
+ "id": 1,
+ "isNew": true,
+ "links": [],
+ "pageSize": null,
+ "scroll": false,
+ "showHeader": true,
+ "sort": {
+ "col": 11,
+ "desc": true
+ },
+ "styles": [
+ {
+ "alias": "",
+ "colorMode": null,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "dateFormat": "YYYY-MM-DD HH:mm:ss",
+ "decimals": 2,
+ "pattern": "Time",
+ "thresholds": [],
+ "type": "hidden",
+ "unit": "short"
+ },
+ {
+ "alias": "",
+ "colorMode": null,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "dateFormat": "YYYY-MM-DD HH:mm:ss",
+ "decimals": 2,
+ "pattern": "Uptime",
+ "thresholds": [],
+ "type": "number",
+ "unit": "dtdurations"
+ },
+ {
+ "alias": "Name",
+ "colorMode": null,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "dateFormat": "YYYY-MM-DD HH:mm:ss",
+ "decimals": 2,
+ "link": false,
+ "linkTargetBlank": true,
+ "linkUrl": "http:",
+ "pattern": "name",
+ "preserveFormat": false,
+ "sanitize": false,
+ "thresholds": [],
+ "type": "string",
+ "unit": "short"
+ },
+ {
+ "alias": "Config Version",
+ "colorMode": null,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "dateFormat": "YYYY-MM-DD HH:mm:ss",
+ "decimals": 2,
+ "pattern": "cfgversion",
+ "thresholds": [],
+ "type": "string",
+ "unit": "short"
+ },
+ {
+ "alias": "Board Rev",
+ "colorMode": null,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "dateFormat": "YYYY-MM-DD HH:mm:ss",
+ "decimals": 2,
+ "pattern": "board_rev",
+ "thresholds": [],
+ "type": "string",
+ "unit": "short"
+ },
+ {
+ "alias": "Model",
+ "colorMode": null,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "dateFormat": "YYYY-MM-DD HH:mm:ss",
+ "decimals": 2,
+ "pattern": "model",
+ "thresholds": [],
+ "type": "string",
+ "unit": "short"
+ },
+ {
+ "alias": "Device MAC",
+ "colorMode": null,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "dateFormat": "YYYY-MM-DD HH:mm:ss",
+ "decimals": 2,
+ "pattern": "device_ap",
+ "thresholds": [],
+ "type": "string",
+ "unit": "short"
+ },
+ {
+ "alias": "Unifi Serial #",
+ "colorMode": null,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "dateFormat": "YYYY-MM-DD HH:mm:ss",
+ "decimals": 2,
+ "pattern": "serial",
+ "thresholds": [],
+ "type": "string",
+ "unit": "short"
+ },
+ {
+ "alias": "Site ID",
+ "colorMode": null,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "dateFormat": "YYYY-MM-DD HH:mm:ss",
+ "decimals": 2,
+ "pattern": "site_id",
+ "thresholds": [],
+ "type": "hidden",
+ "unit": "short"
+ },
+ {
+ "alias": "",
+ "colorMode": null,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "dateFormat": "YYYY-MM-DD HH:mm:ss",
+ "decimals": 2,
+ "pattern": "Version",
+ "thresholds": [],
+ "type": "string",
+ "unit": "short"
+ },
+ {
+ "alias": "",
+ "colorMode": null,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "dateFormat": "YYYY-MM-DD HH:mm:ss",
+ "decimals": 1,
+ "pattern": "Last Seen",
+ "sanitize": true,
+ "thresholds": [],
+ "type": "number",
+ "unit": "dateTimeAsUS"
+ },
+ {
+ "alias": "Bandsteering Mode",
+ "colorMode": null,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "dateFormat": "YYYY-MM-DD HH:mm:ss",
+ "decimals": 2,
+ "pattern": "bandsteering_mode",
+ "thresholds": [],
+ "type": "string",
+ "unit": "short"
+ },
+ {
+ "alias": "",
+ "colorMode": null,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "dateFormat": "YYYY-MM-DD HH:mm:ss",
+ "decimals": 1,
+ "pattern": "CPU",
+ "thresholds": [],
+ "type": "number",
+ "unit": "percent"
+ }
+ ],
+ "targets": [
+ {
+ "alias": "$col",
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "name"
+ ],
+ "type": "tag"
+ },
+ {
+ "params": [
+ "model"
+ ],
+ "type": "tag"
+ },
+ {
+ "params": [
+ "cfgversion"
+ ],
+ "type": "tag"
+ },
+ {
+ "params": [
+ "board_rev"
+ ],
+ "type": "tag"
+ },
+ {
+ "params": [
+ "serial"
+ ],
+ "type": "tag"
+ },
+ {
+ "params": [
+ "site_id"
+ ],
+ "type": "tag"
+ },
+ {
+ "params": [
+ "bandsteering_mode"
+ ],
+ "type": "tag"
+ },
+ {
+ "params": [
+ "device_ap"
+ ],
+ "type": "tag"
+ }
+ ],
+ "measurement": "uap",
+ "orderByTime": "ASC",
+ "policy": "default",
+ "refId": "A",
+ "resultFormat": "table",
+ "select": [
+ [
+ {
+ "params": [
+ "version"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "Version"
+ ],
+ "type": "alias"
+ }
+ ],
+ [
+ {
+ "params": [
+ "ip"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "IP"
+ ],
+ "type": "alias"
+ }
+ ],
+ [
+ {
+ "params": [
+ "uptime"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "Uptime"
+ ],
+ "type": "alias"
+ }
+ ],
+ [
+ {
+ "params": [
+ "last_seen"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "*1000"
+ ],
+ "type": "math"
+ },
+ {
+ "params": [
+ "Last Seen"
+ ],
+ "type": "alias"
+ }
+ ],
+ [
+ {
+ "params": [
+ "cpu"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "CPU"
+ ],
+ "type": "alias"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "name",
+ "operator": "=~",
+ "value": "/^$host$/"
+ }
+ ]
+ }
+ ],
+ "timeFrom": null,
+ "title": "AP Details",
+ "transform": "table",
+ "transparent": false,
+ "type": "table"
+ },
+ {
+ "content": "
\n
Unifi UAP\n",
+ "gridPos": {
+ "h": 3,
+ "w": 3,
+ "x": 21,
+ "y": 0
+ },
+ "id": 34,
+ "links": [],
+ "mode": "html",
+ "title": "",
+ "transparent": true,
+ "type": "text"
+ },
+ {
+ "bgColor": "#3f2b5b",
+ "clockType": "12 hour",
+ "countdownSettings": {
+ "endCountdownTime": "2018-04-29T21:47:00.000Z",
+ "endText": "00:00:00"
+ },
+ "dateSettings": {
+ "dateFormat": "YYYY-MM-DD",
+ "fontSize": "12px",
+ "fontWeight": "bold",
+ "showDate": true
+ },
+ "gridPos": {
+ "h": 3,
+ "w": 3,
+ "x": 21,
+ "y": 3
+ },
+ "id": 32,
+ "links": [],
+ "mode": "time",
+ "offsetFromUtc": null,
+ "offsetFromUtcMinutes": null,
+ "timeSettings": {
+ "customFormat": "HH:mm:ss",
+ "fontSize": "30px",
+ "fontWeight": "normal"
+ },
+ "title": "Now",
+ "type": "grafana-clock-panel"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": false,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "datasource": "${DS_UNIFI}",
+ "editable": true,
+ "error": false,
+ "format": "none",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": false,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "gridPos": {
+ "h": 4,
+ "w": 4,
+ "x": 0,
+ "y": 6
+ },
+ "height": "",
+ "id": 9,
+ "interval": null,
+ "isNew": true,
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "tableColumn": "device_name",
+ "targets": [
+ {
+ "alias": "",
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "device_name"
+ ],
+ "type": "tag"
+ }
+ ],
+ "measurement": "uap_radios",
+ "orderByTime": "ASC",
+ "policy": "default",
+ "query": "SELECT \"channel\" FROM \"uap_radios\" WHERE (\"device_name\" =~ /^$host$/ AND \"radio\" = 'na') AND $timeFilter GROUP BY \"device_name\"",
+ "rawQuery": false,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "channel"
+ ],
+ "type": "field"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "device_name",
+ "operator": "=~",
+ "value": "/^$host$/"
+ },
+ {
+ "condition": "AND",
+ "key": "radio",
+ "operator": "=",
+ "value": "na"
+ }
+ ]
+ }
+ ],
+ "thresholds": "",
+ "title": "5GHz Radio Channel",
+ "transparent": false,
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [],
+ "valueName": "current"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": false,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "datasource": "${DS_UNIFI}",
+ "editable": true,
+ "error": false,
+ "format": "none",
+ "gauge": {
+ "maxValue": 25,
+ "minValue": 6,
+ "show": true,
+ "thresholdLabels": false,
+ "thresholdMarkers": false
+ },
+ "gridPos": {
+ "h": 4,
+ "w": 4,
+ "x": 4,
+ "y": 6
+ },
+ "id": 11,
+ "interval": null,
+ "isNew": true,
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": " dBm",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "sparkline": {
+ "fillColor": "rgba(31, 120, 193, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "tableColumn": "",
+ "targets": [
+ {
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "device_name"
+ ],
+ "type": "tag"
+ }
+ ],
+ "measurement": "uap_radios",
+ "orderByTime": "ASC",
+ "policy": "default",
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "tx_power"
+ ],
+ "type": "field"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "device_name",
+ "operator": "=~",
+ "value": "/^$host$/"
+ },
+ {
+ "condition": "AND",
+ "key": "radio",
+ "operator": "=",
+ "value": "na"
+ }
+ ]
+ }
+ ],
+ "thresholds": "10,18",
+ "title": "5Ghz Radio Tx Power",
+ "transparent": false,
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [],
+ "valueName": "current"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": true,
+ "colors": [
+ "#299c46",
+ "rgba(237, 129, 40, 0.89)",
+ "#d44a3a"
+ ],
+ "datasource": "${DS_UNIFI}",
+ "decimals": 1,
+ "format": "percent",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": true,
+ "thresholdLabels": true,
+ "thresholdMarkers": true
+ },
+ "gridPos": {
+ "h": 4,
+ "w": 4,
+ "x": 8,
+ "y": 6
+ },
+ "hideTimeOverride": true,
+ "id": 30,
+ "interval": null,
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "tableColumn": "system_uptime",
+ "targets": [
+ {
+ "groupBy": [
+ {
+ "params": [
+ "name"
+ ],
+ "type": "tag"
+ }
+ ],
+ "measurement": "uap",
+ "orderByTime": "ASC",
+ "policy": "default",
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "cpu"
+ ],
+ "type": "field"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "name",
+ "operator": "=~",
+ "value": "/^$host$/"
+ }
+ ]
+ }
+ ],
+ "thresholds": "40,70",
+ "timeFrom": "1h",
+ "title": "CPU Usage",
+ "type": "singlestat",
+ "valueFontSize": "70%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": false,
+ "colors": [
+ "#299c46",
+ "rgba(237, 129, 40, 0.89)",
+ "#d44a3a"
+ ],
+ "datasource": "${DS_UNIFI}",
+ "decimals": 3,
+ "format": "dtdurations",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": false,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "gridPos": {
+ "h": 4,
+ "w": 4,
+ "x": 12,
+ "y": 6
+ },
+ "id": 29,
+ "interval": null,
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "tableColumn": "system_uptime",
+ "targets": [
+ {
+ "groupBy": [
+ {
+ "params": [
+ "name"
+ ],
+ "type": "tag"
+ }
+ ],
+ "measurement": "uap",
+ "orderByTime": "ASC",
+ "policy": "default",
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "uptime"
+ ],
+ "type": "field"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "name",
+ "operator": "=~",
+ "value": "/^$host$/"
+ }
+ ]
+ }
+ ],
+ "thresholds": "",
+ "title": "System Uptime",
+ "type": "singlestat",
+ "valueFontSize": "70%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": false,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "datasource": "${DS_UNIFI}",
+ "editable": true,
+ "error": false,
+ "format": "none",
+ "gauge": {
+ "maxValue": 25,
+ "minValue": 6,
+ "show": true,
+ "thresholdLabels": false,
+ "thresholdMarkers": false
+ },
+ "gridPos": {
+ "h": 4,
+ "w": 4,
+ "x": 16,
+ "y": 6
+ },
+ "id": 12,
+ "interval": null,
+ "isNew": true,
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": " dBm",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "tableColumn": "",
+ "targets": [
+ {
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "device_name"
+ ],
+ "type": "tag"
+ }
+ ],
+ "measurement": "uap_radios",
+ "orderByTime": "ASC",
+ "policy": "default",
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "tx_power"
+ ],
+ "type": "field"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "radio",
+ "operator": "=",
+ "value": "ng"
+ },
+ {
+ "condition": "AND",
+ "key": "device_name",
+ "operator": "=~",
+ "value": "/^$host$/"
+ }
+ ]
+ }
+ ],
+ "thresholds": "10,18",
+ "title": "2.4GHz Radio Tx Power",
+ "transparent": false,
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": false,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "datasource": "${DS_UNIFI}",
+ "editable": true,
+ "error": false,
+ "format": "none",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": false,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "gridPos": {
+ "h": 4,
+ "w": 4,
+ "x": 20,
+ "y": 6
+ },
+ "id": 10,
+ "interval": null,
+ "isNew": true,
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "tableColumn": "",
+ "targets": [
+ {
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "device_name"
+ ],
+ "type": "tag"
+ }
+ ],
+ "measurement": "uap_radios",
+ "orderByTime": "ASC",
+ "policy": "default",
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "channel"
+ ],
+ "type": "field"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "device_name",
+ "operator": "=~",
+ "value": "/^$host$/"
+ },
+ {
+ "condition": "AND",
+ "key": "radio",
+ "operator": "=",
+ "value": "ng"
+ }
+ ]
+ }
+ ],
+ "thresholds": "",
+ "title": "2.4GHz Radio Channel",
+ "transparent": false,
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [],
+ "valueName": "current"
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_UNIFI}",
+ "editable": true,
+ "error": false,
+ "fill": 0,
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 0,
+ "y": 10
+ },
+ "id": 3,
+ "isNew": true,
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": true,
+ "max": true,
+ "min": true,
+ "show": true,
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 2,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "alias": "$tag_name $col",
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "name"
+ ],
+ "type": "tag"
+ }
+ ],
+ "measurement": "uap",
+ "orderByTime": "ASC",
+ "policy": "default",
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "loadavg_1"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [
+ "load 1"
+ ],
+ "type": "alias"
+ }
+ ],
+ [
+ {
+ "params": [
+ "loadavg_5"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [
+ "laid 5"
+ ],
+ "type": "alias"
+ }
+ ],
+ [
+ {
+ "params": [
+ "loadavg_15"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [
+ "load15"
+ ],
+ "type": "alias"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "name",
+ "operator": "=~",
+ "value": "/^$host$/"
+ }
+ ]
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Load Average",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 0,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "none",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_UNIFI}",
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 12,
+ "y": 10
+ },
+ "id": 7,
+ "isNew": true,
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": true,
+ "max": true,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 2,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "alias": "$tag_name $col",
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "name"
+ ],
+ "type": "tag"
+ }
+ ],
+ "measurement": "uap",
+ "orderByTime": "ASC",
+ "policy": "default",
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "mem_buffer"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [
+ "Buffer"
+ ],
+ "type": "alias"
+ }
+ ],
+ [
+ {
+ "params": [
+ "mem_used"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [
+ "Used"
+ ],
+ "type": "alias"
+ }
+ ],
+ [
+ {
+ "params": [
+ "mem_total"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [
+ "Total"
+ ],
+ "type": "alias"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "name",
+ "operator": "=~",
+ "value": "/^$host$/"
+ }
+ ]
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Memory",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "decbytes",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_UNIFI}",
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 0,
+ "y": 18
+ },
+ "id": 18,
+ "isNew": true,
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": true,
+ "max": true,
+ "min": true,
+ "show": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "alias": "$tag_device_name",
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "$interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "device_name"
+ ],
+ "type": "tag"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "measurement": "uap_radios",
+ "orderByTime": "ASC",
+ "policy": "default",
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "ccq"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ " / 10"
+ ],
+ "type": "math"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "device_name",
+ "operator": "=~",
+ "value": "/^$host$/"
+ }
+ ]
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Client Connection Quality",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 0,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "percent",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_UNIFI}",
+ "decimals": 0,
+ "editable": true,
+ "error": false,
+ "fill": 2,
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 12,
+ "y": 18
+ },
+ "id": 19,
+ "isNew": true,
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": true,
+ "hideEmpty": true,
+ "hideZero": true,
+ "max": true,
+ "min": true,
+ "rightSide": true,
+ "show": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "stack": true,
+ "steppedLine": false,
+ "targets": [
+ {
+ "alias": "$tag_device_name 5GHz",
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "$__interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "device_name"
+ ],
+ "type": "tag"
+ }
+ ],
+ "measurement": "uap_radios",
+ "orderByTime": "ASC",
+ "policy": "default",
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "num_sta"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "device_name",
+ "operator": "=~",
+ "value": "/^$host$/"
+ },
+ {
+ "condition": "AND",
+ "key": "radio",
+ "operator": "=",
+ "value": "na"
+ }
+ ]
+ },
+ {
+ "alias": "$tag_device_name 2.4GHz",
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "$__interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "device_name"
+ ],
+ "type": "tag"
+ }
+ ],
+ "measurement": "uap_radios",
+ "orderByTime": "ASC",
+ "policy": "default",
+ "refId": "B",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "num_sta"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "device_name",
+ "operator": "=~",
+ "value": "/^$host$/"
+ },
+ {
+ "condition": "AND",
+ "key": "radio",
+ "operator": "=",
+ "value": "ng"
+ }
+ ]
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Clients",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "none",
+ "label": "",
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_UNIFI}",
+ "editable": true,
+ "error": false,
+ "fill": 0,
+ "gridPos": {
+ "h": 7,
+ "w": 12,
+ "x": 0,
+ "y": 26
+ },
+ "id": 8,
+ "isNew": true,
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": true,
+ "max": true,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 3,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "alias": "$tag_device_name:$col",
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "$interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "device_name"
+ ],
+ "type": "tag"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "measurement": "uap_radios",
+ "orderByTime": "ASC",
+ "policy": "default",
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "cu_self_rx"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "Rx"
+ ],
+ "type": "alias"
+ }
+ ],
+ [
+ {
+ "params": [
+ "cu_self_tx"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "Tx"
+ ],
+ "type": "alias"
+ }
+ ],
+ [
+ {
+ "params": [
+ "cu_total"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "Total"
+ ],
+ "type": "alias"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "device_name",
+ "operator": "=~",
+ "value": "/^$host$/"
+ },
+ {
+ "condition": "AND",
+ "key": "radio",
+ "operator": "=",
+ "value": "na"
+ }
+ ]
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "5 GHz Channel Utilization",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 0,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "decimals": 1,
+ "format": "percent",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": "0",
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_UNIFI}",
+ "editable": true,
+ "error": false,
+ "fill": 0,
+ "gridPos": {
+ "h": 7,
+ "w": 12,
+ "x": 12,
+ "y": 26
+ },
+ "id": 27,
+ "isNew": true,
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": true,
+ "max": true,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 3,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "alias": "$tag_device_name:$col",
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "$interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "device_name"
+ ],
+ "type": "tag"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "measurement": "uap_radios",
+ "orderByTime": "ASC",
+ "policy": "default",
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "cu_self_rx"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "Rx"
+ ],
+ "type": "alias"
+ }
+ ],
+ [
+ {
+ "params": [
+ "cu_self_tx"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "Tx"
+ ],
+ "type": "alias"
+ }
+ ],
+ [
+ {
+ "params": [
+ "cu_total"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "Total"
+ ],
+ "type": "alias"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "device_name",
+ "operator": "=~",
+ "value": "/^$host$/"
+ },
+ {
+ "condition": "AND",
+ "key": "radio",
+ "operator": "=",
+ "value": "ng"
+ }
+ ]
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "2.4GHz Channel Utilization",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 2,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "percent",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_UNIFI}",
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "gridPos": {
+ "h": 7,
+ "w": 12,
+ "x": 0,
+ "y": 33
+ },
+ "id": 20,
+ "isNew": true,
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": true,
+ "max": true,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sort": "current",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [
+ {
+ "alias": "/:Rx$/",
+ "transform": "negative-Y"
+ }
+ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "alias": "$tag_device_name:$col",
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "30s"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "device_name"
+ ],
+ "type": "tag"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "measurement": "uap_radios",
+ "orderByTime": "ASC",
+ "policy": "default",
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "rx_bytes"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "1s"
+ ],
+ "type": "derivative"
+ },
+ {
+ "params": [
+ "*8"
+ ],
+ "type": "math"
+ },
+ {
+ "params": [
+ "Rx"
+ ],
+ "type": "alias"
+ }
+ ],
+ [
+ {
+ "params": [
+ "tx_bytes"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "1s"
+ ],
+ "type": "derivative"
+ },
+ {
+ "params": [
+ "*8"
+ ],
+ "type": "math"
+ },
+ {
+ "params": [
+ "Tx"
+ ],
+ "type": "alias"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "device_name",
+ "operator": "=~",
+ "value": "/^$host$/"
+ },
+ {
+ "condition": "AND",
+ "key": "radio",
+ "operator": "=",
+ "value": "na"
+ }
+ ]
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "5 GHz Traffic",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 2,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "bps",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "pps",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_UNIFI}",
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "gridPos": {
+ "h": 7,
+ "w": 12,
+ "x": 12,
+ "y": 33
+ },
+ "id": 24,
+ "isNew": true,
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": true,
+ "max": true,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sort": "current",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [
+ {
+ "alias": "/:Rx$/",
+ "transform": "negative-Y"
+ }
+ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "alias": "$tag_device_name:$col",
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "30s"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "device_name"
+ ],
+ "type": "tag"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "measurement": "uap_radios",
+ "orderByTime": "ASC",
+ "policy": "default",
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "rx_bytes"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "1s"
+ ],
+ "type": "derivative"
+ },
+ {
+ "params": [
+ "*8"
+ ],
+ "type": "math"
+ },
+ {
+ "params": [
+ "Rx"
+ ],
+ "type": "alias"
+ }
+ ],
+ [
+ {
+ "params": [
+ "tx_bytes"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "1s"
+ ],
+ "type": "derivative"
+ },
+ {
+ "params": [
+ "*8"
+ ],
+ "type": "math"
+ },
+ {
+ "params": [
+ "Tx"
+ ],
+ "type": "alias"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "device_name",
+ "operator": "=~",
+ "value": "/^$host$/"
+ },
+ {
+ "condition": "AND",
+ "key": "radio",
+ "operator": "=",
+ "value": "ng"
+ }
+ ]
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "2.4GHz Traffic",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 2,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "bps",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "pps",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_UNIFI}",
+ "decimals": 0,
+ "description": "PPS on the na band calculated in 30 second buckets.",
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "gridPos": {
+ "h": 7,
+ "w": 12,
+ "x": 0,
+ "y": 40
+ },
+ "id": 22,
+ "isNew": true,
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": true,
+ "max": true,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [
+ {
+ "alias": "/:In$/",
+ "transform": "negative-Y"
+ }
+ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "alias": "$tag_device_name:$col",
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "30s"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "device_name"
+ ],
+ "type": "tag"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "measurement": "uap_radios",
+ "orderByTime": "ASC",
+ "policy": "default",
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "rx_packets"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "1s"
+ ],
+ "type": "derivative"
+ },
+ {
+ "params": [
+ "In"
+ ],
+ "type": "alias"
+ }
+ ],
+ [
+ {
+ "params": [
+ "tx_packets"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "1s"
+ ],
+ "type": "derivative"
+ },
+ {
+ "params": [
+ "Out"
+ ],
+ "type": "alias"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "device_name",
+ "operator": "=~",
+ "value": "/^$host$/"
+ },
+ {
+ "condition": "AND",
+ "key": "radio",
+ "operator": "=",
+ "value": "na"
+ }
+ ]
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "5 GHz Packets",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 2,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "decimals": 1,
+ "format": "pps",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "pps",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_UNIFI}",
+ "decimals": 0,
+ "description": "PPS on the ng band calculated in 30 second buckets.",
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "gridPos": {
+ "h": 7,
+ "w": 12,
+ "x": 12,
+ "y": 40
+ },
+ "id": 25,
+ "isNew": true,
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": true,
+ "max": true,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sort": "max",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [
+ {
+ "alias": "/:In$/",
+ "transform": "negative-Y"
+ }
+ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "alias": "$tag_device_name:$col",
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "30s"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "device_name"
+ ],
+ "type": "tag"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "measurement": "uap_radios",
+ "orderByTime": "ASC",
+ "policy": "default",
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "rx_packets"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "1s"
+ ],
+ "type": "derivative"
+ },
+ {
+ "params": [
+ "In"
+ ],
+ "type": "alias"
+ }
+ ],
+ [
+ {
+ "params": [
+ "tx_packets"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "1s"
+ ],
+ "type": "derivative"
+ },
+ {
+ "params": [
+ "Out"
+ ],
+ "type": "alias"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "device_name",
+ "operator": "=~",
+ "value": "/^$host$/"
+ },
+ {
+ "condition": "AND",
+ "key": "radio",
+ "operator": "=",
+ "value": "ng"
+ }
+ ]
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "2.4GHz Packets",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 2,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "decimals": 1,
+ "format": "pps",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "pps",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_UNIFI}",
+ "decimals": 0,
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "gridPos": {
+ "h": 7,
+ "w": 12,
+ "x": 0,
+ "y": 47
+ },
+ "id": 21,
+ "isNew": true,
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": true,
+ "max": true,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sort": "max",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [
+ {
+ "alias": "/:In$/",
+ "transform": "negative-Y"
+ }
+ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "alias": "$tag_device_name:$col",
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "30s"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "radio"
+ ],
+ "type": "tag"
+ },
+ {
+ "params": [
+ "device_name"
+ ],
+ "type": "tag"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "measurement": "uap_radios",
+ "orderByTime": "ASC",
+ "policy": "default",
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "rx_dropped"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "1s"
+ ],
+ "type": "derivative"
+ },
+ {
+ "params": [
+ "Drop:In"
+ ],
+ "type": "alias"
+ }
+ ],
+ [
+ {
+ "params": [
+ "tx_dropped"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "1s"
+ ],
+ "type": "derivative"
+ },
+ {
+ "params": [
+ "Drop:Out"
+ ],
+ "type": "alias"
+ }
+ ],
+ [
+ {
+ "params": [
+ "rx_errors"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "1s"
+ ],
+ "type": "derivative"
+ },
+ {
+ "params": [
+ "Error:In"
+ ],
+ "type": "alias"
+ }
+ ],
+ [
+ {
+ "params": [
+ "tx_errors"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "1s"
+ ],
+ "type": "derivative"
+ },
+ {
+ "params": [
+ "Error:Out"
+ ],
+ "type": "alias"
+ }
+ ],
+ [
+ {
+ "params": [
+ "rx_crypts"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "1s"
+ ],
+ "type": "derivative"
+ },
+ {
+ "params": [
+ "BadCrypt:In"
+ ],
+ "type": "alias"
+ }
+ ],
+ [
+ {
+ "params": [
+ "rx_frags"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "1s"
+ ],
+ "type": "derivative"
+ },
+ {
+ "params": [
+ "BadFrag:In"
+ ],
+ "type": "alias"
+ }
+ ],
+ [
+ {
+ "params": [
+ "tx_retries"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "1s"
+ ],
+ "type": "derivative"
+ },
+ {
+ "params": [
+ "ExsRetry:Out"
+ ],
+ "type": "alias"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "device_name",
+ "operator": "=~",
+ "value": "/^$host$/"
+ },
+ {
+ "condition": "AND",
+ "key": "radio",
+ "operator": "=",
+ "value": "na"
+ }
+ ]
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "5GHz Drops/Errors",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 0,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "decimals": 1,
+ "format": "pps",
+ "label": "",
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_UNIFI}",
+ "decimals": 0,
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "gridPos": {
+ "h": 7,
+ "w": 12,
+ "x": 12,
+ "y": 47
+ },
+ "id": 26,
+ "isNew": true,
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": true,
+ "max": true,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sort": null,
+ "sortDesc": null,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [
+ {
+ "alias": "/:In$/",
+ "transform": "negative-Y"
+ }
+ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "alias": "$tag_device_name:$col",
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "30s"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "device_name"
+ ],
+ "type": "tag"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "measurement": "uap_radios",
+ "orderByTime": "ASC",
+ "policy": "default",
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "rx_dropped"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "1s"
+ ],
+ "type": "derivative"
+ },
+ {
+ "params": [
+ "Drop:In"
+ ],
+ "type": "alias"
+ }
+ ],
+ [
+ {
+ "params": [
+ "tx_dropped"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "1s"
+ ],
+ "type": "derivative"
+ },
+ {
+ "params": [
+ "Drop:Out"
+ ],
+ "type": "alias"
+ }
+ ],
+ [
+ {
+ "params": [
+ "rx_errors"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "1s"
+ ],
+ "type": "derivative"
+ },
+ {
+ "params": [
+ "Error:In"
+ ],
+ "type": "alias"
+ }
+ ],
+ [
+ {
+ "params": [
+ "tx_errors"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "1s"
+ ],
+ "type": "derivative"
+ },
+ {
+ "params": [
+ "Error:Out"
+ ],
+ "type": "alias"
+ }
+ ],
+ [
+ {
+ "params": [
+ "rx_crypts"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "1s"
+ ],
+ "type": "derivative"
+ },
+ {
+ "params": [
+ "BadCrypt:In"
+ ],
+ "type": "alias"
+ }
+ ],
+ [
+ {
+ "params": [
+ "rx_frags"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "1s"
+ ],
+ "type": "derivative"
+ },
+ {
+ "params": [
+ "BadFrag:In"
+ ],
+ "type": "alias"
+ }
+ ],
+ [
+ {
+ "params": [
+ "tx_retries"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ },
+ {
+ "params": [
+ "1s"
+ ],
+ "type": "derivative"
+ },
+ {
+ "params": [
+ "ExsRetry:Out"
+ ],
+ "type": "alias"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "device_name",
+ "operator": "=~",
+ "value": "/^$host$/"
+ },
+ {
+ "condition": "AND",
+ "key": "radio",
+ "operator": "=",
+ "value": "ng"
+ }
+ ]
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "2.4GHz Drops/Errors",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 0,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "decimals": 1,
+ "format": "pps",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "refresh": "30s",
+ "schemaVersion": 16,
+ "style": "dark",
+ "tags": [],
+ "templating": {
+ "list": [
+ {
+ "current": {
+ "selected": true,
+ "text": "Glances",
+ "value": "Glances"
+ },
+ "hide": 2,
+ "label": null,
+ "name": "dataSource",
+ "options": [],
+ "query": "influxdb",
+ "refresh": 1,
+ "regex": "",
+ "type": "datasource"
+ },
+ {
+ "allValue": null,
+ "current": {},
+ "datasource": "${DS_UNIFI}",
+ "hide": 0,
+ "includeAll": true,
+ "label": "UniFi AP:",
+ "multi": true,
+ "name": "host",
+ "options": [],
+ "query": "show tag values from \"uap\" with key=\"name\"",
+ "refresh": 1,
+ "regex": "",
+ "sort": 0,
+ "tagValuesQuery": null,
+ "tags": [],
+ "tagsQuery": null,
+ "type": "query",
+ "useTags": false
+ }
+ ]
+ },
+ "time": {
+ "from": "now-2h",
+ "to": "now"
+ },
+ "timepicker": {
+ "nowDelay": "5s",
+ "refresh_intervals": [
+ "30s",
+ "1m",
+ "5m",
+ "15m",
+ "30m",
+ "1h",
+ "2h"
+ ],
+ "time_options": [
+ "5m",
+ "15m",
+ "1h",
+ "6h",
+ "12h",
+ "24h",
+ "2d",
+ "7d",
+ "30d"
+ ]
+ },
+ "timezone": "browser",
+ "title": "UniFi UAP Insights",
+ "uid": "8nQ_RPZiz",
+ "version": 28
+}
diff --git a/integrations/inputunifi/grafana-unifi-dashboard.png b/integrations/inputunifi/images/unifi-clients-dashboard.png
similarity index 100%
rename from integrations/inputunifi/grafana-unifi-dashboard.png
rename to integrations/inputunifi/images/unifi-clients-dashboard.png
diff --git a/integrations/inputunifi/images/unifi-uap-dashboard.png b/integrations/inputunifi/images/unifi-uap-dashboard.png
new file mode 100644
index 00000000..8c63867b
Binary files /dev/null and b/integrations/inputunifi/images/unifi-uap-dashboard.png differ
diff --git a/integrations/inputunifi/unidev/clients.go b/integrations/inputunifi/unidev/clients.go
index 3e58af58..f4694537 100644
--- a/integrations/inputunifi/unidev/clients.go
+++ b/integrations/inputunifi/unidev/clients.go
@@ -7,8 +7,9 @@ import (
influx "github.com/influxdata/influxdb/client/v2"
)
-// Point generates a client's datapoint for InfluxDB.
-func (u UCL) Point() (*influx.Point, error) {
+// Points generates a client's datapoints for InfluxDB.
+func (u UCL) Points() ([]*influx.Point, error) {
+ var points []*influx.Point
if u.Name == "" && u.Hostname != "" {
u.Name = u.Hostname
} else if u.Hostname == "" && u.Name != "" {
@@ -95,6 +96,9 @@ func (u UCL) Point() (*influx.Point, error) {
"wired-tx_bytes-r": u.WiredTxBytesR,
"wired-tx_packets": u.WiredTxPackets,
}
-
- return influx.NewPoint("clients", tags, fields, time.Now())
+ pt, err := influx.NewPoint("clients", tags, fields, time.Now())
+ if err == nil {
+ points = append(points, pt)
+ }
+ return points, err
}
diff --git a/integrations/inputunifi/unidev/uap.go b/integrations/inputunifi/unidev/uap.go
index 9e2847c1..af7c2986 100644
--- a/integrations/inputunifi/unidev/uap.go
+++ b/integrations/inputunifi/unidev/uap.go
@@ -7,8 +7,12 @@ import (
influx "github.com/influxdata/influxdb/client/v2"
)
-// Point generates a device's datapoint for InfluxDB.
-func (u UAP) Point() (*influx.Point, error) {
+// Points generates a device's datapoints for InfluxDB.
+func (u UAP) Points() ([]*influx.Point, error) {
+ /* I generally suck at InfluxDB, so if I got the tags/fields wrong,
+ please send me a PR or open an Issue to address my faults. Thanks!
+ */
+ var points []*influx.Point
tags := map[string]string{
"id": u.ID,
"mac": u.Mac,
@@ -35,7 +39,7 @@ func (u UAP) Point() (*influx.Point, error) {
"has_speaker": strconv.FormatBool(u.HasSpeaker),
"inform_ip": u.InformIP,
"isolated": strconv.FormatBool(u.Isolated),
- "last_seen": strconv.Itoa(u.LastSeen),
+ "last_seen": strconv.FormatFloat(u.LastSeen, 'f', 6, 64),
"last_uplink_mac": u.LastUplink.UplinkMac,
"last_uplink_remote_port": strconv.Itoa(u.LastUplink.UplinkRemotePort),
"known_cfgversion": u.KnownCfgversion,
@@ -74,6 +78,7 @@ func (u UAP) Point() (*influx.Point, error) {
"loadavg_15": u.SysStats.Loadavg15,
"mem_buffer": u.SysStats.MemBuffer,
"mem_total": u.SysStats.MemTotal,
+ "mem_used": u.SysStats.MemUsed,
"cpu": u.SystemStats.CPU,
"mem": u.SystemStats.Mem,
"system_uptime": u.SystemStats.Uptime,
@@ -165,5 +170,98 @@ func (u UAP) Point() (*influx.Point, error) {
"stat_wifi1-tx_packets": u.Stat.Wifi1TxPackets,
"stat_wifi1-tx_retries": u.Stat.Wifi1TxRetries,
}
- return influx.NewPoint("uap", tags, fields, time.Now())
+ pt, err := influx.NewPoint("uap", tags, fields, time.Now())
+ if err != nil {
+ return nil, err
+ }
+ points = append(points, pt)
+ for _, p := range u.RadioTable {
+ tags := map[string]string{
+ "device_name": u.Name,
+ "device_id": u.ID,
+ "device_mac": u.Mac,
+ "name": p.Name,
+ "wlangroup_id": p.WlangroupID,
+ "channel": p.Channel, // not the channel #
+ "radio": p.Radio,
+ }
+ fields := map[string]interface{}{
+ "builtin_ant_gain": p.BuiltinAntGain,
+ "current_antenna_gain": p.CurrentAntennaGain,
+ "has_dfs": p.HasDfs,
+ "has_fccdfs": p.HasFccdfs,
+ "ht": p.Ht,
+ "is_11ac": p.Is11Ac,
+ "max_txpower": p.MaxTxpower,
+ "min_rssi_enabled": p.MinRssiEnabled,
+ "min_txpower": p.MinTxpower,
+ "nss": p.Nss,
+ "radio_caps": p.RadioCaps,
+ "tx_power": p.TxPower,
+ "tx_power_mode": p.TxPowerMode,
+ }
+
+ for _, s := range u.RadioTableStats {
+ // This may be a tad slower but it allows putting
+ // all the radio stats into one table.
+ if p.Name == s.Name {
+ fields["ast_be_xmit"] = s.AstBeXmit
+ fields["ast_cst"] = s.AstCst
+ fields["channel"] = s.Channel
+ fields["ast_txto"] = s.AstTxto
+ fields["cu_self_rx"] = s.CuSelfRx
+ fields["cu_self_tx"] = s.CuSelfTx
+ fields["cu_total"] = s.CuTotal
+ fields["extchannel"] = s.Extchannel
+ fields["gain"] = s.Gain
+ fields["guest-num_sta"] = s.GuestNumSta
+ fields["num_sta"] = s.NumSta
+ fields["radio"] = s.Radio
+ fields["state"] = s.State
+ fields["radio_tx_packets"] = s.TxPackets
+ fields["radio_tx_power"] = s.TxPower
+ fields["radio_tx_retries"] = s.TxRetries
+ fields["user-num_sta"] = s.UserNumSta
+ }
+ }
+ for _, s := range u.VapTable {
+ if p.Name == s.RadioName {
+ tags["ap_mac"] = s.ApMac
+ tags["bssid"] = s.Bssid
+ fields["ccq"] = s.Ccq
+ fields["essid"] = s.Essid
+ fields["extchannel"] = s.Extchannel
+ tags["vap_id"] = s.ID
+ fields["is_guest"] = s.IsGuest
+ fields["is_wep"] = s.IsWep
+ fields["mac_filter_rejections"] = s.MacFilterRejections
+ fields["map_id"] = s.MapID
+ tags["vap_name"] = s.Name
+ fields["rx_bytes"] = s.RxBytes
+ fields["rx_crypts"] = s.RxCrypts
+ fields["rx_dropped"] = s.RxDropped
+ fields["rx_errors"] = s.RxErrors
+ fields["rx_frags"] = s.RxFrags
+ fields["rx_nwids"] = s.RxNwids
+ fields["rx_packets"] = s.RxPackets
+ fields["tx_bytes"] = s.TxBytes
+ fields["tx_dropped"] = s.TxDropped
+ fields["tx_errors"] = s.TxErrors
+ fields["tx_latency_avg"] = s.TxLatencyAvg
+ fields["tx_latency_max"] = s.TxLatencyMax
+ fields["tx_latency_min"] = s.TxLatencyMin
+ fields["tx_packets"] = s.TxPackets
+ fields["tx_power"] = s.TxPower
+ fields["tx_retries"] = s.TxRetries
+ fields["usage"] = s.Usage
+ tags["wlanconf_id"] = s.WlanconfID
+ }
+ }
+ pt, err := influx.NewPoint("uap_radios", tags, fields, time.Now())
+ if err != nil {
+ return points, err
+ }
+ points = append(points, pt)
+ }
+ return points, nil
}
diff --git a/integrations/inputunifi/unidev/uap_type.go b/integrations/inputunifi/unidev/uap_type.go
index d2f6a55a..30d1d3f2 100644
--- a/integrations/inputunifi/unidev/uap_type.go
+++ b/integrations/inputunifi/unidev/uap_type.go
@@ -1,7 +1,12 @@
package unidev
-// UAP is a Unifi Access Point
+// UAP is a Unifi Access Point.
type UAP struct {
+ /* This was auto generated and then slowly edited by hand
+ to get all the data types right and graphable.
+ No ones feelings will be hurt if you want to break this
+ up into multiple structs, and/or make it better in general.
+ */
ID string `json:"_id"`
UUptime float64 `json:"_uptime"`
AdoptIP string `json:"adopt_ip,omitempty"`
@@ -36,17 +41,17 @@ type UAP struct {
Name string `json:"name"`
NumPort float64 `json:"num_port"`
} `json:"ethernet_table"`
- FwCaps int `json:"fw_caps"`
- GuestNumSta int `json:"guest-num_sta"`
- GuestToken string `json:"guest_token"`
- HasEth1 bool `json:"has_eth1"`
- HasSpeaker bool `json:"has_speaker"`
- InformIP string `json:"inform_ip"`
- InformURL string `json:"inform_url"`
- IP string `json:"ip"`
- Isolated bool `json:"isolated"`
- KnownCfgversion string `json:"known_cfgversion"`
- LastSeen int `json:"last_seen"`
+ FwCaps int `json:"fw_caps"`
+ GuestNumSta int `json:"guest-num_sta"`
+ GuestToken string `json:"guest_token"`
+ HasEth1 bool `json:"has_eth1"`
+ HasSpeaker bool `json:"has_speaker"`
+ InformIP string `json:"inform_ip"`
+ InformURL string `json:"inform_url"`
+ IP string `json:"ip"`
+ Isolated bool `json:"isolated"`
+ KnownCfgversion string `json:"known_cfgversion"`
+ LastSeen float64 `json:"last_seen"`
LastUplink struct {
UplinkMac string `json:"uplink_mac"`
UplinkRemotePort int `json:"uplink_remote_port"`
@@ -132,28 +137,28 @@ type UAP struct {
Is11Ac bool `json:"is_11ac,omitempty"`
} `json:"radio_table"`
RadioTableStats []struct {
- AstBeXmit interface{} `json:"ast_be_xmit"`
- AstCst interface{} `json:"ast_cst"`
- AstTxto interface{} `json:"ast_txto"`
- Channel float64 `json:"channel"`
- CuSelfRx float64 `json:"cu_self_rx"`
- CuSelfTx float64 `json:"cu_self_tx"`
- CuTotal float64 `json:"cu_total"`
- Extchannel float64 `json:"extchannel"`
- Gain float64 `json:"gain"`
- GuestNumSta float64 `json:"guest-num_sta"`
- Name string `json:"name"`
- NumSta float64 `json:"num_sta"`
- Radio string `json:"radio"`
- State string `json:"state"`
- TxPackets float64 `json:"tx_packets"`
- TxPower float64 `json:"tx_power"`
- TxRetries float64 `json:"tx_retries"`
- UserNumSta float64 `json:"user-num_sta"`
+ AstBeXmit float64 `json:"ast_be_xmit"`
+ AstCst float64 `json:"ast_cst"`
+ AstTxto float64 `json:"ast_txto"`
+ Channel float64 `json:"channel"`
+ CuSelfRx float64 `json:"cu_self_rx"`
+ CuSelfTx float64 `json:"cu_self_tx"`
+ CuTotal float64 `json:"cu_total"`
+ Extchannel float64 `json:"extchannel"`
+ Gain float64 `json:"gain"`
+ GuestNumSta float64 `json:"guest-num_sta"`
+ Name string `json:"name"`
+ NumSta float64 `json:"num_sta"`
+ Radio string `json:"radio"`
+ State string `json:"state"`
+ TxPackets float64 `json:"tx_packets"`
+ TxPower float64 `json:"tx_power"`
+ TxRetries float64 `json:"tx_retries"`
+ UserNumSta float64 `json:"user-num_sta"`
} `json:"radio_table_stats"`
Rollupgrade bool `json:"rollupgrade"`
- RxBytes int `json:"rx_bytes"`
- RxBytesD int `json:"rx_bytes-d"`
+ RxBytes float64 `json:"rx_bytes"`
+ RxBytesD float64 `json:"rx_bytes-d"`
ScanRadioTable []interface{} `json:"scan_radio_table"`
Scanning bool `json:"scanning"`
Serial string `json:"serial"`
@@ -257,20 +262,20 @@ type UAP struct {
} `json:"stat"`
State int `json:"state"`
SysStats struct {
- Loadavg1 string `json:"loadavg_1"`
- Loadavg15 string `json:"loadavg_15"`
- Loadavg5 string `json:"loadavg_5"`
- MemBuffer int `json:"mem_buffer"`
- MemTotal int `json:"mem_total"`
- MemUsed int `json:"mem_used"`
+ Loadavg1 float64 `json:"loadavg_1,string"`
+ Loadavg15 float64 `json:"loadavg_15,string"`
+ Loadavg5 float64 `json:"loadavg_5,string"`
+ MemBuffer float64 `json:"mem_buffer"`
+ MemTotal float64 `json:"mem_total"`
+ MemUsed float64 `json:"mem_used"`
} `json:"sys_stats"`
SystemStats struct {
- CPU string `json:"cpu"`
- Mem string `json:"mem"`
- Uptime string `json:"uptime"`
+ CPU float64 `json:"cpu,string"`
+ Mem float64 `json:"mem,string"`
+ Uptime float64 `json:"uptime,string"`
} `json:"system-stats"`
TxBytes float64 `json:"tx_bytes"`
- TxBytesD int `json:"tx_bytes-d"`
+ TxBytesD float64 `json:"tx_bytes-d"`
Type string `json:"type"`
Upgradable bool `json:"upgradable"`
Uplink struct {
@@ -284,63 +289,63 @@ type UAP struct {
Netmask string `json:"netmask"`
NumPort int `json:"num_port"`
RxBytes float64 `json:"rx_bytes"`
- RxBytesR int `json:"rx_bytes-r"`
- RxDropped int `json:"rx_dropped"`
- RxErrors int `json:"rx_errors"`
- RxMulticast int `json:"rx_multicast"`
- RxPackets int `json:"rx_packets"`
- Speed int `json:"speed"`
+ RxBytesR float64 `json:"rx_bytes-r"`
+ RxDropped float64 `json:"rx_dropped"`
+ RxErrors float64 `json:"rx_errors"`
+ RxMulticast float64 `json:"rx_multicast"`
+ RxPackets float64 `json:"rx_packets"`
+ Speed float64 `json:"speed"`
TxBytes float64 `json:"tx_bytes"`
- TxBytesR int `json:"tx_bytes-r"`
- TxDropped int `json:"tx_dropped"`
- TxErrors int `json:"tx_errors"`
- TxPackets int `json:"tx_packets"`
+ TxBytesR float64 `json:"tx_bytes-r"`
+ TxDropped float64 `json:"tx_dropped"`
+ TxErrors float64 `json:"tx_errors"`
+ TxPackets float64 `json:"tx_packets"`
Type string `json:"type"`
Up bool `json:"up"`
UplinkMac string `json:"uplink_mac"`
UplinkRemotePort int `json:"uplink_remote_port"`
} `json:"uplink"`
UplinkTable []interface{} `json:"uplink_table"`
- Uptime int `json:"uptime"`
+ Uptime float64 `json:"uptime"`
UserNumSta int `json:"user-num_sta"`
VapTable []struct {
- ApMac string `json:"ap_mac"`
- Bssid string `json:"bssid"`
- Ccq int `json:"ccq"`
- Channel int `json:"channel"`
- Essid string `json:"essid"`
- Extchannel int `json:"extchannel"`
- ID string `json:"id"`
- IsGuest bool `json:"is_guest"`
- IsWep bool `json:"is_wep"`
- MacFilterRejections int `json:"mac_filter_rejections"`
- MapID interface{} `json:"map_id"`
- Name string `json:"name"`
- NumSta int `json:"num_sta"`
- Radio string `json:"radio"`
- RadioName string `json:"radio_name"`
- RxBytes int `json:"rx_bytes"`
- RxCrypts int `json:"rx_crypts"`
- RxDropped int `json:"rx_dropped"`
- RxErrors int `json:"rx_errors"`
- RxFrags int `json:"rx_frags"`
- RxNwids int `json:"rx_nwids"`
- RxPackets int `json:"rx_packets"`
- SiteID string `json:"site_id"`
- State string `json:"state"`
- T string `json:"t"`
- TxBytes int `json:"tx_bytes"`
- TxDropped int `json:"tx_dropped"`
- TxErrors int `json:"tx_errors"`
- TxLatencyAvg float64 `json:"tx_latency_avg"`
- TxLatencyMax float64 `json:"tx_latency_max"`
- TxLatencyMin float64 `json:"tx_latency_min"`
- TxPackets int `json:"tx_packets"`
- TxPower int `json:"tx_power"`
- TxRetries int `json:"tx_retries"`
- Up bool `json:"up"`
- Usage string `json:"usage"`
- WlanconfID string `json:"wlanconf_id"`
+ ApMac string `json:"ap_mac"`
+ Bssid string `json:"bssid"`
+ Ccq int `json:"ccq"`
+ Channel int `json:"channel"`
+ Essid string `json:"essid"`
+ Extchannel int `json:"extchannel"`
+ ID string `json:"id"`
+ IsGuest bool `json:"is_guest"`
+ IsWep bool `json:"is_wep"`
+ MacFilterRejections int `json:"mac_filter_rejections"`
+ MapID string `json:"map_id"`
+ Name string `json:"name"`
+ NumSta int `json:"num_sta"`
+ Radio string `json:"radio"`
+ RadioName string `json:"radio_name"`
+ RxBytes float64 `json:"rx_bytes"`
+ RxCrypts float64 `json:"rx_crypts"`
+ RxDropped float64 `json:"rx_dropped"`
+ RxErrors float64 `json:"rx_errors"`
+ RxFrags float64 `json:"rx_frags"`
+ RxNwids float64 `json:"rx_nwids"`
+ RxPackets float64 `json:"rx_packets"`
+ SiteID string `json:"site_id"`
+ State string `json:"state"`
+ T string `json:"t"`
+ TxBytes float64 `json:"tx_bytes"`
+ TxDropped float64 `json:"tx_dropped"`
+ TxErrors float64 `json:"tx_errors"`
+ TxLatencyAvg float64 `json:"tx_latency_avg"`
+ TxLatencyMax float64 `json:"tx_latency_max"`
+ TxLatencyMin float64 `json:"tx_latency_min"`
+ TxPackets float64 `json:"tx_packets"`
+ TxPower int `json:"tx_power"`
+ TxRetries int `json:"tx_retries"`
+ Up bool `json:"up"`
+ Usage string `json:"usage"`
+ WlanconfID string `json:"wlanconf_id"`
} `json:"vap_table"`
Version string `json:"version"`
VersionIncompatible bool `json:"version_incompatible"`
diff --git a/integrations/inputunifi/unidev/unidev.go b/integrations/inputunifi/unidev/unidev.go
index 324ab329..7cba8d98 100644
--- a/integrations/inputunifi/unidev/unidev.go
+++ b/integrations/inputunifi/unidev/unidev.go
@@ -13,9 +13,12 @@ import (
const LoginPath = "/api/login"
// Asset provides a common interface to retreive metrics from a device or client.
+// It currently only supports InfluxDB, but could be amended to support other
+// libraries that have a similar interface.
+// This app only uses the .AddPoint/s() methods with the Asset type.
type Asset interface {
// Point() means this is useful to influxdb..
- Point() (*influx.Point, error)
+ Points() ([]*influx.Point, error)
// Add more methods to achieve more usefulness from this library.
}
diff --git a/integrations/inputunifi/unidev/unifi.go b/integrations/inputunifi/unidev/unifi.go
index 1cdad897..8239e620 100644
--- a/integrations/inputunifi/unidev/unifi.go
+++ b/integrations/inputunifi/unidev/unifi.go
@@ -21,7 +21,7 @@ const (
)
// GetUnifiClients returns a response full of clients' data from the Unifi Controller.
-func (c *AuthedReq) GetUnifiClients() ([]Asset, error) {
+func (c *AuthedReq) GetUnifiClients() ([]UCL, error) {
var response struct {
Clients []UCL `json:"data"`
Meta struct {
@@ -34,68 +34,103 @@ func (c *AuthedReq) GetUnifiClients() ([]Asset, error) {
return nil, err
} else if body, err := ioutil.ReadAll(resp.Body); err != nil {
return nil, err
- } else if err = json.Unmarshal(body, response); err != nil {
+ } else if err = json.Unmarshal(body, &response); err != nil {
return nil, err
} else if err = resp.Body.Close(); err != nil {
log.Println("resp.Body.Close():", err) // Not fatal? Just log it.
}
- clients := []Asset{}
- for _, r := range response.Clients {
- clients = append(clients, r)
+ return response.Clients, nil
+}
+
+// GetUnifiClientAssets provides an interface to return common asset types.
+func (c *AuthedReq) GetUnifiClientAssets() ([]Asset, error) {
+ clients, err := c.GetUnifiClients()
+ assets := []Asset{}
+ if err == nil {
+ for _, r := range clients {
+ assets = append(assets, r)
+ }
}
- return clients, nil
+ return assets, err
}
// GetUnifiDevices returns a response full of devices' data from the Unifi Controller.
-func (c *AuthedReq) GetUnifiDevices() ([]Asset, error) {
+func (c *AuthedReq) GetUnifiDevices() ([]USG, []USW, []UAP, error) {
var parsed struct {
Data []json.RawMessage `json:"data"`
Meta struct {
Rc string `json:"rc"`
} `json:"meta"`
}
- assets := []Asset{}
if req, err := c.UniReq(DevicePath, ""); err != nil {
- return nil, err
+ return nil, nil, nil, err
} else if resp, err := c.Do(req); err != nil {
- return nil, err
+ return nil, nil, nil, err
} else if body, err := ioutil.ReadAll(resp.Body); err != nil {
- return nil, err
+ return nil, nil, nil, err
} else if err = json.Unmarshal(body, &parsed); err != nil {
- return nil, err
+ return nil, nil, nil, err
} else if err = resp.Body.Close(); err != nil {
log.Println("resp.Body.Close():", err) // Not fatal? Just log it.
}
+ var usgs []USG
+ var usws []USW
+ var uaps []UAP
for _, r := range parsed.Data {
+ var usg USG
+ var usw USW
+ var uap UAP
// Unamrshal into a map and check "type"
var obj map[string]interface{}
if err := json.Unmarshal(r, &obj); err != nil {
- return nil, err
+ return nil, nil, nil, err
}
- assetType := ""
+ assetType := "- missing -"
if t, ok := obj["type"].(string); ok {
assetType = t
}
+ if Debug {
+ log.Println("Unmarshalling Device Type:", assetType)
+ }
// Unmarshal again into the correct type..
- var asset Asset
switch assetType {
case "uap":
- asset = &UAP{}
- case "ugw":
- asset = &USG{}
+ if err := json.Unmarshal(r, &uap); err != nil {
+ return nil, nil, nil, err
+ }
+ uaps = append(uaps, uap)
+ case "ugw", "usg": // in case they ever fix the name in the api.
+ if err := json.Unmarshal(r, &usg); err != nil {
+ return nil, nil, nil, err
+ }
+ usgs = append(usgs, usg)
case "usw":
- asset = &USW{}
+ if err := json.Unmarshal(r, &usw); err != nil {
+ return nil, nil, nil, err
+ }
+ usws = append(usws, usw)
default:
log.Println("unknown asset type -", assetType, "- skipping")
continue
}
- if Debug {
- log.Println("Unmarshalling", assetType)
- }
- if err := json.Unmarshal(r, asset); err != nil {
- return nil, err
- }
- assets = append(assets, asset)
}
- return assets, nil
+ return usgs, usws, uaps, nil
+}
+
+// GetUnifiDeviceAssets provides an interface to return common asset types.
+func (c *AuthedReq) GetUnifiDeviceAssets() ([]Asset, error) {
+ usgs, usws, uaps, err := c.GetUnifiDevices()
+ assets := []Asset{}
+ if err == nil {
+ for _, r := range usgs {
+ assets = append(assets, r)
+ }
+ for _, r := range usws {
+ assets = append(assets, r)
+ }
+ for _, r := range uaps {
+ assets = append(assets, r)
+ }
+ }
+ return assets, err
}
diff --git a/integrations/inputunifi/unidev/usg.go b/integrations/inputunifi/unidev/usg.go
index dbad1a6c..f904f37c 100644
--- a/integrations/inputunifi/unidev/usg.go
+++ b/integrations/inputunifi/unidev/usg.go
@@ -7,8 +7,9 @@ import (
influx "github.com/influxdata/influxdb/client/v2"
)
-// Point generates a device's datapoint for InfluxDB.
-func (u USG) Point() (*influx.Point, error) {
+// Points generates a device's datapoints for InfluxDB.
+func (u USG) Points() ([]*influx.Point, error) {
+ var points []*influx.Point
tags := map[string]string{
"id": u.ID,
"mac": u.Mac,
@@ -117,5 +118,9 @@ func (u USG) Point() (*influx.Point, error) {
"wan-tx_bytes": u.Stat.WanTxBytes,
"wan-tx_packets": u.Stat.WanTxPackets,
}
- return influx.NewPoint("usg", tags, fields, time.Now())
+ pt, err := influx.NewPoint("usg", tags, fields, time.Now())
+ if err == nil {
+ points = append(points, pt)
+ }
+ return points, err
}
diff --git a/integrations/inputunifi/unidev/usw.go b/integrations/inputunifi/unidev/usw.go
index 215bbc43..bbcb1dc1 100644
--- a/integrations/inputunifi/unidev/usw.go
+++ b/integrations/inputunifi/unidev/usw.go
@@ -7,8 +7,9 @@ import (
influx "github.com/influxdata/influxdb/client/v2"
)
-// Point generates a device's datapoint for InfluxDB.
-func (u USW) Point() (*influx.Point, error) {
+// Points generates a device's datapoints for InfluxDB.
+func (u USW) Points() ([]*influx.Point, error) {
+ var points []*influx.Point
tags := map[string]string{
"id": u.ID,
"mac": u.Mac,
@@ -109,5 +110,9 @@ func (u USW) Point() (*influx.Point, error) {
"stat_tx_retries": u.Stat.TxRetries,
// Add the port stats too.
}
- return influx.NewPoint("usw", tags, fields, time.Now())
+ pt, err := influx.NewPoint("usw", tags, fields, time.Now())
+ if err == nil {
+ points = append(points, pt)
+ }
+ return points, err
}