# Format conventions and examples

Eliona offers powerful tools such as **JSONPath** and **MQTT wildcards**to dynamically and precisely assign incoming data to the correct assets. While JSONPath enables flexible selection of values from JSON data, MQTT wildcards allow the use of dynamic values from topic structures. This documentation shows how you can use both methods effectively to optimize your data processing.

## JSONPath convention

JSONPath is a syntax for selecting and processing values in a JSON document. The basic structure and symbols of JSONPath:

1. **`$`**: The root node of the JSON document.
2. **`.`**: Access to a child element.
3. **`[]`**: Enables access to an element by index or condition.
4. **`?()`**: Filter expression to select elements based on a condition.
5. **`@`**: Represents the current element in the filter expression.
6. **`*`**: Wildcard to select all elements of an array or object.
7. **`..`**: Recursive access to find all instances of a specific name in the hierarchy.

***

## Example 1: Simple query from a JSON payload

**JSON data:**

```json
{
    "devices": [
        {
            "id": "A8032A13B850",
            "name": "WiFi Switch 4",
            "type": "ws2",
            "wifiSwitchTemp": 23.75
        },
        {
            "id": "F008D1C4B034",
            "name": "WiFi Switch 3",
            "type": "ws2",
            "wifiSwitchTemp": 23.93
        }
    ]
}
```

**JSONPath queries and results:**

1. **Query all device data**:\
   **JSONPath**: `$.devices[*]`\
   **Result**:

   ```json
   [
       {
           "id": "A8032A13B850",
           "name": "WiFi Switch 4",
           "type": "ws2",
           "wifiSwitchTemp": 23.75
       },
       {
           "id": "F008D1C4B034",
           "name": "WiFi Switch 3",
           "type": "ws2",
           "wifiSwitchTemp": 23.93
       }
   ]
   ```
2. **Query the temperature of all devices**:\
   **JSONPath**: `$.devices[*].wifiSwitchTemp`\
   **Result**:

   ```json
   [23.75, 23.93]
   ```
3. **Query a device with a specific ID**:\
   **JSONPath**: `$.devices[?(@.id=="A8032A13B850")]`\
   **Result**:

   ```json
   [
       {
           "id": "A8032A13B850",
           "name": "WiFi Switch 4",
           "type": "ws2",
           "wifiSwitchTemp": 23.75
       }
   ]
   ```
4. **Query only the temperature of a specific device**:\
   **JSONPath**: `$.devices[?(@.id=="A8032A13B850")].wifiSwitchTemp`\
   **Result**:

```json
[23.75]
```

<figure><img src="https://content.gitbook.com/content/Nyvwhz1kEMXcHf4HLuZ8/blobs/Aa1OZhTS6Gai4oMkkzNm/image.png" alt=""><figcaption><p>Example for when you want a specific device.</p></figcaption></figure>

***

## Example: Function to generate a GAI/related ID when the payload does not contain an identifier

If an incoming payload does not contain a unique identifier, or if the identifier depends on multiple elements in the payload, a custom function can be used to generate the identifier.

### Scenario: No identifier in the payload

Let’s imagine the following example for a payload:

```json
{
    "device": {
        "name": "WiFi Switch",
        "type": "ws2",
        "status": "active",
        "location": {
            "building": "Building_01",
            "floor": "Floor_02",
            "room": "Room_01"
        }
    }
}
```

In this example, the payload does not contain a direct identifier because there may be multiple WiFi switches, but the combination of **Buildings**, **floor** and **room** can be used to create a unique identifier.

### Solution: Create a function

Use a custom function in Eliona to generate the identifier from the components of the payload.

**Code example: Generate identifier** **from multiple fields**

```javascript
javascriptCode copyfunction parsePayloadCustom(json, context) {
    const input = JSON.parse(json);

    // Initialize object structure
    let obj = {
        "eliona": {
            "uin": null // The identifier is stored here
        }
    };

    // Check whether the required data is available
    if (
        input.device &&
        input.device.location &&
        input.device.location.building &&
        input.device.location.floor &&
        input.device.location.room
    ) {
        // Generate identifier from the fields in the payload
        obj.eliona.uin = `${input.device.location.building}_${input.device.location.floor}_${input.device.location.room}`;
    } else {
        // Fallback: set default value if fields are missing
        obj.eliona.uin = null;
    }

    return obj;
}
```

