Advice from software people

Hi all,
I've been working on scripting in Perspective using Python (or whatever AI's version is called) and I've realized that I don't know where to even start most of the time.

So, I've come here to solicit advice on a specific example that I'm working with. I have an instance of Perspective running on an Edge gateway and I would like to use the Equpment Schedule component. But, as I found out the hard way, Edge doesn't support any sort of databased functionality (other than the built-in historian).

Instead of giving up, I created a function that uses the import/export dataset functionality to do the trick. The script work but, is it the preferred way to do it? I can't help but think that the database installed by Edge as a default is there and available. Should I have been trying using Python to interface to it?

Here is what I cobbled together, criticize away.

def runAction(self, event):
	from random import random, randint
	
	# Get current dataset from file
	file_path = "/usr/local/bin/ignition/data/custom-data/es_data.csv"
	data_string = system.file.readFileAsString(file_path)
	data = system.dataset.fromCSV(data_string)
	
	# Get all data from the form
	eventLabel = self.parent.parent.getChild("cflexName").getChild("TextField").props.text
	itemId = self.parent.parent.getChild("cflexAsset").getChild("Dropdown").props.value
	startDate = self.parent.parent.getChild("cflexSdate").getChild("DateTimeInput").props.value
	endDate = self.parent.parent.getChild("cflexEdate").getChild("DateTimeInput").props.value
	
	# Create new event object
	# Dataset header is itemId, eventId, startDate, endDate, label so,
	# row members need to maintain the same order
	row = [itemId, str(randint(1000, 10000)), startDate, endDate, eventLabel]
	
	# Append event data to new object
	data = system.dataset.addRow(data, row)
	
	# Prepare for CVS export
	csv = system.dataset.toCSV(dataset = data, showHeaders = False, forExport = True)
	filePath = "/usr/local/bin/ignition/data/custom-data/es_data.csv"
	system.file.writeFile(filePath, csv)
	
	# Call the refresh methode to redraw the events
	self.parent.parent.parent.getChild("rflexTop").getChild("btnRefresh").refresh()

It is not available. Edge's cheap price comes from limited functionality, and the database functionality is the key piece that was chopped. While IA won't stop you from importing/exporting datasets as a non-DB substitute, the right answer is to use Standard Ignition instead of Edge. (Trying to evade the limit with custom code to access real databases would be breaking the license, IIUC.)

This is correct, if you want to bring database data to an Edge Gateway it is typically done in a larger architecture w/ at least one primary server that has a database connection. With Edge and a full Gateway, passing a dataset-like object to an edge server requires mainly the Gateway network connection and an approach for moving the object, such as:

  • a dataset memory tag defined on the edge, that is connected over GAN and available to the primary server so it can write data like a schedule to the memory tag (this route is less scripting)
  • system.util.sendMessage | Ignition User Manual Using sendMessage to distribute complex objects to remote Gateways (this route is all scripting)

If there is a standard Gateway available I'd do option 1.

So you have a refresh method on a button, and you're calling it from somewhere else ?
That's... confusing. You're going through a button that has no role whatsoever in what's going on.

Put the refresh method on what needs to be refreshed, and call that from the button AND whatever else needs to refresh things (like this script).

If there are multiple things to refresh, you can give them all a message handler and send a message to everything at once.

Also note that if that refresh is refreshing a table that displays the data...
You should instead bind the table to that data.

If you only have that dataset to store, you could (and probably should) use a dataset tag instead of a file.
Bidirectionally bind a custom prop to the tag, and when the form is filled and validated, add the row to the dataset. This will update the tag.

The tag:

button onActionPerformed script:

	# these are 3 text fields to simulate a form
	foo = self.parent.parent.getChild("foo").getChild("TextField").props.text
	bar = self.parent.parent.getChild("bar").getChild("TextField").props.text
	pox = self.parent.parent.getChild("pox").getChild("TextField").props.text
	
	# add the row to the dataset
	self.view.custom.data = system.dataset.addRow(self.view.custom.data, [foo, bar, pox])

The custom property binding: