Link Search Menu Expand Document

Camlytics Telemetry Interface

Jun 23 2023 at 12:00 AM

  1. Introduction
  2. Aim
  3. Approach
    1. Device Functionality Overview
      1. Capability
      2. Protocol information
    2. Integration Plans
      1. Design Specifications
  4. Usage
    1. Steps on how to deploy and configure the driver
    2. Device Configuration Example and Walkthrough
    3. Available Commander Endpoints
  5. External References
  6. Release Notes

Introduction

Camlytics enables users to connect their camera systems to receive real-time statistics. This is accomplished by combining video monitoring, audience intelligence and space analytics software. Connect your existing private network camera system and get instant real-time statistics on people counting, vehicle counting, locations occupancy, queues, heatmaps and more.

Camlytics

Figure 1 - Camlytics logo

Aim

The statistics provided by Camlytics can be useful for the following use cases:

  • Vehicle counting

  • Occupancy monitoring

  • Queues

Approach

Device Functionality Overview

Camlytics is software installed on your computer. The camera you want to monitor is linked to the software using the camera’s IP address. You can then setup the different cameras in the Camlytics software to gather the statistics you require. This includes adding triggers to the camera. When anything (car, person, animal, etc.) passes through this trigger, the data will be analysed. The details can then be passed to an external source (in this case our driver) through Webhooks. An API is also available to retrieve details about the locations, cameras and triggers used by Camlytics.

Camlytics

Figure 2 - Camlytics overview

Capability

The following events can be detected by the Camlytics software:

  • Tripwire crossed
  • Tailgating
  • Join region
  • Leave region
  • Motion within region
  • Loitering
  • Crowd on
  • Sabotage

The software can also distinguish between pedestrians and vehicles. This even includes the type of vehicle, gender of pedestrian and age range of pedestrian.

Protocol information

Data is received from Camlytics using the following approaches:

  1. A REST API is used to retrieve data from Camlytics.
  2. Subscribing to webhook events to receive telemetry data from Camlytics.

The REST API retrieves the following information:

  • Locations packet
{
    "code": 0,
    "msg": "Success",
    "result": [
        {
            "id": 6418,
            "hash": "Mo28m8Nscj8tYuy1sgmgMnl7ccLmq2ZQo9l8NlKwPGigndB9S3uy+cNLoeIyHEYYwCA4S6y/CdGxf7g5o8AlDb8sBuMpC9l8F94KPlbbmefGJOvFQhtp1WbnO+DC7RhPxRdrfCNo7ew=",
            "name": "GRDDMOCCTV",
            "version": "3.6.5",
            "timezone_offset": "+02:00"
        },
        {
            "id": 5567,
            "hash": "SwU8JH3ldduwsZoxzamSCHxmuW3mX1APFykKwBdVMM5jDzUbXzePSYJzJ62FpFz8FP9JtOKgyIcsT2DvPt4hKtx3XeFag2pWAig8sidjwTL4rKIKUEodoA4odMWZdiDUiZnZSvDXhPWD5Uwb00a81g==",
            "name": "LAPTOP-WV",
            "version": "3.6.1",
            "timezone_offset": "+02:00"
        }
    ]
}
  • Channels packet
{
    "code": 0,
    "msg": "Success",
    "result": [
        {
            "id": "41490aeb-cda2-4710-9802-1b6c424747c1_0000442C",
            "location_id": 6418,
            "name": "G/House- Ground Floor Main Entrance",
            "active": 1,
            "paid": 0
        },
        {
            "id": "d3a086e1-81bc-4a43-8175-32569dc1b337_0000442C",
            "location_id": 6418,
            "name": "G/Mews- Reception",
            "active": 1,
            "paid": 0
        },
        {
            "id": "1d92704e-8d49-432a-8293-04d5d6bcda81_0000442C",
            "location_id": 5567,
            "name": "Manual device 30",
            "active": 1,
            "paid": 0
        }
    ]
}
  • Triggers packet
{
    "code": 0,
    "msg": "Success",
    "result": [
        {
            "id": "0e7b1f2c-6c41-426f-b92f-0d2e98bbe119_0000442C",
            "location_id": 6418,
            "channel_id": "d3a086e1-81bc-4a43-8175-32569dc1b337_0000442C",
            "name": "Exit",
            "type": "Line",
            "active": 1
        },
        {
            "id": "551a98fb-0b59-407d-8e8a-bd4f7f87f9b5_0000442C",
            "location_id": 6418,
            "channel_id": "d3a086e1-81bc-4a43-8175-32569dc1b337_0000442C",
            "name": "Enter",
            "type": "Line",
            "active": 1
        },
        {
            "id": "d38cd09b-e756-4815-8834-fdb41754e740_0000442C",
            "location_id": 6418,
            "channel_id": "41490aeb-cda2-4710-9802-1b6c424747c1_0000442C",
            "name": "Enter",
            "type": "Line",
            "active": 1
        }
    ]
}

The webhook events we receive has the following structure:

