2024-11-02

Analyzing Wakespeed Log Files

The Wakespeed WS-500 alternator regulator produces log files, but are in text format and hard to read. I have created a VBA macro for Excel that makes them much easier to analyze. It puts each of the commands into a separate worksheet with column headers for the messages.

Create an Excel workbook. Press Alt+F11 to open the Visual Basic Editor. Select Insert Module from the menu. Paste the code below into the module. Then from the Excel window save this as Wakespeed.xlsm with the file type "Excel Macro-Enabled Workbook (*.xlsm)".

To run the macro, on the View tab, click the Macros button and select WakespeedLogfile from the macros list. Click Run. It will ask you for the wakespeed log file. The result will make it easy to analyze what the Wakespeed is doing.


Option Explicit

Public Sub WakespeedLogfile()
    Dim fso As Scripting.FileSystemObject
    Dim ts As Scripting.TextStream
    Dim astr() As String
    Dim wks As Worksheet
    Dim strLine As String
    Dim fileName As Variant
    Dim rngCell As Range
    Dim rngHeaders As Range
    Dim intBlank As Integer
    
    fileName = Application.GetOpenFilename(FileFilter:="txt files (*.txt), *.txt", Title:="Wakespeed Log File")
    If fileName = False Then
        Exit Sub
    End If
    Call RemoveWorksheets
    Set fso = New Scripting.FileSystemObject
    Set ts = fso.OpenTextFile(fileName)
    Do Until ts.AtEndOfStream
        strLine = ts.ReadLine
        astr = Split(strLine, ",")
        If Left$(astr(0), 1) <> "#" Then
            If Not WorksheetExists(astr(0)) Then
                 Set wks = ThisWorkbook.Worksheets.Add(After:=ThisWorkbook.Worksheets(ThisWorkbook.Worksheets.Count))
                 wks.Name = astr(0)
                 Call AddColumnHeaders(wks)
            End If
            Set wks = ThisWorkbook.Worksheets(astr(0))
            Call AddRow(wks, astr)
        Else
            Set wks = ThisWorkbook.Worksheets("#")
            wks.Cells(wks.Cells(wks.Rows.Count, 1).End(xlUp).Row + 1, 1).Value = strLine
        End If
    Loop
    ts.Close
    Set ts = Nothing
    Set fso = Nothing
    For Each wks In ThisWorkbook.Worksheets
        intBlank = 1
        Set rngHeaders = wks.UsedRange.Resize(1)
        rngHeaders.HorizontalAlignment = xlCenter
        For Each rngCell In rngHeaders
            If IsEmpty(rngCell.Value) Then
                rngCell.Value = "x" & intBlank
                intBlank = intBlank + 1
            End If
        Next rngCell
        wks.ListObjects.Add(xlSrcRange, wks.UsedRange, , xlYes).TableStyle = "TableStyleLight9"
        wks.Columns.AutoFit
    Next wks
End Sub

