Live return length of PV

I want to have a variable function return the length of a PV, it would be Module/AI1/PV. I want to use the size of the value as a way to modify some size and spacing for instance if the value is 1.01.. compared to 43,000 I will have different spacing needs. 

I can't seem to get an expression to return the value i'm looking for. I'm wondering if there is a method available like .length. 

I'm using a number funciton with a Script Conversion Type, I'm passing Tag and Path to the function as strings. My script is something like:

return DLSYS.Read(Tag + '/' + Path + '.CV').length

I don't know if i'm even in the ballpark here

  • figured this would be an easy one.. I haven't had any luck myself.
  • In reply to TreyB:

    Live Text Boxes/Datalinks aren't like iFix where the width of the text is what is being displayed. You pick the width you want to display and regardless if the value is too short, just right or too long...the width doesn't change.

    You will need to add configuration of the width(s) to your GEM (if that is what you are doing) to define the width to show unfortunately because the width can't be updated at RunTime either (I've tried that...)

  • In reply to TreyB:

    If you want to determine the length of a number you can use the following "Math.ceil(Math.log10(DLSYS[tag]+1)) ". This won't count decimal places. Also doesn't work with negative numbers, so use absolute value if your source can return a negative number.
  • In reply to Matt Stoner:

    Yes, i would add configuration for the position of the relative items, for instance an icon that sits to the left of the datalink (which is right justified) will move further to the right based on the length of the datalink. Not the length of the datalink itself, but the length of the data being returned. Here is what I'm doing at the moment. I have a variable that calculates the length as follows:

    let result = DLSYS.Read(Tag+'/'+Path+'.CV');
    return result.Value;

    tag and path are Input strings to the function

    I haven't yet begun to calculate the length using an object property because I can't yet get the value returned from this function


    I have tested this by creating a datalink to display the returned value of this function. It is set as Numeric.

    I believe i followed the syntax regarding the Read function and the RtValue object. But, i'm not returning a value for the datalink to display and it is just giving me

  • In reply to TreyB:

    In a function you need to use:
    let result = await DLSYS.ReadAsync(Tag+'/'+Path+'.CV');
  • In reply to Matt Stoner:

    Maybe not...must be Friday!
    An OnOpen Script you would need the Async/await. Are you sure that the Tag+'/'+Path+'.CV' is correct?

    You probably need to turn on the Display Debugging option and in Runtime while the picture is active/selected hit F12 and on the Sources you can select the display animations or events to find the logic to do some breakpoints/troubleshooting on what the values are seeing. You will also see the function and can see what is getting passed into it.
  • In reply to Matt Stoner:

    well, if i were half decent at working in DevTools maybe. I'll see if ChatGPT can get me through it.
  • In reply to Matt Stoner:

    So, my first issue was passing Path... i needed to add the double quotes around it so it was a proper string.. In the end i went a little different route and decided I didn't want the length to be constantly updating because the units and PV would keep moving on the screen if it was bouncing between like 9.9 and 10.. or if it was going negative and positive. So, I am checking the scale parameter, since EU100 is going to give me the largest number i can expect. Also, because that number may or may not have decimal places, i trim the decimals and also convert the number to an object. Once i convert the number to an object with toFixed... i am able to use the .length property. the number passed to 'toFixed' is the number of decimal places you want. Actually, I think the function might create a string not an object. Either way... length property was available where it wasn't with the number being returned by the .Value property.

    Then I just check my EU0 to see if i can possibly expect a negative value (if i'm reading pressure).. Then i can account for an extra space.

    Now I can work on updating my GEM with the dynamic spacing based on this variable. Not sure how i'm going to do that though.

    let scale100 = DLSYS.Read(Tag + '/' + FB + '/' + Scale + '.EU100');
    let scaleDec = DLSYS.Read(Tag + '/' + FB + '/' + Scale + '.DECPT');
    let scale0 = DLSYS.Read(Tag + '/' + FB + '/' + Scale + '.EU0');

    if (scale0.Value < 0) {
    return (scale100.Value.toFixed(0).length + scaleDec.Value + 1);}
    else {
    return (scale100.Value.toFixed(0).length + scaleDec.Value); }
  • In reply to TreyB:

    I suspected it was going to be something like that but I think it can be easier than that...if I get some time this week I will play with this to see if it can be easier.
  • In reply to TreyB:

    OK, In the Function I used a single Input called "Scale" and when using this function I used DLSYS["MODULE/SCALE_PATH"] for this input. SCALE_PATH is FB/PARAMETER or whatever the path to get to the scale parameter to be used.

    Then using your logic above my function logic using this "Scale" input becomes:

    if (Scale.Value.Eu0 < 0)
    {
        return (Scale.Value.Eu100.toFixed(0).length + Scale.Value.DecimalPoint + 1);
    }
    else
    {
        return (Scale.Value.Eu100.toFixed(0).length + Scale.Value.DecimalPoint);
    }

    Note: that if you need the EUs for any reason that would be Scale.Value.Units

  • In reply to Matt Stoner:

    yeah, that's fine. My real concern at this point is what to do with the information. I don't know of a good way to go about using the length to change several different paramaters..

    For instance, Gem.length will be used to determine the horizontal position of 3 different objects and also perhaps the left or right justification of some text. I feel like i'm going to have to use a bunch of functions for each of these. I don't like really using functions in the library to do very specific things. I feel like that should be specfiic to the GEM..

    Before I have used a Selection property in Gem Configuration. But this is a drop down selection which then i can associate additional columns and that matrix would define all my variables. However, I can't see a way to do a similar thing as the Selection but with a variable passed to it.

    I also don't know if i can figure out how to write a function that would return several properties to be used. That would also work since then it's just one function for the whole Gem rather than a single function that i use for a single variable in the GEM.

    So, having had those thoughts, i'm presently working on using the variable Gem.length directly in the property of the object. So, in Geometry.Horizontal Position I would set to Animation, rather than Library Animation.. This gives me a Value input.. I thought I could do something like write a mathematical expression
    "0.4 +4*Gem.length" for instance.. But, I haven't gotten anything like that to work yet. Not sure what the Scale property in Animate would be doing. Haven't had a chance to get more familiar with what Animation is actually doing.
  • In reply to TreyB:

    This is sounding like what I commented on earlier that you want to dynamically set the width of objects based on the database configuration...I played around with some of it but ended up just having the PV, EU, etc widths be a configurable width on the GEM and then do all the positioning based on those configuration items because the animations/scripts don't run at edit time so for the person configuring the GEM to know what it "might" look like at runtime it just seemed to be easier.

    We have considered using a custom selector where you could choose the "option" and then you can add measurements to that selection (see below) and then link the object widths to those measurements...but with not fixed width font you have to find the "worse" case and use that width. Unfortunately I don't think you will find an "easy" way to satisfy everything (or you will spend a lot of time trying to get there and may never get to it).

  • In reply to Matt Stoner:

    Exactly. The Selection approach would be great if I could pass Gem.Length to the Name and have a row for each of 2,3,4,5,6,7,8 ....