Hello
I created the following webhook response handler to increase reliability of the delivery of the messages sent by the Electrons. The electrons are connected to machines that can send critical data at any moment so the objective of tracking the responses is to guarantee that the info reached the destination server or else resend.
Appreciate if anyone could comment and critique.
@ScruffR: appreciate your review in light of the discussion in this post Issues with sleep - Need advice on troubleshooting ideas and the need to reduce the risk of heap fragmentation. Thanks in advance
I’ve taken out all non-related code or variable definitions to focus on the response handling. Hope it’s clear. First time posting code.
STARTUP(System.enableFeature(FEATURE_RETAINED_MEMORY));
SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(SEMI_AUTOMATIC);
const int reintentos = 2; // number of retries to send to cloud before data is stored in local memory.
const int waitcloud = 5000; //time in ms to wait for Particle.connected
const int espera_ack = 45*1000; //wait time in seconds to receive acknowledge from the webhook response
//variables dealing with the webhook response
boolean data_in_flight_svc = FALSE; //use to signal the main loop that there was data published to cloud
int last_message;
int retries = 0; //
void setup() {
Particle.subscribe(System.deviceID() +"/hook-response/pub", respuesta_servicio, MY_DEVICES);
//... a bunch of other pin mode and attachInterrupt definitions
Particle.connect();
}
void loop() {
if (StartServ){ //flag set True from ISR when machine is turned ON
timestamp_on = Time.now(); //records time when machine is turned ON
if(waitFor(Particle.connected,waitcloud)) { // waitcloud is a constant set to 4-5 seconds
publicar_machine_on();
}
else { // no cloud then retry in a few secs
retries = 0;
data_in_flight = TRUE;
last_message = millis();
}
StartServ =FALSE;
}
if (millis() - last_message > espera_ack && data_in_flight){ //webhook response not received, retry again or quit after a number of retries
retries++;
if (Particle.connected() && retries <= reintentos){
publicar_machine_on();
}
else { // too many retries, quit retrying
data_in_flight = FALSE;
retries = 0;
}
}
// other loop code
}
// publish data to cloud function
void publicar_machine_on(){
char data[256];
snprintf(data, sizeof(data), "{\"maq\":%i, \"hora\":%i000}",1, timestamp_on); //
Particle.publish("pub_on",data,PRIVATE);
data_in_flight = TRUE;
last_message = millis();
}
// webhook responses handler.
void respuesta_servicio(const char *event, const char *codigo) {
int codigo_respuesta = atoi(codigo); // registers https response code. Looking for the success 201/200 codes
char evento_recibido[100]; //using chars instead of strings to avoid heap fragmentation?
strcpy (evento_recibido, event); //make a copy of the event data received
char dispositivo[25],a[25],b[6],c[1]; //b stores the label of the published event
// publish events handled by this webhook response handler
char key_1[] = "pubsvc";
char key_2[] = "pubinc";
char key_3[] = "pub_on";
char key_4[] = "puboff";
sscanf(evento_recibido, "%[^/]/%[^/]/%[^/]/%s",dispositivo,a,b,c);
if (strcmp(b,key_3) == 0){
if (codigo_respuesta == 201 || codigo_respuesta == 200) {
data_in_flight = FALSE; //successful receipt - resets flag and retries counter.
retries = 0;
}
}
//** There are 4-6 publish events handled by the same handler. only 1 shown above for this example but all handled similarly
}
Thanks in advance for the review
btw… thanks @chipmc. Most of the logic above is based on your recommendations