Bucket variables - adding variables, updating values,recalling values and deleting variables

Hi Everyone

Please could you help me with my analysis script. Everything seems to work fine until script tries to read the variables from the bucket. I realize that it needs to put the contents into an array then get the .last_item but this has had me going around in circles.

This analysis is for a livestock tracker and will send a notification to the devices user when there is higher than usual activity. This will indicate that the livestock being tracked is either being hunted or herded.

In order to do this i added 5 variables to the bucket using the device emulator. Two of the variables are added to the bucket using a Input Form on the TagoIO Run Dashboard.

The analysis script gets the variable values from the bucket.
Increments current event.
If its the first entry to the analysis it sets saved time to Date.now
Sets the current period to saved time - Date.now
If the current event = event and current period = period then send notification
Zero current event
Zero saved time
Zero current period
Update bucket

/* ver 1/13/2021
** Analysis to send a notification to the devices user when there is higher
** than usual activity. This will indicate that the livestock being tracked is
** either being hunted or herded.
**
** Environment Variables
** In order to use this analysis, you must setup the Environment Variable table.
** account_token: Your account token. Check bellow how to get this.
**
** Also add a device token to the environment variables,
** Check bellow how to get this.

** Steps to generate an account_token:
** 1 - Enter the following link: Admin
** 2 - Select your Profile.
** 3 - Enter Tokens tab.
** 4 - Generate a new Token with Expires Never.
** 5 - Press the Copy Button and place at the Environment Variables tab of this analysis.
**
** Steps to generate a device_token:

  • 1 - Go to your device, then token and copy your token.
  • 2 - Go to the analysis, then environment variables,
  • 3 - Type device_token on key, and paste your token on value
    */
    const {Analysis, Utils, Services, Account, Device, Types} = require("@tago-io/sdk");
    //import getDevice from “./lib/getDevice”;
    //import { parseTagoObject } from “./lib/data.logic”;

async function predatorWarning() {
// Send the notifications and output the results to the analysis console.
//To enable email notification add email_tag in enviroment variables.
if (environment_variables.email_tag) {
context.log(‘about to send email’);
await email_service.send({
to: email,
subject: ‘Notification alert’,
message: Unusual activity warning for the device: ${device_name}. Variable: ${scope[0].variable}, Value: ${scope[0].value} ,
}),
context.log('email sent!!! ');

} else {
context.log(‘Emailing not enabled for this device.’);
}

if (phone_tag) {
await sms_service.send({
to: phone_tag.value,
message: Unusual activity warning for the device: ${device_name}. Variable: ${scope[0].variable}, Value: ${scope[0].value} ,
}).then(context.log).catch(context.log);
} else {
context.log(‘Phone number not found for this device.’);
}

if (userID_tag) {
await account.run.notificationCreate(userID_tag.value, {
title: ‘Notification Alert’,
message: Unusual activity warning for the device: ${device_name}. Variable: ${scope[0].variable}, Value: ${scope[0].value} ,
}).then(context.log).catch(context.log);
} else {
context.log(‘User ID not found for this device.’);
}
}

