initial commit
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| *_test.go | ||||
							
								
								
									
										33
									
								
								ap_info.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								ap_info.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | ||||
| package omadaapi | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	"git.tordarus.net/tordarus/ezhttp" | ||||
| 	"git.tordarus.net/tordarus/omada-api/model" | ||||
| ) | ||||
|  | ||||
| func (api *Api) GetApInfo(siteID model.SiteID, macAddress string) (*model.ApInfo, error) { | ||||
| 	req := ezhttp.Request( | ||||
| 		ezhttp.Template(api.tmpl), | ||||
| 		ezhttp.Method("GET"), | ||||
| 		ezhttp.AppendPath( | ||||
| 			fmt.Sprintf("/openapi/v1/%s/sites/%s/aps/%s", | ||||
| 				api.config.OmadaID, | ||||
| 				siteID, | ||||
| 				macAddress)), | ||||
| 	) | ||||
|  | ||||
| 	resp, err := ezhttp.Do(req) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer resp.Body.Close() | ||||
|  | ||||
| 	response, err := ezhttp.ParseJsonResponse[model.Response[model.ApInfo]](resp.Body) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return &response.Result, nil | ||||
| } | ||||
							
								
								
									
										151
									
								
								api.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								api.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,151 @@ | ||||
| package omadaapi | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
|  | ||||
| 	"git.tordarus.net/tordarus/ezhttp" | ||||
| 	"git.tordarus.net/tordarus/omada-api/model" | ||||
| ) | ||||
|  | ||||
| type Api struct { | ||||
| 	tmpl *http.Request | ||||
|  | ||||
| 	config ApiConfig | ||||
|  | ||||
| 	accessToken  string | ||||
| 	refreshToken string | ||||
| } | ||||
|  | ||||
| type ApiConfig struct { | ||||
| 	BasePath     string | ||||
| 	OmadaID      string | ||||
| 	ClientID     string | ||||
| 	ClientSecret string | ||||
| 	Username     string | ||||
| 	Password     string | ||||
| } | ||||
|  | ||||
| func NewApi(config ApiConfig) (*Api, error) { | ||||
| 	tmpl := ezhttp.Request(ezhttp.URL(config.BasePath)) | ||||
|  | ||||
| 	api := &Api{ | ||||
| 		tmpl:   tmpl, | ||||
| 		config: config, | ||||
| 	} | ||||
|  | ||||
| 	loginResponse, err := api.Login() | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("login request failed: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	if loginResponse.ErrorCode != 0 { | ||||
| 		return nil, fmt.Errorf("login request failed: %s", loginResponse.Message) | ||||
| 	} | ||||
|  | ||||
| 	authCodeResponse, err := api.AuthCode(loginResponse.Result.CsrfToken, loginResponse.Result.SessionID) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("auth code request failed: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	if authCodeResponse.ErrorCode != 0 { | ||||
| 		return nil, fmt.Errorf("auth code request failed: %s", authCodeResponse.Message) | ||||
| 	} | ||||
|  | ||||
| 	authTokenResponse, err := api.AuthToken(*authCodeResponse.Result) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("auth token request failed: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	if authTokenResponse.ErrorCode != 0 { | ||||
| 		return nil, fmt.Errorf("auth token request failed: %s", authTokenResponse.Message) | ||||
| 	} | ||||
|  | ||||
| 	api.accessToken = authTokenResponse.Result.AccessToken | ||||
| 	api.refreshToken = authTokenResponse.Result.RefreshToken | ||||
|  | ||||
| 	api.tmpl = ezhttp.Request( | ||||
| 		ezhttp.Template(api.tmpl), | ||||
| 		ezhttp.Headers("Authorization", "AccessToken="+api.accessToken), | ||||
| 	) | ||||
|  | ||||
| 	return api, nil | ||||
| } | ||||
|  | ||||
| func (api *Api) Login() (*model.LoginResponse, error) { | ||||
| 	reqBody := model.LoginRequest{ | ||||
| 		Username: api.config.Username, | ||||
| 		Password: api.config.Password, | ||||
| 	} | ||||
|  | ||||
| 	req := ezhttp.Request( | ||||
| 		ezhttp.Template(api.tmpl), | ||||
| 		ezhttp.Method("POST"), | ||||
| 		ezhttp.AppendPath("/openapi/authorize/login"), | ||||
| 		ezhttp.Query("client_id", api.config.ClientID, "omadac_id", api.config.OmadaID), | ||||
| 		ezhttp.Body(ezhttp.JSON(reqBody)), | ||||
| 	) | ||||
|  | ||||
| 	resp, err := ezhttp.Do(req) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer resp.Body.Close() | ||||
|  | ||||
| 	response, err := ezhttp.ParseJsonResponse[model.LoginResponse](resp.Body) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return response, nil | ||||
| } | ||||
|  | ||||
| func (api *Api) AuthCode(csrfToken, sessionID string) (*model.AuthCodeResponse, error) { | ||||
| 	req := ezhttp.Request( | ||||
| 		ezhttp.Template(api.tmpl), | ||||
| 		ezhttp.Method("POST"), | ||||
| 		ezhttp.AppendPath("/openapi/authorize/code"), | ||||
| 		ezhttp.Query("client_id", api.config.ClientID, "omadac_id", api.config.OmadaID, "response_type", "code"), | ||||
| 		ezhttp.Headers("Csrf-Token", csrfToken, "Cookie", fmt.Sprintf("TPOMADA_SESSIONID=%s", sessionID)), | ||||
| 	) | ||||
|  | ||||
| 	resp, err := ezhttp.Do(req) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer resp.Body.Close() | ||||
|  | ||||
| 	response, err := ezhttp.ParseJsonResponse[model.AuthCodeResponse](resp.Body) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return response, nil | ||||
| } | ||||
|  | ||||
| func (api *Api) AuthToken(authCode string) (*model.AuthTokenResponse, error) { | ||||
| 	req := ezhttp.Request( | ||||
| 		ezhttp.Template(api.tmpl), | ||||
| 		ezhttp.Method("POST"), | ||||
| 		ezhttp.AppendPath("/openapi/authorize/token"), | ||||
| 		ezhttp.Query( | ||||
| 			"code", authCode, | ||||
| 			"grant_type", "authorization_code", | ||||
| 			"client_id", api.config.ClientID, | ||||
| 			"client_secret", api.config.ClientSecret, | ||||
| 		), | ||||
| 	) | ||||
|  | ||||
| 	resp, err := ezhttp.Do(req) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer resp.Body.Close() | ||||
|  | ||||
| 	response, err := ezhttp.ParseJsonResponse[model.AuthTokenResponse](resp.Body) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return response, nil | ||||
| } | ||||
							
								
								
									
										59
									
								
								client.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								client.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,59 @@ | ||||