[ 
    {
        "record_id" : 1635343534,
        "event_type" : "TripwireCrossed",
        "snapshot_id" : -235343534,
        "trigger_id" : "0e7b1f2c-6c41-426f-b92f-0d2e98bbe119_0000442C",
        "origin" : "Pedestrian",
        "suborigin" : "Unknown",
        "age_range" : "",
        "gender" : "",
        "id" : 34454545,
        "channel_id" : "41490aeb-cda2-4710-9802-1b6c424747c1_0000442C",
        "object_id" : 6,
        "location_id" : 6418,
        "event_time" : ""
    }, 
    {
        "record_id" : 1635343534,
        "event_type" : "TripwireCrossed",
        "snapshot_id" : -235343534,
        "trigger_id" : "551a98fb-0b59-407d-8e8a-bd4f7f87f9b5_0000442C",
        "origin" : "Pedestrian",
        "suborigin" : "",
        "age_range" : "26 - 35",
        "gender" : "Male",
        "id" : 34454545,
        "channel_id" : "41490aeb-cda2-4710-9802-1b6c424747c1_0000442C",
        "object_id" : 6,
        "location_id" : 6418,
        "event_time" : ""
    }
]

To interact with the REST API you have to generate an API key on your Camlytics profile and add the public and private key to the DeviceOptions.

Integration Plans

Design Specifications

This driver exposes a POST HTTP endpoint, which can be used to configure the Camlytics service, to POST data for events, to the driver. The driver also runs a daily refresh on data for locations, channels and triggers, which have been configured on Camlytics. This data is used to ensure the publish routing key used to push data to Commander, it is user friendly and does not have multiple ids.

Here is a run down of the drivers device configuration.

Device configuration options

{
    "Devices": {
        "Device1": {
            "Enabled": true,
            "DeviceType": "ScheduledReceptorCamlytics",
            "Debug": true,
            "GatewayId": "CAMLYTICS",
            "ActionDelay": "120000",
            "EventTypeFilter": [ "TripwireCrossed" ],
            "EventOriginFilter": [ "Pedestrian" ],
            "RequestLocationEndpoint": "/service/api/v1/locations",
            "RequestChannelEndpoint": "/service/api/v1/channels",
            "RequestTriggerEndpoint": "/service/api/v1/triggers",
            "CamlyticsBaseUrl": "https://cloud.camlytics.com",
            "PublicKey": "PUBLIC KEY HERE",
            "PrivateKey": "PRIVATE KEY HERE",
            "OverrideLocationName": true,
            "LocationNameLookup": {
               "5567": "Testing",
               "6418": "ManhattanStores"
             },
            "OverrideChannelName": true,
            "ChannelNameLookup": {
               "41490aeb-cda2-4710-9802-1b6c424747c1_0000442C": "Lobby"
             },
            "OverrideTriggerName": true,
            "ProcessMaxDegreeOfParallelism": {
               "0e7b1f2c-6c41-426f-b92f-0d2e98bbe119_0000442C": "Enter",
               "551a98fb-0b59-407d-8e8a-bd4f7f87f9b5_0000442C": "Exit"
            },          
            "ProcessMaxDegreeOfParallelism": 1000,
            "BoundedCapacity": 5000,
            "DailyCountResetTime": "22:00:00"
        }
    }
}

Device configuration definitions

PropertyDescriptionTypeDefaults
Device1The device name for this device. This has to be specified.string-
EnabledGets or sets whether this device is enabled.boolfalse????
DeviceTypeGets or sets the type of this device. To use the Camlytics device, this has to be ‘ScheduledReceptorCamlytics’. Otherwise if defining a default device, it must be ‘DefaultProperties’.string-
DebugGets or sets whether debug information is written to console/log file for this specific device.boolfalse???
GatewayIdGets or sets the gateway identifier.stringLeave this blank or null to use to the collector’s service identifier. Default is: CAMLYTICS
ActionDelaySpecifies how frequently, in milliseconds, the device should check if it should reset the event counts and update the data that it retrieves from Camlytics.int-
EventTypeFilterIndicates the types of events the device should filter for.string arrayTripwireCrossed
EventOriginFilterIndicates the types of event origins the device should filter for.string arrayPedestrian
RequestLocationEndpointThe url that is used to get all locations from Camlytics.string/service/api/v1/locations - This value should not normally have to change
RequestChannelEndpointThe url that is used to get all channels from Camlytics.string/service/api/v1/channels - This value should not normally have to change
RequestTriggerEndpointThe url that is used to get all triggers from Camlytics.string/service/api/v1/triggers - This value should not normally have to change
CamlyticsBaseUrlThe url that is used to get all channels from Camlytics.string“https://cloud.camlytics.com” - This value should not normally have to change
PublicKeyPublic API key for the Camlytics API in order to retrieve location/channel/trigger data.stringNone - Request from Camlytics
PrivateKeyPrivate API key for the Camlytics API in order to retrieve location/channel/trigger data.stringNone - Request from Camlytics
OverrideLocationNameFlag indicating if location names should be overridden with pre-defined values.boolfalse
LocationNameLookupA dictionary containing the ids of locations and the names those locations should be overridden with.dictionary with string key and string value-
OverrideChannelNameFlag indicating if channel names should be overridden with pre-defined values.boolfalse
ChannelNameLookupA dictionary containing the ids of channels and the names those channels should be overridden with.dictionary with string key and string value-
OverrideTriggerNameFlag indicating if trigger names should be overridden with pre-defined values.boolfalse
TriggerNameLookupA dictionary containing the ids of triggers and the names those triggers should be overridden with.dictionary with string key and string value-
ProcessMaxDegreeOfParallelismMaximum number of messages that can be processed by the block. Must be >= 0.int500
BoundedCapacityMaximum number of messaged that can be buffered by the block. Must be >= 0.int500
DailyCountResetTimeThe time of day (UTC) that the device should reset its event counters and request new data for locations/channels/triggers from Camlytics.Timespan22:00:00

