-
Notifications
You must be signed in to change notification settings - Fork 4
/
events_types.go
169 lines (157 loc) · 6.72 KB
/
events_types.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
package securityspy
import (
"fmt"
"io"
"sync"
"time"
)
// This is a list of errors returned by the Events methods.
var (
// ErrUnknownEvent never really returns, but will fire if SecuritySpy
// adds new events this library doesn't know about.
ErrUnknownEvent = fmt.Errorf("unknown event")
// ErrCAMParseFail will return if the camera number in an event stream does not exist.
// If you see this, run Refresh() more often, or fix your flaky camera connection.
ErrCAMParseFail = fmt.Errorf("CAM parse failed")
// ErrIDParseFail will return if the camera number provided by the event stream is not a number.
// This should never happen, but future versions of SecuritySpy could trigger this if formats change.
ErrIDParseFail = fmt.Errorf("ID parse failed")
// ErrCAMMissing like the errors above should never return.
// This is triggered by a corrupted event format.
ErrCAMMissing = fmt.Errorf("camera number missing")
// ErrDateParseFail will only trigger if the time stamp format for events changes.
ErrDateParseFail = fmt.Errorf("timestamp parse failed")
// ErrDisconnect becomes the msg in a custom event when the SecSpy event stream is disconnected.
ErrDisconnect = fmt.Errorf("server connection closed")
)
const (
// BadID happens when the ID cannot be parsed.
BadID = -2
// EventBuffer is the channel buffer size for securityspy events.
EventBuffer = 10000
// UnknownEventText should only appear if SecuritySpy adds new event types.
UnknownEventText = "Unknown Event"
// UnknownReasonText should only appear if SecuritySpy adds new motion detection reasons.
UnknownReasonText = "Unknown Reason"
// EventTimeFormat is the go-time-format returned by SecuritySpy's eventStream
// The GMT offset from ++systemInfo is appended later for unmarshaling w/ localization.
EventTimeFormat = "20060102150405"
)
// Events is the main Events interface. Use the methods bound here to bind your
// own functions, methods and channels to SecuritySpy events. Call Watch() to
// connect to the event stream. The Running bool is true when the event stream
// watcher routine is active.
type Events struct {
server *Server
stream io.ReadCloser
eventChan chan Event
eventBinds map[EventType][]func(event Event)
eventChans map[EventType][]chan Event
binds sync.RWMutex
chans sync.RWMutex
Running bool
}
// Event represents a SecuritySpy event from the Stream Reply.
// This is the INPUT data for an event that is sent to a bound callback method or channel.
type Event struct {
Time time.Time // Local time event was recorded.
When time.Time // Event time according to server.
ID int // Negative numbers are custom events.
Camera *Camera // Each event gets a camera interface.
Type EventType // Event identifier
Msg string // Event Text
Errors []error // Errors populated by parse errors.
Reasons []TriggerEvent // Bitmask of trigger reasons.
}
// EventType is a set of constant strings validated by the EventNames map.
type EventType string
// Events that can be returned by the event stream.
// These events can have channels or callback functions bound to them.
// The DISCONNECTED event fires when the event stream is disconnected, so
// watch that event with a binding to detect stream interruptions.
const (
EventArmContinuous EventType = "ARM_C"
EventDisarmContinuous EventType = "DISARM_C"
EventArmMotion EventType = "ARM_M"
EventDisarmMotion EventType = "DISARM_M"
EventDisarmActions EventType = "DISARM_A"
EventArmActions EventType = "ARM_A"
EventSecSpyError EventType = "ERROR"
EventConfigChange EventType = "CONFIGCHANGE"
EventMotionDetected EventType = "MOTION" // Legacy (v4)
EventMotionEnd EventType = "MOTION_END"
EventOnline EventType = "ONLINE"
EventOffline EventType = "OFFLINE"
EventClassify EventType = "CLASSIFY"
EventTriggerMotion EventType = "TRIGGER_M"
EventTriggerAction EventType = "TRIGGER_A"
EventFileWritten EventType = "FILE"
EventKeepAlive EventType = "NULL"
// The following belong to the library, not securityspy.
EventStreamDisconnect EventType = "DISCONNECTED"
EventStreamConnect EventType = "CONNECTED"
EventUnknownEvent EventType = "UNKNOWN"
EventAllEvents EventType = "ALL"
EventWatcherRefreshed EventType = "REFRESH"
EventWatcherRefreshFail EventType = "REFRESHFAIL"
EventStreamCustom EventType = "CUSTOM"
eventStreamStop EventType = "STOP"
)
// EventName returns the human readable names for each event.
func EventName(eventType EventType) string {
return map[EventType]string{
EventArmContinuous: "Continuous Capture Armed",
EventDisarmContinuous: "Continuous Capture Disarmed",
EventArmMotion: "Motion Capture Armed",
EventDisarmMotion: "Motion Capture Disarmed",
EventArmActions: "Actions Armed",
EventDisarmActions: "Actions Disarmed",
EventSecSpyError: "SecuritySpy Error",
EventConfigChange: "Configuration Change",
EventMotionDetected: "Motion Detected", // Legacy (v4)
EventOffline: "Camera Offline",
EventOnline: "Camera Online",
EventClassify: "Classification",
EventTriggerMotion: "Triggered Motion",
EventTriggerAction: "Triggered Action",
EventFileWritten: "File Written",
EventKeepAlive: "Stream Keep Alive",
// The following belong to the library, not securityspy.
EventStreamDisconnect: "Event Stream Disconnected",
EventStreamConnect: "Event Stream Connected",
EventUnknownEvent: UnknownEventText,
EventAllEvents: "Any Event",
EventWatcherRefreshed: "SystemInfo Refresh Success",
EventWatcherRefreshFail: "SystemInfo Refresh Failure",
EventStreamCustom: "Custom Event",
}[eventType]
}
// TriggerEvent represent the "Reason" a motion or action trigger occurred. v5+ only.
type TriggerEvent int
// These are the trigger reasons SecuritySpy exposes. v5+ only.
const (
TriggerByMotion = TriggerEvent(1) << iota
TriggerByAudio
TriggerByScript
TriggerByCameraEvent
TriggerByWebServer
TriggerByOtherCamera
TriggerByManual
TriggerByHumanDetection
TriggerByVehicleDetection
)
// Reasons is the human-readable explanation for a motion detection reason.
var Reasons = map[TriggerEvent]string{ //nolint:gochecknoglobals
TriggerByMotion: "Motion Detected",
TriggerByAudio: "Audio Detected",
TriggerByScript: "AppleScript",
TriggerByCameraEvent: "Camera Event",
TriggerByWebServer: "Web Server",
TriggerByOtherCamera: "Other Camera",
TriggerByManual: "Manual",
TriggerByHumanDetection: "Human Detected",
TriggerByVehicleDetection: "Vehicle Detected",
}
func (reason TriggerEvent) String() string {
return Reasons[reason]
}