The reason for the behavior is after a few failures to connect to the cloud, the whole networking stack is reset. This is a fairly logical choice, as it could have gotten into a bad state and resetting it will often allow the connection to succeed.
There would need to be some sort of flag and a change to the device OS to make that not happen.
You probably can work around this in user firmware one of two ways:
If you know you rarely use the cloud, you can make sure you only WiFi.connect() instead of Particle.connect(). I use this technique and it works well. My Photon communications are by TCP to a local server so I don’t need the cloud. However, I can send a command via the TCP connection to connect to the cloud so I can OTA flash. The normal state of my devices is breathing green, not breathing cyan.
The other is to use MANUAL mode to take over control so you stop connecting before the network stack reset occurs. For example, you could try connecting to the cloud for a minute, and if it doesn’t connect, stop trying to connect to the cloud for a minute or two, then try again later. Or maybe combine that with a ping test, or something along those lines.
I like your strategies, the command method is clever!
Thinking along similar lines. Perhaps after a few minutes of no cloud connection, call Particle.disconnect() to stop the WiFi disconnects.
This means that you only have the opportunity to connect on reset, which is fine for some applications.
One can envisage a middle ground of kicking off a Particle.connect() say every 10 mins (and calling Particle.disconnect() upon fail).
Thinking more about it, good idea re the ping to check for cloud connectivity whilst in a Particle disconnect state. if good, then Particle.connect(). I would use TCPClient instead of ping because of ping’s long blocking time.
Considering that it has been on the books for a while, will need to build a work around in the interim. This raises the question:
How does the Particle.connect() method determine “cloud available”? We could check this in the Particle.disconnected state, and only if good, call .connect().
Happy to report that a work around was developed. It uses rickkas7’s idea re ping() and extending his WiFi state machine technique.
It now disconnects from the Particle cloud after n attempts with no success. Thereafter, a ping to an internet host is performed every minute which, once successful, connects with the Particle cloud.
@Rickkas7, guess what? Have developed a more refined modification to your state machine:
Particle.connected() returns false, and then some ten seconds later, WiFi is disconnected (orange flash noticed at this point).
This ten second window gives one the opportunity to call Particle.disconnect()before the WiFi is disconnected, hence no pesky WiFi disconnect upon loss of Particle Cloud connectivity.
Next, check for internet connectivity at regular intervals using WiFi.ping() (but not too often because it blocks for 1 second if there is no connection). If there is both internet and WiFi connectivity, only then call Particle.connect() (which will not drop the connection).
Outcome is you can have constant WiFi, with or without Particle Cloud.