How to generate CSV reports using TagoIO

Generating CSV reports using TagoIO

Easily generate reports on the TagoIO platform using input form and analysis. You will learn:

  • How to generate reports
  • How you can use reports to increase value for your application

What do I need to generate a CSV report?

There are some ways for generating reports, but today we are going to learn how to generate .CSV reports. For this task, the developer needs to already have a running application (device already setup, data on device’s bucket) and need to have decided which variables should be reported in the file. You also need to know some concepts like:

How to generate reports using input form and analysis

The reports can be generated on the TagoIO platform by just using a script for an analysis and a widget (we will use the Input Form widget but you can use others than that) to run the analysis. Now, let’s go for the implementation!

Creating the analysis used on reports generation

The script can be found here on Github and is named generateReports.js. You can check the following image if you are having trouble finding the script:

Copy the code from the file here on Github, and paste it on a new analysis within your TagoIO account. After that, set the following environment variables: device_token, dashboard_id and account_token. If you aren’t sure what values you should use on each of the variables, check the topics below, as there are additional explanations for each of them.

  • Device Token: it’s a token generated from the device you are using to work with the data you want to get on your report.

  • Dashboard ID: you need to get the ID of the dashboard you will use to implement this report system.

  • Account Token: token generated from the account you are using.

After you have inserted all the environment variables, you should have your environment variables tab like the following image:

​Now, let’s go for the code!

Code implementation

The script generateReports.js is already operational and it’s just a matter of defining the variables to be included in the report. For this tutorial, I will choose the following variables: temperature and humidity. Go to the script you have pasted on your report generation analysis and search for line 23. Line 23 should have something like that:

const data = await device.find({ variable: ['temperature', 'humidity'], start_date: '10 year', qty: 9999 });

That is the line we want to change, you can see there is an array on the key named variable. You just need to insert the variables you want to report inside this array. For example, if you want the variable battery. Your line should be like the following:

const data = await device.find({ variable: ['battery'], start_date: '10 year', qty: 9999 });

Another example; you want the variables tension, electric_current and capacitance, so your line should be like the following:

const data = await device.find({ variable: ['tension', 'electric_current', 'capacitance'], start_date: '10 year', qty: 9999 });

That’s all you have to change on the code, but, there are some other lines you can change on the script to use the report as you want. You can customize the email that is sent for the user by changing what is written on lines 30 to 35. You can also customize the validation or customize the notification sent to the user in the same script; just take a look at the code and you should find everything that you want to customize. After that, let’s create the widget for our report generation system.

Creating the input form widget to generate reports

This is, by far, the easiest part of the tutorial. We have only four steps to follow here:

  • Create input form widget
  • Select the variables used in the input form
  • Set the variable field types
  • Select the analysis that will be used to generate reports

We are going to create a widget that will have an input for the user to insert the email, and after the email is inserted, the user will click on the button “Generate Report” to receive the link for the report on his email along with a validation on the widget giving the feedback to the user. To create this, just select the dashboard you want to have a report generation system on, and create an input form. On the input form, you should use two variables named email and validation. Like the following image:

After that, go to the field configurations of the widget and set the type of email as Text and the type of the validation as Validation. Like the image:

Now, go to the user control and select the report generation analysis you created before to the field Run analysis when submitting form. Like the image bellow:

You can also customize the text of the submit button and other options on the widget. But you only need what is written on this tutorial to get the report generations working. Check the following example using our report system in action!

Generating report demonstration

demonstration

Email received with link for the report

That’s it for generating reports! Try to use it and check the report you will receive in your email. You can customize, make improvements and make any other changes with the script and widget. If you had any troubles during the tutorial leave your comments here and I will be happy to help you.

@Nicolas Kyriakou

Hello, is this script still functional?

@Phil Gutierre

Hello @n.kyriakou

Sorry for the late reply.

The script is functional, I tested and it’s working great.

