Want to wait until my publish has finished and then go to sleepmode

Dear forum,

I would like to ask you for an advice. What is the best way to wait for a publish event to finish and then go to deep sleep mode?

Have you tried a forum search already?

1 Like

I do not see any answer that is solving this . I think it might not be possible to do it.

The first link solves your problem :wink: You need to publish a second event and subscribe to it. Then you can send your Photon, etc. to sleep.

1 Like

Is this for the Electron? I had an idea to use the new cellular data API to wait for data to go out. This is the proof of concept I threw together to test it. I think it works; I mean the publish goes out. And it sleeps pretty quickly. I’m not positive I like the idea, but feel free to run with the idea if you so desire.
UPDATE: This is completely unnecessary because in 0.5.0 the Electron waits until publishes go out before sleeping!

For the Photon, since data usage is not as much of an issue, I’d subscribe to my own event.

// This program requires system firmware 0.5.0 or later
#include "Particle.h"

bool publishAndWait(const char *eventName, const char *eventData, int ttl, PublishFlag eventType=PUBLIC);

void setup() {
	Serial.begin(9600);
}

void loop() {
	publishAndWait("testevent", "testing", 60, PRIVATE);
	System.sleep(SLEEP_MODE_DEEP, 60);
}


bool publishAndWait(const char *eventName, const char *eventData, int ttl, PublishFlag eventType)
{
	CellularData dataBefore;

	bool hasDataBefore = Cellular.getDataUsage(dataBefore);

	if (!Particle.publish(eventName, eventData, ttl, eventType)) {
		return false;
	}

	if (!hasDataBefore) {
		// Was unable to get data usage, so just delay a while
		delay(2000);
		return true;
	}

	unsigned long startMillis = millis();

	while(millis() - startMillis < 10000) {
		// Wait at most 10 seconds
		CellularData dataAfter;
		if (Cellular.getDataUsage(dataAfter)) {
			if (dataAfter.tx_session > dataBefore.tx_session && dataAfter.rx_session > dataBefore.rx_session) {
				break;
			}
		}

		delay(250);
	}

	// Serial.printlnf("waited %lu ms", (millis() - startMillis));

	return true;
}

Waiting for ones own event to loop back is a bit of a hack, by definition it means the photon is not sleeping as soon as possible.
Although with wifi connecting that small added delay may not be a big issue, you also need to code for the eventuality that your publish fails by lost wifi/cloud after it being sent, so its unnessary complex for simply wanting to sleep as soon as possible :confused:

@rickkas7, that method shows it’s gone out only but even the self-subscription method doesn’t guarantee the publish actually made it to the intended subscriber or subscribers. Ideally, the subscription would be for a target generated event. However, that doesn’t work so much when there are multiple targets. That’s why I simply do a Particle.process() and a small delay after the final publish().

I said I had an idea; I didn’t say I had a good idea! LOL

LOL!!! My take is that SSE is a lot like UDP. You send it and hope for the best since there is no specific mechanism for acknowledgement of receipt. :confused:

On the electron, 0.5.0 firmware will not sleep until the publish has been received by the cloud. On the Photon, we will make publishes confirmable, so that the device can be sure the published event was received.

6 Likes

Was this ever added as I kind of abandoned a project I was working on in order to wait for it to be added. I really need to go into deep sleep as soon as possible as battery power is really at a premium in my project.

This is part of v0.6.0.

Checkout the update thread announcement about 0.6.0-rc.1

Sorry to sound like an idiot but I can’t see it in the list of changes. Could you either point me to the exact documentation or just tell me how to check if the event has been successfully published?

Also I’m now running into the issue that after installing 0.6.0 the web ide will no longer actually flash my device for me. It just times out which is fun. But the local one will still flash it.

Sorry, my bad!
I just remembered this part of the update and confused it with Particle.publish()

BREAKING CHANGES
UDP.flush() and TCP.flush() now conform to the Stream.flush() behavior from Arduino 1.0 Wiring. The current (correct) behavior is to wait
until all data has been transmitted. Previous behavior discarded data in the buffer. #4692

I've just seen that enhancement got pushed to 0.7.0
https://github.com/spark/firmware/issues/1034

But I'm not sure why the lack of this feature would cause you to abandon your project. Unless you have everything else worked out completely the extra seconds delay before going to sleep should not make or break the project. If you had this little margine, you might run into other issues anytime when other tasks require slightly more power than anticipated.