Subscribe Public IP from Particle returns string containing --device_id [solved]

I am getting the Public IP address of my devices (photons on 0.6.1) using the vanilla approach in the documentation.

// request device public IP
void requestPublicIP()
{
    if (Particle.connected())
    {
        Particle.subscribe("spark/", handlerIP);
        Particle.publish("spark/device/ip");
    }
}

And then when published, handling thus:

// function to receive device public IP address
void handlerIP(const char *topic, const char *data)
{
    publicIP = String(data);
    isWAPChanged = true;            //force a resend of the DEVICE_UPDATED message with IP addresses once message received
}

All appeared to be working fine but have now noticed that a number of devices (20) in the fleet are getting --device_id published as the public IP address! Is anyone aware of a change or error that may have caused this? A reset of the devices clears the error - in that the correct public IP address is returned. The devices have been running for approximately a month. Not sure when this issue surfaced.

You are not filtering for the IP event alone. But there are multiple other events that would satisfy the “ambiguous” spark/ filter.
You are taking any spark/ event and just use that unreflected as your expected IP event.

One change that should be coming is that the previous default PUBLIC publish should be changed for a default PRIVATE publish as too many people just forget to use PRIVATE and hence flood the public firehose.
But I thought that wasn’t out yet.

BTW, you should register the subscription only once, but your code doesn’t guard against multi subscriptions on subsequent calls of requestPublicIP()

@ScruffR As I had mentioned I am using the vanilla code example from the photon firmware documentation. So this is incorrect? I would like to test I have understood what you have said, is the following better? I am not clear what the event name is for publicIP.

// request device public IP V2
void requestPublicIP()
{
    if (Particle.connected() && isFirstTry)
    {
        Particle.subscribe("spark/device_ip", handlerIP);
        Particle.publish("spark/device/ip");
        isFirstTry = false;
    }
}

Thank you for the - subscribe once advice. Just to be clear, if the device is disconnected from and reconnected to the Cloud then the subscribe should be repeated? In other words, the subscribe works once and forever or just for a session?

No it's not incorrect, it does what it is supposed to do. It just doesn't guard against any other events also triggering the same handler, but that's not the objective of the respective document.
Some basic understanding of the verbal description provided along side the sample code can be expected.

That's easy to find out.
You can put a Serial.println(topic) in your previous handler and see what kind of events you get thrown.

No, once registered on the device the subscription will be be reestablished automatically.
Hence I'd rather do it that way

void requestPublicIP()
{
  static alreadySubscribed = false;
  if (!alreadySubscribed)
  {
    alreadySubscribed = Particle.subscribe("spark/device/ip", handlerIP, MY_DEVICES);
  }
  Particle.publish("spark/device/ip", PRIVATE);
}

Thanks for clarifying. What happens when I reset/re-power the device - the memory will be cleared and thus the static alreadySubscribed will be set as false and the subscribe requested again? Surely, would need to request the Particle Cloud as to whether device is already subscribed to this topic to be certain.

After a reset/power cycle you want the subscription to be reregistered.
But that’s not the same thing as just disconnecting and reconnecting from the cloud while keeping the subscription rule stored on the devices.

Some background:
On each (re)connect of a device to the cloud a “status hash” is exchanged between the device and the cloud.
If this hash matches, the cloud and the device have the same status about registered Paritcle.variable(), Particle.function() and Particle.subscribe() and no re-registration is required since the previous state can be reapplied.
A mere Particle.disconnect() or connection dropout does not invalidate the hash and hence no re-registration is required.
Only if the hash doesn’t match (which is the case after a warm/cold start) the full registration procedure has to be performed.

1 Like

Thanks - all clear now.