| package omadaapi | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strconv" | ||||
|  | ||||
| 	"git.tordarus.net/tordarus/ezhttp" | ||||
| 	"git.tordarus.net/tordarus/omada-api/model" | ||||
| ) | ||||
|  | ||||
| func (api *Api) GetClients(siteID model.SiteID) <-chan *model.Client { | ||||
| 	out := make(chan *model.Client, 1000) | ||||
|  | ||||
| 	go func() { | ||||
| 		defer close(out) | ||||
|  | ||||
| 		for page := 1; ; page++ { | ||||
| 			resp, err := api.getClients(page, siteID) | ||||
| 			if err != nil { | ||||
| 				return | ||||
| 			} | ||||
|  | ||||
| 			for _, v := range resp.Result.Data { | ||||
| 				out <- &v | ||||
| 			} | ||||
|  | ||||
| 			if resp.Result.CurrentPage*resp.Result.CurrentSize >= resp.Result.TotalRows { | ||||
| 				break | ||||
| 			} | ||||
| 		} | ||||
| 	}() | ||||
|  | ||||
| 	return out | ||||
| } | ||||
|  | ||||
| func (api *Api) getClients(page int, siteID model.SiteID) (*model.PagedResponse[model.Client], error) { | ||||
| 	req := ezhttp.Request( | ||||
| 		ezhttp.Template(api.tmpl), | ||||
| 		ezhttp.Method("GET"), | ||||
| 		ezhttp.AppendPath(fmt.Sprintf("/openapi/v1/%s/sites/%s/clients", api.config.OmadaID, siteID)), | ||||
| 		ezhttp.Query( | ||||
| 			"page", strconv.Itoa(page), | ||||
| 			"pageSize", "100", | ||||
| 		), | ||||
| 	) | ||||
|  | ||||
| 	resp, err := ezhttp.Do(req) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer resp.Body.Close() | ||||
|  | ||||
| 	response, err := ezhttp.ParseJsonResponse[model.PagedResponse[model.Client]](resp.Body) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return response, nil | ||||
| } | ||||
							
								
								
									
										59
									
								
								device.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								device.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,59 @@ | ||||
