I'm trying to dynamically populate a settings template from a JSON config and allow users to update panel settings:
Read from a JSON config file that contains a list of panel settings
Populate a flex repeater with label and current tag value (fields read from config)
Users can update the row's value, which just writes to a custom property on the row
When row edits are made and Save Changes is hit, I want to do the following in an onActionPerformed event:
write the edited value to a intermediate tag
write to a settings bit that operates as a one shot
(PLC receives bit, writes the intermediate tags to panel settings tags, resets bit to 0)
read the updated panel settings
write the updated values back to the rows' custom props
From what I've read, system.tag.writeBlocking() and time.sleep() are no nos in onClick events. However, I'm not familiar enough with the different approaches to implement one shot behavior via Python scripting.
I've implemented this as a single script - doesn't work. I've tried it as a staged script, where onActionPerformed() first triggers Script 1: reads edited values (system.tag.readBlocking()), writes to intermediate tags (system.tag.writeBlocking()), writes to the send settings bit (another system.tag.writeBlocking()). Then I have Script 2: reads from the live panel tags (system.tag.readBlocking()), writes the values back to the custom props that the rows read from. However, this doesn't work because I need a delay for the PLC to finish updating the panel. So it just writes back the initial values to the custom props that display to the user.
Any reason why you can't indirectly bind these tags to their associated view in the repeater? And then when reading from the config just overwrite the associated value in the entry field? Then when the PLC updates values, the embedded views will automatically update their displayed values.
If you are dead set on your current method, you need to split your logic. Ignition is an event based system, make your logic event based. Your save button should only write the values to the intermediate tags and then trigger the bit for the PLC.
Then have your PLC increment an integer when it's done with it's process. Have a Gateway Tag Change event that monitors that integer and on change, broadcasts a message to all open sessions of that specific project to read the latest data from that specific device. Make use of the message payload to pass information that can be used to filter down which sessions should care about the message.
Have a perspective Message Session Event that re-broadcasts the message within the session with system.perspective.sendMessage, and have a message handler on the page with the repeater that reads all the tags for the specified device and pushes their values into the repeater.
You could make it simpler by indirectly binding the integer to a custom property at the view level and having an 'onChange' event script do the value fetching once the value changes. You would need to do the work to be able to indirectly bind to the correct tag for the machine you are editing.
From the manual regarding actions:
Actions are not executed synchronously: sequential actions do not wait for any prior Actions to finish executing before running.