@@ -13,6 +13,12 @@ Imports System.Windows.Forms
1313Public Class UPS_Device
1414# Region "Properties"
1515
16+ Public ReadOnly Property Name As String
17+ Get
18+ Return Nut_Config.UPSName
19+ End Get
20+ End Property
21+
1622 Public ReadOnly Property IsConnected As Boolean
1723 Get
1824 Return (Nut_Socket.IsConnected) ' And Me.Socket_Status
@@ -34,6 +40,16 @@ Public Class UPS_Device
3440 End Set
3541 End Property
3642
43+ Private upsData As UPSData
44+ Public Property UPS_Datas As UPSData
45+ Get
46+ Return upsData
47+ End Get
48+ Private Set (value As UPSData)
49+ upsData = value
50+ End Set
51+ End Property
52+
3753# End Region
3854 Private Const CosPhi As Double = 0.6
3955 ' How many milliseconds to wait before the Reconnect routine tries again.
@@ -103,28 +119,13 @@ Public Class UPS_Device
103119 'Private NutStream As System.Net.Sockets.NetworkStream
104120 'Private ReaderStream As System.IO.StreamReader
105121 'Private WriterStream As System.IO.StreamWriter
106- 'Private ShutdownStatus As Boolean = False
107122 'Private Follow_FSD As Boolean = False
108123 'Private Unknown_UPS_Name As Boolean = False
109124 'Private Invalid_Data As Boolean = False
110125 'Private Invalid_Auth_Data As Boolean = False
111126
112127# Region "Properties"
113- Private upsData As UPSData
114- Public Property UPS_Datas As UPSData
115- Get
116- Return upsData
117- End Get
118- Private Set (value As UPSData)
119- upsData = value
120- End Set
121- End Property
122128
123- Public ReadOnly Property Name As String
124- Get
125- Return Nut_Config.UPSName
126- End Get
127- End Property
128129# End Region
129130
130131 ' Public Event Unknown_UPS()
@@ -139,8 +140,14 @@ Public Class UPS_Device
139140 Public Event ConnectionError(innerException As Exception)
140141 Public Event EncounteredNUTException(ex As NutException, sender As Object )
141142 Public Event New_Retry()
142- Public Event Shutdown_Condition()
143- Public Event Stop_Shutdown()
143+ ' Public Event Shutdown_Condition()
144+ ' Public Event Stop_Shutdown()
145+
146+ ''' <summary>
147+ ''' Raise an event when a status code is added to the UPS that wasn't there before.
148+ ''' </summary>
149+ ''' <param name="newStatuses">The bitmask of status flags that are currently set on the UPS.</param>
150+ Public Event StatusesChanged(sender As UPS_Device, newStatuses As UPS_States)
144151
145152 Public Sub New ( ByRef Nut_Config As Nut_Parameter, ByRef LogFile As Logger, pollInterval As Integer )
146153 Me .LogFile = LogFile
@@ -291,6 +298,8 @@ Public Class UPS_Device
291298 Return freshData
292299 End Function
293300
301+ Private oldStatusBitmask As Integer
302+
294303 Public Sub Retrieve_UPS_Datas() Handles Update_Data.Tick ' As UPSData
295304 LogFile.LogTracing( "Enter Retrieve_UPS_Datas" , LogLvl.LOG_DEBUG, Me )
296305 Try
@@ -304,6 +313,7 @@ Public Class UPS_Device
304313 ' UPS_Datas = GetUPSProductInfo()
305314 ' End Select
306315 'End With
316+
307317 With UPS_Datas.UPS_Value
308318 .Batt_Charge = Double .Parse(GetUPSVar( "battery.charge" , 255 ), ciClone)
309319 .Batt_Voltage = Double .Parse(GetUPSVar( "battery.voltage" , 12 ), ciClone)
@@ -312,7 +322,7 @@ Public Class UPS_Device
312322 .Input_Voltage = Double .Parse(GetUPSVar( "input.voltage" , 220 ), ciClone)
313323 .Output_Voltage = Double .Parse(GetUPSVar( "output.voltage" , .Input_Voltage), ciClone)
314324 .Load = Double .Parse(GetUPSVar( "ups.load" , 100 ), ciClone)
315- UPS_rt_Status = GetUPSVar( "ups.status" , "OL" )
325+ UPS_rt_Status = GetUPSVar( "ups.status" )
316326 .Output_Power = Double .Parse((GetUPSVar( "ups.realpower.nominal" , 0 )), ciClone)
317327 If .Output_Power = 0 Then
318328 .Output_Power = Double .Parse((GetUPSVar( "ups.power.nominal" , 0 )), ciClone)
@@ -344,70 +354,26 @@ Public Class UPS_Device
344354 Dim BattInstantCurrent = (.Output_Voltage * .Load) / (.Batt_Voltage * 100 )
345355 .Batt_Runtime = Math.Floor(.Batt_Capacity * 0.6 * .Batt_Charge * ( 1 - PowerDivider) * 3600 / (BattInstantCurrent * 100 ))
346356 End If
347- Dim StatusArr = UPS_rt_Status.Trim().Split( " " )
348- .UPS_Status = 0
349- For Each State In StatusArr
350- Select Case State
351- Case "OL"
352- LogFile.LogTracing( "UPS is On Line" , LogLvl.LOG_NOTICE, Me )
353- .UPS_Status = .UPS_Status Or UPS_States.OL
354- 'If Not Update_Nut.Interval = Me.Delay Then
355- ' Update_Nut.Stop()
356- ' Update_Nut.Interval = Me.Delay
357- ' Update_Nut.Start()
358- 'End If
359- 'If ShutdownStatus Then
360- ' LogFile.LogTracing("Stop condition Canceled", LogLvl.LOG_NOTICE, Me, WinNUT_Globals.StrLog.Item(AppResxStr.STR_LOG_SHUT_STOP))
361- ' ShutdownStatus = False
362- ' RaiseEvent Stop_Shutdown()
363- 'End If
364- Case "OB"
365- LogFile.LogTracing( "UPS is On Battery" , LogLvl.LOG_NOTICE, Me )
366- .UPS_Status = .UPS_Status Or UPS_States.OB
367- 'If Update_Nut.Interval = Me.Delay Then
368- ' Update_Nut.Stop()
369- ' Update_Nut.Interval = If((Math.Floor(Me.Delay / 5) < 1000), 1000, Math.Floor(Me.Delay / 5))
370- ' Update_Nut.Start()
371- 'End If
372- 'If ((Me.BattCh <= Me.Low_Batt Or Me.BattRuntime <= Me.Backup_Limit) And Not ShutdownStatus) Then
373- ' LogFile.LogTracing("Stop condition reached", LogLvl.LOG_NOTICE, Me, WinNUT_Globals.StrLog.Item(AppResxStr.STR_LOG_SHUT_START))
374- ' RaiseEvent Shutdown_Condition()
375- ' ShutdownStatus = True
376- 'End If
377- Case "LB" , "HB"
378- LogFile.LogTracing( "High/Low Battery on UPS" , LogLvl.LOG_NOTICE, Me )
379- .UPS_Status = .UPS_Status Or UPS_States.LBHB
380- Case "CHRG"
381- LogFile.LogTracing( "Battery is Charging on UPS" , LogLvl.LOG_NOTICE, Me )
382- .UPS_Status = .UPS_Status Or UPS_States.CHRG
383- Case "DISCHRG"
384- LogFile.LogTracing( "Battery is Discharging on UPS" , LogLvl.LOG_NOTICE, Me )
385- .UPS_Status = .UPS_Status Or UPS_States.DISCHRG
386- Case "FSD"
387- LogFile.LogTracing( "Stop condition imposed by the NUT server" , LogLvl.LOG_NOTICE, Me , WinNUT_Globals.StrLog.Item(AppResxStr.STR_LOG_NUT_FSD))
388- .UPS_Status = .UPS_Status Or UPS_States.FSD
389- RaiseEvent Shutdown_Condition()
390- 'ShutdownStatus = True
391- Case "BYPASS"
392- LogFile.LogTracing( "UPS bypass circuit is active - no battery protection is available" , LogLvl.LOG_NOTICE, Me )
393- .UPS_Status = .UPS_Status Or UPS_States.BYPASS
394- Case "CAL"
395- LogFile.LogTracing( "UPS is currently performing runtime calibration (on battery)" , LogLvl.LOG_NOTICE, Me )
396- .UPS_Status = .UPS_Status Or UPS_States.CAL
397- Case "OFF"
398- LogFile.LogTracing( "UPS is offline and is not supplying power to the load" , LogLvl.LOG_NOTICE, Me )
399- .UPS_Status = .UPS_Status Or UPS_States.OFF
400- Case "OVER"
401- LogFile.LogTracing( "UPS is overloaded" , LogLvl.LOG_NOTICE, Me )
402- .UPS_Status = .UPS_Status Or UPS_States.OVER
403- Case "TRIM"
404- LogFile.LogTracing( "UPS is trimming incoming voltage" , LogLvl.LOG_NOTICE, Me )
405- .UPS_Status = .UPS_Status Or UPS_States.TRIM
406- Case "BOOST"
407- LogFile.LogTracing( "UPS is boosting incoming voltage" , LogLvl.LOG_NOTICE, Me )
408- .UPS_Status = .UPS_Status Or UPS_States.BOOST
409- End Select
410- Next
357+
358+ ' Prepare the status string for Enum parsing by replacing spaces with commas.
359+ UPS_rt_Status = UPS_rt_Status.Replace( " " , "," )
360+ Try
361+ .UPS_Status = [Enum].Parse( GetType (UPS_States), UPS_rt_Status)
362+ Catch ex As ArgumentException
363+ LogFile.LogTracing( "Likely encountered an unknown/invalid UPS status. Using previous status." &
364+ vbNewLine & ex.Message, LogLvl.LOG_ERROR, Me )
365+ End Try
366+
367+ ' Get the difference between the old and new statuses, and filter only for active ones.
368+ Dim statusDiff = (oldStatusBitmask Xor .UPS_Status) And .UPS_Status
369+
370+ If statusDiff = 0 Then
371+ LogFile.LogTracing( "UPS statuses have not changed since last update, skipping." , LogLvl.LOG_DEBUG, Me )
372+ Else
373+ LogFile.LogTracing( "UPS statuses have CHANGED, updating..." , LogLvl.LOG_NOTICE, Me )
374+ oldStatusBitmask = .UPS_Status
375+ RaiseEvent StatusesChanged( Me , statusDiff)
376+ End If
411377 End With
412378 RaiseEvent DataUpdated()
413379 End If
@@ -419,7 +385,6 @@ Public Class UPS_Device
419385 'Me.Disconnect(True)
420386 'Enter_Reconnect_Process(Excep, "Error When Retrieve_UPS_Data : ")
421387 End Try
422- ' Return Me.UPSData
423388 End Sub
424389
425390 Private Const MAX_VAR_RETRIES = 3
0 commit comments