System events

System events overview

System events are messages sent by the system and received by application code. They inform the application about changes in the system, such as when the system has entered setup mode (listening mode, blinking dark blue), or when an Over-the-Air (OTA) update starts, or when the system is about to reset.

System events are received by the application by registering a handler. The handler has this general format:

void handler(system_event_t event, int data, void* moredata);

Unused parameters can be removed from right to left, giving these additional function signatures:

void handler(system_event_t event, int data);
void handler(system_event_t event);
void handler();

Here's an example of an application that listens for reset events so that the application is notified the device is about to reset. The application publishes a reset message to the cloud and turns off connected equipment before returning from the handler, allowing the device to reset.

void reset_handler()
{
    // turn off the crankenspitzen
    digitalWrite(D6, LOW);
    // tell the world what we are doing
    Particle.publish("reset", "going down for reboot NOW!");
}

void setup()
{
    // register the reset handler
    System.on(reset, reset_handler);
}

The button handlers may run as an interrupt service routine (ISR). There are limitations on what calls you can make from an ISR, see attachInterrupt for more information. Logging calls such as Log.info() do not work from the button handler as it's called from an interrupt service routine (ISR) and logging cannot be done from an interrupt context.

Some event types provide additional information. For example the button_click event provides a parameter with the number of button clicks:

void button_clicked(system_event_t event, int param)
{
    int times = system_button_clicks(param);
    Log.info("button was clicked %d times", times);
}

Registering multiple events with the same handler

It's possible to subscribe to multiple events with the same handler in cases where you want the same handler to be notified for all the events. For example:

void handle_all_the_events(system_event_t event, int param)
{
    Log.info("got event %d with value %d", (int)event, param);
}

void setup()
{
    // listen for Wi-Fi Listen events and Firmware Update events
    System.on(wifi_listen+firmware_update, handle_all_the_events);
}

To subscribe to all events, there is the placeholder all_events:

void setup()
{
    // listen for network events and firmware update events
    System.on(all_events, handle_all_the_events);
}