Here is another option for using multiple datasources for alarming. This was thrown together and more hard coded than I would like, but it's proof of concept. My opinion is that the alarm list should be sequential and have unique IDs, so this accomplishes that.
This first data source, I was playing around with the data types...
Private Sub AlarmTriggers1_DataChanged(sender As Object, e As Drivers.Common.PlcComEventArgs) Handles AlarmTriggers1.DataChanged
Dim x1 As String = AlarmTriggers1.PLCAddressValueItems(0).LastValue
If x1 <> "" Then
AlarmArray(0) = Convert.ToInt32(x1)
Console.WriteLine(AlarmArray(0))
Active_Alarms(e.PlcAddress, AlarmArray(0), 0)
End If
Dim x2 As String = AlarmTriggers1.PLCAddressValueItems(1).LastValue
If x2 <> "" Then
AlarmArray(1) = Convert.ToInt32(x2)
Console.WriteLine(AlarmArray(1))
Active_Alarms(e.PlcAddress, AlarmArray(1), 1)
End If
End Sub
2nd data source...
Private Sub AlarmTriggers2_DataChanged(sender As Object, e As Drivers.Common.PlcComEventArgs) Handles AlarmTriggers2.DataChanged
Dim x1 As String = AlarmTriggers2.PLCAddressValueItems(0).LastValue
If x1 <> "" Then
AlarmArray(2) = Convert.ToInt32(x1)
Console.WriteLine(AlarmArray(2))
Active_Alarms(e.PlcAddress, AlarmArray(2), 2)
End If
Dim x2 As String = AlarmTriggers2.PLCAddressValueItems(1).LastValue
If x2 <> "" Then
AlarmArray(3) = Convert.ToInt32(x2)
Console.WriteLine(AlarmArray(3))
Active_Alarms(e.PlcAddress, AlarmArray(3), 3)
End If
End Sub
So, I basically created tags (array) to hold the values of both data sources so everything is back in a logical order. Then service the alarm code...
Private Sub Active_Alarms(ByRef PLCAddress As String, ByRef PLCValue As String, ByRef i As Integer)
If AlarmActiveini Is Nothing Then
AlarmActiveini = New IniFile(AlarmActivePath)
End If
Dim Binary_Offset As Integer
Binary_Offset = i * Binary_Length
Dim dt = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
For b = 0 To Binary_Length - 1
Dim Shelved = AlarmActiveini.ReadValue("Alarm " & b + Binary_Offset & "", 7) 'Read Alarm Shelved State
If Shelved = "" Then
AlarmActiveini.WriteValue("Alarm " & b + Binary_Offset & "", 7, 0) 'If NULL/Nothing Then Set to a number (0)
End If
If (PLCValue And (1 << b)) <> 0 Then
Dim result = AlarmActiveini.ReadValue("Alarm " & b + Binary_Offset & "", 3) 'Read Alarm Active State
If result <> "1" Then
AlarmActiveini.WriteValue("Alarm " & b + Binary_Offset & "", 4, dt) 'If Alarm Active State Is Not 1 Then Set Active Time To Now
AlarmActiveini.WriteValue("Alarm " & b + Binary_Offset & "", 1, b + Binary_Offset) 'Set alarm #
Dim Count = AlarmActiveini.ReadValue("Alarm " & b + Binary_Offset & "", 8) 'Get Alarm Historical Count
If Count = "" Then
AlarmActiveini.WriteValue("Alarm " & b + Binary_Offset & "", 8, 1) 'If NULL/Nothing Then Set to a number (1)
Else
AlarmActiveini.WriteValue("Alarm " & b + Binary_Offset & "", 8, Count + 1) 'Increment count by 1
End If
Dim a = b + Binary_Offset
If Alarm_Quantity >= a AndAlso Alarm_Quantity > 0 Then 'Ignore alarm banner if alarm is greater than the alarm quantity
alarmName = AlarmActiveini.ReadValue("Alarm " & b + Binary_Offset & "", 2)
If Globals.Show_New_Alarm_Popup AndAlso Not Splash_Screen.Visible Then
Alarm_Banner.Alarm_Queue(dt, alarmName, b + Binary_Offset) 'Send alarm to list for alarm banner display
End If
End If
If Globals.Alarms_Text_To_Speech Then
If Not AlarmSpeechbw.IsBusy Then
AlarmSpeechbw.RunWorkerAsync()
End If
End If
End If
AlarmActiveini.WriteValue("Alarm " & b + Binary_Offset & "", 3, 1) 'Set Alarm Active State To 1
Else
Dim result = AlarmActiveini.ReadValue("Alarm " & b + Binary_Offset & "", 3) 'Read Alarm Active State
Dim time = AlarmActiveini.ReadValue("Alarm " & b + Binary_Offset & "", 4) 'Read Alarm Fault Time
If result <> "0" AndAlso time <> "" Then
AlarmActiveini.WriteValue("Alarm " & b + Binary_Offset & "", 5, dt) 'If Alarm Active State Is Not 0 Then Set Reset Time To Now
Dim alarmID = b + Binary_Offset
If Alarm_Quantity >= alarmID AndAlso Alarm_Quantity > 0 Then 'Ignore alarm history if alarm is greater than the alarm quantity
Alarm_History_Data(alarmID)
End If
If Globals.Show_New_Alarm_Popup AndAlso Not Splash_Screen.Visible Then
Alarm_Banner.Alarm_Search_Clear(b + Binary_Offset) 'Send alarm id to alarm banner list to clear if shown
End If
End If
AlarmActiveini.WriteValue("Alarm " & b + Binary_Offset & "", 3, 0) 'Set Alarm Active State To 0
End If
Next
Populate_Active_Alarms_Table()
End Sub
There are obviously things to clean up with this, but just wanted to share.
James