func (d *Device) UnmarshalJSON(b []byte) error {
	var dev device
	if err := json.Unmarshal(b, &dev); err != nil {
		return err
	}
	informIP := net.ParseIP(dev.InformIP)
	if informIP == nil {
		return fmt.Errorf("failed to parse inform IP: %v", dev.InformIP)
	}
	informURL, err := url.Parse(dev.InformURL)
	if err != nil {
		return err
	}
	nics := make([]*NIC, 0, len(dev.EthernetTable))
	for _, et := range dev.EthernetTable {
		mac, err := net.ParseMAC(et.MAC)
		if err != nil {
			return err
		}
		nics = append(nics, &NIC{
			MAC:  mac,
			Name: et.Name,
		})
	}
	radios := make([]*Radio, 0, len(dev.RadioTable))
	for _, rt := range dev.RadioTable {
		r := &Radio{
			BuiltInAntenna:     rt.BuiltinAntenna,
			BuiltInAntennaGain: rt.BuiltinAntGain,
			MaxTXPower:         rt.MaxTXPower,
			MinTXPower:         rt.MinTXPower,
			Name:               rt.Name,
		}
		for _, v := range dev.RadioTableStats {
			if v.Name == rt.Name {
				r.Stats = &RadioStationsStats{
					NumberStations:      v.NumSta,
					NumberUserStations:  v.UserNumSta,
					NumberGuestStations: v.GuestNumSta,
				}
			}
		}
		switch rt.Radio {
		case radioNA:
			r.Radio = radio5GHz
		case radioNG:
			r.Radio = radio24GHz
		}
		radios = append(radios, r)
	}
	*d = Device{
		ID:        dev.ID,
		Adopted:   dev.Adopted,
		InformIP:  informIP,
		InformURL: informURL,
		Model:     dev.Model,
		Name:      dev.Name,
		NICs:      nics,
		Radios:    radios,
		Serial:    dev.Serial,
		SiteID:    dev.SiteID,
		Uptime:    time.Duration(time.Duration(dev.Uptime) * time.Second),
		Version:   dev.Version,
		Stats: &DeviceStats{
			TotalBytes: dev.Stat.Bytes,
			All: &WirelessStats{
				ReceiveBytes:    dev.Stat.RxBytes,
				ReceivePackets:  dev.Stat.RxPackets,
				TransmitBytes:   dev.Stat.TxBytes,
				TransmitDropped: dev.Stat.TxDropped,
				TransmitPackets: dev.Stat.TxPackets,
			},
			User: &WirelessStats{
				ReceiveBytes:    dev.Stat.UserRxBytes,
				ReceivePackets:  dev.Stat.UserRxPackets,
				TransmitBytes:   dev.Stat.UserTxBytes,
				TransmitDropped: dev.Stat.UserTxDropped,
				TransmitPackets: dev.Stat.UserTxPackets,
			},
			Guest: &WirelessStats{
				ReceiveBytes:    dev.Stat.GuestRxBytes,
				ReceivePackets:  dev.Stat.GuestRxPackets,
				TransmitBytes:   dev.Stat.GuestTxBytes,
				TransmitDropped: dev.Stat.GuestTxDropped,
				TransmitPackets: dev.Stat.GuestTxPackets,
			},
			Uplink: &WiredStats{
				ReceiveBytes:    dev.Uplink.RxBytes,
				ReceivePackets:  dev.Uplink.RxPackets,
				TransmitBytes:   dev.Uplink.TxBytes,
				TransmitPackets: dev.Uplink.TxPackets,
			},
		},
	}
	return nil
}
UnmarshalJSON unmarshals the raw JSON representation of a Device.
package unifi
import (
	"encoding/json"
	"fmt"
	"net"
	"net/url"
	"time"
)
func (c *Client) Devices(siteName string) ([]*Device, error) {
	var v struct {
		Devices []*Device `json:"data"`
	}
	req, err := c.newRequest(
		"GET",
		fmt.Sprintf("/api/s/%s/stat/device", siteName),
		nil,
	)
	if err != nil {
		return nil, err
	}
	_, err = c.do(req, &v)
	return v.Devices, err
}
type Device struct {
	ID        string
	Adopted   bool
	InformIP  net.IP
	InformURL *url.URL
	Model     string
	Name      string
	NICs      []*NIC
	Radios    []*Radio
	Serial    string
	SiteID    string
	Stats     *DeviceStats
	Uptime    time.Duration
	Version   string
}
type Radio struct {
	BuiltInAntenna     bool
	BuiltInAntennaGain int
	MaxTXPower         int
	MinTXPower         int
	Name               string
	Radio              string
	Stats              *RadioStationsStats
}
type RadioStationsStats struct {
	NumberStations      int
	NumberGuestStations int
	NumberUserStations  int
}
type NIC struct {
	MAC  net.HardwareAddr
	Name string
}
type DeviceStats struct {
	TotalBytes float64
	All        *WirelessStats
	Guest      *WirelessStats
	User       *WirelessStats
	Uplink     *WiredStats
}
func (s *DeviceStats) String() string {
	return fmt.Sprintf("%v", *s)
}
type WirelessStats struct {
	ReceiveBytes    float64
	ReceivePackets  float64
	TransmitBytes   float64
	TransmitDropped float64
	TransmitPackets float64
}
func (s *WirelessStats) String() string {
	return fmt.Sprintf("%v", *s)
}
type WiredStats struct {
	ReceiveBytes    float64
	ReceivePackets  float64
	TransmitBytes   float64
	TransmitPackets float64
}
func (s *WiredStats) String() string {
	return fmt.Sprintf("%v", *s)
}
const (
	radioNA = "na"
	radioNG = "ng"
	radio5GHz  = "5GHz"
	radio24GHz = "2.4GHz"
)