简体   繁体   English

Electric IMP + PubNub:代理拨打额外电话

[英]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. 我正在从事一个IoT项目,该项目使用Electric Imp和PubNub进行通信,并使用Parse进行数据记录,云代码等。

For some reason my code in the IMP IDE is making multiple calls to PubNub channel, when I only want the event broadcasted once. 由于某种原因,当我只希望事件广播一次时,我在IMP IDE中的代码会多次调用PubNub通道。

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. 我想要的只是广播每个连接/事件一次...。但是正如您在我的server.log上看到的那样,似乎每个新的“ Build and Run”命令都广播了两次。

------------------- 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. 这可能是一个愚蠢的错误,因为我不熟练使用Squirrel。

Ignoring the first COMM message (which is strange) the problem does appear to just be the device.onconnect event firing twice. 忽略第一个COMM消息(这很奇怪),问题似乎只是device.onconnect事件触发了两次。 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;
    });
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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