Readers are the primary access control devices that authenticate cardholders at doors and entry points. They are added as peripherals to downstream boards (SIO modules) connected to controllers. This guide covers Mercury reader configuration, which is the most common reader type in acre Access Control systems.
| Property | Type | Description |
|---|---|---|
CommonName |
string | Display name for the reader |
SioIndex |
int | Position on the downstream board (0-based) |
MercuryReaderType |
enum | Physical reader format (Wiegand, OSDP, etc.) |
MercuryReaderAccessMethod |
enum | How cards are read (Card, CardAndPin, etc.) |
NormalGrantAccessTime |
int | Door unlock duration in seconds |
ExtendedGrantAccessTime |
int | Extended unlock for ADA compliance |
DoorHeldTime |
int | Seconds before door-held alarm triggers |
MercuryKeypadType |
enum | Keypad format if present |
MercuryAntiPassbackType |
enum | Anti-passback enforcement mode |
The MercuryReaderAccessMethod property controls how credentials are validated at a reader. See the MercuryReaderAccessMethods enum for all available options.
| Value | Enum | Description |
|---|---|---|
| 0 | Card |
Card only - no PIN required |
| 1 | PinOnly |
PIN only - no card needed |
| 2 | CardAndPin |
Both card and PIN required (two-factor authentication) |
| 3 | CardOrPin |
Either card or PIN grants access |
| 4 | FacilityCodeOnly |
Any card with valid facility code grants access |
| 5 | Unlock |
Reader permanently unlocked (always grants access) |
| 6 | LockDown |
Reader locked down (always denies access) |
| 7 | CardAndPinNoGrantOnDuress |
Card and PIN required, denies access on duress PIN |
💡 Note: When using PIN-based modes (PinOnly, CardAndPin, CardOrPin, CardAndPinNoGrantOnDuress), ensure cardholders have a
PinCodeassigned in their CardAssignmentInfo.
The MercuryReaderType property uses the MercuryReaderTypes enum to specify the physical reader format:
| Value | Enum | Description |
|---|---|---|
| 0 | Wiegand |
Standard Wiegand protocol readers |
| 1 | ClockAndData |
Clock and data protocol readers |
| 2 | WiegandWithMagStripe |
Wiegand readers with magnetic stripe support |
| 3 | ClockAndDataWithMagStripe |
Clock and data readers with magnetic stripe |
| 4 | F2F |
Facility-to-Facility protocol |
| 5 | SupervisedF2F |
Supervised Facility-to-Facility protocol |
| 6 | SupervisedF2FInputsAtReader |
Supervised F2F with inputs at reader |
The MercuryKeypadType property uses the MercuryKeypadTypes enum to specify the keypad format when present:
| Value | Enum | Description |
|---|---|---|
| 0 | None |
No keypad present |
| 1 | Hid4Bit |
HID 4-bit keypad |
| 2 | Hid8Bit |
HID 8-bit keypad |
| 3 | Mr20 |
Mercury MR20 keypad |
| 4 | Motorola8Bit |
Motorola 8-bit keypad |
| 5 | Mr20NoTamper |
Mercury MR20 keypad without tamper detection |
| 6 | FourBit60Second |
4-bit keypad with 60-second timeout |
| 7 | EightBit60Second |
8-bit keypad with 60-second timeout |
| 8 | FourBit10Second |
4-bit keypad with 10-second timeout |
| 9 | EightBit10Second |
8-bit keypad with 10-second timeout |
Before adding a reader, you need:
ControllerInfo (Add Controller)// Get the downstream board where the reader will be connected
var downstream = (await client.SearchAsync(controller, "{\"CommonName\":\"MainSIO\"}"))
.OfType<DownstreamInfo>().FirstOrDefault();
// Add a standard Wiegand reader
var reader = await client.AddPeripheralToDownStreamAsync(downstream, new MercuryReaderInfo
{
CommonName = "Main Entrance Reader",
// Physical configuration
SioIndex = 0, // First reader port on the SIO
MercuryReaderType = MercuryReaderTypes.Wiegand,
// Access method
MercuryReaderAccessMethod = MercuryReaderAccessMethods.Card,
OfflineAccessMethod = MercuryReaderAccessMethods.FacilityCodeOnly,
// Timing settings (in seconds)
NormalGrantAccessTime = 6, // Door unlock time
ExtendedGrantAccessTime = 30, // ADA extended access time
DoorHeldTime = 30, // Door-held alarm threshold
// Security settings
MercuryAntiPassbackType = MercuryAntiPassbackTypes.None,
AntiPassbackTimeout = 0,
MercuryKeypadType = MercuryKeypadTypes.None,
// Strike/lock configuration
StrikeMode = 1, // Normal strike mode
// Host authorization
EnableHostCheckBeforeGrant = false, // No server validation required
HostCheckDefaultIsGrant = true, // Default grant if host unreachable
// Behavior settings
AssumeDoorUsed = false // Require door contact confirmation
});
Console.WriteLine($"Created reader: {reader.CommonName} (Key: {reader.Key})");
var secureReader = await client.AddPeripheralToDownStreamAsync(downstream, new MercuryReaderInfo
{
CommonName = "Secure Area Reader",
SioIndex = 1,
// Require both card and PIN
MercuryReaderAccessMethod = MercuryReaderAccessMethods.CardAndPin,
OfflineAccessMethod = MercuryReaderAccessMethods.Card, // Fallback to card-only offline
MercuryReaderType = MercuryReaderTypes.Wiegand,
MercuryKeypadType = MercuryKeypadTypes.Hid4Bit, // HID 4-bit keypad format
// Timing
NormalGrantAccessTime = 5,
ExtendedGrantAccessTime = 20,
DoorHeldTime = 15,
// Anti-passback for security areas
MercuryAntiPassbackType = MercuryAntiPassbackTypes.Hard,
AntiPassbackTimeout = 300, // 5 minute timeout
StrikeMode = 1,
EnableHostCheckBeforeGrant = false,
HostCheckDefaultIsGrant = true,
AssumeDoorUsed = false
});
var clockDataReader = await client.AddPeripheralToDownStreamAsync(downstream, new MercuryReaderInfo
{
CommonName = "Clock and Data Reader",
SioIndex = 2,
// Clock and data configuration
MercuryReaderType = MercuryReaderTypes.ClockAndData,
MercuryReaderAccessMethod = MercuryReaderAccessMethods.Card,
// Standard timing
NormalGrantAccessTime = 6,
ExtendedGrantAccessTime = 30,
DoorHeldTime = 30,
// No keypad or anti-passback
MercuryAntiPassbackType = MercuryAntiPassbackTypes.None,
MercuryKeypadType = MercuryKeypadTypes.None,
StrikeMode = 1,
EnableHostCheckBeforeGrant = false,
HostCheckDefaultIsGrant = true,
AssumeDoorUsed = false
});
Enable host check for real-time server authorization before granting access:
var hostCheckReader = await client.AddPeripheralToDownStreamAsync(downstream, new MercuryReaderInfo
{
CommonName = "Server-Validated Reader",
SioIndex = 3,
MercuryReaderType = MercuryReaderTypes.Wiegand,
MercuryReaderAccessMethod = MercuryReaderAccessMethods.Card,
// Enable host authorization check
EnableHostCheckBeforeGrant = true, // Always check with server
HostCheckDefaultIsGrant = false, // Deny if server unreachable
NormalGrantAccessTime = 6,
ExtendedGrantAccessTime = 30,
DoorHeldTime = 30,
MercuryAntiPassbackType = MercuryAntiPassbackTypes.None,
MercuryKeypadType = MercuryKeypadTypes.None,
StrikeMode = 1,
AssumeDoorUsed = false,
Tags = ['tfa-mobile']
});
Note: Host check requires reliable network connectivity. Set
HostCheckDefaultIsGrant = truefor fail-open behavior, orfalsefor fail-secure.
| Type | Description | Use Case |
|---|---|---|
None |
No anti-passback | Low-security areas |
Soft |
Logs violations but allows access | Tracking only |
Hard |
Denies access on violation | High-security areas |
Timed |
Resets after timeout | Parking garages |
// Hard anti-passback with 10-minute reset
var apbReader = await client.AddPeripheralToDownStreamAsync(downstream, new MercuryReaderInfo
{
CommonName = "APB-Controlled Reader",
SioIndex = 0,
MercuryAntiPassbackType = MercuryAntiPassbackTypes.Hard,
AntiPassbackTimeout = 600, // 10 minutes in seconds
// Other required properties...
MercuryReaderType = MercuryReaderTypes.Wiegand,
MercuryReaderAccessMethod = MercuryReaderAccessMethods.Card,
NormalGrantAccessTime = 6,
ExtendedGrantAccessTime = 30,
DoorHeldTime = 30,
StrikeMode = 1,
EnableHostCheckBeforeGrant = false,
HostCheckDefaultIsGrant = true,
AssumeDoorUsed = false
});
curl -X POST \
"https://api.us.acresecurity.cloud/api/f/INSTANCE_KEY/controllers/CONTROLLER_KEY/downstream/DOWNSTREAM_KEY/peripherals" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"$type": "Feenics.Keep.WebApi.Model.MercuryReaderInfo, Feenics.Keep.WebApi.Model",
"CommonName": "Main Entrance Reader",
"SioIndex": 0,
"MercuryReaderType": 0,
"MercuryReaderAccessMethod": 0,
"OfflineAccessMethod": 4,
"NormalGrantAccessTime": 6,
"ExtendedGrantAccessTime": 30,
"DoorHeldTime": 30,
"MercuryAntiPassbackType": 0,
"AntiPassbackTimeout": 0,
"MercuryKeypadType": 0,
"StrikeMode": 1,
"EnableHostCheckBeforeGrant": false,
"HostCheckDefaultIsGrant": true,
"AssumeDoorUsed": false
}'
curl -X GET \
"https://api.us.acresecurity.cloud/api/f/INSTANCE_KEY/controllers/CONTROLLER_KEY/downstream/DOWNSTREAM_KEY/peripherals" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
| Practice | Recommendation |
|---|---|
| Naming Convention | Use location-based names (e.g., “Bldg1-Floor2-MainEntry”) |
| Door Held Time | Set based on typical traffic (15-30 seconds typical) |
| Extended Access | Configure for ADA compliance (30+ seconds) |
| Offline Access | Set fallback method for network outages |
| Anti-Passback | Use soft APB initially to monitor before enforcing hard APB |
| Host Check | Only enable for high-security with reliable network |
| SIO Index | Document port assignments in CommonName or Notes |
| Issue | Cause | Solution |
|---|---|---|
| Reader not responding | Wrong SioIndex | Verify physical port matches configuration |
| Cards not reading | Wrong reader type | Match MercuryReaderType to physical hardware |
| Access denied unexpectedly | Anti-passback violation | Check APB settings, reset cardholder APB status |
| Door stays unlocked | High grant time | Reduce NormalGrantAccessTime |
| Keypad not working | Wrong keypad type | Match MercuryKeypadType to hardware |
| Host check timeout | Network issues | Consider HostCheckDefaultIsGrant = true |