Device won't transmit to Losant, mqttClient.state -2

Hello,

I have am working on setting up a temperature and humidity sensor based on the tutorial by
@anaptfox. When testing though, the device says authentication succeeded in the application log, however it doesn’t transmit any data afterward.

log

I am also getting this readout in the serial monitor:

WiFi connected
IP address: 
xxx.xxx.x.x

Authenticating Device...This device is authorized!

Connecting to Losant...-2
.-2
.-2
.-2
.-2
.-2

I have tried removing everything marked “secure” in the code based on this forum thread but still receive the same error. My hardware and the code I am using are listed below. Does anyone have some ideas how I might fix this?

Hardware:
WEMOS D1 Mini Pro
DHT22 Sensor

Sketch:
(source) https://www.losant.com/blog/getting-started-with-the-esp8266-and-dht22-sensor

#include "DHT.h"
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <Losant.h>

#define DHTPIN 4     // what digital pin the DHT22 is conected to
#define DHTTYPE DHT22   // There are multiple kinds of DHT sensors

DHT dht(DHTPIN, DHTTYPE);

// WiFi credentials.
const char* WIFI_SSID = "my_wifi_ssid";
const char* WIFI_PASS = "my_password";

// Losant credentials.
const char* LOSANT_DEVICE_ID = "xxxxxx";
const char* LOSANT_ACCESS_KEY = "xxxxxx";
const char* LOSANT_ACCESS_SECRET = "xxxxxx";

WiFiClientSecure wifiClient;

LosantDevice device(LOSANT_DEVICE_ID);

void connect() {

  // Connect to Wifi.
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(WIFI_SSID);

  // WiFi fix: https://github.com/esp8266/Arduino/issues/2186
  WiFi.persistent(false);
  WiFi.mode(WIFI_OFF);
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASS);

  unsigned long wifiConnectStart = millis();

  while (WiFi.status() != WL_CONNECTED) {
    // Check to see if
    if (WiFi.status() == WL_CONNECT_FAILED) {
      Serial.println("Failed to connect to WIFI. Please verify credentials: ");
      Serial.println();
      Serial.print("SSID: ");
      Serial.println(WIFI_SSID);
      Serial.print("Password: ");
      Serial.println(WIFI_PASS);
      Serial.println();
    }

    delay(500);
    Serial.println("...");
    // Only try for 30 seconds seconds.
    if(millis() - wifiConnectStart > 30000) {
      Serial.println("Failed to connect to WiFi");
      Serial.println("Please attempt to send updated configuration parameters.");
      return;
    }
  }

  Serial.println();
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.println();

  Serial.print("Authenticating Device...");
  HTTPClient http;
  http.begin("http://api.losant.com/auth/device");
  http.addHeader("Content-Type", "application/json");
  http.addHeader("Accept", "application/json");

  /* Create JSON payload to sent to Losant
   *
   *   {
   *     "deviceId": "575ecf887ae143cd83dc4aa2",
   *     "key": "this_would_be_the_key",
   *     "secret": "this_would_be_the_secret"
   *   }
   *
   */

  StaticJsonBuffer<200> jsonBuffer;
  JsonObject& root = jsonBuffer.createObject();
  root["deviceId"] = LOSANT_DEVICE_ID;
  root["key"] = LOSANT_ACCESS_KEY;
  root["secret"] = LOSANT_ACCESS_SECRET;
  String buffer;
  root.printTo(buffer);

  int httpCode = http.POST(buffer);

  if(httpCode > 0) {
      if(httpCode == HTTP_CODE_OK) {
          Serial.println("This device is authorized!");
      } else {
        Serial.println("Failed to authorize device to Losant.");
        if(httpCode == 400) {
          Serial.println("Validation error: The device ID, access key, or access secret is not in the proper format.");
        } else if(httpCode == 401) {
          Serial.println("Invalid credentials to Losant: Please double-check the device ID, access key, and access secret.");
        } else {
           Serial.println("Unknown response from API");
        }
      }
    } else {
        Serial.println("Failed to connect to Losant API.");

   }

  http.end();

  // Connect to Losant.
  Serial.println();
  Serial.print("Connecting to Losant...");


  device.connectSecure(wifiClient, LOSANT_ACCESS_KEY, LOSANT_ACCESS_SECRET);

  while(!device.connected()) {
    delay(500);
    Serial.println(device.mqttClient.state()); // HERE
    Serial.print(".");
  }

  Serial.println("Connected!");
  Serial.println();
  Serial.println("This device is now ready for use!");
}

void setup() {
  Serial.begin(115200);
  Serial.setTimeout(2000);

  // Wait for serial to initialize.
  while(!Serial) { }

  Serial.println("Device Started");
  Serial.println("-------------------------------------");
  Serial.println("Running DHT!");
  Serial.println("-------------------------------------");

  connect();
}

