Add names to all devices.

This commit is contained in:
davidnewhall2 2019-07-10 22:31:57 -07:00
parent d80ad93a17
commit caf60bb705
7 changed files with 76 additions and 41 deletions

View File

@ -9,16 +9,13 @@ import (
// Points generates Unifi Client datapoints for InfluxDB.
// These points can be passed directly to influx.
func (c Client) Points() ([]*influx.Point, error) {
// Fix name and hostname fields. Sometimes one or the other is blank.
switch {
case c.Hostname == "" && c.Name == "":
c.Hostname = c.Mac
c.Name = c.Mac
case c.Hostname == "" && c.Name != "":
c.Hostname = c.Name
case c.Name == "" && c.Hostname != "":
c.Name = c.Hostname
return c.PointsAt(time.Now())
}
// PointsAt generates Unifi Client datapoints for InfluxDB.
// These points can be passed directly to influx.
// This is just like Points(), but specify when points were created.
func (c Client) PointsAt(now time.Time) ([]*influx.Point, error) {
tags := map[string]string{
"id": c.ID,
"mac": c.Mac,
@ -109,7 +106,7 @@ func (c Client) Points() ([]*influx.Point, error) {
"dpi_tx_bytes": c.DpiStats.TxBytes.Val,
"dpi_tx_packets": c.DpiStats.TxPackets.Val,
}
pt, err := influx.NewPoint("clients", tags, fields, time.Now())
pt, err := influx.NewPoint("clients", tags, fields, now)
if err != nil {
return nil, err
}

View File

@ -17,19 +17,22 @@ func (u *Unifi) parseDevices(data []json.RawMessage, siteName string) *Devices {
// Choose which type to unmarshal into based on the "type" json key.
switch assetType { // Unmarshal again into the correct type..
case "uap":
if uap := (UAP{}); u.unmarshalDevice(assetType, r, &uap) == nil {
uap.SiteName = siteName
devices.UAPs = append(devices.UAPs, uap)
dev := UAP{SiteName: siteName}
if u.unmarshalDevice(assetType, r, &dev) == nil {
dev.Name = pick(dev.Name, dev.Mac)
devices.UAPs = append(devices.UAPs, dev)
}
case "ugw", "usg": // in case they ever fix the name in the api.
if usg := (USG{}); u.unmarshalDevice(assetType, r, &usg) == nil {
usg.SiteName = siteName
devices.USGs = append(devices.USGs, usg)
dev := USG{SiteName: siteName}
if u.unmarshalDevice(assetType, r, &dev) == nil {
dev.Name = pick(dev.Name, dev.Mac)
devices.USGs = append(devices.USGs, dev)
}
case "usw":
if usw := (USW{}); u.unmarshalDevice(assetType, r, &usw) == nil {
usw.SiteName = siteName
devices.USWs = append(devices.USWs, usw)
dev := USW{SiteName: siteName}
if u.unmarshalDevice(assetType, r, &dev) == nil {
dev.Name = pick(dev.Name, dev.Mac)
devices.USWs = append(devices.USWs, dev)
}
default:
u.ErrorLog("unknown asset type - %v - skipping", assetType)
@ -50,3 +53,14 @@ func (u *Unifi) unmarshalDevice(dev string, data json.RawMessage, v interface{})
}
return err
}
// pick returns the first non empty string in a list.
// used in a few places around this library.
func pick(strings ...string) string {
for _, s := range strings {
if s != "" {
return s
}
}
return ""
}

View File

@ -10,6 +10,13 @@ import (
// Points generates Unifi Sites' datapoints for InfluxDB.
// These points can be passed directly to influx.
func (u Site) Points() ([]*influx.Point, error) {
return u.PointsAt(time.Now())
}
// PointsAt generates Unifi Sites' datapoints for InfluxDB.
// These points can be passed directly to influx.
// This is just like Points(), but specify when points were created.
func (u Site) PointsAt(now time.Time) ([]*influx.Point, error) {
points := []*influx.Point{}
for _, s := range u.Health {
tags := map[string]string{

View File

@ -9,6 +9,13 @@ import (
// Points generates Wireless-Access-Point datapoints for InfluxDB.
// These points can be passed directly to influx.
func (u UAP) Points() ([]*influx.Point, error) {
return u.PointsAt(time.Now())
}
// PointsAt generates Wireless-Access-Point datapoints for InfluxDB.
// These points can be passed directly to influx.
// This is just like Points(), but specify when points were created.
func (u UAP) PointsAt(now time.Time) ([]*influx.Point, error) {
tags := map[string]string{
"id": u.ID,
"mac": u.Mac,
@ -161,7 +168,7 @@ func (u UAP) Points() ([]*influx.Point, error) {
"stat_wifi0-tx_retries": u.Stat.Wifi0TxRetries.Val,
"stat_wifi1-tx_retries": u.Stat.Wifi1TxRetries.Val,
}
pt, err := influx.NewPoint("uap", tags, fields, time.Now())
pt, err := influx.NewPoint("uap", tags, fields, now)
if err != nil {
return nil, err
}
@ -265,7 +272,7 @@ func (u UAP) Points() ([]*influx.Point, error) {
fields["user-num_sta"] = p.UserNumSta.Val
}
pt, err := influx.NewPoint("uap_vaps", tags, fields, time.Now())
pt, err := influx.NewPoint("uap_vaps", tags, fields, now)
if err != nil {
return points, err
}

View File

@ -82,8 +82,12 @@ func (u *Unifi) GetClients(sites []Site) (Clients, error) {
if err := u.GetData(clientPath, &response); err != nil {
return nil, err
}
for i := range response.Data {
for i, d := range response.Data {
// Add the special "Site Name" to each client. This becomes a Grafana filter somewhere.
response.Data[i].SiteName = site.Desc + " (" + site.Name + ")"
// Fix name and hostname fields. Sometimes one or the other is blank.
response.Data[i].Hostname = pick(d.Hostname, d.Name, d.Mac)
response.Data[i].Name = pick(d.Name, d.Hostname)
}
data = append(data, response.Data...)
}
@ -101,17 +105,7 @@ func (u *Unifi) GetDevices(sites []Site) (*Devices, error) {
if err := u.GetData(devicePath, &response); err != nil {
return nil, err
}
loopDevices := u.parseDevices(response.Data, site.Desc+" ("+site.Name+")")
// Add SiteName to each device asset.
for i := range loopDevices.UAPs {
loopDevices.UAPs[i].SiteName = site.Desc + " (" + site.Name + ")"
}
for i := range loopDevices.USGs {
loopDevices.USGs[i].SiteName = site.Desc + " (" + site.Name + ")"
}
for i := range loopDevices.USWs {
loopDevices.USWs[i].SiteName = site.Desc + " (" + site.Name + ")"
}
loopDevices := u.parseDevices(response.Data, site.SiteName)
devices.UAPs = append(devices.UAPs, loopDevices.UAPs...)
devices.USGs = append(devices.USGs, loopDevices.USGs...)
devices.USWs = append(devices.USWs, loopDevices.USWs...)
@ -127,10 +121,13 @@ func (u *Unifi) GetSites() (Sites, error) {
if err := u.GetData(SiteList, &response); err != nil {
return nil, err
}
sites := make([]string, 0)
for i := range response.Data {
response.Data[i].SiteName = response.Data[i].Desc + " (" + response.Data[i].Name + ")"
sites = append(sites, response.Data[i].Name)
sites := []string{} // used for debug log only
for i, d := range response.Data {
// If the human name is missing (description), set it to the cryptic name.
response.Data[i].Desc = pick(d.Desc, d.Name)
// Add the custom site name to each site. used as a Grafana filter somewhere.
response.Data[i].SiteName = d.Desc + " (" + d.Name + ")"
sites = append(sites, d.Name) // used for debug log only
}
u.DebugLog("Found %d site(s): %s", len(sites), strings.Join(sites, ","))
return response.Data, nil

View File

@ -10,7 +10,13 @@ import (
// Points generates Unifi Gateway datapoints for InfluxDB.
// These points can be passed directly to influx.
func (u USG) Points() ([]*influx.Point, error) {
now := time.Now()
return u.PointsAt(time.Now())
}
// PointsAt generates Unifi Gateway datapoints for InfluxDB.
// These points can be passed directly to influx.
// This is just like Points(), but specify when points were created.
func (u USG) PointsAt(now time.Time) ([]*influx.Point, error) {
tags := map[string]string{
"id": u.ID,
"mac": u.Mac,

View File

@ -9,6 +9,13 @@ import (
// Points generates Unifi Switch datapoints for InfluxDB.
// These points can be passed directly to influx.
func (u USW) Points() ([]*influx.Point, error) {
return u.PointsAt(time.Now())
}
// PointsAt generates Unifi Switch datapoints for InfluxDB.
// These points can be passed directly to influx.
// This is just like Points(), but specify when points were created.
func (u USW) PointsAt(now time.Time) ([]*influx.Point, error) {
tags := map[string]string{
"id": u.ID,
"mac": u.Mac,
@ -93,7 +100,7 @@ func (u USW) Points() ([]*influx.Point, error) {
"uplink_depth": u.UplinkDepth.Txt,
// Add the port stats too.
}
pt, err := influx.NewPoint("usw", tags, fields, time.Now())
pt, err := influx.NewPoint("usw", tags, fields, now)
if err != nil {
return nil, err
}
@ -153,7 +160,7 @@ func (u USW) Points() ([]*influx.Point, error) {
"poe_voltage": p.PoeVoltage.Val,
"full_duplex": p.FullDuplex.Val,
}
pt, err = influx.NewPoint("usw_ports", tags, fields, time.Now())
pt, err = influx.NewPoint("usw_ports", tags, fields, now)
if err != nil {
return points, err
}