From 63b6c50c586be3a5ccfb1971453bcf96bc0d9dcb Mon Sep 17 00:00:00 2001 From: Dustin Franco Date: Tue, 5 Jul 2016 16:20:12 -0700 Subject: [PATCH 1/5] added a comment about a confusing section of code --- sensor.agent.nut | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sensor.agent.nut b/sensor.agent.nut index d275c46..7471895 100644 --- a/sensor.agent.nut +++ b/sensor.agent.nut @@ -311,6 +311,10 @@ device.on("data", function(data) { // Commented out while hacking on the new power controller send_data_json_node(dataToSendNode); } else {//WITH powerdata + //SO MUCH DRY + //Does this else even happen? it seems like it would throw errors if it did... + //explanation: it seems to interpret power data, but it's only happens if powerData isn't present in the reading + //I *think* it's here because we transitioned into powerData being it's own table, so this was here for some reason? local dataToSend = data; local dataToSendNode = {}; dataToSendNode.uuid <- data.device; From 2075e19022f58fe4ff894d42c32f3ca083acd8c5 Mon Sep 17 00:00:00 2001 From: Dustin Franco Date: Tue, 5 Jul 2016 16:30:06 -0700 Subject: [PATCH 2/5] removed a server.log that has been making me cringe for a literal year --- sensor.device.nut | 1 - 1 file changed, 1 deletion(-) diff --git a/sensor.device.nut b/sensor.device.nut index 8d8397f..7296d60 100644 --- a/sensor.device.nut +++ b/sensor.device.nut @@ -1015,7 +1015,6 @@ function send_data(status) { } if(sendFullRead) { - server.log("FULL RES BABY") agent.send("fullRes", { bend=buffer1, tail=buffer2, From 38436b5b34268e337e3279a3dc8de0c77e16ac78 Mon Sep 17 00:00:00 2001 From: Dustin Franco Date: Tue, 5 Jul 2016 16:33:29 -0700 Subject: [PATCH 3/5] added variables necessary for exponential backoff --- sensor.agent.nut | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/sensor.agent.nut b/sensor.agent.nut index 7471895..745b173 100644 --- a/sensor.agent.nut +++ b/sensor.agent.nut @@ -8,7 +8,6 @@ #require "Loggly.class.nut:1.0.1" macAgentSide <- imp.configparams.deviceid; -GlobalTest <- 1 fullResSet <- false THEMACADDRESSAGENTSIDE<-"unknownMacAddress" @@ -22,6 +21,15 @@ loggly <- Loggly(logglyKey, { "limit" : 20 //arbitrary }); +globalDataStore <- []; +agentSendBackoffTimes <- [0.1, 1.0, 2.0, 4.0, 8.0, 15.0, 30.0, 60.0]; +//agentRetryActive prevents multiple chains of retrySendingDataIfNeeded +agentRetryActive <- false; +const FAILED_READINGS_WARNING = 100; +agentBackoffIndex <- 0; + + + function addLogglyDefault(logTable){ logTable.macAddress <- macAgentSide; logTable.sourceGroup <- "Firmware"; From 3604fb652b969f00df358411c0fb29455a434750 Mon Sep 17 00:00:00 2001 From: Dustin Franco Date: Tue, 5 Jul 2016 16:42:12 -0700 Subject: [PATCH 4/5] added code to send_data_json_node function that stored readings if it fails to send to the agent --- sensor.agent.nut | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sensor.agent.nut b/sensor.agent.nut index 745b173..4388453 100644 --- a/sensor.agent.nut +++ b/sensor.agent.nut @@ -104,6 +104,10 @@ function send_data_json_node(data) { server.log("Error sending message to Postgres database."); local logglyWarnTable = failedSendTable(readings_url, res.body, res.statuscode); logglyLog(logglyWarnTable, "Warning"); + for(local x = 0; x < data.data; x++){ + server.log("adding data point with timestamp " + data.data[x].timestamp + " to globalDataStore"); + globalDataStore.append(data.data[x]); + } } else { server.log("Data sent successfully to Postgres database."); } From e7a88bb52ea0b383a78d2f3d661a4328b904a9b7 Mon Sep 17 00:00:00 2001 From: Dustin Franco Date: Tue, 5 Jul 2016 18:04:28 -0700 Subject: [PATCH 5/5] began working on functionality, not quite right just yet --- sensor.agent.nut | 60 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 7 deletions(-) diff --git a/sensor.agent.nut b/sensor.agent.nut index 4388453..7487c3a 100644 --- a/sensor.agent.nut +++ b/sensor.agent.nut @@ -26,6 +26,7 @@ agentSendBackoffTimes <- [0.1, 1.0, 2.0, 4.0, 8.0, 15.0, 30.0, 60.0]; //agentRetryActive prevents multiple chains of retrySendingDataIfNeeded agentRetryActive <- false; const FAILED_READINGS_WARNING = 100; +readings_url <- "https://api.sensor.prod.edyn.com/readings"; agentBackoffIndex <- 0; @@ -89,7 +90,8 @@ function failedSendTable(targetURL, body, statuscode){ // Send data to the readings API function send_data_json_node(data) { server.log(http.jsonencode(data)); - local readings_url = "https://api.sensor.prod.edyn.com/readings"; + server.log("THE TYPE") + server.log(type(data)) local headers = { "Content-Type":"application/json", "User-Agent":"Imp", @@ -104,9 +106,13 @@ function send_data_json_node(data) { server.log("Error sending message to Postgres database."); local logglyWarnTable = failedSendTable(readings_url, res.body, res.statuscode); logglyLog(logglyWarnTable, "Warning"); - for(local x = 0; x < data.data; x++){ - server.log("adding data point with timestamp " + data.data[x].timestamp + " to globalDataStore"); - globalDataStore.append(data.data[x]); + for(local x = 0; x < data.len(); x++){ + server.log("adding data point with timestamp " + data.timestamp + " to globalDataStore"); + globalDataStore.append(data[x]); + } + if(!agentRetryActive){ + retrySendingDataIfNeeded() + agentRetryActive = true; } } else { server.log("Data sent successfully to Postgres database."); @@ -320,7 +326,7 @@ device.on("data", function(data) { server.log("at_input_ilim " + dataToSendNode.data[0].at_input_ilim + ", ovp_active " + dataToSendNode.data[0].ovp_active); server.log("input_uvcl_active " + dataToSendNode.data[0].input_uvcl_active + ", disable_input_uvcl " + dataToSendNode.data[0].disable_input_uvcl); server.log("ntc_warning " + dataToSendNode.data[0].ntc_warning); - // Commented out while hacking on the new power controller + // Commented out while hacking on the new power controller\ send_data_json_node(dataToSendNode); } else {//WITH powerdata //SO MUCH DRY @@ -523,7 +529,7 @@ device.on("data", function(data) { server.log("at_input_ilim " + dataToSendNode.powerData.at_input_ilim + ", ovp_active " + dataToSendNode.powerData.ovp_active); server.log("input_uvcl_active " + dataToSendNode.powerData.input_uvcl_active + ", disable_input_uvcl " + dataToSendNode.powerData.disable_input_uvcl); server.log("ntc_warning " + dataToSendNode.powerData.ntc_warning); - // Commented out while hacking on the new power controller + // Commented out while hacking on the new power controller\ send_data_json_node(dataToSendNode); } @@ -643,7 +649,47 @@ http.onrequest(function (request, response) { - +function retrySendingDataIfNeeded(){ + //globalDataStore.len() is called many times rather than being a single variable because it changes throughout the function. + local numberReadings = globalDataStore.len(); + if(numberReadings){ + if(numberReadings > FAILED_READINGS_WARNING){ + server.log("WARNING: " + globalDataStore.len() + " unsent readings!"); + logglyLog({"warning" : globalDataStore.len() + "unsent readings!"}, "Warning") + } + local sendDataSuccess = send_data_json_node(globalDataStore); + //if send is successful: + if(sendDataSuccess < 204 && sendDataSuccess > 199){ + server.log("readings sent successfully"); + globalDataStore = []; + agentRetryActive = false; + //if it's failed before + if(agentBackoffIndex > 0){ + //loggly warning about the send failing + logglyLog( + { + "message" : "readings sent successfully after failing " + (agentBackoffIndex + 1) + " times" + } + , "Warning"); + agentBackoffIndex = 0; + } + } else { + server.log("Agent side send readings unsuccessful") + if(agentBackoffIndex < agentSendBackoffTimes.len()){ + imp.wakeup(agentSendBackoffTimes[agentBackoffIndex] * 60.0, retrySendingDataIfNeeded); + } else { + imp.wakeup(agentSendBackoffTimes[agentSendBackoffTimes.len() - 1] * 60.0, retrySendingDataIfNeeded); + } + agentBackoffIndex += 1; + logglyLog( + { + "message" : "failed to send readings to backend from agent" + } + , "Warning" + ); + } + } +}