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