Publish and Subscribe Issues

I am having some problems with the Subscribe and Publish functions. I got this example to work fine, but I cannot for the life of me get this one to work. I have the same code and setup as he does, other than the cores, as I am using the photon. Is there something I need to change because of that? Any help would be appreciated. Thanks.

Could you give this a try?
Publishing:

void setup() {
  pinMode(D7,OUTPUT);
}

void loop() {
  Spark.publish("subscribe_example");
  digitalWrite(D7,HIGH);
  delay(2500);
  digitalWrite(D7,LOW);
  delay(2500);
}

Subscribing:

void myHandler(const char *event, const char *data)
{
  digitalWrite(D7, HIGH);
  delay(1000);
  digitalWrite(D7, LOW);
}

void setup()
{
  pinMode(D7, OUTPUT);
  Spark.subscribe("subscribe_example", myHandler);
}

void loop(){}

@Moors7
So I tried it out and I thought I wasn’t getting any results. But like every minute or two, the light on the receiving photons will light up that yes it got the command. Is that supposed to be happening? Because it seems like it should be doing it every 2.5 seconds or so.

@Moors7
Okay I actually went and timed it out and its every 30 seconds that they blink on.

Oh god, it’s late, my error. Please try the subscribing code from above again, I copied my own example. You were thus listening to my events (which are public). My device publishes every 30s, which seems to match with your finding. I guess the code is working :smile:

1 Like

Yeah it works now. They were different variables too when you originally posted and I don’'t know how I didn’t catch it either. Thanks for the help!

1 Like

@Moors7
So today I am working on this again, and I am trying to publish “Hello Photon!” to another photon. I get it to work fine although I keep getting this.

I don’t understand why this {“t”:27.10,“h”:61.00} keeps popping up.

Publishing code:

void setup() {
  pinMode(D7,OUTPUT);
}

void loop() {
  Spark.publish("pubdata", "Hello Photon!");
  digitalWrite(D7,HIGH);
  delay(2500);
  digitalWrite(D7,LOW);
  delay(2500);
}

Subscribing code:

int i = 0;

void myHandler(const char *event, const char *data)
{
  i++;
  Serial.print(i);
  Serial.print(event);
  Serial.print(", data: ");
  if (data)
    Serial.println(data);
  else
    Serial.println("NULL");
}

void setup()
{
  Spark.subscribe("pub", myHandler);
  Serial.begin(9600);
}

Any ideas as to why this is happening?

Indeed I do. You're still listening to my DHT22 temperature/humidity sensor {"t":27.10,"h":61.00} ;). Unless explicitly programmed otherwise, your events are public, and anyone can see them, which is why you're seeing my values pop up over there.
I see that you've kept the publish name the same pubdata, but you're subscribing to pub. It's a bit of a coincidence that it's still working thanks to the fact that subscribtions are prefix-based. What that means is this (from the docs):

A subscription works like a prefix filter. If you subscribe to "foo", you will receive any event whose name begins with "foo", including "foo", "fool", "foobar", and "food/indian/sweet-curry-beans".

Your subscribe is listening to all events starting with 'pub'. Seeing as we're both publishing an event starting with that, you're receiving both. Generally, you want to keep the publish and subscribe name the same. That way, you should only get those events, assuming that name is either unique or private. The prefix is useful if you want to monitor multiple things at once. Let's say you've got two motion sensors, publishing motion/kitchen and motion/hallway respectively. You could subscribe to them individually by using the complete names, or to both at once if you were to specify your subscribe as motion. Since both events start with motion, it will react to both.

That said, the best way to ensure you receive only your own events, is to either make them unique in name or private. The latter is described in the docs over here. You'd have to adjust the subscribing accordingly:

You can listen to events published only by your own devices by adding a MY_DEVICES constant.

// only events from my devices
Spark.subscribe("the_event_prefix", theHandler, MY_DEVICES);

@Moors7

