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. // Points generates Unifi Client datapoints for InfluxDB.
// These points can be passed directly to influx. // These points can be passed directly to influx.
func (c Client) Points() ([]*influx.Point, error) { func (c Client) Points() ([]*influx.Point, error) {
// Fix name and hostname fields. Sometimes one or the other is blank. return c.PointsAt(time.Now())
switch { }
case c.Hostname == "" && c.Name == "":
c.Hostname = c.Mac // PointsAt generates Unifi Client datapoints for InfluxDB.
c.Name = c.Mac // These points can be passed directly to influx.
case c.Hostname == "" && c.Name != "": // This is just like Points(), but specify when points were created.
c.Hostname = c.Name func (c Client) PointsAt(now time.Time) ([]*influx.Point, error) {
case c.Name == "" && c.Hostname != "":
c.Name = c.Hostname
}
tags := map[string]string{ tags := map[string]string{
"id": c.ID, "id": c.ID,
"mac": c.Mac, "mac": c.Mac,
@ -109,7 +106,7 @@ func (c Client) Points() ([]*influx.Point, error) {
"dpi_tx_bytes": c.DpiStats.TxBytes.Val, "dpi_tx_bytes": c.DpiStats.TxBytes.Val,
"dpi_tx_packets": c.DpiStats.TxPackets.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 { if err != nil {
return nil, err 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. // Choose which type to unmarshal into based on the "type" json key.
switch assetType { // Unmarshal again into the correct type.. switch assetType { // Unmarshal again into the correct type..
case "uap": case "uap":
if uap := (UAP{}); u.unmarshalDevice(assetType, r, &uap) == nil { dev := UAP{SiteName: siteName}
uap.SiteName = siteName if u.unmarshalDevice(assetType, r, &dev) == nil {
devices.UAPs = append(devices.UAPs, uap) 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. case "ugw", "usg": // in case they ever fix the name in the api.
if usg := (USG{}); u.unmarshalDevice(assetType, r, &usg) == nil { dev := USG{SiteName: siteName}
usg.SiteName = siteName if u.unmarshalDevice(assetType, r, &dev) == nil {
devices.USGs = append(devices.USGs, usg) dev.Name = pick(dev.Name, dev.Mac)
devices.USGs = append(devices.USGs, dev)
} }
case "usw": case "usw":
if usw := (USW{}); u.unmarshalDevice(assetType, r, &usw) == nil { dev := USW{SiteName: siteName}
usw.SiteName = siteName if u.unmarshalDevice(assetType, r, &dev) == nil {
devices.USWs = append(devices.USWs, usw) dev.Name = pick(dev.Name, dev.Mac)
devices.USWs = append(devices.USWs, dev)
} }
default: default:
u.ErrorLog("unknown asset type - %v - skipping", assetType) 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 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. // Points generates Unifi Sites' datapoints for InfluxDB.
// These points can be passed directly to influx. // These points can be passed directly to influx.
func (u Site) Points() ([]*influx.Point, error) { 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{} points := []*influx.Point{}
for _, s := range u.Health { for _, s := range u.Health {
tags := map[string]string{ tags := map[string]string{

View File

@ -9,6 +9,13 @@ import (
// Points generates Wireless-Access-Point datapoints for InfluxDB. // Points generates Wireless-Access-Point datapoints for InfluxDB.
// These points can be passed directly to influx. // These points can be passed directly to influx.
func (u UAP) Points() ([]*influx.Point, error) { 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{ tags := map[string]string{
"id": u.ID, "id": u.ID,
"mac": u.Mac, "mac": u.Mac,
@ -161,7 +168,7 @@ func (u UAP) Points() ([]*influx.Point, error) {
"stat_wifi0-tx_retries": u.Stat.Wifi0TxRetries.Val, "stat_wifi0-tx_retries": u.Stat.Wifi0TxRetries.Val,
"stat_wifi1-tx_retries": u.Stat.Wifi1TxRetries.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 { if err != nil {
return nil, err return nil, err
} }
@ -265,7 +272,7 @@ func (u UAP) Points() ([]*influx.Point, error) {
fields["user-num_sta"] = p.UserNumSta.Val 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 { if err != nil {
return points, err 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 { if err := u.GetData(clientPath, &response); err != nil {
return nil, err 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 + ")" 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...) 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 { if err := u.GetData(devicePath, &response); err != nil {
return nil, err return nil, err
} }
loopDevices := u.parseDevices(response.Data, site.Desc+" ("+site.Name+")") loopDevices := u.parseDevices(response.Data, site.SiteName)
// 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 + ")"
}
devices.UAPs = append(devices.UAPs, loopDevices.UAPs...) devices.UAPs = append(devices.UAPs, loopDevices.UAPs...)
devices.USGs = append(devices.USGs, loopDevices.USGs...) devices.USGs = append(devices.USGs, loopDevices.USGs...)
devices.USWs = append(devices.USWs, loopDevices.USWs...) 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 { if err := u.GetData(SiteList, &response); err != nil {
return nil, err return nil, err
} }
sites := make([]string, 0) sites := []string{} // used for debug log only
for i := range response.Data { for i, d := range response.Data {
response.Data[i].SiteName = response.Data[i].Desc + " (" + response.Data[i].Name + ")" // If the human name is missing (description), set it to the cryptic name.
sites = append(sites, response.Data[i].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, ",")) u.DebugLog("Found %d site(s): %s", len(sites), strings.Join(sites, ","))
return response.Data, nil return response.Data, nil

View File

@ -10,7 +10,13 @@ import (
// Points generates Unifi Gateway datapoints for InfluxDB. // Points generates Unifi Gateway datapoints for InfluxDB.
// These points can be passed directly to influx. // These points can be passed directly to influx.
func (u USG) Points() ([]*influx.Point, error) { 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{ tags := map[string]string{
"id": u.ID, "id": u.ID,
"mac": u.Mac, "mac": u.Mac,

View File

@ -9,6 +9,13 @@ import (
// Points generates Unifi Switch datapoints for InfluxDB. // Points generates Unifi Switch datapoints for InfluxDB.
// These points can be passed directly to influx. // These points can be passed directly to influx.
func (u USW) Points() ([]*influx.Point, error) { 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{ tags := map[string]string{
"id": u.ID, "id": u.ID,
"mac": u.Mac, "mac": u.Mac,
@ -93,7 +100,7 @@ func (u USW) Points() ([]*influx.Point, error) {
"uplink_depth": u.UplinkDepth.Txt, "uplink_depth": u.UplinkDepth.Txt,
// Add the port stats too. // 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 { if err != nil {
return nil, err return nil, err
} }
@ -153,7 +160,7 @@ func (u USW) Points() ([]*influx.Point, error) {
"poe_voltage": p.PoeVoltage.Val, "poe_voltage": p.PoeVoltage.Val,
"full_duplex": p.FullDuplex.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 { if err != nil {
return points, err return points, err
} }