Group of photon devices


#1

We are automating all of our lighting control on site with relayshield and photon using IFTTT. Already bought one of them to try out and it seems to work. The question is how do we send a message to more than one device at one OR how do we program so that and IFTTT function can control multiple device at the same time?

Thanks,
Regards.


#2

There are multiple routes, one would be to send an event via Particle.publish() (or the respective API endpoint) to which all individual devices Particle.subscribe().
If IFTTT doesn’t support that option, you could have one Photon act as gateway which receives a function call from IFTTT to “broadcast” an event to which the other devices have subscribed.
Or you could go via webhooks, MQTT, …


#3

Hi ScruffR,
Thanks for your advise. I think it would be good to keep one photon as common which will receive all of the commands from IFTTT and it would then relay them to appropriate subscribers. I will have to look into and example of this since I am kind of refreshing my 15 year old C++ skills.

Regards.


#4

Hi ScruffR,
I am revisiting this topic since the attention was diverted to other priorities. I have two versions of code (one for master and one for slave). We have several particle devices and we are trying to keep one device as master which will publish and others will subscribe. We have generated event handler for interiorON function to try it out. Under the slave device, when we are calling to handle the subscribed event only when it belongs to the particular device ID, it does not work. We would like to create different events and only particular devices with their respective relays will get triggered ON. Can you please help on this?

Here are the links to the code:

Thanks,
Regards,
Jatin.


#5

There are some things to note

e.g. in your master code

    Particle.variable("relayStatus", STATUS_MESSAGE_UNAVAILABLE, STRING);
...
    Particle.variable("relayStatus", message, STRING);

This is not how Particle.variable() is used.
You should rather declare one global variable (e.g. char relayState[64]) and register that with the cloud via Particle.variable("relayStatus", relayState) and from then on set relayState (e.g. via strcpy()) to whatever content you want relayStatus to reflect when requested by the cloud.

I’m also always advocating against the use of String and rather use C strings.
for the risk of heap fragmentation.

Next, you should only publish PUBLIC events when absolutely required (aka “talk to somone else’s device”), so you should rather do this

//   Particle.publish(IDname, logString); // PUBLIC is default (for some obscure reason)
   Particle.publish(IDname, logString, PRIVATE);

Your slaves should then subscribe via

    Particle.subscribe("EVENT:InteriorOn", interiorOnHandler, MY_DEVICES);

Why do you compare to a single literal device ID?

    if (strcmp(myId, "3c003a001247343438323536") == 0) {

I’d rather put the device IDs into an array of which the index aligns with your “device names” BAPS_LA_x (don’t introduce two diffferent numbers for the same thing) and search that array for the desired ID.
If you need to call your first device BAPS_LA_1 then just add a dummy item at index 0.

With that you can easily achieve what you’re asking here

e.g.

  if (strcmp(data, myID)) return; // leave when data parameter doesn't match `myID` 

BTW, it’s poor style to use delay(1000) in a Particle.function() callback.


#6

Thanks ScruffR,
One more question: Why is the system id not available in the subscribe handler function?
Thanks,
Regards,
-Jatin.


#7

Because you are probably not sending it in your publish event.


#8

Hi @ScruffR and @jatin

Thanks for the details on this discussion chain. I have very similar question.

I am trying to perform certain actions based on master publishing an event and slave devices subscribing to that particular event. I am able to prove the concept on a single master and single slave device via publish/subscribe functionality.

Since I have multiple slave devices, I don’t want to write different code for each slave device. Instead I have the following logic in mind for slave devices:

if (system_id == “A”) { subscribeEvent (X); }
if (system_id == "B) { subscribeEvent(Y); }

This way I can use the same code on multiple slave devices and differentiate behavior based on their corresponding system id.

But it seems like the system_id is determined statically and not available for run-time analysis/check, to subscribe to an event based on system id. If I remove the if() check, the subscribeEvent() works in flawless fashion.

Is my assumption correct? Let me know if I am wrong and how do I accomplish this task of having a single code base for all slave devices and each one subscribing to an event based on their respective system id.

Thanks,
Patrick


#9

What are you refering to when you say “system_id” - where does it come from?
When are you subscribing? A subscription needs to be registered by max. 30sec after the cloud connect.


#10

The system_id is the return value of system.deviceID().

I am subscribing to the event in the setup() function.


#11

One correction to the original question.

I am subscribing to all events on all slave devices.

I am checking for the deviceID in the subscription handler function.


#12

If you can show your publish (including data string) and subscribe commands it might be easier to advise.

BTW, given that you “system_id” (System.deviceID() a run-time command) is retreivaible able at run time I can’t quite understand where this is coming from

However, since the problem description still feels a bit mushy (who is subscribing to who’s events) to me I just propose a solution to what I “understand” you are after

// slave subscribes to master
void setup() {
  char evtName[32];
  snprintf(evtName, sizeof(evtName), "myEvt_%s", (const char*)System.deviceID());
  subscribe(evtName, eventHandler); // only subscribe to events starting with myEvt_ and ending with device ID
}
// master publishes event based on stored list of device IDs
...
  char evtName[32];
  snprintf(evtName, sizeof(evtName), "myEvt_%s", device[x]);
  Particle.publish(evtName, "some test data", PRIVATE);

#13

Thank you for the details!

I was finally able to accomplish the intended task. It was a small programming mistaking in getting the event_id for the particular device.

Thanks again.