Perspective Components' Value Binding

Hi all,

I'm using one of the standard Perspective components for my motor faceplate and would like to bind a tag to show as the text of the value property, which works as expected.

Now I would like to add a unit to said text - something like: 10 m/s, where the 10 is my tag value.

I tried the following in a script transform:

def transform(self, value, quality, timestamp):
value = toString(value) + 'ft/s'
return value

I tried with and without the toString function and also different variations of it. Nothing worked.

Why doesn't this work and what can I do about it?

Thanks in advance.

Try just str() instead of tostring()

Not sure why you would use a script transform for this, from memory they are slower to run, so they will hog more resources in bulk.

I would just do it with an expression:

{value} + ' m/s'

Supposed to run faster, and it's simpler to read.

2 Likes

An expression binding would be as simple as,
{[default]MyTag} + " m/s"
And if you've specified the EngUnit when creating the tags (which I'm sure you have) then you can use,
{[default]MyTag} + " " + {[default]MyTag.EngUnit}

Note that @David_Stone and I are inserting a space between the numerical value and the units as they're separate "words" and it improves readability. It's a recommendation on the SI standard but I don't know if there's an equivalent for the system still used in some of the colonies.

General comment: I would always try and use a separate label for the units for a few reasons:

  • It allows the numbers to be right-aligned and the units left-aligned so that columns of values containing different units remain tabular even if the lengths of the units varies.
  • You can use a different font weight / size / shade for the units to tone them down and reduce visual clutter. The operator will get to know the units but the numerical value is what's important to them.
  • Keeping them separate means the value can be referenced by another component or expression without another call to the tag. When you mix in a string this gets messy.
6 Likes

@Roman - see How to post code on this forum.

1 Like

Great advice but, I'm not sure how this would be implemented with parameter passing.

I tried the most intuitive way, by go through an expression transform, which obviously didn't work out for me:

{value} + {value.EngUnit}

Is there a solution to this issue?

When passing a tag value, pass the tag path instead, and reference everything with that instead of a passed value.

I think we're on the same page but maybe I'm not explaining myself well. Let me try this again.

How do I replace the literal in the expression field with a pointer to the EngUnit:

Because you aren't passing the actual path to the tag as the parameter, use a property binding to view.params.tagPath, then do an expression transform:

{value} + '/FeedbackStates/stsVelocityFb'

Under that, do another expression transform:

tag({value}) + ' ' + tag({value} + '.EngUnit')

Basically you form the path to the tag, then you reference it, and the EngUnit as well.
If you were just passing a complete tag path, you would just need the second transform.

Create a tagPath parameter on the view.
Create a property binding on the label like this:

Tag value and units

You can get fancier and use the tag's FormatString too:

numberFormat(
	tag({value}),
	tag({value} + ".FormatString")
) 
+ " " 
+ tag({value} + ".EngUnit")

In my example this would result in 14.42 m/s/s.

Oy!

Really @Transistor, @David_Stone ?

The engineering unit retrieval belongs in a separate custom property, which then can be referenced in the original indirect tag binding's transform. (And format string, too, if wanted.)

If you find yourself using the tag() expression function outside an actual expression tag, you are screwing up.

2 Likes

Thanks, Phil.
How would that work?

The Engineering Unit binding, on a component custom property, looks like this:

The Format String binding is similar, also on a component custom property.

Then the text property binding (I used a label component) would look like this:

No tag() function!

Everywhere in a UI you think you need a tag() function, train yourself to split off a custom property with an indirect binding.

8 Likes