---
description: >-
  This section explain how to add new sensors to the webhook server by editing
  the formatData function and addData function in the index.js file.
---

# Adding new sensors

## WEBHOOKS

If you need more information about the webhooks sent from the things stack you can checkout the documentation [here](https://www.thethingsindustries.com/docs/integrations/webhooks/).&#x20;

You can also learn more about the JSON file sent by the webhook [here](https://www.thethingsindustries.com/docs/integrations/payload-formatters/javascript/uplink/)

We also use a custom payload formatting script which you can read more about [here ](https://app.gitbook.com/s/49mLPiixazXEA2ZE0yyK/payload-formatting-script)

## The `formatData` function

### The JSON file

The format data function takes in the JSON file sent by things stack webhook and formats it into an array that makes it easier for the `addData` function to insert data into the database. \
\
The array returned a the end of the function contains the variables sensorData, sensorType, SensorboxConnector and sensorboxID. To get data into these variables you need to get them from the JSON file. \
\
The JSON file from things stack is formatted in this way.

```json
{
  {
    "f_port": 1,
    "frm_payload": "AAAAAAAAAAA=",
    "decoded_payload": {
      "dataArray": ["0","0","0","0","0","0"],
      "plugg": "0",
      "sensor": "0"}
  },
  "rx_metadata": [{
        "gateway_ids": {
          "gateway_id": "test"
        },
        "rssi": 42,
        "channel_rssi": 42,
        "snr": 4.2
  }]
}
//there is more in the message sent from things stack 
//but we dont need more of the message than this
```

To get data into the variables you use a `.` to go index the key-value pairs. This is done like this in the `formatData` function.

* `sensorData = data.uplink_message.decoded_payload.dataArray` \
  `//from the example above this will be an array ["0","0","0","0","0","0"]`
* `sensorType =  data.uplink_message.decoded_payload.sensor`\
  `//from the example above this will be "0"`
* `sensorboxConnector = data.uplink_message.decoded_payload.plugg`\
  `//from the example above this will be "0"`
* `sensorboxID = data.end_device_ids.device_id`\
  `//from the example above this will be "0"`

### Adding new sensors to the function

To add new sensors to the function you need to add a new case in the switch with the sensor type as the case. \
\
The case should format the hexadecimal values in the `sensorData` array into usable values for the database.\
\
The webserver contains three useful functions for formatting the hexadecimal values, `hexToDecimal` , `hexToNegOrPosNum` and the `float-array-to-string`.&#x20;

* `hexToDecimal() //takes in a hex value and converts it to a decimal value`
* `hexToNegOrPosNum() //takes in a 4 byte hex value as a string and converts it to either a negative or positive decimal`
* [`float-to-array-to-string`](https://www.npmjs.com/package/float-array-to-string)`//not used in this version of the server but converts an 4 byte array of hex values into a float value and vice versa`&#x20;

Three examples using the `hexToDecimal` function, the `hexToNegOrPosNum` function and the `float-array-to-string` function.

```javascript
case 48: //Soil humidity
    sensorData = hexToDecimal(sensorData[0]+sensorData[1]) //takes the hex values from sensordata combines them and turns them into decimal 
    returnArray = [sensorType,sensorboxID,sensorboxConnector,sensorData]
    break;
```

```javascript
case 61: //SCD30 Sensor
    //diffrent sensor values
    var co2Sensor = hexToDecimal(sensorData[0]+sensorData[1]) //takes hex values at place [0],[1],[2] and [3] from sensorData and decodes them to a float value
    var tempSensor = hexToNegPosNum(sensorData[2]+sensorData[3]+sensorData[4]+sensorData[5]) //takes hex values at place [4],[5],[6] and [7] from sensorData and decodes them to a float value
    var humiditySensor = hexToDecimal(sensorData[6]+sensorData[7])  //takes hex values at place [8],[9],[10] and [11] from sensorData and decodes them to a float value 
```

```javascript
const floatConverter = require("float-array-to-string") //float-array-to-string is declared further up in the code 

case 61: //SCD30 Sensor
    var co2Sensor = floatConverter.decodeFloatArr(sensorData.slice(0,3)) //takes hex values at place [0],[1],[2] and [3] from sensorData and decodes them to a float value
    var tempSensor = floatConverter.decodeFloatArr(sensorData.slice(4,7)) //takes hex values at place [4],[5],[6] and [7] from sensorData and decodes them to a float value
    var humiditySensor = floatConverter.decodeFloatArr(sensorData.slice(7,11)) //takes hex values at place [8],[9],[10] and [11] from sensorData and decodes them to a float value
    sensorData = [co2Sensor,tempSensor,humiditySensor] //places co2, temp and humidity data into sensordata
    returnArray = [sensorType,sensorboxID,sensorboxConnector,sensorData] //returns [sensorType, sensorboxID,sensorboxConnector, sensorData[float,float,float],]
    break;
```

At the end of the function you need to return the array in this order for the function to be compatible with the `addData` function.

```javascript
returnArray = [sensorType, sensorboxID, sensorboxConnector, sensorData]
```

## The `addData` function

The `addData` function queries the database and inserts the data from the `data` variable. \


To add a new sensor you need to add a new case with the sensor address as the case. The `insertRow` variable in the case should be a SQL query to insert data into the database in this format.

* `DATA[0] = sensorbox_type`
* `DATA[1] = sensorbox_ID`
* `DATA[2] = sensorbox_connector`
* `DATA[3] = sensor value`

{% code lineNumbers="true" %}
```javascript
case "sensor adress": //inserts data into the database and prints it to the console
    insertRow = await client.query(`INSERT INTO "Skjetleingard_test"(sensor_type,sensorbox_id,sensorbox_connector,value) VALUES(${data[0]},'${data[1]}',${data[2]},${data[3]});`)
    console.log(`Inserted ${insertRow} row`);
    break;
```
{% endcode %}

If you get more than one value from your sensor the `formatData` function will return an array as `DATA[3]` to insert the values into the database then you could do something like this.

```javascript
insertRow = await client.query(`INSERT INTO "Skjetleingard_test"(sensor_type, sensorbox_id, sensorbox_connector, value1, value2) VALUES(${data[0]},${String(data[1])},${data[2]},${data[3][0]},${data[3][1]});`)
```

#### Normal errors:

If you run the webserver and get an message in the console that say `error at "xxxxxxx"` or  `column does not exist`. You need to remember to add single quotes around the `data[1]` variable that contains the sensorbox\_id like this `'${data[1]}'`