| package omadaapi | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strconv" | ||||
|  | ||||
| 	"git.tordarus.net/tordarus/ezhttp" | ||||
| 	"git.tordarus.net/tordarus/omada-api/model" | ||||
| ) | ||||
|  | ||||
| func (api *Api) GetDevices(siteID model.SiteID) <-chan *model.Device { | ||||
| 	out := make(chan *model.Device, 1000) | ||||
|  | ||||
| 	go func() { | ||||
| 		defer close(out) | ||||
|  | ||||
| 		for page := 1; ; page++ { | ||||
| 			resp, err := api.getDevices(page, siteID) | ||||
| 			if err != nil { | ||||
| 				return | ||||
| 			} | ||||
|  | ||||
| 			for _, v := range resp.Result.Data { | ||||
| 				out <- &v | ||||
| 			} | ||||
|  | ||||
| 			if resp.Result.CurrentPage*resp.Result.CurrentSize >= resp.Result.TotalRows { | ||||
| 				break | ||||
| 			} | ||||
| 		} | ||||
| 	}() | ||||
|  | ||||
| 	return out | ||||
| } | ||||
|  | ||||
| func (api *Api) getDevices(page int, siteID model.SiteID) (*model.PagedResponse[model.Device], error) { | ||||
| 	req := ezhttp.Request( | ||||
| 		ezhttp.Template(api.tmpl), | ||||
| 		ezhttp.Method("GET"), | ||||
| 		ezhttp.AppendPath(fmt.Sprintf("/openapi/v1/%s/sites/%s/devices", api.config.OmadaID, siteID)), | ||||
| 		ezhttp.Query( | ||||
| 			"page", strconv.Itoa(page), | ||||
| 			"pageSize", "100", | ||||
| 		), | ||||
| 	) | ||||
|  | ||||
| 	resp, err := ezhttp.Do(req) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer resp.Body.Close() | ||||
|  | ||||
| 	response, err := ezhttp.ParseJsonResponse[model.PagedResponse[model.Device]](resp.Body) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return response, nil | ||||
| } | ||||
							
								
								
									
										5
									
								
								go.mod
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								go.mod
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| module git.tordarus.net/tordarus/omada-api | ||||
|  | ||||
| go 1.23.0 | ||||
|  | ||||
| require git.tordarus.net/tordarus/ezhttp v0.0.3 | ||||
							
								
								
									
										2
									
								
								go.sum
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								go.sum
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | ||||
| git.tordarus.net/tordarus/ezhttp v0.0.3 h1:K6IlLmqkAFUF68HJsOTKcP3ejco7qfm+MuEagohoouo= | ||||
| git.tordarus.net/tordarus/ezhttp v0.0.3/go.mod h1:Zq9o0Hibny61GqSCwJHa0PfGjVoUFv/zt2PjiQHXvmY= | ||||
							
								
								
									
										40
									
								
								model/ap_info.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								model/ap_info.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,40 @@ | ||||
