device.isconnected() - is it real time ?

Hello,
I've made some test with device.isconnected() in agent , but it's like dosn't check real time, what I mean:
AGENT

function test(){
if(device.isconnected()){
server.log("device: ONLINE")
} else {
server.log("device: OFFLINE")
}
imp.wakeup(60,test)
}
test()


From Log:


10:00 - internet connection is interrupted
2017-02-24 10:00:26 UTC+2 [Agent] device: ONLINE
2017-02-24 10:01:26 UTC+2 [Agent] device: ONLINE
2017-02-24 10:01:46 UTC+2 [Status] Device disconnected
2017-02-24 10:02:26 UTC+2 [Agent] device: OFFLINE

10:25 - internet connection is interrupted
2017-02-24 10:25:26 UTC+2 [Agent] device: ONLINE
2017-02-24 10:26:26 UTC+2 [Agent] device: ONLINE
2017-02-24 10:27:26 UTC+2 [Agent] device: ONLINE
2017-02-24 10:28:26 UTC+2 [Agent] device: ONLINE
2017-02-24 10:29:26 UTC+2 [Agent] device: ONLINE
2017-02-24 10:30:26 UTC+2 [Agent] device: ONLINE
2017-02-24 10:31:26 UTC+2 [Agent] device: ONLINE
2017-02-24 10:32:13 UTC+2 [Status] Device disconnected
2017-02-24 10:32:26 UTC+2 [Agent] device: OFFLINE

10:49 - internet connection is interrupted
2017-02-24 10:49:12 UTC+2 [Agent] device: ONLINE
2017-02-24 10:50:12 UTC+2 [Agent] device: ONLINE
2017-02-24 10:51:12 UTC+2 [Agent] device: ONLINE
2017-02-24 10:52:12 UTC+2 [Agent] device: ONLINE
2017-02-24 10:53:12 UTC+2 [Agent] device: ONLINE
2017-02-24 10:54:12 UTC+2 [Agent] device: ONLINE
2017-02-24 10:55:12 UTC+2 [Agent] device: ONLINE
2017-02-24 10:56:12 UTC+2 [Agent] device: ONLINE
2017-02-24 10:57:12 UTC+2 [Agent] device: ONLINE
2017-02-24 10:57:49 UTC+2 [Status] Device disconnected
2017-02-24 10:57:54 UTC+2 [Agent] Device disconnected from agent <- device.ondisconnect()
2017-02-24 10:58:12 UTC+2 [Agent] device: OFFLINE


The same is the behavior of device.ondisconnect()

Any solution to take real time connection status of device from agent ?

Comments

  • According to Imp documentation for device.isconnected(), "This is typically done before attempting to send messages and data to the device — if the device is not connected, those messages will be lost." Hence Agent needs to periodically send a simple ping message to the device first then apply function (may need to wait a short time for timeout to kick in).

    There is a new library MessageManager that should help with these sort of checks.
  • Sending ping/alive message dosn't help ...
    Agent code:

    function test(){
    device.send("is.alive.device",1)
    if(device.isconnected()){
    server.log("device: ONLINE")
    } else {
    server.log("device: OFFLINE")
    }
    imp.wakeup(10,test)
    }
    test()

    Device

    agent.on("is.alive.device",function(var){
    server.log("Alive message from agent")
    })

    Another very strange behavior - device is OFFLINE, I'm making changes on code, and Building the code, and Log shows from above function:

    2017-02-24 15:18:54 UTC+2 [Status] Agent restarted: reload.
    2017-02-24 15:18:54 UTC+2 [Agent] device: OFFLINE <- it's really TRUE
    2017-02-24 15:19:04 UTC+2 [Agent] device: ONLINE <- it's really FALSE
    2017-02-24 15:19:14 UTC+2 [Agent] device: ONLINE <- it's really FALSE
    2017-02-24 15:19:24 UTC+2 [Agent] device: ONLINE <- it's really FALSE


    A take look at MessageManager, but it is using ConnectionManager ( never call server.connect() ), which I'm using ...
  • Not surprised by the outcome. It's worth searching online forum for reasons as to how device.isconnected works regarding timing of switching to OFFLINE.

    MessageManager is supposed to help.

    Otherwise it is better to directly monitor pings to device. This works:

    Agent:


    //create global var
    devConnected <- false;

    function onlineConfirm(var) {
    devConnected = true;
    }

    function pingChecker() {
    if(devConnected) server.log("device: ONLINE");
    else server.log("device: OFFLINE");
    }

    function pingdevice() {
    devConnected = false;
    device.send("Ping", 1);
    imp.wakeup(5, pingChecker); // can fiddle with timings to optimise
    imp.wakeup(20,pingdevice);
    }

    pingdevice();

    device.on("confirmPing", onlineConfirm);


    Device:

    function returnToImp(var) {
    agent.send("confirmPing", 1);
    }
    agent.on("Ping", returnToImp);
  • Thank you very much Gerrikoio.
  • Note that a silent connection is assumed to be alive; this is the way TCP works. We perform keepalives down at the TCP level, but pending data will defeat these (that's the way TCP keepalives function).

    Higher level keepalives are also sent, and if the TCP keepalive doesn't kill the connection (~90s worst case on a quiet link) then the high level one will kill it (worst case is ~540s).

    As @gerrikoio says, you can do a ping to instantaneously confirm a device is there; generally you will get the reply back in only tens of milliseconds over the actual packet round-trip time. Some people also just do periodic imp->agent pings, eg every minute, and then their agent code checks how fresh the last one was to determine an offline time.

    On the device side, loss of connection indication is generally very fast if it's a wifi disassociate (handful of seconds), but ~90s if it's a routing outage (packets getting lost between the AP and the server).
Sign In or Register to comment.