arlo-go/camera.go

271 lines
9.0 KiB
Go
Raw Normal View History

package arlo
import (
2020-05-27 19:03:26 +00:00
"context"
"fmt"
)
// A Camera is a Device of type "camera".
// This type is here just for semantics. Some methods explicitly require a device of a certain type.
type Camera Device
2020-05-27 08:49:40 +00:00
type CameraState struct {
InterfaceVersion int `json:"interfaceVersion"`
SerialNumber string `json:"serialNumber"`
BatteryLevel int `json:"batteryLevel"`
BatteryTech string `json:"batteryTech"`
ChargerTech string `json:"chargerTech"`
ChargingState string `json:"chargingState"`
ChargeOnly bool `json:"chargeOnly"`
ChargeNotificationLedEnable bool `json:"chargeNotificationLedEnable"`
AudioMicAGC int `json:"audioMicAGC"`
SignalStrength int `json:"signalStrength"`
Brightness int `json:"brightness"`
Mirror bool `json:"mirror"`
Flip bool `json:"flip"`
PowerSaveMode int `json:"powerSaveMode"`
Zoom struct {
Topleftx int `json:"topleftx"`
Toplefty int `json:"toplefty"`
Bottomrightx int `json:"bottomrightx"`
Bottomrighty int `json:"bottomrighty"`
} `json:"zoom"`
Mic struct {
Mute bool `json:"mute"`
Volume int `json:"volume"`
} `json:"mic"`
Speaker struct {
Mute bool `json:"mute"`
Volume int `json:"volume"`
} `json:"speaker"`
StreamingMode string `json:"streamingMode"`
ContinuousStreamState string `json:"continuousStreamState"`
Motion struct {
Sensitivity int `json:"sensitivity"`
Zones []interface{} `json:"zones"`
} `json:"motion"`
Resolution struct {
Width int `json:"width"`
Height int `json:"height"`
} `json:"resolution"`
IdleLedEnable bool `json:"idleLedEnable"`
PrivacyActive bool `json:"privacyActive"`
StandbyActive bool `json:"standbyActive"`
SetupActive bool `json:"setupActive"`
ConnectionState string `json:"connectionState"`
ActivityState string `json:"activityState"`
SwVersion string `json:"swVersion"`
HwVersion string `json:"hwVersion"`
ModelID string `json:"modelId"`
MotionSetupModeEnabled bool `json:"motionSetupModeEnabled"`
MotionSetupModeSensitivity int `json:"motionSetupModeSensitivity"`
MotionDetected bool `json:"motionDetected"`
AudioDetected bool `json:"audioDetected"`
HasStreamed bool `json:"hasStreamed"`
LocalRecordingActive bool `json:"localRecordingActive"`
OlsonTimeZone string `json:"olsonTimeZone"`
Name string `json:"name"`
NightVisionMode int `json:"nightVisionMode"`
VideoMode string `json:"videoMode"`
Hdr string `json:"hdr"`
UpdateAvailable interface{} `json:"updateAvailable"`
BlockNotifications struct {
Block bool `json:"block"`
Duration int `json:"duration"`
EndTime int `json:"endTime"`
} `json:"blockNotifications"`
BestLocalLiveStreaming string `json:"bestLocalLiveStreaming"`
}
2018-09-22 19:22:42 +00:00
// Cameras is a slice of Camera objects.
2020-05-27 08:49:40 +00:00
type Cameras []*Camera
// Find returns a camera with the device id passed in.
func (cs *Cameras) Find(deviceId string) *Camera {
for _, c := range *cs {
if c.DeviceId == deviceId {
2020-05-27 08:49:40 +00:00
return c
}
}
return nil
}
2020-05-27 19:03:26 +00:00
func (c *Camera) On(ctx context.Context) error {
b := c.arlo.Basestations.Find(c.ParentId)
if b == nil {
2020-05-27 19:03:26 +00:00
return fmt.Errorf("basestation (%s) not found for camera (%s)", c.ParentId, c.DeviceId)
}
2020-05-27 19:03:26 +00:00
err := b.makeRequest(ctx, "set", fmt.Sprintf("cameras/%s", c.DeviceId), true, CameraProperties{
PrivacyActive: false,
}, nil)
if err != nil {
return err
}
return nil
}
// On turns a camera off; meaning it won't detect and record events.
2020-05-27 19:03:26 +00:00
func (c *Camera) Off(ctx context.Context) (response *EventStreamResponse, err error) {
payload := EventStreamPayload{
Action: "set",
Resource: fmt.Sprintf("cameras/%s", c.DeviceId),
PublishResponse: true,
Properties: CameraProperties{
PrivacyActive: true,
},
From: fmt.Sprintf("%s_%s", c.UserId, TransIdPrefix),
To: c.ParentId,
}
b := c.arlo.Basestations.Find(c.ParentId)
if b == nil {
2020-05-27 08:49:40 +00:00
return nil, fmt.Errorf("basestation (%s) not found for camera (%s)", c.ParentId, c.DeviceId)
}
2020-05-27 19:03:26 +00:00
return b.makeEventStreamRequest(ctx, payload)
}
// SetBrightness sets the camera brightness.
// NOTE: Brightness is between -2 and 2 in increments of 1 (-2, -1, 0, 1, 2).
// Setting it to an invalid value has no effect.
2020-05-27 19:03:26 +00:00
func (c *Camera) SetBrightness(ctx context.Context, brightness int) (response *EventStreamResponse, err error) {
// Sanity check; if the values are above or below the allowed limits, set them to their limit.
if brightness < -2 {
brightness = -2
} else if brightness > 2 {
brightness = 2
}
payload := EventStreamPayload{
Action: "set",
Resource: fmt.Sprintf("cameras/%s", c.DeviceId),
PublishResponse: true,
Properties: CameraProperties{
Brightness: brightness,
},
From: fmt.Sprintf("%s_%s", c.UserId, TransIdPrefix),
To: c.ParentId,
}
b := c.arlo.Basestations.Find(c.ParentId)
if b == nil {
2020-05-27 08:49:40 +00:00
return nil, fmt.Errorf("basestation (%s) not found for camera (%s)", c.ParentId, c.DeviceId)
}
2020-05-27 19:03:26 +00:00
return b.makeEventStreamRequest(ctx, payload)
}
func (c *Camera) EnableMotionAlerts(ctx context.Context, sensitivity int, zones []string) error {
b := c.arlo.Basestations.Find(c.ParentId)
if b == nil {
return fmt.Errorf("basestation (%s) not found for camera (%s)", c.ParentId, c.DeviceId)
}
err := b.makeRequest(ctx, "set", fmt.Sprintf("cameras/%s", c.DeviceId), true, MotionDetectionProperties{
BaseDetectionProperties: BaseDetectionProperties{
Armed: true,
Sensitivity: sensitivity,
Zones: zones,
},
}, nil)
if err != nil {
return err
}
return nil
}
2020-05-27 19:03:26 +00:00
func (c *Camera) DisableMotionAlerts(ctx context.Context, sensitivity int, zones []string) (response *EventStreamResponse, err error) {
payload := EventStreamPayload{
Action: "set",
Resource: fmt.Sprintf("cameras/%s", c.DeviceId),
PublishResponse: true,
Properties: MotionDetectionProperties{
BaseDetectionProperties: BaseDetectionProperties{
Armed: false,
Sensitivity: sensitivity,
Zones: zones,
},
},
From: fmt.Sprintf("%s_%s", c.UserId, TransIdPrefix),
To: c.ParentId,
}
b := c.arlo.Basestations.Find(c.ParentId)
if b == nil {
2020-05-27 08:49:40 +00:00
return nil, fmt.Errorf("basestation (%s) not found for camera (%s)", c.ParentId, c.DeviceId)
}
2020-05-27 19:03:26 +00:00
return b.makeEventStreamRequest(ctx, payload)
}
2020-05-27 19:03:26 +00:00
func (c *Camera) EnableAudioAlerts(ctx context.Context, sensitivity int) (response *EventStreamResponse, err error) {
payload := EventStreamPayload{
Action: "set",
Resource: fmt.Sprintf("cameras/%s", c.DeviceId),
PublishResponse: true,
Properties: AudioDetectionProperties{
BaseDetectionProperties: BaseDetectionProperties{
Armed: true,
Sensitivity: sensitivity,
},
},
From: fmt.Sprintf("%s_%s", c.UserId, TransIdPrefix),
To: c.ParentId,
}
b := c.arlo.Basestations.Find(c.ParentId)
if b == nil {
2020-05-27 08:49:40 +00:00
return nil, fmt.Errorf("basestation (%s) not found for camera (%s)", c.ParentId, c.DeviceId)
}
2020-05-27 19:03:26 +00:00
return b.makeEventStreamRequest(ctx, payload)
}
2020-05-27 19:03:26 +00:00
func (c *Camera) DisableAudioAlerts(ctx context.Context, sensitivity int) (response *EventStreamResponse, err error) {
payload := EventStreamPayload{
Action: "set",
Resource: fmt.Sprintf("cameras/%s", c.DeviceId),
PublishResponse: true,
Properties: AudioDetectionProperties{
BaseDetectionProperties: BaseDetectionProperties{
Armed: false,
Sensitivity: sensitivity,
},
},
From: fmt.Sprintf("%s_%s", c.UserId, TransIdPrefix),
To: c.ParentId,
}
b := c.arlo.Basestations.Find(c.ParentId)
if b == nil {
2020-05-27 08:49:40 +00:00
return nil, fmt.Errorf("basestation (%s) not found for camera (%s)", c.ParentId, c.DeviceId)
}
2020-05-27 19:03:26 +00:00
return b.makeEventStreamRequest(ctx, payload)
}
// action: disabled OR recordSnapshot OR recordVideo
2020-05-27 19:03:26 +00:00
func (c *Camera) SetAlertNotificationMethods(ctx context.Context, action string, email, push bool) (response *EventStreamResponse, err error) {
payload := EventStreamPayload{
Action: "set",
Resource: fmt.Sprintf("cameras/%s", c.DeviceId),
PublishResponse: true,
Properties: EventActionProperties{
BaseEventActionProperties: BaseEventActionProperties{
ActionType: action,
StopType: "timeout",
Timeout: 15,
EmailNotification: EmailNotification{
Enabled: email,
EmailList: []string{"__OWNER_EMAIL__"},
PushNotification: push,
},
},
},
From: fmt.Sprintf("%s_%s", c.UserId, TransIdPrefix),
To: c.ParentId,
}
b := c.arlo.Basestations.Find(c.ParentId)
if b == nil {
2020-05-27 08:49:40 +00:00
return nil, fmt.Errorf("basestation (%s) not found for camera (%s)", c.ParentId, c.DeviceId)
2018-09-22 19:22:42 +00:00
}
2020-05-27 19:03:26 +00:00
return b.makeEventStreamRequest(ctx, payload)
}