###### tags: `TA Stuff 2021` `Pycom` `ESP32` # TTS-Ubidots In the previous [TTS tutorial](https://hackmd.io/@lnu-iot/rkWOVue6_), we left things off at sending payload/data. In this tutorial, you will learn how to visualize the data you send to TTS. ### Table of Contents [TOC] ## Create a Ubidots STEM Account First, you need to create your Ubidots stem account [here](https://ubidots.com/stem/). Once you're registered, you will be redirected to the following page: ![](https://i.imgur.com/gxc46Zz.png) ## Create a Ubidots Data Plugin Navigate to `Devices` and select `plugins`. :::warning Ubidots STEM accounts can only have one data plugin, so if you already have one configured for e.g. Helium, then remove it and create a new one. ::: To create a new Data Plugin, select the `Create Data Plugin` button and choose `The Things Stack`. ![](https://i.imgur.com/FBrOUlY.png) :::info There are two plugins available for TTS. The one we use in this tutorial is the one for receiving and decoding data from LoRaWAN devices. ::: Confirm your choice by pressing the turquoise right-arrow and select the `Default token` as your `Ubidots Token` from the drop-down menu. ![](https://i.imgur.com/UUmDmIQ.png) Now, finish the configuration by giving your plugin a name and description (in the next step). This is what you should see. ![](https://i.imgur.com/O7WqE7r.png) Give your plugin a few seconds to fire up and refresh the page. Now, you should see the pluging running. ## Create a TTS webhook Now that you have created a Ubidots Data Plugin, revisit your TTS application and navigate to `Integrations/Webhooks`. Select the `Add webhook` button located in the top-right corner and choose `Ubidots`. Give your webhook an appropriate name (can be anything). Then, navigate to `Devices->Plugins` in Ubidots and select your TTS plugin. Once there, you can find your `Plugin ID` in the page URL. ![](https://i.imgur.com/UJcAkCx.png) The `Plugin ID` in the example image above is `60ef11c04763e72fe7e16090`. Add this as `Plugin ID` in TTS. Finally, enter your `Ubidots token` in TTS, which can be found in `My Profile->API Credentials` or [here](https://stem.ubidots.com/accounts/me/apiCredentials). ![](https://i.imgur.com/fQ0rd08.png) Now, create the webhook. It should now be listed under `Integrations->Webhooks` in your TTS console. Select it, and scroll down to `Enabled messages`. ![](https://i.imgur.com/hc8AjIc.png) Replace the default `Uplink message` url with the one provided for you in the Ubidots Data Plugin you created earlier. You can find it by nagivating to `Devices->Plugins->YourPlugin->Decoder` and copying `HTTPs Endpoint URL` of the plugin. You dont need the whole URL, only the part from `/api`, so your `Uplink message` url should look something like: `/api/web-hook/kxSCgvP93BUJXL25gUQCErvvJrA=` ![](https://i.imgur.com/yz37uWh.png) In the image above, you can see our API-url in place. When you're done, press `Save changes`. ## Simulate Uplinks Now, it is time to see how uplink messages to TTS (from your device) are forwarded to Ubidots. In your TTS-console, navigate to `Applications->End devices->your device -> Messaging`. ![](https://i.imgur.com/iRBWIyO.png) Enter `02 03` in the `Payload` field and press `Simulate uplink`. You should see a success-message indicating a successful simulation. Now, go to your Ubidots account and navigate to `Devices`. Woop woop, a new device! ![](https://i.imgur.com/oPSt6jp.png) And if you select it, you should see something like this: ![](https://i.imgur.com/mNUmPN4.png) This simply means that your Ubidots integration in TTS works! However, you probably have more interesting variables to visualize than `F Port`, `Frame Counter`, etc.. You will learn how to decode your payload in the next section. ## Ubidots decoder In the [TTS](https://hackmd.io/5RbTAtCxTPu-hRi3k4p3dQ) tutorial, we left things off at transmitting data to TTS. Consider the code snippet below: ```python= while True: temperature = -23.3 # Your sensor value humidity = 40 # Your sensor value # > = big-endian # h = Temperature (2 bytes, 16 bits, signed) Range: −32,768 to 32,767 # B = Humidity (1 byte, 8 bits, unsigned) Range: 0 to 255 payload = struct.pack('>hB', int(temperature * 100), int(humidity)) s.send(payload) print('sent temperature:', temperature) print('sent humidity:', humidity) time.sleep(900) # wait 900 seconds (15 minutes) before sending again ``` When these two values are sent to TTS, the `MAC payload` looks like this: ![](https://i.imgur.com/CziaVAQ.png) The first two bytes (`F6 E6`) are the temperature bytes and the third byte (`28`) is the humidity byte. Here is why we chose one byte for humidity and two bytes for temperature: The humidity value can span between 0 and 100 % and an appropriate datatype to use here is an `unsigned byte` (0-127). As for the temperature, it can span (depending on the type of your sensor) from -60°C to 80°C. So we need a signed type. A signed type means that its values can be both positive and negative. We could use a `signed byte`, and that would probably suffice, but then we would only get the temperature as integer values, and not as floats. 23.3°C looks nicer than 23°C. So we use two bytes for temperature. Now, we can multiply our temperature by 100 before packing & sending it and divide it by 100 when unpacking/decoding our payload. :::info Notice that we're already multiplying our temperature by 100 during the packing in row 8 in the code-snippet above. ::: So here is how you decode your payload: In ubidots, navigate to `Devices->Plugins->Your plugin->Decoder` and replace the default `Decoding Function` with the following code-snippet and press `SAVE & MAKE LIVE`: ```javascript= function format_payload(args){ var ubidots_payload = {}; // Log received data for debugging purposes: // console.log(JSON.stringify(args)); // Get RSSI and SNR variables using gateways data: var gateways = args['uplink_message']['rx_metadata']; for (const i in gateways) { // Get gateway EUI and name var gw = gateways[i]; var gw_eui = gw['gateway_ids']['eui']; var gw_id = gw['gateway_ids']['gateway_id']; // Build RSSI and SNR variables ubidots_payload['rssi-' + gw_id] = { "value": gw['rssi'], "context": { "channel_index": gw['channel_index'], "channel_rssi": gw['channel_rssi'], "gw_eui": gw_eui, "gw_id": gw_id, "uplink_token": gw['uplink_token'] } } ubidots_payload['snr-' + gw_id] = gw['snr']; } // Get Fcnt and Port variables: ubidots_payload['f_cnt'] = args['uplink_message']['f_cnt']; ubidots_payload['f_port'] = args['uplink_message']['f_port']; // Get uplink's timestamp ubidots_payload['timestamp'] = new Date(args['uplink_message']['received_at']).getTime(); // If you're already decoding in TTS using payload formatters, // then uncomment the following line to use "uplink_message.decoded_payload". // PROTIP: Make sure the incoming decoded payload is an Ubidots-compatible JSON (See https://ubidots.com/docs/hw/#sending-data) // var decoded_payload = args['uplink_message']['decoded_payload']; // By default, this plugin uses "uplink_message.frm_payload" and sends it to the decoding function "decodeUplink". // For more vendor-specific decoders, check out https://github.com/TheThingsNetwork/lorawan-devices/tree/master/vendor let bytes = Buffer.from(args['uplink_message']['frm_payload'], 'base64'); var decoded_payload = decodeUplink(bytes)['data']; // Merge decoded payload into Ubidots payload Object.assign(ubidots_payload, decoded_payload); return ubidots_payload } function decodeUplink(bytes) { var decoded = {}; decoded.temperature = (bytes[0] << 24 >> 16 | bytes[1]) / 100; decoded.humidity = bytes[2]; return {"data": decoded}; } module.exports = { format_payload }; ``` :::info Notice the division by 100 in row 50 in the code-snippet above. ::: To test your new decoder, navigate to `Applications->End devices->Your device->Messaging` and insert `FF E9 28` as your payload and press `Simulate uplink`. Now, if you go back to your device in Ubidots, you should see your temperature & humidity values. Just now, we simulated the uplink but the same would happen if you ran `main.py`. ![](https://i.imgur.com/2vNBJ58.png) Now that you have your sensor data available on Ubidots, let's create a dashboard! :D ## Create a Ubidots Dashboard In Ubidots, navigate to `Data->Dashboards` and press `Add new Dashboard`. Now, it is your task to experiment with the settings to create a dashboard that best fits your needs. ![](https://i.imgur.com/rlh6ibo.png) Then, go ahead and click on `Add new Widget` and select the `Thermometer` widget. ![](https://i.imgur.com/q5iakRS.png) Now, click on `Add variables` in the `Data` section in your thermometer and set the label to `temperature`. This connects the widget with your `temperature` variable in your Ubidots device. Do the same for your humidity value. Perhaps, use the gauge widget for humidity. Here are the results: ![](https://i.imgur.com/s4piX8B.png) <br/> :::info **Credit** Written by David Mozart :::