Service Commands
Service commands enable programmatic interaction with acre Access Control hardware and services through a unified event-based messaging architecture. Rather than calling direct hardware APIs, commands are published as events that are routed to the appropriate service handler.
Overview
The acre platform uses an event-driven command architecture where hardware control operations are published as typed events. Each service subscribes to specific event types (monikers) and processes commands asynchronously.
| Feature |
Description |
| Architecture |
Publish-Subscribe event pattern |
| Method |
PublishEventAsync() via the wrapper or /eventmessagesink REST endpoint |
| Routing |
Commands routed by AppKey and EventTypeMoniker |
| Authentication |
Standard OAuth 2.0 bearer tokens |
| Response |
Asynchronous - subscribe to events for results |
How Service Commands Work
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Client App │────▶│ Event Sink │────▶│ Hardware Service│
│ │ │ (Message Bus) │ │ (Mercury/Bosch) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
│ PublishEventAsync │ Route by Moniker │ Execute Command
└──────────────────────┴────────────────────────┘
│
┌────────▼────────┐
│ Event Response │
│ (Status Update) │
└─────────────────┘
Key Components
| Component |
Description |
| AppKey |
Identifies the target service application (e.g., MercuryCommands, BoschCommands) |
| Namespace |
Logical grouping for event types (e.g., MercuryServiceCommands) |
| Nickname |
Specific command identifier (e.g., mercury:command-pulse) |
| ObjectLinks |
References to target hardware objects (Controllers, Readers, Panels) |
| EventData |
Optional parameters for the command (BSON-encoded) |
Available Service Commands
Hardware Control Services
| Service |
AppKey |
Namespace |
Description |
| Mercury Commands |
MercuryCommands |
MercuryServiceCommands |
HID Mercury controller operations |
| Bosch Commands |
BoschCommands |
BoschServiceCommands |
Bosch intrusion panel operations |
| Engage Commands |
EngageServiceCommands |
EngageServiceCommands |
Schlage Engage wireless lock operations |
Integration Services
| Service |
AppKey |
Namespace |
Description |
| LDAP Commands |
LdapService |
LdapServiceEvents |
Directory synchronization operations |
Publishing Commands
Using the C# Wrapper
// Basic command pattern
await client.PublishEventAsync(
instance, // Target folder/instance
"AppKey", // Target service identifier
new MonikerItem
{
Namespace = "ServiceNamespace", // Event type namespace
Nickname = "service:command" // Specific command
},
DateTime.UtcNow, // Timestamp
new { /* parameters */ }, // Command parameters (BSON)
objectLink1.AsObjectLink("Relation1"), // Target hardware
objectLink2.AsObjectLink("Relation2") // Additional targets
);
Using REST API
curl -X POST \
'https://api.{region}.acresecurity.cloud/api/f/{instance}/eventmessagesink' \
-H 'Authorization: Bearer {TOKEN}' \
-H 'Content-Type: application/json' \
-d '{
"$type": "Feenics.Keep.WebApi.Model.EventMessagePosting, Feenics.Keep.WebApi.Model",
"OccurredOn": "2024-01-15T12:00:00.000Z",
"AppKey": "MercuryCommands",
"EventTypeMoniker": {
"$type": "Feenics.Keep.WebApi.Model.MonikerItem, Feenics.Keep.WebApi.Model",
"Namespace": "MercuryServiceCommands",
"Nickname": "mercury:command-pulse"
},
"RelatedObjects": [
{
"$type": "Feenics.Keep.WebApi.Model.ObjectLinkItem, Feenics.Keep.WebApi.Model",
"Href": "/api/f/{instance}/peripherals/{reader-key}",
"LinkedObjectKey": "{reader-key}",
"CommonName": "Main Entrance Reader",
"Relation": "Reader"
},
{
"$type": "Feenics.Keep.WebApi.Model.ObjectLinkItem, Feenics.Keep.WebApi.Model",
"Href": "/api/f/{instance}/controllers/{controller-key}",
"LinkedObjectKey": "{controller-key}",
"CommonName": "Front Door Controller",
"Relation": "Controller"
}
],
"EventDataBsonBase64": "BQAAAAA="
}'
Command Response Handling
Service commands execute asynchronously. To receive command results:
1. Subscribe to Events
Use the Event Subscription mechanism to receive status updates.
// Subscribe to status change events
client.EventReceived += (sender, evt) =>
{
if (evt.EventType.Nickname.Contains("status"))
{
Console.WriteLine($"Status update: {evt.Message}");
}
};
2. Poll Object Status
After sending a command, query the target object for updated status.
// Check controller status after command
var controller = await client.GetControllerAsync(instance, controllerKey);
Console.WriteLine($"Online: {controller.Status?.IsOnline}");
Console.WriteLine($"Updating: {controller.Status?.IsUpdating}");
Best Practices
| Practice |
Description |
| Validate Objects First |
Ensure target objects exist and are accessible before sending commands |
| Handle Timeouts |
Commands may not execute immediately - implement appropriate wait strategies |
| Use Event Subscriptions |
Subscribe to events to receive command execution feedback |
| Check Online Status |
Verify hardware is online before sending real-time commands |
| Rate Limiting |
Avoid flooding the system with rapid successive commands |
Troubleshooting
| Issue |
Cause |
Solution |
| Command not received |
Invalid AppKey or Namespace |
Verify exact case-sensitive values |
| No response events |
Not subscribed to events |
Set up event subscription before sending commands |
| Object not found |
Invalid ObjectLink |
Verify object key and Href path |
| Permission denied |
Insufficient privileges |
Ensure user has Publish permission on EventType |
| Hardware offline |
Controller disconnected |
Check controller status before sending commands |