Private Sub AddColumnHeaders(wks As Worksheet)
    Dim astr() As String
    Select Case wks.Name
        Case "AOK;"
            astr = Split("AOK;", ",")
        Case "AST;"
            astr = Split("AST;, Hours, , BatVolts, AltAmps, BatAmps, SystemWatts, ,TargetVolts, TargetAmps, TargetWatts, AltState, ,BTemp, ATemp, ,RPMs, , AltVolts, FTemp, DVCC_LimitAmps, FLD%", ",")
        Case "CPE;"
            astr = Split("CPE;, n, acptVBAT, acptTIME, acptEXIT, res1, , ocAMPS, ocTIME, ocVBAT, ocAEXIT, , floatVBAT, floatAMPS, floatTIME, floatRESUMEA, floatRESUMEAH , floatRESUMEV, ,pfTIME, pfRESUME, pfRESUMEAH, , equalVBAT, equalAMPS, equalTIME, equalEXIT, , BatComp, CompMin, MinCharge, MaxCharge, ,RdcVolts, RdcLowTemp, RdcHighTemp, RdcAmps,floatSOC, ,MaxAmps, ,pfVBAT, MaxBatVolts", ",")
        Case "CST;"
            astr = Split("CST;, BatteryID, IDOverride, Instance, Priority, ,Enable NMEA2000?, Enable OSE?, ,AllowRBM?,IsRBM, ShuntAtBat?, ,RBM ID, IgnoringRBM?,Enable_ALT_CAN, ,CAN_ID, ,EngineID, BitRate, Aggregate BMS, N2K Alt Sense, , Enable-DVCC?, DVCC Active?, , CAN_TxErr, CAN_RxErr", ",")
        Case "DBG;"
            astr = Split("DBG;", ",")
        Case "DCV;"
            astr = Split("DCV;, Model, Mode, , Volts, Volts_HalfPower, ,48v Charge Limit Amps, ,12v support Limit Amps, 48v Cutoff Voltage, 48v Cuttoff SOC”, ,12v Refresh Volts, 12v Refresh Hold, 12v Refresh Days", ",")
        Case "DST;"
            astr = Split("DST;, DCDC_State, Volts, ,12vBatVolts, 12vBatCurrent, 48vBatCurrent, DCDC_Temp", ",")
        Case "ENG;"
            astr = Split("ENG;, J1939MaxLoad, ,RFM_RPM, RFM1, RFM2, RFM3, RFM4, RFM5, RFM6, RFM7, RFM8, ,Setpoint in _Setpoint", ",")
        Case "FLT;"
            astr = Split("FLT;, FaultCode, RequriedSensorStatus", ",")
        Case "NAK;"
            astr = Split("NAK;", ",")
        Case "NPC;"
            astr = Split("NPC;, Enable BLE?, Name, Password, , DeviceID, DOM", ",")
        Case "RST;"
            astr = Split("RST;", ",")
        Case "SCV;"
            astr = Split("SCV;, Lockout, BTS2ATS?, RevAmp, SvOvr, BcOvr, CpOvr, ,AltTempSet, drtNORM, drtSMALL, drtHALF, PBF, ,Amp Limit, Watt Limit, , Alt Poles, Drive Ratio, Shunt Ratio, ,IdleRPM, TachMinField, Warmup Delay, Required Sensor, DC_Disconnected_VBat, FeatureIN_mod, TriggerHalfPowerRPM, Ignore Sensor, Feature-OUT mod, ,BMS Amp Cap, Promiscuous Mode", ",")
        Case "SST;"
            astr = Split("SST;, Version , ,Derate Mode, System Options, , CP index, BC Mult, SysVolts, ,AltCap, CapRPMs, , Ahs, Whs, ,ForcedTM?, RequredSensorFlag, ,BLE-ReadOnlyState?", ",")
        Case Else
            Debug.Assert False
    End Select
    Call AddRow(wks, astr)
End Sub

Private Sub AddRow(wks As Worksheet, astr() As String)
    Dim lastRow As Long
    Dim i As Integer
    
    lastRow = wks.Cells(wks.Rows.Count, 1).End(xlUp).Row + 1
    For i = LBound(astr) To UBound(astr)
        wks.Cells(lastRow, i + 1).Value = Trim(astr(i))
    Next i
End Sub

Private Sub RemoveWorksheets()
    Dim wks As Worksheet
    On Error Resume Next
    Application.DisplayAlerts = False
    Set wks = ThisWorkbook.Worksheets.Add(After:=ThisWorkbook.Worksheets(ThisWorkbook.Worksheets.Count))
    For Each wks In ThisWorkbook.Worksheets
        wks.Delete
    Next wks
    Application.DisplayAlerts = True
    Set wks = ThisWorkbook.Worksheets.Item(1)
    wks.Name = "#"
    wks.UsedRange.ClearContents
    wks.Cells(1, 1).Value = "Comment"
    On Error GoTo 0
End Sub

Private Function WorksheetExists(sheetName As String) As Boolean
    Dim ws As Worksheet
    On Error Resume Next
    Set ws = ThisWorkbook.Worksheets(sheetName)
    WorksheetExists = Not ws Is Nothing
    On Error GoTo 0
End Function