Checking if Core is online and API return codes

Hey guys,

I have been trying to find a way to check whether a core is online at a specific moment (not scheduled), I did find a workaround, but the documentation says that it would return 404 if the CORE is not connected to the cloud but with the API calls I have only received it if an ONLINE core does not have the requested function. In addition, the API is returning codes which I believe do not make sense nor are very consistent.

Offline core:
GET devices/{deviceid}/variable: 408 Timeout: {ā€œerrorā€: ā€œTimed out.ā€}

POST devices/{deviceid}/function: 200 OK: {ā€œerrorā€: ā€œTimed out.ā€}

GET /devices/{deviceid}: 200 OK: {ā€œidā€: ā€œ{deviceid}ā€,ā€œnameā€: ā€œSpark coreā€,ā€œvariablesā€: null,ā€œfunctionsā€: null}

Online core:
GET devices/{deviceid}/variable: 200 OK: {ā€œcmdā€: ā€œVarReturnā€,ā€œnameā€: ā€œtestā€,ā€œerrorā€: ā€œVariable not foundā€,ā€œcoreInfoā€: {ā€œlast_appā€: ā€œā€,ā€œlast_heardā€: ā€œ2014-02-10T15:29:19.534Zā€,ā€œconnectedā€: true,ā€œdeviceIDā€: ā€œ{deviceid}ā€}}

POST devices/{deviceid}/function: 404 Not Found: {error: ā€œFunction not foundā€}

GET /devices/{deviceid}: 200 OK: {ā€œidā€: ā€œ{deviceid}ā€,ā€œnameā€: ā€œSpark coreā€,ā€œvariablesā€: null,ā€œfunctionsā€: null}

^^^^^ Last one could change if any variable or functions are exposed.

Yes, I could create a function and check for the ā€œconnected: trueā€ part, but there are some problems with this:

  • I have to send an already existing exposed function which I have to know before hand (which might change from core to core) and have to code it so itā€™s ignored because itā€™s just an online check and I want no action to be done.
  • I can expose a brand new function just to return 1 which effectively would reduce my exposed functions by 1 and of course, have to take the time to put it every time.

I guess meanwhile I could try sending a GET variable or POST function and check the Json for timeout.

My recommendations for the spark team:

  • I believe it would be awesome to have the ā€œconnected: {state}ā€ in the GET /devices/{deviceid}
  • If possible have the last_heard in the GET /devices/{deviceid} as well (in case this is saved after the core is disconnected)
  • Return 404 (or 408?) in GET /devices/{deviceid} if core is offline
  • Return a consistent code of 408 or 404 when doing /variable and /function on offline cores
  • Return 400 on a non exposed /variable and /function

Thanks for your time and for reading my post!

2 Likes

Hi @Iv4n,

Hmm, the device info endpoint should have a ā€˜connectedā€™ property. Iā€™m adding that back in, and it should be included in our next code push. Iā€™ve been trying to avoid returning 404ā€™s when the core is actually configured for that user. We return 404 when a user hits a core they donā€™t own / isnā€™t claimed. Youā€™re right in that the API should be as consistent as possible, and thatā€™s something weā€™ll converge towards definitely. We want to make sure we donā€™t break any existing apps (mobile, web, etc), so these changes might start appearing when we start v2.

You can get a list of all your cores and their connected status by hitting your devices endpoint:

https://api.spark.io/v1/devices?access_token=your_access_token

You can also hit the attributes endpoint for your core, and see the connected status there:

https://api.spark.io/v1/devices/your_core_id/?access_token=your_access_token

Thank you!
David

I get connected ā€˜trueā€™ even if my core is offline. What is the proper way to check if a core is online?

Hereā€™s the command i executed while my core was powered off:
curl https://api.spark.io/v1/devices/DEVICE_ID?access_token=ACCESS_TOKEN

and hereā€™s the result
{
ā€œidā€: ā€œDEVICE_IDā€,
ā€œnameā€: ā€œCORE_NAMEā€,
ā€œconnectedā€: true,
ā€œvariablesā€: [],
ā€œfunctionsā€: [],
ā€œcc3000_patch_versionā€: ā€œ1.29ā€
}

Hi @sarvagyavaish,

That property can have a half life of something like 10 minutes when a core connection is suddenly dropped / isnā€™t cleaned up properly. Iā€™m working on fixing this, but you can always try something like grabbing a variable from your core / calling a function if you need to be 100% certain your core is online. Sorry about any confusion that caused!

Thanks,
David

Hi @Dave,
I am having the same issue where the battery dies on my core but it still says it is online.
Since the core can go offline without me knowing i am checking if it is online first and then proceeding if it is. however 10 minutes is a long time and was hoping this would be fixed soon.

I saw your comment:

I'm working on fixing this

how is that going? have you identified a fix and if so do you know when it will go live?

If it won't be fixed soon is there a function i can call to flush the cache or something?

thanks for any info.

best,
jon

Hi @b3ko,

There are a few ways we could make the resolution a bit clearer on cores being online / offline. I had a project in the works recently, but had to delay it a bit. Ultimately it relates to how the socket is cleaned up by your core when it goes offline. If the socket is closed cleanly, the server will know the core is offline immediately, but if not it waits for the socket to time out.

What if I include the last ping time from your core in the device status API calls, so even if the API says itā€™s online and is wrong, youā€™ll get a timestamp of the last time your core pinged, so you can tune your own logic to say something like: ā€œIf my core hasnā€™t pinged in 10-30 seconds, then itā€™s offline even if the server says otherwiseā€

Thoughts? That way I can add enough information that you can get your desired behavior without adding any restrictions / assumptions to other peopleā€™s use case.

Thanks,
David

Iā€™ve been playing with making the devices/ calls, getting status back for a core showing whether itā€™s connected or not.

when the core is active, I get a quick response showing connected=true, when the core is offline, the response takes a very long time but eventually, after a few cups of coffee :> comes back connected=false.

Please fix this. Ideally the response is quick in either case. If the core is online, then the full response. If the core is offline, a response with just connected=false is fine. Just donā€™t make us wait.

Hi @uChobby,

Good question! There are two types of ā€˜onlineā€™ checks that the API will make, one is quick, and one is slow:

If you call the ā€œList devicesā€ endpoint, youā€™ll get a fast timeout of about 2 seconds:

#fast online check
GET /v1/devices

If you call the get device attributes endpoint, the api will wait for your core to reply with details about what variables and functions are registered. Iā€™m working on reducing this delay as much as possible, but right now that could mean the api waits up to 30 seconds for a reply back from your core.

#slower attributes check
GET /v1/devices/your_core_id

There is currently a private event when your cores come online, and Iā€™m working on adding an event for when the core goes offline, but this will have a lag time of about 60-90 seconds depending on if your core disconnects cleanly or not. :slight_smile:

I hope that helps!

Thanks,
David

1 Like

Awā€¦ so if we do a clean disconnect the response will be quick and accurate. That works fine for me. Is there anything special that we need to do in the firmware when we go to sleep to signal cleanly?

I have not tried this yetā€¦

1 Like

Hi @uChobby,

I suspect if youā€™re using semi_automatic / manual modes, you can call Spark.disconnect() - http://docs.spark.io/firmware/#spark-disconnect

Thanks,
David