| package model | ||||
|  | ||||
| import "encoding/json" | ||||
|  | ||||
| type ApInfo struct { | ||||
| 	Type               string                `json:"type"` | ||||
| 	MacAddress         string                `json:"mac"` | ||||
| 	Name               string                `json:"name"` | ||||
| 	IP                 string                `json:"ip"` | ||||
| 	IPv6               []string              `json:"ipv6List"` | ||||
| 	WlanGroupID        string                `json:"wlanId"` | ||||
| 	WirelessUplinkInfo *ApWirelessUplinkInfo `json:"wirelessUplink"` | ||||
| 	Model              string                `json:"model"` | ||||
| 	FirmwareVersion    string                `json:"firmwareVersion"` | ||||
| 	CpuUtil            int                   `json:"cpuUtil"` | ||||
| 	MemUtil            int                   `json:"memoryUtil"` | ||||
| 	UptimeSeconds      int                   `json:"uptimeLong"` | ||||
| } | ||||
|  | ||||
| func (i ApInfo) String() string { | ||||
| 	data, _ := json.MarshalIndent(i, "", "\t") | ||||
| 	return string(data) | ||||
| } | ||||
|  | ||||
| type ApWirelessUplinkInfo struct { | ||||
| 	UplinkMacAddress string `json:"uplinkMac"` | ||||
| 	Name             string `json:"name"` | ||||
| 	Channel          int    `json:"channel"` | ||||
| 	SignalStrengh    int    `json:"rssi"` | ||||
| 	SignalNoiseRatio int    `json:"snr"` | ||||
| 	TransferRate     string `json:"txRate"` | ||||
| 	TransferRateMbps int    `json:"txRateInt"` | ||||
| 	ReceiveRate      string `json:"rxRate"` | ||||
| 	ReceiveRateMbps  int    `json:"rxRateInt"` | ||||
| 	UpBytes          int    `json:"upBytes"` | ||||
| 	DownBytes        int    `json:"downBytes"` | ||||
| 	UpPackets        int    `json:"upPackets"` | ||||
| 	DownPackets      int    `json:"downPackets"` | ||||
| 	Activity         int    `json:"activity"` | ||||
| } | ||||
							
								
								
									
										209
									
								
								model/client.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										209
									
								
								model/client.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,209 @@ | ||||
