Error at "execute an action on a device"


#1

Hi,

I tried to “execute an action on a device” for study but “400 Bad request” returned.
I checked ‘device ID’ and ‘account ID’ in request URL and ‘access token’ in header but I can not find any errors.
I may misunderstand something. Could you tell me advice?

I attach tconsole.log(png) and header(png).

I try to upload my source program file but this forum can not accept text file and zip file.
So I paste my javascript program source in this topic.

Thank you.
Kazu.

==== source program ======
Sorry. I can not paste program normally. Topic editor analyze html tags. I will fix them.

I fixed. Cause is blank lines.

<html> <body> <script type="text/javascript"> var access_token; var accountId; var result; var deviceNum; var deviceId = new Array(); // authenticateUser("xxxxxxxxx@xxxxx.jp", "xxxxxxxxxxx") .then(function (result) { access_token = result.access_token console.log(access_token); return getUserInfo(result.access_token); // }).then(function (result) { console.log(result.toSource()); accountId = result.accountAccess[0].account.accountId; return getCurrentDevices(access_token, accountId); // }).then(function (result) { console.log(result.toSource()); deviceNum=result.length; console.log(deviceNum); for(iii=0;iii<deviceNum;iii++){ deviceId[iii] = result[iii].deviceId; } console.log(deviceId); return getCurrentTagsOfDevices(access_token, accountId); // }).then(function (result) { console.log(result.toSource()); return getCurrentStateOfDevices(access_token, accountId); // }).then(function (result) { // return getCurrentAttributesOfDevices(access_token, accountId); // }).then(function (result) { console.log(result.toSource()); return ExecuteActionDevice(access_token, accountId, deviceId[0]); // }).then(function (result) { console.log(result.toSource()); // }).catch(function (e) { // console.log(e); }); // // // Get OAuth token, instant gratification example function authenticateUser(username, password) { return new Promise(function (resolve, reject) { var tokenUrl = "https://api.afero.io/oauth/token"; var basicAuthorizationValue = btoa("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); var requestBody = "grant_type=password&username=" + encodeURIComponent(username) + "&password=" + encodeURIComponent(password); // var xhr = new XMLHttpRequest(); xhr.open('POST', tokenUrl, true); xhr.setRequestHeader("Authorization", "Basic " + basicAuthorizationValue); xhr.setRequestHeader('Content-Type', "application/x-www-form-urlencoded"); xhr.responseType = 'json'; // xhr.onload = function () { if (this.status >= 200 && this.status <= 299) { resolve(this.response); } else { reject(this.statusText); } return(this); // }; xhr.onerror = function (e) { reject(this.statusText); }; console.log(requestBody); xhr.send(requestBody); }); } // function getUserInfo(accessToken) { return new Promise(function (resolve, reject) { var tokenUrl = "https://api.afero.io/v1/users/me"; var xhr = new XMLHttpRequest(); xhr.open('GET', tokenUrl, true); xhr.setRequestHeader("Authorization", "Bearer " + accessToken); xhr.setRequestHeader('Content-Type', "application/json"); xhr.responseType = 'json'; // xhr.onload = function () { if (this.status >= 200 && this.status <= 299) { resolve(this.response); } else { reject(this.statusText); } return(this); // }; xhr.onerror = function (e) { reject(this.statusText); }; xhr.send(); }); } // function getCurrentDevices(accessToken, accountId) { return new Promise(function (resolve, reject) { var tokenUrl = "https://api.afero.io/v1/accounts/" + accountId + "/devices" ; var xhr = new XMLHttpRequest(); xhr.open('GET', tokenUrl, true); xhr.setRequestHeader("Authorization", "Bearer " + accessToken); xhr.setRequestHeader('Content-Type', "application/json"); xhr.responseType = 'json'; xhr.onload = function () { if (this.status >= 200 && this.status <= 299) { resolve(this.response); } else { reject(this.statusText); } return(this); // }; xhr.onerror = function (e) { reject(this.statusText); }; xhr.send(); }); } // function getCurrentTagsOfDevices(accessToken, accountId) { return new Promise(function (resolve, reject) { var tokenUrl = "https://api.afero.io/v1/accounts/" + accountId + "/devices?expansions=tags" ; var xhr = new XMLHttpRequest(); xhr.open('GET', tokenUrl, true); xhr.setRequestHeader("Authorization", "Bearer " + accessToken); xhr.setRequestHeader('Content-Type', "application/json"); xhr.responseType = 'json'; xhr.onload = function () { if (this.status >= 200 && this.status <= 299) { resolve(this.response); } else { reject(this.statusText); } return(this); // }; xhr.onerror = function (e) { reject(this.statusText); }; xhr.send(); }); } // // function getCurrentStateOfDevices(accessToken, accountId) { return new Promise(function (resolve, reject) { var tokenUrl = "https://api.afero.io/v1/accounts/" + accountId + "/devices?expansions=state" ; var xhr = new XMLHttpRequest(); xhr.open('GET', tokenUrl, true); xhr.setRequestHeader("Authorization", "Bearer " + accessToken); xhr.setRequestHeader('Content-Type', "application/json"); xhr.responseType = 'json'; xhr.onload = function () { if (this.status >= 200 && this.status <= 299) { resolve(this.response); } else { reject(this.statusText); } return(this); // }; xhr.onerror = function (e) { reject(this.statusText); }; xhr.send(); }); } // // function getCurrentAttributesOfDevices(accessToken, accountId) { return new Promise(function (resolve, reject) { var tokenUrl = "https://api.afero.io/v1/accounts/" + accountId + "/devices?expansions=attributes" ; var xhr = new XMLHttpRequest(); xhr.open('GET', tokenUrl, true); xhr.setRequestHeader("Authorization", "Bearer " + accessToken); xhr.setRequestHeader('Content-Type', "application/json"); xhr.responseType = 'json'; xhr.onload = function () { if (this.status >= 200 && this.status <= 299) { resolve(this.response); } else { reject(this.statusText); } return(this); // }; xhr.onerror = function (e) { reject(this.statusText); }; xhr.send(); }); } // function ExecuteActionDevice(accessToken, accountId, deviceId2) { // console.log(accessToken); console.log(accountId); console.log(deviceId2); // return new Promise(function (resolve, reject) { // var tokenUrl = "https://api.afero.io/v1/accounts/" + accountId + "/devices/" + deviceId2 + "/actions";

              var requestBody = "type=attribute_read&attrId=3&data=01";

