简体   繁体   中英

Electric IMP + PubNub: Agent making extra calls

I'm working on a IoT project that uses Electric Imp and PubNub for communication, and Parse for data logging, cloud code, etc.

For some reason my code in the IMP IDE is making multiple calls to PubNub channel, when I only want the event broadcasted once.

Here is the code:

#require "PubNub.class.nut:1.1.0"
#require "Parse.class.nut:1.0.1"
// Log the URLs we need
server.log("");
server.log("------------------- RESTART CYCLE ------------------")
server.log("Agent Loaded. Agent URL: " + http.agenturl());

local impID = imp.configparams.deviceid;
local reqCount = 0;
local myResponse = [];


// Connect to PubNub
const publishKey = "#####################";
const subscribeKey = "#####################";
pubNub <- PubNub(publishKey, subscribeKey);


// Subscribe to PubNub Channel
pubNub.subscribe([impID, "iPlugComm"], function(err, result, timetoken) {
    if (err != null) {
        server.log(err);
        return;
    }
    parseComm(result,timetoken);
});

// Connect to Parse.com
const APP_ID = "#####################";
const REST_API_KEY = "#####################";
parse <- Parse(APP_ID, REST_API_KEY);

server.log("imp id = "+impID);
server.log("----------------------------------------------------")
server.log("");

// Process URI Requests
function requestHandler(request, response) {
  try {
    // check if the user myCommand led as a query parameter
    if ("myCommand" in request.query) {
        local myVar = request.query.myCommand;
        response.header("Access-Control-Allow-Origin", "*");
        myResponse.append(response);
        device.send("myCommand", myVar);
    }else{
        response.send(500, "Invalid Command Sent");
    }
  } 
  catch (ex) {
    response.send(500, "Invalid Command Sent: " + ex);
  }
}

// Parse Incoming PubNub Message
function parseComm(result, timetoken){
  local time = timetoken;
  local idx = 1;
  local deviceID,
        deviceName, 
        deviceMode, 
        deviceMessage, 
        deviceAction, 
        deviceChannel;
  foreach (channel, data in result) {
      // logstr += ("Channel: " + channel + ": " + data["deviceName"]);
      deviceID =  data["deviceID"];
      deviceName = data["deviceName"];
      deviceMode = data["deviceMode"];
      deviceMessage = data["deviceMessage"];
      deviceAction = data["deviceAction"];
      deviceChannel = channel;
      if (idx++ < result.len()) {
          logstr += ", ";
      }
  }
  server.log("COMM on channel '"+deviceChannel+"' from "+ deviceName +": "+deviceMessage+".");
}

// Log Device Connection to Parse.com
local logINIT = parse.createObject("EventLog", {
  "deviceID" : impID,
  "deviceType" : "Electric Imp",
  "deviceMode" : "Slave",
  "deviceState" : "Online",
  "deviceName": "Agent-"+impID,
  "deviceMessage": "Imp restarted.",
  "deviceURL": http.agenturl()
})
logINIT.save(function(err, data) {
  if (err != null) server.log ("Could not update object: " + err.error)
});

device.onconnect(function() {
  server.log("Device CONNECTED to agent.");
  // Publish Connection
  pubNub.publish("iPlugComm", { 
      deviceID = impID,
      deviceName = "Agent-"+impID,
      deviceMode = "Slave",
      deviceMessage = "Imp Agent Restarted",
      deviceAction = "null",
  });
});

device.ondisconnect(function() {
    server.log("Device DISCONNECTED from agent");
    server.log("Device CONNECTED to agent.");
    // Publish Connection
    pubNub.publish("iPlugComm", { 
        deviceID = impID,
        deviceName = "Agent-"+impID,
        deviceMode = "Slave",
        deviceMessage = "Imp Device Disconnected",
        deviceAction = "null",
    });
});

// register the HTTP handler
http.onrequest(requestHandler);

What I would like is to just broadcast each connection/event once.... but as you can see by my server.log, I seem to be broadcasting twice with each new 'Build and Run' command.

------------------- RESTART CYCLE ------------------
2015-10-29 10:31:21 UTC-3   [Agent] Agent Loaded. Agent URL: https://agent.electricimp.com/#####
2015-10-29 10:31:21 UTC-3   [Agent] imp id = #########
2015-10-29 10:31:21 UTC-3   [Agent] ----------------------------------------------------
2015-10-29 10:31:21 UTC-3   [Agent] 
2015-10-29 10:31:21 UTC-3   [Agent] Device CONNECTED to agent.
2015-10-29 10:31:21 UTC-3   [Agent] COMM on channel '(null : (nil))' from (null : (nil)): (null : (nil)).
2015-10-29 10:31:22 UTC-3   [Agent] Device CONNECTED to agent.
2015-10-29 10:31:22 UTC-3   [Agent] Published data at 14461254820532282
2015-10-29 10:31:22 UTC-3   [Agent] COMM on channel 'iPlugComm' from Agent-237f476938a609ee: Imp Agent Restarted.
2015-10-29 10:31:22 UTC-3   [Agent] Published data at 14461254821522215
2015-10-29 10:31:22 UTC-3   [Agent] COMM on channel 'iPlugComm' from Agent-237f476938a609ee: Imp Agent Restarted.
2015-10-29 10:31:22 UTC-3   [Status]    Device connected
2015-10-29 10:31:22 UTC-3   [Device]    IMP Device Started

Anyone see where my error is? It's likely a dumb mistake as I'm not fluent with Squirrel.

Ignoring the first COMM message (which is strange) the problem does appear to just be the device.onconnect event firing twice. This is a known issue on our end (it only happens after Build and Run.)

One way to work around the problem might be to set a short "debounce" timer of sorts:

local debounce = false;
device.onconnect(function() {
    if (debounce) return;
    // Do stuff
    debounce = true;
    imp.wakeup(1, function() {
        debounce = false;
    });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM