Remove the library. Source it externally.
This commit is contained in:
		
							parent
							
								
									978ae5b0c1
								
							
						
					
					
						commit
						33e7fa71ac
					
				| 
						 | 
					@ -2,10 +2,10 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[projects]]
 | 
					[[projects]]
 | 
				
			||||||
  name = "github.com/davecgh/go-spew"
 | 
					  branch = "master"
 | 
				
			||||||
  packages = ["spew"]
 | 
					  name = "github.com/golift/unifi"
 | 
				
			||||||
  revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73"
 | 
					  packages = ["."]
 | 
				
			||||||
  version = "v1.1.1"
 | 
					  revision = "24c7eb106b3c9ff4260c88b54c02f0f86301fa75"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[projects]]
 | 
					[[projects]]
 | 
				
			||||||
  name = "github.com/influxdata/influxdb"
 | 
					  name = "github.com/influxdata/influxdb"
 | 
				
			||||||
| 
						 | 
					@ -14,17 +14,16 @@
 | 
				
			||||||
    "models",
 | 
					    "models",
 | 
				
			||||||
    "pkg/escape"
 | 
					    "pkg/escape"
 | 
				
			||||||
  ]
 | 
					  ]
 | 
				
			||||||
  revision = "76f907b0fada2f16931e37471da695349fcdf8c6"
 | 
					  revision = "698dbc789aff13c2678357a6b93ff73dd7136571"
 | 
				
			||||||
  version = "v1.7.2"
 | 
					  version = "v1.7.3"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[projects]]
 | 
					[[projects]]
 | 
				
			||||||
  branch = "master"
 | 
					 | 
				
			||||||
  name = "github.com/influxdata/platform"
 | 
					  name = "github.com/influxdata/platform"
 | 
				
			||||||
  packages = [
 | 
					  packages = [
 | 
				
			||||||
    "models",
 | 
					    "models",
 | 
				
			||||||
    "pkg/escape"
 | 
					    "pkg/escape"
 | 
				
			||||||
  ]
 | 
					  ]
 | 
				
			||||||
  revision = "98469bf07613ffae6f025893761c1e7a5e96e4aa"
 | 
					  revision = "0f79e4ea3248354c789cba274542e0a8e55971db"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[projects]]
 | 
					[[projects]]
 | 
				
			||||||
  name = "github.com/naoina/go-stringutil"
 | 
					  name = "github.com/naoina/go-stringutil"
 | 
				
			||||||
| 
						 | 
					@ -53,21 +52,9 @@
 | 
				
			||||||
  revision = "ba968bfe8b2f7e042a574c888954fccecfa385b4"
 | 
					  revision = "ba968bfe8b2f7e042a574c888954fccecfa385b4"
 | 
				
			||||||
  version = "v0.8.1"
 | 
					  version = "v0.8.1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[projects]]
 | 
					 | 
				
			||||||
  name = "github.com/pmezard/go-difflib"
 | 
					 | 
				
			||||||
  packages = ["difflib"]
 | 
					 | 
				
			||||||
  revision = "792786c7400a136282c1664665ae0a8db921c6c2"
 | 
					 | 
				
			||||||
  version = "v1.0.0"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[projects]]
 | 
					 | 
				
			||||||
  name = "github.com/stretchr/testify"
 | 
					 | 
				
			||||||
  packages = ["assert"]
 | 
					 | 
				
			||||||
  revision = "ffdc059bfe9ce6a4e144ba849dbedead332c6053"
 | 
					 | 
				
			||||||
  version = "v1.3.0"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[solve-meta]
 | 
					[solve-meta]
 | 
				
			||||||
  analyzer-name = "dep"
 | 
					  analyzer-name = "dep"
 | 
				
			||||||
  analyzer-version = 1
 | 
					  analyzer-version = 1
 | 
				
			||||||
  inputs-digest = "3b1d8ae8346fc10f0725163478eab3fa466a2064f4d44077102c5f7651625dc4"
 | 
					  inputs-digest = "5fa0fad44ae6516c3c699a60210634ddcc7d36e6b8a10bae25d0efcc001bb768"
 | 
				
			||||||
  solver-name = "gps-cdcl"
 | 
					  solver-name = "gps-cdcl"
 | 
				
			||||||
  solver-version = 1
 | 
					  solver-version = 1
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,9 +25,13 @@
 | 
				
			||||||
#   unused-packages = true
 | 
					#   unused-packages = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[constraint]]
 | 
				
			||||||
 | 
					  branch = "master"
 | 
				
			||||||
 | 
					  name = "github.com/golift/unifi"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[constraint]]
 | 
					[[constraint]]
 | 
				
			||||||
  name = "github.com/influxdata/influxdb"
 | 
					  name = "github.com/influxdata/influxdb"
 | 
				
			||||||
  version = "1.7.2"
 | 
					  version = "1.7.3"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[constraint]]
 | 
					[[constraint]]
 | 
				
			||||||
  name = "github.com/naoina/toml"
 | 
					  name = "github.com/naoina/toml"
 | 
				
			||||||
| 
						 | 
					@ -37,14 +41,6 @@
 | 
				
			||||||
  name = "github.com/ogier/pflag"
 | 
					  name = "github.com/ogier/pflag"
 | 
				
			||||||
  version = "0.0.1"
 | 
					  version = "0.0.1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[constraint]]
 | 
					 | 
				
			||||||
  name = "github.com/pkg/errors"
 | 
					 | 
				
			||||||
  version = "0.8.1"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[constraint]]
 | 
					 | 
				
			||||||
  name = "github.com/stretchr/testify"
 | 
					 | 
				
			||||||
  version = "1.3.0"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[prune]
 | 
					[prune]
 | 
				
			||||||
  go-tests = true
 | 
					  go-tests = true
 | 
				
			||||||
  unused-packages = true
 | 
					  unused-packages = true
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,7 +12,7 @@ build:
 | 
				
			||||||
linux:
 | 
					linux:
 | 
				
			||||||
	for p in $(PACKAGES); do GOOS=linux go build -ldflags "-w -s" $${p}; done
 | 
						for p in $(PACKAGES); do GOOS=linux go build -ldflags "-w -s" $${p}; done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
install: man
 | 
					install: man test build
 | 
				
			||||||
	@echo "If you get errors, you may need sudo."
 | 
						@echo "If you get errors, you may need sudo."
 | 
				
			||||||
	GOBIN=/usr/local/bin go install -ldflags "-w -s" ./...
 | 
						GOBIN=/usr/local/bin go install -ldflags "-w -s" ./...
 | 
				
			||||||
	mkdir -p /usr/local/etc/unifi-poller /usr/local/share/man/man1
 | 
						mkdir -p /usr/local/etc/unifi-poller /usr/local/share/man/man1
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -90,13 +90,6 @@ 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 & License
 | 
				
			||||||
