AccessSynchronization¶
Overview¶
Access control data synchronization between PQ Server and device (credential upload/download, access level sync, offline database management). The adapter implements synchronization logic based on device capabilities.
- Added in: PQ Framework 2.0
- Namespace:
Pq.Adapters.Framework
When to Use¶
- Access control panels with offline credential storage
- Smart locks with local user databases
- Door controllers with cached credentials
- Biometric readers with template storage
- Any device requiring credential synchronization
States¶
Synchronization Lifecycle¶
| State | Description | Status String |
|---|---|---|
Idle |
No synchronization in progress | pq.state.access.sync.idle |
Active |
Synchronization operation in progress | pq.state.access.sync.active |
Failed |
Synchronization failed, error condition | pq.state.access.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:
SyncStarted(timestamp) (adapter-defined)
- Transition to
Activestate - Begin credential upload/download operation
SyncCompleted(timestamp, credentialCount) (adapter-defined)
- Transition to
Idlestate - Log synchronization success with statistics
SyncFailed(timestamp, errorMessage) (adapter-defined)
- Transition to
Failedstate - Log synchronization failure with error details
Properties¶
None. All synchronization configuration is adapter-specific. Define properties in adapter-registration.yaml if needed (e.g., sync_mode, batch_size, retry_policy).
YAML Example¶
device_types:
- type_id: AccessControlPanel
name: "Access Control Panel"
functions:
AccessSynchronization:
ConnectionBase:
properties:
sync_mode:
type: "string"
default: "auto"
description: "Synchronization mode: auto, manual, scheduled"
batch_size:
type: "int"
default: 100
range: [1, 1000]
description: "Credentials per batch operation"
offline_capacity:
type: "int"
default: 10000
description: "Maximum offline credentials supported"
- type_id: SmartLock
name: "Smart Door Lock"
functions:
AccessSynchronization:
Door:
properties:
sync_interval_hours:
type: "int"
default: 24
description: "Hours between automatic synchronization"
Code Usage¶
public class AccessPanelThing : Thing
{
public AccessSynchronizationFunction Sync { get; }
protected override async Task OnSyncRequested(CancellationToken ct)
{
// transition to active state
await Sync.TransitionToAsync("access.sync.active", ct);
try
{
// adapter-specific sync logic
var credentials = await GetPendingCredentials(ct);
await UploadToDevice(credentials, ct);
// transition to idle on success
await Sync.TransitionToAsync("access.sync.idle", ct);
Logger.LogInformation("Synchronized {Count} credentials", credentials.Count);
}
catch (Exception ex)
{
// transition to failed on error
await Sync.TransitionToAsync("access.sync.failed", ct);
Logger.LogError(ex, "Synchronization failed");
}
}
private async Task<List<Credential>> GetPendingCredentials(CancellationToken ct)
{
// fetch from PQ Server API
return await ApiClient.GetCredentialsAsync(DeviceId, ct);
}
private async Task UploadToDevice(List<Credential> credentials, CancellationToken ct)
{
// adapter-specific device communication
foreach (var batch in credentials.Chunk(BatchSize))
{
await DeviceClient.UploadCredentialsAsync(batch, ct);
}
}
}
Extended Construction¶
AccessSynchronization uses extended construction (extended_construction: true). The framework provides:
public class AccessSynchronizationFunction : FunctionBase
{
// framework provides constructor with Thing reference
public AccessSynchronizationFunction(Thing thing)
: base(thing)
{
}
// adapter implements synchronization logic
public async Task SyncCredentials(List<Credential> credentials, CancellationToken ct)
{
await TransitionToAsync("access.sync.active", ct);
// sync implementation
}
}
Synchronization Patterns¶
Full Sync (Initial/Manual)¶
- Device reports firmware version, capacity, current count
- Server compares hashes, determines delta
- Upload new/changed credentials
- Remove deleted credentials
- Verify integrity
Incremental Sync (Automatic)¶
- Device polls for changes since last sync
- Server returns delta (adds/updates/deletes)
- Device applies changes
- Device confirms completion
Person Profiles¶
Access synchronization can include adapter-specific per-person settings declared in
access-model.yaml under person_profiles. Use this for panel user flags such as
user level, menu type, dual-code mode, or group-selection permission.
When person_profiles is declared, the generated synchronization base calls:
Generated AccessModel.PersonAccess contains typed profile properties, for example
person.UserProfile. Adapter code should read those properties directly. The
generated mapper applies YAML defaults and validates required profile fields before
Transform() runs.
Event-Driven Sync (Real-Time)¶
- Server publishes credential change event
- Adapter receives event, filters by device
- Adapter pushes change to device immediately
- Device acknowledges change
Notes¶
- No Predefined Actions: Adapters define custom actions based on device protocol
- State Tracking: Framework tracks sync state, adapter handles transitions
- Error Recovery: Adapter implements retry logic, partial sync, rollback
- Capacity Management: Check device capacity before sync operations
- Conflict Resolution: Server is authoritative, device reflects server state
- Performance: Use batch operations, parallel upload when supported
See Also¶
- Functions: AntipassbackSynchronization - Antipassback zone configuration sync
- Functions: TimeSynchronization - Clock synchronization
- Functions: Door - Access control door
- Functions: Reader - Credential reader