initial commit
This commit is contained in:
commit
751ddc2436
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
|
||||
}
|
Loading…
Reference in New Issue
Block a user