How to batch add StringChangeOfValueAlarmExt?

Trying to add alarms to a BStringWritable. I have a couple hundred points that need this alarm so this needs to be done through some automation.

Program services doesn’t seem to work and Vykon pro util module has batch alarm adding point for Booleans, Enums and Numerics only, doesn’t have a BatchAddStringChangeOfValueAlarmExt.

You cannot add alarms through program services. It has to be through a program object.

Here is a program object that I used for a basic alarm extensions:

/* Auto-generated ProgramImpl Code */

import java.util.*;              /* java Predefined*/
import javax.baja.nre.util.*;    /* nre Predefined*/
import javax.baja.sys.*;         /* baja Predefined*/
import javax.baja.status.*;      /* baja Predefined*/
import javax.baja.util.*;        /* baja Predefined*/
import com.tridium.program.*;    /* program-rt Predefined*/
import javax.baja.naming.*;      /* baja User Defined*/
import javax.baja.control.*;     /* control User Defined*/
import javax.baja.alarm.ext.*;   /* alarm-rt User Defined*/
import javax.baja.alarm.ext.offnormal.*; /* alarm-rt User Defined*/
import javax.baja.alarm.ext.fault.*; /* alarm-rt User Defined*/

public class ProgramImpl
  extends com.tridium.program.ProgramBase
{

////////////////////////////////////////////////////////////////
// Getters
////////////////////////////////////////////////////////////////

  public String getPointName() { return getString("pointName"); }

////////////////////////////////////////////////////////////////
// Setters
////////////////////////////////////////////////////////////////

  public void setPointName(String v) { setString("pointName", v); }

////////////////////////////////////////////////////////////////
// Program Source
////////////////////////////////////////////////////////////////

  /**
  Add Alarm Extension
  Program to add a String Change of State Alarm Extension to String Points
  **/ 
  
  /**
  For example, If you want to add an Out Of Range Alarm Extension slot to a Boolean Writable whose displayName is like "pump"
  1. Go the the Property sheet of this program object, and type in "pump" (without the quotes)
  2. Come back to this screen and make sure the Program is Up-To_Date, if not Recompile this program object and then execute it.
  **/
  
  
  public void onStart() throws Exception
  {
    // start up code here
  }
  
  public void onExecute() throws Exception
  {
    // execute code (set executeOnChange flag on inputs)
    process(Sys.getStation());
  
  }
  
  public void process(BComponent c) throws Exception
  {
    
    try
    {
      //System.out.println("starting try block");
      String x = c.getName();
      if (x != null && x.toLowerCase().indexOf(getPointName().toLowerCase())>-1)  //converts name strings to lower case and compares components name to string property
      {
        //System.out.println("comparing name");
        if (c.getType().toString().equals("control:StringWritable"))
        {
          //System.out.println("comparing type");
          BOrd sourceOrd = BOrd.make("station:|" + c.getSlotPath().toString());
          BComponent source = (BComponent) sourceOrd.resolve().get();
          BStringChangeOfStateAlgorithm b = new BStringChangeOfStateAlgorithm();
          ((BStringWritable) source).add("Alarm", new BAlarmSourceExt());
          sourceOrd = BOrd.make("station:|" + c.getSlotPath().toString() + "/Alarm");
          BAlarmSourceExt ase = (BAlarmSourceExt) sourceOrd.resolve().get();
          ase.setOffnormalAlgorithm(b);
        }
      }  
      // recurse
      System.out.println("recursing");
      BComponent[] kids = c.getChildComponents();
      for(int i=0; i<kids.length; ++i)
      process(kids[i]);
      //
        
    } // try
    catch ( Exception e )
    {
      System.out.println(e);
    }  
  }
  
  public void onStop() throws Exception
  {
    // shutdown code here
  }
  
}

This one uses to find a point name and a string writable.

If you to add a query here and such, you’ll have to modify this program to do that.

I only modify my original program to add this to strings.

1 Like

Nice, I’ve been avoiding this task hoping someone would have the code. This I can work with.

1 Like

Here’s my final working code for anyone that may need it in the future:

/** Add Alarm Extension Program to add a String Change of State Alarm Extension to String Points **/
/** For example, If you want to add an Out Of Range Alarm Extension slot to StringWritable points
    1. Create a query that selects the StringWritable points you want to modify
    2. Execute this program to add alarm extensions to all points returned by the query
**/

public void onStart() throws Exception {
    // start up code here
}

public void onExecute() throws Exception {
    // execute code
    addAlarmExtensions();
}

public void addAlarmExtensions() throws Exception {
    try {
        System.out.println("Starting alarm extension addition process...");
        
        // Get the query for StringWritable points
        BOrd pointsQuery = getPointQuery().getOrd();
        BITable pointsTable = (BITable) pointsQuery.resolve().get();
        
        @SuppressWarnings("unchecked")
        TableCursor<BComponent> cursor = pointsTable.cursor();
        
        int processedCount = 0;
        int successCount = 0;
        
        while (cursor.next()) {
            processedCount++;
            BComponent point = cursor.get();
            
            try {
                if (point instanceof BStringWritable) {
                    System.out.println("Processing point: " + point.getSlotPath());
                    
                    // Add alarm extension
                    BStringChangeOfStateAlgorithm algorithm = new BStringChangeOfStateAlgorithm();
                    algorithm.setExpression("Connected");
                    algorithm.setNormalOnMatch(true);
                    algorithm.setCaseSensitive(true);
                    ((BStringWritable) point).add("Alarm", new BAlarmSourceExt());
                    
                    // Configure the alarm algorithm
                    BOrd alarmOrd = BOrd.make("station:|" + point.getSlotPath().toString() + "/Alarm");
                    BAlarmSourceExt alarmExt = (BAlarmSourceExt) alarmOrd.resolve().get();
                    alarmExt.setOffnormalAlgorithm(algorithm);
                    
                    System.out.println("Successfully added alarm extension to: " + point.getSlotPath());
                    successCount++;
                }
            } catch (Exception e) {
                System.out.println("Error processing point " + point.getSlotPath() + ": " + e.getMessage());
            }
        }
        
        System.out.println("Process completed. Processed: " + processedCount + 
                          ", Successful: " + successCount);
        
    } catch (Exception e) {
        System.out.println("Critical error in alarm extension process: " + e);
        e.printStackTrace();
    }
}

public void onStop() throws Exception {
    // shutdown code here
}

2 Likes