***

### Configuration in Eliona

1. **Create function:**
   * Go to the option **"Create function"** in the menu.
   * Give the function a name, e.g. `parsePayloadCustom`.
   * Add the above code in the **Code editor** it.
2. **Connect function with a format:**
   * In the "Configure format" menu, select the appropriate format.
   * Add the function using the button **"Attach function"** add.
3. Identifier **use:**

   * The format uses the generated identifier (`eliona.uin`) to assign incoming data to the correct asset. For this, either **Externally for the related ID or GAI** can be selected depending on where you want the ID to be.

   <img src="https://content.gitbook.com/content/Nyvwhz1kEMXcHf4HLuZ8/blobs/KOsoBsvBU9I5oqMcbYlV/image.png" alt="" data-size="original">

***

## Using MQTT wildcards for GAI/related ID creation

### **MQTT topic structure in the example:**

{% @mermaid/diagram content="graph TD
A(building\_01) --> B(building\_01/floor\_01)
A --> C(building\_01/floor\_02)
B --> D(building\_01/floor\_01/room\_01)
B --> E(building\_01/floor\_01/room\_02)
C --> F(building\_01/floor\_02/room\_01)
C --> G(building\_01/floor\_02/room\_02)
" %}

### **Wildcards in MQTT**

MQTT supports two wildcard types that can be used in topics:

1. **`+` (single-level wildcard)**
   * Represents "all values at this topic level".
   * Example:\
     The topic `building_01/+/room_01` matches the following topics:
     * `building_01/floor_01/room_01`
     * `building_01/floor_02/room_01`
2. **`#` (multi-level wildcard)**
   * Represents "all values from this level downward".
   * Can **only be used at the end** of a topic.
   * Example:\
     The topic `building_01/#` matches the following topics:
     * `building_01/floor_01`
     * `building_01/floor_01/room_01`
     * `building_01/floor_02/room_02`

***

### **How MQTT wildcards work**

* **`+`-wildcard:**\
  Each `+`-wildcard replaces exactly one part of the topic. If there are multiple `+`-wildcards in a topic, you can access them in Eliona using numbers (`1`, `2`, etc.).\
  Example: In the topic `building_01/+/+`, represents:
  * `1`: the first part replaced by `+` .
  * `2`: the second part replaced by `+` .
* **`#`-wildcard:**\
  Captures all values and levels from the position where it stands. Everything in the topic that takes the place of `#` can be referenced directly in Eliona via `#` .

***

### **Examples of using MQTT wildcards**

#### **Example 1: Using `#` to capture rooms**

**Subscription topic:**\
`building_01/#`

**Received message:**\
`building_01/floor_01/room_01`

**Configuration in Eliona:**

* **Identifier**: `#`

**Result:**\
The topic `floor_01/room_01` is used as the GAI/related ID.

***

### **Example 2: Using `+` to identify a level**

**Subscription topic:**\
`building_01/+/room_01`

**Received message:**\
`building_01/floor_02/room_01`

**Configuration in Eliona:**

* **Identifier**: `1`

**Result:**\
The value `floor_02` (the level replaced by the first `+` ) is used as the GAI/related ID.

***

### **Example 3: Combination of `+` and `#` to capture multiple levels**

**Subscription topic:**\
`building_01/+/+/#`

**Received message:**\
`building_01/floor_01/room_02/sensor_01`

**Configuration in Eliona:**

* **Identifier**:
  * `1` → `floor_01` (first `+`-wildcard)
  * `2` → `room_02` (second `+`-wildcard)
  * `#` → `sensor_01` (all values that replace `#` )

**Result:**\
The values `floor_01`, `room_02` and `sensor_01` can be used individually as the GAI/related ID.

***

## **Important notes**

1. **MQTT wildcards only work with topic mode:**\
   In identification, select **"Topic"** as shown in the following image:

   <figure><img src="https://content.gitbook.com/content/Nyvwhz1kEMXcHf4HLuZ8/blobs/7IRTIwEYsAKkSOUUI6S4/image.png" alt=""><figcaption></figcaption></figure>
2. **Automatic processing in Eliona:**
   * Eliona automatically replaces wildcards with the actual values of the topic.
   * No additional processing is required.
3. **Numbering of the `+`-wildcards note:**
   * Use the corresponding number (`1`, `2`, etc.) to access the specific values.
