DeltaV Live Script Action on User Login

Hello everyone.  In Operate, we have an OnChange event (variable on the toolbar) that fires on new logins and records the currently logged in user to a control module (named after the workstation) for reasons.  I'll need to reproduce this in DeltaV Live.  The trouble I'm having, of course, is the best way to react to the new login.  I've been trying string and multi-language string variables OnWrite, tying the value of the variable to a function which takes ENV.UserName(), but this isn't working.  I even tried a boolean variable and animating it's value to something like ENV.UserName() != prevUser (another string variable to manage the trigger).  I'm pretty new to Live, so I'm probably missing something.  What advice do you wise one's have?

Thanks!

-Daniel

  • Andre may have already done this but I would probably create a string variable on the Layout being used. Create a layout timer (interactions tab) to run "occasionally", compare the current user to the variable, if different do your logic and then update the Layout variable.

    I know there are other methods to probably do this but not sure how "supported" they would be or performance issues they could cause.
  • I have done this, well something similar. I created a variable and tied it to a module parameter. Then, in the OnWrite script, I perform the logic I want and finish this with a Return SourceValue.

    This last command sets the variable value equal to the source value, which was my module parameter. once the source and the variable are equal the OnWrite script stops. Without the Return value, the script just keeps on executing.

    In your case, I think it would be:
    return ENV.UserName()

    I would use a String variable.

    As Matt suggests, placing this in your layout ensures it is monitoring all the time. Layout variables are you Global variables, available everywhere as Lyt.VarName. If you did this in the Alarm Banner, it would work because you are not referencing the variable from anywhere outside the host display. I think the right place is the Layout, but you have to make sure all layouts have the variable.

    PS> I'd love to see Layouts get a set of "Global Variables" or "common Variables" that you can manage and automatically appear on all Layouts, ensuring you don't have to edit each layout every time you need a new common variable. Especially since you can't copy and past variables. And a common On Open script that runs on all Layouts before any Layout specific On Open script. With all the display options and corresponding layouts we see with Live, a common set of variables and initialization script would be nice to have.

    Andre Dicaire

  • In reply to Andre Dicaire:

    Oops. I spoke too soon. I see that the String and Multi-Language type variable does not allow an animation. You can't point the string to the ENV.UserName(). I used a numeric value on my Onwrite test.

    So forget the OnWrite based on the current user name. I'll have to poke around. Matt's suggestion to use a timer might be the way to go. I'll see what I fing.

    Andre Dicaire

  • In reply to Andre Dicaire:

    Thanks! I didn't go down the timer road at first, since I think I would prefer to have an event handler fire like OnChange does, but that's the old VBA way, and with HTML5 and TypeScript, timers may have to be the way to do this kind of thing. Appreciate the replies guys.
  • In reply to Daniel Parrish:

    This OnChange has been brought up as a need but I haven't heard any update if it will be added or not. New features are low priority for awhile.
  • In reply to Matt Stoner:

    Understood. What's the UDEP link again, and I'll give it a bump for good measure. Thanks for the help Matt!
  • In reply to Andre Dicaire:

    Ok gents. I got the trigger working. Noting that you can only animate a string using a function (Library Animation), I created a simple function that takes in a string and simply returns it. Doing that, I can pass in either ENV.UserName() OR pass in a datalink's .Value parameter (that's important) that is tied to ENV.UserName(). The later actually works a little better, since it doesn't respond to the temporary <none> user login that happens when changing users, that can cause a double-firing.
  • In reply to Daniel Parrish:

    Glad you figured it out.  I did some more digging to get the full picture.  Here's what I found.

    The Layout variable is limited to setting variables as a static value or tied to a Standard.  Animations and library Animations are not supported at that level.  At all the other levels, you can define the Variable with the options shown, assuming the option is permitted on the variable type.

     

    Layout

    Display

    Contextual Display

    Gem

    Group

    Static Value

    X

    X

    X

    X

    X

    Browse Standard

    X

    X

    X

    X

    X

    New Standard

    X

    X

    X

    X

    X

    Animation

     

    X

    X

    X

    X

    Blink Animation

     

    X

    X

    X

    X

    Library Animation

     

    X

    X

    X

    X

    Variables

     

    X

    X

    X

    X

    References

     

    X

    X

    X

    X

    For each variable type, the following options are allowed:

     

    Static Value

    Browse Standard

    New Standard

    Animation

    Blink Animation

    Library Animation

    Variables

    References

    Color

    X

    X

    X

     

    X

    X

    X

    X

    Font

    X

    X

    X

    X

     

    X

    X

    X

    Boolean

    X

    X

    X

    X

     

    X

    X

    X

    Image

    X

    X

    X

     

     

    X

    X

    X

    String

    X

    X

    X

     

     

    X

    X

    X

    Multi-Language string

    X

    X

    X

     

     

    X

    X

    X

    Measurement

    X

    X

    X

    X

     

    X

    X

    X

    Number

    X

    X

    X

    X

     

    X

    X

    X

    Color, Image, string and multi-language string do no support Animation, and one must use Library Animation.  The Library animation must be of type string and this ensures the animation returns a valid data type.

    In the OOB Functions, there is F_ReadParameter of type String, which allows you to read a DeltaV parameter and return it as a string, which you will need to link a display variable to a runtime string.

    I created a getUserName funciton of type string to return the user name.  As you eventually found, this works.  The Variable follows the Logon User name.

    I then created an OnWrite Script.  I created a COUNT variable and increment this on a log on change, as a way to show the script fires only once per name change. 

    On write script is:

    {

    Dsp.COUNT = Dsp.COUNT + 1;

    return ENV.UserName()

    }

    There appears to be a wrinkle in that you are picking up <none> as you transition between users.  You likely need to differentiate between a User change and a log off that leaves the user as <none>.  Assuming you want to do something different for a log off  versus a user change, you might be able to use a counter like above.  Read ENV.UserName in to a string at the top of the script.  If == to "<none>", increment the count.  If the count increments to x, then a log off has occurred and execute the appropriate script.  If ENV.UserName becomes something else, then a user change has occurred and you can execute that script.

    {

    let UserName = ENV.UserName()

    If (UserName == "<none>") then  {

      Dsp.Count = dsp.count +1;

      If (Dsp.Count >= 5)  Then   {

         Dsp.Count = 0;

         //Execute Log Off script as user has been left as <none>

         Return UserName

    }

    }

    Else {

    Dsp.Count = 0;

    \\UserName has changed to a new user 

    \\ Execute Script for new user change

    return UserName

    }

    }

    I haven't tested this, but the point is, if you don't return the updated value in the function, the script should fire again, and after a number of runs, you know a log off has occurred rather than a change user.

    What I learned was the Layout Variables cannot be animated.  They are either Static or liked to a Standard.  The Alarm Banner is one display that is always used.  I'm thinking that you can add this variable to the Alarm Banner to monitor the user and execute scripts.  

    Andre Dicaire

  • In reply to Andre Dicaire:

    Thanks for the research! Nicely done. I'll be wrapping this all up in a Gem anyway with some other elements, so animating a variable at the Gem level should work. All my testing has been on a display, so your table is helpful to see that it should function the same on a Gem. Thanks a lot Andre.

    -Daniel
  • In reply to Daniel Parrish:

    I had another thought on this. I'm thinking of creating a function for the ENV functions. The function would take a string as an input, say UserName, Node, etc, and would us that to determine which ENV function it should call, and return that string. This way, you have one Function in the library, and can use it for various environment calls.

    I'm thinking a Case statement so the function checks the Input STRING, and returns the ENV.STRING(). I'd use much more clever names and such, for sure.

    What do you think?

    Andre Dicaire

  • In reply to Andre Dicaire:

    I can see that working. It's not dissimilar from what I wound up doing with a single function that takes a string input and simply returns it. I can send it any of the ENV functions, a datalink's .Value, or anything really. This allows me to use it to animate string variables like I wanted. I just called it F_ReturnString. If I discover the need for other datatypes being treated the same way, then I'll do the same thing per type needed. Lemme know how you like your implementation vs. what I did and we can compare.

    -Daniel