• Not Answered

Resolving named set value to string

I have the statement 
A  := LOGEVENT ("Valve position changed to "  +  '^/DC1/PV_D.CVS');
in a CALC block. When the containing module is assigned to a workstation it produces what I want eg "Valve position changed to OPEN". If the module is assigned to a controller it produces eg "Valve position changed to ‘vlvno-pv:1’".

I am guessing that this is because the named states in this named set are not User Selectable. BOL says “In addition, named set states have to be configured as user selectable for the state names to be available for use within the controller.” However I don't know why it is different for a module in a workstation.

If I am correct in the above assumption (which maybe someone could  confirm) the obvious solution is to make the named sets User selectable. The problem is that the particular named sets I want to use are 'system' sets which are protected against changing

I think the protection can be removed by exporting the set, changing "FIXED=T" in the export file to "FIXED=F" and importing. However this change, I seem to remember, is overwritten if DeltaV is upgraded.

I don't really want to have to replace all the instances of the 'system' named set with a user defined one as there are an awful lot. Any ideas?

12 Replies

  • Have you tried downloading setup data to affected controller?
  • In reply to vmvmhatre:

    No I haven't done this as the named set is one that is already in use, so I didn't think this would be necessary. However it could be worth a try.
  • In reply to Cedric Dawnhawk:

    Downloading setup data makes no difference.
  • Is it possible to condition the LOGEVENT.
    IF '^/DC1/PV_D.CVS' = ‘vlvno-pv:1’ THEN
    A := LOGEVENT ("Valve position changed to OPEN");
    ELSE
    A := LOGEVENT ("Valve position changed to CLOSED");
    ENDIF;

  • Hi Cedric,
    I guess the setup data download was done at the initial total download. Afterwards, as you stated, the NS can't change.

    There is another point to consider. A NS is a structured variable and owns at least 3 sub parameter and the default
    '^/DC1/PV_D.CV', '^/DC1/PV_D.CVS', '^/DC1/PV_D.CVI', '^/DC1/PV_D'
    You can assign to any of the parameter, but the other 3 need time to updated before the next cycle.
    Mean, if you assign '^/DC1/PV_D.CV' := 1 will change only this sub-parameter. .CVS, .CVI and default will have the old value in the same cycle. This is even valid for any other parameter if you use 'PARAMETER.CV' or 'PARAMETER'
    I'm not 100% sure if that works, but you might try to assign the NS to the string '^/DC1/PV_D.CVS' := ‘vlvno-pv:Open’ and write that value into a string parameter 'STRINGTYPE' := '^/DC1/PV_D.CVS' afterwards. Use the STRINGTYPE for your LogEvent.
    The update process of output variables is anyway some tricky. If you connect an output of a FB (FB/OUT) to an output-parameter then the output parameter get the value only if the execution of this Level ends (i.e. in a composite).
    If you use the Output-Parameter in the same cycle in another expression afterwards, then it will hold the old value while the FB/OUT parameter is updated. A FB is just another deeper level of the calling level
    So you better use the FB/OUT parameter in further usage inside this composite. I guess the update of a named set works accordingly at the end of the execution of that level (Composite/CM Level) to show the new value at least to the next higher entity.
    Let us know your solution later. This is a common problem for many user here.
    Best Regards,
    Michael
  • In reply to Nicholas Stom:

    Thanks Nicholas. Yes that would work but I want to include the logging in a class module where the named set may be different eg vlvnc-pv so the messages would then be wrong, unless I made the condition expression more complicated. I also have some valves that have three positions.
  • In reply to Michael Krispin:

    Thanks Michael. You may have identified the cause, although I am not sure why things are different when the module is assigned to a workstation rather than a controller. Although I didn't show it in the initial post, the full script is:

    if '^/LOG_ENABLE.CV' = True then
    PV_NOW := '^/DC1/PV_D.CVI';
    if (PV_NOW != PV_OLD) then
    if (PV_NOW != 'vlvnc-pv:UNDEFINED') then
    A := LOGEVENT("Valve position changed to " + '^/DC1/PV_D.CVS');
    endif;
    endif;
    endif;
    PV_OLD := '^/DC1/PV_D.CVI';

    so it only executes when .CVI has changed from the previous scan. If .CVS is not changed until the end of the execution scan, it may pick up a value of .CVS that has not been resolved to its name. I should try checking for changes in .CVS not .CVI

    I would try it immediately but I only have access to real controllers when I visit site, which is fairly infrequently. Otherwise I only have a simulation system on which things seem to work.

    I have also fallen foul of the updating of output parameters. I had an OR block at the top level of a module connected to an internal write parameter DIS_CHANGE. Elsewhere in the module there was an SFC composite which was supposed to check the value of the OR block output. Although the SFC composite was after the OR block in the execution order, it didn't detect changes to the OR block output in that module scan if I referenced DIS_CHANGE. I had to reference OR/OUT_D to get it to work. Presumably updating of output parameters and write parameters is always the last thing in the execution order. It may well say this somewhere in BOL.

    You don't think my comment:
    "I am guessing that this is because the named states in this named set are not User Selectable. BOL says “In addition, named set states have to be configured as user selectable for the state names to be available for use within the controller.”
    is relevant?

    If/when I find the answer I will post it, unless Andre Dicaire or Matt Stoner already know the answer ???
  • In reply to Cedric Dawnhawk:

    The NS should work as long as the entry is visible and downloaded to the controller, the user selectable is only for allowing changes from HMI, control studio, etc although there are items that will actually allow you to set the value to non user selectable values like logic in the controller, Watchit, OPC, etc.

    As far as the DIS_CHANGE parameter wired to OR1/OUT_D, Write/Output Parameters are only updated at last part of the execution of the module/composite (after the last block). Changing the DIS_CHANGE parameter type to Internal Reference and point it to OR1/OUT_D would allow you to reference this parameter. If you was to see this, put a module in debug mode and advance thru each block and you will see the wire doesn't update the parameters after the blocks executes and only will get done after the last block executes. Read/Input Parameters are opposite in that they are only done before the first block execution. So if you have a Action/Calc block that updates a Read/Input parameter, any wires from these will be what the value was when it first starting executing.

    Just a note on your expression: if your PV_D is non-zero and you download your module it will do the LOGEVENT again as these temporary variables will get reset to 0. You may consider adding the following as the first part of the expression to address not logging the event on download (although if the PV changes on the first scan after the download...it wouldn't record it so pick your poison):

    IF SYSSTAT('$sysstat_opts:MyDownload') OR SYSSTAT('$sysstat_opts:TotalDownload') THEN
    PV_OLD := '^/DC1/PV_D.CVI';
    endif;

    You can remove the TotalDownload option but wanted to show it here so others can see that check.

  • In reply to Matt Stoner:

    We still haven't answered why the module log event returns the Named State for PV_D value when assigned to the Workstation, but returns the Named Set:index when assigned to the controller. This may have something to do with the the physical controller working with indices rather than words.

    Have you tried using an Alarm configured at the Log priority? Set the %P1 to the /DC1/PV_D.CVS parameter and the alarm message to " Valve position changed to %P1 ". The alarm message parameter is sent to the Ejournal Workstation where it is converted to text and inserted into the message. Set up a condition block or CALC with Boolean Ouptut parameter to trigger the alarm on a change. (CND with PDET and OUT parameter?)

    That should give you the message you wish to capture. You also get to name this alarm and can more easily search for these events.

    Andre Dicaire

  • In reply to Matt Stoner:

    Matt
    Thanks for the clarification regarding UserSelectable and output parameter updating. Regarding the script, I'm not too bothered about spurious logging on download, but the use of the SYSSTAT function is interesting and something that could be very useful in other modules.
  • In reply to Andre Dicaire:

    Thanks Andre

    When I visit site again I'll set some time aside to experiment to try and see what the differenceis between workstation and controller environment . Annoying I can't do it on the simulation system.

    Regarding using a Log priority alarm, I have used this approach with digital pump running signals to indicate when the pump stops and starts. You can just attach the alarm directly to the digital status signal as the log alarm produces an ACT/ACK message when it goes true then an INACT/ACK message when it goes false. This might be a problem with monitoring valves, where there is the UNDEFINED state and possibly the active 2 state to consider. However I may end up doing something along those lines.
  • In reply to Cedric Dawnhawk:

    one approach i've seen is to use an Action block and some String parameters to hold the on/off words. The log event message uses the module specific words. You can add this to the class and specify words for different instance.

    This was used mainly for DO blocks that did not have a named set. I'd go with the Log alarm.

    Note also that the Simulate controller allows all FBs but a licensed Proplus or App station does not allow certain control blocks like PID and Units.

    Andre Dicaire