| package model | ||||
|  | ||||
| import "encoding/json" | ||||
|  | ||||
| type Client struct { | ||||
| 	ID                        string                      `json:"id"` | ||||
| 	MacAddress                string                      `json:"mac"` | ||||
| 	Name                      string                      `json:"name"` | ||||
| 	Hostname                  string                      `json:"hostName"` | ||||
| 	Vendor                    string                      `json:"vendor"` | ||||
| 	DeviceType                string                      `json:"deviceType"` | ||||
| 	DeviceCategory            string                      `json:"deviceCategory"` | ||||
| 	OsName                    string                      `json:"osName"` | ||||
| 	IP                        string                      `json:"ip"` | ||||
| 	IPv6List                  []string                    `json:"ipv6List"` | ||||
| 	ConnectionType            ConnectionType              `json:"connectType"` | ||||
| 	ConnectionDevType         ConnectionDeviceType        `json:"connectDevType"` | ||||
| 	ConnectedToWirelessRouter bool                        `json:"connectedToWirelessRouter"` | ||||
| 	Wireless                  bool                        `json:"wireless"` | ||||
| 	SSID                      string                      `json:"ssid"` | ||||
| 	SignalLevel               int                         `json:"signalLevel"` | ||||
| 	HealthScore               int                         `json:"healthScore"` | ||||
| 	SignalRank                int                         `json:"signalRank"` | ||||
| 	WifiMode                  WifiMode                    `json:"wifiMode"` | ||||
| 	ApName                    string                      `json:"apName"` | ||||
| 	ApMac                     string                      `json:"apMac"` | ||||
| 	RadioID                   RadioID                     `json:"radioId"` | ||||
| 	Channel                   int                         `json:"channel"` | ||||
| 	ReceiveRateKbits          int                         `json:"rxRate"` | ||||
| 	TransferRateKbits         int                         `json:"txRate"` | ||||
| 	PowerSave                 bool                        `json:"powerSave"` | ||||
| 	SignalStrengh             int                         `json:"rssi"` | ||||
| 	SignalNoiseRatio          int                         `json:"snr"` | ||||
| 	SwitchMac                 string                      `json:"switchMac"` | ||||
| 	SwitchName                string                      `json:"switchName"` | ||||
| 	GatewayMac                string                      `json:"gatewayMac"` | ||||
| 	GatewayName               string                      `json:"gatewayName"` | ||||
| 	VLanID                    int                         `json:"vid"` | ||||
| 	NetworkName               string                      `json:"networkName"` | ||||
| 	Dot1xIdentity             string                      `json:"dot1xIdentity"` | ||||
| 	Dot1xVlan                 int                         `json:"dot1xVlan"` | ||||
| 	Port                      int                         `json:"port"` | ||||
| 	LagID                     int                         `json:"lagId"` | ||||
| 	Activity                  int                         `json:"activity"` | ||||
| 	TrafficDownBytes          int                         `json:"trafficDown"` | ||||
| 	TrafficUpBytes            int                         `json:"trafficUp"` | ||||
| 	UptimeSeconds             int                         `json:"uptime"` | ||||
| 	LastSeen                  int                         `json:"lastSeen"` | ||||
| 	AuthStatus                AuthStatus                  `json:"authStatus"` | ||||
| 	Blocked                   bool                        `json:"blocked"` | ||||
| 	Guest                     bool                        `json:"guest"` | ||||
| 	Active                    bool                        `json:"active"` | ||||
| 	Manager                   bool                        `json:"manager"` | ||||
| 	IpSetting                 *ClientIpSetting            `json:"ipSetting"` | ||||
| 	DownPacket                int                         `json:"downPacket"` | ||||
| 	UpPacket                  int                         `json:"upPacket"` | ||||
| 	RateLimit                 *ClientRateLimit            `json:"rateLimit"` | ||||
| 	ClientLockToApSetting     *ClientLockToApSetting      `json:"clientLockToApSetting"` | ||||
| 	MultiLink                 []*ClientMultiFrequencyInfo `json:"multiLink"` | ||||
| 	Unit                      int                         `json:"unit"` | ||||
| 	StandardPort              string                      `json:"standardPort"` | ||||
| 	BlockDisable              bool                        `json:"blockDisable"` | ||||
| 	DhcpLeaseTimeSeconds      int                         `json:"dhcpLeaseTime"` | ||||
| 	SystemName                string                      `json:"systemName"` | ||||
| 	Description               string                      `json:"description"` | ||||
| 	Capabilities              []string                    `json:"capabilities"` | ||||
| 	ClientStat                *ClientStat                 `json:"clientStat"` | ||||
| } | ||||
|  | ||||
| func (c Client) String() string { | ||||
| 	data, _ := json.MarshalIndent(c, "", "\t") | ||||
| 	return string(data) | ||||
| } | ||||
|  | ||||
| type ConnectionType int | ||||
|  | ||||
| const ( | ||||
| 	ConnectionTypeWirelessGuest ConnectionType = iota | ||||
| 	ConnectionTypeWirelessUser | ||||
| 	ConnectionTypeWiredUser | ||||
| ) | ||||
|  | ||||
| type ConnectionDeviceType string | ||||
|  | ||||
| const ( | ||||
| 	ConnectionDeviceTypeAP      ConnectionDeviceType = "ap" | ||||
| 	ConnectionDeviceTypeSwitch  ConnectionDeviceType = "switch" | ||||
| 	ConnectionDeviceTypeGateway ConnectionDeviceType = "gateway" | ||||
| ) | ||||
|  | ||||
| type WifiMode int | ||||
|  | ||||
| const ( | ||||
| 	WifiMode11a WifiMode = iota | ||||
| 	WifiMode11b | ||||
| 	WifiMode11g | ||||
| 	WifiMode11na | ||||
| 	WifiMode11ng | ||||
| 	WifiMode11ac | ||||
| 	WifiMode11axa | ||||
| 	WifiMode11axg | ||||
| 	WifiMode11beg | ||||
| 	WifiMode11bea | ||||
| ) | ||||
|  | ||||
| type RadioID int | ||||
|  | ||||
| const ( | ||||
| 	RadioID_2_4G RadioID = iota | ||||
| 	RadioID_5G   RadioID = iota | ||||
| 	RadioID_5G2  RadioID = iota | ||||
| 	RadioID_6G   RadioID = iota | ||||
| ) | ||||
|  | ||||
| type AuthStatus int | ||||
|  | ||||
| const ( | ||||
| 	AuthStatusConnected AuthStatus = iota | ||||
| 	AuthStatusPending | ||||
| 	AuthStatusAuthorized | ||||
| 	AuthStatusAuthFree | ||||
| ) | ||||
|  | ||||
| type ClientIpSetting struct { | ||||
| 	UseFixedAddr bool   `json:"useFixedAddr"` | ||||
| 	NetID        string `json:"netId"` | ||||
| 	IP           string `json:"ip"` | ||||
| } | ||||
|  | ||||
| type ClientRateLimit struct { | ||||
| 	Mode               RateLimitMode    `json:"mode"` | ||||
| 	RateLimitProfileID string           `json:"rateLimitProfileId"` | ||||
| 	CustomRateLimit    *CustomRateLimit `json:"customRateLimit"` | ||||
| } | ||||
|  | ||||
| type RateLimitMode int | ||||
|  | ||||
| const ( | ||||
| 	RateLimitModeCustom RateLimitMode = iota | ||||
| 	RateLimitModeProfile | ||||
| ) | ||||
|  | ||||
| type CustomRateLimit struct { | ||||
| 	UpEnable   bool      `json:"upEnable"` | ||||
| 	UpUnit     SpeedUnit `json:"upUnit"` | ||||
| 	UpLimit    int       `json:"upLimit"` | ||||
| 	DownEnable bool      `json:"downEnable"` | ||||
| 	DownUnit   SpeedUnit `json:"downUnit"` | ||||
| 	DownLimit  int       `json:"downLimit"` | ||||
| } | ||||
|  | ||||
| type SpeedUnit int | ||||
|  | ||||
| const ( | ||||
| 	SpeedUnitKbps SpeedUnit = iota | ||||
| 	SpeedUnitMbps | ||||
| ) | ||||
|  | ||||
| type ClientLockToApSetting struct { | ||||
| 	Enable bool           `json:"enable"` | ||||
| 	APs    []*ApBriefInfo `json:"aps"` | ||||
| } | ||||
|  | ||||
| type ApBriefInfo struct { | ||||
| 	Name       string `json:"name"` | ||||
| 	MacAddress string `json:"mac"` | ||||
| } | ||||
|  | ||||
| type ClientMultiFrequencyInfo struct { | ||||
| 	RadioID            int      `json:"radioId"` | ||||
| 	WifiMode           WifiMode `json:"wifiMode"` | ||||
| 	Channel            int      `json:"channel"` | ||||
| 	ReceiveRateKbits   int      `json:"rxRate"` | ||||
| 	TransferRateKbits  int      `json:"txRate"` | ||||
| 	PowerSave          bool     `json:"powerSave"` | ||||
| 	SignalStrengh      int      `json:"rssi"` | ||||
| 	SignalNoiseRatio   int      `json:"snr"` | ||||
| 	SignalLevel        int      `json:"signalLevel"` | ||||
| 	SignalRank         int      `json:"signalRank"` | ||||
| 	UpPacket           int      `json:"upPacket"` | ||||
| 	DownPacket         int      `json:"downPacket"` | ||||
| 	TrafficDownBytes   int      `json:"trafficDown"` | ||||
| 	TrafficUpBytes     int      `json:"trafficUp"` | ||||
| 	Activity           int      `json:"activity"` | ||||
| 	SignalLevelAndRank int      `json:"signalLevelAndRank"` | ||||
| } | ||||
|  | ||||
| type ClientStat struct { | ||||
| 	Total            int `json:"total"` | ||||
| 	Wireless         int `json:"wireless"` | ||||
| 	Wired            int `json:"wired"` | ||||
| 	Num2G            int `json:"num2g"` | ||||
| 	Num5G            int `json:"num5g"` | ||||
| 	Num6G            int `json:"num6g"` | ||||
| 	NumUser          int `json:"numUser"` | ||||
| 	NumGuest         int `json:"numGuest"` | ||||
| 	NumWirelessUser  int `json:"numWirelessUser"` | ||||
| 	NumWirelessGuest int `json:"numWirelessGuest"` | ||||
| 	Num2gUser        int `json:"num2gUser"` | ||||
| 	Num5gUser        int `json:"num5gUser"` | ||||
| 	Num6gUser        int `json:"num6gUser"` | ||||
| 	Num2gGuest       int `json:"num2gGuest"` | ||||
| 	Num5gGuest       int `json:"num5gGuest"` | ||||
| 	Num6gGuest       int `json:"num6gGuest"` | ||||
| 	Poor             int `json:"poor"` | ||||
| 	Fair             int `json:"fair"` | ||||
| 	NoData           int `json:"noData"` | ||||
| 	Good             int `json:"good"` | ||||
| } | ||||
							
								
								
									
										45
									
								
								model/device.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								model/device.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | ||||
