Skip to content

platform sdk events

Andre Lafleur edited this page Oct 8, 2026 · 12 revisions

Working with Security Center events

The Security Center SDK allows applications to subscribe to events from entities in the system and raise events programmatically. Events notify your application when something happens, such as a door opening, a camera going offline, or a custom event being raised.

Note

Events are notifications that something happened. For commands directed at entities your application owns (a request to unlock a door, arm a zone), see Receiving actions. To send commands to entities from your application, use the methods on Engine.ActionManager.

This page covers operational events delivered through Engine.EventReceived, such as access granted, door state, video, and alarm events. To detect changes to entity properties, custom fields, relationships, or entity lifecycle, see Detecting entity changes.

Event subscription

Subscribe to events using Engine.EventReceived:

engine.EventReceived += OnEventReceived;

private void OnEventReceived(object sender, EventReceivedEventArgs e)
{
    Console.WriteLine($"Event received: {e.EventType} from {e.SourceGuid}");
}

Filtering event types

By default, the Engine receives every event type for entities in its cache. For an Engine that your application instantiated, use SetEventFilter to replace the current filter with the event types your application must receive:

engine.SetEventFilter(new[] { EventType.DoorOpen, EventType.DoorClose, EventType.AccessGranted });

Use AddToEventFilter to add event types to an existing restricted filter. It does not restrict the default all-events filter. Call ClearEventFilter to restore all event types:

engine.ClearEventFilter();

In a Workspace SDK extension, SetEventFilter adds the requested event types without replacing filters used by other extensions. In a plugin, SetEventFilter replaces the current filter.

Event argument types

The EventReceivedEventArgs base class can be cast to specialized types that provide event-specific properties. Common examples:

Type Description
LicensePlateReadEventArgs License plate recognition (LPR) reads with a Plate property
LicensePlateHitEventArgs LPR hotlist hits
VideoAnalyticsEventArgs Video analytics events
AccessRequestedEventArgs Access requests requiring confirmation
AlarmTriggeredRoutableEventArgs Alarm events with alarm details

Specialized event argument types also cover parking, pan-tilt-zoom, health monitoring, and other subsystems. Use pattern matching to check the actual type:

private void OnEventReceived(object sender, EventReceivedEventArgs e)
{
    if (e is LicensePlateReadEventArgs lprEvent)
    {
        Console.WriteLine($"Plate read: {lprEvent.Plate.Value}");
    }
    else if (e is VideoAnalyticsEventArgs analyticsEvent)
    {
        Console.WriteLine($"Analytics event from: {analyticsEvent.SourceGuid}");
    }
}

LicensePlateReadEventArgs also exposes the read's annotation values as string properties: ConfidenceScore, StateName, VehicleType, VehicleMake, VehicleSpeed, RelativeMotion, CharactersHeight, and Context. Each property reads a specific annotation field: StateName from "State Name", VehicleType from "Vehicle Type", VehicleMake from "Vehicle Make", RelativeMotion from "Relative Motion", CharactersHeight from "Characters Height", ConfidenceScore from "Confidence Score", Context from "Context", and VehicleSpeed from "Speed". The values are present when the ALPR unit supplies the annotation; the matching is not case sensitive. Annotation fields are configured in the ALPR settings of Security Center.

For a custom annotation field, cast e.Event to LprReadEvent and call GetAttributeValue(name), passing the annotation field name; the lookup is not case sensitive and returns null when the field is absent. AttributesXml holds the same data as an XML document, with an Attributes root element whose Attribute child elements carry the field name in a name attribute and the value as element text, if you need to enumerate every field.

EventReceivedEventArgs properties

All event args expose common properties:

Property Type Description
EventType EventType The type identifier for the event
SourceGuid Guid The entity GUID that generated the event
Timestamp DateTime When the event occurred (UTC)
GroupId Guid Context identifier for grouping related events
Event Event The underlying event object. For event types without a specialized event class, this is a generic Event instance rather than null.

Event properties

When EventReceivedEventArgs.Event is not null, it provides additional properties:

Property Type Description
Type EventType The event type
SourceEntity Guid The source entity GUID
GroupId Guid Shared by events that represent the same occurrence so Security Desk shows them as a single entry
Timestamp DateTime Event timestamp
Coordinates GeoCoordinate Geographic coordinates (if applicable)
RelatedEntities IEnumerable<Guid> Related entity GUIDs
OfflinePeriod OfflinePeriodType Indicates if the event occurred during an offline period

The Event property returns the base Event class. Cast it to a specialized class to access event-specific properties:

private void OnEventReceived(object sender, EventReceivedEventArgs e)
{
    if (e.Event is AccessEvent accessEvent)
    {
        Console.WriteLine($"Cardholder: {accessEvent.Cardholder}");
        Console.WriteLine($"Access point: {accessEvent.AccessPoint}");
    }
    else if (e.Event is AlarmEvent alarmEvent)
    {
        Console.WriteLine($"Alarm state: {alarmEvent.AlarmState}");
        Console.WriteLine($"Priority: {alarmEvent.Priority}");
    }
}
Event class Description
AccessEvent Access control events with Cardholder, Credentials, AccessPoint
AlarmEvent Alarm events with AlarmState, Priority, TriggerEntity
CameraEvent Camera events with VideoEncoderDevice
CustomEventInstance Custom events with Id, Message

About the source entity

The SourceGuid (on EventReceivedEventArgs) or SourceEntity (on the Event object) identifies the entity that generated the event. This is the primary entity the event is about.

Source entity examples include:

  • An AccessGranted event can use an area, door, or elevator as its source entity.
  • A CameraMotionOn event uses a camera as its source entity.
  • A UnitDisconnected event can use an access control, intrusion, license plate recognition, or video unit as its source entity.

