String Results not appearing properly on Ubidots Variable page

In short, I am trying to send BLE scan results (only MAC Address and RSSI value in my case) to Ubidots. So, I tried to use ubidots.add(String, int) to send the addresses and the respective RSSI, but the variables don’t appear properly on Ubidots. I am using the ble_scan example from arduino.

Here are the results on the Ubidots variables page. The RSSI value (negative int)
appears correctly, but the Address doesn’t.

Example of scan results in Serial Port: (no Ubidots just raw data)

MAC Address: 1c:f3:67:78:63:96
RSSI: -84
MAC Address: 1c:f3:67:78:63:96
RSSI: -92
MAC Address: 7c:ab:ef:f7:f7:79
RSSI: -82
MAC Address: 1c:f3:67:78:63:96
RSSI: -84
MAC Address: 5d:9f:e4:7b:35:33
RSSI: -82

This is the output when I use Ubidots
As you can see, the ubidots.add() does indeed receive the Address and its MAC, but doesnt send over to Ubidots

.....WiFi connected
IP address: 
192.168.1.11
Starting Scan...
Scan Started
----------
payload:
UbidotsESP32/0.0.1|POST|BBFF-yRZeguGTJQXLKQIx2cOzEkEsWTQhk0|2462ABE081BC:2462ABE081BC=>4e:7e:45:e1:47:8a:-88|end
----------

Sending data...
----------
Server's response:
ERROR|400
----------
----------
payload:
UbidotsESP32/0.0.1|POST|BBFF-yRZeguGTJQXLKQIx2cOzEkEsWTQhk0|2462ABE081BC:2462ABE081BC=>4e:7e:45:e1:47:8a:-88|end
----------

Sending data...
Trying to connect to industrial.api.ubidots.com , attempt number: 0
Trying to connect to industrial.api.ubidots.com , attempt number: 1
Trying to connect to industrial.api.ubidots.com , attempt number: 2
Trying to connect to industrial.api.ubidots.com , attempt number: 3
Trying to connect to industrial.api.ubidots.com , attempt number: 4
[ERROR] Could not connect to the host
----------
payload:
UbidotsESP32/0.0.1|POST|BBFF-yRZeguGTJQXLKQIx2cOzEkEsWTQhk0|2462ABE081BC:2462ABE081BC=>TJQXLKQIx2cOzEkEsWTQhk0|2462ABE081BC:2462ABE081BC=>:-88|end
----------

Below is my edited code

    /*
    Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32- 
    snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleScan.cpp
    Ported to Arduino ESP32 by Evandro Copercini
    */
#include <UbiBuilder.h>
#include <UbiConstants.h>
#include <Ubidots.h>
#include <UbiHttp.h>
#include <UbiProtocol.h>
#include <UbiProtocolHandler.h>
#include <UbiTcp.h>
#include <UbiTypes.h>
#include <UbiUdp.h>
#include <UbiUtils.h>

#include <iostream>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
#include <WiFi.h>
#include <Ubidots.h>

/* Network credentials*/
const char* UBIDOTS_TOKEN = "token inserted";
const char* WIFI_SSID = "network1";
const char* WIFI_PASS = "password1"; 
Ubidots ubidots(UBIDOTS_TOKEN, UBI_TCP);

/*Initializing scan variables*/
int scanTime = 2; //In seconds
BLEScan* pBLEScan;
String readString;


class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
    void onResult(BLEAdvertisedDevice advertisedDevice) {

      /*           Printing MACs and resp RSSI
        Serial.print("MAC Address: ");
        Serial.println(advertisedDevice.getAddress().toString().c_str());
        Serial.print("RSSI: ");
        Serial.println(advertisedDevice.getRSSI());
        delay(200); */

      /* Sending to Ubidots*/
      delay(2500);
      ubidots.add(advertisedDevice.getAddress().toString().c_str(), advertisedDevice.getRSSI());
      //      delay(5500);
      bool bufferSent = false;
      bufferSent = ubidots.send();
      delay(1000);
    }
};
void setup() {
  Serial.begin(115200);
  ubidots.wifiConnect(WIFI_SSID, WIFI_PASS);
  ubidots.setDebug(true);  // Uncomment to debug

  Serial.println("Starting Scan...");
  BLEDevice::init("ESP32");
  pBLEScan = BLEDevice::getScan(); //create new scan
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
  pBLEScan->setActiveScan(true); //active scan uses more power, but gets results faster
  pBLEScan->setInterval(100);
  pBLEScan->setWindow(99);  // less or equal setInterval value
}

void loop() {
  ESP.restart();
  Serial.println("Scan Started");
  BLEScanResults foundDevices = pBLEScan->start(scanTime, false);
  pBLEScan->clearResults();   // delete results fromBLEScan buffer to release memory
  delay(1000);
}

Any Help is appreciated. Thanks in advance!

Good day @ahmed_sabrymohamed,

Thank you for sharing your question with the community.

Ubidots doesn’t support non-numerical data as values however, if you need to send strings, this can be done using the variable context. You’d simply add a “context” key, containing arbitrary key: value pairs to suit your application, for example:

{"rrssi": {"value": -82, "context":{"MAC":"1c:f3:67:78:63:96"}}}

Please refer to our Docs to learn about variables context. You can find it in the intro. You can also refer to the explanation in our Hardware Docs.

All the best,
-Isabel

Hi, Thanks for the reply and sorry for the delayed response.

I don’t understand how and where to incorporate the context into my arduino code?
Please keep in mind that I do not create the MAC Addresses and RSSI values. They are generated from methods that belong to “MyAdvertisedDeviceCallbacks” class.

I plan on taking each Address and respective RSSI and sending them individually. (Just like the Serial Port output I’ve provided in the question.

Hi @ahmed_sabrymohamed.

In our Hardware documentation, you can find examples of how to send both values and context to a Ubidots variable using an ESP device. You only need to build the payload in the required format and assign the values RRSI to the value and MAC address to the context, which generate automatically from the method you mentioned. Additionally, please refer here to learn how to send context to a variable using the ESP32.

You will need to add the following line to your code based on the library documentation.

ubidots.add("rrsi", value, context);

Please let us know if you have additional questions.

Best,
-Isabel

Hi, Thank you so much for the reply.

ubidots.addContext was the exact line I was looking for.

However, in my case, this method: advertisedDevice.getAddress().toString().c_str() is what generates the MAC Addresses and the output data type is not the same as the output of this line: char* context = (char*)malloc(sizeof(char) * 60); So, an error occurs:

error: invalid conversion from 'const char*' to 'char*' [-fpermissive]
         ubidots.addContext("MAC Address",advertisedDevice.getAddress().toString().c_str());

I understand that this isn’t a Ubidots related error butrather a coding error. I’ve tried to change char* to const char* and other similar data types, but no luck as I don’t have much experience on C++. If you have any idea on what to change, that would be immense help.

On another note, this is another ‘error’ in the same run instance:

note:   initializing argument 2 of 'void Ubidots::addContext(char*, char*)'
   void addContext(char *key_label, char *key_value);

Could the problem actually be that the void addContext() method only takes direct String values, not generated values? ie. “16-4F-8A-71-EF-DA” which is my input in the IDE, not a String automatically generated from the method.

Thanks again for your effort.