Command and Control lets a customer application send a command to a controllable point in the Mapped Graph. A common use case is writing a new value to a BACnet point, such as changing a setpoint or commanding an output.
Command and Control uses NATS as the customer-facing command channel. NATS is a messaging system, customers connect to Mapped over NATS, send a command request to a known subject, and then wait for a command response.
Draft note: Replace all {PLACEHOLDER} values before publishing.
| Area | Current behavior |
|---|---|
| Customer connection | NATS |
| Command payload format | Protocol Buffers |
| Current field protocol support | BACnet |
| Current edge path | Gateway outbound WebSocket |
| Command persistence | Not persistent today |
| Customer response handling | Customer must remain connected to receive the response |
| Request authorization | Same authorization model as the Mapped GraphQL API |
| Point reference | Point ID or mapping key |
Important: Commands are not persistent today. The customer application must keep its NATS connection active until Mapped sends the response. A response may return quickly, or it may take longer depending on the command timeout and downstream device behavior.
At a high level, the customer application sends a command to Mapped over NATS. Mapped validates the request, authorizes the point reference, routes the command to the correct gateway, and returns the command response.
[Diagram placeholder showing customer application connecting to Mapped over NATS, Mapped routing to a UG over outbound WebSocket, and the UG writing to a BACnet controller.]
Command and Control access is currently enabled through Support.
| Step | Owner | Action |
|---|---|---|
| 1 | Customer | Request Command and Control access from Mapped Support |
| 2 | Support | Open an internal ticket to generate NATS credentials |
| 3 | Mapped | Generate NATS credentials for the customer account |
| 4 | Support | Provide the NATS credentials to the customer |
| 5 | Customer | Choose a NATS client library and integrate it into the customer application |
| 6 | Support or Mapped | Enable Command and Control on the UG bootstrap, if the target points are UG-backed |
Note: Command and Control is not enabled on the gateway by default. It must be enabled through a request to Mapped Support.
Customers typically use an existing NATS client library, rather than building their own client. NATS provides official and community-supported clients for common programming languages.
Use the following connection information:
| Setting | Value |
|---|---|
| NATS URL | {NATS_URL} |
| NATS subject | {NATS_COMMAND_SUBJECT} |
| Credentials | Provided by Mapped Support |
| Payload encoding | Protocol Buffers |
| Request message | {WRITE_PROP_REQUEST_MESSAGE_NAME} |
| Response message | {CONTROL_RESPONSE_MESSAGE_NAME} |
| Protobuf source | {MAPPED_PB_CONTROL_PROTO_LINK} |
Important: NATS credentials are connection credentials only. They allow the customer application to connect to Mapped. They do not authorize an individual command.
Every command request must include an authorization header. Command and Control uses the same authorization rules as the Mapped GraphQL API.
The authorization header is evaluated per request. This is separate from the NATS credentials used to establish the connection.
| Credential | Purpose | Scope |
|---|---|---|
| NATS credentials | Establish a NATS connection to Mapped | Customer account |
| Authorization header | Authorize the specific command request | Organization and allowed resources |
The authorization header can use:
Each command request includes:
| Field | Required | Description |
|---|---|---|
| Authorization header | Yes | Uses the same rules as the Mapped GraphQL API |
| Point reference | Yes | Either a point ID or a mapping key |
| Value | Yes | The typed value to write |
| Priority | No | Optional BACnet priority index |
The point reference can be either a Mapped point ID or a mapping key.
If the request includes a point ID, Mapped Cloud looks up the corresponding mapping key using the request credentials. If the request includes a mapping key, Mapped Cloud still validates the mapping key using the request credentials. This validation also acts as an authorization check. If the point does not exist, or if it belongs to a different organization, the request fails.
Use the protobuf request message defined in {MAPPED_PB_CONTROL_PROTO_LINK}.
Request ResponseCopy1 2 3 4 5 6 7 8 9 10 11 12 13 14{ "headers": { "authorization": "Bearer PAT_OR_JWT" }, "request": { "pointReference": { "pointId": "PNTxxxxxxxxxxxxxxxxxxxxxxxx" }, "value": { "floatValue": 72 }, "priority": null } }
The same command can reference a mapping key instead of a point ID.
Request ResponseCopy1 2 3 4 5 6 7 8 9 10 11 12 13 14{ "headers": { "authorization": "Bearer PAT_OR_JWT" }, "request": { "pointReference": { "mappingKey": "msrc://CONNECTOR_ID@SOURCE/GATEWAY_ID/DEVICE_ADDRESS/OBJECT_ID" }, "value": { "floatValue": 72 }, "priority": null } }
Draft note: Replace these examples with exact protobuf field names from {MAPPED_PB_CONTROL_PROTO_LINK} before publishing.
Command values use a typed value mode; the value should match the point data type shown in the Mapped Graph.
Common value types include:
| Value type | Example |
|---|---|
| Boolean | true |
| Integer | 72 |
| Float | 72.0 |
| String | "occupied" |
Some downstream systems accept values that do not exactly match the type advertised in the graph. Mapped does not strictly prevent customers from attempting a different type. If the device or protocol rejects the value, Mapped returns an error.
The gateway may perform safe type conversions when the conversion does not result in data loss. For example, if a controller expects a float and the customer sends integer 72, the gateway may convert it to 72.0.
Draft note: Confirm the exact safe conversion rules with Engineering before publishing. The recommended customer guidance is to match the point data type shown in the Mapped Graph whenever possible.
For BACnet commands, the request can optionally include a priority.
If priority is omitted or set to null, Mapped attempts to command the point normally.
If priority is set, Mapped attempts to write the value at that BACnet priority.
Request ResponseCopy1 2 3 4 5 6 7 8 9 10 11 12 13 14{ "headers": { "authorization": "Bearer PAT_OR_JWT" }, "request": { "pointReference": { "pointId": "PNTxxxxxxxxxxxxxxxxxxxxxxxx" }, "value": { "booleanValue": true }, "priority": 8 } }
An application can either send a command and not wait for a response, or keep the connection open and wait for a response.
For applications that need confirmation, keep the NATS connection active until the response is received.
Mapped returns standardized control result codes. When available, Mapped also includes the raw downstream device or protocol error. For example, if a BACnet controller returns a useful error, Mapped can include that error in the response.
Copy1 2 3 4 5 6 7 8::static_response::{ "requestId": "REQUEST_ID", "result": { "code": "CONTROL_RESULT_CODE", "message": "STANDARDIZED_ERROR_MESSAGE", "downstreamMessage": "RAW_DEVICE_OR_PROTOCOL_MESSAGE" } }
Common failure cases include:
| Failure case | Expected behavior |
|---|---|
| Point ID does not exist | Request fails |
| Mapping key does not exist | Request fails |
| Point is outside the authorized organization | Request fails |
| No active WebSocket exists for the gateway | Request fails fast |
| Downstream device rejects the value | Error returned from the device or protocol |
| Value type cannot be safely converted | Error returned |
| Command times out | Timeout error returned |
For routing, the gateway establishes an outbound WebSocket connection to Mapped Cloud and announces its gateway ID. When Mapped receives a command request, it resolves the point reference, determines the target mapping key, extracts the gateway ID, and looks for an active WebSocket connection for that gateway.
If an active connection exists, Mapped sends the command to the UG. If there is no active connection, Mapped fails fast and returns an error to the customer.
Note: The UG connection is outbound from the customer environment to Mapped Cloud.
Mapped can accept either a point ID or a mapping key in the command request.
Mapped ultimately needs a mapping key to route the command. If the application provides a point ID, Mapped resolves the mapping key. If the applicagtion provides a mapping key, Mapped validates that it exists and is authorized.
In some cases, a point's source identity can change at the edge. For example, if a BACnet point changes IP address, the gateway may contribute a new point in the core graph. The resolved graph may merge the old and new contributions into the same point because they share a BACnet object ID. For routing, Mapped Cloud uses the latest usable mapping key known to the gateway.
Command responses are not persisted today. The application must remain connected to receive the response.
Mapped chose NATS to support future persistent command workflows. In the future, Mapped may support NATS JetStream, which could allow a customer to send commands, disconnect, reconnect later, and retrieve stored responses.
Check that the request includes a valid authorization header and that the token has access to the organization and point.
Confirm that the point ID or mapping key exists in the Mapped Graph. If using a mapping key, confirm that it is the current mapping key for the target point.
The target gateway may not have an active WebSocket connection. Confirm that the gateway is online and that Command and Control is enabled.
Confirm that the value type matches the point type shown in the Mapped Graph. If the device requires a specific BACnet data type, priority, or proprietary value, use the value expected by the downstream system.
Confirm that the application kept the NATS connection active after sending the request. Command responses are not persisted today.