void report(double humidity, double tempC, double tempF, double heatIndexC, double heatIndexF) {
  StaticJsonBuffer<500> jsonBuffer;
  JsonObject& root = jsonBuffer.createObject();
  root["humidity"] = humidity;
  root["tempC"] = tempC;
  root["tempF"] = tempF;
  root["heatIndexC"] = heatIndexC;
  root["heatIndexF"] = heatIndexF;
  device.sendState(root);
  Serial.println("Reported!");
}

int timeSinceLastRead = 0;
void loop() {
   bool toReconnect = false;

  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("Disconnected from WiFi");
    toReconnect = true;
  }

  if (!device.connected()) {
    Serial.println("Disconnected from MQTT");
    Serial.println(device.mqttClient.state());
    toReconnect = true;
  }

  if (toReconnect) {
    connect();
  }

  device.loop();

  // Report every 15 minutes.
  if(timeSinceLastRead > 900000) {
    // Reading temperature or humidity takes about 250 milliseconds!
    // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
    float h = dht.readHumidity();
    // Read temperature as Celsius (the default)
    float t = dht.readTemperature();
    // Read temperature as Fahrenheit (isFahrenheit = true) 
    float f = dht.readTemperature(true) - 4;

    // Check if any reads failed and exit early (to try again).
    if (isnan(h) || isnan(t) || isnan(f)) {
      Serial.println("Failed to read from DHT sensor!");
      timeSinceLastRead = 0;
      return;
    }

    // Compute heat index in Fahrenheit (the default)
    float hif = dht.computeHeatIndex(f, h);
    // Compute heat index in Celsius (isFahreheit = false)
    float hic = dht.computeHeatIndex(t, h, false);

    Serial.print("Humidity: ");
    Serial.print(h);
    Serial.print(" %\t");
    Serial.print("Temperature: ");
    Serial.print(t);
    Serial.print(" *C ");
    Serial.print(f);
    Serial.print(" *F\t");
    Serial.print("Heat index: ");
    Serial.print(hic);
    Serial.print(" *C ");
    Serial.print(hif);
    Serial.println(" *F");
    report(h, t, f, hic, hif);

    timeSinceLastRead = 0;
  }
  delay(100);
  timeSinceLastRead += 100;
}

Hi @Elizabeth_McGee,

Welcome to the Losant Forums :smile: I am curious, have you stumbled upon or tried the resolution steps from this forum post? And if so, are you still encountering the -2 error?

Thanks so much!
Julia

Thank you @ JuliaKempf! I am looking through the forum post and it looks like adding the Losant certificate might solve the problem. I’m attempting to add it using the Wifi101 Firmware Updater but am receiving the following error:

error: declaration of C function 'sint8 spi_flash_read(uint8*, uint32, uint32)' conflicts with sint8 spi_flash_read(uint8 *pu8Buf, uint32 u32Addr, uint32 u32Sz);

I’m guessing this is because my device is flashed using NodeMCU? Do you know of a way to add the certificate with this firmware? I’ve been searching online for a how-to without much luck.

Thank you!
Elizabeth

Hi @Elizabeth_McGee,

I just wanted to let you know that we did just recently update the Losant library to support ArduinoJson 6. I would recommend reconfiguring for this change. You can find an updated example here; please let me know if I can answer any further questions!

Thanks so much,
Julia

Hi @JuliaKempf,

I have updated the Losant library and installed ArduinoJson 6, but now am receiving errors that the sketch needs to be converted from Json 5 to 6. I am using the same code found in the tutorial by @anaptfox, but don’t have the coding knowledge to make this conversion. Is there a simpler way to install the Losant certificates to get rid of the -2 error? If the Losant library update is what’s needed to resolve the problem, is there a way to get an updated version of the tutorial code?

Thank you,
Elizabeth

Hi @Elizabeth_McGee,

It can be sometimes difficult to debug these problems due to the range of device components and possible failures. This can be even more difficult if trying to accomplish multiple tasks within one step. To begin debugging, we recommend breaking this task into parts to deduce where the issue is transpiring!

The tutorial code you are following does two things, it reads from your sensor and reports to Losant. Your first step to debugging is to ensure you are able to successfully connect to Losant. The two code pieces have been combined in the second snippet. The first snippet is the code that reads the sensor. Removing the sensor code will allow you to exclusively connect to Losant without attempting to read values from the DHT. This example also includes the code to connect to Losant (but utilizes a different sensor), this can be a helpful reference to see how the Losant code functions.

Please let me know your findings after attempting to connect, I’ll be interested to see if the error continues or changes. :smile: In addition, you can also find a detailed changelog for this upgrade here.

Thanks!
Julia

Thank you for the information @JuliaKempf! I managed to get the rest of the code converted for the JSON upgrade based on the link you provided. I also isolated the Losant connection code from the DHT code but still seem to be having the same problem. The -2 isn’t appearing in the serial monitor anymore but I think this is because the new MQTT library that I had to install while making the JSON upgrade doesn’t include the error codes.

