How to force a handshake for OTA updates


#31

Yeah, That’s why I appreciate the support so much, it takes a lot of time to respond to the forum so often, I hope that Particle give you all your product for free for all the support you provide!!


#32

Have you tried

Particle.publish("spark/device/session/end", "", PRIVATE);

Publishing this event will disconnect your session and force a new session to be created. Don’t call it too often, as it will use several K bytes of data to re-authenticate and create a new session, but it should work for force it.


The secret OTA sauce... reliable OTA updates
nRF52840 Hardware Watchdog Question
Product Boron not updating to the newer firmware version when software resetting
#33

No I haven’t tried that! - I’ll give it a go, where would I have found out about this? (there might be other great tidbits I can implement)

Regards
Marshall


#34

That’s one I didn’t know either - was this shared with the Elite before? Must have missed the memo :pensive:


#35

Here is the missing publish issue. - sorry if this is the wrong thread, please move it if it is.

As you can see, when the device comes online it is missing the regular 5min publish that should be there.


#36

BTW, are you using a Particle SIM or 3rd party?


#37

third party.

The force handshake works!


#38

With a 3rd party SIM your keep alive may be too long for the providers requirements.
While it is true that a publish will do the UDP hole punching, for that the first attempt after the hole had already closed will probably fail as it is “consumed” in the process.

Have you set Particle.keepAlive() after the connection gets established?
There is an open issue regarding that
https://github.com/particle-iot/firmware/issues/1482


#39

What is the difference between this and just calling Particle.disconnect + Particle.connect (which is what I’ve been doing). I’ve been looking for an alternative to Particle.disconnect + Particle.connect due to the fact that i run mine in SEMI_AUTOMATIC and Particle.connect comes with the blocking risk. Would calling Particle.publish here allow me to achieve the same thing without the blocking risk? Note, I have the SYSTEM_THREAD enabled.


#40

Particle.disconnect will stop actively using the cloud connection, but will reuse the session upon reconnection. Reusing the saved session is normally a good thing because it saves several K bytes of data usage upon Particle.connect, including waking from sleep.

However, there’s an unknown condition where sometimes you might have trouble communicating and starting a new session seems to help.


#41

I have struggled to get reliable OTA for several months. I have a VERY tight power budget and hence spend a lot of time asleep. The app only wakes for a few seconds every 15 minutes, and doing long idle connects didn’t seem like a great solution. After combing dozens of threads I finally stumbled upon this one and the suggest that @rickkas7 provided to force a session disconnect / reset using

Particle.publish(“spark/device/session/end”, “”, PRIVATE);

It works! I only do it infrequently (once every four hours) but ending the Session is the ONE THING that seems to reliably force a new product firmware release to load. If this is the 'best practice’ for OTA updates that it be shared extensively with the community. Thank you @rickkas7 !!


#42

OMG. This is exactly what I’m looking for. But is there anyway to achieve this through the cloud, rather than initiating from the device?


Some devices are not updating their "last heard" or "last handshake" Why?
#43

Yes. If you PUT the disconnect endpoint for a device it will reset the cloud connection from the cloud side.

curl -X PUT https://api.particle.io/v1/devices/<deviceid>/disconnect?access_token=<token>

This should also work from the product endpoint using a product bearer token:

curl -X PUT https://api.particle.io/v1/products/<productid>/devices/<deviceid>/disconnect?access_token=<token>

#44

You’re a :star:

Worked like a charm.


#46

I’ve been using the particle rules engine for forcing updates based on this guide here:
https://docs.particle.io/tutorials/iot-rules-engine/dynamic-firmware-management/

Is this helpful?


#47

Hey all — to close the loop here — we’ve just announced a new feature to help intelligently deliver a firmware release as quickly as possible, but also without disrupting busy devices. I believe this new feature can help address challenges discussed in this post.

Check out our announcement here and let me know if you have questions: New OTA firmware capabilities and intelligent releases for optimized control


#48

I have been looking for something like this for weeks, and I finally found this … Thank you!


#49

Hi everyone,

I’ve been trying to figure out how to do this for free (not a premium customer, not planning on becoming one).

Old technique (Particle OS v0.6.1)

I used to just have all my devices subscribed to a private “fleetReset” event that I would manually publish to my product’s event stream using particle API, and that would cause every device in my fleet to reset at the same time. After reset, they would connect to the cloud again and at this point they would receive a firmware update. So I would “release” firmware to my fleet, and then cause all connected devices to reset simultaneously, which would result in coordinated fleet-wide firmware update to all my devices. Any device not connected at the time of the “fleetReset” publish would simply automatically receive firmware update next time it connected due to cloud handshake.

This technique does not work anymore (Particle OS v1.0.1)

When I try this technique now that I have upgraded all my fleet from 0.6.1 to 1.0.1, I am dismayed to find that a device reset does not result in a cloud handshake (now, the session is preserved across resets, so no handshake on reset, thus no firmware update).

Calling Particle.disconnect()/connect() does not force handshake (Particle OS v1.0.1)

In a post in this thread (above), @ScruffR said:

You can just Particle.disconnect() , wait a few seconds and Particle.connect() again.

I had the idea of refactoring my “fleetReset” logic to a “fleetHandshake” logic, based on the idea that if I call Particle.disconnect(), wait a minute, and then call Particle.connect(), the Electron should be forced to handshake with the Particle cloud on reconnect.

This is not the case. The new product default firmware does not get downloaded by using this technique, because this technique does not force a handshake with the cloud.

How to immediately flash to all my devices for FREE

It appears that the only option for forcing a firmware update to the fleet that is free is:

  • Use the Particle API to loop through each device in the fleet and send an API request to flash new firmware to each device

@jeiden is my understanding correct?


#50

@jaza_tom,

I use this API call to end a device’s cloud connection:

https://api.particle.io/v1/devices/XXX/disconnect?access_token=YYY

This forces a new handshake, which will result in an update if you’ve got something queued. Not as easy as your old method, but not as bad as looping through each device with particle update


#51

A reset does not seem to kill the session keys, pulling the RST pin does not, and pulling the EN pin does not on a Boron, unless it is done long enough, and I have not be able to determine that limit yet.

Have you tried this:

I am currently trying this for when a module hangs. My quest is to find a way to reset the device and session keys that work every single time from 1.0.1 and up, (It is a MAJOR pain). Otherwise we can not use this in a product.