async function predator(context, scope) {
if (!scope[0]) return context.log(‘This analysis must be triggered by an action.’);

//context.log(JSON.stringify(scope));
context.log(“Running Analysis”);

//must have the environment variables set at analysis -> environment variables
const environment = Utils.envToJson(context.environment);
if (!environment.account_token)
return context.log(‘Missing “account_token” environment variable’);
else if (environment.account_token.length !== 36)
return context.log(‘Invalid “account_token” in the environment variable’);
context.log(“Enviroment Set”);

//instancing user device and account
const account = new Account({ token: environment.account_token });
context.log(“Instance New Account”);
context.log('Token: ', environment.account_token);
const config_dev = new Device({ token: environment.device_token });
context.log("Instance New Device ");
context.log('Token: ', environment.device_token);

const customer_dev = await getDevice(account, scope[0].origin);
//choose the variable name to analysis here
const a_event = await customer_dev.getData({ qty: 9999, variable: “event” }); //This value can be set in a Input Form on the TagoIO Run Dashboard
context.log('a_event: ', a_event.value);
const a_period = await customer_dev.getData({ qty: 9999, variable: “period” }); //This value can be set in a Input Form on the TagoIO Run Dashboard
context.log('a_period : ', a_period.value);
const a_current_event = await customer_dev.getData({ qty: 9999, variable: “current_event” });
context.log('a_current_event : ', a_current_event.value);
const a_current_period = await customer_dev.getData({ qty: 9999, variable: “current_period” });
context.log('a_current_period: ', a_current_period.value);
const a_saved_time = await customer_dev.getData({ qty: 9999, variable: “saved_time” });
context.log('a_saved_time: ', a_saved_time.value);

//data to be saved in the bucket
const data_to_bucket = {
current_event: 0,
saved_time : 0000000000000,
current_period : 0,

};

//get the last item of object a_current_event and increment the values
a_current_event.last_item((x) => (data_to_bucket.current_event = data_to_bucket.current_event + 1));
a_current_event.value = x.value;

if (data_to_bucket.current_event = 1) {
//get the last item of object a_saved_time and set to current time
a_saved_time.last_item((y) => (data_to_bucket.saved_time = Date.now() ));
}
a_saved_time.value = y.value;

//get the last item of object a_current_period and recalculate period
a_current_period.last_item((z) => (data_to_bucket.current_period = (data_to_bucket.current_period + (Date.now() - data_to_bucket.saved_time) )));
a_current_period.value = z;

//if user defined number of events occur within user define period initiate predator warning notification
if ((a_current_event.value = a_event.value) && (a_current_period.value = period.value)) {
//call predatorWarning
await predatorWarning(contest,scope);

//reset the variables and parse to tagoIO structure to be saved on bucket
 data_to_bucket.current_event = 0;
 data_to_bucket.saved_time = 0000000000000;
 data_to_bucket.current_period = 0;
await config_dev.sendData(parseTagoObject(data_to_bucket)); 

} else if ((a_current_event.value < a_event.value) && (a_current_period.value < period.value)) {
//parsing updated data to tagoIO structure to be saved on bucket for use in the next event
await config_dev.sendData(parseTagoObject(data_to_bucket));

} else if (a_current_period.value > period.value) {
//reset the variables and parse to tagoIO structure to be saved on bucket
data_to_bucket.current_event = 0;
data_to_bucket.saved_time = 0000000000000;
data_to_bucket.current_period = 0;
await config_dev.sendData(parseTagoObject(data_to_bucket));
}

//console logging
console.log(“End of script”);
}

module.exports = new Analysis(predator);

// Insert your token here
// To run analysis on your machine (external)
//export default new Analysis(predator, { token: “*****************” });

Thanks for help
Steven

Hi, @flaxies,
I couldn’t understand what is the problem, but reading your code it seems that is missing some part of the code. The functions “getDevice” and “parseTagoObject” is never defined.

const customer_dev = await getDevice(account, scope[0].origin);

if the “scope[0].origin” is an Device token use an Device Class.

Another problem is that the “getData” function from the Device class returns an array, so this code below doesn’t make sense.

  //get the last item of object a_current_event and increment the values
  a_current_event.last_item(
    (x) => (data_to_bucket.current_event = data_to_bucket.current_event + 1)
  );
  a_current_event.value = x.value;

  if ((data_to_bucket.current_event = 1)) {
    //get the last item of object a_saved_time and set to current time
    a_saved_time.last_item((y) => (data_to_bucket.saved_time = Date.now()));
  }
  a_saved_time.value = y.value;

  //get the last item of object a_current_period and recalculate period
  a_current_period.last_item(
    (z) =>
      (data_to_bucket.current_period =
        data_to_bucket.current_period +
        (Date.now() - data_to_bucket.saved_time))
  );
  a_current_period.value = z;

You can retrieve the last insert from the bucket like this

const a_event = await customer_dev.getData({ 
    query: "last_insert",
    variable: "event" 
})

The “a_event” variable will be an array with only the last value inserted.

If this doesn’t solve your problem, try to send more datails.

1 Like

Hi stoklosa

Thanks for the reply.

I am just struggling with how to get the data from the device bucket. My program runs to the point where it must get the data values then fails so any scripting below that is a work in progress. I f you could help me to understand the bucket data structure i should be able to move forward. As you can see i have tried many ways to try and get the data value into my code so i can manipulate it, they all fail.
I thought that this was because the data variable was not created by my device but was created by the emulator and platform input form but I’m sure it should still work otherwise how else could you add variables to use in your analysis.

Thanks for the help.
Steven

