Repository navigation
platform sdk entity change event reference
Use this reference to choose a supported Platform SDK event when your application must keep its view of entity data current. The reference covers configuration, relationship, availability, and runtime-state changes. Most events do not provide a field name, previous value, or new value. Batched events identify each entity by its globally unique identifier (GUID) and entity type.
The tables separate configuration and relationship changes from runtime state. This reference does not inventory operational Security Center events, such as access granted or alarm triggered.
If you have not selected an event category, start with Detecting entity changes.
Before subscribing, use the Engine to log on to Security Center, register the required entity types, and load the entity data or relationships that your application monitors:
- Use
EntityTypeFilterto register the complete entity type, even when the query includes other filters. This registration enables theEngineto receive notifications about additions and a limited set of common or type-specific updates, but it does not cover every property change or load each entity's properties and relationships. - Use
EntityGuidsin a non-GuidsOnlyquery to load known entities. Alternatively, callEngine.GetEntityto retrieve theEntityobject, and then read each property or relationship that your application plans to monitor. - Retrieve the
Entityobject before subscribing to an instance event, and load a relationship before subscribing to its event.
When GuidsOnly is true, the query does not load entity properties or relationships. GuidsOnly does not register an entity type by itself. If the query also includes EntityTypeFilter, that filter registers its entity types. The Engine can receive EntitiesAdded notifications for a registered type, but type registration does not guarantee EntitiesInvalidated or EntitiesRemoved notifications for every GUID returned by the query.
Use the batched Engine events to track additions, invalidations, and removals in the Engine's entity cache.
| Event | Event argument | What it reports | What to read |
|---|---|---|---|
Engine.EntitiesAdded |
EntitiesAddedEventArgs |
The Engine added an entity to its cache | Use each EntityUpdateInfo.EntityGuid to retrieve the entity if you need its data. |
Engine.EntitiesInvalidated |
EntitiesInvalidatedEventArgs |
An update invalidated cached data for one or more entities | Retrieve each entity and read the properties or relationships that your application uses. |
Engine.EntitiesRemoved |
EntitiesRemovedEventArgs |
The Engine removed one or more entities from its cache | Use the identity in EntityUpdateInfo to remove saved application state. Do not rely on retrieving the removed entity in the handler. |
All three event argument types expose these properties:
| Property | Type | Meaning |
|---|---|---|
Entities |
ReadOnlyCollection<EntityUpdateInfo> |
The entities in the notification. Each item contains only EntityGuid and EntityType. |
IsLocalUpdate |
bool |
Whether the SDK classifies the notification as local to the same Engine instance. |
IsLocalUpdate applies to the entire batch. It is not a property of EntityUpdateInfo. The Entities collection can contain the same entity more than once. Group items by EntityGuid when your application requires one refresh per entity.
EntitiesInvalidated does not identify which data changed. Treat it as a refresh signal and compare the current data with the values your application saved.
EntitiesAdded has two common meanings: the Engine loaded an existing entity for the first time, or it received a newly created entity after registering that entity type. The event does not distinguish between these cases.
EntitiesRemoved can follow deletion from Security Center or an SDK rollback of a local creation that did not succeed. It is not raised merely because disconnection clears the Engine cache. Neither EntitiesAdded nor EntitiesRemoved is an audit record. A type-filtered GuidsOnly query can receive EntitiesAdded, but it does not guarantee invalidation or removal notifications for every returned GUID.
When IsLocalUpdate is true, the same Engine instance initiated the operation and the SDK reports the notification as local. When it is false, the SDK does not report the notification as local to that Engine instance. A value of false can represent an update received from Security Center, an SDK rollback notification, or a local update reported as remote because IEngine.ViewLocalUpdatesAsRemote is true. The value does not identify the person or component that initiated the operation.
These instance events are declared by Entity and inherited by its subclasses. Retrieve the entity from the Engine before subscribing.
| Event | Event argument and payload | What it reports | What to read |
|---|---|---|---|
Entity.FieldsChanged |
FieldsChangedEventArgs, with IsLocalUpdate
|
Common built-in properties and some type-specific configuration properties | Read the properties that your application uses. The argument does not identify the changed property. |
Entity.CustomFieldsChanged |
EventArgs, with no payload |
Custom field values assigned to the entity | Call GetCustomFields or GetCustomFieldsAsync and compare the current values with your saved values. |
FieldsChanged and EntitiesInvalidated are not equivalent. A supported configuration-field update can raise both. A change that affects only a relationship, custom field value, or runtime status can include the entity in EntitiesInvalidated and raise another event without raising FieldsChanged.
Cardholder.MemberOfChanged is the only static event in this table. It is shared by all loaded cardholders and visitors and does not identify the affected entity. For every instance event, the sender is the entity that changed.
| Event | Event argument and payload | What it reports | What to read |
|---|---|---|---|
AccessPoint.AccessRulesChanged |
AccessRulesChangedEventArg, with IsLocalUpdate
|
Access rules associated with the access point | AccessRules |
Alarm.RecipientsChanged |
RecipientsChangedEventArgs, with IsLocalUpdate
|
Alarm recipients | Recipients |
Cardholder.CredentialChanged |
CredentialsChangedEventArg, with IsLocalUpdate
|
Credentials associated with the cardholder or visitor | Credentials |
Cardholder.MemberOfChanged, static |
EventArgs, with no entity identity or locality |
Parent-group membership for a cardholder or visitor | Use Engine.EntitiesInvalidated to identify the entity, and then read Parents. |
CardholderGroup.MembersChanged |
MembersChangedEventArgs, with IsLocalUpdate
|
Direct members of the cardholder group | Children |
SystemConfiguration.CustomEventsChanged |
EventArgs, with no payload |
Custom event definitions | CustomEventService.CustomEvents |
SystemConfiguration.CustomFieldsChanged |
EventArgs, with no payload |
Custom field definitions | CustomFieldService.CustomFields |
SystemConfiguration.CustomFieldTypesChanged |
EventArgs, with no payload |
A system configuration refresh notification that is not specific to custom field types | CustomFieldService.CustomFieldTypes |
UserGroup.MembersChanged |
MembersChangedEventArgs, with IsLocalUpdate
|
Direct child users and user groups of the user group | Children |
Visitor inherits Cardholder.CredentialChanged, so use the same event and reread pattern for visitor credentials.
AccessRulesChangedEventArg, CredentialsChangedEventArg, MembersChangedEventArgs, and RecipientsChangedEventArgs expose only IsLocalUpdate. They do not identify which relationship item was added or removed.
Cardholder.MemberOfChanged is a static event shared by all loaded cardholders and visitors. Its sender is null, and its declared handler type is EventHandler. The handler therefore receives only EventArgs, without the entity GUID or IsLocalUpdate.
When you need to identify the changed cardholder or visitor, handle Engine.EntitiesInvalidated and read Parents on the affected entity. When you monitor a known group instead, use CardholderGroup.MembersChanged and read its Children collection.
SystemConfiguration declares a CustomFieldsChanged event with the same name as the event inherited from Entity. The events report different data:
-
systemConfiguration.CustomFieldsChangedreports changes to custom field definitions. ReadsystemConfiguration.CustomFieldService.CustomFields. -
Entity.CustomFieldsChangedreports custom field value changes on entity types that support custom fields, and is also raised when a custom field definition is added for the entity's type.
A variable declared as SystemConfiguration uses the definition event. Neither event provides IsLocalUpdate.
SystemConfiguration.CustomFieldTypesChanged can be raised when another system configuration property changes. The event does not prove that a custom field type changed. Before acting on the notification, read CustomFieldService.CustomFieldTypes and compare the result with your saved definitions.
The events in this section are raised from entity runtime-state updates. They do not provide IsLocalUpdate.
Subscribe to IsOnlineChanged only for the entity types listed here. Do not assume that an entity raises this event merely because it exposes IsOnline and RunningState. The event argument does not contain the new state, so read both properties from the sender.
| Entity type | Event | Event argument | What to read |
|---|---|---|---|
Area, Door, and Zone
|
IsOnlineChanged |
EventArgs |
IsOnline and RunningState
|
Camera |
IsOnlineChanged |
EventArgs |
IsOnline and RunningState
|
LprUnit |
IsOnlineChanged |
IsOnlineChangedEventArgs, with no properties |
IsOnline and RunningState
|
Role |
IsOnlineChanged |
EventArgs |
IsOnline and RunningState
|
Unit |
IsOnlineChanged |
IsOnlineChangedEventArgs, with no properties |
IsOnline and RunningState
|
VideoUnit |
IsOnlineChanged |
IsOnlineChangedEventArgs, with no properties |
IsOnline and RunningState
|
Other entity types can expose IsOnline and RunningState without raising IsOnlineChanged when their online state changes.
Area, Door, and Zone inherit AccessPointGroup.IsOnlineChanged. Although Elevator also inherits the event, elevator online-state changes do not raise it. Handle Engine.EntitiesInvalidated and reread the elevator state instead.
Alarm.IsActiveChanged is raised when the Engine changes the active state that it tracks for a loaded Alarm. IsActiveChangedEventArgs has no properties. The sender is the affected Alarm; read Alarm.IsActive to determine whether the Engine currently tracks at least one active instance.
Door offers a static event for each matching door-state notification received by the Engine and an instance event on the affected Door for each supported input or lock state. Both forms use DoorIOStateChangeEventArgs, which contains the affected Door entity's GUID in Door and the reported state in IsActive.
| State | Static event | Instance event | Meaning of IsActive
|
|---|---|---|---|
| Door sensor | Door.DoorSensorStateChanged |
Door.SensorStateChanged |
true means open. false means closed. |
| Pull station | Door.DoorPullStationStateChanged |
Door.PullStationStateChanged |
true means activated. false means normal. |
| Request to exit (REX) | Door.DoorRexStateChanged |
Door.RexStateChanged |
true means active. false means inactive. |
| Door lock | Door.DoorLockStateChanged |
Door.LockStateChanged |
The two events use opposite values. See the explanation after the table. |
The static events use the Engine as sender. The instance events use the affected Door as sender. Retrieve a Door before subscribing to its instance events. Subscribing to a static event does not load any Door entity. When the Engine receives a matching notification, it raises the static event first, retrieves the affected Door, and then raises the instance event if the retrieval succeeds.
The two lock events interpret IsActive differently for the same transition:
- For
Door.DoorLockStateChanged,truemeans locked andfalsemeans unlocked. - For
Door.LockStateChanged,truemeans unlocked andfalsemeans locked.
These events report the Door entity's effective lock state. They do not report the state of an optional lock-sensor input or explain what caused the Door entity to lock or unlock.
Use DoorIOStateChangeEventArgs.IsActive for the reported transition. Do not assume that Door.IsOpen, Door.IsLocked, or another cached state property has already been refreshed when the handler runs. If your application needs the complete state of the Door entity, defer or coalesce the refresh, and then reread and compare the properties that it uses.
The default event filter for an Engine created by the application includes these event types. If the application replaces that filter by calling Engine.SetEventFilter, include both event types for every state it monitors:
| State | Event types to include |
|---|---|
| Door sensor |
EventType.DoorOpen and EventType.DoorClose
|
| Pull station |
EventType.DoorPullStationActivated and EventType.DoorPullStationNormal
|
| Request to exit (REX) |
EventType.DoorRexOn and EventType.DoorRexOff
|
| Door lock |
EventType.DoorLock and EventType.DoorUnlock
|
InputDevice and OutputDevice each expose a static event for all loaded devices of that type and an instance event for one device. IntrusionArea exposes static and instance events for arming-state and input-bypass changes.
| Event | Event argument and payload | What to read |
|---|---|---|
InputDevice.InputDeviceStateChanged, static |
InputStateChangeArgs, with DeviceGuid (Guid) and State (InputState) |
Use the payload, or retrieve the input device and read State. |
InputDevice.StateChanged |
InputStateChangeArgs, with DeviceGuid (Guid) and State (InputState) |
Use the payload or read the sender's State. |
IntrusionArea.IntrusionAreaStateChanged, static |
IntrusionAreaStateChangedEventArgs, with IntrusionAreaGuid (Guid), State (ArmingState), and Input (Guid) |
Use State for the reported transition. |
IntrusionArea.StateChanged |
IntrusionAreaStateChangedEventArgs, with IntrusionAreaGuid (Guid), State (ArmingState), and Input (Guid) |
Use State for the reported transition. Read the sender's ArmedState when your application needs the current cached state. |
IntrusionArea.IntrusionAreaBypassChanged, static |
IntrusionAreaBypassChangedEventArgs, with IntrusionAreaGuid (Guid) and InputBypassed (bool) |
Use InputBypassed for the reported change. |
IntrusionArea.BypassChanged |
IntrusionAreaBypassChangedEventArgs, with IntrusionAreaGuid (Guid) and InputBypassed (bool) |
Use InputBypassed for the reported change. Read the sender's IsInputBypassed when your application needs the current cached state. |
OutputDevice.OutputDeviceStateChanged, static |
OutputStateChangedEventArgs, with DeviceGuid (Guid) and State (OutputState) |
Use the payload, or retrieve the output device and read State. |
OutputDevice.StateChanged |
OutputStateChangedEventArgs, with DeviceGuid (Guid) and State (OutputState) |
Use the payload or read the sender's State. |
The static device and intrusion-area events use the Engine as the sender. The instance events use the affected entity as the sender.
When an entity-cache refresh changes a cached intrusion area's arming state, it raises IntrusionArea.StateChanged with Input set to Guid.Empty. It does not raise the static IntrusionArea.IntrusionAreaStateChanged event.
When the Engine receives a matching operational event, it raises the static event first, retrieves the affected IntrusionArea, and then raises the instance event if the retrieval succeeds. For an operational state transition, Input can identify the related input. For a bypass notification, InputBypassed is true when the bypass becomes active and false when it becomes inactive.
The relationships in this table do not have a supported entity-specific event. Handle Engine.EntitiesInvalidated, match the required EntityType and EntityGuid, and reread the relationship.
| Relationship | Entity to match | What to read |
|---|---|---|
| Access rule cardholders and cardholder groups | AccessRule |
Cardholders |
| Elevator floors | Elevator |
Floors |
| Map objects | Map |
MapObjects |
| Partition members and user access | Partition |
Members and UserAccesses
|
Do not use Entity.FieldsChanged as the fallback for these relationships. The SDK does not guarantee that a relationship-only update raises Entity.FieldsChanged.
- About the Engine entity cache: How the Engine loads entity data and refreshes cached objects.
- About custom fields: How to read custom field definitions and entity values.
- Working with Security Center events: How to monitor Security Center operations and occurrences.
- Overview
- Connecting to Security Center
- SDK certificates
- Referencing SDK assemblies
- ASP.NET hosting
- SDK compatibility
- Migrating to modern .NET
- Entities
- Entity cache
- Entity loading, cache, and query options
- Detecting entity changes
- Entity change event reference
- Transactions
- Security Center events
- Actions
- Security Desk
- Custom events
- Event-to-actions
- Managing macros
- ReportManager
- ReportManager query reference
- Access control raw events
- DownloadAllRelatedData and StrictResults
- Privileges
- Partitions
- Entity write restrictions
- About custom fields
- About video
- About cameras
- Enrolling a video unit
- Ingesting third-party video
- Archiver and auxiliary archiver roles
- Archive transfer
- About access control
- About cardholders and credentials
- About doors, areas, elevators, and access points
- About access rules and schedules
- About access control units and interface modules
- Enrolling an access control unit
- Door templates
- Visitors
- Mobile credentials
- About threat levels
- About alarms
- About incidents
- Maps
- Logging
- Overview
- Localization
- Certificates
- Lifecycle
- Threading
- State management
- Configuration
- Restricted configuration
- Events
- Queries
- Request manager
- Database
- Entity ownership
- Engine extensions
- Entity mappings
- Server management
- Custom privileges
- Custom entity types
- Resolving non-SDK assemblies
- Deploying plugins
- Modern .NET support
- Overview
- Localization
- Certificates
- Creating modules
- Tasks
- Pages
- Components
- Tile extensions
- Services
- Contextual actions
- Custom actions
- Options extensions
- Configuration pages
- Monitors
- Shared components
- Commands
- Extending events
- Map extensions
- Timeline providers
- Image extractors
- Credential encoders
- Credential readers
- Cardholder fields extractors
- Badge printers
- Content builders
- Dashboard widgets
- Incidents
- Logon providers
- Pinnable content builders
- Custom report pages
- Overview
- Getting started
- Media file formats
- MediaPlayer
- VideoSourceFilter
- MediaExporter
- MediaFile
- G64 converters
- FileCryptingManager
- PlaybackSequenceQuerier
- PlaybackStreamReader
- OverlayFactory
- PtzCoordinatesManager
- AudioTransmitter
- AudioRecorder
- AnalogMonitorController
- Camera blocking
- Overview
- Getting started
- Referencing entities
- Entity operations
- About access control in the Web SDK
- About video in the Web SDK
- Users and user groups
- Partitions
- Custom fields
- Custom card formats
- Actions
- Events and alarms
- Incidents
- Reports
- Tasks
- Macros
- Custom entity types
- System endpoints
- Performance guide
- Reference
- Endpoints
- Constants
- Enumerations
- Under the hood
- Troubleshooting