Skip to content

Instantly share code, notes, and snippets.

@ElectricImpSampleCode
Last active June 2, 2021 08:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ElectricImpSampleCode/c9d61d17c969510dd2f64b036413b579 to your computer and use it in GitHub Desktop.
Save ElectricImpSampleCode/c9d61d17c969510dd2f64b036413b579 to your computer and use it in GitHub Desktop.
imp API Cookbook recipe: repeating timers
class Timer {
static version = "1.0.0";
/*
* Private Properties
*/
_repeat = true;
_period = 0;
_timer = null;
_cb = null;
/*
* @constructor
*
* @param {Integer|Float} period - The period before the timer fires
* @param {Bool} repeat - Should the timer repeat. Default: true
* @param {Function} callback - The function to be called when the timer fires
*
*/
constructor(period, repeat = true, callback = null) {
if (!(typeof period == "integer" || typeof period == "float"))
throw "Timer period must be an integer or float";
if (typeof repeat != "bool")
throw "Timer repeat must be true or false";
if (typeof callback != "function" || callback == null)
throw "Timer callback must be a function";
_period = period;
_repeat = repeat;
_cb = callback;
_timer = imp.wakeup(_period, _firee.bindenv(this));
}
/*
* Call the timer's target immediately.
*
* This does not affect the timer, which will fire after the set period
*
*/
function fire() {
if (_cb != null) imp.wakeup(0, _cb);
if (!_repeat) invalidate();
}
/*
* Invalidate the timer immediately.
*
* If the timer has not yet fired when this is called, it will not do so
*
*/
function invalidate() {
if (_timer != null) {
imp.cancelwakeup(_timer);
_timer, _cb = null;
}
}
/*
* Indicates whether the timer is valid.
*
* A valid timer is one that has been set and, if it is non-repeating, has
* not yet fired. Repeating timers remain valid.
*
* @returns {Bool} whether the timer is valid (true) or not (false)
*
*/
function isValid() {
return (_timer != null);
}
/*
* Internal timer fire handler
*
* @private
*
*/
function _firee() {
// The timer has fired: trigger the callback
fire();
// Re-schedule or invalidate the timer
if (_repeat) {
_timer = imp.wakeup(_period, _firee.bindenv(this));
} else {
_timer, _cb = null;
}
}
}
// Early-run code
server.setsendtimeoutpolicy(RETURN_ON_ERROR, WAIT_TIL_SENT, 10);
/*
* Include the Timer class here
*/
// Set an LED on pin M (imp003 and up)
hardware.pinM.configure(DIGITAL_OUT, 0);
// Record LED state
state <- true;
// Instantiate a repeating (true) timer that will fire in 10 seconds,
// and then every subsequent 10 seconds, to call the inline function,
// which flips the LED state
timer <- Timer(10, true, function() {
hardware.pinM.write(state ? 1 : 0);
state = !state
});
// Cause the timer to fire prematurely after 15 seconds
imp.wakeup(15, function() {
if (timer.isValid()) timer.fire();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment