# Access Gateway Metadata

## Concept

You can access the global variable `normalizedPayload` which contains the following metadata:

```javascript
{
    "deveui": string, // The device's DevEUI
    "port": number, // The message's port
    "counter": number,
    "frequency": number, // GHz
    "data_rate": string, // Data rate according to https://blog.dbrgn.ch/2017/6/23/lorawan-data-rates/
    "coding_rate": string,
    "gateways": [
        "id": string,
        "datetime": date,
        "channel": number,
        "rssi": number,
        "snr": number
    ]
}
```

This data is extracted from the LoRaWAN Network Server as being forwarded to Datacake over the Webhook. This information is normalized, meaning no matter whether you use TTN, TTI, Loriot, ChirpStack, or Wanesy, the information is always equally available and always formatted in the same way.&#x20;

### Raw Metadata

If you rather want to access the raw payload received from the LNS, you can do so via the global `rawPayload` variable.

{% hint style="warning" %}
Please note that when you access the `rawPayload`, the information is not normalized and the content of `rawPayload` looks different between different LoRaWAN Network Server!
{% endhint %}

## Example Usage

In the following snippet, you find an example of how to read the Metadata from your Payload and how to bring that into your Datacake Payload Decoder section.

```javascript
function Decoder(payload, port) {
    
    // Output normalized Payload
    console.log(JSON.stringify(normalizedPayload,0,4));
    
    // Output raw payload coming from webhook of your LNS
    console.log(JSON.stringify(rawPayload,0,4));    
    
    // Extract RSSI and Data-Rate from normalized Payload:
    // As being "normalized" this works between all LNS:
    // Including safety check so that these values really exist
    var LORA_RSSI = (!!normalizedPayload.gateways && !!normalizedPayload.gateways[0] && normalizedPayload.gateways[0].rssi) || 0;
    var LORA_SNR = (!!normalizedPayload.gateways && !!normalizedPayload.gateways[0] && normalizedPayload.gateways[0].snr) || 0;
    var LORA_DATARATE = normalizedPayload.data_rate;    
    
    // extract timestamp from gateway
    var ts = rawPayload.recvTime; // Kerlink Wanesy
    
    // use normalized payload - NOTE: must have at least one Gateway!
    var ts = normalizedPayload.gateways[0]["datetime"];
    
    // Build up an array that can be used to forward it onto Datacake:
    var decoded = [
        {
            field: "LORA_RSSI",
            value: LORA_RSSI,
            timestamp: ts            
        },
        {
            field: "LORA_DATARATE",
            value: LORA_DATARATE,
            timestamp: ts
        }
    ];
    
    return decoded;
}
```

#### Alternate Version

```javascript
function Decoder(bytes, port) {
    
    var decoded = {};
    
    decoded.battery = ((bytes[0] << 8 | bytes[1]) & 0x3FFF) / 1000;
    decoded.distance = bytes[2] << 8 | bytes[3];
    decoded.temperature = (bytes[4] << 8 | bytes[5]) / 10.0;
    
    // Extract Gateway Information
    
    try {
        
        decoded.LORA_RSSI = (!!normalizedPayload.gateways && !!normalizedPayload.gateways[0] && normalizedPayload.gateways[0].rssi) || 0;
        decoded.LORA_SNR = (!!normalizedPayload.gateways && !!normalizedPayload.gateways[0] && normalizedPayload.gateways[0].snr) || 0;
        decoded.LORA_DATARATE = normalizedPayload.data_rate;   
        
    } catch (e) {
        
        console.log(JSON.stringify(e));
    }
    
    return decoded;

}
```

### Create corresponding fields in Database

In order to store those Metadata-Fields, you can create new Fields on your Device and have historical Data for each field that you forward and store. Here is how this looks for the above example:

![](/files/-MC6ZiTga6nZEM-s0C6i)

## Extract Location

Some LNS (depending also on settings) embed gateway information in uplinks and send it with the webhook forward to Datacake.&#x20;

You can use the `rawPayload` variable to access it and forward it onto a location field on your device.

### Example

#### The Things Network / The Things Stack

Because we are using the `rawPayload` Object, the following example only works with The Things Stack LNS, aka The Things Network

```javascript
function Decoder(bytes, port) {

    var datacakeFields = [];
    
    try {

        // Please note that there can be more than just one Gateway
        // in the webhook data. This examples always uses the first.

        var lat = rawPayload.uplink_message.rx_metadata[0].location.latitude
        var lon = rawPayload.uplink_message.rx_metadata[0].location.longitude

        // in order to be able to forward location data to Datacake
        // We need to build a tuple that contains latitude + longitude
        // surrounded by parenthesis

        var location = "(" + lat + "," + lon + ")";
    
        // now forward the data to datacake
        // please make sure to create a location field called GATEWAY_LOCATION
        
        datacakeFields.push({
            field: "GATEWAY_LOCATION",
            value: location
        });
     
    } catch (e) {
        console.log("Error fetching location. Probably gateway data missing.");
    }
    
    return datacakeFields;
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.datacake.de/lorawan/payload-decoders/access-gateway-metadata.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