// var requestBody = “type=attribute_write&attrId=3&data=01”;
///
var xhr = new XMLHttpRequest();
xhr.open(‘POST’, tokenUrl, true);
xhr.setRequestHeader(“Authorization”, "Bearer " + accessToken);
xhr.setRequestHeader(‘Content-Type’, “application/json”);
xhr.setRequestHeader(‘Accept’ , “application/json”);
//
//
xhr.responseType = ‘json’;
xhr.onload = function () {
if (this.status >= 200 && this.status <= 299) {
resolve(this.response);
} else {
reject(this.statusText);
}
return(this); //
};
xhr.onerror = function (e) {
reject(this.statusText);
};
console.log(requestBody);
// document.write(requestBody);
xhr.send(requestBody);
//
});
}
//
</script>
</body>
</html>


#3

Hi, Kazuya!

One quick thing to try, I have seen this before, instead of:

requestBody = “type=attribute_read&attrId=3&data=01”;

Can you please try to set the requestBody to:

{
type=attribute_read
attrId=3
data=01
}

(you can also try this, it should work as well)

requestBody = " { type=attribute_read,attrId=3,data=01 }";

Also, please note that an older version of the online developer documentation was wrong, the LED attribute in the Modulo is id=1024, not 3. Please see https://developer.afero.io/docs/en/?target=AttrRegistry.html for an updated list of attributes.

Please give that a try and let me know if it works for you!

Cheers,

Joe


#4

Hi, Joe

Thank you for your reply.

It seems that it does not work.
I tried following texts and so on.
var requestBody = “type=attribute_read&attrId=1024&data=01”;
var requestBody = “type=attribute_read,&attrId=1024”;
var requestBody = " { type=attribute_read&attrId=1024 }";
var requestBody = " { type=attribute_read&attrId=1024&data=01 }";
var requestBody = " { type=“attribute_read”&attrId=1024&data=“01” }";
var requestBody = " { type=“attribute_read”&attrId=1024 }";
etc.
Cheers,
Kazuya.


#5

Hi Kazuya,

My apologies, I wrote that stuff from memory instead of actually checking my notes. :frowning:

This string works for me for the request Body, I just tested it:

{ “type”: “attribute_write”, “attrId”: 1024, “data”: “00” }

The request parameters have to be in json format and not urlencoded.

Cheers,

Joe


#6

Hi, Joe.

It works.
Double quotes in json texts need escapes in javascript program like following script.

var requestBody = "{ “type”: “attribute_write”, “attrId”: 1024, “data”: “01” } "; //LED OFF
var requestBody = "{ “type”: “attribute_write”, “attrId”: 1024, “data”: “00” } "; //LED ON

Thank you.
Kazuya


#7

Hi Kazuya!

Excellent work! I’m happy that it’s working for you. Thank you also for posting your solution so other people can benefit from it. :smile:

Cheers,

Joe