| package model | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| ) | ||||
|  | ||||
| type Device struct { | ||||
| 	MacAddress       string       `json:"mac"` | ||||
| 	Name             string       `json:"name"` | ||||
| 	Type             DeviceType   `json:"type"` | ||||
| 	Subtype          string       `json:"subtype"` | ||||
| 	DeviceSeriesType int          `json:"deviceSeriesType"` | ||||
| 	Model            string       `json:"model"` | ||||
| 	IP               string       `json:"ip"` | ||||
| 	IPv6             []string     `json:"ipv6"` | ||||
| 	Uptime           string       `json:"uptime"` | ||||
| 	Status           DeviceStatus `json:"status"` | ||||
| 	LastSeen         int          `json:"lastSeen"` | ||||
| 	CpuUtil          int          `json:"cpuUtil"` | ||||
| 	MemUtil          int          `json:"memUtil"` | ||||
| 	SerialNumber     string       `json:"sn"` | ||||
| 	LicenseStatus    int          `json:"licenseStatus"` | ||||
| 	TagName          string       `json:"tagName"` | ||||
| } | ||||
|  | ||||
| func (d Device) String() string { | ||||
| 	data, _ := json.MarshalIndent(d, "", "\t") | ||||
| 	return string(data) | ||||
| } | ||||
|  | ||||
| type DeviceStatus int | ||||
|  | ||||
| const ( | ||||
| 	DeviceStatusDisconnected DeviceStatus = iota | ||||
| 	DeviceStatusConnected | ||||
| 	DeviceStatusPending | ||||
| 	DeviceStatusHeartbeatMissed | ||||
| 	DeviceStatusIsolated | ||||
| ) | ||||
|  | ||||
| type DeviceType string | ||||
|  | ||||
| const ( | ||||
| 	DeviceTypeAP DeviceType = "ap" | ||||
| ) | ||||
							
								
								
									
										26
									
								
								model/login.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								model/login.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | ||||
