Execute an Action on a Device using Cloud APIs


#1

Greeting Everyone!

I am current trying to use the cloud apis to call an action on the first i/o pin. I am using C# in Unity and got the OAuth token taking care of. I am able to get user information, userId, deviceId etc… by following the very clear documentations. One last hiccup is that I am trying to call an action to turn on/off the pin 1. I got the error message back saying --{“error”:“httpMessageNotReadable”,“error_description”:""}-- I am guessing I may have format the POST request payload incorrectly.

Here’s the URL endpoint I’ve used (accountId and deviceId not showing here) “https://api.afero.io/v1/accounts/” + accountId + “/devices/” + deviceId + “/actions”

I am following the request payload format from the docs like this
{
“type”: “attribute_write”,
“attrId”: 1,
“data”: “01”
}
and the same header structure with the oath access token that I used to get all the device id and status.

But I am not getting the JSON respond the document shown. If anyone have any idea or advice would be greatly appreciated.

Thanks!
Mankit


Do you have detailed documents for attribute,tags and stats for deivices
#3

Hi, Mankit!

So the good news is that your requests are all correct and should work. The bad news is the Attribute ID you’re using isn’t the correct one for the GPIO you’re trying to set, which is why you’re getting an error.

What I need to do after I reply to you is to a) file a bug to get that error message rewritten to be a little more explanatory, and b) file a bug to update the developer docs with the proper attribute information for direct API requests.

A lot of that attribute information has changed over the last few months as we expand the platform’s functionality, which is nice, but it leaves the developer documentation out of date. Sorry about that! We’ll get it updated ASAP.

For now, to toggle a GPIO pin on the Modulo, use the following attributeID and data:

GPIO off (low) “data”: "00"
GPIO on (high) “data”: “01”

GPIO 0 = “attrId”: 1024
GPIO 1 = “attrId”: 1026
GPIO 2 = “attrId”: 1028
GPIO 3 = “attrId”: 1030

You can turn on the Modulo LED with:
{
“type”: “attribute_write”,
“attrId”: 1024,
“data”: “00”
}
(and back off with data=“01”)

The LED on the Modulo is Active Low so you actually set it to “00” to turn it on and “01” to turn it off but you’re setting the GPIO properly (00=low, 01=high)

The other “skipped” attribute IDs (1025, 1027, 1029, 1031) are configuration attributes that you can use to set the parameters for the I/O port. We’ll put full documentation in an update to the developer docs, but quickly here are some of the things you might need to know.

Writing to the configuration attribute of a port (it’s the GPIO port plus one, 1025, 1027, 1029, 1031) with the following bits set will define the GPIO’s function:

Bit Name Description
0 Direction 0 = output, 1 = input
1 ADC 1 = Configure pin as an ADC (only valid if direction is input)
2 Pull Up 1 = Configure internal pull up (only valid if direction is input)
3 Pull Down 1 = Configure internal pull down (only valid if direction is input)
4 PWM 1 = Configure pin as PWM (only valid if direction is output)
5 Comparator 1 = Configure pin as Comparator (only valid if direction is input)
6 Toggle 1 = Configure pin as Toggle (only valid if direction is input, and not set as Count)
7 Pulse 1 = Configure pin as Pulser (only valid if direction is output)
8 Active Low 1 = active level of pin is LOW, 0 = active level of pin is HIGH
9 Count 1 = Configure pin to count input pulses (only valid if direction is input, and not set as Toggle)
16-47 Comparator Percentage/PWM Frequency/Pulse Configuration
If Comparator bit is set, than this 32 bit value represents the percentage of reference voltage to compare against.
If PWM bit is set, than this 32 bit value represents the frequency in hertz for the PWM.
If Pulse bit is set, than this 32 bit value represents two 16 bit values:
16-31: Pulse width in milliseconds
32-47: Minimum time between pulses in milliseconds
48-51 Bound IO

The information on PWM/Comparator settings and Binding is a little long to just paste here, so we’ll get it into the developer docs as soon as we can. That said, if you’re intending to use the Modulo for PWM generation or an analog voltage comparison, let us know and I’ll paste up something useable in the forum for you if you need it before we get the documentation upgraded.

Good catch, thanks for pointing this out to us!

Joe


#4

Hi Joe,

Thank you for the thorough reply so quickly! The predefined attribute ID now all make sense to me. I was wonder why when I listing my current devices and state information. It come back with the JSON that got the id of 1024, 1025…1030,1031 because I only setup GPIO 0 and GPIO 3. Now I know. :smile:

