arlo-go/arlo.go

182 lines
4.0 KiB
Go
Raw Normal View History

package arlo
2017-12-10 19:17:09 +00:00
import (
2020-05-27 08:49:40 +00:00
"context"
"fmt"
"sync"
"time"
2020-05-27 08:49:40 +00:00
"github.com/go-resty/resty/v2"
2017-12-10 19:17:09 +00:00
)
type Arlo struct {
user string
pass string
2020-05-27 08:49:40 +00:00
client *resty.Client
Account Account
Basestations Basestations
Cameras Cameras
rwmutex sync.RWMutex
2017-12-10 19:17:09 +00:00
}
2020-05-27 08:49:40 +00:00
func NewArlo() (arlo *Arlo) {
2018-09-22 19:22:42 +00:00
2020-05-27 08:49:40 +00:00
c := resty.New().
SetHostURL(BaseUrl).
SetTimeout(30 * time.Second)
return &Arlo{
2017-12-10 19:17:09 +00:00
client: c,
}
}
2020-05-27 11:35:02 +00:00
func (a *Arlo) get(url string, result interface{}) error {
var errorResponse ErrorResponse
resp, err := a.client.R().
SetResult(result).
SetError(&errorResponse).
Get(url)
if err != nil {
return err
}
if resp.IsError() {
return fmt.Errorf(errorResponse.Reason)
}
return nil
}
func (a *Arlo) post(url string, body interface{}, result interface{}, xcloudId string) error {
var errorResponse ErrorResponse
request := a.client.R().
SetBody(body).
SetResult(result).
SetError(&errorResponse)
if xcloudId != "" {
request.SetHeader("xcloudId", xcloudId)
}
resp, err := request.Post(url)
if err != nil {
return err
}
if resp.IsError() {
return fmt.Errorf(errorResponse.Reason)
}
return nil
}
func (a *Arlo) put(url string, result interface{}, xcloudId string) error {
var errorResponse ErrorResponse
request := a.client.R().
SetResult(result).
SetError(&errorResponse)
if xcloudId != "" {
request.SetHeader("xcloudId", xcloudId)
}
resp, err := request.Put(url)
if err != nil {
return err
}
if resp.IsError() {
return fmt.Errorf(errorResponse.Reason)
}
return nil
}
2020-05-27 08:49:40 +00:00
func (a *Arlo) Login(ctx context.Context, user string, pass string) error {
var loginResponse LoginResponse
2020-05-27 11:35:02 +00:00
err := a.post(LoginV2Uri, map[string]string{
"email": user,
"password": pass,
}, &loginResponse, "")
2018-09-22 19:22:42 +00:00
if err != nil {
2020-05-27 11:35:02 +00:00
return fmt.Errorf("posting login request: %v", err)
}
2020-05-27 08:49:40 +00:00
if !loginResponse.Success {
2020-05-27 11:35:02 +00:00
return fmt.Errorf("no success but no error")
}
2020-05-27 08:49:40 +00:00
a.client.SetHeader("Authorization", loginResponse.Data.Token)
a.Account = loginResponse.Data
if _, err := a.GetDevices(ctx); err != nil {
return fmt.Errorf("getting devices: %v", err)
}
2020-05-27 08:49:40 +00:00
return nil
}
func (a *Arlo) Logout() error {
2020-05-27 11:35:02 +00:00
var response BaseResponse
err := a.put(LogoutUri, &response, "")
if err != nil {
2020-05-27 11:35:02 +00:00
return err
2020-05-27 08:49:40 +00:00
}
2020-05-27 11:35:02 +00:00
if !response.Success {
return fmt.Errorf("no success but no error")
}
2020-05-27 08:49:40 +00:00
return nil
}
2020-05-27 08:49:40 +00:00
func (a *Arlo) GetSession() (*Session, error) {
var response SessionResponse
2020-05-27 11:35:02 +00:00
err := a.get(SessionUri, &response)
2020-05-27 08:49:40 +00:00
if err != nil {
2020-05-27 11:35:02 +00:00
return nil, err
}
2020-05-27 11:35:02 +00:00
if !response.Success {
return nil, fmt.Errorf("no success but no error")
}
return &response.Data, nil
}
2020-05-27 08:49:40 +00:00
func (a *Arlo) GetDevices(ctx context.Context) (*Devices, error) {
var response DeviceResponse
2020-05-27 11:35:02 +00:00
err := a.get(fmt.Sprintf(DevicesUri, time.Now().Format("20060102")), &response)
2020-05-27 08:49:40 +00:00
if err != nil {
2020-05-27 11:35:02 +00:00
return nil, err
}
if !response.Success {
2020-05-27 11:35:02 +00:00
return nil, fmt.Errorf("no success but no error")
}
if len(response.Data) == 0 {
2020-05-27 08:49:40 +00:00
return nil, fmt.Errorf("no device found")
}
2018-09-22 19:22:42 +00:00
// Cache a pointer to the arlo object with each device.
for i := range response.Data {
response.Data[i].arlo = a
}
2018-09-22 19:22:42 +00:00
// Disconnect all of the basestations from the EventStream.
2020-05-27 08:49:40 +00:00
for _, basestation := range a.Basestations {
if err := basestation.Disconnect(); err != nil {
return nil, fmt.Errorf("disconnecting device %s: %v", basestation.DeviceName, err)
}
}
a.rwmutex.Lock()
// Cache the devices as their respective types.
2020-05-27 08:49:40 +00:00
a.Cameras = response.Data.GetCameras()
a.Basestations = response.Data.GetBasestations()
a.rwmutex.Unlock()
// subscribe each basestation to the EventStream.
2020-05-27 08:49:40 +00:00
for _, basestation := range a.Basestations {
if err := basestation.Subscribe(ctx); err != nil {
return nil, fmt.Errorf("subscribing device %s: %v", basestation.DeviceName, err)
}
}
return &response.Data, nil
}
// GetProfile returns the user profile for the currently logged in user.
2020-05-27 08:49:40 +00:00
func (a *Arlo) GetProfile() (*UserProfile, error) {
var response UserProfileResponse
2020-05-27 11:35:02 +00:00
err := a.get(ProfileUri, &response)
2020-05-27 08:49:40 +00:00
if err != nil {
2020-05-27 11:35:02 +00:00
return nil, err
}
2020-05-27 11:35:02 +00:00
if !response.Success {
return nil, fmt.Errorf("no success but no error")
}
2020-05-27 08:49:40 +00:00
return &response.Data, nil
}