async function predator(context, scope) {

  if (!scope[0]) return context.log('This analysis must be triggered by an action.');

  

  //context.log(JSON.stringify(scope));

  context.log("Running Analysis");

  //must have the environment variables set at analysis -> environment variables

  const environment = Utils.envToJson(context.environment);

  if (!environment.account_token) 

      return context.log('Missing "account_token" environment variable');

  else if (environment.account_token.length !== 36) 

      return context.log('Invalid "account_token" in the environment variable');

  context.log("Enviroment Set");

  //instancing user device and account

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

  //context.log("Instance New Account");

  //context.log('Token: ', environment.account_token);

  const customer_dev = new Device({ token: environment.device_token });

  context.log("Instance New Device ");

  context.log('Token: ', environment.device_token);

  // This checks if we received the data 'event'

  //const customer_dev = await getDevice(account, scope[0].origin);

  //choose the variable name to analysis here

  //const deviceData = await customer_dev.find({ variable: "events", qty : 2 }); //This value can be set in a Input Form on the TagoIO Run Dashboard

  const a_event = await customer_dev.getData({ variable: "events", qty : 2 }); //This value can be set in a Input Form on the TagoIO Run Dashboard

  //const a_event = scope.find((data) => data.variable === "events");

  //const a_event = scope.getData({ variable: "events", qty : 2 });

  //const a_event = deviceData.find(x => x.variable === "events");

  //const [a_event] = await customer_dev.find({ variable: 'events', qty: 1, query: 'last_item'});

  if (!a_event) { 

    context.log("No 'events' found in the scope.");

  }else {

    context.log('events: ', a_event.value);

    //((a_event) => console.log(a_event[0]));

  }

      

  //context.log('a_event: ', a_event[1]);

 /* const a_period = await customer_dev.getData({ qty: 9999, variable: "period" }); //This value can be set in a Input Form on the TagoIO Run Dashboard

  context.log('a_period : ', a_period.value);

  const a_current_event = await customer_dev.getData({ qty: 9999, variable: "current_event" });

  context.log('a_current_event : ', a_current_event.value);

  const a_current_period = await customer_dev.getData({ qty: 9999, variable: "current_period" });

  context.log('a_current_period: ', a_current_period.value);

  const a_saved_time = await customer_dev.getData({ qty: 9999, variable: "saved_time" });

  context.log('a_saved_time: ', a_saved_time.value);

*/

Hi @flaxies,

as your question is about getting data from your device bucket, i did a simple analysis to get a location variable from my bucket to demonstrate:

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

async function getData(context) {
  const envVars = Utils.envToJson(context.environment);

  context.log(envVars);

  if (!envVars.device_token) {
    return context.log("Missing device_token environment variable");
  }

  const device = new Device({ token: envVars.device_token });

  const info = await device.getData({ variable: "location" });

  context.log(JSON.stringify(info));
}

module.exports = new Analysis(getData);

so there is nothing wrong with your code, you did the new Device and getData correctly, maybe the problem is the device token itself, you need to get the token as in the following image:

and put it into your environment variables.

Hi Everyone

Thanks i solved the problem after reading
stoklosa
it seems i was not accessing the variable value in the correct manner after getData.
I attach my code with correction.

async function predator(context, scope) {

  if (!scope[0]) return context.log('This analysis must be triggered by an action.');

  

  //context.log(JSON.stringify(scope));

  context.log("Running Analysis");

  //must have the environment variables set at analysis -> environment variables

  const environment = Utils.envToJson(context.environment);

  if (!environment.account_token) 

      return context.log('Missing "account_token" environment variable');

  else if (environment.account_token.length !== 36) 

      return context.log('Invalid "account_token" in the environment variable');

  context.log("Enviroment Set");

  //instancing user device and account

  const customer_dev = new Device({ token: environment.device_token });

  context.log("Instance New Device ");

  context.log('Token: ', environment.device_token);

  

  // create the filter options to get the data from TagoIO

  const filter = {

    variable: "events",

    query: "last_value",

  };

  const eventsArray = await customer_dev.getData(filter);

  // Check if the array is not empty

  if (!eventsArray || !eventsArray[0]) {

    return context.log("Empty Array");

  } else {

     // query:last_item always returns only one value

    const value = eventsArray[0].value;

    // print to the console at TagoIO

    context.log("events: ", value);

  }
1 Like