API request limitations

Hi.

I am doing a analysis and I have to use the function “Utils.getTokenByName” to get a device token. Worked fine some times, but stop works, after some days, worked fine some times and again stop works.

This API requests have any limitation or I missing something?

PS. No error messages appears, only not continue the script, I will put the code and prints to clarify.

const { Analysis, Account, Device, Utils } = require("@tago-io/sdk");

async function copyToDummyDevice(account = new Account(), dummy_device = new Device(), device_id = '') {
    // Get the device token and instance device class.
    const device_token = await Utils.getTokenByName(account, device_id);
    const device = new Device({ token: device_token });

    // Fetch the last location on the device, result is an array, so [last_location] automatically access index 0 of the array.
    // variable we're trying to fetch is location.
    const [last_location] = await device.getData({ variables: ['location'], qty: 1 });
    if (!last_location) { // stop if no variable location was found in the device.
        return context.log("Missing variable location for this device");
    }

    // Delete any previous value for the variable location, with serie of the device_id
    await dummy_device.deleteData({ variables: 'location', series: [device_id] });

    // Insert the data location, with the serie being the device_id.
    dummy_device.sendData({
        variable: 'location',
        value: "test",
        location: last_location.location,
        serie: device_id,
    }); 
}

async function myAnalysis(context) {
  
  const env_vars = Utils.envToJson(context.environment);
  if (!env_vars.account_token) {
    return context.log("Missing account_token environment variable");
  }

  const account = new Account({ token: env_vars.account_token });

  // Fetch the list of devices filtered by tag key "device_type" and value "customer"
  const customer_devices = await account.devices.list({ fields: ['id', 'name', 'tags'], filter: { tags: [{ key: 'device_type', value: 'map' }] } });

  for (const customer_dummy_info of customer_devices) {
    // Check if there is any device with tag key "customer_id" with the value of the tag on the customer device.
    const devices_to_copy =  await account.devices.list({ fields: ['id', 'name', 'tags'], filter: { tags: [{ key: 'device_type', value: "pin" }] } });
    if (!devices_to_copy.length) {
      context.log(`No pin device found for customer ""`);
      continue;
    }

    // Get the dummy device token and instance device class.
    const dummy_device_token = await Utils.getTokenByName(account, customer_dummy_info.id);
    const dummy_device = new Device({ token: dummy_device_token });

    // Send each device to the function copyToDummyDevice.
    devices_to_copy.forEach((device) => {
      copyToDummyDevice(account, dummy_device, device.id);
    });
  }
}

module.exports = new Analysis(myAnalysis);

1 Like

Hi @julihermes.melo ,

One thing you can do there is place .then and .catch to see exactly what error is returning.

also checks if every interation on that for of loop has the id property on the current object (customer_dummy_info.id)

Let me know if that helps solving your problem.

-Guilherme

2 Likes

Ok, I will try later.
Thanks!

2 Likes

Hi, @guilhermeco, sorry for the delay.

I tested and I got this informations below in console:
image

And the code update is this:

Can you help me with this?

1 Like

Hi @julihermes.melo,

can you paste over your last version code? So I can run in my machine?

1 Like

Yes.
PS. its not a finish work.

/*
 * Populate Map
 *
 * Read information from devices with tag "pin" and copy 
 * to a dumby device to show infos in a map.
 *
 */

const { Analysis, Account, Device, Utils } = require("@tago-io/sdk");

async function copyToDummyDevice(account = new Account(), dummy_device = new Device(), device_id = '') {
  context.log(`log 3`);
    // Get the device token and instance device class.
    const device_token = await Utils.getTokenByName(account, device_id);
    const device = new Device({ token: device_token });

    // Fetch the last location on the device, result is an array, so [last_location] automatically access index 0 of the array.
    // variable we're trying to fetch is location.
    const [last_location] = await device.getData({ variables: ['location'], qty: 1 });
    if (!last_location) { // stop if no variable location was found in the device.
        return context.log("Missing variable location for this device");
    }

    // Delete any previous value for the variable location, with serie of the device_id
    await dummy_device.deleteData({ variables: 'location', series: [device_id] });

    // Insert the data location, with the serie being the device_id.
    dummy_device.sendData({
        variable: 'location',
        value: "teste",
        location: last_location.location,
        serie: device_id,
    }); 
}

async function myAnalysis(context) {
  
  const env_vars = Utils.envToJson(context.environment);
  if (!env_vars.account_token) {
    return context.log("Missing account_token environment variable");
  }

  const account = new Account({ token: env_vars.account_token });

  // Fetch the list of devices filtered by tag key "device_type" and value "customer"
  const customer_devices = await account.devices.list({ fields: ['id', 'name', 'tags'], filter: { tags: [{ key: 'device_type', value: 'map' }] } });

  for (const customer_dummy_info of customer_devices) {
    // Check if there is any device with tag key "customer_id" with the value of the tag on the customer device.
    const devices_to_copy =  await account.devices.list({ fields: ['id', 'name', 'tags'], filter: { tags: [{ key: 'device_type', value: "pin" }] } });
    if (!devices_to_copy.length) {
      context.log(`No pin device found for customer ""`);
      continue;
    }

    context.log(`log before`);
    // Get the dummy device token and instance device class.
    const dummy_device_token = await Utils.getTokenByName(account, customer_dummy_info.id).then(
    function(e) {
      context.log(e);
    },
    function(e) {
      context.log(e);
    });
    context.log(`log after`);
    const dummy_device = new Device({ token: dummy_device_token });

    // Send each device to the function copyToDummyDevice.
    devices_to_copy.forEach((device) => {
      copyToDummyDevice(account, dummy_device, device.id);
    });
  }
}

module.exports = new Analysis(myAnalysis);

// To run analysis on your machine (external)
// module.exports = new Analysis(myAnalysis, { token: "YOUR-TOKEN" });
1 Like

hi!

Any update about it?

Hi @juilhermes.melo,

yes, actually the correct call with catch would be

    const dummy_device_token = await Utils.getTokenByName(
      account,
      customer_dummy_info.id
    ).catch((msg) => console.lo(msg));

So that you catch only the errors. To place a then block as well you would need to do something like this:

    const dummy_device_token = await Utils.getTokenByName(
      account,
      customer_dummy_info.id
    )
      .then((data) => {
        console.log(data);
        return data;
      })
      .catch((msg) => console.lo(msg));

The way you’ve coded the function will only console.log the result from the endpoint call, you should also return it.

I’ve run the code into my machine and now its working properly, instantiating the Device class with the correct devices.

Can you try making the necessary changes in your scripts and then perform a test?

Btw, sorry for the delay.

-Guilherme

1 Like

Hi, @guilhermeco!

I change my code like you said and I get this below. Can you help me with this error?

Reference error means that something you’re using was not declared in the function. In this case, the script couldn’t find any reference for “context”. Did you include the context in your function parameters? I can see in the code you sent it is not declared:

async function copyToDummyDevice(account = new Account(), dummy_device = new Device(), device_id = ‘’)

Also, if you don’t want to declare, the analysis was updated this week to support console.log instead of context.log. You can just update all context.log in your script to use console.log instead, then you don’t need to declare the context in all your functions.

1 Like

Hi.

I haven’t had time to see the solution you showed yet, as soon as I get it fixed I’ll give you feedback.
But seeing here the problem was the context of the log, my bad.
As soon as possible I say something.