9.2. Configure the Switch

Switching Criteria - Domains

Generally speaking, the criteria for switching between redundant data streams should reflect expectations from the plant or process. The criteria for an invalid domain apply to identical points in each of the two input data domains. When that criteria is met in one domain, it is no longer considered valid, and the DataHub instance makes the switch.

Key concepts:

Switching Criteria - Points

For any point in the domain  means that your entire data set is considered invalid if even one data point meets your test criteria. Instead, consider using a sentinel point or pattern.

For this point  lets you choose a connection status point or specify a pattern to act on behalf of the whole domain.

Valid and Invalid OPC Qualities

The OPC spec has two general categories for valid and invalid qualities, where only Good and Local Override are valid. The rest of the OPC qualities, such as Initializing, Out of Service, Sensor Failure, Not Connected, Bad, and so on are considered invalid for different reasons. If you want to test for all of these, and switch whenever there might be an interruption to the data stream, or a change in data quality, you can choose not equal to and Good for Data quality is in the Input Domain configuration.

There are two things you'll need to consider:

  1. If a point's quality changes to Local Override it will cause the system to switch. This rarely happens unless someone enters a value for a point in the DataHub Data Browser.

  2. If you choose this setting for all points, then the system will switch whenever any of the points on the current source is not Good. Consider instead testing a sentinel point or pattern, as explained above.

Checking value AND quality

The interface does not allow for checking both the value of a point and its quality. You can use this script to create a synthetic point that reacts to both, and lets you check them.

Example Script RedundancyState.g

/* Creates a state point that combines both quality and value to 
 * produce a single output value that can be used by a redundancy 
 * pair to determine input domain validity.  The computeState method 
 * can be as complex as you like, so long as it finally writes 
 * a 0 or 1 to the state point.
 */

require ("Application");

class RedundancyState Application
{
	// The state point to be used for configuring the redundancy pair
	statePoint = "RedundancyState";
	
	// The point in the input data set to check for quality and value
	sentinelPoint = "WinAC1500.Memory.master";
	
	// The names of the input domains.
	domains = [ "HPC_1", "HPC_2" ];
}

method RedundancyState.computeState (pointSymbol)
{
	local info = PointMetadata(pointSymbol);
	local isBad = (info.quality != OPC_QUALITY_GOOD || info.value == 0);
	datahub_write(string(info.domain, ":", .statePoint), isBad ? 0 : 1);
}

method RedundancyState.constructor ()
{
	local pointName, pointSymbol;
	with domain in .domains do
	{
		pointName = string(domain, ":", .sentinelPoint);
		pointSymbol = symbol(pointName);
		datahub_command(format("(create %s:%s 1)", domain, .statePoint), 1);
		datahub_command(format("(create %s:%s 1)", domain, pointName), 1);
		
		.OnChange(pointSymbol, `(@self).computeState(#@pointSymbol));
		.computeState(pointSymbol);
	}
}

/* Start the program by instantiating the class. */
ApplicationSingleton (RedundancyState);