So the MY_DEVICES did not work for me. It just refused to take anything. But then I just used the specific device ID and it worked perfectly which will do for now. I know all the photons are on the same account, so I don’t know why that happens. I am curious as to how to go about troubleshooting this or anything.

Did you try this in combination with Spark.publish("pubdata", PRIVATE); method?


Considering that I’m still receiving your “hello photon!” messages, I’m going to assume you haven’t. Give that a try and see if it works for you?

1 Like

You are the man. Got it to work pretty smoothly. Sorry about the Hello Photon messages haha.

1 Like

Glad I could help :smile:

No worries, I haven't got anything subscribing to that :wink:

I have some questions about subscribing as well. I understand that a particle.subscribe() will listen for all public events. When I add a CORE-ID though I would think I could listen to events from that specific device. Is that true or can I only add a CORE-ID if it’s one of my own devices?

From the command line interface I can do a: particle subscribe
This gives me a ton of data (as expected).

So then I look at that data and see that event “temperature” is reasonably common, so I then do a:
particle subscribe temperature
This gives me a whole lot less data (as expected). Now I just get “temperature” events. Great.

So I look at that data and pick one of the CORE-ID’s and try this:
particle subscribe temperature 30003f000747353138383138

Now I would hope to get only temperature events, and only from this particular device (which is not my device). But I don’t. Instead I see this:

C:>particle subscribe temperature 30003f000747353138383138
Subscribing to “temperature” from 30003f000747353138383138’s stream
Listening to: /v1/devices/30003f000747353138383138/events/temperature
C:>

It just returns to my command prompt and does nothing further. Any tips would be greatly appreciated.

I’d be inclined to say that you can’t subscribe to other people’s devices using the CLI. Obviously, you can filter them out yourself, but that functionality isn’t built in.
Why would you need to subscribe to other people’s data though?

1 Like

Thanks Moors7. There are two reasons to subscribe to someone else’s data. At the moment I was just doing it to learn and debug. I only have one unit - an Electron. So I can either publish or subscribe. I just now ordered a Photon. So I’ll soon be able to subscribe to my own events.

The other reason is that I may use a single Photon to subscribe to a number of weather stations. These would not all be my own weather stations, but would belong to my kitesurfing and paragliding friends. This is not a critical need as I can make sure and have everyone use unique event ID’s. But I was hoping to keep the event names very short (like “wind”) to minimize bandwidth, and subscribe to specific devices.

I presume that doing a subscribe from the device will have the same limitation (namely that you cannot subscribe to someone else by device ID)?

Thanks.

Remember that the event name is a prefix, so you can have each of your friends publish something like “windJR”, “windBO”, “windSH”, etc (using their initials as a suffix, so you know who sent each one). You can then choose which ones you want to subscribe to, by specifying the whole name, or get them all by subscribing to “wind”. If you only want to get events from yourself and your friends, you might want to pick a more unique name than “wind” as the prefix.

Thanks Ric. And understood. I have considered that, but was partly curious about the functionality of subscribing. It would be handy and intuitive (but not necessary) if the device ID worked whether it was my Electron or someone else’s. It seems odd that I can see all the public events, and their device ID’s, but can’t filter based on the device ID.

This is the case with the CLI. Do you know if it’s also true when done in firmware on the Electron?

That's just the same with "firmware subscribe" as both (CLI & firmware) hit the same endpoint to file their subscription.
And the reason for not being able to filter for device ID is that the ID is a seperate field and not part of the event name field which is the actual filter key.

Understood. But if I understand correctly it can filter on device_id as long as it's one of my devices, and my publish() call specifies PRIVATE - right?

I've been through the docs on publish and subscribe, but I can't seem to find a genuine reference on those commands - only a sort of general description and some examples.

Thanks again for your help.

Yes, but that filtering does already happen on the cloud side and your device will never see the other events to do the firmware filtering.
To do the filtering for arbitrary device IDs, you'd need to send a list of device IDs you're interested in up to the cloud and there is no function to do that.

1 Like