Unit OOS with MCOMMAND

Hello,

I would like to implement a logic which stops the execution of all modules within a unit, except the Unit Support Module.

My original idea was to just put a flag in the Unit Support Module which all the modules are referencing to place themselves in OOS. This is fine, but once they are in OOS, I have no way of placing them back into In Service because the logic within the modules is not executing. I tried doing this, hoping that the wire is transformed into a reference in the controller and it gets executed, but it isn't:

As you see, even if the USM_OOS parameter is set back to "In Service", it won't get written to the module's MCOMMAND.

So, do you know any more elegant solution? Or do I need to hardcode a reference to each module's MCOMMAND parameter within the USM itself? (i.e have a huge expression which acts on module1/MCOMMAND, module2/MCOMMAND, etc. which would have to be updated each time I add or remove a module)

Thank you,

  • I would highly recommend NOT doing this implementation!

    Doing this means there are no interlocks, no alarming (either coming active/inactive or the acknowledging of them), outputs left in whatever position they were, etc. and BAD THINGS WILL HAPPEN to People and/or Equipment!!!!

    What are you trying to accomplish by doing this? You should rethink how to achieve what you what to do instead of going down this path...

    The answer to the question is yes the logic needs to reside in USM module that is continuously running to turn all the modules on/off but don't go there...
  • In reply to Matt Stoner:

    Hi Istvan, I'm afraid I'd have to echo Matt's concerns. While we're not really sure (based on the information you've provided) what problem you're trying to solve here I think it's a pretty fair bet that your approach will produce less than optimal results.

    If you backed up a step or two and helped folks here understand the operational issue you're trying to address, I'm guessing you'll get some valuable input from the gang here. Look forward to hearing more from you.


    dewey
  • Maybe your are trying to reduce controller loading by setting not in process UNITS (and related CMs/EQMs) out of service??
    I've seen this before and it may create a lot of problems, as Matt explains.
  • In reply to Matt Stoner:

    Thanks for the warnings. It's about Modbus TCP mobile equipment which gets disconnected.
    First, there is a maintenance mode on the units which disables all alarms. From this maintenance mode the user will have the option to "turn off" the unit which would do two things:
    1. stop scanning the Modbus device using the VIM's dataset scan control so that no integrity error appears on the controller when the equipment is disconnected
    2. stop executing the modules. This is because multiple of these mobile equipment can potentially be connected to the controller, but only one at a time. So multiple units are assigned, but only one is ever connected and active. I'd like to avoid to keep running all the modules.
  • In reply to István Orbán:

    I’ve noticed that there is no way to preserve the MCOMMAND parameter’s value after a download:
    - “Restore parameter value after restart” is enabled on the MCOMMAND parameter
    - “Restore parameter values after restart” is enabled on the module
    - “Parameter download behavior” is set to “Preserve user-defined and critical block values”
    But still, after a partial download of the module, it goes back to “In Service”. Is there a way to preserve this parameter?
  • In reply to István Orbán:

    Assuming I go ahead with the implementation, what would be the more optimized way to do it? Having in mind that we have some units with 200+ modules. I don't know how healthy it is to maintain so many references in a module (is there a limit?), even though they are all on the same controller.

    Option 1: hardcode the module names in an expression.

    Pro: references are not maintained in parameters. Contra: expression needs to be changed when a module is added/removed.

    Option 2: maintain external references to all modules' MCOMMAND parameter.

    Pro: expression is fixed, does not need to change. Contra: 100+ ext.ref. parameters.

    Option 3: something tricky with dynamic references and configuring just the names of the modules as string parameters.

    - build reference to just a limited number of modules (25-50?) at a time

    - set MCOMMAND

    - point references to the next set of modules

    - etc.

    - when done, destroy references (point to dummy or leave them empty)

    Disadvantage would be that it takes multiple scans to shut down the unit, but this is not a huge concern.

  • In reply to István Orbán:

    Hi Istvan,
    you need to handle a very interesting application. All above bloggers of course gave enough "no goes" but the many mobile equipment which is connected only once at a time clarify your problem and I think your way might be ok at all for this.
    Just to clarify, is the mobile equipment that different with sensors/actors or do they look similar? Let say you have many standard package units, but the unit itselfs look similar (maybe with only some different equipment which can be set "ignored" how ever)
    If similar, can you reuse your sensor/actor CMs, means do that equipment have the same Flow or Temperature sensor and the same Valves etc, where the address fortunately can reuse also under the same Modbus register? If equipment might be the same but registers are different you might consider also different landing modules and set with dynamic references in your final target sensor/actor to that different landing modules.
    Do that different Modbus slaves even have different slave addresses once they are connected?
    Would be good to get more info about that mobile equipment.
    Regards , Michael
  • In reply to Michael Krispin:

    The required logic could be handled on the communication modules(landing modules, diagnostic module for VIM's configured in deltav), in the diagnosic module of VIM you can write a logic to enable/disable(the alarms) based upon the respective equipment device is connected/disconnected, the modules will be continously running in the controller.This way you can retain the other features as it is and also not deviating from the standard configuration of DeltaV.

    1. The point is your logic should handle(enable/disable alarms) the control modules of only those connected equipment.
    2. The number of connected slave equipments equals to the respective slave logic modules written in the vim diagnostic module.
    3. Show on the faceplate of the control module if either the device is connected or disconnected.

    As Michael suggested, you are handling a different/smart application. need to give a design thought of logic implementation either on class level or classless design of library.

    Karma doesn't have any menu, you get serve what you deserve.

  • In reply to István Orbán:

    By any chance is this all going through a VIM?

    If so I would look into to using dataset scan control, (page 82 of the modbus TCP vim manual), you can disable either devices or registers from DeltaV. When they are disabled, I believe the registers just go to 0 by default.

    This gets around the OOS issues presented above, and should cut down the alarms from disconnecting the equipment.

    If you need help with this, you can contact your LBP, or just call the GSC now that Mynah is a part of Emerson! They should be able to help you out with this if it's the direction you want to go.

  • In reply to Tyler Anderson:

    Tyler: Yes, it is going through a VIM. Dataset scan control is also planned, I mentioned above that we are also shutting down the modbus communication when placing the unit in OOS.

    Michael: there are no shared modules between the different mobile equipment. Yes, their Modbus addresses are all different. Each of them is just one Modbus device (a remote I/O module).

    Kartik29: disabling the alarms is done in a previous step (maintenance mode). From this maintenance mode you can go "deeper" into OOS. I would say the concept of mobile equipment is already deviating from the DeltaV standard... there are not many built-in mechanisms to make it easy, even though more and more people have them.
  • In reply to István Orbán:

    You've got several options but it comes down to either doing this in the controller, or from a workstation.

    In the controller, you have to define the modules to be manipulated. It appears you do not have these modules defined by aliases under the Units? If the were, this would only allow for a common "phase" that could run to set modules OOS. If the aliases are all different, you still have to write a specific name reference for each module in each unit. What you would like is an indexed list of the modules under the unit so that you could write code to programmatically write to each module with a generic function (the Service module or a Module state Management Phase).

    I am thinking of two options here. Create a Named set for each Unit and list the module names in this Named set. You could then be able to read each module name, concatenated it with the parameter and set a Dynamic reference parameter. When the path binds (CST = 0) you write the MCOMMAND value (OOS or In Service) and clear the path, move on to the next index, and if it is not "NULL" of "", loop back and do the next Entry.

    This uses a Named set per Unit, but it allows you to manage the list of modules per unit with a Set UP download to the controller. And it uses a common piece of code rather than explicit logic that needs to be altered, which introduces risk and code maintenance issues.

    Or you could use a separate Module List module, that uses a generic parameter naming scheme like '^/MODULE1.CV' to hold a module name. There is a unique module for each unit, or these could be Unit Parameters. A final '^/COUNT.CV' integer parameter is set to the number of defined MODULEX parameters. Again, using a dynamic reference, an Action expression steps through to read the Module1.cv value and concatenates this into the DYnamic.$REF field, waits for it to bind, writes the desired MCOMMAND value, Checks module is OOS or In Service, clears the $ref, and moves to next index. To manage this, you add MODULEX string parameter with module name to module and set Count to match.

    Another approach is to use a VBA function that reads an XML file with the Unit/module names listed. (or a CSV file, what ever is easier for you). Then you can run through this list programmatically. You would want to limit the number of writes per second, and confirm all modules actually change state as desired. Maybe add a parameter in the Unit to indicate the unit is In Service, Out of Service, In transition, Aborted. If in transition, the function cannot be initiated, but could be aborted. That way, you avoid two workstations trying to set the modules at the same time.

    The advantage here is that you'll get a record of the module MCOMMAND writes, who initiated the transition, and a transition complete message when the status is set to OUT of Service. But you also have Upload records for MCOMMAND to delete/ignore. But now you have an XML file to manage for setting the module list.

    The downside here is that you have an XML file sitting in the workstation and VBA code to execute on it. You can add a LogEvent command in the controller function to log each module's transition. So, I'd lean to using either the Named Set or a ModuleList module, which could be an embedded block. I'd make sure to have a Status parameter that indicates when a Unit is transitioning to and from OOS, and allow for a user to Abort, and change their mind. And a good "Are you Sure" message. And of course, disable this whenever it is not appropriate to run it.

    This would be a lot easier if we also had a String Array type parameter, rather then having to use Named sets. Then you could have a single Unit Level, String Array parameter. And maybe this could be a standard parameter on every unit that is automatically populated with the modules under a Unit. This would give an option to manage module parameters by Aliasing, or by index. Hmm. We would need to be able to use the array string by reference: '^/MODULE_LIST[x]/BLOCK/PARAMETER.CV' in an expression.

    And while I'm at it, every module should have an indexed alarm reference so we can interrogate or set Alarm parameters in a generic way rather than explicit alarm names. If my Detail displays could reference:
    '..../ALM_LIST[x].NAME, .CUALM, .NALM, .LIMIT, .ENABLED, etc. then the alarm settings in the Detail display would be generic, and simply work, with whatever alarm names are used, because it would show alarms by index. Having a String Array, and a way to embed this into a parameter path would solve this.

    Andre Dicaire