How to get device information from afero Cloud?


#1

Hi,

I’m trying to connect afero Cloud with node.js.

I made a profile that has two attributes(LED and Button).

I can get access_token(OAuth Autheentication).
And I can also get user information(Get Information About a User).
But I cannot get current devices and state information.

Is there any idea about this case?

I’m do this with the following code.

var request = require(‘request’);
function getDeviceData(){

var headers = {
‘Content-Type’:‘application/json’,
‘Accept’:‘application/json’,
‘Authorization’:"Bearer " + access_token
}

var options = {
url: ‘https://api.afero.io/v1/accounts/’ + user_id + ‘/devices?expansions=state’,
method: ‘GET’,
headers: headers,
json: true,
}

request(options, function (error, response, body) {
console.log("Afero reuslt(body): ", body);
console.log("Afero reuslt(error): ", error);
})

}

Response from afero cloud is this.

Afero reuslt(body): {
timestamp: 1471998513506,
status: 403,
error: ‘Forbidden’,
message: ‘Access is denied’,
path: ‘/v1/accounts/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/devices’ }

Afero reuslt(error): null

Regards,
Takeshi


#2

Hi There…I think I might know the issue. In your example, you are passing the ‘user_id’ in the URL for device state, instead of the ‘accountId’ which is correct.

As you mention, you first (a) Get the OAuth Authentication. Next (b) you get the user information. Instead of using the userId field returned from step (b), use the accountId value instead, which looks like this in the response:


{
“account”: {
accountId”: “52s5e51b-gdsd-4460-wwew-fe508aff16c8”,
“type”: “CUSTOMER”,
“description”: “Primary Account”,
“createdTimestamp”: 1447977955915
}
}

Then, the endpoint you would call would NOT be this:

https://api.afero.io/v1/accounts/' + user_id + '/devices?expansions=state

but instead be this:

 https://api.afero.io/v1/accounts/' + accountId + '/devices?expansions=state

The HTTP Status 403-Forbidden you are getting right now I believe is because you are using a userId in the accountId field, and the Afero Cloud considers this an invalid request. Could you try this?


#3

Thanks for replying.

It seems my user information is wrong.
Because the accountAccess field is empty.

Response from server(uesr information) looks like this.

{ userId: ‘xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx’,
firstName: ‘Takeshi’,
lastName: ‘Matsumoto’,
lastUsedTimestamp: 0,
accountAccess: [ { account: [Object], privileges: [Object] } ],
partnerAccess: [ { partner: [Object], privileges: [Object] } ],
credential:
{ credentialId: ‘takeshi@xxxxx.co.jp’,
verified: true,
lastUsedTimestamp: 1472021803898,
type: ‘EMAIL’,
failedAttempts: 0 },
tos:
[ { currentVersion: 1,
userVersion: 1,
tosType: ‘user’,
url: ‘https://cdn.afero.io/tos/user/v1/user.html’,
needsAcceptance: false },
{ currentVersion: 1,
userVersion: 1,
tosType: ‘developer’,
url: ‘https://cdn.afero.io/tos/developer/v1/developer.html’,
needsAcceptance: false },
{ currentVersion: 1,
userVersion: 0,
tosType: ‘general’,
url: ‘https://cdn.afero.io/tos/general/v1/general.html’,
needsAcceptance: true } ] }

Some special setting is necessary for getting user information?
I made this kind of code for getting user information.

function getMeData(){

var headers = {
‘Content-Type’:‘application/json’,
‘Accept’:‘application/json’,
‘Authorization’:"Bearer " + access_token
}

var options = {
url: ‘https://api.afero.io/v1/users/me’,
method: ‘GET’,
headers: headers,
json: true,
}

request(options, function (error, response, body) {
user_id = body.userId;
console.log("Afero reuslt(body): ", body);
})

}


#4

Hi Takeshi, Hi Mike,

Mike is correct that the accountId is what the API wants, however, your API call to get your user information does not return correct information. I do not know why your accountAccess information is coming back empty, but I’ll be happy to look into it with the service engineers. If you can, please email me privately (developer @ afero.io) and I can look up your account on the service to see if there might be something wrong with it.

