> ## Documentation Index
> Fetch the complete documentation index at: https://api-docs.bienport.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Third Party Application → Resource Commands

> How external apps control device outputs via MQTT and receive confirmations/notifications.

<Note>
  This is a public API!
</Note>

<Info>
  A third‑party app sends control commands to field devices and receives both an immediate command acknowledgement and an eventual state‑change notification.
</Info>

## Transport & Topics

* **Publish commands to:** <code>resource/commands</code>\
  <em>QoS:</em> <code>2</code> (exactly‑once delivery negotiated by MQTT)
* **Subscribe for responses & notifications:** <code>application/third-party/appName/instanceId</code>

<Warning>
  Always include a unique <code>correlationId</code> in requests and verify the same value in responses/notifications. JWT must be valid; otherwise the gateway returns an error response.
</Warning>

<Warning>
  Allways subscribe to topic `application/third-party/appName/instanceId` where `appId` value is `appName.instanceId`in request payload!
</Warning>

***

## Message Envelopes (Common)

### Command Request

```json theme={null}
{
  "messageType": "commandMessage",
  "appId": "appName.instanceId",
  "brand": "Bimetri",
  "jwtToken": "replace-with-your-token",
  "userId": 12345,
  "organizationId": 23456,
  "command": "<command>",
  "correlationId": "<unique-id>",
  "parameters": { /* command-specific */ }
}
```

### Command Response

```json theme={null}
{
  "messageType": "commandResponse",
  "correlationId": "<same-as-request>",
  "result": "<sent|not_send|failed|send_no_ack|unauthorized>",
  "reason": "<human-readable>",
  "data": { /* command-specific echo & device info */ }
}
```

### Notification (Async)

```json theme={null}
{
  "messageType": "notification",
  "appId": "appName.instanceId",
  "correlationId": "<same-as-request-or-omitted>",
  "command": "<command>",
  "notificationType": "<event>",
  "userName": "<who-triggered>",
  "userId": 12345,
  "parameters": { /* event-specific payload */ }
}
```

<Tip>
  Responses typically acknowledge queuing (e.g., <code>result = "sent"</code>), while notifications carry the <em>final</em> device state. Treat notifications as the source of truth for UI state.
</Tip>

***

# 1) <code>setExtDO</code> Command

Set an external digital output (relay/DO) to <code>on</code>/<code>off</code>.

## Request

```json theme={null}
{
  "messageType": "commandMessage",
  "appId": "flexyWattApp.1",
  "brand": "Bimetri",
  "jwtToken": "replace-with-your-token",
  "userId": 12345,
  "organizationId": 23456,
  "command": "setExtDO",
  "correlationId": "100",
  "parameters": {
    "resourceId": 101,
    "output": 4,
    "status": 0
  }
}
```

### Parameters

* <code>resourceId</code> (number) – Target device identifier.
* <code>output</code> (number) – Output index/port (1‑based unless otherwise provisioned).
* <code>status</code> (number) – Desired state: <code>1</code> (on/closed), <code>0</code> (off/open).

<Note>
  Some deployments may validate output ranges per model; invalid ports will yield an error response.
</Note>

***

For this example (due to `"appId": "flexyWattApp.1"`); subscribe to topic `application/third-party/flexyWattApp/1` or `application/third-party/flexyWattApp/#` (for all instances) to receive responses and async notifications.

## Immediate Response

```json theme={null}
{
  "messageType": "commandResponse",
  "correlationId": "100",
  "result": "sent",
  "reason": "Command Queued",
  "data": {
    "command": "setExtDO",
    "resourceId": 101,
    "brand": "Bimetri",
    "model": "BMM620",
    "networkId": "26:AA:E0:23:23:5E"
  }
}
```

### Error Response (Example)

```json theme={null}
{
  "messageType": "commandResponse",
  "correlationId": "100",
  "result": "not_send",
  "reason": "The user does not have access rights to the resource!",
  "data": {
    "command": "setExtDO",
    "resourceId": 101,
    "userId": 12345
  }
}
```

<PossibleErrors>
  <ul>
    <li><code>not\_send</code> – AuthN/AuthZ failed or validation error (missing fields, invalid output index).</li>
    <li><code>send\_no\_ack</code> – Command published but no device acknowledgement within timeout.</li>
    <li><code>failed</code> – Delivery ok but device/backend reported failure.</li>
    <li><code>unauthorized</code> – JWT invalid/expired.</li>
  </ul>
</PossibleErrors>

***

## State‑Change Notification

Emitted when the device confirms the output’s actual state.

```json theme={null}
{
  "messageType": "notification",
  "appId": "flexyWattApp.1",
  "correlationId": "100",
  "command": "setExtDO",
  "notificationType": "extDOStateChanged",
  "userName": "Flexywatt User",
  "userId": 12345,
  "parameters": {
    "resourceId": 101,
    "brand": "Bimetri",
    "model": "BMM620",
    "networkId": "26:AA:E0:23:23:5E",
    "organizationId": 23456,
    "output": 4,
    "status": 1
  }
}
```

<Tip>
  Use the pair <code>(resourceId, output)</code> plus <code>correlationId</code> to de‑duplicate and to reconcile UI state after reconnects.
</Tip>

***

## Consumer Guidance

* **QoS & retries:** Expect duplicate deliveries at QoS 1. Make handlers idempotent.
* **Timeouts:** If no notification arrives, surface the queued state and allow users to retry.
* **Security:** Store tokens securely; rotate when expired; never log full JWTs.
* **Tracing:** Log <code>correlationId</code> on both publish and receive paths for observability.