| package model | ||||
|  | ||||
| type LoginRequest struct { | ||||
| 	Username string `json:"username"` | ||||
| 	Password string `json:"password"` | ||||
| } | ||||
|  | ||||
| type LoginResponse Response[LoginResponseResult] | ||||
| type LoginResponseResult struct { | ||||
| 	CsrfToken string `json:"csrfToken"` | ||||
| 	SessionID string `json:"sessionId"` | ||||
| } | ||||
|  | ||||
| type AuthCodeResponse struct { | ||||
| 	ErrorCode int     `json:"errorCode"` | ||||
| 	Message   string  `json:"msg"` | ||||
| 	Result    *string `json:"result"` | ||||
| } | ||||
|  | ||||
| type AuthTokenResponse Response[AuthTokenResponseResult] | ||||
| type AuthTokenResponseResult struct { | ||||
| 	AccessToken  string `json:"accessToken"` | ||||
| 	TokenType    string `json:"tokenType"` | ||||
| 	ExpiresIn    int    `json:"expiresIn"` | ||||
| 	RefreshToken string `json:"refreshToken"` | ||||
| } | ||||
							
								
								
									
										15
									
								
								model/response.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								model/response.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| package model | ||||
|  | ||||
| type Response[T any] struct { | ||||
| 	ErrorCode int    `json:"errorCode"` | ||||
| 	Message   string `json:"msg"` | ||||
| 	Result    T      `json:"result"` | ||||
| } | ||||
|  | ||||
| type PagedResponse[T any] Response[PagedResponseResult[T]] | ||||
| type PagedResponseResult[T any] struct { | ||||
| 	TotalRows   int `json:"totalRows"` | ||||
| 	CurrentPage int `json:"currentPage"` | ||||
| 	CurrentSize int `json:"currentSize"` | ||||
| 	Data        []T `json:"data"` | ||||
| } | ||||
							
								
								
									
										22
									
								
								model/site.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								model/site.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | ||||
