Subscribe Help - Handler not functioning as hoped [Solved]

Code:


/* Includes ------------------------------------------------------------------*/
#include "NCD2Relay/NCD2Relay.h"

NCD2Relay relayController;

SYSTEM_MODE(AUTOMATIC);

int triggerRelay(String command);

void klaxonHandler(const char *event, const char *data);

bool tripped[6];

int debugTrips[6];

int minTrips = 5;

/* This function is called once at start up ----------------------------------*/
void setup()
{
  Particle.function("controlRelay", triggerRelay);
  Particle.subscribe("klaxon", klaxonHandler);
  Serial.begin(115200);
  relayController.setAddress(0, 0, 0);
}

/* This function loops forever --------------------------------------------*/
void loop()
{
  //
}

int triggerRelay(String command) {
  if (command.equalsIgnoreCase("turnonallrelays")) {
    relayController.turnOnAllRelays();
    return 1;
  }
  if (command.equalsIgnoreCase("turnoffallrelays")) {
    relayController.turnOffAllRelays();
    return 1;
  }
  if (command.startsWith("setBankStatus:")) {
    int status = command.substring(14).toInt();
    if (status < 0 || status > 255) {
      return 0;
    }
    Serial.print("Setting bank status to: ");
    Serial.println(status);
    relayController.setBankStatus(status);
    Serial.println("done");
    return 1;
  }
  //Relay Specific Command
  int relayNumber = command.substring(0, 1).toInt();
  Serial.print("relayNumber: ");
  Serial.println(relayNumber);
  String relayCommand = command.substring(1);
  Serial.print("relayCommand:");
  Serial.print(relayCommand);
  Serial.println(".");
  if (relayCommand.equalsIgnoreCase("on")) {
    Serial.println("Turning on relay");
    relayController.turnOnRelay(relayNumber);
    Serial.println("returning");
    return 1;
  }
  if (relayCommand.equalsIgnoreCase("off")) {
    relayController.turnOffRelay(relayNumber);
    return 1;
  }
  if (relayCommand.equalsIgnoreCase("toggle")) {
    relayController.toggleRelay(relayNumber);
    return 1;
  }
  if (relayCommand.equalsIgnoreCase("momentary")) {
    relayController.turnOnRelay(relayNumber);
    delay(300);
    relayController.turnOffRelay(relayNumber);
    return 1;
  }
  return 0;
}

void klaxonHandler(const char *event, const char *data) {
  if (event == "klaxon" && data == "on") {
    //triggerRelay("turnonallrelays");
    relayController.turnOnAllRelays();
  } else if (event == "klaxon" && data == "off") {
    //triggerRelay("turnoffallrelays");
    relayController.turnOffAllRelays();
  }
}

So for some reason this won’t actually trigger the relays… Could it be that an actual device has to issue the command? I am actually publishing an event to cloud via a node app the I’ve been working on for the past couple of days. I know it’s hitting the cloud because I see in the logs.

I think this has something to do with an error I’ve made in the subscription handler…

Cheers,

How are you publishing the event?
If it’s a PRIVATE event, you need to subscribe with MY_DEVICES.

Also adding a Serial.printlnf("%s: <%s>", (const char*)event, (const char*)data); might give you a clue if the handler is called at all and what the payload actually is.

Yes Sir, So I put that in and flashed it to the device I can see it comming into the Serial Monitor just fine. Only the data has <> around it. I imagine thats due to the formatting you sent above.

So now it must be a matter of how the handler calls the:

relayController.turnOnAllRelays();

function.

Yup, I usually use extra <...> to also see if there are any non-visibles (like blanks) sneaking their way into a string.

1 Like

Klever man! I thought it neater that way…

req.write(qs.stringify({ name: 'klaxon', data: 'off', ttl: '120', private: 'true' }));
req.end();

This is the blip copied from POSTMAN and also pasted into my NODEJS API Web App

It works quite well showing up in the particle logs. So I’m confident this part is good…

1 Like

The point is that you can’t compare C strings with ==.
You need to write your string comparison like this

  if (strcmp(event, "klaxon") == 0 && strcmp(data, "on") == 0)
  {
    ...
  }  
  else if (strcmp(event, "klaxon") == 0 && strcmp(data, "off") == 0)
  {
    ...
  }

The way you did it there is a pointer compare, and since both strings are not located at the same spot in memory the pointers are not equal.
That == compare only works with String objects.

2 Likes

Sorry for the late reply @ScruffR! You sir, are the savior of the day! These worked!

We found that the response time using the NodeJS based application I’ve built is so much quicker than using the DoButton App (initial testing method). Best of all, we have at the moment 20 Electrons that all respond to the same function at very close to the same time. And that number will be growing to 100+ very soon!

Thanks so much again.

Cheers,

4 Likes

Glad @callen ScruffR was able to help you out! Thanks @ScruffR!