package main import ( "encoding/json" "fmt" "git.tordarus.net/tordarus/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 ReceivedFormatted string `json:"received_fmt"` TransferredFormatted string `json:"transferred_fmt"` } func MakeTrafficRate(received, transferred uint64) TrafficRate { return TrafficRate{ Received: received, Transferred: transferred, ReceivedFormatted: FormatBytesPerSecond(received), TransferredFormatted: FormatBytesPerSecond(transferred), } } func (tr TrafficRate) Add(o TrafficRate) TrafficRate { return MakeTrafficRate( tr.Received+o.Received, tr.Transferred+o.Transferred, ) } func (tr TrafficRate) Sub(o TrafficRate) TrafficRate { return MakeTrafficRate( tr.Received-o.Received, 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 := MakeTrafficRate(0, 0) 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 := MakeTrafficRate(0, 0) 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", FormatBytesPerSecond(tr.Received), FormatBytesPerSecond(tr.Transferred)) } func (stats TrafficStats) String() string { data, _ := json.MarshalIndent(stats, "", "\t") return string(data) } func FormatBytesPerSecond[T gmath.Integer](bytes T) string { value := float64(bytes) if value >= 1000000000 { return fmt.Sprintf("%.1f GB/s", value/1000000000) } else if value >= 1000000 { return fmt.Sprintf("%.1f MB/s", value/1000000) } else if value >= 1000 { return fmt.Sprintf("%.0f kB/s", value/1000) } else { return fmt.Sprintf("%.0f B/s", value) } }