Skip to content

AntipassbackSynchronization

Overview

Antipassback zone configuration synchronization between PQ Server and device. Antipassback rules govern the order in which a credential may pass through access points (for example, a credential must exit a zone before it can re-enter). This function keeps the device's local zone/antipassback configuration aligned with the server. The adapter implements the synchronization logic based on device capabilities.

  • Added in: PQ Framework 2.0
  • Namespace: Pq.Adapters.Framework

When to Use

  • Access controllers that enforce antipassback or zone-occupancy rules locally
  • Panels with configurable in/out zone topology
  • Devices that track entry/exit order per credential
  • Any device requiring zone definitions to be pushed and kept current

If a device has no concept of zones or directional control, this function is not needed.

States

Synchronization Lifecycle

State Description Status String
Idle No synchronization in progress pq.state.antipassback.sync.idle
Active Synchronization operation in progress pq.state.antipassback.sync.active
Failed Synchronization failed, error condition pq.state.antipassback.sync.failed

Actions

No predefined actions. The adapter implements synchronization logic using:

  • Custom actions for sync events
  • State transitions via base class methods
  • Command handlers for sync requests

Common Adapter-Defined Actions

Adapters typically implement these patterns:

ZoneSyncStarted(timestamp) (adapter-defined)

  • Transition to Active state
  • Begin uploading zone/antipassback configuration

ZoneSyncCompleted(timestamp, zoneCount) (adapter-defined)

  • Transition to Idle state
  • Log synchronization success with statistics

ZoneSyncFailed(timestamp, errorMessage) (adapter-defined)

  • Transition to Failed state
  • Log synchronization failure with error details

Properties

None. All antipassback configuration is adapter-specific. Define properties in adapter-registration.yaml if needed (e.g., zone_reset_schedule, hard_apb_enabled, occupancy_limit).

YAML Example

device_types:
  - type_id: AccessControlPanel
    name: "Access Control Panel"
    functions:
      AntipassbackSynchronization:
      AccessSynchronization:
      ConnectionBase:
    properties:
      hard_apb_enabled:
        type: "bool"
        default: true
        description: "Hard antipassback (deny) vs soft (log only)"
      zone_reset_schedule:
        type: "string"
        default: "daily"
        description: "When zone occupancy is reset: never, daily, scheduled"
      max_zones:
        type: "int"
        default: 16
        range: [1, 256]
        description: "Maximum zones supported by the device"

Code Usage

public class AccessPanelThing : Thing
{
    public AntipassbackSynchronizationFunction ApbSync { get; }

    protected override async Task OnZoneSyncRequested(CancellationToken ct)
    {
        // transition to active state
        await ApbSync.TransitionToAsync("antipassback.sync.active", ct);

        try
        {
            // adapter-specific zone configuration logic
            var zones = await GetZoneConfiguration(ct);
            await UploadZonesToDevice(zones, ct);

            // transition to idle on success
            await ApbSync.TransitionToAsync("antipassback.sync.idle", ct);

            Logger.LogInformation("Synchronized {Count} antipassback zones", zones.Count);
        }
        catch (Exception ex)
        {
            // transition to failed on error
            await ApbSync.TransitionToAsync("antipassback.sync.failed", ct);

            Logger.LogError(ex, "Antipassback synchronization failed");
        }
    }

    private async Task<List<ZoneDefinition>> GetZoneConfiguration(CancellationToken ct)
    {
        // fetch from PQ Server API
        return await ApiClient.GetZonesAsync(DeviceId, ct);
    }

    private async Task UploadZonesToDevice(List<ZoneDefinition> zones, CancellationToken ct)
    {
        // adapter-specific device communication
        foreach (var zone in zones)
        {
            await DeviceClient.WriteZoneAsync(zone, ct);
        }
    }
}

Extended Construction

AntipassbackSynchronization uses extended construction (extended_construction: true). The framework provides the constructor with the Thing reference and tracks the sync state; the adapter implements the zone configuration logic and drives the state transitions.

Notes

  • No Predefined Actions: Adapters define custom actions based on device protocol
  • State Tracking: Framework tracks sync state, adapter handles transitions
  • Server Is Authoritative: Device zone configuration reflects server-side topology
  • Pairs With Access Sync: Antipassback zones reference the same access points managed by AccessSynchronization; synchronize both consistently
  • Occupancy Reset: Decide whether occupancy counters reset on schedule, on sync, or never, and document the behavior in the adapter's design-notes

See Also

  • Functions: AccessSynchronization - Credential and access-level synchronization
  • Functions: Reader - Credential reader (raises antipassback denial events)
  • Functions: Door - Access control door