[ {“deviceId”:“XXXXXXXXXXXXXXXX”, “profileId”:“XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX”, “updating”:“false”, “createdTimestamp”:“1461701642509”, “virtual”:“false”, “disconnectNotificationLevel”:“LOW”, “friendlyName”:“Afero01”, “attributes”:[ {“id”:“1024”, “data”:“0000”, “value”:“0”, “updatedTimestamp”:“1467912356883”}, {“id”:“1025”, “data”:“0001000000000000”, “value”:“256”, “updatedTimestamp”:“1467912356975”}, {“id”:“1030”, “data”:“0100”, “value”:“1”, “updatedTimestamp”:“1467912357076”}, {“id”:“1031”, “data”:“4500000000000000”, “value”:“69”, “updatedTimestamp”:“1467912357177”}, {“id”:“2001”, “data”:“0000000000000000”, “value”:“0”, “updatedTimestamp”:“1467912357306”}, {“id”:“2002”, “data”:“0000000000000000”, “value”:“0”, “updatedTimestamp”:“1467912357391”}, {“id”:“2003”, “data”:“E60C000000000000”, “value”:“3302”, “updatedTimestamp”:“1467912357467”}, {“id”:“2004”, “data”:“6313000000000000”, “value”:“4963”, “updatedTimestamp”:“1467912357600”}, {“id”:“60000”, “data”:“01”, “value”:“true”, “updatedTimestamp”:“1467912357713”}, {“id”:“65018”, “updatedTimestamp”:“1466191219260”}, {“id”:“65019”, “data”:“3030204E2F41”, “value”:“00 N/A”, “updatedTimestamp”:“1467912357794”}, {“id”:“65020”, “data”:“FA000000180018000C00A00F”, “value”:“FA000000180018000C00A00F”, “updatedTimestamp”:“1467912357935”}, {“id”:“65021”, “data”:“00”, “value”:“false”, “updatedTimestamp”:“1467912358040”} ], “developerDevice”:“true”, “partnerId”:“xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx”, “deviceTypeId”:“xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx”} ]

I would need to spend little more time to playing with the PWM and ADC functions. I tried the attrId = 1024 instead of 1 and still getting the same message. I’ve logging the request payload to just making sure I am calling it right. Here just the payload string “type=attribute_write&attrId=1024&data=01”. On the other end, just a thought. I’ve use the Android app to change the value of GPIO0 and there after request the status using the cloud api. I’ve noticed the “data” and “value” in the attribute also changed in the cloud. Is “value” have anything to deal with it?

Thanks again!
Mankit


#5

Hi Mankit,

Using the example in the developer docs, except changing the attrId and data to the values below, I can turn the LED on the Modulo ON with the following request:

{
 "type": "attribute_write",
 "attrId": 1024,
 "data": "00"
} 

…I can then turn the LED OFF with the same request with “data”: “01”.

Can you verify that works for you, or does that give you an error still?

(This is using the URL https://api.afero.io/v1/accounts/XXXXXXX/devices/YYYYYYYYY/actions and including Content-Type: application/json, Accept: application/json, and Authentication: Bearer ZZZZZZZZZZZZZZ headers)

As for your other question, “data” and “value” are related items - in the API “data” is a little-endian signed 16 bit integer value, which you can set or read as you see fit. We’ve found that in development a lot of folks (internally too, including me…) would have trouble parsing this data field – accidentally forgetting it’s little endian or signed or whatever – so we (recently) added the “value” field to the response. In essence, “value” is just a string representation of “data” - it makes it easier to read the value field than parse the data field.

In the Afero Profile Editor, you can also map the “Value” fields of an attribute to a text label in the UI Controls for an attribute, so that you can map some arbitrary numeric value into a human-readable form.

I’m going to say that for the sake of argument you can consider “data” to the the writeable parameter and “value” as a readable easy to parse representation of “data”. You can actually write the “value” field (and “data” will be updated accordingly) if you find that easier to deal with. We don’t officially support that right now, but it works, so I’m going to recommend using “data” as your writeable field and if you have a particular case where that doesn’t work for you (or makes your life particularly complicated) let me know and I’ll see if we can call it officially supported in the future.

Cheers,

Joe


#6

Hi Joe,

Yes, I am using the URL https://api.afero.io/v1/accounts/XXXXXXX/devices/YYYYYYYYY/actions, and the headers is the same that I used for getting the devices info. I don’t know if I might have run into issue of converting the “data” into little-endian in my script. I’ll give some try in the weekend and maybe try logging the byte array value of what being sent to the cloud. I maybe lost in conversion with numbers…

Thanks!
Mankit


#7

Hi, Mankit!

Just to let you know we’ve updated the Developer Docs with information on what Attributes you can use on the devices. Please check out https://developer.afero.io/docs/en/?target=AttrRegistry.html and let us know if you have any more questions!

Cheers,

Joe