'AVCS SENS - AIDA64 Sensor Data Monitoring Function v2.6 ' - Parses new AIDA64 data every 3 seconds (including External DHT11 data every 30 seconds, if available) ' - Rolling data points of 10, averages calculated over the last 30 seconds ' - Differential Diagnostic Algorithm of data compared to low/med/high/extreme baselines via DHT11 data ' by SemlerPDX Mar2022 ' VETERANS-GAMING.COM Imports Microsoft.VisualBasic Imports System Imports System.IO Imports System.IO.Ports Imports System.Math Imports System.Text.RegularExpressions Imports System.Diagnostics Imports System.Text Imports System.Linq Imports System.Xml Imports System.Threading Public Class VAInline dim MonitorTimerDelay as integer = 3000 'in milliseconds (default 3000 == 3 seconds) dim SensorsCheckDelay as integer = 10 'in multiples of MonitorTimerDelay (default 10 == 30 seconds) dim itemDataPointsMax as decimal? = 10 'total data points to keep in any array, used with AVCS_SENS_DataPointsTotal (Dec) dim itemDataPointsTotal as decimal? = 0 'variable current data points of any given array dim newSensorsCount as integer = 0 dim dtFormat as string = "M/d/yyyy H:mm:ss" dim diagnosticsSensors() as string = {"SCPUUTI","TCPU","TCPUDIO","TCPUPKG","FCPU","FCPUOPT","SMEMUTI","SGPU1UTI","SVMEMUSAGE","TGPU1DIO","FGPU1","TMOBO","TPCHDIO","FPCH","TSB","FSB","TNB","FNB","TVRM","TFAN1VRM","FCHA","FCHA1","FCHA2","FCHA3","FCHA4","FCHA5","FCHA6","FCHA7","FCHA8","FCHA9"} dim savedRequests as integer = 0 dim mainInterval as integer = 0 dim historicLevels() as string = {"LOW","MEDIUM","HIGH","EXTREME"} dim levelBracket as string = "" dim historicLevelBracket as string = "" dim percentDifferenceMax as decimal? = 100 dim pdMaxTemps as decimal? = 25 dim pdMaxFans as decimal? = 100 dim diagnosis as boolean dim currentAverage as decimal = 1 dim debugging as boolean = false dim debugStopwatch as boolean = false dim debugSensors as boolean = false dim debugAIDA as boolean = false dim debugArduino as boolean = false dim debugAverages as boolean = false dim checkResults as boolean = false Public Function LoadHistoricSensorBaselines() dim checkBaselinesSet() as string = {"MEDIUM","HIGH","EXTREME"} dim checkBaselines as string dim contents() as string dim entry() as string if ((VA.GetText("AVCS_SENS_HistoricBaselineData")) IsNot nothing) checkBaselines = VA.GetText("AVCS_SENS_HistoricBaselineData") if (checkBaselines.Contains(vbNewLine)) contents = checkBaselines.Split(new string() {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries) for each line as string in contents entry = line.Split("=") VA.SetText(entry(0), entry(1)) next end if for each baseline as string in checkBaselinesSet if (checkBaselines.Contains("AVCS_SENS_SensorAverages_" + baseline)) VA.SetBoolean("AVCS_SENS_SET_BASELINE_LEVEL_" + baseline, true) else VA.SetBoolean("AVCS_SENS_SET_BASELINE_LEVEL_" + baseline, nothing) end if next end if End Function Public Function GetFanLabelKeyword(ByVal sensorID as string, ByVal sensorLabel as string, ByVal sensorValue as string) if (VA.GetText("AVCS_SENS_FAN_" + sensorID) isNot nothing) sensorLabel = VA.GetText("AVCS_SENS_FAN_" + sensorID) else 'Get User Choice for Fan Label and Command Phrase VA.SetText("AVCS_SENS_FAN_LABEL", "Sensor ID: " + sensorID + "(\n)Sensor Label: " + sensorLabel + "(\n)Sensor Value: " + sensorValue) VA.Command.Execute("F_AIDA_CASE_FANS", true) if (VA.GetText("AVCS_SENS_FAN_LABEL") isNot nothing) sensorLabel = VA.GetText("AVCS_SENS_FAN_LABEL").Replace(" ", "") + "_fan" 'This value seems unused - test without and see if all works... maybe leftover from previous build? VA.SetText("AVCS_SENS_FAN_" + sensorID, sensorLabel) if (VA.GetInt("AVCS_DATA_SAVED_requests") isNot nothing) savedRequests = VA.GetInt("AVCS_DATA_SAVED_requests") + 1 else savedRequests = 1 end if VA.SetInt("AVCS_DATA_SAVED_requests", savedRequests) VA.SetText("AVCS_DATA_SAVED_name_" + savedRequests.ToString(), "AVCS_SENS_FAN_" + sensorID) VA.SetText("AVCS_DATA_SAVED_value_" + savedRequests.ToString(), sensorLabel) else return nothing end if end if VA.SetText("AVCS_SENS_FAN_LABEL", nothing) return sensorLabel End Function Public Function GetLargestInteger(ParamArray integers as integer()) as integer if integers.Length = 0 throw New ArgumentException("AVCS ERROR: GetLargestInteger check params input") end if return integers.Max() End Function Public Function GetAverages(ByRef itemData as string, ByVal dataLabel as string, ByRef itemDataPointsTotal as decimal?) dim dataPointsArray() as string dim dataSum as decimal? = 0 dim dataPointsLen as decimal? = 0 dim dataAverage as decimal? = 0 dataPointsArray = itemData.Split(New String() {","}, StringSplitOptions.RemoveEmptyEntries) dataPointsLen = Convert.ToDecimal(dataPointsArray.Length) if (dataPointsLen >= 11) itemData = dataPointsArray(1) for i as integer = 2 to dataPointsArray.Length - 1 if ((dataPointsArray(i) isNot nothing) andAlso (dataPointsArray(i) <> "")) itemData = itemData + "," + dataPointsArray(i) if (debugSensors) VA.WriteToLog("Check DataPoint = " + dataPointsArray(i).ToString(), "green") end if end if next VA.SetText("AVCS_SENS_" + dataLabel, itemData) if (debugSensors) VA.WriteToLog("Check Variable = " + "AVCS_SENS_" + dataLabel + " = " + VA.GetText("AVCS_SENS_" + dataLabel).ToString(), "purple") end if dataPointsArray = itemData.Split(New String() {","}, StringSplitOptions.RemoveEmptyEntries) dataPointsLen = Convert.ToDecimal(dataPointsArray.Length) itemDataPointsTotal = dataPointsLen if (debugSensors) VA.WriteToLog("AVCS SENS New DataPointsMax = " + itemDataPointsTotal.ToString(), "green") end if else if (debugSensors) VA.WriteToLog("AVCS SENS Cannot build averages yet, data points below 10 = " + dataPointsLen.ToString(), "orange") end if end if if (debugSensors) VA.WriteToLog("dataPoints = " + itemData.ToString(), "pink") VA.WriteToLog("dataPointsLen = " + itemDataPointsTotal.ToString(), "pink") end if for each dataPoint as string in dataPointsArray try dataSum += Convert.ToDecimal(dataPoint) if (debugSensors) VA.WriteToLog("DataPoint = " + dataPoint, "pink") end if catch if (debugSensors) VA.WriteToLog("DataPoint NOT numeric = " + dataPoint, "red") end if end try next dataAverage = dataSum / dataPointsLen if (debugSensors) VA.WriteToLog("Equation: " + dataAverage.ToString() + " = " + dataSum.ToString() + " / " + dataPointsLen.ToString(), "green") end if if (itemDataPointsTotal = 0) itemDataPointsTotal = dataPointsLen end if return dataAverage end function Public Function GetAveragedAverages(ByVal givenAverages() as decimal) dim averagesSum as decimal = 0 dim averagesLen as decimal = 0 dim averagesAverage as decimal = 0 try for x as integer = 0 to givenAverages.GetUpperBound(0) averagesSum = averagesSum + givenAverages(x) next averagesLen = givenAverages.Length averagesAverage = averagesSum / averagesLen if (debugAverages) VA.WriteToLog("func sum = " + averagesSum.ToString(), "pink") VA.WriteToLog("func len = " + averagesLen.ToString(), "pink") VA.WriteToLog("func avg = " + averagesAverage.ToString(), "red") end if catch if (debugAIDA) VA.WriteToLog("AVCS SENS CATCH CalcAvgs possible divide by zero - givenAverages.Length = " + givenAverages.Length.ToString(), "red") end if end try return averagesAverage End Function Public Function GetAverageDistances(ByVal thisAverage as decimal, ByVal theseAverages() as decimal) dim historicDistances() as decimal = {} dim nearestDistance as decimal = decimal.MaxValue dim currentDistance as decimal = decimal.MaxValue try for y as integer = 0 to theseAverages.GetUpperBound(0) currentDistance = Abs(thisAverage - theseAverages(y)) if (isNumeric(currentDistance)) redim preserve historicDistances(historicDistances.length) historicDistances(historicDistances.length - 1) = currentDistance end if if (Abs(thisAverage - theseAverages(y)) < nearestDistance) nearestDistance = Abs(thisAverage - theseAverages(y)) if (y <= 3) historicLevelBracket = historicLevels(y) end if end if next if (debugAverages) VA.WriteToLog("AVCS SENS GetAvgD distance from nearest HistoricAverage = " + nearestDistance.ToString(), "pink") end if catch VA.WriteToLog("AVCS SENS GetAvgD function error at TryCatch", "red") end try nearestDistance = nothing currentDistance = nothing return historicDistances End Function Public Function GetRoundedAverage(ByVal thisDecimal as decimal, ByVal decimalPlaces as integer) try 'Try to compare decimal with integer version of itself to discover decimal places, then round dim checkInteger as Int32 = Convert.ToInt32(thisDecimal) if (thisDecimal = checkInteger) 'For TTS brevity use the one that couldn't end with .000 thisDecimal = checkInteger elseif (checkInteger <> thisDecimal) 'dim roundDecimal as Double = checkInteger dim roundDecimal as Double = thisDecimal thisDecimal = Round(roundDecimal, decimalPlaces) end if catch 'Result is a whole number already, does not need rounding for TTS brevity end try return thisDecimal end function Public Function GetRebuiltAverages(ByVal averagesArray() as decimal) dim rebuiltAveragesArray() as decimal = {} 'Handle 0 values by turning into 1, should work if consitently applied to all for i as integer = 0 to averagesArray.GetUpperBound(0) redim preserve rebuiltAveragesArray(rebuiltAveragesArray.length) if (averagesArray(i) < 1) rebuiltAveragesArray(rebuiltAveragesArray.length - 1) = 1 else rebuiltAveragesArray(rebuiltAveragesArray.length - 1) = averagesArray(i) end if next return rebuiltAveragesArray End Function Public Function DifferentialDiagnostics(ByVal newLabel as string, ByVal newAverage as decimal) dim averages() as decimal = {} dim averageDistances() as decimal = {} dim historicAverages() as decimal = {} dim historicAverageDistances() as decimal = {} dim historicAveragesDistances() as decimal = {} dim historicLevelBrackets() as decimal = {} dim historicAverageDistance as decimal = 1 dim averagedAverage as decimal = 1 dim historicAverage as decimal = 1 dim percentDifference as decimal = 0 dim averageDistance as decimal = 0 dim differentialDiagnosis as string = "stable" dim roundResult as Double if ((newLabel <> "") and (newAverage > -1)) 'If it is temperature sensor, data to get is delta-T over Ambient if (newLabel.StartsWith("Temp")) newLabel = "dTa_" + newLabel end if if (VA.GetText("AVCS_SENS_SensorAverages_LOW_" + newLabel) isNot nothing) historicAverages = VA.GetText("AVCS_SENS_SensorAverages_LOW_" + newLabel).Split(New String() {","}, StringSplitOptions.RemoveEmptyEntries).[Select](Function(n) decimal.Parse(n)).ToArray() if not(historicAverages.Length < 10) 'step 1 -- for low, medium, high, and extreme - get average arrays for this level, build into an Array of level averages for i as integer = 0 to historicLevels.GetUpperBound(0) redim historicAverages(0) historicLevelBracket = "" if (VA.GetText("AVCS_SENS_SensorAverages_" + historicLevels(i) + "_" + newLabel) isNot nothing) historicAverages = VA.GetText("AVCS_SENS_SensorAverages_" + historicLevels(i) + "_" + newLabel).Split(New String() {","}, StringSplitOptions.RemoveEmptyEntries).[Select](Function(n) decimal.Parse(n)).ToArray() if not(historicAverages.Length < 1) averagedAverage = 0 averagedAverage = GetAveragedAverages(historicAverages) if (IsNumeric(averagedAverage)) if (debugAverages) VA.WriteToLog("averagedAverage of bracket '" + i.ToString() + "' = " + averagedAverage.ToString(), "orange") end if redim preserve historicLevelBrackets(historicLevelBrackets.length) historicLevelBrackets(historicLevelBrackets.length - 1) = averagedAverage end if if (debugAverages) VA.WriteToLog("averages of bracket '" + historicLevels(i).ToString() + "' = " + averagedAverage.ToString(), "pink") end if end if end if next if (debugAverages) VA.WriteToLog("historicLevelBrackets = " + historicLevelBrackets(0).ToString(), "green") end if 'step 2 - identify nearest bracket by value of newAverage against historicLevelBrackets GetAverageDistances(newAverage, historicLevelBrackets) 'Checking historicLevelBrackets: if (debugAverages) VA.WriteToLog("historicLevelBrackets(0) = " + historicLevelBrackets(0).ToString(), "yellow") VA.WriteToLog("historicLevelBrackets(1) = " + historicLevelBrackets(1).ToString(), "yellow") VA.WriteToLog("historicLevelBrackets(2) = " + historicLevelBrackets(2).ToString(), "yellow") VA.WriteToLog("historicLevelBrackets(3) = " + historicLevelBrackets(3).ToString(), "yellow") end if 'save return as 'historicLevelBracket' gets changed anytime function is called, but only useful here levelBracket = historicLevelBracket VA.SetText("AVCS_SENS_Current_LevelBracket",levelBracket) 'step 3 - get an average of all the historic averages distances to each other 'now that we know which bracket to examine, use the levelBracket to get that bracket averages redim historicAverages(0) if (VA.GetText("AVCS_SENS_SensorAverages_" + levelBracket + "_" + newLabel) isNot nothing) historicAverages = VA.GetText("AVCS_SENS_SensorAverages_" + levelBracket + "_" + newLabel).Split(New String() {","}, StringSplitOptions.RemoveEmptyEntries).[Select](Function(n) decimal.Parse(n)).ToArray() if (debugAverages) for i as integer = 0 to historicAverages.GetUpperBound(0) VA.WriteToLog("historicAverages("+i.ToString()+") = " + historicAverages(i).ToString(), "pink") next end if for i as integer = 0 to historicAverages.GetUpperBound(0) if (IsNumeric(historicAverages(i))) historicAverageDistances = GetAverageDistances(historicAverages(i), historicAverages) 'Replace zero-distance to self in each iteration with 1 historicAverageDistances = GetRebuiltAverages(historicAverageDistances) 'Get Average of these distances and add to AveragesDistances array averageDistance = GetAveragedAverages(historicAverageDistances) redim preserve historicAveragesDistances(historicAveragesDistances.length) historicAveragesDistances(historicAveragesDistances.length - 1) = averageDistance if (debugAverages) VA.WriteToLog("averageDistance = " + averageDistance.ToString(), "pink") for x as integer = 0 to historicAveragesDistances.GetUpperBound(0) VA.WriteToLog("bracket historicAverages = " + historicAveragesDistances(x).ToString(), "yellow") next end if end if next 'Check all average distances created above if (debugAverages) for f as integer = 0 to historicAveragesDistances.GetUpperBound(0) VA.WriteToLog("historicAverageDistances("+f.ToString()+") = " + historicAveragesDistances(f).ToString(), "pink") next end if 'Get the average distance between all averages in this set historicAverageDistance = GetAveragedAverages(historicAveragesDistances) 'Get the average distance between given average and all historic averages averageDistances = GetAverageDistances(newAverage, historicAverages) averageDistance = GetAveragedAverages(averageDistances) end if 'Check the historicLevelBracket that was determined: if (checkResults) select case levelBracket case historicLevels(0) VA.WriteToLog(newLabel + " is LOW", "green") case historicLevels(1) VA.WriteToLog(newLabel + " is MEDIUM", "yellow") case historicLevels(2) VA.WriteToLog(newLabel + " is HIGH", "orange") case historicLevels(3) VA.WriteToLog(newLabel + " is EXTREME", "red") case else VA.WriteToLog("AVCS SENS ERROR: Select Case levelBracket failed", "red") end select VA.WriteToLog("averageDistance of current number from historic averages= " + GetRoundedAverage(averageDistance,2).ToString(), "green") VA.WriteToLog("historicAverageDistance of historic averages from each other = " + GetRoundedAverage(historicAverageDistance,2).ToString(), "green") end if 'Get Percent Difference via (((ad-had)/had)*100) if (historicAverageDistance < averageDistance) percentDifference = (((averageDistance - historicAverageDistance)/historicAverageDistance) * 100) roundResult = percentDifference percentDifference = GetRoundedAverage(roundResult, 3) else percentDifference = 0 end if if (newLabel.Contains("fan")) percentDifferenceMax = pdMaxFans else percentDifferenceMax = pdMaxTemps end if 'Store baseline/up/down status with VA Boolean states of notset/true/false historicAverage = GetAveragedAverages(historicAverages) VA.SetBoolean("AVCS_SENS_ATYPICAL_" + newLabel, nothing) if (percentDifference > percentDifferenceMax) if (newAverage > historicAverage) differentialDiagnosis = "higher" VA.SetBoolean("AVCS_SENS_ATYPICAL_" + newLabel, true) elseif (newAverage < historicAverage) differentialDiagnosis = "lower" VA.SetBoolean("AVCS_SENS_ATYPICAL_" + newLabel, false) end if end if if (checkResults) VA.WriteToLog("FINAL percent diff = " + GetRoundedAverage(percentDifference, 2).ToString() + "% (" + differentialDiagnosis + ")", "green") end if 'Set data to final variable for this sensor with a timestamp, overwriting previous data VA.SetText("~dtFormat",dtFormat) dtFormat = VA.ParseTokens("{DATETIMEFORMAT:~dtFormat}") differentialDiagnosis = dtFormat + "," + newAverage.ToString() + "," + historicAverage.ToString() + "," + averageDistance.ToString() + "," + percentDifference.ToString() + "," + differentialDiagnosis VA.SetText("AVCS_SENS_DIAGNOSTICS_" + newLabel, differentialDiagnosis) if (debugAverages) VA.WriteToLog("AVCS_SENS_DIAGNOSTICS_" + newLabel + " = " + differentialDiagnosis, "green") end if elseif ((historicAverages.Length > 0) and (historicAverages.Length < itemDataPointsMax)) 'Wait for enough historic data points before diagnosing if (debugAverages) VA.WriteToLog("AVCS SENS Cannot build differential diagnostics yet, data points below 10 = " + historicAverages.Length.ToString(), "orange") end if end if end if end if historicAverageDistance = nothing averagedAverage = nothing historicAverage = nothing percentDifference = nothing averageDistance = nothing differentialDiagnosis = nothing levelBracket = nothing historicLevelBracket = nothing roundResult = nothing averages = nothing averageDistances = nothing historicAverages = nothing historicAverageDistances = nothing historicAveragesDistances = nothing historicLevelBrackets = nothing End Function Public Function MonitorDebug(ByVal requestAllOff as boolean) if (requestAllOff) debugging = false debugSensors = false debugAIDA = false debugArduino = false debugAverages = false checkResults = false debugStopwatch = false VA.SetBoolean("AVCS_SENS_Debugging", false) VA.SetBoolean("AVCS_SENS_DebugSensors", false) VA.SetBoolean("AVCS_SENS_DebugAIDA", false) VA.SetBoolean("AVCS_SENS_DebugArduino", false) VA.SetBoolean("AVCS_SENS_DebugAverages", false) VA.SetBoolean("AVCS_SENS_DebugCheckResults", false) VA.SetBoolean("AVCS_SENS_DebugStopwatch", false) else if ((VA.GetBoolean("AVCS_SENS_DebugSensors") isNot nothing) andAlso (VA.GetBoolean("AVCS_SENS_DebugSensors"))) debugSensors = true else debugSensors = false end if if ((VA.GetBoolean("AVCS_SENS_DebugAIDA") isNot nothing) andAlso (VA.GetBoolean("AVCS_SENS_DebugAIDA"))) debugAIDA = true else debugAIDA = false end if if ((VA.GetBoolean("AVCS_SENS_DebugArduino") isNot nothing) andAlso (VA.GetBoolean("AVCS_SENS_DebugArduino"))) debugArduino = true else debugArduino = false end if if ((VA.GetBoolean("AVCS_SENS_DebugAverages") isNot nothing) andAlso (VA.GetBoolean("AVCS_SENS_DebugAverages"))) debugAverages = true else debugAverages = false end if if ((VA.GetBoolean("AVCS_SENS_DebugCheckResults") isNot nothing) andAlso (VA.GetBoolean("AVCS_SENS_DebugCheckResults"))) checkResults = true else checkResults = false end if if ((VA.GetBoolean("AVCS_SENS_DebugStopwatch") isNot nothing) andAlso (VA.GetBoolean("AVCS_SENS_DebugStopwatch"))) debugStopwatch = true else debugStopwatch = false end if end if End Function Private Sub MonitorTimerElapsed(sender As Object, e As System.Timers.ElapsedEventArgs) if ((VA.GetBoolean("AVCS_MAIN_TIMER_WORKING") isNot nothing) andAlso (VA.GetBoolean("AVCS_MAIN_TIMER_WORKING"))) 'do nothing for now, maybe debug msg later? else VA.SetBoolean("AVCS_MAIN_TIMER_WORKING", true) dim keyFile as string = "" dim reBuild as string = "" + vbNewLine + "" + vbNewLine dim fixLines as string = ">" + vbNewLine + "<" dim contents() as string dim doc as XmlDocument = New XmlDocument() dim nodeGet as XmlNode dim baselineLevels() as string = {"LOW","MEDIUM","HIGH","EXTREME"} dim itemDataAverage as decimal? = 0 dim itemID as string = "" dim itemNode as string = "" dim itemLabel as string = "" dim itemValue as string = "" dim itemData as string = "" dim currentLabel as string = "" dim counter as integer = 0 dim valueDHTc as decimal = 0 dim valueDeltaToverAmb as decimal = 0 dim intervalSensors as Int32 = 0 dim debugWatch as Stopwatch = New Stopwatch if ((VA.GetBoolean("AVCS_SENS_Debugging") isNot nothing) andAlso (VA.GetBoolean("AVCS_SENS_Debugging"))) MonitorDebug(true) else MonitorDebug(false) end if if (debugStopwatch) 'VA.WriteToLog("AVCS AIDA64 Sensor Monitor is now executing at " + e.SignalTime.ToString(), "green") debugWatch.Start() end if if ((VA.GetBoolean("AVCS_SENS_ReloadBaselines") isNot nothing) andAlso (VA.GetBoolean("AVCS_SENS_ReloadBaselines"))) if (debugAverages) VA.WriteToLog("AVCS SENS - re-loading baseline data found on file....", "black") end if VA.Command.Execute("F_AIDA_BASELINES", true) VA.SetBoolean("AVCS_SENS_ReloadBaselines", nothing) LoadHistoricSensorBaselines() Thread.Sleep(100) end if 'SensorsCheckDelay Config Setting -- when changed, new minimum time must be >= 2000ms, as a multiple of main timer loop interval if ((VA.GetInt("AVCS_SENS_SensorsCheckDelay") isNot nothing) andAlso (Integer.TryParse(VA.GetInt("AVCS_SENS_SensorsCheckDelay"), SensorsCheckDelay))) if ((SensorsCheckDelay * MonitorTimerDelay) < 2000) SensorsCheckDelay = 10 if (debugSensors) VA.WriteToLog("AVCS SENS ERROR: SensorsCheckDelay interval lower than 2 seconds, resetting to minimum 10xMonitorTimerDelay...", "red") end if end if end if if ((VA.GetBoolean("AVCS_SENS_Logging") isNot nothing) andAlso (VA.GetBoolean("AVCS_SENS_Logging"))) 'USB External DHT11 Serial Data Parsing Section ================================ if (VA.GetInt("AVCS_SENS_IntervalAIDA") isNot nothing) intervalSensors = Convert.ToInt32(VA.GetInt("AVCS_SENS_IntervalAIDA")) intervalSensors += 1 if (intervalSensors >= SensorsCheckDelay) intervalSensors = 0 end if VA.SetInt("AVCS_SENS_IntervalAIDA", intervalSensors) else VA.SetInt("AVCS_SENS_IntervalAIDA", 0) end if if (debugAIDA) VA.WriteToLog("AVCS AIDA64 Sensor Monitor Interval = " + intervalSensors.ToString(), "blue") end if 'AIDA SharedMem Data Parsing Section ================================ if (VA.GetText("AVCS_SENS_SHAREDMEM_XML") isNot nothing) keyFile = VA.GetText("AVCS_SENS_SHAREDMEM_XML").Replace("><", fixLines) if (debugSensors) VA.WriteToLog("AVCS_SENS_SHAREDMEM_XML is NOT nothing", "pink") VA.WriteToLog(keyFile, "pink") end if if (keyFile.Contains(vbNewLine)) contents = keyFile.Split(new string() {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries) for each line as string in contents if (line.StartsWith("<") or line.StartsWith(" ") or line.StartsWith("\t")) reBuild = reBuild + line.ToString() + vbNewLine end if next reBuild = reBuild + "" + vbNewLine end if doc.LoadXml(reBuild) for each node as XmlNode in doc.SelectNodes("/sensordata/*") if (doc.GetElementsByTagName("label").Item(counter) isNot nothing) nodeGet = doc.GetElementsByTagName("id").Item(counter) itemID = nodeGet.ChildNodes(0).InnerText nodeGet = doc.GetElementsByTagName("label").Item(counter) itemLabel = nodeGet.ChildNodes(0).InnerText nodeGet = doc.GetElementsByTagName("value").Item(counter) itemValue = nodeGet.ChildNodes(0).InnerText if (itemValue = "0") itemValue = "1" end if itemID = itemID.Replace(" ", "_") 'VA.WriteToLog("NODENAME: " + node.Name + " (" + itemID + ") " + itemLabel + " = " + itemValue, "yellow") 'NEW----------- Set/Get Sensor Item Label ---EXAMPLES: 'VA.SetText("AVCS_SENS_" + itemID, itemLabel) 'VA.SetText("AVCS_SENS_" + itemLabel, data) 'VA.GetText("AVCS_SENS_" + VA.ParseTokens("{TXT:AVCS_SENS_" + itemID + ":}")) = data itemNode = "" select case (node.Name) case "sys" itemNode = "sys" case "temp" itemNode = "temp" case "fan" itemNode = "fan" case "duty" itemNode = "sys" case "volt" itemNode = "volt" case "curr" itemNode = "curr" case "pwr" itemNode = "pwr" case else itemNode = "sys" end select if (VA.GetText("AVCS_SENS_" + itemID) is nothing) itemLabel = itemLabel. Replace(" (HH:MM)", ""). Replace("Utilization", "Use"). Replace("Processes", "Process_Count"). Replace("CPU OPT", "Optional CPU"). Replace("PCH Diode", "PCH"). Replace("GPU Diode", "GPU"). Replace("Chassis ", "Case "). Replace("iGPU", "GPU"). Replace("GPU1", "GPU"). Replace("GPU2", "GPU"). Replace("South Bridge", "Southbridge"). Replace("#", ""). Replace(" ", "_") if (debugSensors) VA.WriteToLog("(" + itemID + ") " + itemLabel + " = " + itemValue, "yellow") end if select case (node.Name) case "sys" itemLabel = itemLabel case "temp" itemLabel = itemLabel + "_temp" case "fan" if (itemLabel.Contains("Case")) itemLabel = GetFanLabelKeyword(itemID, itemLabel, itemValue) else itemLabel = itemLabel + "_fan" end if case "duty" itemLabel = itemLabel + "_fan_use" case "volt" itemLabel = itemLabel + "_voltage" case "curr" itemLabel = itemLabel + "_amperage" case "pwr" itemLabel = itemLabel + "_wattage" case else itemLabel = nothing end select 'Get/Set itemLabel function... 'save to variable ... save to baselines file if (itemLabel isNot nothing) VA.SetText("AVCS_SENS_" + itemID, itemLabel) if (VA.GetInt("AVCS_DATA_SAVED_requests") isNot nothing) savedRequests = VA.GetInt("AVCS_DATA_SAVED_requests") + 1 else savedRequests = 1 end if VA.SetInt("AVCS_DATA_SAVED_requests", savedRequests) VA.SetText("AVCS_DATA_SAVED_name_" + savedRequests.ToString(), "AVCS_SENS_" + itemID) VA.SetText("AVCS_DATA_SAVED_value_" + savedRequests.ToString(), itemLabel) end if else itemLabel = VA.GetText("AVCS_SENS_" + itemID) end if 'Record this Sensor Data to Variables if (itemLabel isNot nothing) itemData = nothing if (not(itemValue.Contains(":"))) if (VA.GetText("AVCS_SENS_" + itemLabel) isNot nothing) itemData = VA.GetText("AVCS_SENS_" + itemLabel) itemData = itemData + "," + itemValue itemDataAverage = GetAverages(itemData, itemLabel, itemDataPointsTotal) 'Round electric values to two decimal places, else 0 decimal places if (itemLabel.EndsWith("_voltage") or itemLabel.EndsWith("_amperage") or itemLabel.EndsWith("_wattage")) itemDataAverage = GetRoundedAverage(itemDataAverage, 2) else itemDataAverage = GetRoundedAverage(itemDataAverage, 0) end if if (debugSensors) VA.WriteToLog("New Average for " + itemLabel + " = " + itemDataAverage.ToString(), "grey") end if VA.SetText("AVCS_SENS_" + itemLabel, itemData) VA.SetDecimal("AVCS_SENS_LastAverage_" + itemLabel, itemDataAverage) if ((VA.GetDecimal("AVCS_SENS_TempDHTc") isNot nothing) andAlso ((diagnosticsSensors.Contains(itemID)) andAlso (itemDataPointsTotal >= itemDataPointsMax))) if ((VA.GetBoolean("AVCS_SENS_GET_BASELINE") isNot nothing) andAlso (VA.GetBoolean("AVCS_SENS_GET_BASELINE"))) if ((VA.GetText("AVCS_SENS_SET_BASELINE_LEVEL") isNot nothing) andAlso (baselineLevels.Contains(VA.GetText("AVCS_SENS_SET_BASELINE_LEVEL")))) if (VA.GetInt("AVCS_DATA_SAVED_requests") isNot nothing) savedRequests = VA.GetInt("AVCS_DATA_SAVED_requests") + 1 else savedRequests = 1 end if VA.SetInt("AVCS_DATA_SAVED_requests", savedRequests) VA.SetText("AVCS_DATA_SAVED_name_" + savedRequests.ToString(), "AVCS_SENS_SensorAverages_" + VA.GetText("AVCS_SENS_SET_BASELINE_LEVEL") + "_" + itemLabel) VA.SetText("AVCS_DATA_SAVED_value_" + savedRequests.ToString(), itemData) VA.SetText("AVCS_SENS_SensorAverages_" + VA.GetText("AVCS_SENS_SET_BASELINE_LEVEL") + "_" + itemLabel, itemData) end if end if end if else VA.SetText("AVCS_SENS_" + itemLabel, itemValue) end if 'Check if this is a temperature sensor if ((node.Name = "temp") andAlso (VA.GetDecimal("AVCS_SENS_TempDHTc") isNot nothing)) if (debugSensors) VA.WriteToLog("New Temp Sensor for " + itemLabel + " and Ambient = " + VA.GetDecimal("AVCS_SENS_TempDHTc").ToString(), "yellow") end if 'Calculate Delta-T over Ambient from DHT11 Temp (c) value if (Decimal.TryParse(itemValue, valueDeltaToverAmb)) andAlso ((valueDeltaToverAmb <> 0) and (valueDeltaToverAmb > (Decimal.TryParse(VA.GetDecimal("AVCS_SENS_TempDHTc"), valueDHTc)))) valueDeltaToverAmb -= valueDHTc if (debugSensors) VA.WriteToLog("New Ambient = " + valueDHTc.ToString(), "yellow") VA.WriteToLog("New dTa for " + itemLabel + " = " + valueDeltaToverAmb.ToString(), "green") end if itemData = nothing itemDataPointsTotal = 0 itemValue = valueDeltaToverAmb.ToString() itemLabel = "dTa_" + itemLabel if (VA.GetText("AVCS_SENS_" + itemLabel) isNot nothing) itemData = VA.GetText("AVCS_SENS_" + itemLabel) itemData = itemData + "," + itemValue itemDataAverage = GetAverages(itemData, itemLabel, itemDataPointsTotal) itemDataAverage = GetRoundedAverage(itemDataAverage, 3) if (debugSensors) VA.WriteToLog("New Average for " + itemLabel + " = " + itemDataAverage.ToString(), "grey") end if VA.SetText("AVCS_SENS_" + itemLabel, itemData) VA.SetDecimal("AVCS_SENS_LastAverage_" + itemLabel, itemDataAverage) if ((diagnosticsSensors.Contains(itemID)) andAlso (itemDataPointsTotal >= itemDataPointsMax)) if ((VA.GetBoolean("AVCS_SENS_GET_BASELINE") isNot nothing) andAlso (VA.GetBoolean("AVCS_SENS_GET_BASELINE"))) if ((VA.GetText("AVCS_SENS_SET_BASELINE_LEVEL") isNot nothing) andAlso (baselineLevels.Contains(VA.GetText("AVCS_SENS_SET_BASELINE_LEVEL")))) if (VA.GetInt("AVCS_DATA_SAVED_requests") isNot nothing) savedRequests = VA.GetInt("AVCS_DATA_SAVED_requests") + 1 else savedRequests = 1 end if VA.SetInt("AVCS_DATA_SAVED_requests", savedRequests) VA.SetText("AVCS_DATA_SAVED_name_" + savedRequests.ToString(), "AVCS_SENS_SensorAverages_" + VA.GetText("AVCS_SENS_SET_BASELINE_LEVEL") + "_" + itemLabel) VA.SetText("AVCS_DATA_SAVED_value_" + savedRequests.ToString(), itemData) VA.SetText("AVCS_SENS_SensorAverages_" + VA.GetText("AVCS_SENS_SET_BASELINE_LEVEL") + "_" + itemLabel, itemData) end if end if end if else VA.SetText("AVCS_SENS_" + itemLabel, itemValue) end if else if (debugSensors) VA.WriteToLog("AVCS SENS ERROR at TryParse Decimal dTa - check code at dTa Calc", "red") end if end if end if else VA.SetText("AVCS_SENS_" + itemLabel, itemValue) end if end if counter += 1 end if next if ((VA.GetInt("AVCS_SENS_MAIN_INTERVAL") isNot nothing) andAlso (VA.GetInt("AVCS_SENS_MAIN_INTERVAL") < 100)) VA.SetInt("AVCS_SENS_MAIN_INTERVAL", VA.GetInt("AVCS_SENS_MAIN_INTERVAL") + 1) elseif (VA.GetInt("AVCS_SENS_MAIN_INTERVAL") is nothing) VA.SetInt("AVCS_SENS_MAIN_INTERVAL", 1) end if if (debugStopwatch) VA.WriteToLog("Current Main Interval: " + VA.GetInt("AVCS_SENS_MAIN_INTERVAL").ToString(), "pink") end if 'Save To File function for Get Baseline calls if (VA.GetInt("AVCS_DATA_SAVED_requests") isNot nothing) if ((VA.GetBoolean("AVCS_SENS_GET_BASELINE") isNot nothing) andAlso (VA.GetBoolean("AVCS_SENS_GET_BASELINE"))) VA.SetText("AVCS_SENS_SET_BASELINE_LEVEL", "") VA.SetBoolean("AVCS_SENS_ReloadBaselines", true) VA.Command.Execute("F_SFS_SAVE_BASELINES", true) VA.SetBoolean("AVCS_SENS_GET_BASELINE", false) else VA.Command.Execute("F_SFS_SAVE_DATA", true) end if end if if (debugSensors) VA.WriteToLog("New DataPointsMax = " + itemDataPointsTotal.ToString(), "orange") VA.WriteToLog("New System Uptime = " + VA.GetText("AVCS_SENS_WindowsOS_Uptime"), "orange") end if 'AVCS Differential Diagnosis Algorithm Section ================================ if ((VA.GetDecimal("AVCS_SENS_TempDHTc") isNot nothing) andAlso ((itemDataPointsTotal >= itemDataPointsMax) and ((intervalSensors = 4) or (intervalSensors = 9)))) if (debugArduino) VA.WriteToLog("AVCS SENS - Diagnostic Interval Entered....", "yellow") end if if ((VA.GetBoolean("AVCS_SENS_Diagnosing") isNot nothing) andAlso (not(VA.GetBoolean("AVCS_SENS_Diagnosing")))) VA.SetBoolean("AVCS_SENS_Diagnosing", true) if ((VA.GetText("AVCS_SENS_DIAGNOSTIC_SENSORS") isNot nothing) andAlso (VA.GetText("AVCS_SENS_DIAGNOSTIC_SENSORS").Contains(","))) diagnosticsSensors = VA.GetText("AVCS_SENS_DIAGNOSTIC_SENSORS").Split(",").ToArray() end if dim countLow as integer = 0 dim countMed as integer = 0 dim countHigh as integer = 0 dim countExtr as integer = 0 for i as integer = 0 to diagnosticsSensors.GetUpperBound(0) if ((diagnosticsSensors(i) <> "") andAlso (VA.GetText("AVCS_SENS_" + diagnosticsSensors(i)) isNot nothing)) currentLabel = VA.GetText("AVCS_SENS_" + diagnosticsSensors(i)) currentAverage = -1 'If it is temperature sensor, data to get is deltaT over Ambient if (currentLabel.StartsWith("Temp")) if (VA.GetDecimal("AVCS_SENS_LastAverage_dTa_" + currentLabel) isNot nothing) currentAverage = VA.GetDecimal("AVCS_SENS_LastAverage_dTa_" + currentLabel) if (debugSensors) VA.WriteToLog("AVCS SENS SUCCESS at DifferentialDiagnosis - dta Temp currentAverage is:" + currentAverage.ToString(), "green") end if else if (debugSensors) VA.WriteToLog("AVCS SENS Error at DifferentialDiagnosis - dta Temp currentAverage is nothing", "red") end if end if else if (VA.GetDecimal("AVCS_SENS_LastAverage_" + currentLabel) isNot nothing) currentAverage = VA.GetDecimal("AVCS_SENS_LastAverage_" + currentLabel) if (debugSensors) VA.WriteToLog("AVCS SENS SUCCESS at DifferentialDiagnosis - non Temp currentAverage is:" + currentAverage.ToString(), "green") end if else if (debugSensors) VA.WriteToLog("AVCS SENS Error at DifferentialDiagnosis - non Temp currentAverage is nothing", "red") end if end if end if if (currentAverage > -1) DifferentialDiagnostics(currentLabel,currentAverage) if (VA.GetText("AVCS_SENS_Current_LevelBracket") isNot nothing) select case (VA.GetText("AVCS_SENS_Current_LevelBracket")) case historicLevels(0) countLow += 1 case historicLevels(1) countMed += 1 case historicLevels(2) countHigh += 1 case historicLevels(3) countExtr += 1 case else VA.WriteToLog("AVCS SENS ERROR: Select Case levelBracket failed", "red") end select end if if (debugSensors) VA.WriteToLog("AVCS SENS DifferentialDiagnosis complete on this set", "green") end if else if (debugSensors) VA.WriteToLog("AVCS SENS Error at DifferentialDiagnosis Section of Timer Event line 1060", "red") end if end if else if (debugSensors) VA.WriteToLog("AVCS SENS Error at DifferentialDiagnosis Else line 1031", "red") end if end if next 'Evaluate number of sensors reporting state similar to a low-extreme baseline to assume overall PC state select case (GetLargestInteger(countLow,countMed,countHigh,countExtr)) case countLow VA.SetText("AVCS_SENS_Current_LevelBracket", "LOW") case countMed VA.SetText("AVCS_SENS_Current_LevelBracket", "MEDIUM") case countHigh VA.SetText("AVCS_SENS_Current_LevelBracket", "HIGH") case countExtr VA.SetText("AVCS_SENS_Current_LevelBracket", "EXTREME") case else VA.SetText("AVCS_SENS_Current_LevelBracket", "LOW") end select countLow = nothing countMed = nothing countHigh = nothing countExtr = nothing VA.SetBoolean("AVCS_SENS_Diagnosing", false) if (debugArduino) VA.WriteToLog("AVCS SENS - Diagnostic Interval Completed....", "green") end if else if (debugArduino) VA.WriteToLog("AVCS SENS - Diagnostic Interval Postponed (bool in use)....", "yellow") end if end if end if end if else VA.WriteToLog("AVCS AIDA64 Sensor Monitor has been terminated...", "black") VA.SetBoolean("AVCS_SENS_Monitoring", nothing) VA.SetInt("AVCS_SENS_MAIN_INTERVAL", nothing) if (VA.GetBoolean("AVCS_SENS_UnloadClose") is nothing) VA.SetText("AVCS_SENS_TTS_WILDCARD", "Sensor Data [Monitoring;;] Systems have been [terminated;disabled;ended]") VA.Command.Execute("F_SAY_TTS", true) end if sender.Stop() end if if (debugStopwatch) debugWatch.Stop() VA.WriteToLog("Interval " + intervalSensors.ToString() + " Function Time to Complete: " + debugWatch.Elapsed.TotalMilliseconds.ToString() + "ms", "pink") end if VA.SetBoolean("AVCS_MAIN_TIMER_WORKING", nothing) end if End Sub Private Sub MonitorTimer(ByVal timerInterval as integer) dim t as New System.Timers.Timer(timerInterval) AddHandler t.Elapsed, AddressOf MonitorTimerElapsed VA.WriteToLog("AVCS AIDA64 Sensor Monitor is now running...", "black") t.Start() End Sub Public Sub Main() 'Begin AVCS AIDA64 Sensor Monitor Systems if ((VA.GetBoolean("AVCS_SENS_Monitoring") isNot nothing) andAlso (VA.GetBoolean("AVCS_SENS_Monitoring"))) MonitorDebug(false) 'DataPointsTotal Config Setting -- when changed, new baselines must be established to include equal data points if ((VA.GetDecimal("AVCS_SENS_DataPointsTotal") isNot nothing) andAlso (Decimal.TryParse(VA.GetDecimal("AVCS_SENS_DataPointsTotal"), itemDataPointsMax))) if (itemDataPointsMax < 10) itemDataPointsMax = 10 if (debugSensors) VA.WriteToLog("AVCS SENS ERROR: DataPointsTotal lower than 10, resetting to minimum 10...", "red") end if end if end if if ((VA.GetInt("AVCS_SENS_MonitorTimerDelay") isNot nothing) andAlso (Integer.TryParse(VA.GetInt("AVCS_SENS_MonitorTimerDelay"), MonitorTimerDelay))) if (MonitorTimerDelay < 1000) MonitorTimerDelay = 1000 if (debugSensors) VA.WriteToLog("AVCS SENS ERROR: MonitorTimerDelay lower than 1 second, resetting to minimum 1 sec...", "red") end if end if end if VA.SetBoolean("AVCS_SENS_Diagnosing", false) VA.SetBoolean("AVCS_SENS_Logging", true) MonitorTimer(MonitorTimerDelay) 'Check if called by autostart - bypass TTS if not called by command or Sensor Menu if (VA.ParseTokens("{CMDACTION}") = "Plugin") VA.SetText("AVCS_SENS_TTS_WILDCARD", "Sensor Data [Monitoring;;] Systems are now [active;online;ready;engaged]") VA.Command.Execute("F_SAY_TTS", true) end if else VA.WriteToLog("AVCS AIDA64 Sensor Monitor called but Shared Memory Monitor not running... exiting...", "red") VA.SetBoolean("AVCS_SENS_Logging", false) VA.SetBoolean("AVCS_SENS_Monitoring", false) MonitorDebug(true) end if VA.SetBoolean("AVCS_SENS_Monitor_Startup", nothing) End Sub End Class