Once we get that fixed, you can use “https://api.afero.io/v1/accounts//devices” to get a list of the devices attached to your account, and then “devices?expansions=attributes” will give back attribute trees for all devices, or you can use “devices/?expansions=attributes” to get an attribute set from a specific device.

Be sure to check out this forum post (Do you have detailed documents for attribute,tags and stats for deivices) and the developer doc at (https://developer.afero.io/docs/en/?target=AttrRegistry.html) for information on atttributes and what they mean (and the somewhat non-intuitive format of the “data” field!)

Thank you!

Joe


#5

Hi, Joe and Mike,

I finally fully access cloud API from node.js.
I got device information and change attribute from my private server.

The following is my complete code.

function getAccessToken(){

var headers = {
‘Content-Type’:‘application/x-www-form-urlencoded’,
‘Authorization’:"Basic "+btoa(“xxxxxxxxxxxxxxxxxxxxxxxxxxx:xxxxxxxxxxxxxxxxxxxxxxxxxxxxx”)
}

var options = {
url: ‘https://api.afero.io/oauth/token’,
method: ‘POST’,
headers: headers,
body: “grant_type=password&username=” + encodeURIComponent(“xxxx@xxxx.xx.xx”) + “&password=” + encodeURIComponent(“xxxxxx”),
json: true,
}

request(options, function (error, response, body) {
access_token = body.access_token;
console.log("access_token: ", body.access_token);
console.log(“Check point 1.”);
getMeData();
});

}

function getMeData(){

var headers2 = {
‘Content-Type’:‘application/json’,
‘Accept’:‘application/json’,
‘Authorization’:"Bearer " + access_token
}

var options2 = {
url: ‘https://api.afero.io/v1/users/me’,
method: ‘GET’,
headers: headers2,
json: true,
}

request(options2, function (error, response, body) {
user_id = body.userId;
account_id = body.accountAccess[0].account.accountId;
console.log("Account ID(account_id): ", account_id);
getDeviceData();
})

}

function getDeviceData(){

var headers3 = {
‘Content-Type’:‘application/json’,
‘Accept’:‘application/json’,
‘Authorization’:"Bearer " + access_token
}

var options3 = {
url: ‘https://api.afero.io/v1/accounts/’ + account_id + ‘/devices?expansions=attributes’,
method: ‘GET’,
headers: headers3,
json: true,
}

request(options3, function (error, response, body) {

device_id = body[0].deviceId;

console.log("array number: ", body[0].attributes.length);

for(var i=0; i<body[0].attributes.length; i++){
    console.log(body[0].attributes[i]);
}

console.log("Afero result(deviceID): ", device_id);
console.log("Afero result(body): ", body);
console.log("Check point 3.");
doDeviceAction();
changeFriendlyName();

})

}

function doDeviceAction(){

var headers4 = {
‘Content-Type’:‘application/json’,
‘Accept’:‘application/json’,
‘Authorization’:"Bearer " + access_token
}

var options4 = {
url: ‘https://api.afero.io/v1/accounts/’ + account_id + ‘/devices/’ + device_id + ‘/actions’,
method: ‘POST’,
headers: headers4,
body: {type:‘attribute_write’, attrId:xxxx, data:‘01’},
json: true
}

request(options4, function (error, response, body) {
console.log("Afero result(body): ", body);
console.log("Afero result(error): ", error);
console.log(“Check point 4.”);
})

}

function changeFriendlyName(){

var headers5 = {
‘Content-Type’:‘application/json’,
‘Accept’:‘application/json’,
‘Authorization’:"Bearer " + access_token
}

var options5 = {
url: ‘https://api.afero.io/v1/accounts/’ + account_id + ‘/devices/’ + device_id + ‘/friendlyName’,
method: ‘PUT’,
headers: headers5,
body: {friendlyName:‘test’},
json: true
}

request(options5, function (error, response, body) {
console.log("Afero result(body): ", body);
console.log("Afero result(error): ", error);
console.log(“Check point 5.”);
})

}

Thank you.

Takeshi