main
1package protect
2
3import (
4 "context"
5 "fmt"
6 "net/url"
7 "strconv"
8 "time"
9)
10
11// EventsParams configures the events query.
12type EventsParams struct {
13 CameraID string
14 StartTime time.Time
15 EndTime time.Time
16 Types []string // e.g., "motion", "smartDetect"
17 Limit int // Max events per request
18}
19
20// ListEvents fetches events for the given parameters.
21// This handles pagination internally and returns all matching events.
22func (c *Client) ListEvents(ctx context.Context, params EventsParams) ([]Event, error) {
23 var allEvents []Event
24 limit := params.Limit
25 if limit <= 0 {
26 limit = 100
27 }
28
29 startMs := params.StartTime.UnixMilli()
30 endMs := params.EndTime.UnixMilli()
31
32 for {
33 events, err := c.fetchEventsPage(ctx, params.CameraID, startMs, endMs, params.Types, limit)
34 if err != nil {
35 return allEvents, err
36 }
37
38 if len(events) == 0 {
39 break
40 }
41
42 allEvents = append(allEvents, events...)
43
44 // If we got fewer than limit, we're done
45 if len(events) < limit {
46 break
47 }
48
49 // Use end time of last event (+1ms) as start for next page
50 lastEvent := events[len(events)-1]
51 startMs = lastEvent.End + 1
52 }
53
54 return allEvents, nil
55}
56
57// fetchEventsPage fetches a single page of events.
58func (c *Client) fetchEventsPage(ctx context.Context, cameraID string, startMs, endMs int64, types []string, limit int) ([]Event, error) {
59 params := url.Values{}
60 params.Set("cameras", cameraID)
61 params.Set("start", strconv.FormatInt(startMs, 10))
62 params.Set("end", strconv.FormatInt(endMs, 10))
63 params.Set("limit", strconv.Itoa(limit))
64 params.Set("orderDirection", "ASC")
65
66 if len(types) > 0 {
67 for _, t := range types {
68 params.Add("types", t)
69 }
70 }
71
72 path := "/events?" + params.Encode()
73 req, err := c.newRequest(ctx, "GET", path, nil)
74 if err != nil {
75 return nil, fmt.Errorf("creating request: %w", err)
76 }
77
78 var events EventsResponse
79 err = c.doJSON(req, &events)
80 if err != nil {
81 return nil, fmt.Errorf("fetching events: %w", err)
82 }
83
84 return events, nil
85}
86
87// ListDayEvents is a convenience method to list all events for a single day.
88func (c *Client) ListDayEvents(ctx context.Context, cameraID string, date time.Time) ([]Event, error) {
89 // Start of day in local time
90 startOfDay := time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, date.Location())
91 endOfDay := startOfDay.Add(24 * time.Hour)
92
93 return c.ListEvents(ctx, EventsParams{
94 CameraID: cameraID,
95 StartTime: startOfDay,
96 EndTime: endOfDay,
97 Types: []string{"motion", "smartDetect"},
98 Limit: 100,
99 })
100}