What are best practices for dealing with loss of cellular connection with electron

I’ve been reading the forum posts and documentation about dealing with connection loss on the Electron and have some questions:

The device I’m working on lives in a vehicle and needs to continue to operate locally even when there is no connection. It will attempt to send (publish to a webhook) heartbeat data every 5 minutes unless an alarm condition exists; then it will send immediately (but no more than 1/second).

I originally believed that running in SYSTEM_MODE(AUTOMATIC) would be OK – I’m OK if the code doesn’t start running until an initial connection is made. However, from what I also read, in AUTOMATIC mode, Particle.publish will block until a connection exists – so in areas with poor cellular coverage, the project will essentially hang and won’t be able to do it’s “local” thing.

So I looked at using SYSTEM_MODE(SEMI_AUTOMATIC) and doing a Particle.connect initially in Setup().

As I understand things, I can check for a connection with: if (Particle.connected()) … However, from what I also read, the Electron “checks in” with the cloud only every 23 minutes (from Particle.keepAlive() documentation. So apparently Particle.connected() really doesn’t tell me that I actually have a connection – only that there was one within the last 23 minutes? Is this true?


Assuming the Electron initially connected and then moves (vehicle travels) to a poor reception area and has no connection. Do I understand correctly that when I do a Particle.publish() it will attempt to send, and if it can’t it will block a Particle.publish even in SEMI_AUTOMATIC mode? I thought I found that in SEMI_AUTOMATIC mode it will block for only up to 8 seconds, then my loop will continue – but elsewhere there is no such exception documented?


So what is the best way to determine if I have an actual connection, and to be able to not have a Particle.publish blocked (or avoid firing it) when there isn’t a connection?

Thank you.

You should also investigate SYSTEM_THREAD(ENABLED)

I could be wrong but I don’t think SYSTEM_THREAD(ENABLED) on its own helps as much as it seems to on a Photon because Cellular.connect() is blocking (as well as potentially very slow) even in threaded mode. So in something like a vehicle that moves in and out of signal you might want some extra babysitting to make sure your local tasks are handled properly.
Other threads suggest a timer checking the status of Cellular.connecting in case it hangs for whatever reason which in turn could set a delay until retry or whatever approach best suits your particular application. Arguably it is hard to create a one size fits all solution unless at some later date the blocking behavior is somehow abolished completely.

OK, so is this correct:

In Setup(), I would add

SYSTEM_THREAD(ENABLED);
waitUntil(Particle.connected);  // This will block until a connection is established, just as if the above line wasn’t there.

in Loop(), when I want to do a publish, I could do:

if ( Particle.publish(…) )  {
	//Publish worked, expect results to hit my subscribe() handler soon
} else {
	// Publish didn’t work, continue on and try again in 5 minutes
}

Question 2: If the Particle.publish works (Electron is connected and webhook gets called), can I go about my business immediately upon return, or are there other aspects of the SYSTEM_THREAD(ENABLED) that I need to be concerned about (in regard to the “publish” itself, not in general)?

If I'm willing to ignore publish's that don't get sent due to no connection, is this necessary? That is, if at some time in the future the Electron is able to connect back up to the cloud, can I expect a publish done at that time to work? Or is the reconnection process not so automatic - in that I need to somehow make it happen?

Nope, if you looked at the docs about SYSTEM_THREAD(ENABLED) you might have seen the sample implementation putting it outside of setup() just the same as SYSTEM_MODE() would be.

And as @Viscacha mentioned in SEMI_AUTOMATIC Particle.connect() will be blocking (for some IMHO nonsensical reason), so you might want to consider MANUAL mode and make sure to call Particle.process() as often as possible.

That makes sense - hopefully I would have caught that when I went to include it.

But am I correct about how the publish would work and that it will return true (it worked) or false (no connection or other problem) and that it won't block?

Thanks.

Things recently got a bit hazy about what's blocking when and why, but I'd say Particle.publish() is (or should be) not blocking unless you also set the WITH_ACK flag. But without it set, the return value of Particle.publish() does not tell you whether the event was successfully published or the device is even connected, but only whether the "send request" was handed to the cellular module successfully or not.
However, once you called the function you can get on with your work and don't have to wait for the event to be sent.

That's actually just what I want. There's nothing it (or I) can do if it isn't connected, so the best that can happen is that it tries to send. And that the Electron reconnects by itself when possible.

The script at the other end of the webhook deals with making notification (via SMS) of a lost connection and/or a reconnection.

Thanks for the help.