Device-os: Particle.keepAlive() API does not work

Created on 27 Jan 2018  路  3Comments  路  Source: particle-iot/device-os

Bug Report

Expected Behavior

You can call Particle.keepAlive(30); at any time and it should ping the server every 30 seconds. The system should keep track of the last TX/RX time and compare against the keepAlive interval (which if changed to a shorter setting may kick off a ping).

Observed Behavior

No activity in the log output every 30 seconds as expected when keepAlive is set before we are connected to the Cloud.

Steps to Reproduce

  • Run the test app and observe the log output.
  • Fails to work in THREADED or NON-THREADED mode
  • Tested with system firmware 0.7.0-rc.4 and 0.8.0-rc.1

Test App

SerialLogHandler logHandler(LOG_LEVEL_ALL);

SYSTEM_THREAD(ENABLED);

void setup() {
    Particle.keepAlive(30); // send a ping every 30 seconds
}

Workaround

Call keepAlive after we are connected to the Cloud.

void loop() {
    static bool once = false;
    if (!once && Particle.connected()) {
        Particle.keepAlive(30); // send a ping every 30 seconds
        once = true;
    }
}
bug confirmed

Most helpful comment

Expected behavior is just that, that you can call it any time and it just sets the ping interval. The system can keep track of the last TX/RX time and compare against the keepAlive interval (which if changed to a shorter setting may kick off a ping).

All 3 comments

Maybe the "expected" behaviour should be that you can call Particle.keepAlive() anytime (prior or after connection) or at least like Particle.variable(), Particle.function() and Particle.subscribe() before up to a few seconds after the connection and still work as expected.

Expected behavior is just that, that you can call it any time and it just sets the ping interval. The system can keep track of the last TX/RX time and compare against the keepAlive interval (which if changed to a shorter setting may kick off a ping).

Agreed with @technobly that the expected behavior is that there be no race condition for setting the keepAlive interval. Once set anywhere in the code, this should be propagated and preserved.

On a personal note, I spent a while independently rediscovering this bug, including an hour spent debugging with Particle's tech support. The bug also exists in 0.6.4 and 0.7.0. Think the fix will be backported?

P.S. As a follow-up, I found that the workaround can be simplified by keeping the code in setup(), as follows:

void setup() 
{
  // .
  // .
  // .

  Particle.connect();

  // Wait endlessly until the Particle is connected
  while (Particle.connected() == false) {
  }

  // Set the keep alive time. If this is too short, we won't be able to contact the Electron from the
  // Particle cloud.
  // NOTE: THIS MUST BE DONE AFTER THE PARTICLE IS CONNECTED. The upshot is
  // that in MANUAL or SEMI_AUTOMATIC modes this needs to be called after
  // Particle.connect() is successful.
  Particle.keepAlive(30);

  // .
  // .
  // .
}
Was this page helpful?
0 / 5 - 0 ratings