main
Raw Download raw file
  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}