# Most efficient way to read tags and insert into csv

**URL:** <https://forum.inductiveautomation.com/t/most-efficient-way-to-read-tags-and-insert-into-csv/65298>\
**Category:** Ignition\
**Created:** [October 17, 2022, 5:59pm UTC](https://forum.inductiveautomation.com/t/most-efficient-way-to-read-tags-and-insert-into-csv/65298 "2022-10-17T17:59:58Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![michael.black](https://avatars.discourse-cdn.com/v4/letter/m/ee7513/32.png) [@michael.black](https://forum.inductiveautomation.com/u/michael.black)\
**Post date:** [October 17, 2022, 5:59pm UTC](https://forum.inductiveautomation.com/t/most-efficient-way-to-read-tags-and-insert-into-csv/65298/1 "2022-10-17T17:59:58Z")

</div>

I am running Ignition Edge 8.1.21.

I am trying to figure out the most efficient way to read in tag values and then use these values as my data for a script running the csv library.

For each digital input I have two tags within a data type I created that I want to read in, the first being name and the second being StateOnOff. I want my csv file to look like this as an example using the screenshot of my tag structure:

LSHH-100 OFF  
LSH-200 ON

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/a/6/a6ba446b16fd64d2e0d1441453a2e98ebb7d548b.png)

I know there is a way to read in these tags using code where you aren't reading in each individual tag within the script. And is it better to put the values into a dataset and then transfer this data set into a csv? Better to do it with a dictionary?

---

<div class="post-metadata">

**Author:** ![pascal.fragnoud](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pascal.fragnoud/32/24728_2.png) [@pascal.fragnoud](https://forum.inductiveautomation.com/u/pascal.fragnoud)\
**Post date:** [October 17, 2022, 6:20pm UTC](https://forum.inductiveautomation.com/t/most-efficient-way-to-read-tags-and-insert-into-csv/65298/2 "2022-10-17T18:20:15Z")

</div>

`system.tag.readBlocking` takes a list of tags paths. Use this.  
Build the tags paths:

```python
from itertools import chain
base_name = "[provider]DigitalO/InputSlot3In"
paths = list(chain(*(["{}/Name".format(base_name, i), "{}/StateOnOff".format(base_name, i)] for i in xrange(1, 5))))
values = [qval.value for qval in system.tags.readBlocking(paths)]

```

Then format and export to csv.  
If you need help with that part too, I'll try and do my best.

---

<div class="post-metadata">

**Author:** ![michael.black](https://avatars.discourse-cdn.com/v4/letter/m/ee7513/32.png) [@michael.black](https://forum.inductiveautomation.com/u/michael.black)\
**Post date:** [October 17, 2022, 6:25pm UTC](https://forum.inductiveautomation.com/t/most-efficient-way-to-read-tags-and-insert-into-csv/65298/3 "2022-10-17T18:25:06Z")

</div>

interesting. I do want to get values from the following tag data types though:

InputSlot3In0, InputSlot3In2, InputSlot3In3, InputSlot3In4, InputSlot3In5, InputSlot4In0

As you can see they aren't in order

---

<div class="post-metadata">

**Author:** ![Steve\_Laubach](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/steve_laubach/32/60900_2.png) [@Steve\_Laubach](https://forum.inductiveautomation.com/u/Steve_Laubach)\
**Post date:** [October 17, 2022, 6:27pm UTC](https://forum.inductiveautomation.com/t/most-efficient-way-to-read-tags-and-insert-into-csv/65298/4 "2022-10-17T18:27:31Z")

</div>

system.tag.readBlocking returns a list of qualified values in the order of the list of tag paths passed in. Note, it returns qualified values; not values. You have to handle those accordingly.

[https://docs.inductiveautomation.com/display/DOC81/system.tag.readBlocking](https://docs.inductiveautomation.com/display/DOC81/system.tag.readBlocking)

---

<div class="post-metadata">

**Author:** ![pascal.fragnoud](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pascal.fragnoud/32/24728_2.png) [@pascal.fragnoud](https://forum.inductiveautomation.com/u/pascal.fragnoud)\
**Post date:** [October 17, 2022, 6:28pm UTC](https://forum.inductiveautomation.com/t/most-efficient-way-to-read-tags-and-insert-into-csv/65298/5 "2022-10-17T18:28:51Z")

</div>

that's easily fixable:

```python
folders = [
    "InputSlot3In0",
    "InputSlot3In2",
    ... etc
]
paths = list(chain(*(["DigitalO/{}/Name".format(f), "DigitalO/{}/StateOnOff".format(f)] for f in folders)))

```

edit: note that if you have a lot of instances of this UDT, you can use `system.tag.browse` to build the list programmatically instead.

---

<div class="post-metadata">

**Author:** ![michael.black](https://avatars.discourse-cdn.com/v4/letter/m/ee7513/32.png) [@michael.black](https://forum.inductiveautomation.com/u/michael.black)\
**Post date:** [October 17, 2022, 6:47pm UTC](https://forum.inductiveautomation.com/t/most-efficient-way-to-read-tags-and-insert-into-csv/65298/6 "2022-10-17T18:47:16Z")

</div>

This is what I have for the script using your example above

```auto
def create_DI_file ():
	"""Create CSV file showing digital input status.
			
	Params: N/A
	
	Returns: N/A
	"""
			
	import csv
	from itertools import chain
									
	header = ['Digital Input', 'State']
	
	folders = ["InputSlot3In0", "InputSlot3In2", "InputSlot3In3", "InputSlot3In4", "InputSlot3In5", "InputSlot4In0"]
	paths = list(chain(*("[PLC]DigitalO/{}/Name".format(f), "[PLC]DigitalO/{}/StateOnOff".format(f)] for f in folders)))
	values = [qval.value for qval in system.tags.readBlocking(paths)]
							
	with open('C:\DailyCSVFiles\DIStatus.csv', 'w', newline='') as f:
			
		writer = csv.writer(f)
		
		writer.writerow(header)
		
		writer.writerow(values)

```

... I get this error when trying to run the script

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/e/8/e8b607040e211454c4ab4e049e6c52728a3e64c2.png)

---

<div class="post-metadata">

**Author:** ![pascal.fragnoud](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pascal.fragnoud/32/24728_2.png) [@pascal.fragnoud](https://forum.inductiveautomation.com/u/pascal.fragnoud)\
**Post date:** [October 17, 2022, 6:49pm UTC](https://forum.inductiveautomation.com/t/most-efficient-way-to-read-tags-and-insert-into-csv/65298/7 "2022-10-17T18:49:57Z")

</div>

> [@michael.black](#):
>
> ```auto
> paths = list(chain(*("[PLC]DigitalO/{}/Name".format(f), "[PLC]DigitalO/{}/StateOnOff".format(f)] for f in folders)))
> 
> ```

you're missing a `[`:  
`	paths = list(chain(*(["[PLC]DigitalO/{}/Name".format(f), "[PLC]DigitalO/{}/StateOnOff".format(f)] for f in folders))) `

By the way, there are system functions to convert to csv and download a file. You should use those.  
And you'll need to re-structure the data, as it is it's a simple list. You'll need a list of lists, with each inner list containing the name and state of that particular machine/whatever they are.

```python
data_table = list(zip(values[::2], values[1::2]))

```

---

<div class="post-metadata">

**Author:** ![michael.black](https://avatars.discourse-cdn.com/v4/letter/m/ee7513/32.png) [@michael.black](https://forum.inductiveautomation.com/u/michael.black)\
**Post date:** [October 17, 2022, 7:05pm UTC](https://forum.inductiveautomation.com/t/most-efficient-way-to-read-tags-and-insert-into-csv/65298/8 "2022-10-17T19:05:25Z")

</div>

Thanks. I did get it to work but like you said it just gave me a list as seen here:

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/9/5/952101dc8c4f37ee75063427cf8dbe73183f99a6.png)

Where would this other line of code go and what would it be replacing?  
I tried putting this into the code as follows and got this:

```auto
def create_DI_file ():
	"""Create CSV file showing digital input status.
			
	Params: N/A
	
	Returns: N/A
	"""
			
	import csv
	from itertools import chain
									
	header = ['Digital Input', 'State']
	
	folders = ["InputSlot3In0", "InputSlot3In2", "InputSlot3In3", "InputSlot3In4", "InputSlot3In5", "InputSlot4In0"]
	
	paths = list(chain(*(["[PLC]DigitalO/{}/Name".format(f), "[PLC]DigitalO/{}/StateOnOff".format(f)] for f in folders)))
	values = [qval.value for qval in system.tag.readBlocking(paths)]
							
	data_table = list(zip(values[::2], values[1::2]))
	
	with open('C:\DailyCSVFiles\DIStatus.csv', 'w') as f:
			
		writer = csv.writer(f)
		
		writer.writerow(header)
		
		writer.writerow(data_table)

```

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/6/2/629d49adb115359a05c84a13c31d8f491c5eea91.png)

---

<div class="post-metadata">

**Author:** ![pascal.fragnoud](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pascal.fragnoud/32/24728_2.png) [@pascal.fragnoud](https://forum.inductiveautomation.com/u/pascal.fragnoud)\
**Post date:** [October 17, 2022, 7:10pm UTC](https://forum.inductiveautomation.com/t/most-efficient-way-to-read-tags-and-insert-into-csv/65298/9 "2022-10-17T19:10:38Z")

</div>

Because that's not how you use `writerow`.

But I'd repeat my suggestion: use the system functions.

```python
dataset = system.dataset.toDataSet(header, data_table)
csv = system.dataset.toCSV(dataset, True, False, False)
system.perspective.download("filename", csv)

```

edit: wait, is this vision or perspective ?

---

<div class="post-metadata">

**Author:** ![michael.black](https://avatars.discourse-cdn.com/v4/letter/m/ee7513/32.png) [@michael.black](https://forum.inductiveautomation.com/u/michael.black)\
**Post date:** [October 17, 2022, 7:11pm UTC](https://forum.inductiveautomation.com/t/most-efficient-way-to-read-tags-and-insert-into-csv/65298/10 "2022-10-17T19:11:54Z")

</div>

perspective

---

<div class="post-metadata">

**Author:** ![pascal.fragnoud](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pascal.fragnoud/32/24728_2.png) [@pascal.fragnoud](https://forum.inductiveautomation.com/u/pascal.fragnoud)\
**Post date:** [October 17, 2022, 7:27pm UTC](https://forum.inductiveautomation.com/t/most-efficient-way-to-read-tags-and-insert-into-csv/65298/11 "2022-10-17T19:27:26Z")

</div>

Then if you piece together the little snippets in the posts above, it should do the trick.

If don't want to use a standard download, (maybe you're doing this in a gateway script) you'll need to dig in the csv writer doc to find how to write a table.  
Or loop through it:

```python
for row in data_table:
    writer.writerow(row) #might need formatting, I don't know how this function works

```

---

<div class="post-metadata">

**Author:** ![michael.black](https://avatars.discourse-cdn.com/v4/letter/m/ee7513/32.png) [@michael.black](https://forum.inductiveautomation.com/u/michael.black)\
**Post date:** [October 17, 2022, 7:31pm UTC](https://forum.inductiveautomation.com/t/most-efficient-way-to-read-tags-and-insert-into-csv/65298/12 "2022-10-17T19:31:48Z")

</div>

I am doing it through a button right now but eventually I want to create this csv file once a day through gateway scripting. I tried the method above using system.perspective.download but did not have luck. The file isn't changing at all. If I am doing it through gateway scripting would this perspective download function not work?

---

<div class="post-metadata">

**Author:** ![pascal.fragnoud](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pascal.fragnoud/32/24728_2.png) [@pascal.fragnoud](https://forum.inductiveautomation.com/u/pascal.fragnoud)\
**Post date:** [October 17, 2022, 7:35pm UTC](https://forum.inductiveautomation.com/t/most-efficient-way-to-read-tags-and-insert-into-csv/65298/13 "2022-10-17T19:35:30Z")

</div>

> [@michael.black](#):
>
> The file isn't changing at all.

Did you not get a download prompt ? What do your logs say ?

> [@michael.black](#):
>
> If I am doing it through gateway scripting would this perspective download function not work?

Nope.  
Read up on ignition's scopes, this will help you tremendously in using ignition.

Is the file supposed to go on the same machine as the gateway is running ?

---

<div class="post-metadata">

**Author:** ![michael.black](https://avatars.discourse-cdn.com/v4/letter/m/ee7513/32.png) [@michael.black](https://forum.inductiveautomation.com/u/michael.black)\
**Post date:** [October 17, 2022, 7:39pm UTC](https://forum.inductiveautomation.com/t/most-efficient-way-to-read-tags-and-insert-into-csv/65298/14 "2022-10-17T19:39:11Z")

</div>

Yes. Same machine. I want to create the file locally on same machine running Gateway and then send this file out in an email shortly after.

I am getting nothing in the logs, no errors or other indications when I press the button.

---

<div class="post-metadata">

**Author:** ![michael.black](https://avatars.discourse-cdn.com/v4/letter/m/ee7513/32.png) [@michael.black](https://forum.inductiveautomation.com/u/michael.black)\
**Post date:** [October 17, 2022, 7:40pm UTC](https://forum.inductiveautomation.com/t/most-efficient-way-to-read-tags-and-insert-into-csv/65298/15 "2022-10-17T19:40:53Z")

</div>

so seems like I would have to go the route of using the csv write instead is what you are saying if I intend to do this through a scheduled gateway event

---

<div class="post-metadata">

**Author:** ![pascal.fragnoud](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pascal.fragnoud/32/24728_2.png) [@pascal.fragnoud](https://forum.inductiveautomation.com/u/pascal.fragnoud)\
**Post date:** [October 17, 2022, 7:43pm UTC](https://forum.inductiveautomation.com/t/most-efficient-way-to-read-tags-and-insert-into-csv/65298/16 "2022-10-17T19:43:26Z")

</div>

There might be system functions for that but I never used them.  
One of those should do:  
[https://docs.inductiveautomation.com/display/DOC81/system.file](https://docs.inductiveautomation.com/display/DOC81/system.file)

---

<div class="post-metadata">

**Author:** ![michael.black](https://avatars.discourse-cdn.com/v4/letter/m/ee7513/32.png) [@michael.black](https://forum.inductiveautomation.com/u/michael.black)\
**Post date:** [October 17, 2022, 8:10pm UTC](https://forum.inductiveautomation.com/t/most-efficient-way-to-read-tags-and-insert-into-csv/65298/17 "2022-10-17T20:10:36Z")

</div>

Ok. Will check it out. Thanks for the help!
