Skip to content

MQTT / WAN Protocol Reference

DFACS communicates with the DFACSWAN cloud portal via MQTT over TLS. Each device subscribes and publishes to topics namespaced by its DEVICE_ID.

Broker: portal.dragonflyacs.ai:8883 (TLS)
Topic prefix: dfacs/{DEVICE_ID}/ or dfacswan/instance/{DEVICE_ID}/


Connection Behaviour

  • Auto-reconnects on disconnect with exponential backoff: starts at 5s, caps at 300s
  • Heartbeat published every 30 seconds
  • 5 missed heartbeat ACKs triggers a WAN settings revert to defaults
  • Firebase config loaded in memory only — never persisted to disk

Topics — Device Subscribes (Portal → Device)

Commands

Topic Description
dfacs/{DEVICE_ID}/command Portal-issued commands (see Commands section)
dfacs/{DEVICE_ID}/config/update Remote config push
dfacs/register/response/{DEVICE_ID} Registration acknowledgment
dfacs/{DEVICE_ID}/heartbeat/ack Heartbeat acknowledgment

User Sync

Topic Description
dfacswan/instance/{DEVICE_ID}/users/update Add or modify a single user
dfacswan/instance/{DEVICE_ID}/users/revoke Deactivate a user
dfacswan/instance/{DEVICE_ID}/users/sync Full user list replacement

Schedule Sync

Topic Description
dfacswan/instance/{DEVICE_ID}/schedules/push Door and holiday schedule push
dfacswan/instance/{DEVICE_ID}/schedules/sync/ack ACK/NACK for schedule push

Alcatraz

Topic Description
dfacs/{DEVICE_ID}/alcatraz/profile/deleted Profile removal notification
dfacs/{DEVICE_ID}/alcatraz/credential/deleted Card/badge deletion
dfacs/{DEVICE_ID}/alcatraz/credential/added Card/badge addition
dfacs/{DEVICE_ID}/alcatraz/profiles/synced Trigger local profile re-sync
dfacs/{DEVICE_ID}/alcatraz/enrollment/lookup Enrollment barcode lookup request
dfacs/{DEVICE_ID}/image/request Request Alcatraz event image

Audit

Topic Description
dfacswan/instance/{DEVICE_ID}/audit_event Portal audit log entry

Topics — Device Publishes (Device → Portal)

Status & Registration

Topic Description
dfacs/register Initial registration with device metadata
dfacs/{DEVICE_ID}/status System status update
dfacs/{DEVICE_ID}/heartbeat Periodic health update (every 30s)
dfacs/{DEVICE_ID}/command/response Response to a portal command

User Sync ACK

Topic Description
dfacswan/instance/{DEVICE_ID}/users/ack ACK/NACK for user updates

Schedule Sync

Topic Description
dfacs/{DEVICE_ID}/schedules/ack ACK/NACK for schedule push
dfacs/{DEVICE_ID}/schedules/sync Push local schedule changes to portal

Alcatraz

Topic Description
dfacs/{DEVICE_ID}/alcatraz/enrollment/lookup/response Member email/name for enrollment
dfacs/{DEVICE_ID}/image/response Base64-encoded event image

Message Formats

Registration

Published to dfacs/register on startup.

{
  "device_id": "dfacs-aabbccdd",
  "timestamp": "2026-05-26T14:30:00Z",
  "friendly_name": "Main Gym Door",
  "version": "4.1.5",
  "local_ip": "192.168.1.100",
  "mac_suffix": "aabbccdd",
  "api_type": "zenoti",
  "relay_type": "dragonfly"
}

Heartbeat

Published to dfacs/{DEVICE_ID}/heartbeat every 30 seconds.

{
  "timestamp": "2026-05-26T14:30:00Z",
  "device_id": "dfacs-aabbccdd",
  "friendly_name": "Main Gym Door",
  "version": "4.1.5",
  "api_type": "zenoti",
  "uptime_seconds": 86400,
  "relay_state": "locked | unlocked | unknown",
  "failsafe_active": false,
  "memory_percent": 45.2,
  "cpu_percent": 12.5,
  "disk_percent": 72.1,
  "pending_checkins": 0,
  "schedule_hash": "abc123def456",
  "schedule_status": "open | closed | modified"
}

Access Log Event (Check-in)

Published to dfacs/{DEVICE_ID}/status after each scan.

{
  "barcode": "1234567890",
  "timestamp": "2026-05-26T14:30:00Z",
  "result": "Allowed",
  "reason": null,
  "first_name": "Jane",
  "last_name": "Smith",
  "membership_type": "Premium"
}

result is "Allowed" or "Denied". reason is null on allowed, or a denial reason string on denied.


Commands

The portal sends commands to dfacs/{DEVICE_ID}/command. Each command has a command field and optional parameters.

Door Control

Command Parameters Description
open duration (int, seconds) Unlock door for N seconds
lock Lock relay
unlock Permanently unlock relay
failsafe enable (bool) Toggle fail-safe feature

Data Retrieval

Command Parameters Description
get_status Return relay state + system metrics
get_config Return all config settings
get_access_logs limit (int) Return recent access logs
get_audit_events limit (int) Return system audit events
get_denied_barcodes Return full blocklist
get_barcodes limit, offset, search Paginated vendor barcode list
get_checkin_queue Return pending offline check-ins
get_checkin_history limit (int) Return sent check-in history
get_system_logs limit, level, after Return application logs
get_event_viewer lookback_minutes (int) Windows Event Viewer logs
get_table_checksums Row counts for sync verification
get_schedules Return all access schedules
get_membership_types Return available membership type filters
get_access_restrictions Return current membership allow/deny lists

Sync & Data Management

Command Parameters Description
sync_barcodes Force immediate barcode sync
save_schedule schedule (object) Create or update an access schedule
delete_schedule id (int) Delete an access schedule
set_access_restrictions allowed (list), denied (list) Update membership type filters

Command Response Format

Published to dfacs/{DEVICE_ID}/command/response:

{
  "command": "get_status",
  "success": true,
  "data": { ... },
  "error": null,
  "timestamp": "2026-05-26T14:30:00Z"
}

User Sync Payloads

Add/Update User

{
  "firebase_uid": "uid_abc123",
  "email": "[email protected]",
  "first_name": "Jane",
  "last_name": "Smith",
  "role_name": "Operator",
  "permissions": ["door.unlock", "access_logs.view"],
  "is_active": true
}

Revoke User

{
  "firebase_uid": "uid_abc123"
}

Full Sync

{
  "users": [ { ...user object... }, ... ]
}

ACK response to dfacswan/instance/{DEVICE_ID}/users/ack:

{
  "success": true,
  "count": 12,
  "error": null
}

Schedule Sync Payload

{
  "door_schedules": [
    {
      "id": 1,
      "name": "Business Hours",
      "is_active": true,
      "weekly_hours": {
        "monday": [["06:00", "22:00"]],
        "tuesday": [["06:00", "22:00"]],
        "saturday": [["08:00", "18:00"]],
        "sunday": []
      }
    }
  ],
  "holiday_schedules": [
    {
      "id": 1,
      "name": "Christmas",
      "date": "2026-12-25",
      "recurs_annually": true,
      "override_type": "closed",
      "deny_access_control": true
    }
  ]
}