- Copyright © 2016 Garrett Bjerkhoel.
 | 
					- Copyright © 2016 Garrett Bjerkhoel.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,19 +7,19 @@ import (
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/davidnewhall/unifi-poller/unidev"
 | 
						"github.com/golift/unifi"
 | 
				
			||||||
 | 
						"github.com/influxdata/influxdb/client/v2"
 | 
				
			||||||
	influx "github.com/influxdata/influxdb/client/v2"
 | 
					 | 
				
			||||||
	"github.com/naoina/toml"
 | 
						"github.com/naoina/toml"
 | 
				
			||||||
	flg "github.com/ogier/pflag"
 | 
						flag "github.com/ogier/pflag"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func main() {
 | 
					func main() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	configFile := parseFlags()
 | 
						configFile := parseFlags()
 | 
				
			||||||
	log.Println("Unifi-Poller Starting Up! PID:", os.Getpid())
 | 
						log.Println("Unifi-Poller Starting Up! PID:", os.Getpid())
 | 
				
			||||||
	config, err := GetConfig(configFile)
 | 
						config, err := GetConfig(configFile)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		flg.Usage()
 | 
							flag.Usage()
 | 
				
			||||||
		log.Fatalf("Config Error '%v': %v", configFile, err)
 | 
							log.Fatalf("Config Error '%v': %v", configFile, err)
 | 
				
			||||||
	} else if log.SetFlags(0); config.Debug {
 | 
						} else if log.SetFlags(0); config.Debug {
 | 
				
			||||||
		log.SetFlags(log.Lshortfile | log.Lmicroseconds | log.Ldate)
 | 
							log.SetFlags(log.Lshortfile | log.Lmicroseconds | log.Ldate)
 | 
				
			||||||
| 
						 | 
					@ -27,13 +27,13 @@ func main() {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	log.Println("Loaded Configuration:", configFile)
 | 
						log.Println("Loaded Configuration:", configFile)
 | 
				
			||||||
	// Create an authenticated session to the Unifi Controller.
 | 
						// Create an authenticated session to the Unifi Controller.
 | 
				
			||||||
	unifi, err := unidev.AuthController(config.UnifiUser, config.UnifiPass, config.UnifiBase, config.VerifySSL)
 | 
						device, err := unifi.AuthController(config.UnifiUser, config.UnifiPass, config.UnifiBase, config.VerifySSL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Fatalln("Unifi Controller Error:", err)
 | 
							log.Fatalln("Unifi Controller Error:", err)
 | 
				
			||||||
	} else if !config.Quiet {
 | 
						} else if !config.Quiet {
 | 
				
			||||||
		log.Println("Authenticated to Unifi Controller @", config.UnifiBase, "as user", config.UnifiUser)
 | 
							log.Println("Authenticated to Unifi Controller @", config.UnifiBase, "as user", config.UnifiUser)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	infdb, err := influx.NewHTTPClient(influx.HTTPConfig{
 | 
						infdb, err := client.NewHTTPClient(client.HTTPConfig{
 | 
				
			||||||
		Addr:     config.InfluxURL,
 | 
							Addr:     config.InfluxURL,
 | 
				
			||||||
		Username: config.InfluxUser,
 | 
							Username: config.InfluxUser,
 | 
				
			||||||
		Password: config.InfluxPass,
 | 
							Password: config.InfluxPass,
 | 
				
			||||||
| 
						 | 
					@ -42,23 +42,23 @@ func main() {
 | 
				
			||||||
		log.Fatalln("InfluxDB Error:", err)
 | 
							log.Fatalln("InfluxDB Error:", err)
 | 
				
			||||||
	} else if config.Quiet {
 | 
						} else if config.Quiet {
 | 
				
			||||||
		// Doing it this way allows debug error logs (line numbers, etc)
 | 
							// Doing it this way allows debug error logs (line numbers, etc)
 | 
				
			||||||
		unidev.Debug = false
 | 
							unifi.Debug = false
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		log.Println("Logging Unifi Metrics to InfluXDB @", config.InfluxURL, "as user", config.InfluxUser)
 | 
							log.Println("Logging Unifi Metrics to InfluXDB @", config.InfluxURL, "as user", config.InfluxUser)
 | 
				
			||||||
		log.Println("Polling Unifi Controller, interval:", config.Interval.value)
 | 
							log.Println("Polling Unifi Controller, interval:", config.Interval.value)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	log.Println("Everyting checks out! Beginning Poller Routine.")
 | 
						log.Println("Everyting checks out! Beginning Poller Routine.")
 | 
				
			||||||
	config.PollUnifiController(infdb, unifi, config.Quiet)
 | 
						config.PollUnifiController(infdb, device, config.Quiet)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func parseFlags() string {
 | 
					func parseFlags() string {
 | 
				
			||||||
	flg.Usage = func() {
 | 
						flag.Usage = func() {
 | 
				
			||||||
		fmt.Println("Usage: unifi-poller [--config=filepath] [--version]")
 | 
							fmt.Println("Usage: unifi-poller [--config=filepath] [--version]")
 | 
				
			||||||
		flg.PrintDefaults()
 | 
							flag.PrintDefaults()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	configFile := flg.StringP("config", "c", defaultConfFile, "Poller Config File (TOML Format)")
 | 
						configFile := flag.StringP("config", "c", defaultConfFile, "Poller Config File (TOML Format)")
 | 
				
			||||||
	version := flg.BoolP("version", "v", false, "Print the version and exit")
 | 
						version := flag.BoolP("version", "v", false, "Print the version and exit")
 | 
				
			||||||
	if flg.Parse(); *version {
 | 
						if flag.Parse(); *version {
 | 
				
			||||||
		fmt.Println("unifi-poller version:", Version)
 | 
							fmt.Println("unifi-poller version:", Version)
 | 
				
			||||||
		os.Exit(0) // don't run anything else.
 | 
							os.Exit(0) // don't run anything else.
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -91,17 +91,17 @@ func GetConfig(configFile string) (Config, error) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// PollUnifiController runs forever, polling and pushing.
 | 
					// PollUnifiController runs forever, polling and pushing.
 | 
				
			||||||
func (c *Config) PollUnifiController(infdb influx.Client, unifi *unidev.AuthedReq, quiet bool) {
 | 
					func (c *Config) PollUnifiController(infdb client.Client, device *unifi.AuthedReq, quiet bool) {
 | 
				
			||||||
	ticker := time.NewTicker(c.Interval.value)
 | 
						ticker := time.NewTicker(c.Interval.value)
 | 
				
			||||||
	for range ticker.C {
 | 
						for range ticker.C {
 | 
				
			||||||
		var clients, devices []unidev.Asset
 | 
							var clients, devices []unifi.Asset
 | 
				
			||||||
		var bp influx.BatchPoints
 | 
							var bp client.BatchPoints
 | 
				
			||||||
		var err error
 | 
							var err error
 | 
				
			||||||
		if clients, err = unifi.GetUnifiClientAssets(); err != nil {
 | 
							if clients, err = device.GetUnifiClientAssets(); err != nil {
 | 
				
			||||||
			log.Println("ERROR unifi.GetUnifiClientsAssets():", err)
 | 
								log.Println("ERROR unifi.GetUnifiClientsAssets():", err)
 | 
				
			||||||
		} else if devices, err = unifi.GetUnifiDeviceAssets(); err != nil {
 | 
							} else if devices, err = device.GetUnifiDeviceAssets(); err != nil {
 | 
				
			||||||
			log.Println("ERROR unifi.GetUnifiDeviceAssets():", err)
 | 
								log.Println("ERROR unifi.GetUnifiDeviceAssets():", err)
 | 
				
			||||||
		} else if bp, err = influx.NewBatchPoints(influx.BatchPointsConfig{Database: c.InfluxDB}); err != nil {
 | 
							} else if bp, err = client.NewBatchPoints(client.BatchPointsConfig{Database: c.InfluxDB}); err != nil {
 | 
				
			||||||
			log.Println("ERROR influx.NewBatchPoints:", err)
 | 
								log.Println("ERROR influx.NewBatchPoints:", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,5 +8,6 @@ for f in cmd/*/README.md;do
 | 
				
			||||||
    PKGNOCMD="${f#cmd/}"
 | 
					    PKGNOCMD="${f#cmd/}"
 | 
				
			||||||
    PKG="${PKGNOCMD%/README.md}"
 | 
					    PKG="${PKGNOCMD%/README.md}"
 | 
				
			||||||
    echo "Creating Man Page: ${f} -> ${OUTPUT}${PKG}.1.gz"
 | 
					    echo "Creating Man Page: ${f} -> ${OUTPUT}${PKG}.1.gz"
 | 
				
			||||||
 | 
					    echo "If this produces an error. Install ronn; something like: sudo gem install ronn"
 | 
				
			||||||
    ronn < "$f" | gzip -9 > "${OUTPUT}${PKG}.1.gz"
 | 
					    ronn < "$f" | gzip -9 > "${OUTPUT}${PKG}.1.gz"
 | 
				
			||||||
done
 | 
					done
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,10 +0,0 @@
 | 
				
			||||||
# Go Library: `unidev`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
It connects to a Unifi Controller, given a url, username and password. Returns
 | 
					 | 
				
			||||||
an authenticated http Client you may use to query the device for data. Also
 | 
					 | 
				
			||||||
contains some built-in methods for de-serializing common client and device
 | 
					 | 
				
			||||||
data. The included asset interface currently only works for InfluxDB but could
 | 
					 | 
				
			||||||
probably be modified to support other output mechanisms; not sure really.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This lib is rudimentary and gets a job done for the tool at hand. It could be
 | 
					 | 
				
			||||||
used to base your own library. Good luck!
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,104 +0,0 @@
 | 
				
			||||||
package unidev
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
	"time"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	influx "github.com/influxdata/influxdb/client/v2"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 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 != "" {
 | 
					 | 
				
			||||||
		u.Hostname = u.Name
 | 
					 | 
				
			||||||
	} else if u.Hostname == "" && u.Name == "" {
 | 
					 | 
				
			||||||
		u.Hostname = "-no-name-"
 | 
					 | 
				
			||||||
		u.Name = "-no-name-"
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	tags := map[string]string{
 | 
					 | 
				
			||||||
		"id":                 u.ID,
 | 
					 | 
				
			||||||
		"mac":                u.Mac,
 | 
					 | 
				
			||||||
		"user_id":            u.UserID,
 | 
					 | 
				
			||||||
		"site_id":            u.SiteID,
 | 
					 | 
				
			||||||
		"network_id":         u.NetworkID,
 | 
					 | 
				
			||||||
		"usergroup_id":       u.UserGroupID,
 | 
					 | 
				
			||||||
		"ap_mac":             u.ApMac,
 | 
					 | 
				
			||||||
		"gw_mac":             u.GwMac,
 | 
					 | 
				
			||||||
		"sw_mac":             u.SwMac,
 | 
					 | 
				
			||||||
		"oui":                u.Oui,
 | 
					 | 
				
			||||||
		"radio_name":         u.RadioName,
 | 
					 | 
				
			||||||
		"radio":              u.Radio,
 | 
					 | 
				
			||||||
		"radio_proto":        u.RadioProto,
 | 
					 | 
				
			||||||
		"name":               u.Name,
 | 
					 | 
				
			||||||
		"fixed_ip":           u.FixedIP,
 | 
					 | 
				
			||||||
		"sw_port":            strconv.Itoa(u.SwPort),
 | 
					 | 
				
			||||||
		"os_class":           strconv.Itoa(u.OsClass),
 | 
					 | 
				
			||||||
		"os_name":            strconv.Itoa(u.OsName),
 | 
					 | 
				
			||||||
		"dev_cat":            strconv.Itoa(u.DevCat),
 | 
					 | 
				
			||||||
		"dev_id":             strconv.Itoa(u.DevID),
 | 
					 | 
				
			||||||
		"dev_family":         strconv.Itoa(u.DevFamily),
 | 
					 | 
				
			||||||
		"authorized":         strconv.FormatBool(u.Authorized),
 | 
					 | 
				
			||||||
		"is_11r":             strconv.FormatBool(u.Is11R),
 | 
					 | 
				
			||||||
		"is_wired":           strconv.FormatBool(u.IsWired),
 | 
					 | 
				
			||||||
		"is_guest":           strconv.FormatBool(u.IsGuest),
 | 
					 | 
				
			||||||
		"is_guest_by_uap":    strconv.FormatBool(u.IsGuestByUAP),
 | 
					 | 
				
			||||||
		"is_guest_by_ugw":    strconv.FormatBool(u.IsGuestByUGW),
 | 
					 | 
				
			||||||
		"is_guest_by_usw":    strconv.FormatBool(u.IsGuestByUSW),
 | 
					 | 
				
			||||||
		"noted":              strconv.FormatBool(u.Noted),
 | 
					 | 
				
			||||||
		"powersave_enabled":  strconv.FormatBool(u.PowersaveEnabled),
 | 
					 | 
				
			||||||
		"qos_policy_applied": strconv.FormatBool(u.QosPolicyApplied),
 | 
					 | 
				
			||||||
		"use_fixedip":        strconv.FormatBool(u.UseFixedIP),
 | 
					 | 
				
			||||||
		"channel":            strconv.Itoa(u.Channel),
 | 
					 | 
				
			||||||
		"vlan":               strconv.Itoa(u.Vlan),
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	fields := map[string]interface{}{
 | 
					 | 
				
			||||||
		"ip":                     u.IP,
 | 
					 | 
				
			||||||
		"essid":                  u.Essid,
 | 
					 | 
				
			||||||
		"bssid":                  u.Bssid,
 | 
					 | 
				
			||||||
		"hostname":               u.Hostname,
 | 
					 | 
				
			||||||
		"dpi_stats_last_updated": u.DpiStatsLastUpdated,
 | 
					 | 
				
			||||||
		"last_seen_by_uap":       u.LastSeenByUAP,
 | 
					 | 
				
			||||||
		"last_seen_by_ugw":       u.LastSeenByUGW,
 | 
					 | 
				
			||||||
		"last_seen_by_usw":       u.LastSeenByUSW,
 | 
					 | 
				
			||||||
		"uptime_by_uap":          u.UptimeByUAP,
 | 
					 | 
				
			||||||
		"uptime_by_ugw":          u.UptimeByUGW,
 | 
					 | 
				
			||||||
		"uptime_by_usw":          u.UptimeByUSW,
 | 
					 | 
				
			||||||
		"assoc_time":             u.AssocTime,
 | 
					 | 
				
			||||||
		"bytes_r":                u.BytesR,
 | 
					 | 
				
			||||||
		"ccq":                    u.Ccq,
 | 
					 | 
				
			||||||
		"first_seen":             u.FirstSeen,
 | 
					 | 
				
			||||||
		"idle_time":              u.IdleTime,
 | 
					 | 
				
			||||||
		"last_seen":              u.LastSeen,
 | 
					 | 
				
			||||||
		"latest_assoc_time":      u.LatestAssocTime,
 | 
					 | 
				
			||||||
		"network":                u.Network,
 | 
					 | 
				
			||||||
		"noise":                  u.Noise,
 | 
					 | 
				
			||||||
		"note":                   u.Note,
 | 
					 | 
				
			||||||
		"roam_count":             u.RoamCount,
 | 
					 | 
				
			||||||
		"rssi":                   u.Rssi,
 | 
					 | 
				
			||||||
		"rx_bytes":               u.RxBytes,
 | 
					 | 
				
			||||||
		"rx_bytes_r":             u.RxBytesR,
 | 
					 | 
				
			||||||
		"rx_packets":             u.RxPackets,
 | 
					 | 
				
			||||||
		"rx_rate":                u.RxRate,
 | 
					 | 
				
			||||||
		"signal":                 u.Signal,
 | 
					 | 
				
			||||||
		"tx_bytes":               u.TxBytes,
 | 
					 | 
				
			||||||
		"tx_bytes_r":             u.TxBytesR,
 | 
					 | 
				
			||||||
		"tx_packets":             u.TxPackets,
 | 
					 | 
				
			||||||
		"tx_power":               u.TxPower,
 | 
					 | 
				
			||||||
		"tx_rate":                u.TxRate,
 | 
					 | 
				
			||||||
		"uptime":                 u.Uptime,
 | 
					 | 
				
			||||||
		"wired-rx_bytes":         u.WiredRxBytes,
 | 
					 | 
				
			||||||
		"wired-rx_bytes-r":       u.WiredRxBytesR,
 | 
					 | 
				
			||||||
		"wired-rx_packets":       u.WiredRxPackets,
 | 
					 | 
				
			||||||
		"wired-tx_bytes":         u.WiredTxBytes,
 | 
					 | 
				
			||||||
		"wired-tx_bytes-r":       u.WiredTxBytesR,
 | 
					 | 
				
			||||||
		"wired-tx_packets":       u.WiredTxPackets,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	pt, err := influx.NewPoint("clients", tags, fields, time.Now())
 | 
					 | 
				
			||||||
	if err == nil {
 | 
					 | 
				
			||||||
		points = append(points, pt)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return points, err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,88 +0,0 @@
 | 
				
			||||||
package unidev
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// UCL defines all the data a connected-network client contains.
 | 
					 | 
				
			||||||
type UCL struct {
 | 
					 | 
				
			||||||
	ID            string `json:"_id"`
 | 
					 | 
				
			||||||
	IsGuestByUAP  bool   `json:"_is_guest_by_uap"`
 | 
					 | 
				
			||||||
	IsGuestByUGW  bool   `json:"_is_guest_by_ugw"`
 | 
					 | 
				
			||||||
	IsGuestByUSW  bool   `json:"_is_guest_by_usw"`
 | 
					 | 
				
			||||||
	LastSeenByUAP int64  `json:"_last_seen_by_uap"`
 | 
					 | 
				
			||||||
	LastSeenByUGW int64  `json:"_last_seen_by_ugw"`
 | 
					 | 
				
			||||||
	LastSeenByUSW int64  `json:"_last_seen_by_usw"`
 | 
					 | 
				
			||||||
	UptimeByUAP   int64  `json:"_uptime_by_uap"`
 | 
					 | 
				
			||||||
	UptimeByUGW   int64  `json:"_uptime_by_ugw"`
 | 
					 | 
				
			||||||
	UptimeByUSW   int64  `json:"_uptime_by_usw"`
 | 
					 | 
				
			||||||
	ApMac         string `json:"ap_mac"`
 | 
					 | 
				
			||||||
	AssocTime     int64  `json:"assoc_time"`
 | 
					 | 
				
			||||||
	Authorized    bool   `json:"authorized"`
 | 
					 | 
				
			||||||
	Bssid         string `json:"bssid"`
 | 
					 | 
				
			||||||
	BytesR        int64  `json:"bytes-r"`
 | 
					 | 
				
			||||||
	Ccq           int64  `json:"ccq"`
 | 
					 | 
				
			||||||
	Channel       int    `json:"channel"`
 | 
					 | 
				
			||||||
	DevCat        int    `json:"dev_cat"`
 | 
					 | 
				
			||||||
	DevFamily     int    `json:"dev_family"`
 | 
					 | 
				
			||||||
	DevID         int    `json:"dev_id"`
 | 
					 | 
				
			||||||
	DpiStats      struct {
 | 
					 | 
				
			||||||
		App       int64
 | 
					 | 
				
			||||||
		Cat       int64
 | 
					 | 
				
			||||||
		RxBytes   int64
 | 
					 | 
				
			||||||
		RxPackets int64
 | 
					 | 
				
			||||||
		TxBytes   int64
 | 
					 | 
				
			||||||
		TxPackets int64
 | 
					 | 
				
			||||||
	} `json:"dpi_stats"`
 | 
					 | 
				
			||||||
	DpiStatsLastUpdated int64  `json:"dpi_stats_last_updated"`
 | 
					 | 
				
			||||||
	Essid               string `json:"essid"`
 | 
					 | 
				
			||||||
	FirstSeen           int64  `json:"first_seen"`
 | 
					 | 
				
			||||||
	FixedIP             string `json:"fixed_ip"`
 | 
					 | 
				
			||||||
	Hostname            string `json:"hostname"`
 | 
					 | 
				
			||||||
	GwMac               string `json:"gw_mac"`
 | 
					 | 
				
			||||||
	IdleTime            int64  `json:"idle_time"`
 | 
					 | 
				
			||||||
	IP                  string `json:"ip"`
 | 
					 | 
				
			||||||
	Is11R               bool   `json:"is_11r"`
 | 
					 | 
				
			||||||
	IsGuest             bool   `json:"is_guest"`
 | 
					 | 
				
			||||||
	IsWired             bool   `json:"is_wired"`
 | 
					 | 
				
			||||||
	LastSeen            int64  `json:"last_seen"`
 | 
					 | 
				
			||||||
	LatestAssocTime     int64  `json:"latest_assoc_time"`
 | 
					 | 
				
			||||||
	Mac                 string `json:"mac"`
 | 
					 | 
				
			||||||
	Name                string `json:"name"`
 | 
					 | 
				
			||||||
	Network             string `json:"network"`
 | 
					 | 
				
			||||||
	NetworkID           string `json:"network_id"`
 | 
					 | 
				
			||||||
	Noise               int64  `json:"noise"`
 | 
					 | 
				
			||||||
	Note                string `json:"note"`
 | 
					 | 
				
			||||||
	Noted               bool   `json:"noted"`
 | 
					 | 
				
			||||||
	OsClass             int    `json:"os_class"`
 | 
					 | 
				
			||||||
	OsName              int    `json:"os_name"`
 | 
					 | 
				
			||||||
	Oui                 string `json:"oui"`
 | 
					 | 
				
			||||||
	PowersaveEnabled    bool   `json:"powersave_enabled"`
 | 
					 | 
				
			||||||
	QosPolicyApplied    bool   `json:"qos_policy_applied"`
 | 
					 | 
				
			||||||
	Radio               string `json:"radio"`
 | 
					 | 
				
			||||||
	RadioName           string `json:"radio_name"`
 | 
					 | 
				
			||||||
	RadioProto          string `json:"radio_proto"`
 | 
					 | 
				
			||||||
	RoamCount           int64  `json:"roam_count"`
 | 
					 | 
				
			||||||
	Rssi                int64  `json:"rssi"`
 | 
					 | 
				
			||||||
	RxBytes             int64  `json:"rx_bytes"`
 | 
					 | 
				
			||||||
	RxBytesR            int64  `json:"rx_bytes-r"`
 | 
					 | 
				
			||||||
	RxPackets           int64  `json:"rx_packets"`
 | 
					 | 
				
			||||||
	RxRate              int64  `json:"rx_rate"`
 | 
					 | 
				
			||||||
	Signal              int64  `json:"signal"`
 | 
					 | 
				
			||||||
	SiteID              string `json:"site_id"`
 | 
					 | 
				
			||||||
	SwDepth             int    `json:"sw_depth"`
 | 
					 | 
				
			||||||
	SwMac               string `json:"sw_mac"`
 | 
					 | 
				
			||||||
	SwPort              int    `json:"sw_port"`
 | 
					 | 
				
			||||||
	TxBytes             int64  `json:"tx_bytes"`
 | 
					 | 
				
			||||||
	TxBytesR            int64  `json:"tx_bytes-r"`
 | 
					 | 
				
			||||||
	TxPackets           int64  `json:"tx_packets"`
 | 
					 | 
				
			||||||
	TxPower             int64  `json:"tx_power"`
 | 
					 | 
				
			||||||
	TxRate              int64  `json:"tx_rate"`
 | 
					 | 
				
			||||||
	Uptime              int64  `json:"uptime"`
 | 
					 | 
				
			||||||
	UserID              string `json:"user_id"`
 | 
					 | 
				
			||||||
	UserGroupID         string `json:"usergroup_id"`
 | 
					 | 
				
			||||||
	UseFixedIP          bool   `json:"use_fixedip"`
 | 
					 | 
				
			||||||
	Vlan                int    `json:"vlan"`
 | 
					 | 
				
			||||||
	WiredRxBytes        int64  `json:"wired-rx_bytes"`
 | 
					 | 
				
			||||||
	WiredRxBytesR       int64  `json:"wired-rx_bytes-r"`
 | 
					 | 
				
			||||||
	WiredRxPackets      int64  `json:"wired-rx_packets"`
 | 
					 | 
				
			||||||
	WiredTxBytes        int64  `json:"wired-tx_bytes"`
 | 
					 | 
				
			||||||
	WiredTxBytesR       int64  `json:"wired-tx_bytes-r"`
 | 
					 | 
				
			||||||
	WiredTxPackets      int64  `json:"wired-tx_packets"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,266 +0,0 @@
 | 
				
			||||||
package unidev
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
	"time"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	influx "github.com/influxdata/influxdb/client/v2"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 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,
 | 
					 | 
				
			||||||
		"device_type":             u.Stat.O,
 | 
					 | 
				
			||||||
		"device_oid":              u.Stat.Oid,
 | 
					 | 
				
			||||||
		"device_ap":               u.Stat.Ap,
 | 
					 | 
				
			||||||
		"site_id":                 u.SiteID,
 | 
					 | 
				
			||||||
		"name":                    u.Name,
 | 
					 | 
				
			||||||
		"addopted":                strconv.FormatBool(u.Adopted),
 | 
					 | 
				
			||||||
		"bandsteering_mode":       u.BandsteeringMode,
 | 
					 | 
				
			||||||
		"board_rev":               strconv.Itoa(u.BoardRev),
 | 
					 | 
				
			||||||
		"cfgversion":              u.Cfgversion,
 | 
					 | 
				
			||||||
		"config_network_ip":       u.ConfigNetwork.IP,
 | 
					 | 
				
			||||||
		"config_network_type":     u.ConfigNetwork.Type,
 | 
					 | 
				
			||||||
		"connect_request_ip":      u.ConnectRequestIP,
 | 
					 | 
				
			||||||
		"connect_request_port":    u.ConnectRequestPort,
 | 
					 | 
				
			||||||
		"default":                 strconv.FormatBool(u.Default),
 | 
					 | 
				
			||||||
		"device_id":               u.DeviceID,
 | 
					 | 
				
			||||||
		"discovered_via":          u.DiscoveredVia,
 | 
					 | 
				
			||||||
		"fw_caps":                 strconv.Itoa(u.FwCaps),
 | 
					 | 
				
			||||||
		"guest-num_sta":           strconv.Itoa(u.GuestNumSta),
 | 
					 | 
				
			||||||
		"guest_token":             u.GuestToken,
 | 
					 | 
				
			||||||
		"has_eth1":                strconv.FormatBool(u.HasEth1),
 | 
					 | 
				
			||||||
		"has_speaker":             strconv.FormatBool(u.HasSpeaker),
 | 
					 | 
				
			||||||
		"inform_ip":               u.InformIP,
 | 
					 | 
				
			||||||
		"isolated":                strconv.FormatBool(u.Isolated),
 | 
					 | 
				
			||||||
		"last_uplink_mac":         u.LastUplink.UplinkMac,
 | 
					 | 
				
			||||||
		"last_uplink_remote_port": strconv.Itoa(u.LastUplink.UplinkRemotePort),
 | 
					 | 
				
			||||||
		"known_cfgversion":        u.KnownCfgversion,
 | 
					 | 
				
			||||||
		"led_override":            u.LedOverride,
 | 
					 | 
				
			||||||
		"locating":                strconv.FormatBool(u.Locating),
 | 
					 | 
				
			||||||
		"model":                   u.Model,
 | 
					 | 
				
			||||||
		"outdoor_mode_override":   u.OutdoorModeOverride,
 | 
					 | 
				
			||||||
		"serial":                  u.Serial,
 | 
					 | 
				
			||||||
		"type":                    u.Type,
 | 
					 | 
				
			||||||
		"version_incompatible":    strconv.FormatBool(u.VersionIncompatible),
 | 
					 | 
				
			||||||
		"vwireEnabled":            strconv.FormatBool(u.VwireEnabled),
 | 
					 | 
				
			||||||
		"wifi_caps":               strconv.Itoa(u.WifiCaps),
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	fields := map[string]interface{}{
 | 
					 | 
				
			||||||
		"ip":                         u.IP,
 | 
					 | 
				
			||||||
		"bytes":                      u.Bytes,
 | 
					 | 
				
			||||||
		"bytes_d":                    u.BytesD,
 | 
					 | 
				
			||||||
		"bytes_r":                    u.BytesR,
 | 
					 | 
				
			||||||
		"last_seen":                  u.LastSeen,
 | 
					 | 
				
			||||||
		"rx_bytes":                   u.RxBytes,
 | 
					 | 
				
			||||||
		"rx_bytes-d":                 u.RxBytesD,
 | 
					 | 
				
			||||||
		"tx_bytes":                   u.TxBytes,
 | 
					 | 
				
			||||||
		"tx_bytes-d":                 u.TxBytesD,
 | 
					 | 
				
			||||||
		"uptime":                     u.Uptime.Number,
 | 
					 | 
				
			||||||
		"considered_lost_at":         u.ConsideredLostAt,
 | 
					 | 
				
			||||||
		"next_heartbeat_at":          u.NextHeartbeatAt,
 | 
					 | 
				
			||||||
		"scanning":                   u.Scanning,
 | 
					 | 
				
			||||||
		"spectrum_scanning":          u.SpectrumScanning,
 | 
					 | 
				
			||||||
		"roll_upgrade":               u.Rollupgrade,
 | 
					 | 
				
			||||||
		"state":                      u.State,
 | 
					 | 
				
			||||||
		"upgradable":                 u.Upgradable,
 | 
					 | 
				
			||||||
		"user-num_sta":               u.UserNumSta,
 | 
					 | 
				
			||||||
		"version":                    u.Version,
 | 
					 | 
				
			||||||
		"loadavg_1":                  u.SysStats.Loadavg1,
 | 
					 | 
				
			||||||
		"loadavg_5":                  u.SysStats.Loadavg5,
 | 
					 | 
				
			||||||
		"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,
 | 
					 | 
				
			||||||
		"stat_bytes":                 u.Stat.Bytes,
 | 
					 | 
				
			||||||
		"stat_duration":              u.Stat.Duration,
 | 
					 | 
				
			||||||
		"stat_guest-rx_bytes":        u.Stat.RxBytes,
 | 
					 | 
				
			||||||
		"stat_guest-rx_crypts":       u.Stat.RxCrypts,
 | 
					 | 
				
			||||||
		"stat_guest-rx_dropped":      u.Stat.RxDropped,
 | 
					 | 
				
			||||||
		"stat_guest-rx_errors":       u.Stat.RxErrors,
 | 
					 | 
				
			||||||
		"stat_guest-rx_frags":        u.Stat.RxFrags,
 | 
					 | 
				
			||||||
		"stat_guest-rx_packets":      u.Stat.RxPackets,
 | 
					 | 
				
			||||||
		"stat_guest-tx_bytes":        u.Stat.TxBytes,
 | 
					 | 
				
			||||||
		"stat_guest-tx_dropped":      u.Stat.TxDropped,
 | 
					 | 
				
			||||||
		"stat_guest-tx_errors":       u.Stat.TxErrors,
 | 
					 | 
				
			||||||
		"stat_guest-tx_packets":      u.Stat.TxPackets,
 | 
					 | 
				
			||||||
		"stat_guest-tx_retries":      u.Stat.TxRetries,
 | 
					 | 
				
			||||||
		"stat_port_1-rx_broadcast":   u.Stat.Port1RxBroadcast,
 | 
					 | 
				
			||||||
		"stat_port_1-rx_bytes":       u.Stat.Port1RxBytes,
 | 
					 | 
				
			||||||
		"stat_port_1-rx_multicast":   u.Stat.Port1RxMulticast,
 | 
					 | 
				
			||||||
		"stat_port_1-rx_packets":     u.Stat.Port1RxPackets,
 | 
					 | 
				
			||||||
		"stat_port_1-tx_broadcast":   u.Stat.Port1TxBroadcast,
 | 
					 | 
				
			||||||
		"stat_port_1-tx_bytes":       u.Stat.Port1TxBytes,
 | 
					 | 
				
			||||||
		"stat_port_1-tx_multicast":   u.Stat.Port1TxMulticast,
 | 
					 | 
				
			||||||
		"stat_port_1-tx_packets":     u.Stat.Port1TxPackets,
 | 
					 | 
				
			||||||
		"stat_rx_bytes":              u.Stat.RxBytes,
 | 
					 | 
				
			||||||
		"stat_rx_crypts":             u.Stat.RxCrypts,
 | 
					 | 
				
			||||||
		"stat_rx_dropped":            u.Stat.RxDropped,
 | 
					 | 
				
			||||||
		"stat_rx_errors":             u.Stat.RxErrors,
 | 
					 | 
				
			||||||
		"stat_rx_frags":              u.Stat.RxFrags,
 | 
					 | 
				
			||||||
		"stat_rx_packets":            u.Stat.TxPackets,
 | 
					 | 
				
			||||||
		"stat_tx_bytes":              u.Stat.TxBytes,
 | 
					 | 
				
			||||||
		"stat_tx_dropped":            u.Stat.TxDropped,
 | 
					 | 
				
			||||||
		"stat_tx_errors":             u.Stat.TxErrors,
 | 
					 | 
				
			||||||
		"stat_tx_packets":            u.Stat.TxPackets,
 | 
					 | 
				
			||||||
		"stat_tx_retries":            u.Stat.TxRetries,
 | 
					 | 
				
			||||||
		"stat_user-rx_bytes":         u.Stat.UserRxBytes,
 | 
					 | 
				
			||||||
		"stat_user-rx_crypts":        u.Stat.UserRxCrypts,
 | 
					 | 
				
			||||||
		"stat_user-rx_dropped":       u.Stat.UserRxDropped,
 | 
					 | 
				
			||||||
		"stat_user-rx_errors":        u.Stat.UserRxErrors,
 | 
					 | 
				
			||||||
		"stat_user-rx_frags":         u.Stat.UserRxFrags,
 | 
					 | 
				
			||||||
		"stat_user-rx_packets":       u.Stat.UserRxPackets,
 | 
					 | 
				
			||||||
		"stat_user-tx_bytes":         u.Stat.UserTxBytes,
 | 
					 | 
				
			||||||
		"stat_user-tx_dropped":       u.Stat.UserTxDropped,
 | 
					 | 
				
			||||||
		"stat_user-tx_errors":        u.Stat.UserTxErrors,
 | 
					 | 
				
			||||||
		"stat_user-tx_packets":       u.Stat.UserTxPackets,
 | 
					 | 
				
			||||||
		"stat_user-tx_retries":       u.Stat.UserTxRetries,
 | 
					 | 
				
			||||||
		"stat_user-wifi0-rx_bytes":   u.Stat.UserWifi0RxBytes,
 | 
					 | 
				
			||||||
		"stat_user-wifi0-rx_crypts":  u.Stat.UserWifi0RxCrypts,
 | 
					 | 
				
			||||||
		"stat_user-wifi0-rx_dropped": u.Stat.UserWifi0RxDropped,
 | 
					 | 
				
			||||||
		"stat_user-wifi0-rx_errors":  u.Stat.UserWifi0RxErrors,
 | 
					 | 
				
			||||||
		"stat_user-wifi0-rx_frags":   u.Stat.UserWifi0RxFrags,
 | 
					 | 
				
			||||||
		"stat_user-wifi0-rx_packets": u.Stat.UserWifi0RxPackets,
 | 
					 | 
				
			||||||
		"stat_user-wifi0-tx_bytes":   u.Stat.UserWifi0TxBytes,
 | 
					 | 
				
			||||||
		"stat_user-wifi0-tx_dropped": u.Stat.UserWifi0TxDropped,
 | 
					 | 
				
			||||||
		"stat_user-wifi0-tx_errors":  u.Stat.UserWifi0TxErrors,
 | 
					 | 
				
			||||||
		"stat_user-wifi0-tx_packets": u.Stat.UserWifi0TxPackets,
 | 
					 | 
				
			||||||
		"stat_user-wifi0-tx_retries": u.Stat.UserWifi0TxRetries,
 | 
					 | 
				
			||||||
		"stat_user-wifi1-rx_bytes":   u.Stat.UserWifi1RxBytes,
 | 
					 | 
				
			||||||
		"stat_user-wifi1-rx_crypts":  u.Stat.UserWifi1RxCrypts,
 | 
					 | 
				
			||||||
		"stat_user-wifi1-rx_dropped": u.Stat.UserWifi1RxDropped,
 | 
					 | 
				
			||||||
		"stat_user-wifi1-rx_errors":  u.Stat.UserWifi1RxErrors,
 | 
					 | 
				
			||||||
		"stat_user-wifi1-rx_frags":   u.Stat.UserWifi1RxFrags,
 | 
					 | 
				
			||||||
		"stat_user-wifi1-rx_packets": u.Stat.UserWifi1RxPackets,
 | 
					 | 
				
			||||||
		"stat_user-wifi1-tx_bytes":   u.Stat.UserWifi1TxBytes,
 | 
					 | 
				
			||||||
		"stat_user-wifi1-tx_dropped": u.Stat.UserWifi1TxDropped,
 | 
					 | 
				
			||||||
		"stat_user-wifi1-tx_errors":  u.Stat.UserWifi1TxErrors,
 | 
					 | 
				
			||||||
		"stat_user-wifi1-tx_packets": u.Stat.UserWifi1TxPackets,
 | 
					 | 
				
			||||||
		"stat_user-wifi1-tx_retries": u.Stat.UserWifi1TxRetries,
 | 
					 | 
				
			||||||
		"stat_wifi0-rx_bytes":        u.Stat.Wifi0RxBytes,
 | 
					 | 
				
			||||||
		"stat_wifi0-rx_crypts":       u.Stat.Wifi0RxCrypts,
 | 
					 | 
				
			||||||
		"stat_wifi0-rx_dropped":      u.Stat.Wifi0RxDropped,
 | 
					 | 
				
			||||||
		"stat_wifi0-rx_errors":       u.Stat.Wifi0RxErrors,
 | 
					 | 
				
			||||||
		"stat_wifi0-rx_frags":        u.Stat.Wifi0RxFrags,
 | 
					 | 
				
			||||||
		"stat_wifi0-rx_packets":      u.Stat.Wifi0RxPackets,
 | 
					 | 
				
			||||||
		"stat_wifi0-tx_bytes":        u.Stat.Wifi0TxBytes,
 | 
					 | 
				
			||||||
		"stat_wifi0-tx_dropped":      u.Stat.Wifi0TxDropped,
 | 
					 | 
				
			||||||
		"stat_wifi0-tx_errors":       u.Stat.Wifi0TxErrors,
 | 
					 | 
				
			||||||
		"stat_wifi0-tx_packets":      u.Stat.Wifi0TxPackets,
 | 
					 | 
				
			||||||
		"stat_wifi0-tx_retries":      u.Stat.Wifi0TxRetries,
 | 
					 | 
				
			||||||
		"stat_wifi1-rx_bytes":        u.Stat.Wifi1RxBytes,
 | 
					 | 
				
			||||||
		"stat_wifi1-rx_crypts":       u.Stat.Wifi1RxCrypts,
 | 
					 | 
				
			||||||
		"stat_wifi1-rx_dropped":      u.Stat.Wifi1RxDropped,
 | 
					 | 
				
			||||||
		"stat_wifi1-rx_errors":       u.Stat.Wifi1RxErrors,
 | 
					 | 
				
			||||||
		"stat_wifi1-rx_frags":        u.Stat.Wifi1RxFrags,
 | 
					 | 
				
			||||||
		"stat_wifi1-rx_packets":      u.Stat.Wifi1RxPackets,
 | 
					 | 
				
			||||||
		"stat_wifi1-tx_bytes":        u.Stat.Wifi1TxBytes,
 | 
					 | 
				
			||||||
		"stat_wifi1-tx_dropped":      u.Stat.Wifi1TxDropped,
 | 
					 | 
				
			||||||
		"stat_wifi1-tx_errors":       u.Stat.Wifi1TxErrors,
 | 
					 | 
				
			||||||
		"stat_wifi1-tx_packets":      u.Stat.Wifi1TxPackets,
 | 
					 | 
				
			||||||
		"stat_wifi1-tx_retries":      u.Stat.Wifi1TxRetries,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	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.String,
 | 
					 | 
				
			||||||
			"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.Number,
 | 
					 | 
				
			||||||
			"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
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,361 +0,0 @@
 | 
				
			||||||
package unidev
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 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"`
 | 
					 | 
				
			||||||
	AdoptURL     string  `json:"adopt_url,omitempty"`
 | 
					 | 
				
			||||||
	Adopted      bool    `json:"adopted"`
 | 
					 | 
				
			||||||
	AntennaTable []struct {
 | 
					 | 
				
			||||||
		ID        float64 `json:"id"`
 | 
					 | 
				
			||||||
		Name      string  `json:"name"`
 | 
					 | 
				
			||||||
		Wifi0Gain float64 `json:"wifi0_gain"`
 | 
					 | 
				
			||||||
		Wifi1Gain float64 `json:"wifi1_gain"`
 | 
					 | 
				
			||||||
	} `json:"antenna_table"`
 | 
					 | 
				
			||||||
	BandsteeringMode string  `json:"bandsteering_mode,omitempty"`
 | 
					 | 
				
			||||||
	BoardRev         int     `json:"board_rev"`
 | 
					 | 
				
			||||||
	Bytes            float64 `json:"bytes"`
 | 
					 | 
				
			||||||
	BytesD           float64 `json:"bytes-d"`
 | 
					 | 
				
			||||||
	BytesR           float64 `json:"bytes-r"`
 | 
					 | 
				
			||||||
	Cfgversion       string  `json:"cfgversion"`
 | 
					 | 
				
			||||||
	ConfigNetwork    struct {
 | 
					 | 
				
			||||||
		IP   string `json:"ip"`
 | 
					 | 
				
			||||||
		Type string `json:"type"`
 | 
					 | 
				
			||||||
	} `json:"config_network"`
 | 
					 | 
				
			||||||
	ConnectRequestIP   string        `json:"connect_request_ip"`
 | 
					 | 
				
			||||||
	ConnectRequestPort string        `json:"connect_request_port"`
 | 
					 | 
				
			||||||
	ConsideredLostAt   float64       `json:"considered_lost_at"`
 | 
					 | 
				
			||||||
	CountrycodeTable   []float64     `json:"countrycode_table"`
 | 
					 | 
				
			||||||
	Default            bool          `json:"default,omitempty"`
 | 
					 | 
				
			||||||
	DeviceID           string        `json:"device_id"`
 | 
					 | 
				
			||||||
	DiscoveredVia      string        `json:"discovered_via,omitempty"`
 | 
					 | 
				
			||||||
	DownlinkTable      []interface{} `json:"downlink_table"`
 | 
					 | 
				
			||||||
	EthernetTable      []struct {
 | 
					 | 
				
			||||||
		Mac     string  `json:"mac"`
 | 
					 | 
				
			||||||
		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        float64 `json:"last_seen"`
 | 
					 | 
				
			||||||
	LastUplink      struct {
 | 
					 | 
				
			||||||
		UplinkMac        string `json:"uplink_mac"`
 | 
					 | 
				
			||||||
		UplinkRemotePort int    `json:"uplink_remote_port"`
 | 
					 | 
				
			||||||
	} `json:"last_uplink"`
 | 
					 | 
				
			||||||
	LedOverride         string  `json:"led_override"`
 | 
					 | 
				
			||||||
	Locating            bool    `json:"locating"`
 | 
					 | 
				
			||||||
	Mac                 string  `json:"mac"`
 | 
					 | 
				
			||||||
	Model               string  `json:"model"`
 | 
					 | 
				
			||||||
	Name                string  `json:"name"`
 | 
					 | 
				
			||||||
	NextHeartbeatAt     float64 `json:"next_heartbeat_at"`
 | 
					 | 
				
			||||||
	NumSta              float64 `json:"num_sta"`
 | 
					 | 
				
			||||||
	OutdoorModeOverride string  `json:"outdoor_mode_override"`
 | 
					 | 
				
			||||||
	PortTable           []struct {
 | 
					 | 
				
			||||||
		AggregatedBy bool    `json:"aggregated_by"`
 | 
					 | 
				
			||||||
		AttrNoEdit   bool    `json:"attr_no_edit,omitempty"`
 | 
					 | 
				
			||||||
		Autoneg      bool    `json:"autoneg"`
 | 
					 | 
				
			||||||
		BytesR       float64 `json:"bytes-r"`
 | 
					 | 
				
			||||||
		Enable       bool    `json:"enable"`
 | 
					 | 
				
			||||||
		FlowctrlRx   bool    `json:"flowctrl_rx"`
 | 
					 | 
				
			||||||
		FlowctrlTx   bool    `json:"flowctrl_tx"`
 | 
					 | 
				
			||||||
		FullDuplex   bool    `json:"full_duplex"`
 | 
					 | 
				
			||||||
		IsUplink     bool    `json:"is_uplink"`
 | 
					 | 
				
			||||||
		Jumbo        bool    `json:"jumbo"`
 | 
					 | 
				
			||||||
		MacTable     []struct {
 | 
					 | 
				
			||||||
			Age    float64 `json:"age"`
 | 
					 | 
				
			||||||
			Mac    string  `json:"mac"`
 | 
					 | 
				
			||||||
			Static bool    `json:"static"`
 | 
					 | 
				
			||||||
			Uptime float64 `json:"uptime"`
 | 
					 | 
				
			||||||
			Vlan   float64 `json:"vlan"`
 | 
					 | 
				
			||||||
		} `json:"mac_table"`
 | 
					 | 
				
			||||||
		Masked    bool    `json:"masked"`
 | 
					 | 
				
			||||||
		Media     string  `json:"media"`
 | 
					 | 
				
			||||||
		Name      string  `json:"name"`
 | 
					 | 
				
			||||||
		OpMode    string  `json:"op_mode"`
 | 
					 | 
				
			||||||
		PoeCaps   float64 `json:"poe_caps"`
 | 
					 | 
				
			||||||
		PortDelta struct {
 | 
					 | 
				
			||||||
			RxBytes   float64 `json:"rx_bytes"`
 | 
					 | 
				
			||||||
			RxPackets float64 `json:"rx_packets"`
 | 
					 | 
				
			||||||
			TimeDelta float64 `json:"time_delta"`
 | 
					 | 
				
			||||||
			TxBytes   float64 `json:"tx_bytes"`
 | 
					 | 
				
			||||||
			TxPackets float64 `json:"tx_packets"`
 | 
					 | 
				
			||||||
		} `json:"port_delta"`
 | 
					 | 
				
			||||||
		PortIdx     float64 `json:"port_idx"`
 | 
					 | 
				
			||||||
		PortPoe     bool    `json:"port_poe"`
 | 
					 | 
				
			||||||
		PortconfID  string  `json:"portconf_id"`
 | 
					 | 
				
			||||||
		RxBroadcast float64 `json:"rx_broadcast"`
 | 
					 | 
				
			||||||
		RxBytes     float64 `json:"rx_bytes"`
 | 
					 | 
				
			||||||
		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"`
 | 
					 | 
				
			||||||
		StpPathcost float64 `json:"stp_pathcost"`
 | 
					 | 
				
			||||||
		StpState    string  `json:"stp_state"`
 | 
					 | 
				
			||||||
		TxBroadcast float64 `json:"tx_broadcast"`
 | 
					 | 
				
			||||||
		TxBytes     float64 `json:"tx_bytes"`
 | 
					 | 
				
			||||||
		TxBytesR    float64 `json:"tx_bytes-r"`
 | 
					 | 
				
			||||||
		TxDropped   float64 `json:"tx_dropped"`
 | 
					 | 
				
			||||||
		TxErrors    float64 `json:"tx_errors"`
 | 
					 | 
				
			||||||
		TxMulticast float64 `json:"tx_multicast"`
 | 
					 | 
				
			||||||
		TxPackets   float64 `json:"tx_packets"`
 | 
					 | 
				
			||||||
		Up          bool    `json:"up"`
 | 
					 | 
				
			||||||
	} `json:"port_table"`
 | 
					 | 
				
			||||||
	RadioTable []struct {
 | 
					 | 
				
			||||||
		BuiltinAntGain     float64 `json:"builtin_ant_gain"`
 | 
					 | 
				
			||||||
		BuiltinAntenna     bool    `json:"builtin_antenna"`
 | 
					 | 
				
			||||||
		Channel            FlexInt `json:"channel"`
 | 
					 | 
				
			||||||
		CurrentAntennaGain float64 `json:"current_antenna_gain"`
 | 
					 | 
				
			||||||
		Ht                 string  `json:"ht"`
 | 
					 | 
				
			||||||
		MaxTxpower         float64 `json:"max_txpower"`
 | 
					 | 
				
			||||||
		MinRssiEnabled     bool    `json:"min_rssi_enabled"`
 | 
					 | 
				
			||||||
		MinTxpower         float64 `json:"min_txpower"`
 | 
					 | 
				
			||||||
		Name               string  `json:"name"`
 | 
					 | 
				
			||||||
		Nss                float64 `json:"nss"`
 | 
					 | 
				
			||||||
		Radio              string  `json:"radio"`
 | 
					 | 
				
			||||||
		RadioCaps          float64 `json:"radio_caps"`
 | 
					 | 
				
			||||||
		TxPower            FlexInt `json:"tx_power"`
 | 
					 | 
				
			||||||
		TxPowerMode        string  `json:"tx_power_mode"`
 | 
					 | 
				
			||||||
		WlangroupID        string  `json:"wlangroup_id"`
 | 
					 | 
				
			||||||
		HasDfs             bool    `json:"has_dfs,omitempty"`
 | 
					 | 
				
			||||||
		HasFccdfs          bool    `json:"has_fccdfs,omitempty"`
 | 
					 | 
				
			||||||
		Is11Ac             bool    `json:"is_11ac,omitempty"`
 | 
					 | 
				
			||||||
	} `json:"radio_table"`
 | 
					 | 
				
			||||||
	RadioTableStats []struct {
 | 
					 | 
				
			||||||
		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          float64       `json:"rx_bytes"`
 | 
					 | 
				
			||||||
	RxBytesD         float64       `json:"rx_bytes-d"`
 | 
					 | 
				
			||||||
	ScanRadioTable   []interface{} `json:"scan_radio_table"`
 | 
					 | 
				
			||||||
	Scanning         bool          `json:"scanning"`
 | 
					 | 
				
			||||||
	Serial           string        `json:"serial"`
 | 
					 | 
				
			||||||
	SiteID           string        `json:"site_id"`
 | 
					 | 
				
			||||||
	SpectrumScanning bool          `json:"spectrum_scanning"`
 | 
					 | 
				
			||||||
	SSHSessionTable  []interface{} `json:"ssh_session_table"`
 | 
					 | 
				
			||||||
	Stat             struct {
 | 
					 | 
				
			||||||
		Ap                 string  `json:"ap"`
 | 
					 | 
				
			||||||
		Bytes              float64 `json:"bytes"`
 | 
					 | 
				
			||||||
		Datetime           string  `json:"datetime"`
 | 
					 | 
				
			||||||
		Duration           float64 `json:"duration"`
 | 
					 | 
				
			||||||
		GuestRxBytes       float64 `json:"guest-rx_bytes"`
 | 
					 | 
				
			||||||
		GuestRxCrypts      float64 `json:"guest-rx_crypts"`
 | 
					 | 
				
			||||||
		GuestRxDropped     float64 `json:"guest-rx_dropped"`
 | 
					 | 
				
			||||||
		GuestRxErrors      float64 `json:"guest-rx_errors"`
 | 
					 | 
				
			||||||
		GuestRxFrags       float64 `json:"guest-rx_frags"`
 | 
					 | 
				
			||||||
		GuestRxPackets     float64 `json:"guest-rx_packets"`
 | 
					 | 
				
			||||||
		GuestTxBytes       float64 `json:"guest-tx_bytes"`
 | 
					 | 
				
			||||||
		GuestTxDropped     float64 `json:"guest-tx_dropped"`
 | 
					 | 
				
			||||||
		GuestTxErrors      float64 `json:"guest-tx_errors"`
 | 
					 | 
				
			||||||
		GuestTxPackets     float64 `json:"guest-tx_packets"`
 | 
					 | 
				
			||||||
		GuestTxRetries     float64 `json:"guest-tx_retries"`
 | 
					 | 
				
			||||||
		O                  string  `json:"o"`
 | 
					 | 
				
			||||||
		Oid                string  `json:"oid"`
 | 
					 | 
				
			||||||
		Port1RxBroadcast   float64 `json:"port_1-rx_broadcast"`
 | 
					 | 
				
			||||||
		Port1RxBytes       float64 `json:"port_1-rx_bytes"`
 | 
					 | 
				
			||||||
		Port1RxMulticast   float64 `json:"port_1-rx_multicast"`
 | 
					 | 
				
			||||||
		Port1RxPackets     float64 `json:"port_1-rx_packets"`
 | 
					 | 
				
			||||||
		Port1TxBroadcast   float64 `json:"port_1-tx_broadcast"`
 | 
					 | 
				
			||||||
		Port1TxBytes       float64 `json:"port_1-tx_bytes"`
 | 
					 | 
				
			||||||
		Port1TxMulticast   float64 `json:"port_1-tx_multicast"`
 | 
					 | 
				
			||||||
		Port1TxPackets     float64 `json:"port_1-tx_packets"`
 | 
					 | 
				
			||||||
		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"`
 | 
					 | 
				
			||||||
		RxPackets          float64 `json:"rx_packets"`
 | 
					 | 
				
			||||||
		SiteID             string  `json:"site_id"`
 | 
					 | 
				
			||||||
		Time               float64 `json:"time"`
 | 
					 | 
				
			||||||
		TxBytes            float64 `json:"tx_bytes"`
 | 
					 | 
				
			||||||
		TxDropped          float64 `json:"tx_dropped"`
 | 
					 | 
				
			||||||
		TxErrors           float64 `json:"tx_errors"`
 | 
					 | 
				
			||||||
		TxPackets          float64 `json:"tx_packets"`
 | 
					 | 
				
			||||||
		TxRetries          float64 `json:"tx_retries"`
 | 
					 | 
				
			||||||
		UserRxBytes        float64 `json:"user-rx_bytes"`
 | 
					 | 
				
			||||||
		UserRxCrypts       float64 `json:"user-rx_crypts"`
 | 
					 | 
				
			||||||
		UserRxDropped      float64 `json:"user-rx_dropped"`
 | 
					 | 
				
			||||||
		UserRxErrors       float64 `json:"user-rx_errors"`
 | 
					 | 
				
			||||||
		UserRxFrags        float64 `json:"user-rx_frags"`
 | 
					 | 
				
			||||||
		UserRxPackets      float64 `json:"user-rx_packets"`
 | 
					 | 
				
			||||||
		UserTxBytes        float64 `json:"user-tx_bytes"`
 | 
					 | 
				
			||||||
		UserTxDropped      float64 `json:"user-tx_dropped"`
 | 
					 | 
				
			||||||
		UserTxErrors       float64 `json:"user-tx_errors"`
 | 
					 | 
				
			||||||
		UserTxPackets      float64 `json:"user-tx_packets"`
 | 
					 | 
				
			||||||
		UserTxRetries      float64 `json:"user-tx_retries"`
 | 
					 | 
				
			||||||
		UserWifi0RxBytes   float64 `json:"user-wifi0-rx_bytes"`
 | 
					 | 
				
			||||||
		UserWifi0RxCrypts  float64 `json:"user-wifi0-rx_crypts"`
 | 
					 | 
				
			||||||
		UserWifi0RxDropped float64 `json:"user-wifi0-rx_dropped"`
 | 
					 | 
				
			||||||
		UserWifi0RxErrors  float64 `json:"user-wifi0-rx_errors"`
 | 
					 | 
				
			||||||
		UserWifi0RxFrags   float64 `json:"user-wifi0-rx_frags"`
 | 
					 | 
				
			||||||
		UserWifi0RxPackets float64 `json:"user-wifi0-rx_packets"`
 | 
					 | 
				
			||||||
		UserWifi0TxBytes   float64 `json:"user-wifi0-tx_bytes"`
 | 
					 | 
				
			||||||
		UserWifi0TxDropped float64 `json:"user-wifi0-tx_dropped"`
 | 
					 | 
				
			||||||
		UserWifi0TxErrors  float64 `json:"user-wifi0-tx_errors"`
 | 
					 | 
				
			||||||
		UserWifi0TxPackets float64 `json:"user-wifi0-tx_packets"`
 | 
					 | 
				
			||||||
		UserWifi0TxRetries float64 `json:"user-wifi0-tx_retries"`
 | 
					 | 
				
			||||||
		UserWifi1RxBytes   float64 `json:"user-wifi1-rx_bytes"`
 | 
					 | 
				
			||||||
		UserWifi1RxCrypts  float64 `json:"user-wifi1-rx_crypts"`
 | 
					 | 
				
			||||||
		UserWifi1RxDropped float64 `json:"user-wifi1-rx_dropped"`
 | 
					 | 
				
			||||||
		UserWifi1RxErrors  float64 `json:"user-wifi1-rx_errors"`
 | 
					 | 
				
			||||||
		UserWifi1RxFrags   float64 `json:"user-wifi1-rx_frags"`
 | 
					 | 
				
			||||||
		UserWifi1RxPackets float64 `json:"user-wifi1-rx_packets"`
 | 
					 | 
				
			||||||
		UserWifi1TxBytes   float64 `json:"user-wifi1-tx_bytes"`
 | 
					 | 
				
			||||||
		UserWifi1TxDropped float64 `json:"user-wifi1-tx_dropped"`
 | 
					 | 
				
			||||||
		UserWifi1TxErrors  float64 `json:"user-wifi1-tx_errors"`
 | 
					 | 
				
			||||||
		UserWifi1TxPackets float64 `json:"user-wifi1-tx_packets"`
 | 
					 | 
				
			||||||
		UserWifi1TxRetries float64 `json:"user-wifi1-tx_retries"`
 | 
					 | 
				
			||||||
		Wifi0RxBytes       float64 `json:"wifi0-rx_bytes"`
 | 
					 | 
				
			||||||
		Wifi0RxCrypts      float64 `json:"wifi0-rx_crypts"`
 | 
					 | 
				
			||||||
		Wifi0RxDropped     float64 `json:"wifi0-rx_dropped"`
 | 
					 | 
				
			||||||
		Wifi0RxErrors      float64 `json:"wifi0-rx_errors"`
 | 
					 | 
				
			||||||
		Wifi0RxFrags       float64 `json:"wifi0-rx_frags"`
 | 
					 | 
				
			||||||
		Wifi0RxPackets     float64 `json:"wifi0-rx_packets"`
 | 
					 | 
				
			||||||
		Wifi0TxBytes       float64 `json:"wifi0-tx_bytes"`
 | 
					 | 
				
			||||||
		Wifi0TxDropped     float64 `json:"wifi0-tx_dropped"`
 | 
					 | 
				
			||||||
		Wifi0TxErrors      float64 `json:"wifi0-tx_errors"`
 | 
					 | 
				
			||||||
		Wifi0TxPackets     float64 `json:"wifi0-tx_packets"`
 | 
					 | 
				
			||||||
		Wifi0TxRetries     float64 `json:"wifi0-tx_retries"`
 | 
					 | 
				
			||||||
		Wifi1RxBytes       float64 `json:"wifi1-rx_bytes"`
 | 
					 | 
				
			||||||
		Wifi1RxCrypts      float64 `json:"wifi1-rx_crypts"`
 | 
					 | 
				
			||||||
		Wifi1RxDropped     float64 `json:"wifi1-rx_dropped"`
 | 
					 | 
				
			||||||
		Wifi1RxErrors      float64 `json:"wifi1-rx_errors"`
 | 
					 | 
				
			||||||
		Wifi1RxFrags       float64 `json:"wifi1-rx_frags"`
 | 
					 | 
				
			||||||
		Wifi1RxPackets     float64 `json:"wifi1-rx_packets"`
 | 
					 | 
				
			||||||
		Wifi1TxBytes       float64 `json:"wifi1-tx_bytes"`
 | 
					 | 
				
			||||||
		Wifi1TxDropped     float64 `json:"wifi1-tx_dropped"`
 | 
					 | 
				
			||||||
		Wifi1TxErrors      float64 `json:"wifi1-tx_errors"`
 | 
					 | 
				
			||||||
		Wifi1TxPackets     float64 `json:"wifi1-tx_packets"`
 | 
					 | 
				
			||||||
		Wifi1TxRetries     float64 `json:"wifi1-tx_retries"`
 | 
					 | 
				
			||||||
	} `json:"stat"`
 | 
					 | 
				
			||||||
	State    int `json:"state"`
 | 
					 | 
				
			||||||
	SysStats struct {
 | 
					 | 
				
			||||||
		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    float64 `json:"cpu,string"`
 | 
					 | 
				
			||||||
		Mem    float64 `json:"mem,string"`
 | 
					 | 
				
			||||||
		Uptime float64 `json:"uptime,string"`
 | 
					 | 
				
			||||||
	} `json:"system-stats"`
 | 
					 | 
				
			||||||
	TxBytes    float64 `json:"tx_bytes"`
 | 
					 | 
				
			||||||
	TxBytesD   float64 `json:"tx_bytes-d"`
 | 
					 | 
				
			||||||
	Type       string  `json:"type"`
 | 
					 | 
				
			||||||
	Upgradable bool    `json:"upgradable"`
 | 
					 | 
				
			||||||
	Uplink     struct {
 | 
					 | 
				
			||||||
		FullDuplex       bool    `json:"full_duplex"`
 | 
					 | 
				
			||||||
		IP               string  `json:"ip"`
 | 
					 | 
				
			||||||
		Mac              string  `json:"mac"`
 | 
					 | 
				
			||||||
		MaxSpeed         int     `json:"max_speed"`
 | 
					 | 
				
			||||||
		MaxVlan          int     `json:"max_vlan"`
 | 
					 | 
				
			||||||
		Media            string  `json:"media"`
 | 
					 | 
				
			||||||
		Name             string  `json:"name"`
 | 
					 | 
				
			||||||
		Netmask          string  `json:"netmask"`
 | 
					 | 
				
			||||||
		NumPort          int     `json:"num_port"`
 | 
					 | 
				
			||||||
		RxBytes          float64 `json:"rx_bytes"`
 | 
					 | 
				
			||||||
		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         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      FlexInt       `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               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"`
 | 
					 | 
				
			||||||
	VwireEnabled        bool          `json:"vwireEnabled"`
 | 
					 | 
				
			||||||
	VwireTable          []interface{} `json:"vwire_table"`
 | 
					 | 
				
			||||||
	VwireVapTable       []struct {
 | 
					 | 
				
			||||||
		Bssid     string `json:"bssid"`
 | 
					 | 
				
			||||||
		Radio     string `json:"radio"`
 | 
					 | 
				
			||||||
		RadioName string `json:"radio_name"`
 | 
					 | 
				
			||||||
		State     string `json:"state"`
 | 
					 | 
				
			||||||
	} `json:"vwire_vap_table"`
 | 
					 | 
				
			||||||
	WifiCaps int `json:"wifi_caps"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,105 +0,0 @@
 | 
				
			||||||
package unidev
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bytes"
 | 
					 | 
				
			||||||
	"crypto/tls"
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"log"
 | 
					 | 
				
			||||||
	"net/http"
 | 
					 | 
				
			||||||
	"net/http/cookiejar"
 | 
					 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	influx "github.com/influxdata/influxdb/client/v2"
 | 
					 | 
				
			||||||
	"github.com/pkg/errors"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// LoginPath is Unifi Controller Login API Path
 | 
					 | 
				
			||||||
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..
 | 
					 | 
				
			||||||
	Points() ([]*influx.Point, error)
 | 
					 | 
				
			||||||
	// Add more methods to achieve more usefulness from this library.
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// AuthedReq is what you get in return for providing a password!
 | 
					 | 
				
			||||||
type AuthedReq struct {
 | 
					 | 
				
			||||||
	*http.Client
 | 
					 | 
				
			||||||
	baseURL string
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// FlexInt provides a container and unmarshalling for fields that may be
 | 
					 | 
				
			||||||
// numbers or strings in the Unifi API
 | 
					 | 
				
			||||||
type FlexInt struct {
 | 
					 | 
				
			||||||
	Number float64
 | 
					 | 
				
			||||||
	String string
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// UnmarshalJSON converts a string or number to an integer.
 | 
					 | 
				
			||||||
func (f *FlexInt) UnmarshalJSON(b []byte) error {
 | 
					 | 
				
			||||||
	var unk interface{}
 | 
					 | 
				
			||||||
	if err := json.Unmarshal(b, &unk); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	switch i := unk.(type) {
 | 
					 | 
				
			||||||
	case float64:
 | 
					 | 
				
			||||||
		f.Number = i
 | 
					 | 
				
			||||||
		f.String = strconv.FormatFloat(i, 'f', -1, 64)
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	case string:
 | 
					 | 
				
			||||||
		f.String = i
 | 
					 | 
				
			||||||
		f.Number, _ = strconv.ParseFloat(i, 64)
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return errors.New("Cannot unmarshal to FlexInt")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// AuthController creates a http.Client with authenticated cookies.
 | 
					 | 
				
			||||||
// Used to make additional, authenticated requests to the APIs.
 | 
					 | 
				
			||||||
func AuthController(user, pass, url string, verifySSL bool) (*AuthedReq, error) {
 | 
					 | 
				
			||||||
	json := `{"username": "` + user + `","password": "` + pass + `"}`
 | 
					 | 
				
			||||||
	jar, err := cookiejar.New(nil)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, errors.Wrap(err, "cookiejar.New(nil)")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	a := &AuthedReq{&http.Client{
 | 
					 | 
				
			||||||
		Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: !verifySSL}},
 | 
					 | 
				
			||||||
		Jar:       jar,
 | 
					 | 
				
			||||||
	}, url}
 | 
					 | 
				
			||||||
	req, err := a.UniReq(LoginPath, json)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return a, errors.Wrap(err, "UniReq(LoginPath, json)")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	resp, err := a.Do(req)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return a, errors.Wrap(err, "authReq.Do(req)")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer func() {
 | 
					 | 
				
			||||||
		if err := resp.Body.Close(); err != nil {
 | 
					 | 
				
			||||||
			log.Println("resp.Body.Close():", err) // Not fatal. Just log it.
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}()
 | 
					 | 
				
			||||||
	if resp.StatusCode != http.StatusOK {
 | 
					 | 
				
			||||||
		return a, errors.Errorf("authentication failed (%v): %v (status: %v/%v)",
 | 
					 | 
				
			||||||
			user, url+LoginPath, resp.StatusCode, resp.Status)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return a, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// UniReq is a small helper function that adds an Accept header.
 | 
					 | 
				
			||||||
func (a AuthedReq) UniReq(apiPath string, params string) (req *http.Request, err error) {
 | 
					 | 
				
			||||||
	if params != "" {
 | 
					 | 
				
			||||||
		req, err = http.NewRequest("POST", a.baseURL+apiPath, bytes.NewBufferString(params))
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		req, err = http.NewRequest("GET", a.baseURL+apiPath, nil)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err == nil {
 | 
					 | 
				
			||||||
		req.Header.Add("Accept", "application/json")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,82 +0,0 @@
 | 
				
			||||||
package unidev
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"io/ioutil"
 | 
					 | 
				
			||||||
	"net/http"
 | 
					 | 
				
			||||||
	"testing"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/stretchr/testify/assert"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestFlexInt(t *testing.T) {
 | 
					 | 
				
			||||||
	t.Parallel()
 | 
					 | 
				
			||||||
	a := assert.New(t)
 | 
					 | 
				
			||||||
	type testReply struct {
 | 
					 | 
				
			||||||
		Five    FlexInt `json:"five"`
 | 
					 | 
				
			||||||
		Seven   FlexInt `json:"seven"`
 | 
					 | 
				
			||||||
		Auto    FlexInt `json:"auto"`
 | 
					 | 
				
			||||||
		Channel FlexInt `json:"channel"`
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	var r testReply
 | 
					 | 
				
			||||||
	// test unmarshalling the custom type three times with different values.
 | 
					 | 
				
			||||||
	a.Nil(json.Unmarshal([]byte(`{"five": "5", "seven": 7, "auto": "auto"}`), &r))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// test number in string.
 | 
					 | 
				
			||||||
	a.EqualValues(5, r.Five.Number)
 | 
					 | 
				
			||||||
	a.EqualValues("5", r.Five.String)
 | 
					 | 
				
			||||||
	// test number.
 | 
					 | 
				
			||||||
	a.EqualValues(7, r.Seven.Number)
 | 
					 | 
				
			||||||
	a.EqualValues("7", r.Seven.String)
 | 
					 | 
				
			||||||
	// test string.
 | 
					 | 
				
			||||||
	a.EqualValues(0, r.Auto.Number)
 | 
					 | 
				
			||||||
	a.EqualValues("auto", r.Auto.String)
 | 
					 | 
				
			||||||
	// test (error) struct.
 | 
					 | 
				
			||||||
	a.NotNil(json.Unmarshal([]byte(`{"channel": {}}`), &r),
 | 
					 | 
				
			||||||
		"a non-string and non-number must produce an error.")
 | 
					 | 
				
			||||||
	a.EqualValues(0, r.Channel.Number)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestUniReq(t *testing.T) {
 | 
					 | 
				
			||||||
	t.Parallel()
 | 
					 | 
				
			||||||
	a := assert.New(t)
 | 
					 | 
				
			||||||
	u := "/test/path"
 | 
					 | 
				
			||||||
	url := "http://some.url:8443"
 | 
					 | 
				
			||||||
	// Test empty parameters.
 | 
					 | 
				
			||||||
	authReq := &AuthedReq{&http.Client{}, url}
 | 
					 | 
				
			||||||
	r, err := authReq.UniReq(u, "")
 | 
					 | 
				
			||||||
	a.Nil(err, "newrequest must not produce an error")
 | 
					 | 
				
			||||||
	a.EqualValues(u, r.URL.Path,
 | 
					 | 
				
			||||||
		"the provided apiPath was not added to http request")
 | 
					 | 
				
			||||||
	a.EqualValues(url, r.URL.Scheme+"://"+r.URL.Host, "URL improperly encoded")
 | 
					 | 
				
			||||||
	a.EqualValues("GET", r.Method, "without parameters the method must be GET")
 | 
					 | 
				
			||||||
	a.EqualValues("application/json", r.Header.Get("Accept"), "Accept header must be set to application/json")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Test with parameters
 | 
					 | 
				
			||||||
	p := "key1=value9&key2=value7"
 | 
					 | 
				
			||||||
	authReq = &AuthedReq{&http.Client{}, "http://some.url:8443"}
 | 
					 | 
				
			||||||
	r, err = authReq.UniReq(u, p)
 | 
					 | 
				
			||||||
	a.Nil(err, "newrequest must not produce an error")
 | 
					 | 
				
			||||||
	a.EqualValues(u, r.URL.Path,
 | 
					 | 
				
			||||||
		"the provided apiPath was not added to http request")
 | 
					 | 
				
			||||||
	a.EqualValues(url, r.URL.Scheme+"://"+r.URL.Host, "URL improperly encoded")
 | 
					 | 
				
			||||||
	a.EqualValues("POST", r.Method, "with parameters the method must be POST")
 | 
					 | 
				
			||||||
	a.EqualValues("application/json", r.Header.Get("Accept"), "Accept header must be set to application/json")
 | 
					 | 
				
			||||||
	// Check the parameters.
 | 
					 | 
				
			||||||
	d, err := ioutil.ReadAll(r.Body)
 | 
					 | 
				
			||||||
	a.Nil(err, "problem reading request body, POST parameters may be malformed")
 | 
					 | 
				
			||||||
	a.EqualValues(p, string(d), "POST parameters improperly encoded")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestAuthController(t *testing.T) {
 | 
					 | 
				
			||||||
	t.Parallel()
 | 
					 | 
				
			||||||
	a := assert.New(t)
 | 
					 | 
				
			||||||
	url := "http://127.0.0.1:64431"
 | 
					 | 
				
			||||||
	authReq, err := AuthController("user1", "pass2", url, false)
 | 
					 | 
				
			||||||
	a.NotNil(err)
 | 
					 | 
				
			||||||
	a.EqualValues(url, authReq.baseURL)
 | 
					 | 
				
			||||||
	a.Contains(err.Error(), "authReq.Do(req):", "an invalid destination should product a .Do(req) error.")
 | 
					 | 
				
			||||||
	/* TODO: OPEN web server, check parameters posted, more. This test is incomplete.
 | 
					 | 
				
			||||||
	a.EqualValues(`{"username": "user1","password": "pass2"}`, string(post_params), "user/pass json parameters improperly encoded")
 | 
					 | 
				
			||||||
	*/
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,154 +0,0 @@
 | 
				
			||||||
package unidev
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"io/ioutil"
 | 
					 | 
				
			||||||
	"log"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/pkg/errors"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Debug ....
 | 
					 | 
				
			||||||
var Debug = false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	// ClientPath is Unifi Clients API Path
 | 
					 | 
				
			||||||
	ClientPath = "/api/s/default/stat/sta"
 | 
					 | 
				
			||||||
	// DevicePath is where we get data about Unifi devices.
 | 
					 | 
				
			||||||
	DevicePath = "/api/s/default/stat/device"
 | 
					 | 
				
			||||||
	// NetworkPath contains network-configuration data. Not really graphable.
 | 
					 | 
				
			||||||
	NetworkPath = "/api/s/default/rest/networkconf"
 | 
					 | 
				
			||||||
	// UserGroupPath contains usergroup configurations.
 | 
					 | 
				
			||||||
	UserGroupPath = "/api/s/default/rest/usergroup"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// GetUnifiClients returns a response full of clients' data from the Unifi Controller.
 | 
					 | 
				
			||||||
func (c *AuthedReq) GetUnifiClients() ([]UCL, error) {
 | 
					 | 
				
			||||||
	var response struct {
 | 
					 | 
				
			||||||
		Clients []UCL `json:"data"`
 | 
					 | 
				
			||||||
		Meta    struct {
 | 
					 | 
				
			||||||
			Rc string `json:"rc"`
 | 
					 | 
				
			||||||
		} `json:"meta"`
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	req, err := c.UniReq(ClientPath, "")
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, errors.Wrap(err, "c.UniReq(ClientPath)")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	resp, err := c.Do(req)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, errors.Wrap(err, "c.Do(req)")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer func() {
 | 
					 | 
				
			||||||
		if err := resp.Body.Close(); err != nil {
 | 
					 | 
				
			||||||
			log.Println("resp.Body.Close():", err) // Not fatal? Just log it.
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}()
 | 
					 | 
				
			||||||
	if body, err := ioutil.ReadAll(resp.Body); err != nil {
 | 
					 | 
				
			||||||
		return nil, errors.Wrap(err, "ioutil.ReadAll(resp.Body)")
 | 
					 | 
				
			||||||
	} else if err = json.Unmarshal(body, &response); err != nil {
 | 
					 | 
				
			||||||
		return nil, errors.Wrap(err, "json.Unmarshal([]UCL)")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	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 assets, err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// GetUnifiDevices returns a response full of devices' data from the Unifi Controller.
 | 
					 | 
				
			||||||
func (c *AuthedReq) GetUnifiDevices() ([]USG, []USW, []UAP, error) {
 | 
					 | 
				
			||||||
	var parsed struct {
 | 
					 | 
				
			||||||
		Data []json.RawMessage `json:"data"`
 | 
					 | 
				
			||||||
		Meta struct {
 | 
					 | 
				
			||||||
			Rc string `json:"rc"`
 | 
					 | 
				
			||||||
		} `json:"meta"`
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	req, err := c.UniReq(DevicePath, "")
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, nil, nil, errors.Wrap(err, "c.UniReq(DevicePath)")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	resp, err := c.Do(req)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, nil, nil, errors.Wrap(err, "c.Do(req)")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer func() {
 | 
					 | 
				
			||||||
		if err := resp.Body.Close(); err != nil {
 | 
					 | 
				
			||||||
			log.Println("resp.Body.Close():", err) // Not fatal? Just log it.
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}()
 | 
					 | 
				
			||||||
	if body, err := ioutil.ReadAll(resp.Body); err != nil {
 | 
					 | 
				
			||||||
		return nil, nil, nil, errors.Wrap(err, "ioutil.ReadAll(resp.Body)")
 | 
					 | 
				
			||||||
	} else if err = json.Unmarshal(body, &parsed); err != nil {
 | 
					 | 
				
			||||||
		return nil, nil, nil, errors.Wrap(err, "json.Unmarshal([]json.RawMessage)")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var usgs []USG
 | 
					 | 
				
			||||||
	var usws []USW
 | 
					 | 
				
			||||||
	var uaps []UAP
 | 
					 | 
				
			||||||
	// Loop each item in the raw JSON message, detect its type and unmarshal it.
 | 
					 | 
				
			||||||
	for i, 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, nil, nil, errors.Wrapf(err, "[%d] json.Unmarshal(interfce{})", i)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		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..
 | 
					 | 
				
			||||||
		switch assetType {
 | 
					 | 
				
			||||||
		case "uap":
 | 
					 | 
				
			||||||
			if err := json.Unmarshal(r, &uap); err != nil {
 | 
					 | 
				
			||||||
				return nil, nil, nil, errors.Wrapf(err, "[%d] json.Unmarshal([]UAP)", i)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			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, errors.Wrapf(err, "[%d] json.Unmarshal([]USG)", i)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			usgs = append(usgs, usg)
 | 
					 | 
				
			||||||
		case "usw":
 | 
					 | 
				
			||||||
			if err := json.Unmarshal(r, &usw); err != nil {
 | 
					 | 
				
			||||||
				return nil, nil, nil, errors.Wrapf(err, "[%d] json.Unmarshal([]USW)", i)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			usws = append(usws, usw)
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			log.Println("unknown asset type -", assetType, "- skipping")
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	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
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,186 +0,0 @@
 | 
				
			||||||
package unidev
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
	"time"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	influx "github.com/influxdata/influxdb/client/v2"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 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,
 | 
					 | 
				
			||||||
		"device_type":            u.Stat.O,
 | 
					 | 
				
			||||||
		"device_oid":             u.Stat.Oid,
 | 
					 | 
				
			||||||
		"site_id":                u.SiteID,
 | 
					 | 
				
			||||||
		"addopted":               strconv.FormatBool(u.Adopted),
 | 
					 | 
				
			||||||
		"name":                   u.Name,
 | 
					 | 
				
			||||||
		"adopt_ip":               u.AdoptIP,
 | 
					 | 
				
			||||||
		"adopt_url":              u.AdoptURL,
 | 
					 | 
				
			||||||
		"cfgversion":             u.Cfgversion,
 | 
					 | 
				
			||||||
		"config_network_ip":      u.ConfigNetwork.IP,
 | 
					 | 
				
			||||||
		"config_network_type":    u.ConfigNetwork.Type,
 | 
					 | 
				
			||||||
		"connect_request_ip":     u.ConnectRequestIP,
 | 
					 | 
				
			||||||
		"connect_request_port":   u.ConnectRequestPort,
 | 
					 | 
				
			||||||
		"default":                strconv.FormatBool(u.Default),
 | 
					 | 
				
			||||||
		"device_id":              u.DeviceID,
 | 
					 | 
				
			||||||
		"discovered_via":         u.DiscoveredVia,
 | 
					 | 
				
			||||||
		"guest_token":            u.GuestToken,
 | 
					 | 
				
			||||||
		"inform_ip":              u.InformIP,
 | 
					 | 
				
			||||||
		"known_cfgversion":       u.KnownCfgversion,
 | 
					 | 
				
			||||||
		"led_override":           u.LedOverride,
 | 
					 | 
				
			||||||
		"locating":               strconv.FormatBool(u.Locating),
 | 
					 | 
				
			||||||
		"model":                  u.Model,
 | 
					 | 
				
			||||||
		"outdoor_mode_override":  u.OutdoorModeOverride,
 | 
					 | 
				
			||||||
		"serial":                 u.Serial,
 | 
					 | 
				
			||||||
		"type":                   u.Type,
 | 
					 | 
				
			||||||
		"version_incompatible":   strconv.FormatBool(u.VersionIncompatible),
 | 
					 | 
				
			||||||
		"usg_caps":               strconv.FormatFloat(u.UsgCaps, 'f', 6, 64),
 | 
					 | 
				
			||||||
		"speedtest-status-saved": strconv.FormatBool(u.SpeedtestStatusSaved),
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	fields := map[string]interface{}{
 | 
					 | 
				
			||||||
		"ip":                             u.IP,
 | 
					 | 
				
			||||||
		"bytes":                          u.Bytes,
 | 
					 | 
				
			||||||
		"last_seen":                      u.LastSeen,
 | 
					 | 
				
			||||||
		"license_state":                  u.LicenseState,
 | 
					 | 
				
			||||||
		"fw_caps":                        u.FwCaps,
 | 
					 | 
				
			||||||
		"guest-num_sta":                  u.GuestNumSta,
 | 
					 | 
				
			||||||
		"rx_bytes":                       u.RxBytes,
 | 
					 | 
				
			||||||
		"tx_bytes":                       u.TxBytes,
 | 
					 | 
				
			||||||
		"uptime":                         u.Uptime,
 | 
					 | 
				
			||||||
		"considered_lost_at":             u.ConsideredLostAt,
 | 
					 | 
				
			||||||
		"next_heartbeat_at":              u.NextHeartbeatAt,
 | 
					 | 
				
			||||||
		"roll_upgrade":                   u.Rollupgrade,
 | 
					 | 
				
			||||||
		"state":                          u.State,
 | 
					 | 
				
			||||||
		"upgradable":                     u.Upgradable,
 | 
					 | 
				
			||||||
		"user-num_sta":                   u.UserNumSta,
 | 
					 | 
				
			||||||
		"version":                        u.Version,
 | 
					 | 
				
			||||||
		"num_desktop":                    u.NumDesktop,
 | 
					 | 
				
			||||||
		"num_handheld":                   u.NumHandheld,
 | 
					 | 
				
			||||||
		"num_mobile":                     u.NumMobile,
 | 
					 | 
				
			||||||
		"speedtest-status_latency":       u.SpeedtestStatus.Latency,
 | 
					 | 
				
			||||||
		"speedtest-status_rundate":       u.SpeedtestStatus.Rundate,
 | 
					 | 
				
			||||||
		"speedtest-status_runtime":       u.SpeedtestStatus.Runtime,
 | 
					 | 
				
			||||||
		"speedtest-status_download":      u.SpeedtestStatus.StatusDownload,
 | 
					 | 
				
			||||||
		"speedtest-status_ping":          u.SpeedtestStatus.StatusPing,
 | 
					 | 
				
			||||||
		"speedtest-status_summary":       u.SpeedtestStatus.StatusSummary,
 | 
					 | 
				
			||||||
		"speedtest-status_upload":        u.SpeedtestStatus.StatusUpload,
 | 
					 | 
				
			||||||
		"speedtest-status_xput_download": u.SpeedtestStatus.XputDownload,
 | 
					 | 
				
			||||||
		"speedtest-status_xput_upload":   u.SpeedtestStatus.XputUpload,
 | 
					 | 
				
			||||||
		// have two WANs? mmmm, go ahead and add it. ;)
 | 
					 | 
				
			||||||
		"config_network_wan_type": u.ConfigNetworkWan.Type,
 | 
					 | 
				
			||||||
		"wan1_bytes-r":            u.Wan1.BytesR,
 | 
					 | 
				
			||||||
		"wan1_enable":             u.Wan1.Enable,
 | 
					 | 
				
			||||||
		"wan1_full_duplex":        u.Wan1.FullDuplex,
 | 
					 | 
				
			||||||
		"wan1_purpose":            "uplink", // because it should have a purpose.
 | 
					 | 
				
			||||||
		"wan1_gateway":            u.Wan1.Gateway,
 | 
					 | 
				
			||||||
		"wan1_ifname":             u.Wan1.Ifname,
 | 
					 | 
				
			||||||
		"wan1_ip":                 u.Wan1.IP,
 | 
					 | 
				
			||||||
		"wan1_mac":                u.Wan1.Mac,
 | 
					 | 
				
			||||||
		"wan1_max_speed":          u.Wan1.MaxSpeed,
 | 
					 | 
				
			||||||
		"wan1_name":               u.Wan1.Name,
 | 
					 | 
				
			||||||
		"wan1_netmask":            u.Wan1.Netmask,
 | 
					 | 
				
			||||||
		"wan1_rx_bytes":           u.Wan1.RxBytes,
 | 
					 | 
				
			||||||
		"wan1_rx_bytes-r":         u.Wan1.RxBytesR,
 | 
					 | 
				
			||||||
		"wan1_rx_dropped":         u.Wan1.RxDropped,
 | 
					 | 
				
			||||||
		"wan1_rx_errors":          u.Wan1.RxErrors,
 | 
					 | 
				
			||||||
		"wan1_rx_multicast":       u.Wan1.RxMulticast,
 | 
					 | 
				
			||||||
		"wan1_rx_packets":         u.Wan1.RxPackets,
 | 
					 | 
				
			||||||
		"wan1_type":               u.Wan1.Type,
 | 
					 | 
				
			||||||
		"wan1_speed":              u.Wan1.Speed,
 | 
					 | 
				
			||||||
		"wan1_up":                 u.Wan1.Up,
 | 
					 | 
				
			||||||
		"wan1_tx_bytes":           u.Wan1.TxBytes,
 | 
					 | 
				
			||||||
		"wan1_tx_bytes-r":         u.Wan1.TxBytesR,
 | 
					 | 
				
			||||||
		"wan1_tx_dropped":         u.Wan1.TxDropped,
 | 
					 | 
				
			||||||
		"wan1_tx_errors":          u.Wan1.TxErrors,
 | 
					 | 
				
			||||||
		"wan1_tx_packets":         u.Wan1.TxPackets,
 | 
					 | 
				
			||||||
		"loadavg_1":               u.SysStats.Loadavg1,
 | 
					 | 
				
			||||||
		"loadavg_5":               u.SysStats.Loadavg5,
 | 
					 | 
				
			||||||
		"loadavg_15":              u.SysStats.Loadavg15,
 | 
					 | 
				
			||||||
		"mem_used":                u.SysStats.MemUsed,
 | 
					 | 
				
			||||||
		"mem_buffer":              u.SysStats.MemBuffer,
 | 
					 | 
				
			||||||
		"mem_total":               u.SysStats.MemTotal,
 | 
					 | 
				
			||||||
		"cpu":                     u.SystemStats.CPU,
 | 
					 | 
				
			||||||
		"mem":                     u.SystemStats.Mem,
 | 
					 | 
				
			||||||
		"system_uptime":           u.SystemStats.Uptime,
 | 
					 | 
				
			||||||
		"stat_duration":           u.Stat.Duration,
 | 
					 | 
				
			||||||
		"stat_datetime":           u.Stat.Datetime,
 | 
					 | 
				
			||||||
		"gw":                      u.Stat.Gw,
 | 
					 | 
				
			||||||
		"false":                   "false", // to fill holes in graphs.
 | 
					 | 
				
			||||||
		"lan-rx_bytes":            u.Stat.LanRxBytes,
 | 
					 | 
				
			||||||
		"lan-rx_packets":          u.Stat.LanRxPackets,
 | 
					 | 
				
			||||||
		"lan-tx_bytes":            u.Stat.LanTxBytes,
 | 
					 | 
				
			||||||
		"lan-tx_packets":          u.Stat.LanTxPackets,
 | 
					 | 
				
			||||||
		"wan-rx_bytes":            u.Stat.WanRxBytes,
 | 
					 | 
				
			||||||
		"wan-rx_dropped":          u.Stat.WanRxDropped,
 | 
					 | 
				
			||||||
		"wan-rx_packets":          u.Stat.WanRxPackets,
 | 
					 | 
				
			||||||
		"wan-tx_bytes":            u.Stat.WanTxBytes,
 | 
					 | 
				
			||||||
		"wan-tx_packets":          u.Stat.WanTxPackets,
 | 
					 | 
				
			||||||
		"uplink_name":             u.Uplink.Name,
 | 
					 | 
				
			||||||
		"uplink_latency":          u.Uplink.Latency,
 | 
					 | 
				
			||||||
		"uplink_speed":            u.Uplink.Speed,
 | 
					 | 
				
			||||||
		"uplink_num_ports":        u.Uplink.NumPort,
 | 
					 | 
				
			||||||
		"uplink_max_speed":        u.Uplink.MaxSpeed,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	pt, err := influx.NewPoint("usg", tags, fields, time.Now())
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	points = append(points, pt)
 | 
					 | 
				
			||||||
	for _, p := range u.NetworkTable {
 | 
					 | 
				
			||||||
		tags := map[string]string{
 | 
					 | 
				
			||||||
			"device_name":               u.Name,
 | 
					 | 
				
			||||||
			"device_id":                 u.ID,
 | 
					 | 
				
			||||||
			"device_mac":                u.Mac,
 | 
					 | 
				
			||||||
			"name":                      p.Name,
 | 
					 | 
				
			||||||
			"dhcpd_dns_enabled":         strconv.FormatBool(p.DhcpdDNSEnabled),
 | 
					 | 
				
			||||||
			"dhcpd_enabled":             strconv.FormatBool(p.DhcpdEnabled),
 | 
					 | 
				
			||||||
			"dhcpd_ntp_enabled":         strconv.FormatBool(p.DhcpdNtpEnabled),
 | 
					 | 
				
			||||||
			"dhcpd_time_offset_enabled": strconv.FormatBool(p.DhcpdTimeOffsetEnabled),
 | 
					 | 
				
			||||||
			"dhcp_relay_enabledy":       strconv.FormatBool(p.DhcpRelayEnabled),
 | 
					 | 
				
			||||||
			"dhcpd_gateway_enabled":     strconv.FormatBool(p.DhcpdGatewayEnabled),
 | 
					 | 
				
			||||||
			"dhcpd_wins_enabled":        strconv.FormatBool(p.DhcpdWinsEnabled),
 | 
					 | 
				
			||||||
			"dhcpguard_enabled":         strconv.FormatBool(p.DhcpguardEnabled),
 | 
					 | 
				
			||||||
			"enabled":                   strconv.FormatBool(p.Enabled),
 | 
					 | 
				
			||||||
			"vlan_enabled":              strconv.FormatBool(p.VlanEnabled),
 | 
					 | 
				
			||||||
			"attr_no_delete":            strconv.FormatBool(p.AttrNoDelete),
 | 
					 | 
				
			||||||
			"upnp_lan_enabled":          strconv.FormatBool(p.UpnpLanEnabled),
 | 
					 | 
				
			||||||
			"igmp_snooping":             strconv.FormatBool(p.IgmpSnooping),
 | 
					 | 
				
			||||||
			"is_guest":                  strconv.FormatBool(p.IsGuest),
 | 
					 | 
				
			||||||
			"is_nat":                    strconv.FormatBool(p.IsNat),
 | 
					 | 
				
			||||||
			"networkgroup":              p.Networkgroup,
 | 
					 | 
				
			||||||
			"site_id":                   p.SiteID,
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		fields := map[string]interface{}{
 | 
					 | 
				
			||||||
			"dhcpd_ip_1":             p.DhcpdIP1,
 | 
					 | 
				
			||||||
			"domain_name":            p.DomainName,
 | 
					 | 
				
			||||||
			"dhcpd_start":            p.DhcpdStart,
 | 
					 | 
				
			||||||
			"dhcpd_stop":             p.DhcpdStop,
 | 
					 | 
				
			||||||
			"ip":                     p.IP,
 | 
					 | 
				
			||||||
			"ip_subnet":              p.IPSubnet,
 | 
					 | 
				
			||||||
			"mac":                    p.Mac,
 | 
					 | 
				
			||||||
			"name":                   p.Name,
 | 
					 | 
				
			||||||
			"num_sta":                p.NumSta,
 | 
					 | 
				
			||||||
			"purpose":                p.Purpose,
 | 
					 | 
				
			||||||
			"rx_bytes":               p.RxBytes,
 | 
					 | 
				
			||||||
			"rx_packets":             p.RxPackets,
 | 
					 | 
				
			||||||
			"tx_bytes":               p.TxBytes,
 | 
					 | 
				
			||||||
			"tx_packets":             p.TxPackets,
 | 
					 | 
				
			||||||
			"up":                     p.Up,
 | 
					 | 
				
			||||||
			"vlan":                   p.Vlan,
 | 
					 | 
				
			||||||
			"dhcpd_ntp_1":            p.DhcpdNtp1,
 | 
					 | 
				
			||||||
			"dhcpd_unifi_controller": p.DhcpdUnifiController,
 | 
					 | 
				
			||||||
			"ipv6_interface_type":    p.Ipv6InterfaceType,
 | 
					 | 
				
			||||||
			"attr_hidden_id":         p.AttrHiddenID,
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		pt, err = influx.NewPoint("usg_networks", tags, fields, time.Now())
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return points, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		points = append(points, pt)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return points, err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,260 +0,0 @@
 | 
				
			||||||
package unidev
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "encoding/json"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// USG is a Unifi Security Gateway
 | 
					 | 
				
			||||||
type USG struct {
 | 
					 | 
				
			||||||
	ID            string  `json:"_id"`
 | 
					 | 
				
			||||||
	UUptime       float64 `json:"_uptime"`
 | 
					 | 
				
			||||||
	AdoptIP       string  `json:"adopt_ip"`
 | 
					 | 
				
			||||||
	AdoptURL      string  `json:"adopt_url"`
 | 
					 | 
				
			||||||
	Adopted       bool    `json:"adopted"`
 | 
					 | 
				
			||||||
	Bytes         float64 `json:"bytes"`
 | 
					 | 
				
			||||||
	Cfgversion    string  `json:"cfgversion"`
 | 
					 | 
				
			||||||
	ConfigNetwork struct {
 | 
					 | 
				
			||||||
		IP   string `json:"ip"`
 | 
					 | 
				
			||||||
		Type string `json:"type"`
 | 
					 | 
				
			||||||
	} `json:"config_network"`
 | 
					 | 
				
			||||||
	ConfigNetworkWan struct {
 | 
					 | 
				
			||||||
		Type string `json:"type"`
 | 
					 | 
				
			||||||
	} `json:"config_network_wan"`
 | 
					 | 
				
			||||||
	ConnectRequestIP   string  `json:"connect_request_ip"`
 | 
					 | 
				
			||||||
	ConnectRequestPort string  `json:"connect_request_port"`
 | 
					 | 
				
			||||||
	ConsideredLostAt   float64 `json:"considered_lost_at"`
 | 
					 | 
				
			||||||
	Default            bool    `json:"default"`
 | 
					 | 
				
			||||||
	DeviceID           string  `json:"device_id"`
 | 
					 | 
				
			||||||
	DiscoveredVia      string  `json:"discovered_via"`
 | 
					 | 
				
			||||||
	EthernetTable      []struct {
 | 
					 | 
				
			||||||
		Mac     string  `json:"mac"`
 | 
					 | 
				
			||||||
		Name    string  `json:"name"`
 | 
					 | 
				
			||||||
		NumPort float64 `json:"num_port"`
 | 
					 | 
				
			||||||
	} `json:"ethernet_table"`
 | 
					 | 
				
			||||||
	FwCaps          float64 `json:"fw_caps"`
 | 
					 | 
				
			||||||
	GuestNumSta     float64 `json:"guest-num_sta"`
 | 
					 | 
				
			||||||
	GuestToken      string  `json:"guest_token"`
 | 
					 | 
				
			||||||
	InformIP        string  `json:"inform_ip"`
 | 
					 | 
				
			||||||
	InformURL       string  `json:"inform_url"`
 | 
					 | 
				
			||||||
	IP              string  `json:"ip"`
 | 
					 | 
				
			||||||
	KnownCfgversion string  `json:"known_cfgversion"`
 | 
					 | 
				
			||||||
	LastSeen        float64 `json:"last_seen"`
 | 
					 | 
				
			||||||
	LedOverride     string  `json:"led_override"`
 | 
					 | 
				
			||||||
	LicenseState    string  `json:"license_state"`
 | 
					 | 
				
			||||||
	Locating        bool    `json:"locating"`
 | 
					 | 
				
			||||||
	Mac             string  `json:"mac"`
 | 
					 | 
				
			||||||
	Model           string  `json:"model"`
 | 
					 | 
				
			||||||
	Name            string  `json:"name"`
 | 
					 | 
				
			||||||
	NetworkTable    []struct {
 | 
					 | 
				
			||||||
		ID                     string      `json:"_id"`
 | 
					 | 
				
			||||||
		DhcpdDNSEnabled        bool        `json:"dhcpd_dns_enabled"`
 | 
					 | 
				
			||||||
		DhcpdEnabled           bool        `json:"dhcpd_enabled"`
 | 
					 | 
				
			||||||
		DhcpdIP1               string      `json:"dhcpd_ip_1,omitempty"`
 | 
					 | 
				
			||||||
		DhcpdLeasetime         json.Number `json:"dhcpd_leasetime,Number"`
 | 
					 | 
				
			||||||
		DhcpdStart             string      `json:"dhcpd_start"`
 | 
					 | 
				
			||||||
		DhcpdStop              string      `json:"dhcpd_stop"`
 | 
					 | 
				
			||||||
		DhcpdWinsEnabled       bool        `json:"dhcpd_wins_enabled,omitempty"`
 | 
					 | 
				
			||||||
		DhcpguardEnabled       bool        `json:"dhcpguard_enabled,omitempty"`
 | 
					 | 
				
			||||||
		DomainName             string      `json:"domain_name"`
 | 
					 | 
				
			||||||
		Enabled                bool        `json:"enabled"`
 | 
					 | 
				
			||||||
		IgmpSnooping           bool        `json:"igmp_snooping,omitempty"`
 | 
					 | 
				
			||||||
		IP                     string      `json:"ip"`
 | 
					 | 
				
			||||||
		IPSubnet               string      `json:"ip_subnet"`
 | 
					 | 
				
			||||||
		IsGuest                bool        `json:"is_guest"`
 | 
					 | 
				
			||||||
		IsNat                  bool        `json:"is_nat"`
 | 
					 | 
				
			||||||
		Mac                    string      `json:"mac"`
 | 
					 | 
				
			||||||
		Name                   string      `json:"name"`
 | 
					 | 
				
			||||||
		Networkgroup           string      `json:"networkgroup"`
 | 
					 | 
				
			||||||
		NumSta                 float64     `json:"num_sta"`
 | 
					 | 
				
			||||||
		Purpose                string      `json:"purpose"`
 | 
					 | 
				
			||||||
		RxBytes                float64     `json:"rx_bytes"`
 | 
					 | 
				
			||||||
		RxPackets              float64     `json:"rx_packets"`
 | 
					 | 
				
			||||||
		SiteID                 string      `json:"site_id"`
 | 
					 | 
				
			||||||
		TxBytes                float64     `json:"tx_bytes"`
 | 
					 | 
				
			||||||
		TxPackets              float64     `json:"tx_packets"`
 | 
					 | 
				
			||||||
		Up                     string      `json:"up"`
 | 
					 | 
				
			||||||
		Vlan                   string      `json:"vlan,omitempty"`
 | 
					 | 
				
			||||||
		VlanEnabled            bool        `json:"vlan_enabled"`
 | 
					 | 
				
			||||||
		DhcpRelayEnabled       bool        `json:"dhcp_relay_enabled,omitempty"`
 | 
					 | 
				
			||||||
		DhcpdGatewayEnabled    bool        `json:"dhcpd_gateway_enabled,omitempty"`
 | 
					 | 
				
			||||||
		DhcpdNtp1              string      `json:"dhcpd_ntp_1,omitempty"`
 | 
					 | 
				
			||||||
		DhcpdNtpEnabled        bool        `json:"dhcpd_ntp_enabled,omitempty"`
 | 
					 | 
				
			||||||
		DhcpdTimeOffsetEnabled bool        `json:"dhcpd_time_offset_enabled,omitempty"`
 | 
					 | 
				
			||||||
		DhcpdUnifiController   string      `json:"dhcpd_unifi_controller,omitempty"`
 | 
					 | 
				
			||||||
		Ipv6InterfaceType      string      `json:"ipv6_interface_type,omitempty"`
 | 
					 | 
				
			||||||
		AttrHiddenID           string      `json:"attr_hidden_id,omitempty"`
 | 
					 | 
				
			||||||
		AttrNoDelete           bool        `json:"attr_no_delete,omitempty"`
 | 
					 | 
				
			||||||
		UpnpLanEnabled         bool        `json:"upnp_lan_enabled,omitempty"`
 | 
					 | 
				
			||||||
	} `json:"network_table"`
 | 
					 | 
				
			||||||
	NextHeartbeatAt     float64 `json:"next_heartbeat_at"`
 | 
					 | 
				
			||||||
	NumDesktop          float64 `json:"num_desktop"`
 | 
					 | 
				
			||||||
	NumHandheld         float64 `json:"num_handheld"`
 | 
					 | 
				
			||||||
	NumMobile           float64 `json:"num_mobile"`
 | 
					 | 
				
			||||||
	NumSta              float64 `json:"num_sta"`
 | 
					 | 
				
			||||||
	OutdoorModeOverride string  `json:"outdoor_mode_override"`
 | 
					 | 
				
			||||||
	PortTable           []struct {
 | 
					 | 
				
			||||||
		DNS         []string `json:"dns,omitempty"`
 | 
					 | 
				
			||||||
		Enable      bool     `json:"enable"`
 | 
					 | 
				
			||||||
		FullDuplex  bool     `json:"full_duplex"`
 | 
					 | 
				
			||||||
		Gateway     string   `json:"gateway,omitempty"`
 | 
					 | 
				
			||||||
		Ifname      string   `json:"ifname"`
 | 
					 | 
				
			||||||
		IP          string   `json:"ip"`
 | 
					 | 
				
			||||||
		Mac         string   `json:"mac"`
 | 
					 | 
				
			||||||
		Name        string   `json:"name"`
 | 
					 | 
				
			||||||
		Netmask     string   `json:"netmask"`
 | 
					 | 
				
			||||||
		RxBytes     float64  `json:"rx_bytes"`
 | 
					 | 
				
			||||||
		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"`
 | 
					 | 
				
			||||||
		TxDropped   float64  `json:"tx_dropped"`
 | 
					 | 
				
			||||||
		TxErrors    float64  `json:"tx_errors"`
 | 
					 | 
				
			||||||
		TxPackets   float64  `json:"tx_packets"`
 | 
					 | 
				
			||||||
		Up          bool     `json:"up"`
 | 
					 | 
				
			||||||
	} `json:"port_table"`
 | 
					 | 
				
			||||||
	Rollupgrade     bool    `json:"rollupgrade"`
 | 
					 | 
				
			||||||
	RxBytes         float64 `json:"rx_bytes"`
 | 
					 | 
				
			||||||
	Serial          string  `json:"serial"`
 | 
					 | 
				
			||||||
	SiteID          string  `json:"site_id"`
 | 
					 | 
				
			||||||
	SpeedtestStatus struct {
 | 
					 | 
				
			||||||
		Latency        float64 `json:"latency"`
 | 
					 | 
				
			||||||
		Rundate        float64 `json:"rundate"`
 | 
					 | 
				
			||||||
		Runtime        float64 `json:"runtime"`
 | 
					 | 
				
			||||||
		StatusDownload float64 `json:"status_download"`
 | 
					 | 
				
			||||||
		StatusPing     float64 `json:"status_ping"`
 | 
					 | 
				
			||||||
		StatusSummary  float64 `json:"status_summary"`
 | 
					 | 
				
			||||||
		StatusUpload   float64 `json:"status_upload"`
 | 
					 | 
				
			||||||
		XputDownload   float64 `json:"xput_download"`
 | 
					 | 
				
			||||||
		XputUpload     float64 `json:"xput_upload"`
 | 
					 | 
				
			||||||
	} `json:"speedtest-status"`
 | 
					 | 
				
			||||||
	SpeedtestStatusSaved bool `json:"speedtest-status-saved"`
 | 
					 | 
				
			||||||
	Stat                 struct {
 | 
					 | 
				
			||||||
		Datetime     string  `json:"datetime"`
 | 
					 | 
				
			||||||
		Duration     float64 `json:"duration"`
 | 
					 | 
				
			||||||
		Gw           string  `json:"gw"`
 | 
					 | 
				
			||||||
		LanRxBytes   float64 `json:"lan-rx_bytes"`
 | 
					 | 
				
			||||||
		LanRxPackets float64 `json:"lan-rx_packets"`
 | 
					 | 
				
			||||||
		LanTxBytes   float64 `json:"lan-tx_bytes"`
 | 
					 | 
				
			||||||
		LanTxPackets float64 `json:"lan-tx_packets"`
 | 
					 | 
				
			||||||
		O            string  `json:"o"`
 | 
					 | 
				
			||||||
		Oid          string  `json:"oid"`
 | 
					 | 
				
			||||||
		SiteID       string  `json:"site_id"`
 | 
					 | 
				
			||||||
		Time         float64 `json:"time"`
 | 
					 | 
				
			||||||
		WanRxBytes   float64 `json:"wan-rx_bytes"`
 | 
					 | 
				
			||||||
		WanRxDropped float64 `json:"wan-rx_dropped"`
 | 
					 | 
				
			||||||
		WanRxPackets float64 `json:"wan-rx_packets"`
 | 
					 | 
				
			||||||
		WanTxBytes   float64 `json:"wan-tx_bytes"`
 | 
					 | 
				
			||||||
		WanTxPackets float64 `json:"wan-tx_packets"`
 | 
					 | 
				
			||||||
	} `json:"stat"`
 | 
					 | 
				
			||||||
	State    float64 `json:"state"`
 | 
					 | 
				
			||||||
	SysStats struct {
 | 
					 | 
				
			||||||
		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    float64 `json:"cpu,string"`
 | 
					 | 
				
			||||||
		Mem    float64 `json:"mem,string"`
 | 
					 | 
				
			||||||
		Uptime float64 `json:"uptime,string"`
 | 
					 | 
				
			||||||
	} `json:"system-stats"`
 | 
					 | 
				
			||||||
	TxBytes    float64 `json:"tx_bytes"`
 | 
					 | 
				
			||||||
	Type       string  `json:"type"`
 | 
					 | 
				
			||||||
	Upgradable bool    `json:"upgradable"`
 | 
					 | 
				
			||||||
	Uplink     struct {
 | 
					 | 
				
			||||||
		BytesR           float64  `json:"bytes-r"`
 | 
					 | 
				
			||||||
		Drops            float64  `json:"drops"`
 | 
					 | 
				
			||||||
		Enable           bool     `json:"enable"`
 | 
					 | 
				
			||||||
		FullDuplex       bool     `json:"full_duplex"`
 | 
					 | 
				
			||||||
		Gateways         []string `json:"gateways"`
 | 
					 | 
				
			||||||
		IP               string   `json:"ip"`
 | 
					 | 
				
			||||||
		Latency          float64  `json:"latency"`
 | 
					 | 
				
			||||||
		Mac              string   `json:"mac"`
 | 
					 | 
				
			||||||
		MaxSpeed         float64  `json:"max_speed"`
 | 
					 | 
				
			||||||
		Name             string   `json:"name"`
 | 
					 | 
				
			||||||
		Nameservers      []string `json:"nameservers"`
 | 
					 | 
				
			||||||
		Netmask          string   `json:"netmask"`
 | 
					 | 
				
			||||||
		NumPort          float64  `json:"num_port"`
 | 
					 | 
				
			||||||
		RxBytes          float64  `json:"rx_bytes"`
 | 
					 | 
				
			||||||
		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"`
 | 
					 | 
				
			||||||
		SpeedtestLastrun float64  `json:"speedtest_lastrun"`
 | 
					 | 
				
			||||||
		SpeedtestPing    float64  `json:"speedtest_ping"`
 | 
					 | 
				
			||||||
		SpeedtestStatus  string   `json:"speedtest_status"`
 | 
					 | 
				
			||||||
		TxBytes          float64  `json:"tx_bytes"`
 | 
					 | 
				
			||||||
		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"`
 | 
					 | 
				
			||||||
		Uptime           float64  `json:"uptime"`
 | 
					 | 
				
			||||||
		XputDown         float64  `json:"xput_down"`
 | 
					 | 
				
			||||||
		XputUp           float64  `json:"xput_up"`
 | 
					 | 
				
			||||||
	} `json:"uplink"`
 | 
					 | 
				
			||||||
	Uptime              float64 `json:"uptime"`
 | 
					 | 
				
			||||||
	UserNumSta          float64 `json:"user-num_sta"`
 | 
					 | 
				
			||||||
	UsgCaps             float64 `json:"usg_caps"`
 | 
					 | 
				
			||||||
	Version             string  `json:"version"`
 | 
					 | 
				
			||||||
	VersionIncompatible bool    `json:"version_incompatible"`
 | 
					 | 
				
			||||||
	Wan1                struct {
 | 
					 | 
				
			||||||
		BytesR      float64  `json:"bytes-r"`
 | 
					 | 
				
			||||||
		DNS         []string `json:"dns"`
 | 
					 | 
				
			||||||
		Enable      bool     `json:"enable"`
 | 
					 | 
				
			||||||
		FullDuplex  bool     `json:"full_duplex"`
 | 
					 | 
				
			||||||
		Gateway     string   `json:"gateway"`
 | 
					 | 
				
			||||||
		Ifname      string   `json:"ifname"`
 | 
					 | 
				
			||||||
		IP          string   `json:"ip"`
 | 
					 | 
				
			||||||
		Mac         string   `json:"mac"`
 | 
					 | 
				
			||||||
		MaxSpeed    float64  `json:"max_speed"`
 | 
					 | 
				
			||||||
		Name        string   `json:"name"`
 | 
					 | 
				
			||||||
		Netmask     string   `json:"netmask"`
 | 
					 | 
				
			||||||
		RxBytes     float64  `json:"rx_bytes"`
 | 
					 | 
				
			||||||
		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    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"`
 | 
					 | 
				
			||||||
	} `json:"wan1"`
 | 
					 | 
				
			||||||
	Wan2 struct {
 | 
					 | 
				
			||||||
		BytesR      float64  `json:"bytes-r"`
 | 
					 | 
				
			||||||
		DNS         []string `json:"dns"`
 | 
					 | 
				
			||||||
		Enable      bool     `json:"enable"`
 | 
					 | 
				
			||||||
		FullDuplex  bool     `json:"full_duplex"`
 | 
					 | 
				
			||||||
		Gateway     string   `json:"gateway"`
 | 
					 | 
				
			||||||
		Ifname      string   `json:"ifname"`
 | 
					 | 
				
			||||||
		IP          string   `json:"ip"`
 | 
					 | 
				
			||||||
		Mac         string   `json:"mac"`
 | 
					 | 
				
			||||||
		MaxSpeed    float64  `json:"max_speed"`
 | 
					 | 
				
			||||||
		Name        string   `json:"name"`
 | 
					 | 
				
			||||||
		Netmask     string   `json:"netmask"`
 | 
					 | 
				
			||||||
		RxBytes     float64  `json:"rx_bytes"`
 | 
					 | 
				
			||||||
		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    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"`
 | 
					 | 
				
			||||||
	} `json:"wan2"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,118 +0,0 @@
 | 
				
			||||||
package unidev
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
	"time"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	influx "github.com/influxdata/influxdb/client/v2"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 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,
 | 
					 | 
				
			||||||
		"device_type":            u.Stat.O,
 | 
					 | 
				
			||||||
		"device_oid":             u.Stat.Oid,
 | 
					 | 
				
			||||||
		"site_id":                u.SiteID,
 | 
					 | 
				
			||||||
		"name":                   u.Name,
 | 
					 | 
				
			||||||
		"addopted":               strconv.FormatBool(u.Adopted),
 | 
					 | 
				
			||||||
		"adopt_ip":               u.AdoptIP,
 | 
					 | 
				
			||||||
		"adopt_url":              u.AdoptURL,
 | 
					 | 
				
			||||||
		"cfgversion":             u.Cfgversion,
 | 
					 | 
				
			||||||
		"config_network_ip":      u.ConfigNetwork.IP,
 | 
					 | 
				
			||||||
		"config_network_type":    u.ConfigNetwork.Type,
 | 
					 | 
				
			||||||
		"connect_request_ip":     u.ConnectRequestIP,
 | 
					 | 
				
			||||||
		"connect_request_port":   u.ConnectRequestPort,
 | 
					 | 
				
			||||||
		"default":                strconv.FormatBool(u.Default),
 | 
					 | 
				
			||||||
		"device_id":              u.DeviceID,
 | 
					 | 
				
			||||||
		"discovered_via":         u.DiscoveredVia,
 | 
					 | 
				
			||||||
		"inform_ip":              u.InformIP,
 | 
					 | 
				
			||||||
		"last_uplink_mac":        u.LastUplink.UplinkMac,
 | 
					 | 
				
			||||||
		"known_cfgversion":       u.KnownCfgversion,
 | 
					 | 
				
			||||||
		"led_override":           u.LedOverride,
 | 
					 | 
				
			||||||
		"locating":               strconv.FormatBool(u.Locating),
 | 
					 | 
				
			||||||
		"model":                  u.Model,
 | 
					 | 
				
			||||||
		"outdoor_mode_override":  u.OutdoorModeOverride,
 | 
					 | 
				
			||||||
		"serial":                 u.Serial,
 | 
					 | 
				
			||||||
		"type":                   u.Type,
 | 
					 | 
				
			||||||
		"version_incompatible":   strconv.FormatBool(u.VersionIncompatible),
 | 
					 | 
				
			||||||
		"dot1x_portctrl_enabled": strconv.FormatBool(u.Dot1XPortctrlEnabled),
 | 
					 | 
				
			||||||
		"flowctrl_enabled":       strconv.FormatBool(u.FlowctrlEnabled),
 | 
					 | 
				
			||||||
		"has_fan":                strconv.FormatBool(u.HasFan),
 | 
					 | 
				
			||||||
		"has_temperature":        strconv.FormatBool(u.HasTemperature),
 | 
					 | 
				
			||||||
		"jumboframe_enabled":     strconv.FormatBool(u.JumboframeEnabled),
 | 
					 | 
				
			||||||
		"stp_priority":           u.StpPriority,
 | 
					 | 
				
			||||||
		"stp_version":            u.StpVersion,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	fields := map[string]interface{}{
 | 
					 | 
				
			||||||
		"fw_caps":                  u.FwCaps,
 | 
					 | 
				
			||||||
		"guest-num_sta":            u.GuestNumSta,
 | 
					 | 
				
			||||||
		"ip":                       u.IP,
 | 
					 | 
				
			||||||
		"bytes":                    u.Bytes,
 | 
					 | 
				
			||||||
		"fan_level":                u.FanLevel,
 | 
					 | 
				
			||||||
		"general_temperature":      u.GeneralTemperature,
 | 
					 | 
				
			||||||
		"last_seen":                u.LastSeen,
 | 
					 | 
				
			||||||
		"license_state":            u.LicenseState,
 | 
					 | 
				
			||||||
		"overheating":              u.Overheating,
 | 
					 | 
				
			||||||
		"rx_bytes":                 u.RxBytes,
 | 
					 | 
				
			||||||
		"tx_bytes":                 u.TxBytes,
 | 
					 | 
				
			||||||
		"uptime":                   u.Uptime,
 | 
					 | 
				
			||||||
		"considered_lost_at":       u.ConsideredLostAt,
 | 
					 | 
				
			||||||
		"next_heartbeat_at":        u.NextHeartbeatAt,
 | 
					 | 
				
			||||||
		"roll_upgrade":             u.Rollupgrade,
 | 
					 | 
				
			||||||
		"state":                    u.State,
 | 
					 | 
				
			||||||
		"upgradable":               u.Upgradable,
 | 
					 | 
				
			||||||
		"user-num_sta":             u.UserNumSta,
 | 
					 | 
				
			||||||
		"version":                  u.Version,
 | 
					 | 
				
			||||||
		"loadavg_1":                u.SysStats.Loadavg1,
 | 
					 | 
				
			||||||
		"loadavg_5":                u.SysStats.Loadavg5,
 | 
					 | 
				
			||||||
		"loadavg_15":               u.SysStats.Loadavg15,
 | 
					 | 
				
			||||||
		"mem_buffer":               u.SysStats.MemBuffer,
 | 
					 | 
				
			||||||
		"mem_used":                 u.SysStats.MemUsed,
 | 
					 | 
				
			||||||
		"mem_total":                u.SysStats.MemTotal,
 | 
					 | 
				
			||||||
		"cpu":                      u.SystemStats.CPU,
 | 
					 | 
				
			||||||
		"mem":                      u.SystemStats.Mem,
 | 
					 | 
				
			||||||
		"system_uptime":            u.SystemStats.Uptime,
 | 
					 | 
				
			||||||
		"stat_bytes":               u.Stat.Bytes,
 | 
					 | 
				
			||||||
		"stat_duration":            u.Stat.Duration,
 | 
					 | 
				
			||||||
		"stat_guest-rx_bytes":      u.Stat.RxBytes,
 | 
					 | 
				
			||||||
		"stat_guest-rx_crypts":     u.Stat.RxCrypts,
 | 
					 | 
				
			||||||
		"stat_guest-rx_dropped":    u.Stat.RxDropped,
 | 
					 | 
				
			||||||
		"stat_guest-rx_errors":     u.Stat.RxErrors,
 | 
					 | 
				
			||||||
		"stat_guest-rx_frags":      u.Stat.RxFrags,
 | 
					 | 
				
			||||||
		"stat_guest-rx_packets":    u.Stat.RxPackets,
 | 
					 | 
				
			||||||
		"stat_guest-tx_bytes":      u.Stat.TxBytes,
 | 
					 | 
				
			||||||
		"stat_guest-tx_dropped":    u.Stat.TxDropped,
 | 
					 | 
				
			||||||
		"stat_guest-tx_errors":     u.Stat.TxErrors,
 | 
					 | 
				
			||||||
		"stat_guest-tx_packets":    u.Stat.TxPackets,
 | 
					 | 
				
			||||||
		"stat_guest-tx_retries":    u.Stat.TxRetries,
 | 
					 | 
				
			||||||
		"stat_port_1-rx_broadcast": u.Stat.Port1RxBroadcast,
 | 
					 | 
				
			||||||
		"stat_port_1-rx_bytes":     u.Stat.Port1RxBytes,
 | 
					 | 
				
			||||||
		"stat_port_1-rx_multicast": u.Stat.Port1RxMulticast,
 | 
					 | 
				
			||||||
		"stat_port_1-rx_packets":   u.Stat.Port1RxPackets,
 | 
					 | 
				
			||||||
		"stat_port_1-tx_broadcast": u.Stat.Port1TxBroadcast,
 | 
					 | 
				
			||||||
		"stat_port_1-tx_bytes":     u.Stat.Port1TxBytes,
 | 
					 | 
				
			||||||
		"stat_port_1-tx_multicast": u.Stat.Port1TxMulticast,
 | 
					 | 
				
			||||||
		"stat_port_1-tx_packets":   u.Stat.Port1TxPackets,
 | 
					 | 
				
			||||||
		"stat_rx_bytes":            u.Stat.RxBytes,
 | 
					 | 
				
			||||||
		"stat_rx_crypts":           u.Stat.RxCrypts,
 | 
					 | 
				
			||||||
		"stat_rx_dropped":          u.Stat.RxDropped,
 | 
					 | 
				
			||||||
		"stat_rx_errors":           u.Stat.RxErrors,
 | 
					 | 
				
			||||||
		"stat_rx_frags":            u.Stat.RxFrags,
 | 
					 | 
				
			||||||
		"stat_rx_packets":          u.Stat.TxPackets,
 | 
					 | 
				
			||||||
		"stat_tx_bytes":            u.Stat.TxBytes,
 | 
					 | 
				
			||||||
		"stat_tx_dropped":          u.Stat.TxDropped,
 | 
					 | 
				
			||||||
		"stat_tx_errors":           u.Stat.TxErrors,
 | 
					 | 
				
			||||||
		"stat_tx_packets":          u.Stat.TxPackets,
 | 
					 | 
				
			||||||
		"stat_tx_retries":          u.Stat.TxRetries,
 | 
					 | 
				
			||||||
		"uplink_depth":             strconv.FormatFloat(u.UplinkDepth, 'f', 6, 64),
 | 
					 | 
				
			||||||
		// Add the port stats too.
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	pt, err := influx.NewPoint("usw", tags, fields, time.Now())
 | 
					 | 
				
			||||||
	if err == nil {
 | 
					 | 
				
			||||||
		points = append(points, pt)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return points, err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,415 +0,0 @@
 | 
				
			||||||
package unidev
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// USW is a Unifi Switch
 | 
					 | 
				
			||||||
type USW struct {
 | 
					 | 
				
			||||||
	ID            string  `json:"_id"`
 | 
					 | 
				
			||||||
	UUptime       float64 `json:"_uptime"`
 | 
					 | 
				
			||||||
	AdoptIP       string  `json:"adopt_ip"`
 | 
					 | 
				
			||||||
	AdoptURL      string  `json:"adopt_url"`
 | 
					 | 
				
			||||||
	Adopted       bool    `json:"adopted"`
 | 
					 | 
				
			||||||
	BoardRev      float64 `json:"board_rev"`
 | 
					 | 
				
			||||||
	Bytes         float64 `json:"bytes"`
 | 
					 | 
				
			||||||
	Cfgversion    string  `json:"cfgversion"`
 | 
					 | 
				
			||||||
	ConfigNetwork struct {
 | 
					 | 
				
			||||||
		IP   string `json:"ip"`
 | 
					 | 
				
			||||||
		Type string `json:"type"`
 | 
					 | 
				
			||||||
	} `json:"config_network"`
 | 
					 | 
				
			||||||
	ConnectRequestIP     string        `json:"connect_request_ip"`
 | 
					 | 
				
			||||||
	ConnectRequestPort   string        `json:"connect_request_port"`
 | 
					 | 
				
			||||||
	ConsideredLostAt     float64       `json:"considered_lost_at"`
 | 
					 | 
				
			||||||
	Default              bool          `json:"default"`
 | 
					 | 
				
			||||||
	DeviceID             string        `json:"device_id"`
 | 
					 | 
				
			||||||
	DhcpServerTable      []interface{} `json:"dhcp_server_table"`
 | 
					 | 
				
			||||||
	DiscoveredVia        string        `json:"discovered_via"`
 | 
					 | 
				
			||||||
	Dot1XPortctrlEnabled bool          `json:"dot1x_portctrl_enabled"`
 | 
					 | 
				
			||||||
	DownlinkTable        []struct {
 | 
					 | 
				
			||||||
		FullDuplex bool    `json:"full_duplex"`
 | 
					 | 
				
			||||||
		Mac        string  `json:"mac"`
 | 
					 | 
				
			||||||
		PortIdx    float64 `json:"port_idx"`
 | 
					 | 
				
			||||||
		Speed      float64 `json:"speed"`
 | 
					 | 
				
			||||||
	} `json:"downlink_table"`
 | 
					 | 
				
			||||||
	EthernetTable []struct {
 | 
					 | 
				
			||||||
		Mac     string  `json:"mac"`
 | 
					 | 
				
			||||||
		Name    string  `json:"name"`
 | 
					 | 
				
			||||||
		NumPort float64 `json:"num_port,omitempty"`
 | 
					 | 
				
			||||||
	} `json:"ethernet_table"`
 | 
					 | 
				
			||||||
	FanLevel           float64 `json:"fan_level"`
 | 
					 | 
				
			||||||
	FlowctrlEnabled    bool    `json:"flowctrl_enabled"`
 | 
					 | 
				
			||||||
	FwCaps             float64 `json:"fw_caps"`
 | 
					 | 
				
			||||||
	GeneralTemperature float64 `json:"general_temperature"`
 | 
					 | 
				
			||||||
	GuestNumSta        float64 `json:"guest-num_sta"`
 | 
					 | 
				
			||||||
	HasFan             bool    `json:"has_fan"`
 | 
					 | 
				
			||||||
	HasTemperature     bool    `json:"has_temperature"`
 | 
					 | 
				
			||||||
	InformIP           string  `json:"inform_ip"`
 | 
					 | 
				
			||||||
	InformURL          string  `json:"inform_url"`
 | 
					 | 
				
			||||||
	IP                 string  `json:"ip"`
 | 
					 | 
				
			||||||
	JumboframeEnabled  bool    `json:"jumboframe_enabled"`
 | 
					 | 
				
			||||||
	KnownCfgversion    string  `json:"known_cfgversion"`
 | 
					 | 
				
			||||||
	LastSeen           float64 `json:"last_seen"`
 | 
					 | 
				
			||||||
	LastUplink         struct {
 | 
					 | 
				
			||||||
		UplinkMac string `json:"uplink_mac"`
 | 
					 | 
				
			||||||
	} `json:"last_uplink"`
 | 
					 | 
				
			||||||
	LedOverride         string  `json:"led_override"`
 | 
					 | 
				
			||||||
	LicenseState        string  `json:"license_state"`
 | 
					 | 
				
			||||||
	Locating            bool    `json:"locating"`
 | 
					 | 
				
			||||||
	Mac                 string  `json:"mac"`
 | 
					 | 
				
			||||||
	Model               string  `json:"model"`
 | 
					 | 
				
			||||||
	Name                string  `json:"name"`
 | 
					 | 
				
			||||||
	NextHeartbeatAt     float64 `json:"next_heartbeat_at"`
 | 
					 | 
				
			||||||
	NumSta              float64 `json:"num_sta"`
 | 
					 | 
				
			||||||
	OutdoorModeOverride string  `json:"outdoor_mode_override"`
 | 
					 | 
				
			||||||
	Overheating         bool    `json:"overheating"`
 | 
					 | 
				
			||||||
	PortOverrides       []struct {
 | 
					 | 
				
			||||||
		Name       string  `json:"name,omitempty"`
 | 
					 | 
				
			||||||
		PoeMode    string  `json:"poe_mode,omitempty"`
 | 
					 | 
				
			||||||
		PortIdx    float64 `json:"port_idx"`
 | 
					 | 
				
			||||||
		PortconfID string  `json:"portconf_id"`
 | 
					 | 
				
			||||||
	} `json:"port_overrides"`
 | 
					 | 
				
			||||||
	PortTable []struct {
 | 
					 | 
				
			||||||
		AggregatedBy bool          `json:"aggregated_by"`
 | 
					 | 
				
			||||||
		Autoneg      bool          `json:"autoneg"`
 | 
					 | 
				
			||||||
		BytesR       float64       `json:"bytes-r"`
 | 
					 | 
				
			||||||
		Dot1XMode    string        `json:"dot1x_mode"`
 | 
					 | 
				
			||||||
		Dot1XStatus  string        `json:"dot1x_status"`
 | 
					 | 
				
			||||||
		Enable       bool          `json:"enable"`
 | 
					 | 
				
			||||||
		FlowctrlRx   bool          `json:"flowctrl_rx"`
 | 
					 | 
				
			||||||
		FlowctrlTx   bool          `json:"flowctrl_tx"`
 | 
					 | 
				
			||||||
		FullDuplex   bool          `json:"full_duplex"`
 | 
					 | 
				
			||||||
		IsUplink     bool          `json:"is_uplink"`
 | 
					 | 
				
			||||||
		Jumbo        bool          `json:"jumbo"`
 | 
					 | 
				
			||||||
		LldpTable    []interface{} `json:"lldp_table"`
 | 
					 | 
				
			||||||
		Masked       bool          `json:"masked"`
 | 
					 | 
				
			||||||
		Media        string        `json:"media"`
 | 
					 | 
				
			||||||
		Name         string        `json:"name"`
 | 
					 | 
				
			||||||
		OpMode       string        `json:"op_mode"`
 | 
					 | 
				
			||||||
		PoeCaps      float64       `json:"poe_caps"`
 | 
					 | 
				
			||||||
		PoeClass     string        `json:"poe_class,omitempty"`
 | 
					 | 
				
			||||||
		PoeCurrent   string        `json:"poe_current,omitempty"`
 | 
					 | 
				
			||||||
		PoeEnable    bool          `json:"poe_enable,omitempty"`
 | 
					 | 
				
			||||||
		PoeGood      bool          `json:"poe_good,omitempty"`
 | 
					 | 
				
			||||||
		PoeMode      string        `json:"poe_mode,omitempty"`
 | 
					 | 
				
			||||||
		PoePower     string        `json:"poe_power,omitempty"`
 | 
					 | 
				
			||||||
		PoeVoltage   string        `json:"poe_voltage,omitempty"`
 | 
					 | 
				
			||||||
		PortIdx      float64       `json:"port_idx"`
 | 
					 | 
				
			||||||
		PortPoe      bool          `json:"port_poe"`
 | 
					 | 
				
			||||||
		PortconfID   string        `json:"portconf_id"`
 | 
					 | 
				
			||||||
		RxBroadcast  float64       `json:"rx_broadcast"`
 | 
					 | 
				
			||||||
		RxBytes      float64       `json:"rx_bytes"`
 | 
					 | 
				
			||||||
		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"`
 | 
					 | 
				
			||||||
		StpPathcost  float64       `json:"stp_pathcost"`
 | 
					 | 
				
			||||||
		StpState     string        `json:"stp_state"`
 | 
					 | 
				
			||||||
		TxBroadcast  float64       `json:"tx_broadcast"`
 | 
					 | 
				
			||||||
		TxBytes      float64       `json:"tx_bytes"`
 | 
					 | 
				
			||||||
		TxBytesR     float64       `json:"tx_bytes-r"`
 | 
					 | 
				
			||||||
		TxDropped    float64       `json:"tx_dropped"`
 | 
					 | 
				
			||||||
		TxErrors     float64       `json:"tx_errors"`
 | 
					 | 
				
			||||||
		TxMulticast  float64       `json:"tx_multicast"`
 | 
					 | 
				
			||||||
		TxPackets    float64       `json:"tx_packets"`
 | 
					 | 
				
			||||||
		Up           bool          `json:"up"`
 | 
					 | 
				
			||||||
		SfpFound     bool          `json:"sfp_found,omitempty"`
 | 
					 | 
				
			||||||
	} `json:"port_table"`
 | 
					 | 
				
			||||||
	Rollupgrade     bool          `json:"rollupgrade"`
 | 
					 | 
				
			||||||
	RxBytes         float64       `json:"rx_bytes"`
 | 
					 | 
				
			||||||
	Serial          string        `json:"serial"`
 | 
					 | 
				
			||||||
	SiteID          string        `json:"site_id"`
 | 
					 | 
				
			||||||
	SSHSessionTable []interface{} `json:"ssh_session_table"`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Stat struct {
 | 
					 | 
				
			||||||
		Bytes             float64 `json:"bytes"`
 | 
					 | 
				
			||||||
		Datetime          string  `json:"datetime"`
 | 
					 | 
				
			||||||
		Duration          float64 `json:"duration"`
 | 
					 | 
				
			||||||
		O                 string  `json:"o"`
 | 
					 | 
				
			||||||
		Oid               string  `json:"oid"`
 | 
					 | 
				
			||||||
		Port1RxBroadcast  float64 `json:"port_1-rx_broadcast"`
 | 
					 | 
				
			||||||
		Port1RxBytes      float64 `json:"port_1-rx_bytes"`
 | 
					 | 
				
			||||||
		Port1RxDropped    float64 `json:"port_1-rx_dropped"`
 | 
					 | 
				
			||||||
		Port1RxMulticast  float64 `json:"port_1-rx_multicast"`
 | 
					 | 
				
			||||||
		Port1RxPackets    float64 `json:"port_1-rx_packets"`
 | 
					 | 
				
			||||||
		Port1TxBroadcast  float64 `json:"port_1-tx_broadcast"`
 | 
					 | 
				
			||||||
		Port1TxBytes      float64 `json:"port_1-tx_bytes"`
 | 
					 | 
				
			||||||
		Port1TxMulticast  float64 `json:"port_1-tx_multicast"`
 | 
					 | 
				
			||||||
		Port1TxPackets    float64 `json:"port_1-tx_packets"`
 | 
					 | 
				
			||||||
		Port2RxBroadcast  float64 `json:"port_2-rx_broadcast"`
 | 
					 | 
				
			||||||
		Port2RxBytes      float64 `json:"port_2-rx_bytes"`
 | 
					 | 
				
			||||||
		Port2RxDropped    float64 `json:"port_2-rx_dropped"`
 | 
					 | 
				
			||||||
		Port2RxMulticast  float64 `json:"port_2-rx_multicast"`
 | 
					 | 
				
			||||||
		Port2RxPackets    float64 `json:"port_2-rx_packets"`
 | 
					 | 
				
			||||||
		Port2TxBroadcast  float64 `json:"port_2-tx_broadcast"`
 | 
					 | 
				
			||||||
		Port2TxBytes      float64 `json:"port_2-tx_bytes"`
 | 
					 | 
				
			||||||
		Port2TxMulticast  float64 `json:"port_2-tx_multicast"`
 | 
					 | 
				
			||||||
		Port2TxPackets    float64 `json:"port_2-tx_packets"`
 | 
					 | 
				
			||||||
		Port3RxBroadcast  float64 `json:"port_3-rx_broadcast"`
 | 
					 | 
				
			||||||
		Port3RxBytes      float64 `json:"port_3-rx_bytes"`
 | 
					 | 
				
			||||||
		Port3RxDropped    float64 `json:"port_3-rx_dropped"`
 | 
					 | 
				
			||||||
		Port3RxMulticast  float64 `json:"port_3-rx_multicast"`
 | 
					 | 
				
			||||||
		Port3RxPackets    float64 `json:"port_3-rx_packets"`
 | 
					 | 
				
			||||||
		Port3TxBroadcast  float64 `json:"port_3-tx_broadcast"`
 | 
					 | 
				
			||||||
		Port3TxBytes      float64 `json:"port_3-tx_bytes"`
 | 
					 | 
				
			||||||
		Port3TxMulticast  float64 `json:"port_3-tx_multicast"`
 | 
					 | 
				
			||||||
		Port3TxPackets    float64 `json:"port_3-tx_packets"`
 | 
					 | 
				
			||||||
		Port4RxBroadcast  float64 `json:"port_4-rx_broadcast"`
 | 
					 | 
				
			||||||
		Port4RxBytes      float64 `json:"port_4-rx_bytes"`
 | 
					 | 
				
			||||||
		Port4RxDropped    float64 `json:"port_4-rx_dropped"`
 | 
					 | 
				
			||||||
		Port4RxMulticast  float64 `json:"port_4-rx_multicast"`
 | 
					 | 
				
			||||||
		Port4RxPackets    float64 `json:"port_4-rx_packets"`
 | 
					 | 
				
			||||||
		Port4TxBroadcast  float64 `json:"port_4-tx_broadcast"`
 | 
					 | 
				
			||||||
		Port4TxBytes      float64 `json:"port_4-tx_bytes"`
 | 
					 | 
				
			||||||
		Port4TxMulticast  float64 `json:"port_4-tx_multicast"`
 | 
					 | 
				
			||||||
		Port4TxPackets    float64 `json:"port_4-tx_packets"`
 | 
					 | 
				
			||||||
		Port5RxBroadcast  float64 `json:"port_5-rx_broadcast"`
 | 
					 | 
				
			||||||
		Port5RxBytes      float64 `json:"port_5-rx_bytes"`
 | 
					 | 
				
			||||||
		Port5RxDropped    float64 `json:"port_5-rx_dropped"`
 | 
					 | 
				
			||||||
		Port5RxMulticast  float64 `json:"port_5-rx_multicast"`
 | 
					 | 
				
			||||||
		Port5RxPackets    float64 `json:"port_5-rx_packets"`
 | 
					 | 
				
			||||||
		Port5TxBroadcast  float64 `json:"port_5-tx_broadcast"`
 | 
					 | 
				
			||||||
		Port5TxBytes      float64 `json:"port_5-tx_bytes"`
 | 
					 | 
				
			||||||
		Port5TxMulticast  float64 `json:"port_5-tx_multicast"`
 | 
					 | 
				
			||||||
		Port5TxPackets    float64 `json:"port_5-tx_packets"`
 | 
					 | 
				
			||||||
		Port6RxBroadcast  float64 `json:"port_6-rx_broadcast"`
 | 
					 | 
				
			||||||
		Port6RxBytes      float64 `json:"port_6-rx_bytes"`
 | 
					 | 
				
			||||||
		Port6RxDropped    float64 `json:"port_6-rx_dropped"`
 | 
					 | 
				
			||||||
		Port6RxMulticast  float64 `json:"port_6-rx_multicast"`
 | 
					 | 
				
			||||||
		Port6RxPackets    float64 `json:"port_6-rx_packets"`
 | 
					 | 
				
			||||||
		Port6TxBroadcast  float64 `json:"port_6-tx_broadcast"`
 | 
					 | 
				
			||||||
		Port6TxBytes      float64 `json:"port_6-tx_bytes"`
 | 
					 | 
				
			||||||
		Port6TxMulticast  float64 `json:"port_6-tx_multicast"`
 | 
					 | 
				
			||||||
		Port6TxPackets    float64 `json:"port_6-tx_packets"`
 | 
					 | 
				
			||||||
		Port7RxBroadcast  float64 `json:"port_7-rx_broadcast"`
 | 
					 | 
				
			||||||
		Port7RxBytes      float64 `json:"port_7-rx_bytes"`
 | 
					 | 
				
			||||||
		Port7RxDropped    float64 `json:"port_7-rx_dropped"`
 | 
					 | 
				
			||||||
		Port7RxMulticast  float64 `json:"port_7-rx_multicast"`
 | 
					 | 
				
			||||||
		Port7RxPackets    float64 `json:"port_7-rx_packets"`
 | 
					 | 
				
			||||||
		Port7TxBroadcast  float64 `json:"port_7-tx_broadcast"`
 | 
					 | 
				
			||||||
		Port7TxBytes      float64 `json:"port_7-tx_bytes"`
 | 
					 | 
				
			||||||
		Port7TxMulticast  float64 `json:"port_7-tx_multicast"`
 | 
					 | 
				
			||||||
		Port7TxPackets    float64 `json:"port_7-tx_packets"`
 | 
					 | 
				
			||||||
		Port8RxBroadcast  float64 `json:"port_8-rx_broadcast"`
 | 
					 | 
				
			||||||
		Port8RxBytes      float64 `json:"port_8-rx_bytes"`
 | 
					 | 
				
			||||||
		Port8RxDropped    float64 `json:"port_8-rx_dropped"`
 | 
					 | 
				
			||||||
		Port8RxMulticast  float64 `json:"port_8-rx_multicast"`
 | 
					 | 
				
			||||||
		Port8RxPackets    float64 `json:"port_8-rx_packets"`
 | 
					 | 
				
			||||||
		Port8TxBroadcast  float64 `json:"port_8-tx_broadcast"`
 | 
					 | 
				
			||||||
		Port8TxBytes      float64 `json:"port_8-tx_bytes"`
 | 
					 | 
				
			||||||
		Port8TxMulticast  float64 `json:"port_8-tx_multicast"`
 | 
					 | 
				
			||||||
		Port8TxPackets    float64 `json:"port_8-tx_packets"`
 | 
					 | 
				
			||||||
		Port9RxBroadcast  float64 `json:"port_9-rx_broadcast"`
 | 
					 | 
				
			||||||
		Port9RxBytes      float64 `json:"port_9-rx_bytes"`
 | 
					 | 
				
			||||||
		Port9RxDropped    float64 `json:"port_9-rx_dropped"`
 | 
					 | 
				
			||||||
		Port9RxMulticast  float64 `json:"port_9-rx_multicast"`
 | 
					 | 
				
			||||||
		Port9RxPackets    float64 `json:"port_9-rx_packets"`
 | 
					 | 
				
			||||||
		Port9TxBroadcast  float64 `json:"port_9-tx_broadcast"`
 | 
					 | 
				
			||||||
		Port9TxBytes      float64 `json:"port_9-tx_bytes"`
 | 
					 | 
				
			||||||
		Port9TxMulticast  float64 `json:"port_9-tx_multicast"`
 | 
					 | 
				
			||||||
		Port9TxPackets    float64 `json:"port_9-tx_packets"`
 | 
					 | 
				
			||||||
		Port10RxBroadcast float64 `json:"port_10-rx_broadcast"`
 | 
					 | 
				
			||||||
		Port10RxBytes     float64 `json:"port_10-rx_bytes"`
 | 
					 | 
				
			||||||
		Port10RxDropped   float64 `json:"port_10-rx_dropped"`
 | 
					 | 
				
			||||||
		Port10RxMulticast float64 `json:"port_10-rx_multicast"`
 | 
					 | 
				
			||||||
		Port10RxPackets   float64 `json:"port_10-rx_packets"`
 | 
					 | 
				
			||||||
		Port10TxBroadcast float64 `json:"port_10-tx_broadcast"`
 | 
					 | 
				
			||||||
		Port10TxBytes     float64 `json:"port_10-tx_bytes"`
 | 
					 | 
				
			||||||
		Port10TxMulticast float64 `json:"port_10-tx_multicast"`
 | 
					 | 
				
			||||||
		Port10TxPackets   float64 `json:"port_10-tx_packets"`
 | 
					 | 
				
			||||||
		Port11RxBroadcast float64 `json:"port_11-rx_broadcast"`
 | 
					 | 
				
			||||||
		Port11RxBytes     float64 `json:"port_11-rx_bytes"`
 | 
					 | 
				
			||||||
		Port11RxDropped   float64 `json:"port_11-rx_dropped"`
 | 
					 | 
				
			||||||
		Port11RxMulticast float64 `json:"port_11-rx_multicast"`
 | 
					 | 
				
			||||||
		Port11RxPackets   float64 `json:"port_11-rx_packets"`
 | 
					 | 
				
			||||||
		Port11TxBroadcast float64 `json:"port_11-tx_broadcast"`
 | 
					 | 
				
			||||||
		Port11TxBytes     float64 `json:"port_11-tx_bytes"`
 | 
					 | 
				
			||||||
		Port11TxMulticast float64 `json:"port_11-tx_multicast"`
 | 
					 | 
				
			||||||
		Port11TxPackets   float64 `json:"port_11-tx_packets"`
 | 
					 | 
				
			||||||
		Port12RxBroadcast float64 `json:"port_12-rx_broadcast"`
 | 
					 | 
				
			||||||
		Port12RxBytes     float64 `json:"port_12-rx_bytes"`
 | 
					 | 
				
			||||||
		Port12RxDropped   float64 `json:"port_12-rx_dropped"`
 | 
					 | 
				
			||||||
		Port12RxMulticast float64 `json:"port_12-rx_multicast"`
 | 
					 | 
				
			||||||
		Port12RxPackets   float64 `json:"port_12-rx_packets"`
 | 
					 | 
				
			||||||
		Port12TxBroadcast float64 `json:"port_12-tx_broadcast"`
 | 
					 | 
				
			||||||
		Port12TxBytes     float64 `json:"port_12-tx_bytes"`
 | 
					 | 
				
			||||||
		Port12TxMulticast float64 `json:"port_12-tx_multicast"`
 | 
					 | 
				
			||||||
		Port12TxPackets   float64 `json:"port_12-tx_packets"`
 | 
					 | 
				
			||||||
		Port13RxBroadcast float64 `json:"port_13-rx_broadcast"`
 | 
					 | 
				
			||||||
		Port13RxBytes     float64 `json:"port_13-rx_bytes"`
 | 
					 | 
				
			||||||
		Port13RxDropped   float64 `json:"port_13-rx_dropped"`
 | 
					 | 
				
			||||||
		Port13RxMulticast float64 `json:"port_13-rx_multicast"`
 | 
					 | 
				
			||||||
		Port13RxPackets   float64 `json:"port_13-rx_packets"`
 | 
					 | 
				
			||||||
		Port13TxBroadcast float64 `json:"port_13-tx_broadcast"`
 | 
					 | 
				
			||||||
		Port13TxBytes     float64 `json:"port_13-tx_bytes"`
 | 
					 | 
				
			||||||
		Port13TxMulticast float64 `json:"port_13-tx_multicast"`
 | 
					 | 
				
			||||||
		Port13TxPackets   float64 `json:"port_13-tx_packets"`
 | 
					 | 
				
			||||||
		Port14RxBroadcast float64 `json:"port_14-rx_broadcast"`
 | 
					 | 
				
			||||||
		Port14RxBytes     float64 `json:"port_14-rx_bytes"`
 | 
					 | 
				
			||||||
		Port14RxDropped   float64 `json:"port_14-rx_dropped"`
 | 
					 | 
				
			||||||
		Port14RxMulticast float64 `json:"port_14-rx_multicast"`
 | 
					 | 
				
			||||||
		Port14RxPackets   float64 `json:"port_14-rx_packets"`
 | 
					 | 
				
			||||||
		Port14TxBroadcast float64 `json:"port_14-tx_broadcast"`
 | 
					 | 
				
			||||||
		Port14TxBytes     float64 `json:"port_14-tx_bytes"`
 | 
					 | 
				
			||||||
		Port14TxMulticast float64 `json:"port_14-tx_multicast"`
 | 
					 | 
				
			||||||
		Port14TxPackets   float64 `json:"port_14-tx_packets"`
 | 
					 | 
				
			||||||
		Port15RxBroadcast float64 `json:"port_15-rx_broadcast"`
 | 
					 | 
				
			||||||
		Port15RxBytes     float64 `json:"port_15-rx_bytes"`
 | 
					 | 
				
			||||||
		Port15RxDropped   float64 `json:"port_15-rx_dropped"`
 | 
					 | 
				
			||||||
		Port15RxMulticast float64 `json:"port_15-rx_multicast"`
 | 
					 | 
				
			||||||
		Port15RxPackets   float64 `json:"port_15-rx_packets"`
 | 
					 | 
				
			||||||
		Port15TxBroadcast float64 `json:"port_15-tx_broadcast"`
 | 
					 | 
				
			||||||
		Port15TxBytes     float64 `json:"port_15-tx_bytes"`
 | 
					 | 
				
			||||||
		Port15TxMulticast float64 `json:"port_15-tx_multicast"`
 | 
					 | 
				
			||||||
		Port15TxPackets   float64 `json:"port_15-tx_packets"`
 | 
					 | 
				
			||||||
		Port16RxBroadcast float64 `json:"port_16-rx_broadcast"`
 | 
					 | 
				
			||||||
		Port16RxBytes     float64 `json:"port_16-rx_bytes"`
 | 
					 | 
				
			||||||
		Port16RxDropped   float64 `json:"port_16-rx_dropped"`
 | 
					 | 
				
			||||||
		Port16RxMulticast float64 `json:"port_16-rx_multicast"`
 | 
					 | 
				
			||||||
		Port16RxPackets   float64 `json:"port_16-rx_packets"`
 | 
					 | 
				
			||||||
		Port16TxBroadcast float64 `json:"port_16-tx_broadcast"`
 | 
					 | 
				
			||||||
		Port16TxBytes     float64 `json:"port_16-tx_bytes"`
 | 
					 | 
				
			||||||
		Port16TxMulticast float64 `json:"port_16-tx_multicast"`
 | 
					 | 
				
			||||||
		Port16TxPackets   float64 `json:"port_16-tx_packets"`
 | 
					 | 
				
			||||||
		Port17RxBroadcast float64 `json:"port_17-rx_broadcast"`
 | 
					 | 
				
			||||||
		Port17RxBytes     float64 `json:"port_17-rx_bytes"`
 | 
					 | 
				
			||||||
		Port17RxDropped   float64 `json:"port_17-rx_dropped"`
 | 
					 | 
				
			||||||
		Port17RxMulticast float64 `json:"port_17-rx_multicast"`
 | 
					 | 
				
			||||||
		Port17RxPackets   float64 `json:"port_17-rx_packets"`
 | 
					 | 
				
			||||||
		Port17TxBroadcast float64 `json:"port_17-tx_broadcast"`
 | 
					 | 
				
			||||||
		Port17TxBytes     float64 `json:"port_17-tx_bytes"`
 | 
					 | 
				
			||||||
		Port17TxMulticast float64 `json:"port_17-tx_multicast"`
 | 
					 | 
				
			||||||
		Port17TxPackets   float64 `json:"port_17-tx_packets"`
 | 
					 | 
				
			||||||
		Port18RxBroadcast float64 `json:"port_18-rx_broadcast"`
 | 
					 | 
				
			||||||
		Port18RxBytes     float64 `json:"port_18-rx_bytes"`
 | 
					 | 
				
			||||||
		Port18RxDropped   float64 `json:"port_18-rx_dropped"`
 | 
					 | 
				
			||||||
		Port18RxMulticast float64 `json:"port_18-rx_multicast"`
 | 
					 | 
				
			||||||
		Port18RxPackets   float64 `json:"port_18-rx_packets"`
 | 
					 | 
				
			||||||
		Port18TxBroadcast float64 `json:"port_18-tx_broadcast"`
 | 
					 | 
				
			||||||
		Port18TxBytes     float64 `json:"port_18-tx_bytes"`
 | 
					 | 
				
			||||||
		Port18TxMulticast float64 `json:"port_18-tx_multicast"`
 | 
					 | 
				
			||||||
		Port18TxPackets   float64 `json:"port_18-tx_packets"`
 | 
					 | 
				
			||||||
		Port19RxBroadcast float64 `json:"port_19-rx_broadcast"`
 | 
					 | 
				
			||||||
		Port19RxBytes     float64 `json:"port_19-rx_bytes"`
 | 
					 | 
				
			||||||
		Port19RxDropped   float64 `json:"port_19-rx_dropped"`
 | 
					 | 
				
			||||||
		Port19RxMulticast float64 `json:"port_19-rx_multicast"`
 | 
					 | 
				
			||||||
		Port19RxPackets   float64 `json:"port_19-rx_packets"`
 | 
					 | 
				
			||||||
		Port19TxBroadcast float64 `json:"port_19-tx_broadcast"`
 | 
					 | 
				
			||||||
		Port19TxBytes     float64 `json:"port_19-tx_bytes"`
 | 
					 | 
				
			||||||
		Port19TxMulticast float64 `json:"port_19-tx_multicast"`
 | 
					 | 
				
			||||||
		Port19TxPackets   float64 `json:"port_19-tx_packets"`
 | 
					 | 
				
			||||||
		Port20RxBroadcast float64 `json:"port_20-rx_broadcast"`
 | 
					 | 
				
			||||||
		Port20RxBytes     float64 `json:"port_20-rx_bytes"`
 | 
					 | 
				
			||||||
		Port20RxDropped   float64 `json:"port_20-rx_dropped"`
 | 
					 | 
				
			||||||
		Port20RxMulticast float64 `json:"port_20-rx_multicast"`
 | 
					 | 
				
			||||||
		Port20RxPackets   float64 `json:"port_20-rx_packets"`
 | 
					 | 
				
			||||||
		Port20TxBroadcast float64 `json:"port_20-tx_broadcast"`
 | 
					 | 
				
			||||||
		Port20TxBytes     float64 `json:"port_20-tx_bytes"`
 | 
					 | 
				
			||||||
		Port20TxMulticast float64 `json:"port_20-tx_multicast"`
 | 
					 | 
				
			||||||
		Port20TxPackets   float64 `json:"port_20-tx_packets"`
 | 
					 | 
				
			||||||
		Port21RxBroadcast float64 `json:"port_21-rx_broadcast"`
 | 
					 | 
				
			||||||
		Port21RxBytes     float64 `json:"port_21-rx_bytes"`
 | 
					 | 
				
			||||||
		Port21RxDropped   float64 `json:"port_21-rx_dropped"`
 | 
					 | 
				
			||||||
		Port21RxMulticast float64 `json:"port_21-rx_multicast"`
 | 
					 | 
				
			||||||
		Port21RxPackets   float64 `json:"port_21-rx_packets"`
 | 
					 | 
				
			||||||
		Port21TxBroadcast float64 `json:"port_21-tx_broadcast"`
 | 
					 | 
				
			||||||
		Port21TxBytes     float64 `json:"port_21-tx_bytes"`
 | 
					 | 
				
			||||||
		Port21TxMulticast float64 `json:"port_21-tx_multicast"`
 | 
					 | 
				
			||||||
		Port21TxPackets   float64 `json:"port_21-tx_packets"`
 | 
					 | 
				
			||||||
		Port22RxBroadcast float64 `json:"port_22-rx_broadcast"`
 | 
					 | 
				
			||||||
		Port22RxBytes     float64 `json:"port_22-rx_bytes"`
 | 
					 | 
				
			||||||
		Port22RxDropped   float64 `json:"port_22-rx_dropped"`
 | 
					 | 
				
			||||||
		Port22RxMulticast float64 `json:"port_22-rx_multicast"`
 | 
					 | 
				
			||||||
		Port22RxPackets   float64 `json:"port_22-rx_packets"`
 | 
					 | 
				
			||||||
		Port22TxBroadcast float64 `json:"port_22-tx_broadcast"`
 | 
					 | 
				
			||||||
		Port22TxBytes     float64 `json:"port_22-tx_bytes"`
 | 
					 | 
				
			||||||
		Port22TxMulticast float64 `json:"port_22-tx_multicast"`
 | 
					 | 
				
			||||||
		Port22TxPackets   float64 `json:"port_22-tx_packets"`
 | 
					 | 
				
			||||||
		Port23RxBroadcast float64 `json:"port_23-rx_broadcast"`
 | 
					 | 
				
			||||||
		Port23RxBytes     float64 `json:"port_23-rx_bytes"`
 | 
					 | 
				
			||||||
		Port23RxDropped   float64 `json:"port_23-rx_dropped"`
 | 
					 | 
				
			||||||
		Port23RxMulticast float64 `json:"port_23-rx_multicast"`
 | 
					 | 
				
			||||||
		Port23RxPackets   float64 `json:"port_23-rx_packets"`
 | 
					 | 
				
			||||||
		Port23TxBroadcast float64 `json:"port_23-tx_broadcast"`
 | 
					 | 
				
			||||||
		Port23TxBytes     float64 `json:"port_23-tx_bytes"`
 | 
					 | 
				
			||||||
		Port23TxMulticast float64 `json:"port_23-tx_multicast"`
 | 
					 | 
				
			||||||
		Port23TxPackets   float64 `json:"port_23-tx_packets"`
 | 
					 | 
				
			||||||
		Port24RxBroadcast float64 `json:"port_24-rx_broadcast"`
 | 
					 | 
				
			||||||
		Port24RxBytes     float64 `json:"port_24-rx_bytes"`
 | 
					 | 
				
			||||||
		Port24RxDropped   float64 `json:"port_24-rx_dropped"`
 | 
					 | 
				
			||||||
		Port24RxMulticast float64 `json:"port_24-rx_multicast"`
 | 
					 | 
				
			||||||
		Port24RxPackets   float64 `json:"port_24-rx_packets"`
 | 
					 | 
				
			||||||
		Port24TxBroadcast float64 `json:"port_24-tx_broadcast"`
 | 
					 | 
				
			||||||
		Port24TxBytes     float64 `json:"port_24-tx_bytes"`
 | 
					 | 
				
			||||||
		Port24TxMulticast float64 `json:"port_24-tx_multicast"`
 | 
					 | 
				
			||||||
		Port24TxPackets   float64 `json:"port_24-tx_packets"`
 | 
					 | 
				
			||||||
		// Have a 48 port switch? How 'bout a pull request. :D
 | 
					 | 
				
			||||||
		RxBroadcast float64 `json:"rx_broadcast"`
 | 
					 | 
				
			||||||
		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"`
 | 
					 | 
				
			||||||
		RxMulticast float64 `json:"rx_multicast"`
 | 
					 | 
				
			||||||
		RxPackets   float64 `json:"rx_packets"`
 | 
					 | 
				
			||||||
		SiteID      string  `json:"site_id"`
 | 
					 | 
				
			||||||
		Sw          string  `json:"sw"`
 | 
					 | 
				
			||||||
		Time        float64 `json:"time"`
 | 
					 | 
				
			||||||
		TxBroadcast float64 `json:"tx_broadcast"`
 | 
					 | 
				
			||||||
		TxBytes     float64 `json:"tx_bytes"`
 | 
					 | 
				
			||||||
		TxDropped   float64 `json:"tx_dropped"`
 | 
					 | 
				
			||||||
		TxErrors    float64 `json:"tx_errors"`
 | 
					 | 
				
			||||||
		TxMulticast float64 `json:"tx_multicast"`
 | 
					 | 
				
			||||||
		TxPackets   float64 `json:"tx_packets"`
 | 
					 | 
				
			||||||
		TxRetries   float64 `json:"tx_retries"`
 | 
					 | 
				
			||||||
	} `json:"stat"`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	State       float64 `json:"state"`
 | 
					 | 
				
			||||||
	StpPriority string  `json:"stp_priority"`
 | 
					 | 
				
			||||||
	StpVersion  string  `json:"stp_version"`
 | 
					 | 
				
			||||||
	SysStats    struct {
 | 
					 | 
				
			||||||
		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    float64 `json:"cpu,string"`
 | 
					 | 
				
			||||||
		Mem    float64 `json:"mem,string"`
 | 
					 | 
				
			||||||
		Uptime float64 `json:"uptime,string"`
 | 
					 | 
				
			||||||
	} `json:"system-stats"`
 | 
					 | 
				
			||||||
	TxBytes    float64 `json:"tx_bytes"`
 | 
					 | 
				
			||||||
	Type       string  `json:"type"`
 | 
					 | 
				
			||||||
	Upgradable bool    `json:"upgradable"`
 | 
					 | 
				
			||||||
	Uplink     struct {
 | 
					 | 
				
			||||||
		FullDuplex  bool    `json:"full_duplex"`
 | 
					 | 
				
			||||||
		IP          string  `json:"ip"`
 | 
					 | 
				
			||||||
		Mac         string  `json:"mac"`
 | 
					 | 
				
			||||||
		MaxSpeed    float64 `json:"max_speed"`
 | 
					 | 
				
			||||||
		Media       string  `json:"media"`
 | 
					 | 
				
			||||||
		Name        string  `json:"name"`
 | 
					 | 
				
			||||||
		Netmask     string  `json:"netmask"`
 | 
					 | 
				
			||||||
		NumPort     float64 `json:"num_port"`
 | 
					 | 
				
			||||||
		PortIdx     float64 `json:"port_idx"`
 | 
					 | 
				
			||||||
		RxBytes     float64 `json:"rx_bytes"`
 | 
					 | 
				
			||||||
		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    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"`
 | 
					 | 
				
			||||||
	} `json:"uplink"`
 | 
					 | 
				
			||||||
	UplinkDepth         float64 `json:"uplink_depth"`
 | 
					 | 
				
			||||||
	Uptime              float64 `json:"uptime"`
 | 
					 | 
				
			||||||
	UserNumSta          float64 `json:"user-num_sta"`
 | 
					 | 
				
			||||||
	Version             string  `json:"version"`
 | 
					 | 
				
			||||||
	VersionIncompatible bool    `json:"version_incompatible"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
		Loading…
	
		Reference in New Issue