Run periodically executeAndDistribute() report function

Hi everyone,

To present a little bit my project architecture to help you visualize, I have a general UDT which possess several parameters (client name, database name, …), and I create an instance of this UDT for each of my clients, specifying the value of the parameters.
I also created “template” views, and with the dropConfig property I create an instance of these templates for each clients. One on this template uses the ReportViewer component, and I pass the different parameters to this component so that the report could be generated for each client.

Now, I want to send periodically a report to my different clients. At first, I tried to use the Schedule Tab of the report module, but it doesn’t seems to fit with my architecture because I need to specify the value of the parameters, but as I said previously I have to pass them to the ReportViewer component so that the report can be generated for each client. Then, I’m trying to use the executeAndDistribute function, which allows me to pass the parameters in the arguments of the function. To test this function, I created an event script when clicking on a button, containing this code, and it works fine :

system.report.executeAndDistribute(path="Filtration_report", project="Filtration", action= "email",
	  parameters={"StartDate": system.date.addDays(system.date.now(), -7), "udtName":self.view.params.udtElements.Parameters.UDTName, "database":self.view.params.udtElements.Parameters.Database,"H2O2displayFilter2":self.getSibling("ReportViewer").props.params.H2O2displayFilter2,"CLO2displayFilter2":self.getSibling("ReportViewer").props.params.CLO2displayFilter2},
	  actionSettings = {"to":["myaddress@mail.com"], "smtpServerName":"My_SMTP", "from":"filtration@mail.com", "subject":"Filtration Report"})

But I don’t really know how to launch this code periodically (let’s say on sunday evening) and not when clicking on a button. I though about using a loop which verify if the date correspond to sunday 23h59 but I’m afraid that it generates too many useless calculations. Is there another way to do this ?

Thanks,

Carla

You could do this as a gateway timer script and check the time matches before you run your report; alternatively and probably more effciently, you could create expression tags that go true when the time and date matches when you want to send the report and have it trigger a gateway tag change script

Use a gateway scheduled script
Gateway Event Scripts - Ignition User Manual 8.1 - Ignition Documentation (inductiveautomation.com)

4 Likes

It is perfectly what I need.

To explain a little bit what I did, I created a Gateway Scheduled Script where I had firstly to find the right UDT instance (which contains the keyword “Filtration” in its name), and once I have this UDT, I retrieve the UDT parameters I need and pass them to the function.

Here is the code

tags = system.tag.browse("[default]")
	
	for tag in tags : 
		if "Filtration" in tag['name'] : 
			Filtration_tag = tag 
		
	udtName = system.tag.readBlocking(["[default]/"+Filtration_tag['name']+"/_Parameters.UDTName"])[0].value
	database = system.tag.readBlocking(["[default]/"+Filtration_tag['name']+"/_Parameters.Database"])[0].value
	
	system.report.executeAndDistribute(path="Filtration_report", project="Moutounade", action= "email",
	  parameters={"StartDate":system.date.addDays(system.date.now(), -7), "udtName":udtName, "database":database},
	  actionSettings = {"to":["myaddress@mail.com"], "smtpServerName":"My_SMTP", "from":"filtration@mail.com", "subject":"Filtration Report"})

Thanks for your help !

Sorry, I have another question. On the documentation it is written that it is optional to specify the project name. If I don’t specify it and that this script is present in several projects, is there going to be a conflict ?

Wrap this up into a single read for better performance. It may not matter much here, but it is a good habit to get into.

udtPath = "[default]/%s/_Parameters.UDTName" % Filtration_tag['name']
dbPath = "[default]/%s/_Parameters.Database" % Filtration_tag['name']

tags = system.tag.readBlocking([udtPath ,dbPath ])
udtName = tags[0].value
database = tags[1].value

Specifying the project name for system.report.executeAndDistribute is only optional when you call it in the client scope. Since you are calling the function in a Gateway Scheduled Script, you are in the gateway scope, so yes, project is required.

Not sure what you mean here. Why would you need this script be in multiple projects?

Thanks, I was just trying to figure out how to do that

okay, I see, I didn’t quite understand.

Hmm… For the moment it is not done, but in the long term we thought perhaps to create a project per client, so that each one has its own page, and therefore it would imply that this function is used in different projects.

Are you saying this exact script would be in each project? Or do you mean the same script with a different UDT tag, different functionality, or something of the like?

Maybe I missed something, but in the Page Configurator, we can’t put parameters in the views paths, right ?
If I’m right, it means that we will have to create several projects, one for each of our clients, so that every client could have his own page. And in this case, as we will have several projects, this script will be present several times too. Then, the code itself will remain the same, but with different parameters (database, udtName etc won’t have the same value for each client). But as the parameters (and project name) won’t be the same, I don’t think there will be a problem then.