An event can have multiple related entities stored in the RelatedEntities collection. The SourceEntity property returns the first entity in this collection. When processing events, use SourceGuid or SourceEntity to identify which entity triggered the event.

Group related events with GroupId

The GroupId property enables event de-duplication in the Monitoring task. When multiple events share the same non-empty GroupId, Security Desk displays them as a single entry while still triggering event-to-actions for each individual event.

Use GroupId when multiple components report the same occurrence. For example, if an access control unit and the Access Manager role both report the same access event, assign the same GroupId to both events. Security Desk then displays one entry in the Monitoring task instead of duplicates.

When raising events from multiple sources that represent the same logical occurrence, assign the same GroupId to consolidate their display:

var correlationId = Guid.NewGuid();

var event1 = engine.ActionManager.BuildEvent(EventType.DoorRexOn, door1Guid);
event1.GroupId = correlationId;

var event2 = engine.ActionManager.BuildEvent(EventType.DoorRexOn, door2Guid);
event2.GroupId = correlationId;

engine.ActionManager.RaiseEvent(event1);
engine.ActionManager.RaiseEvent(event2);

Both events trigger their configured actions, but the Monitoring task displays only one entry.

Classify delayed events with OfflinePeriodType

The OfflinePeriod property indicates when an event occurred relative to unit connectivity. This applies to events from devices that can store events locally while disconnected from Security Center, such as access control units.

When a unit reconnects after being offline, it uploads stored events to Security Center. The system assigns an OfflinePeriodType based on how old each event is:

Value Default threshold Event-to-actions behavior
None Not applicable (online) All actions execute normally
GracePeriod 15 minutes All actions execute normally
OfflineAlarmPeriod 3 days Only alarm-related actions execute
Offline Beyond 3 days Event is logged only, no actions execute
private void OnEventReceived(object sender, EventReceivedEventArgs e)
{
    if (e.Event.OfflinePeriod == OfflinePeriodType.Offline)
    {
        // This event occurred while the unit was offline for an extended period
        // No event-to-actions were triggered for this event
    }
}

Loading entities to receive events

You only receive events for entities loaded in the engine's entity cache.

Load a specific entity by GUID:

engine.GetEntity(doorGuid);

Load all entities of a type by running a query. The query searches the Directory database and loads matching entities into the cache:

var query = (EntityConfigurationQuery)engine.ReportManager.CreateReportQuery(ReportType.EntityConfiguration);
query.EntityTypeFilter.Add(EntityType.Door);
query.Query();

See About the ReportManager for more query options.

See About the Engine entity cache for pagination and efficient entity loading.

Raising events

Use ActionManager.BuildEvent to create an event and ActionManager.RaiseEvent to send it to Security Center:

Event eventInstance = engine.ActionManager.BuildEvent(EventType.DoorRexOn, doorGuid);
engine.ActionManager.RaiseEvent(eventInstance);

The BuildEvent method creates an event instance for the specified event type and source entity. Some event types return specialized classes with additional properties that you can set before raising the event. If the SDK cannot create an event instance for the specified EventType, BuildEvent throws an SdkException.

Each entity has a SupportedEvents property that lists the event types it produces:

var door = engine.GetEntity(doorGuid);
foreach (var eventType in door.SupportedEvents)
{
    Console.WriteLine($"Supported: {eventType}");
}

SupportedEvents lists the event types that an entity can produce, not the event types that your application can raise. The application type determines which event types your application can raise, as described below.

You can set Timestamp to a past time and OfflinePeriod to indicate the event occurred while offline:

var eventInstance = engine.ActionManager.BuildEvent(EventType.DoorRexOn, doorGuid);
eventInstance.Timestamp = DateTime.UtcNow.AddHours(-2);
eventInstance.OfflinePeriod = OfflinePeriodType.GracePeriod;
engine.ActionManager.RaiseEvent(eventInstance);

Not all event types can be raised programmatically. Security Center restricts which events each application type can raise:

Application type Can raise
SDK application Custom events on any entity, plus specific event types like camera bookmarks and video analytics
Plugin Events on entities the plugin owns, such as door events on doors managed by an access control plugin

Calling RaiseEvent with an event type that the current application is not allowed to raise throws an SdkException. Many event types are system-generated only and cannot be raised by any application, such as AlarmTriggered and UserLoggedOn.

Events raised through RaiseEvent are sent to other connected applications that have the source entity loaded, but not to the application that raised them. RaiseEvent does not guarantee persistence. When the SDK provides an entity-specific method for the operation, use that method instead of constructing the corresponding event manually.

See Raising custom events for the event type that all SDK applications can raise on any entity.

Event transactions

When raising multiple events, use an event transaction to batch them together. This sends all events to Security Center in a single request, improving performance.

Create an event transaction, add the prebuilt events, and then commit the transaction:

bool RaiseEvents(Engine engine, IEnumerable<Event> events)
{
    EventTransaction transaction = engine.TransactionManager.CreateEventTransaction();

    foreach (Event eventInstance in events)
    {
        transaction.AddEvent(eventInstance);
    }

    return transaction.CommitTransaction();
}

Disposing an EventTransaction also commits it, so you can use a using statement when you do not need the commit result.

You can run multiple event transactions in parallel since each transaction maintains its own context.

Unsubscribing from events

Remove event handlers when they are no longer needed:

engine.EventReceived -= OnEventReceived;

See also

Platform SDK

Plugin SDK

Workspace SDK

Media SDK

Macro SDK

Web SDK

Synergis RIO

Media Gateway

Genetec Web Player

Clone this wiki locally