How to get devices + attribute values

Hi all,

I would like to fetch a list of all devices along with a couple of their attributes, namedly cputemp and cpuload but unsure how to accomplish this.

I can get the devices ok but unsure how to specify which attributes to fetch also, if it’s even possible.

Can anyone lend a hand on how to create a query to achieve this?

Thanks,
Nigel

Hey @Nigel_Reed,

When using the Device: Get Node, you can choose to include Composite State for those devices. You can do this in the Node Configuration by selecting the drop-down for “Composite State to Include”, and selecting “Include the Following Attributes”, as seen here:
image

Then you will be able to select which attributes you would like returned. :slight_smile:

Please let me know if this works for you!

Thank you,
Heath

Doh. I forgot to mention I’m using the API for this. Will that still be required in the workflow?

Hey @Nigel_Reed,

No problem at all!

There is not currently an API endpoint that will get you exactly what you’re looking for. You can try the Last Value Query endpoint. This will get you the last value reported for a single attribute for multiple devices.

Could you tell me a bit more about your use case and what you’re using the API for? Are you running your own, custom software? I’d love to hear more about how you’re using Losant!

Thank you,
Heath

If you drop me an email, I’ll be happy to discuss. I wouldn’t want to do so in public due to customer confidentiality.

What I am trying to do it produce current cpu load and temperatures for all our devices that can be generated using the API so I can script and sort/filter the report manually.

Unfortunately, I can’t get that to work. I went back to basics and tried the CURL example:

curl -H ‘Content-Type: application/json’
-H ‘Accept: application/json’ -H ‘Authorization: Bearer blahblah’
-X POST
-d ‘{“attribute”:“cpuTemp”}’ \ https://api.losant.com/applications/myid/data/last-value-query

I get nothing.

When I use the devices endpoint, I can see

‘attributes’ => [
…snip…
{
‘name’ => ‘cpuTemp’,
‘dataType’ => ‘number’,
‘description’ => ‘’,
‘attributeTags’ => {}
} },

Hey @Nigel_Reed,

Looking at what you pasted in, it looks like you might not have included deviceIds in your request.

From the example in the docs:

curl -H 'Content-Type: application/json' \
    -H 'Accept: application/json' \
    -H 'Authorization: Bearer YOUR_API_ACCESS_TOKEN' \
    -X POST \
    -d '{"deviceIds":["575ecf887ae143cd83dc4aa2","575ef5c97ae143cd83dc4aac"],"attribute":"voltage"}' \
    https://api.losant.com/applications/APPLICATION_ID/data/last-value-query

Thanks,
Heath

I can’t provide 6000+ device id’s. That’s not feasible. I didn’t see anything that states device id’s are mandatory. You’d think if not specified then everything would be returned.

First things first - the data.lastValueQuery endpoint will only return a maximum of 1,000 devices in a single call, whether you pass device IDs or device tags, and that endpoint does not have any pagination features built into it. So if you need 6,000 devices in a single response, that will not work for your use case. Instead, it would require multiple, carefully constructed API calls (as outlined below).

Instead of passing an array of device IDs, pass an array of deviceTags instead. This would require every device you want to retrieve data for to have a common key (but not necessarily a common value). For example …

{
  "deviceTags": [{"key": "myKey"}]
}

would return an entry for each device that had a tag with a key of “myKey” regardless of the tag’s value.

In your case, you would need some sort of tag value grouping mechanism to break the devices up in chunks of 1,000 or less, so you would want to tag, say, 800 devices with “myKey=1”, and the next 800 with “myKey=2”, and so on, constructing your tag query as …

{
  "deviceTags": [{"key": "myKey", "value": "1"}]
}

If your use case allows it, you could make a single call to the data.export endpoint that would send all device data and a selection of attributes to either a callback URL or an email address, but it would be on you to wait for that result, download and parse the CSV, and take whatever action you need that data for in your application.

I did make a feature request to allow for returning composite state through the devices.get endpoint (similar to how the Device: Get Node works) and will let you know if it is selected for development and is completed. Bear in mind that would be a paginated endpoint, so you still wouldn’t get 6,000+ devices in a single API call.

Yeah, the data export really defeats the purpose of accessing via the API.

I use another API where I have results paginated so I already have routines to handle that sort of situation.

If the composite state gets developed, that would be useful, especially if it could be filtered. I’ll keep an eye out.

Thanks,
Nigel

I did want to swing around and let you know I got the data.lastValueQuery working using the deviceTags.

I’ll watch out for an update regarding your enhancement request.

Thanks,
Nigel