Alarms Engine (Reference) manages the execution, evaluation, and lifecycle of all alarm conditions within the FrameworX runtime environment. The Alarms Engine orchestrates:

The Alarms Engine orchestrates:

  • Continuous condition evaluation
  • State machine transitions
  • Event generation and logging
  • Notification dispatching
  • Database synchronization
  • Multi-threaded processing

Understanding the engine helps when:

  • Optimizing high-volume alarm systems
  • Debugging complex alarm behaviors
  • Implementing custom notification schemes
  • Managing distributed alarm architectures

In this page:

Alarm Lifecycle

State Machine

Each alarm item follows this state progression:

  • Normal - Condition not met
    • → Active (condition triggered)
  • Active - Condition met, not acknowledged
    • → Acknowledged (operator ack)
    • → Normalized (condition cleared)
  • Acknowledged - Condition met, acknowledged
    • → Normal (condition cleared)
  • Normalized - Condition cleared, not acknowledged
    • → Normal (operator ack)

State Transitions

csharp

// State transition events
OnActive()      // Normal → Active
OnAcknowledge() // Active → Acknowledged
OnNormalize()   // Active → Normalized
OnReturn()      // Any → Normal

Evaluation Process

Scan Cycle

The engine evaluates alarms in cycles:

  1. Tag Value Update - Tag system notifies engine
  2. Condition Check - Evaluate against limits
  3. Deadband Verification - Apply time/value deadbands
  4. State Evaluation - Determine state change
  5. Event Generation - Create alarm event
  6. Notification Dispatch - Trigger notifications

Multi-Threading

  • Main Thread - Coordinates evaluation
  • Evaluation Threads - Pool for condition checking
  • Database Thread - Async logging
  • Notification Threads - Parallel notification dispatch

Thread pool size: Min(CPU cores * 2, Active alarm count / 100)


Condition Evaluation

Standard Conditions

For each scan cycle:

IF (EvaluateCondition(TagValue, Limit))
  AND (NOT InDeadband())
  AND (EnableCondition == True)
  AND (Group.Enabled == True)
THEN
  TriggerAlarm()

Rate of Change

Special handling for RateOfChange:

CurrentRate = (CurrentValue - PreviousValue) / TimeDelta
IF (CurrentRate >= Limit)
  TriggerAlarm()

Sampling: Every 100ms for RateOfChange conditions

Deviation Alarms

Deviation = ABS(TagValue - Setpoint)
IF (Deviation > Limit + SetpointDeadband)
  TriggerAlarm()

Deadband Processing

Time Deadband

Prevents re-triggering within time window:

  • Activation - Alarm triggers at T0
  • Deadband Period - T0 to (T0 + TimeDeadband)
  • Blocked - Cannot re-trigger during period
  • Clear - After deadband expires

Value Deadband

Hysteresis to prevent chattering:

  • Hi Alarm Example:
    • Trigger: Value >= 100
    • Clear: Value < (100 - Deadband)
    • Re-trigger: Value >= (100 + Deadband)

Combined Deadbands

Both time AND value must be satisfied:

CanRetrigger = (TimeSinceLastAlarm > TimeDeadband) 
            AND (ValueChange > ValueDeadband)

Database Operations

Write Queue

Asynchronous database writes:

  • Queue Size: 10,000 events (configurable)
  • Batch Size: 100 events per write
  • Flush Interval: 1 second or when batch full

Event Types Logged

  • Alarm Active - Condition triggered
  • Alarm Acknowledged - Operator acknowledgment
  • Alarm Normalized - Condition cleared
  • Alarm Return - Return to normal
  • Configuration Change - Runtime modifications

Database Schema

sql

AlarmEvents (
  EventID BIGINT PRIMARY KEY,
  Timestamp DATETIME,
  TagName VARCHAR(255),
  AlarmGroup VARCHAR(100),
  AlarmArea VARCHAR(255),
  EventType INT,
  Value FLOAT,
  Limit FLOAT,
  Message TEXT,
  UserName VARCHAR(100),
  AckTime DATETIME
)

Notification Pipeline

Dispatch Sequence

  1. Group Notification - Check NotificationMethod
  2. Sound Alert - Play configured sound
  3. Visual Update - Update display elements
  4. Script Execution - Call custom methods
  5. External Systems - API calls/integrations

Priority Handling

High-priority alarms bypass queue:

Priority >= 900: Immediate dispatch
Priority 500-899: High priority queue
Priority 100-499: Normal queue
Priority < 100: Low priority queue

Performance Optimization

Evaluation Strategies

Lazy Evaluation:

  • Only evaluate on tag change
  • Skip disabled alarms
  • Cache unchanging conditions

Batch Processing:

  • Group related alarms
  • Evaluate in parallel
  • Single database transaction

Memory Management

  • Alarm Pool: Pre-allocated alarm objects
  • Event Buffer: Circular buffer for events
  • Cache Size: Last 1000 evaluations
  • String Interning: Reuse message strings

CPU Optimization

  • Condition Caching: Store compiled expressions
  • SIMD Operations: Vectorized limit checks
  • Thread Affinity: Pin threads to cores

Startup Sequence

  1. Load Configuration - Read alarm definitions
  2. Initialize Database - Connect and verify schema
  3. Compile Conditions - Pre-compile expressions
  4. Cache Warmup - Load recent alarm states
  5. Apply Disable Time - Suppress per settings
  6. Begin Evaluation - Start scan cycles

Shutdown Sequence

  1. Stop Evaluation - Halt new scans
  2. Process Queue - Complete pending evaluations
  3. Flush Database - Write all events
  4. Save State - Cache current states
  5. Close Connections - Cleanup resources

Advanced Configuration

Engine Tuning Parameters

Access via configuration file:

xml

<AlarmEngine>
  <ThreadPoolSize>16</ThreadPoolSize>
  <EvaluationInterval>100</EvaluationInterval>
  <DatabaseBatchSize>100</DatabaseBatchSize>
  <QueueSize>10000</QueueSize>
  <CacheSize>1000</CacheSize>
  <UseParallelEvaluation>true</UseParallelEvaluation>
</AlarmEngine>

Runtime Metrics

Monitor engine performance:

csharp

var metrics = @Alarm.Engine.Metrics;
int evaluationsPerSec = metrics.EvaluationRate;
int queueDepth = metrics.QueueDepth;
double avgEvalTime = metrics.AverageEvaluationTime;
int activeThreads = metrics.ActiveThreadCount;

Troubleshooting

High CPU Usage:

  • Reduce evaluation frequency
  • Optimize complex conditions
  • Increase deadband values
  • Check for alarm storms

Database Lag:

  • Increase batch size
  • Optimize connection string
  • Check database performance
  • Archive old data

Memory Growth:

  • Reduce cache size
  • Check for memory leaks
  • Monitor queue depth
  • Clear old events

Missed Alarms:

  • Verify evaluation interval
  • Check thread pool size
  • Review condition logic
  • Monitor system resources

Best Practices

  1. Size thread pool appropriately - 2x CPU cores typical
  2. Use deadbands effectively - Prevent evaluation storms
  3. Optimize conditions - Simple expressions evaluate faster
  4. Batch database writes - Reduce I/O overhead
  5. Monitor queue depth - Indicates processing bottlenecks
  6. Regular maintenance - Archive and optimize database
  7. Profile before optimizing - Measure actual bottlenecks




In this section...