Comparing Nested Object Properties in Perspective

My issue is in trying to compare two custom properties configured on the top level of a view I am building in perspective.

image

I have a button whose display property is bound to one of the properties and compared in a script transform to the other property.

The properties are objects with multiple levels of containment, and I would like the comparison to be made at every level. The binding shown above always returns 'true' even when the object structure, keys, and values are equivalent on the surface. The two ignition native data types that are coming through to the display property binding are 'DotReferenceJythonMap' for the property that has been bound to and 'PropertyTreeScriptWrapper$ObjectWrapper' for the property referenced by its path. I assume due to the different data types, a simple boolean expression comparing the values isn't possible. I tried casting them to dictionaries (which works for the top level but not subsequent levels of containment), but that doesn't work. I have read a little bit about how Perspective handles python native functions on their wrapper objects, but haven't grasped it entirely (any insight would be helpful).

Is there a best way to accomplish this comparison? Should I write a function to recursively cast nested data types to python classes? This seems like a pretty simple binding but haven't found a good solution yet. Thanks in advance.

Try comparing them in an expression, rather than a script transform. We have more leeway/ability to override behavior in expressions, and I remember taking some effort to get comparisons working between Perspective objects in expressions.

That works for when the properties are initially populated (display property evaluates to false), but when a modification is made to 'currentConfigs' and changed back to the original, the display property remains true. Is my understanding correct that an expression binding refreshes when either/any of the referenced properties change (unlike property bindings)?

That should be the case, yes. I think we probably should fix the way equality works for these scripting objects, though... I'll make a ticket to do that.

In the meantime, I guess your best bet will have to be a recursive comparison function that steps through all the items. You could make it somewhat more efficient by comparing keys first, then values. You could also marshal both objects to JSON and compare their JSON representation, since you're guaranteed to not have any arbitrarily complex, non-serializable types in these two dictionaries.

1 Like

Encoding and decoding the JSON representations worked.

1 Like