Add Peripherals
Overview
Peripherals are the input and output devices that make a reader function as a complete door. A typical door configuration includes a Request-to-Exit (REX) input, a door contact sensor, and a door strike output. These components work together to provide secure, monitored access control.
Key Concepts
| Component |
Type |
Purpose |
| REX (Request-to-Exit) |
Input |
Detects when someone pushes a button or motion sensor to exit |
| Door Contact |
Input |
Monitors whether the door is open or closed |
| Door Strike |
Output |
Unlocks the door when access is granted |
| Slave Reader |
Reader |
Secondary reader (exit side of door) |
| Auxiliary Input |
Input |
Additional monitoring (glass break, tamper, etc.) |
Reader Peripheral Types (ReaderPeripheralTypes Enum)
Valid values for adding peripherals to a reader:
| Value |
Description |
Rex |
Request-to-Exit device (input) |
Contact |
Door contact sensor (input) |
Strike |
Door strike/lock (output) |
Slave |
Slave/exit reader |
Peripheral Behaviour Values
| Value |
Description |
0 |
Normally Closed (NC) - Circuit is closed when inactive |
1 |
Normally Open (NO) - Circuit is open when inactive |
Output Mode Values
| Value |
Mode |
Description |
0 |
Normal |
Standard momentary activation |
1 |
Toggle |
Stays in current state until next activation |
2 |
Timed |
Activates for specified duration |
Prerequisites
Before adding peripherals, ensure you have:
- ✅ A controller with downstream configured
- ✅ A reader created on the downstream
- ✅ Knowledge of physical I/O wiring and indices
C# Examples
Add Complete Door Configuration
This example adds REX, door contact, and strike to a reader for a complete door setup.
using Feenics.Keep.WebApi.Wrapper;
using Feenics.Keep.WebApi.Model;
// Assuming 'reader' is a MercuryReaderInfo object
var readerName = reader.CommonName;
// 1. Add REX (Request-to-Exit) Input
var rex = await client.AddPeripheralToReaderAsync(
(MercuryReaderInfo)reader,
ReaderPeripheralTypes.Rex,
new MercuryInputInfo
{
CommonName = $"REX - {readerName}",
Behaviour = 1, // Normally Open (typical for motion sensors/push buttons)
Debounce = 2, // 200ms debounce to prevent false triggers
SioNumber = 0, // SIO board number
SioIndex = 1 // Input index on the SIO (REX typically on index 1)
});
Console.WriteLine($"Added REX: {rex.CommonName}");
// 2. Add Door Contact Input
var contact = await client.AddPeripheralToReaderAsync(
(MercuryReaderInfo)reader,
ReaderPeripheralTypes.Contact,
new MercuryInputInfo
{
CommonName = $"Door Contact - {readerName}",
Behaviour = 0, // Normally Closed (door closed = circuit closed)
Debounce = 4, // 400ms debounce for door bounce
SioNumber = 0,
SioIndex = 0 // Contact typically on index 0
});
Console.WriteLine($"Added Contact: {contact.CommonName}");
// 3. Add Door Strike Output
var strike = await client.AddPeripheralToReaderAsync(
(MercuryReaderInfo)reader,
ReaderPeripheralTypes.Strike,
new MercuryOutputInfo
{
CommonName = $"Strike - {readerName}",
Mode = 0, // Normal mode
ActivationTime = 6, // Unlock for 6 seconds
SioNumber = 0,
SioIndex = 0 // Output index on the SIO
});
Console.WriteLine($"Added Strike: {strike.CommonName}");
// Add a general purpose input (e.g., glass break sensor)
var glassBreak = await client.AddInputToControllerAsync(
controller,
new MercuryInputInfo
{
CommonName = "Glass Break - Lobby Window",
Behaviour = 0, // Normally Closed
Debounce = 1, // Quick response
LatchMode = 1, // Latch until acknowledged
SioNumber = 1, // On MR16-IN board
SioIndex = 0
});
Complete Door Setup Function
/// <summary>
/// Configures a complete door with all standard peripherals
/// </summary>
public async Task<(MercuryInputInfo rex, MercuryInputInfo contact, MercuryOutputInfo strike)>
SetupDoorPeripheralsAsync(MercuryReaderInfo reader, int sioNumber = 0)
{
var doorName = reader.CommonName;
// Determine indices based on reader position
// Typically: Reader 1 uses inputs 0-1, Reader 2 uses inputs 2-3, etc.
var readerIndex = reader.SioIndex ?? 0;
var inputStartIndex = readerIndex * 2;
var outputIndex = readerIndex;
// Add REX
var rex = await client.AddPeripheralToReaderAsync(
reader,
ReaderPeripheralTypes.Rex,
new MercuryInputInfo
{
CommonName = $"REX - {doorName}",
Behaviour = 1, // NO
Debounce = 2,
SioNumber = sioNumber,
SioIndex = inputStartIndex + 1
}) as MercuryInputInfo;
// Add Contact
var contact = await client.AddPeripheralToReaderAsync(
reader,
ReaderPeripheralTypes.Contact,
new MercuryInputInfo
{
CommonName = $"Contact - {doorName}",
Behaviour = 0, // NC
Debounce = 4,
SioNumber = sioNumber,
SioIndex = inputStartIndex
}) as MercuryInputInfo;
// Add Strike
var strike = await client.AddPeripheralToReaderAsync(
reader,
ReaderPeripheralTypes.Strike,
new MercuryOutputInfo
{
CommonName = $"Strike - {doorName}",
Mode = 0,
ActivationTime = 6,
SioNumber = sioNumber,
SioIndex = outputIndex
}) as MercuryOutputInfo;
Console.WriteLine($"Configured door: {doorName}");
Console.WriteLine($" REX: Input {inputStartIndex + 1}");
Console.WriteLine($" Contact: Input {inputStartIndex}");
Console.WriteLine($" Strike: Output {outputIndex}");
return (rex, contact, strike);
}
cURL Examples
ACCESS_TOKEN="your-access-token"
INSTANCE_KEY="your-instance-key"
READER_KEY="your-reader-key"
# Add REX (Request-to-Exit) input
curl -X POST \
"https://api.us.acresecurity.cloud/api/f/${INSTANCE_KEY}/peripherals/${READER_KEY}/Rex" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"$type": "Feenics.Keep.WebApi.Model.MercuryInputInfo, Feenics.Keep.WebApi.Model",
"CommonName": "REX - Front Door",
"Behaviour": 1,
"Debounce": 2,
"SioNumber": 0,
"SioIndex": 1,
"IsDisabled": false,
"LatchMode": 0
}'
# Add door contact sensor
curl -X POST \
"https://api.us.acresecurity.cloud/api/f/${INSTANCE_KEY}/peripherals/${READER_KEY}/Contact" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"$type": "Feenics.Keep.WebApi.Model.MercuryInputInfo, Feenics.Keep.WebApi.Model",
"CommonName": "Contact - Front Door",
"Behaviour": 0,
"Debounce": 4,
"SioNumber": 0,
"SioIndex": 0,
"IsDisabled": false,
"LatchMode": 0
}'
Add Door Strike Output
# Add door strike relay
curl -X POST \
"https://api.us.acresecurity.cloud/api/f/${INSTANCE_KEY}/peripherals/${READER_KEY}/Strike" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"$type": "Feenics.Keep.WebApi.Model.MercuryOutputInfo, Feenics.Keep.WebApi.Model",
"CommonName": "Strike - Front Door",
"Mode": 0,
"ActivationTime": 6,
"SioNumber": 0,
"SioIndex": 0
}'
| Property |
Type |
Description |
CommonName |
string |
Descriptive name for the input |
Behaviour |
int |
0 = Normally Closed, 1 = Normally Open |
Debounce |
int |
Debounce time in 100ms increments |
LatchMode |
int |
0 = No latch, 1 = Latch until acknowledged |
SioNumber |
int |
SIO board number |
SioIndex |
int |
Input point index on the SIO |
IsDisabled |
bool |
Disable input processing |
EntryDelay |
int? |
Delay before armed input triggers (seconds) |
ExitDelay |
int? |
Delay after arming before input becomes active |
HoldTime |
int? |
Time input must be active before triggering |
Output Properties Reference
| Property |
Type |
Description |
CommonName |
string |
Descriptive name for the output |
Mode |
int |
0 = Normal, 1 = Toggle, 2 = Timed |
ActivationTime |
int |
Time output stays active (seconds) |
SioNumber |
int |
SIO board number |
SioIndex |
int |
Output point index on the SIO |
Best Practices
| Practice |
Description |
| Use consistent naming |
Include door name and peripheral type in CommonName |
| Match physical wiring |
Ensure SioIndex matches actual wiring |
| Set appropriate debounce |
REX: 2 (200ms), Contact: 4 (400ms) |
| Test each peripheral |
Verify inputs/outputs work before going live |
| Document I/O mapping |
Keep a record of which index maps to which wire |
| Consider fail-safe vs fail-secure |
Strike mode affects door behavior during power loss |
Troubleshooting
| Issue |
Possible Cause |
Solution |
| Door won’t unlock |
Wrong strike output index |
Verify SioIndex matches physical wiring |
| Contact shows wrong state |
Behaviour mismatch |
Toggle between NC (0) and NO (1) |
| REX not triggering |
High debounce value |
Reduce debounce time |
| False alarms |
Low debounce value |
Increase debounce for noisy environments |
| Peripheral not found |
Wrong reader key |
Verify reader exists and is on correct downstream |
| Multiple peripherals same index |
Index conflict |
Each peripheral needs unique SioIndex |