diff --git a/docs/tutorials/receive-lorawan-sensor-data-from-chirpstack.md b/docs/tutorials/receive-lorawan-sensor-data-from-chirpstack.md index 25db11bd..d479f5c2 100644 --- a/docs/tutorials/receive-lorawan-sensor-data-from-chirpstack.md +++ b/docs/tutorials/receive-lorawan-sensor-data-from-chirpstack.md @@ -6,6 +6,14 @@ sidebar_position: 3 [ChirpStack](https://www.chirpstack.io/) is an open source LoRaWAN network server stack. This tutorial explains how to receive LoRaWAN sensor data via ChirpStack using the [MQTT Agent](../user-guide/agents-protocols/mqtt). The tutorial is based on the [Dragino LHT65](https://www.dragino.com/products/temperature-humidity-sensor/item/151-lht65.html) LoRaWAN sensor device as an example. +:::note +This tutorial focuses on the **manual configuration** of MQTT agent links to provide a deeper understanding of the integration process. + +For a more automated approach, please see the specific agent documentation: +* **[ChirpStack](../user-guide/agents-protocols/chirpstack.md)** +* **[The Things Stack (TTS)](../user-guide/agents-protocols/the-things-stack.md)** +::: + ## Install and start ChirpStack 1. Make a copy of the ChirpStack Docker repository with the following commands: ```shell diff --git a/docs/user-guide/agents-protocols/_lorawan-asset-types.md b/docs/user-guide/agents-protocols/_lorawan-asset-types.md new file mode 100644 index 00000000..8b456fc2 --- /dev/null +++ b/docs/user-guide/agents-protocols/_lorawan-asset-types.md @@ -0,0 +1,107 @@ +## LoRaWAN Asset Types + +When using LoRaWAN agents such as [ChirpStack](chirpstack.md) or [The Things Stack](the-things-stack.md), OpenRemote can automatically provision assets and their communication links. + +This automation relies on the use of specific **LoRaWAN Asset Types**. In these types, each attribute that is linked to a device data point must contain an `AGENT_LINK_CONFIG` meta item. This meta item acts as a blueprint, allowing the agent to automatically configure the underlying MQTT protocol agent links. + +### Configuration Keys + +The `AGENT_LINK_CONFIG` meta item is a `ValueType.ObjectMap` containing the following keys: + +| Key | Type | Description | +|:---|:---|:---| +| `uplinkPort` | `Integer` | Filters incoming messages by the LoRaWAN FPort. | +| `valueFilterJsonPath` | `String` | The JSON Path used to extract the value from the payload (see [Payload Formats](#network-server-payload-formats)). | +| `valueConverter` | `Map` | Defines a value converter map for incoming values. | +| `downlinkPort` | `Integer` | The FPort used for sending downlink commands. | +| `writeValueConverter` | `Map` | Maps attribute values (e.g., `TRUE`/`FALSE`) to the required Base64 payloads. | + +### Network Server Payload Formats + +The `valueFilterJsonPath` specifies the exact location of sensor data within the incoming MQTT message. Because different LoRaWAN network servers wrap the decoded device data in different JSON envelopes, the root of your path must match your specific provider: + +| Network Server | Payload Root | Example Path | +| :--- | :--- | :--- | +| **ChirpStack** | `$.object` | `$.object.Temperature` | +| **The Things Stack** | `$.uplink_message.decoded_payload` | `$.uplink_message.decoded_payload.Temperature` | + +### Example Asset Type + +The example demonstrates how to map a sensor reading (uplink) and a command switch (downlink). + +```java +@Entity +public class LoRaWanAsset extends Asset { + + // Uplink: Map temperature from Port 2 + public static final AttributeDescriptor TEMPERATURE = new AttributeDescriptor<>("temperature", ValueType.NUMBER, + new MetaItem<>(MetaItemType.READ_ONLY), + new MetaItem<>(MetaItemType.AGENT_LINK_CONFIG, new ValueType.ObjectMap() {{ + putAll(Map.of( + "uplinkPort", 2, + // For ChirpStack use $.object... + // For The Things Stack use $.uplink_message.decoded_payload... + "valueFilterJsonPath", "$.object.Temperature" + )); + }}) + ).withUnits(UNITS_CELSIUS); + + // Downlink: Map switch to Base64 payloads on Port 4 + public static final AttributeDescriptor SWITCH = new AttributeDescriptor<>("switch", ValueType.BOOLEAN, + new MetaItem<>(MetaItemType.AGENT_LINK_CONFIG, new ValueType.ObjectMap() {{ + putAll(Map.of( + "downlinkPort", 4, + "writeValueConverter", new ValueType.ObjectMap() {{ + putAll(Map.of( + "TRUE", "DAE=", + "FALSE", "DAA=" + )); + }} + )); + }}) + ); + + public static final AttributeDescriptor DEV_EUI = new AttributeDescriptor<>("devEUI", ValueType.TEXT, new MetaItem<>(MetaItemType.READ_ONLY)); + public static final AttributeDescriptor VENDOR_ID = new AttributeDescriptor<>("vendorId", ValueType.TEXT, new MetaItem<>(MetaItemType.READ_ONLY)); + public static final AttributeDescriptor MODEL_ID = new AttributeDescriptor<>("modelId", ValueType.TEXT, new MetaItem<>(MetaItemType.READ_ONLY)); + public static final AttributeDescriptor FIRMWARE_VERSION = new AttributeDescriptor<>("firmwareVersion", ValueType.TEXT, new MetaItem<>(MetaItemType.READ_ONLY)); + public static final AttributeDescriptor SUPPORTS_CLASS_C = new AttributeDescriptor<>("supportsClassC", ValueType.BOOLEAN, new MetaItem<>(MetaItemType.READ_ONLY)); + + public static final AssetDescriptor DESCRIPTOR = new AssetDescriptor<>("molecule-co2", "f18546", LoRaWanAsset.class); + + protected LoRaWanAsset() { + } + + public LoRaWanAsset(String name) { + super(name); + } +} +``` + +### Downlink Payload Encoding + +When sending commands to a LoRaWAN device, the network server (ChirpStack or The Things Stack) requires the raw binary payload to be formatted as a **Base64 encoded string**. + +The `writeValueConverter` is used to perform this data transformation. It maps high-level OpenRemote attribute values to the specific Base64 strings required by the device's hardware commands. + +In the example above, the device expects a 2-byte binary command to toggle a switch: + +| Attribute Value | Raw Hex Command | Base64 String | Action | +| :--- | :--- |:---| :--- | +| `TRUE` | `0x0C01` | `DAE=` | Switch On | +| `FALSE` | `0x0C00` | `DAA=` | Switch Off | + +### Device Metadata Attributes + +To successfully manage LoRaWAN devices, the Asset Type must include specific attributes for identification and hardware context. + +#### Mandatory: DevEUI +The `devEUI` attribute is **mandatory**. The agent uses this unique 64-bit identifier to match the physical device on the network server (ChirpStack or The Things Stack) to the corresponding asset in OpenRemote. + +#### Optional Attributes +The following attributes are optional. These are typically populated during the **CSV Import** process: + +* **vendorId**: The manufacturer of the device (e.g., *Dragino* or *Milesight*). +* **modelId**: The specific hardware model or part number (e.g., *LHT65*). +* **firmwareVersion**: The version of the software running on the device. +* **supportsClassC**: A boolean flag indicating if the device supports Class C (always-on) communication. \ No newline at end of file diff --git a/docs/user-guide/agents-protocols/chirpstack.md b/docs/user-guide/agents-protocols/chirpstack.md new file mode 100644 index 00000000..15c6a343 --- /dev/null +++ b/docs/user-guide/agents-protocols/chirpstack.md @@ -0,0 +1,126 @@ +--- +sidebar_position: 3 +--- + +import AssetTypes from './_lorawan-asset-types.md'; + +# ChirpStack + +The ChirpStack agent allows integration of LoRaWAN devices managed by a [ChirpStack](https://www.chirpstack.io/) Network Server. + +## How It Works + +The ChirpStack agent acts as a bridge between OpenRemote and a **ChirpStack Network Server** by utilizing two primary communication channels: + +### Message Exchange (MQTT) + +The agent connects to the **ChirpStack MQTT integration** for real-time data flow: +* **Uplink messages:** The agent subscribes to device events to receive sensor data. +* **Downlink messages:** The agent publishes to command topics to send configuration or control packets back to the end-devices. + +### Device Management (gRPC API) + +The agent utilizes the **ChirpStack gRPC API** to interact with the Network Server's management layer. This is specifically used for: +* **Auto-discovery:** The agent queries the API to list the **devices** registered in ChirpStack. +* **Device Profiles:** For each discovered device, the agent retrieves its related **device profile**. This allows OpenRemote to understand the device type during the automatic asset creation process. + +## Agent configuration + +The following describes the supported agent configuration attributes: + +| Attribute | Description | Required | Default | +|-----------------|-----------------------------------------------------------------------------------------------------------------|----------|--------------------------------------------------| +| `MQTTHost` | The hostname or IP address of the ChirpStack MQTT broker. | Y | - | +| `MQTTPort` | The network port for the MQTT connection. | Y | - | +| `clientId` | The unique identifier for this agent's session on the MQTT broker. | Y | - | +| `secureMode` | Boolean flag indicating if the MQTT connection should use TLS/SSL encryption. | N | false | +| `resumeSession` | Boolean flag indicating if the MQTT broker should persist the session and queue messages during agent downtime. | N | false | +| `subscribeQos` | MQTT Quality of Service level for receiving uplinks (0, 1, 2). | N | 0 | +| `publishQos` | MQTT Quality of Service level for sending downlinks (0, 1, 2). | N | 0 | +| `host` | The hostname or IP address of the ChirpStack gRPC API. | Y | - | +| `port` | The network port for the ChirpStack gRPC API. | N | secureGRPC==true -> 443, secureGRPC==false -> 80 | +| `applicationId` | The UUID of the ChirpStack application to be integrated. | Y | - | +| `apiKey` | A ChirpStack API Key used to authenticate the gRPC connection. | Y | - | +| `secureGRPC` | Boolean flag to enable gRPC TLS/SSL encryption. | N | false | + + +**Example:** + +```yaml +MQTTHost: 192.168.1.50 +MQTTPort: 1883 +clientId: or_chirpstack_agent_1 +secureMode: false +resumeSession: true +host: 192.168.1.50 +port: 8080 +applicationId: 7d809e33-d2ad-4ef1-aac8-2be67501c4d3 +apiKey: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhd... +secureGRPC: false +``` + +## Device to Asset Mapping + +To ensure the ChirpStack Agent can automatically create and configure assets, it must be able to map a ChirpStack device to a specific **OpenRemote Asset Type**. + +### Auto-discovery Mapping (ChirpStack Tags) + +For devices discovered via the gRPC API, the mapping is defined within the **ChirpStack Device Profile**. By adding a specific tag to the profile, you provide the agent with the Asset Type template required to create the asset in OpenRemote: + +| Tag Key | Tag Value | +| :--- | :--- | +| `openremote-asset-type` | The exact name of the **OpenRemote Asset Type** (e.g., `WeatherStationAsset`). | + +During auto-discovery, the agent reads this tag and creates the corresponding asset in OpenRemote. + +### CSV Import Mapping +When importing devices via a CSV file, the asset type is defined directly within the file. The CSV must include a column that specifies the **Asset Type name** for each device record. + +For a detailed breakdown of the required columns and an example file, see the [CSV Import Format](#csv-import-format) section below. + +## MQTT Agent Link Automation + +The ChirpStack agent handles the transmission of sensor data (**uplinks**) and commands (**downlinks**) via the **MQTT protocol**. To eliminate the need for manual configuration of every attribute, the agent automatically provisions these communication links during the discovery or import process. + +### Automatic Provisioning Logic + +Once a matching Asset Type template is identified, the agent configures the **MQTT Agent Links** based on the following workflow: + +1. **Meta item Lookup**: The agent scans the attributes of the selected Asset Type for a meta item named `AGENT_LINK_CONFIG`. For details on the format of this meta item, see [LoRaWAN Asset Types](#lorawan-asset-types). +2. **Link Creation**: The agent uses the template defined in the meta item to generate the specific MQTT topics and data filters required for that individual device. + +### Attributes Configured + +The following attributes are automatically populated on the resulting agent links to handle the MQTT protocol logic: + +* **MQTT Specific**: `subscriptionTopic`, `publishTopic`. +* **Generic Data Processing**: `valueFilters`, `messageMatchPredicate`, `messageMatchFilters`, `writeValue`, and `writeValueConverter`. + +## CSV Import Format + +Bulk provisioning allows you to create many assets at once. The agent processes each row to instantiate a new asset, using the specified `assetType` to identify which **template** to apply for automatic link configuration. + +### CSV Column Structure + +> **Note:** The CSV file must **not** contain a header row. The agent identifies the data based on the specific column order defined below. + +| Col | Required | Attribute | Description | +| :--- |:---| :--- |:---| +| 1 | **Y** | `devEUI` | The 16-character hexadecimal unique identifier.| +| 2 | N | `deviceName` | The display name for the asset in OpenRemote.| +| 3 | **Y** | `assetType` | The exact name of the **Asset Type template** (case-sensitive).| +| 4 | N | `vendorId` | The manufacturer of the device.| +| 5 | N | `modelId` | The specific hardware model identifier.| +| 6 | N | `firmwareVersion` | The software version on the device.| + +### Example File Content + +```csv +a84043d8d1842175,Dragino LHT65 1,DraginoLHT65Asset,dragino,lht65,1.8 +a84043d8d1842176,Dragino LHT65 2,DraginoLHT65Asset,dragino,lht65,1.8 +``` + + + +### Reference Documentation +* **[Agent Link Overview](overview.md)**: Deep dive into generic OpenRemote attributes like filters and predicates. \ No newline at end of file diff --git a/docs/user-guide/agents-protocols/disabled-protocols/_category_.json b/docs/user-guide/agents-protocols/disabled-protocols/_category_.json index 59351e07..890b6420 100644 --- a/docs/user-guide/agents-protocols/disabled-protocols/_category_.json +++ b/docs/user-guide/agents-protocols/disabled-protocols/_category_.json @@ -1,6 +1,6 @@ { "label": "Disabled Protocols", - "position": 20, + "position": 21, "link": { "type": "generated-index" } diff --git a/docs/user-guide/agents-protocols/email.md b/docs/user-guide/agents-protocols/email.md index 7c229969..679baf0a 100644 --- a/docs/user-guide/agents-protocols/email.md +++ b/docs/user-guide/agents-protocols/email.md @@ -1,5 +1,5 @@ --- -sidebar_position: 3 +sidebar_position: 4 --- # E-mail diff --git a/docs/user-guide/agents-protocols/http.md b/docs/user-guide/agents-protocols/http.md index 1e2f827e..70c530f9 100644 --- a/docs/user-guide/agents-protocols/http.md +++ b/docs/user-guide/agents-protocols/http.md @@ -1,5 +1,5 @@ --- -sidebar_position: 4 +sidebar_position: 5 --- # HTTP diff --git a/docs/user-guide/agents-protocols/knx.md b/docs/user-guide/agents-protocols/knx.md index 70eca5c8..e45a1f5d 100644 --- a/docs/user-guide/agents-protocols/knx.md +++ b/docs/user-guide/agents-protocols/knx.md @@ -1,5 +1,5 @@ --- -sidebar_position: 5 +sidebar_position: 6 --- # KNX diff --git a/docs/user-guide/agents-protocols/lora.md b/docs/user-guide/agents-protocols/lora.md index 15dc5fcf..c9a3bcd0 100644 --- a/docs/user-guide/agents-protocols/lora.md +++ b/docs/user-guide/agents-protocols/lora.md @@ -1,14 +1,22 @@ --- -sidebar_position: 6 +sidebar_position: 7 --- # LoRa -OpenRemote supports LoRa integration. You can connect OpenRemote to the most popular LoRa network servers (e.g. ChirpStack and TTN), using their documented APIs. As example we have worked out this [Tutorial: connecting to LoRaWAN sensor data from Chirpstack](../../tutorials/receive-lorawan-sensor-data-from-chirpstack.md). +The documentation on this page focuses on custom protocol implementations built directly on top of the **LoRa PHY (Physical Layer)**, such as mesh networks, rather than standard LoRaWAN network server integrations. + +:::note +For standard **LoRaWAN** network server support, please refer to the following protocol documentation: +* **[ChirpStack](chirpstack.md)** +* **[The Things Stack (TTS)](the-things-stack.md)** + +If you require a technical deep dive into manual configuration of MQTT agent links, see the **[Manual ChirpStack Tutorial](../../tutorials/receive-lorawan-sensor-data-from-chirpstack.md)**. +::: ## Proof of concept for LoRa mesh network for GPS trackers -In addition, a couple of students have worked on a generic way to use LoRa to connect several devices in a mesh network and link these through a Protocol Agent with OpenRemote. In the specific application they have developed a Range of LoRa GPS trackers which allow for integrating all these trackers, including their live location within OpenRemote. +A couple of students have worked on a generic way to use LoRa to connect several devices in a mesh network and link these through a Protocol Agent with OpenRemote. In the specific application they have developed a Range of LoRa GPS trackers which allow for integrating all these trackers, including their live location within OpenRemote. Both the firmware running on the individual devices, as well as the Protocol Agent for OpenRemote is available as a separate project ['or-loratrackers'](https://github.com/openremote/or-loratrackers). It includes a generic asset and attribute model such that the code can be applied for any kind of application and asset model in which you like to build your own connected network of devices leveraging a mesh. diff --git a/docs/user-guide/agents-protocols/modbus.md b/docs/user-guide/agents-protocols/modbus.md index 82dccfc1..64a4a8ca 100644 --- a/docs/user-guide/agents-protocols/modbus.md +++ b/docs/user-guide/agents-protocols/modbus.md @@ -1,5 +1,5 @@ --- -sidebar_position: 7 +sidebar_position: 8 --- # Modbus diff --git a/docs/user-guide/agents-protocols/mqtt.md b/docs/user-guide/agents-protocols/mqtt.md index ba5584b7..a2ec9e73 100644 --- a/docs/user-guide/agents-protocols/mqtt.md +++ b/docs/user-guide/agents-protocols/mqtt.md @@ -1,5 +1,5 @@ --- -sidebar_position: 8 +sidebar_position: 9 --- # MQTT diff --git a/docs/user-guide/agents-protocols/openweathermap.md b/docs/user-guide/agents-protocols/openweathermap.md index 7c2c2b26..52078b3d 100644 --- a/docs/user-guide/agents-protocols/openweathermap.md +++ b/docs/user-guide/agents-protocols/openweathermap.md @@ -1,5 +1,5 @@ --- -sidebar_position: 17 +sidebar_position: 19 --- # OpenWeatherMap diff --git a/docs/user-guide/agents-protocols/partner-integrations.md b/docs/user-guide/agents-protocols/partner-integrations.md index 93adbc8b..ecbe1c29 100644 --- a/docs/user-guide/agents-protocols/partner-integrations.md +++ b/docs/user-guide/agents-protocols/partner-integrations.md @@ -1,5 +1,5 @@ --- -sidebar_position: 17 +sidebar_position: 20 --- # Partner Integrations diff --git a/docs/user-guide/agents-protocols/serial.md b/docs/user-guide/agents-protocols/serial.md index d42e0c0d..d348e7a0 100644 --- a/docs/user-guide/agents-protocols/serial.md +++ b/docs/user-guide/agents-protocols/serial.md @@ -1,5 +1,5 @@ --- -sidebar_position: 11 +sidebar_position: 12 --- # Serial diff --git a/docs/user-guide/agents-protocols/simulator.md b/docs/user-guide/agents-protocols/simulator.md index 9d17b76f..8ebc55d4 100644 --- a/docs/user-guide/agents-protocols/simulator.md +++ b/docs/user-guide/agents-protocols/simulator.md @@ -1,5 +1,5 @@ --- -sidebar_position: 9 +sidebar_position: 10 --- # Simulator diff --git a/docs/user-guide/agents-protocols/snmp.md b/docs/user-guide/agents-protocols/snmp.md index 6798cb4a..c01d628c 100644 --- a/docs/user-guide/agents-protocols/snmp.md +++ b/docs/user-guide/agents-protocols/snmp.md @@ -1,5 +1,5 @@ --- -sidebar_position: 10 +sidebar_position: 11 --- # SNMP diff --git a/docs/user-guide/agents-protocols/tcp.md b/docs/user-guide/agents-protocols/tcp.md index b09f9717..538215c0 100644 --- a/docs/user-guide/agents-protocols/tcp.md +++ b/docs/user-guide/agents-protocols/tcp.md @@ -1,5 +1,5 @@ --- -sidebar_position: 12 +sidebar_position: 13 --- # TCP diff --git a/docs/user-guide/agents-protocols/the-things-stack.md b/docs/user-guide/agents-protocols/the-things-stack.md new file mode 100644 index 00000000..a7ad2ec8 --- /dev/null +++ b/docs/user-guide/agents-protocols/the-things-stack.md @@ -0,0 +1,148 @@ +--- +sidebar_position: 14 +--- + +import AssetTypes from './_lorawan-asset-types.md'; + +# The Things Stack (TTS) + +The TTS agent allows integration of LoRaWAN devices managed by [The Things Stack (V3)](https://www.thethingsindustries.com/docs/the-things-stack/). + +## How It Works + +The TTS agent acts as a bridge between OpenRemote and a **The Things Stack Network Server** by utilizing two primary communication channels: + +### Message Exchange (MQTT) + +The agent connects to the **TTS MQTT integration** for real-time data flow: +* **Uplink messages:** The agent subscribes to device events to receive sensor data. +* **Downlink messages:** The agent publishes to command topics to send configuration or control packets back to the end-devices. + +### Device Management and Discovery (gRPC API) + +The agent utilizes the **The Things Stack gRPC API** as the primary interface for managing device lifecycles and metadata. This is used for: + +* **Real-time auto-discovery:** Instead of periodic polling, the agent listens to the gRPC events stream. When a device sends an uplink or performs a `Join`, the agent detects it instantly. +* **Attribute-based Template Identification:** Once a device is detected, the agent queries the gRPC API to retrieve the device's specific metadata. It looks for a custom **TTS device attribute** that defines the **OpenRemote Asset Type**, allowing the agent to apply the correct template automatically. + +## Agent configuration + +The following describes the supported agent configuration attributes: + +| Attribute | Description | Required | Default | +|--------------------|----------------------------------------------------------------------------------------------------------------|----------|--------------------------------------------------| +| `MQTTHost` | The hostname or IP address of the TTS MQTT broker. | Y | - | +| `MQTTPort` | The network port for the MQTT connection. | Y | - | +| `clientId` | The unique identifier for this agent's session on the MQTT broker. | Y | - | +| `secureMode` | Boolean flag indicating if the MQTT connection should use TLS/SSL encryption. | N | false | +| `usernamePassword` | MQTT credentials (JSON format - see below) | Y | - | +| `resumeSession` | Boolean flag indicating if the MQTT broker should persist the session and queue messages during agent downtime.| N | false | +| `subscribeQos` | MQTT Quality of Service level for receiving uplinks (0, 1, 2). | N | 0 | +| `publishQos` | MQTT Quality of Service level for sending downlinks (0, 1, 2). | N | 0 | +| `host` | The hostname or IP address of the TTS gRPC API. | Y | - | +| `port` | The network port for the TTS gRPC API. | N | secureGRPC==true -> 443, secureGRPC==false -> 80 | +| `applicationId` | The identifier of the TTS application to be integrated. | Y | - | +| `tenantId` | TTS tenant identifier. | Y | - | +| `apiKey` | TTS API key used to authenticate the gRPC connection. | Y | - | +| `secureGRPC` | Boolean flag to enable gRPC TLS/SSL encryption. | N | true | + +### MQTT Credentials Format + +The TTS agent requires the `usernamePassword` attribute to be provided in a specific JSON format. Note that the **username** is the combined Application and Tenant ID, while the **password** is your TTS API Key. + +**Format:** + +```json +{ + "username": "{applicationId}@{tenantId}", + "password": "{apiKey}" +} +``` + +**Example:** + +```yaml +MQTTHost: eu1.cloud.thethings.network +MQTTPort: 8883 +clientId: or_tts_agent_1 +secureMode: true +usernamePassword: > + { + "username": "parking-sensors@ttn", + "password": "NNSXS.FUFJDFQHVP7SRG2FAE3NS26LVDQQMFTKVVBPCGI.YHI2JQ6..." + } +resumeSession: true +host: eu1.cloud.thethings.network +port: 443 +applicationId: parking-sensors +tenantId: ttn +apiKey: NNSXS.FUFJDFQHVP7SRG2FAE3NS26LVDQQMFTKVVBPCGI.YHI2JQ6... +secureGRPC: true +``` + +## Device to Asset Mapping + +To ensure the TTS agent can automatically create and configure assets, it must map a TTS device to a specific **OpenRemote Asset Type**. + +### Auto-discovery Mapping (TTS Attributes) + +For devices discovered via the gRPC events stream, the mapping is defined within the **TTS End Device Attributes**. By adding a specific attribute to the device in the TTS Console, you provide the agent with the **Asset Type template** required to create the asset in OpenRemote: + +| Attribute Key | Attribute Value | +| :--- | :--- | +| `openremote-asset-type` | The exact name of the **OpenRemote Asset Type** (e.g., `WeatherStationAsset`). | + +During auto-discovery, the agent reads this TTS device attribute and creates the corresponding asset in OpenRemote. + +### CSV Import Mapping + +When importing devices via a CSV file, the asset type is defined directly within the file. The CSV must include a column that specifies the **Asset Type name** for each device record. + +For a detailed breakdown of the required columns and an example file, see the [CSV Import Format](#csv-import-format) section below. + +## MQTT Agent Link Automation + +The TTS agent handles the transmission of sensor data (**uplinks**) and commands (**downlinks**) via the **MQTT protocol**. To eliminate the need for manual configuration of every attribute, the agent automatically provisions these communication links during the discovery or import process. + +### Automatic Provisioning Logic + +Once a matching Asset Type template is identified, the agent configures the **MQTT Agent Links** based on the following workflow: + +1. **Meta item Lookup**: The agent scans the attributes of the selected Asset Type for a meta item named `AGENT_LINK_CONFIG`. For details on the format of this meta item, see [LoRaWAN Asset Types](#lorawan-asset-types). +2. **Link Creation**: The agent uses the template defined in the meta item to generate the specific MQTT topics and data filters required for that individual device. + +### Attributes Configured + +The following attributes are automatically populated on the resulting agent links to handle the MQTT protocol logic: + +* **MQTT Specific**: `subscriptionTopic`, `publishTopic`. +* **Generic Data Processing**: `valueFilters`, `messageMatchPredicate`, `messageMatchFilters`, `writeValue`, and `writeValueConverter`. + +## CSV Import Format + +Bulk provisioning allows you to create many assets at once. The agent processes each row to instantiate a new asset, using the specified `assetType` to identify which **template** to apply for automatic link configuration. + +### CSV Column Structure + +> **Note:** The CSV file must **not** contain a header row. The agent identifies the data based on the specific column order defined below. + +| Col | Required | Attribute | Description | +| :--- |:---| :--- |:---| +| 1 | **Y** | `devEUI` | The 16-character hexadecimal unique identifier.| +| 2 | N | `deviceName` | The display name for the asset in OpenRemote.| +| 3 | **Y** | `assetType` | The exact name of the **Asset Type template** (case-sensitive).| +| 4 | N | `vendorId` | The manufacturer of the device.| +| 5 | N | `modelId` | The specific hardware model identifier.| +| 6 | N | `firmwareVersion` | The software version on the device.| + +### Example File Content + +```csv +a84043d8d1842175,Dragino LHT65 1,DraginoLHT65Asset,dragino,lht65,1.8 +a84043d8d1842176,Dragino LHT65 2,DraginoLHT65Asset,dragino,lht65,1.8 +``` + + + +### Reference Documentation +* **[Agent Link Overview](overview.md)**: Deep dive into generic OpenRemote attributes like filters and predicates. \ No newline at end of file diff --git a/docs/user-guide/agents-protocols/udp.md b/docs/user-guide/agents-protocols/udp.md index c774b0f8..6d36b255 100644 --- a/docs/user-guide/agents-protocols/udp.md +++ b/docs/user-guide/agents-protocols/udp.md @@ -1,5 +1,5 @@ --- -sidebar_position: 13 +sidebar_position: 15 --- # UDP diff --git a/docs/user-guide/agents-protocols/velbus.md b/docs/user-guide/agents-protocols/velbus.md index 135ff7a1..2b05b04d 100644 --- a/docs/user-guide/agents-protocols/velbus.md +++ b/docs/user-guide/agents-protocols/velbus.md @@ -1,5 +1,5 @@ --- -sidebar_position: 14 +sidebar_position: 16 --- # Velbus diff --git a/docs/user-guide/agents-protocols/websocket-agent.md b/docs/user-guide/agents-protocols/websocket-agent.md index a24a42b9..36b2f5b0 100644 --- a/docs/user-guide/agents-protocols/websocket-agent.md +++ b/docs/user-guide/agents-protocols/websocket-agent.md @@ -1,5 +1,5 @@ --- -sidebar_position: 15 +sidebar_position: 17 --- # WebSocket diff --git a/docs/user-guide/agents-protocols/z-wave.md b/docs/user-guide/agents-protocols/z-wave.md index 01b61bec..3ceab5bd 100644 --- a/docs/user-guide/agents-protocols/z-wave.md +++ b/docs/user-guide/agents-protocols/z-wave.md @@ -1,5 +1,5 @@ --- -sidebar_position: 16 +sidebar_position: 18 --- # Z-Wave