| package model | ||||
|  | ||||
| import "encoding/json" | ||||
|  | ||||
| type SiteID string | ||||
| type Site struct { | ||||
| 	ID        SiteID   `json:"siteId"` | ||||
| 	Name      string   `json:"name"` | ||||
| 	TagIDs    []string `json:"tagIds"` | ||||
| 	Region    string   `json:"region"` | ||||
| 	TimeZone  string   `json:"timeZone"` | ||||
| 	Scenario  string   `json:"scenario"` | ||||
| 	Longitude float64  `json:"longitude"` | ||||
| 	Latitude  float64  `json:"latitude"` | ||||
| 	Address   string   `json:"address"` | ||||
| 	Type      int      `json:"type,omitempty"` | ||||
| } | ||||
|  | ||||
| func (s Site) String() string { | ||||
| 	data, _ := json.MarshalIndent(s, "", "\t") | ||||
| 	return string(data) | ||||
| } | ||||
							
								
								
									
										59
									
								
								site.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								site.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,59 @@ | ||||
| package omadaapi | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strconv" | ||||
|  | ||||
| 	"git.tordarus.net/tordarus/ezhttp" | ||||
| 	"git.tordarus.net/tordarus/omada-api/model" | ||||
| ) | ||||
|  | ||||
| func (api *Api) GetSites() <-chan *model.Site { | ||||
| 	out := make(chan *model.Site, 1000) | ||||
|  | ||||
| 	go func() { | ||||
| 		defer close(out) | ||||
|  | ||||
| 		for page := 1; ; page++ { | ||||
| 			resp, err := api.getSites(page) | ||||
| 			if err != nil { | ||||
| 				return | ||||
| 			} | ||||
|  | ||||
| 			for _, v := range resp.Result.Data { | ||||
| 				out <- &v | ||||
| 			} | ||||
|  | ||||
| 			if resp.Result.CurrentPage*resp.Result.CurrentSize >= resp.Result.TotalRows { | ||||
| 				break | ||||
| 			} | ||||
| 		} | ||||
| 	}() | ||||
|  | ||||
| 	return out | ||||
| } | ||||
|  | ||||
| func (api *Api) getSites(page int) (*model.PagedResponse[model.Site], error) { | ||||
| 	req := ezhttp.Request( | ||||
| 		ezhttp.Template(api.tmpl), | ||||
| 		ezhttp.Method("GET"), | ||||
| 		ezhttp.AppendPath(fmt.Sprintf("/openapi/v1/%s/sites", api.config.OmadaID)), | ||||
| 		ezhttp.Query( | ||||
| 			"page", strconv.Itoa(page), | ||||
| 			"pageSize", "100", | ||||
| 		), | ||||
| 	) | ||||
|  | ||||
| 	resp, err := ezhttp.Do(req) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer resp.Body.Close() | ||||
|  | ||||
| 	response, err := ezhttp.ParseJsonResponse[model.PagedResponse[model.Site]](resp.Body) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return response, nil | ||||
| } | ||||
		Reference in New Issue
	
	Block a user