Dynamic referencing in property Change script

Hi,

Im fairly new to text programming and was wondering if there was a function or notation in scripting that works the same way as in indirect tags.

Where in indirect tags I would use {1} to reference another variable.

Im trying to do a simple if statement in a propertyChange script.

example:

if event.propertyName == "DeviceChange"



  DynamicDeviceName = "DeviceName"  #F1,F2,F3,F4,F5,F6,F7,F8 and so on........
  #The DynamicDeviceName has over 40 different possibilities.



  if event.source.Service."DynamicDeviceName" == 1: #DynamicDeviceName is defined by which DeviceName is present.
     print "Good Vibes only"


  if event.source.Service.F1 == 1:
     print "SomeCoolStuff"
  #F1 is a device but it can also be: 
  if event.source.Service.F2 == 1:
     print "SomethingElse"
  #since "F2" is also a Device in the udt

  # event.source.Service   is a reference to a Template property called Service which is a UDT that contains 42 booleans. 
  # So to call upon the wanted information I Wish to call upon event.source.Service.F1 when the DeviceName is F1


Thanks,
Thomas

Can you edit your question (pencil icon), select each piece of code and use the </> code formatting button to format your code? This will preserve indentation, apply syntax highlighting and make it much easier to read.

I don’t really understand the question very well, could you rephrase it a bit?

You can use variables in Python like this:

myVar = 5
print myVar
#This will print '5' 

There is possibly a way to accomplish what you are trying to do, but you haven’t given enough information.

What type is event.source.Service? I say that because as far as I am aware no component has a Service property.

What is the overall goal here, there may be a much better way to achieve whatever it is you are trying to achieve.

1 Like

Unless service is a property on a custom component from a module, I don't think this is valid. Though even if its a custom component from a module, I don't think this is valid python regardless.

If you are new to Ignition I highly recommend going through the following - Inductive University Course List - Learn Ignition Free

If you can explain what end goal you're trying to achieve exactly, it will help us better to help you.

1 Like

UDT is not a valid Python Type.

Can you run something like:

print type(event.source.Service)

And let us know what is printed in the console?

1 Like

<type ‘com.inductiveautomation.factorypmi.application.binding.UDTProperty’>

The goal is to set a status based on a boolean that declares if the machine is out for service

I created a user defined tag UDT containing the different tags.

I basically want to insert a string containing the DeviceName into my if statement “event.source.Service.” and from there reach the “position” in the UDT (User defined Tag)and get the False/True from the tag.

This:

if event.source.Service.F1:

is not going to work. Because the type UDTProperty doesn’t have an F1(or whatever) method.

Something like this might work though (Not even close to being tested):

if event.source.Service.TagPath.getItemName() == 'F1':
    if event.source.Service.getValue(event.source.Service.TagPath).value:
         print "Some Cool Stuff"

Honestly though, I’m not sure you’re approaching this correctly? Is one indicator going to show the status of 42 different booleans? Why won’t an indirect tag binding work?

I would consider using two properties on the template One that holds the base path to the UDT and another that holds the Device name. Then use those to build and indirect tag binding for the status indicator. No script needed.

What propertyChange event is this firing on? I would recommend against putting this on any vision component’s property change. Seems like this should be a gateway tag change event or in the gateway context of some sort.

1 Like

It can be done using eval(), but, just because it can be done doesn’t mean that it should be done. eval() can be very dangerous to use as it will try to execute anything you put into it. Even bad stuff…

service = event.source.parent.getComponent('LH Container').Service

deviceList = ['F1', 'F2', 'F3']
for device in deviceList:
	print eval('service.{}'.format(device))

I would add memory tags to your UDT, write a gateway timer script to poll the tags, and then set the memory tags to whatever status you need.

Surely, use getattr before eval, unless I’m missing something about the problem statement:
https://docs.python.org/2.7/library/functions.html#getattr

(I do agree with others that there’s probably a better way to architect this whole thing, though)

3 Likes

Huh. I thought I had had tried it earlier, but looking back at my notes, I had tried __getattribute__. A subtle but important difference.

Greetings,

I’ve Taken your recommendations into account and bound the tag directly as a Template Parameter.

so instead of the UDT being bound to the template, now instead it is the boolean that is a parameter.

thank you for your replies!

1 Like