String "Command received: " not shown on the serial monitor output

#1

Hello,

I am trying to develop functionality that need data from this platform.
As I am relatively new to this, I probably miss something simple but quit importent to receive data form this plaform through JSON.

The workflow gives the result I expected, with the latest field having the expected value.

{
  "time": "2017-02-16T08:07:08.971Z",
  "data": {},
  "applicationId": "58a4095250530f0001031a72",
  "triggerId": "58a409f585f6e20001f725cb-Hkz8sFWFl",
  "triggerType": "virtualButton",
  "relayId": "58932b056b20be000123219d",
  "relayType": "user",
  "flowId": "58a409f585f6e20001f725cb",
  "flowName": "AVRI Kalender Led",
  "applicationName": "AVRI",
  "globals": {},
  "text": "groen"
}

The question is why it is not received by my device?

Here all the documentation I can provide (including my code through the Arduino IDE)
Application

My Sandbox / AVRI

ApplicationID

58a4095250530f0001031a72

DeviceID

58a4099c03c8370001bf8509

WorkflowID

58a409f585f6e20001f725cb

Status Connect

Connected

Device Type

Standalone

Device Attributes

Data Type = String
Name = text

Workflow Node: Device Command

Properties

Label = SendText
Select the device(s) to send command to. = Checked: Select specific devices and tags
Device IDs / Tags = AVRI Kalender Led
Command Name Template = setLed
Command Payload Type = JSON Template
Command Payload JSON Template = {“STR1”:“text”}

Debug (Node: DebugCommand)
Extra info: the debug info was just gennereted, but the device was disconnected.
The test upon this request is based was yesterday. But this is not relevant for the case!

{
“time”: “2017-02-16T08:07:08.971Z”,
“data”: {},
“applicationId”: “58a4095250530f0001031a72”,
“triggerId”: “58a409f585f6e20001f725cb-Hkz8sFWFl”,
“triggerType”: “virtualButton”,
“relayId”: “58932b056b20be000123219d”,
“relayType”: “user”,
“flowId”: “58a409f585f6e20001f725cb”,
“flowName”: “AVRI Kalender Led”,
“applicationName”: “AVRI”,
“globals”: {},
“text”: “groen”
}

Sourcecode

/**
*
*
*
*
*
*
*/

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

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

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

#define BUTTON_PIN 5
#define MQTT_MAX_PACKET_SIZE 256

volatile bool buttonStateChanged = false;

WiFiClientSecure wifiClient;

LosantDevice device(LOSANT_DEVICE_ID);


void setup() {
  Serial.begin(115200);
  while(!Serial) { }
  
  pinMode(BUTTON_PIN, INPUT);

  // Attach an interrupt to the button input so we are
  // notified when it changes.
  attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), buttonStateChangedHandler, CHANGE);

  // Register the command handler to be called when a command is received
  // from the Losant platform.
  device.onCommand(&handleCommand); 
  
  connect();

}


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();
  }

  if(buttonStateChanged) {
    bool value = digitalRead(BUTTON_PIN);
    reportState(value == 0 ? true : false);
    buttonStateChanged = false;
  }

  device.loop();
  
  delay(200);

}

/**
 * Connects to WiFi and then to the Losant platform.
 */
void connect() {

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

  WiFi.begin(WIFI_SSID, WIFI_PASS);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  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
  */

  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);

  unsigned long connectionStart = millis();
  while(!device.connected()) {
    delay(500);
    Serial.print(".");

    // If we can't connect after 5 seconds, restart the board.
    if(millis() - connectionStart > 5000) {
      Serial.println("Failed to connect to Losant, restarting board.");
      ESP.restart();
    }
  }

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

/**
 * Reports state to Losant whenever button is pressed.
 */
void reportState(bool isPressed) {
  // Build the JSON payload and send to Losant.
  // { "button" : <bool> }
  StaticJsonBuffer<200> jsonBuffer;
  JsonObject& root = jsonBuffer.createObject();
  root["button"] = isPressed ? 1 : 0;
  device.sendState(root);

  Serial.println(isPressed ? "Ingedrukt" : "Geen actie");
}

// Called whenever the device receives a command from the Losant platform.

void handleCommand(LosantCommand *command) {
  
  Serial.print("Command received: ");
  Serial.println(command->name);
  JsonObject& payload = *command->payload;
  
  //print payload
  Serial.print("Payload is: ");
  payload.printTo(Serial);
  Serial.println();

  if (strcmp(command->name, "setLed") == 0) {
      setLed();
  }
  
}

// Handles the setLed from payload.
void setLed() {
  Serial.println("Action...");
}

/**
 * Called whenever the button interrupt is triggered.
 */
void buttonStateChangedHandler() {
  buttonStateChanged = true;
}

Serial monitor output

Connecting to x…x
… did not make a copy, but as the device is authorized should be self explaining.
This device is authorized!

QUESTION (expected a string, but not shown)

Why is the string "Command received: " not shown on the serial monitor output?
Or: what am I missing?

#2

There are a couple of things I would try:

  • Try increasing the packet size on the underlying pubsubclient: Sending commands with larger payloads Unfortunately the underlying library silently refuses commands if the packet is too large.

  • Does the command show up in the application communication log? This log is a live stream of all device communication. Open it another tab and then attempt to send the command. It should show up.

  • Try manually sending the command using the debug tab on the device page.

#3

Hello Brandon,
Thanks for your quick respons.

  • Trying to increase the packet size.
    I have search the Arduino folder and the only place I found was in the file MQTTClient.h
    Printing the MAX_MQTT_PACKET_SIZE it give 128 as a result.
    The only place I see it is set is in MQTTClient.h. And there it is dynamically set; I don’t see the size 128 been set.
  • Application log
    The application log give expected results:
    Received Payload
▶
(root){} 3 keys
"name":"setLed"
▶
"payload":{} 1 key
"STR1":"text"
"time":"2017-02-17T18:53:47.603Z"
  • manually sending the command
    This shows the same outcome as the DeviceCommand (as expected), except for the “time”:
User Wim ten Brinke sent command setLed to Device AVRI Kalender Led
POST/applications/58a4095250530f0001031a72/devices/58a4099c03c8370001bf8509/command
Fri Feb 17 2017 20:12:11 GMT+01:00
Received Payload
▶
(root){} 3 keys
"name":"setLed"
▶
"payload":{} 1 key
"STR1":"text"
"time":"2017-02-17T19:12:11.983Z"

Looking forward to a reaction. Kind regards, Wim

#4

Hello,
The last few days I tried to several options.

  • cleaned the code
  • bought a new device; a device can be defect
  • installed PlatformIO on Atom and added some Losant things, build the software and uploaded it to the new device.
    Unfortunately it does not make a difference.
    The function “void handleCommand(LosantCommand *command)” seems not activated; the text from the command "Serial.print("Command received: "); is not printed in the serial monitor (not on PlatformIO and not on the ArduinoIDE).

Is there anything I can do on my side to provide info that can lead to the solution?

#5

I’ll install the source you provided above on a NodeMCU and test it out. Hopefully I’ll be able to reproduce the issue.

#6

I flashed your exact code using Arduino IDE v1.6.12 and did not experience any issues. Here’s a screenshot of the serial monitor:

I sent the command from the device page:

#7

Thanks a lot.
I test it again.
Can a router be causing trouble as far as you know?
Should not because of the HTTP, but may be there is an issue somewhere about this.