package main import ( "encoding/json" "fmt" "git.milar.in/milarin/gmath" omadamodel "git.tordarus.net/tordarus/omada-api/model" ) type ClientUniqueID struct { SiteID omadamodel.SiteID ClientMac string } type TrafficRate struct { Received uint64 `json:"received"` // bytes per second Transferred uint64 `json:"transferred"` // bytes per second } func (tr TrafficRate) Add(o TrafficRate) TrafficRate { return TrafficRate{ Received: tr.Received + o.Received, Transferred: tr.Transferred + o.Transferred, } } func (tr TrafficRate) Sub(o TrafficRate) TrafficRate { return TrafficRate{ Received: tr.Received - o.Received, Transferred: tr.Transferred - o.Transferred, } } type SiteTraffic struct { Total TrafficRate `json:"total"` Clients map[string]TrafficRate `json:"clients"` } func NewSiteTraffic(clients map[string]TrafficRate) *SiteTraffic { total := TrafficRate{} for _, rate := range clients { total = total.Add(rate) } return &SiteTraffic{ Total: total, Clients: clients, } } type TrafficStats struct { Total TrafficRate `json:"total"` Sites map[string]*SiteTraffic `json:"sites"` } func NewTrafficStats(sites map[string]*SiteTraffic) *TrafficStats { total := TrafficRate{} for _, siteTraffic := range sites { total = total.Add(siteTraffic.Total) } return &TrafficStats{ Total: total, Sites: sites, } } func (tr TrafficRate) String() string { return fmt.Sprintf("Rx: %s | Tx: %s", FormatBytes(tr.Received), FormatBytes(tr.Transferred)) } func (stats TrafficStats) String() string { data, _ := json.MarshalIndent(stats, "", "\t") return string(data) } func FormatBytes[T gmath.Integer](bytes T) string { value := float64(bytes) if value >= 1000000000000 { return fmt.Sprintf("%.02fT", value/1000000000000) } else if value >= 1000000000 { return fmt.Sprintf("%.02fG", value/1000000000) } else if value >= 1000000 { return fmt.Sprintf("%.02fM", value/1000000) } else if value >= 1000 { return fmt.Sprintf("%.02fK", value/1000) } else { return fmt.Sprintf("%.02fB", value) } }