Usage

Steps on how to deploy and configure the driver

The link below demonstrates the steps to follow when a user deploys and configures a V-Raptor driver:

Deployment Manager Application

Device Configuration Example and Walkthrough

Here is an example config, with a walkthrough below it.

{
  "Devices": {
    "WalkthroughDevice": {
      "Enabled": true,
      "DeviceType": "ScheduledReceptorCamlytics",
      "Debug": true,
      "GroupName": "CAMLYTICS",
      "ActionDelay": 120000,
      "EventTypeFilter": [ "TripwireCrossed" ],
      "EventOriginFilter": [ "Pedestrian" ],
      "PublicKey": "PUBLIC KEY HERE",
      "PrivateKey": "PRIVATE KEY HERE",
      "OverrideLocationName": true,
      "LocationNameLookup": {
        "5567": "Testing",
        "6418": "ManhattanStores"
      },
      "OverrideChannelName": true,
      "ChannelNameLookup": {
        "41490aeb-cda2-4710-9802-1b6c424747c1_0000442C": "Lobby"
      },
      "OverrideTriggerName": true,
      "TriggerNameLookup": {
        "0e7b1f2c-6c41-426f-b92f-0d2e98bbe119_0000442C": "Enter",
        "551a98fb-0b59-407d-8e8a-bd4f7f87f9b5_0000442C": "Exit"
      },
      "DailyCountResetTime": "20:00:00"
    }
  }
}
  • Lets start by creating a new device called ‘WalkthroughDevice’.
  • We want to implement the Camlytics device, so tell it that the device called ‘WalkthroughDevice’ is of type ‘ScheduledReceptorCamlytics’.
  • We want this device to be enabled, so we set ‘enabled’ to true.
  • We set the GroupName to ‘CAMLYTICS’.
  • We set the action delay to 2 minutes.
  • Next we configure the EventTypeFilter. In this case we only want to pass TripwireCrossed events to Commander.
  • We configure the EventOriginFilter. In this case we only want to pass Pedestrian events to Commander.
  • The next part involves specifying the public and private keys used to communicate with Camlytics.
  • We set OverrideLocationName to true, meaning the mapping specified in LocationNameLookup will be applied. The mapping contains the LocationId along with the name we want to use for that location.
  • We set OverrideChannelName to true, meaning the mapping specified in ChannelNameLookup will be applied. The mapping contains the ChannelId along with the name we want to use for that location.
  • We set OverrideTriggerName to true, meaning the mapping specified in TriggerNameLookup will be applied. The mapping contains the TriggerId along with the name we want to use for that location.
  • DailyCountResetTime is set to 20:00 UTC time. This means that the counters will be reset at this time.

Available Commander Endpoints

Standard Gateway Path: LocationName-ChannelName.CAMLYTICS:Origin|TriggerName.EventType-Value

Important note: The LocationName-ChannelName section removed spaces and underscores.

Example: ManhattanStores-Lobby.CAMLYTICS:Pedestrian|Enter.TripwireCrossed-Value

  • Event Category Endpoints

The routing keys for the event category packets sent by Camlytics are constructed as follows:

var gatewayId = $"{locationName}-{channelName}";

deviceInfo.DeviceName = triggerName.Replace(" ", string.Empty).Replace("_", string.Empty);
deviceInfo.DeviceType = eventItem.Origin;
deviceInfo.GatewayId = gatewayId.Replace(" ", string.Empty).Replace("_", string.Empty);
deviceInfo.GroupName = Options.GroupName.Replace(" ", string.Empty).Replace("_", string.Empty);

And the available properties are constructed as follows:

var propToAdd = new List<IDevicePropertyObject>();

propToAdd.Add(CreateProperty<int>(EventType));
propToAdd.Add(CreateProperty<DateTime>("EventTime"));

Meaning these are the 2 properties to be sent:

CountProperty NameData TypeComment
1EventTypeintEventType is the actual EventType, such as TripwireCrossed, while the value is the total count for that event.
2EventTimeDateTimeThe time the event was logged by Camlytics.

External References

Camlytics Website

Release Notes

VersionDescriptionRelease Date
4.0.49.1-alpha-2306081701Initial version of the driver2023-06-09 (QA approval pending)