During the initial sketch upload from IDE, the application log in Losant shows “Authentication succeeded” but nothing happens after this and the IDE serial monitor shows a bunch of dots. If I change the code to an usecure connection, it will also register in Losant as unsecure but still nothing happens after this.

I initially built the device in July, 2018 and it worked without any problems, then sometime last year it was no longer able to connect.

Is there a way to add the Losant certificate in the sketch itself or something else I should try?

Thank you for your help!

Hi @Elizabeth_McGee ,

I don’t know if anyone has followed up with this with you. We have been using ESP32 and ESP8266 in our applications. Made the changes and upgrades ourselves before Losant updated the libraries to work with Ardruino Json6. However their latest update to the code seems like what you’d be after. You can find it at link. This is a pretty good starting point.

Cheers,
Park

1 Like

Hi everyone,

First time posting here, but I cannot get the code in the link posted by @Pinyo_Folvig to run on my ESP8266 12E. It is not able to connect to Losant. I copied the code from the link over to a new sketch, added my WiFi info, device info, and let it run. No love. One thing I did run across is the MQTT item needing to be set to 256, but that seemed to have already been done in the library I downloaded.

I’m terribly lost in C++, so I have no idea how to begin troubleshooting this. Any help is appreciated.

Hi @Wayne_Hughes,

Welcome to the Losant Forums - happy to help out.

Would you be able to provide some further details about the error you’re running into? Screenshots of your code block and screenshots of any errors you’re seeing in Losant would be a great starting point.

Is the device not connecting at all or not reporting data?

Thanks,
@Aidan_Zebertavage

Hi Adrian. There isn’t much to screenshot. I just used the canned esp8266.ino file, added my Wi-Fi creds and device ID. When I run it all I see is it connects to my Wi-Fi and prints dots by ‘connecting to Losant.’

I verified my keys through the website and was able to successfully connect in the simulator. I can also see connection requests going out through my gateway, so it is attempting, but I’ve no idea how to see what the http response is.

Hey @Wayne_Hughes, I’m testing this on a device we have here a Losant to see if I can get the same result.

In the meantime, in the past, we have found the esp8266 (depending on the manufacturer) to have some random issues. Would you happen to have an alternative device you can test with?

1 Like

I tried with the same results on three units. Here is the specific unit I bought.

Since I have your attention, I think it would be really helpful if someone updated that ESP8266 DHT blog. That’s where I started and had to do some digging to get this far.

Thanks a ton for looking into this.

@anaptfox - I have a packet capture if someone can review. I am using the sample esp8266.ino sketch and only modified the fields for the SSID, password, device ID, key, and secret.

I have a Fortigate firewall, and just to be sure I used my phone as a hotspot (making sure to disable wifi on the phone first). I modded the sketch to connect to my phone hotspot and received the same results.

@Wayne_Hughes,

Last week, after doing some testing with the library. I have a potential way for you to figure out why your device isn’t connecting. In the

while(!device.connected()) {
    delay(500);
    Serial.println("Last Error:");
    Serial.println(device.mqttClient.lastError());
    Serial.println("Return Code:");
    Serial.println(device.mqttClient.returnCode());
    Serial.println("."); 
    Serial.print(".");
  }

This will print out any error messages from the underlying MQTT client the Losant library uses.

Once done, you can find out exactly what those codes are here:

  • The error codes can be found here.
  • The return codes can be found here.

That’s going to give us a great next step.

Also, just to confirm, what board are you selecting in Arduino’s board manager for your device?

1 Like

NodeMCU 1.0 (ESP-12E Module)

.Last Error:
-10 ( LWMQTT_CONNECTION_DENIED = -10,)
Return Code:
5 (LWMQTT_NOT_AUTHORIZED = 5,)

So, that means I didn’t auth my device correctly in the console somehow? It worked when I tested it through the simulator.

@Wayne_Hughes,

If you’re getting an unauthorized, it means that the device ID, access key, and secret for that device isn’t valid. Could you double confirm those?

// Losant credentials.
const char* LOSANT_DEVICE_ID = "my-device-id";
const char* LOSANT_ACCESS_KEY = "my-app-key";
const char* LOSANT_ACCESS_SECRET = "my-app-secret";

One thing to ensure that, if these work in the Device Simulator. It simulates activity for the device you’re currently looking at. When you generate the key/secret there, it’s to be used for that one device.

In the Access Key / Secret Settings, you can see what devices are allowed to use that key:

Would you happen to be trying to use a different device? Or is it possible that the key/secret you’re trying to use is not restricted to the device (LOSANT_DEVICE_ID) you’re using to connect?

An easy way to independently verify your device credentials is by using the Device Auth API. Here is an example of a successful verification using Postman:

Using that example, you can verify that your device Id is valid for the given key/secret.

My device ID, access key, and secret perfectly match what is in the console. I copied the keys from my sketch into the simulator to validate and I only have one device.

Would it be best to delete the device in the console and create another one?

One other question - are spaces supported in the device IDs?

@Wayne_Hughes,

No, There shouldn’t be any spaces in your Device’s ID. Are you seeing that?