If you have any questions, we’ll be glad to help you.

Best regards,

Phil Gutierre
Customer Support

Hi all, sorry for the bump.

Is there a way to change the device token (or device enterely, for that matter) from a blueprint dashboard?

I mean, if I have a blueprint dash where I can select any numbers of devices, I’m searching a way to get the device from the bluerprint itself rather than hardcode its token every time.

Hey Ignacio,

If you’re using a blueprint dashboard, you can remove the need of the token from your script.

Just replace the line for tago_device (line 48) with those lines of code instead:

const deviceID = scope[0].device;
const tago_device = await TagoUtils.getDevice(account, deviceID);

And remove the need of having a device_token in the environment variables by deleting the IF at line 44

Hello,

I have a Blueprint dashboard and followed above steps including changing the code with suggested 2 lines but still can’t get it working. Even though the script is returning correct device ID and device_token, I’m getting this error when using the input form widget for an email - The promise rejected with the reason “Device can’t be found”.] { code: ‘ERR_UNHANDLED_REJECTION’ }.

Could you advise what might be the solution to this issue?

Thanks.

Roman

Are you sure you’ve entered the correct account-token from the profile you’re using? You must set this up in the environment variable of the analysis.

You may also want to check the analysis to make sure it doesn’t have something like scope[0].origin instead of scope[0].device. As I don’t think this analysis had been migrated to be compatible with Immutable and Mutable buckets. I’ll add in our roadmap to update it.

Hi.

Yes, I’m sure that correct account-token from the profile is used in environment variable. I’ve checked multiple times. Also the script in the analysis is following the instructions but still getting the error. I’m not sure what I’m doing wrong.

And just to clarify - when I use original script from GitHub I get the error above - “Device can’t be found”. When I use the recommended modification on line 48 I get this one: undefined:65 const tago_device = await TagoUtils.getDevice(account, deviceID); ^ ReferenceError: account is not defined at Analysis.explore [as _analysis] (eval at ([eval]:8:39), :65:51) at Analysis.runOnTagoIO (/analysis_node/node_modules/tago/analysis/index.js:35:10) at new Analysis (/analysis_node/node_modules/tago/analysis/index.js:17:12) at eval (eval at ([eval]:8:39), :113:18) at Immediate. ([eval]:8:39) at processImmediate (node:internal/timers:466:21)

Below is the part of the script with the proposed modification.

async function explore(context, scope) {

if (!scope\[0\]) return context.log('no scope');

const env\_var = TagoUtils.env\_to\_obj(context.environment);

if (!env\_var.account\_token) return context.log('Can\\'t find variable account\_token on environment variables');

if (!env\_var.dashboard\_id) return context.log('Can\\'t find variable dashboard\_id on environment variables');



const tago\_acc = new TagoAccount(env\_var.account\_token);

const deviceID = scope\[0\].device;

const tago\_device = await TagoUtils.getDevice(account, deviceID);

Thanks.

Hi Roman,

You also need to change 2 more lines:

Line 37 to:

await emailService.send(email.value.replace(/;/g, ‘,’), subject, message, from_e, attachment);

Line 53 to:

const token = await TagoUtils.getTokenByName(tago_acc, customer_email.device, [‘Default’, ‘Generic’, ‘Token #1’, ‘Token #2’]);

Dear Tago Team

Is there any way to generate an .xlsx file for excel instead of a csv file?

Hi,

You can do this changing the function sendReport line 33:

const attachment = {

archive: csv,

filename: “report.xlsx”,

};

Dear Mateus,

Thank you for your answer, but what you indicate does not work. It is only changing the file extension from CSV to XLSX, but the file is still CSV. Doing what you indicate I download the XLSX but it can not be opened with excel because it gives error.

Is there any other way to do it?

Is there a way to automate this without having to use a widget to initiate the analysis. In it’s current form, the script has no way of knowing what the email address is unless passed through a widget.