Soooo... Backwards wiring layout, any easy way to fix..

Xoticrox

New elf
Joined
Dec 10, 2020
Messages
23
Never even thought about it untill after the fact... I have a Singing Tree that I have wired up, works great making it sing and such, however, I didn't even think about the direction of the wiring being reversed when I did the model in xLights. Now I have this thing all wired up, and its backwards. Is there any easy way to fix this without re doing the model in xLights, or redoing the lights on the tree?
 
Custom xLights models can be copied into an Excel spreadsheet. If you copy it into a spreadsheet and send it to me, I think I'd be able to write a VBA macro to reverse it. You could then copy it back into xLights.

You would still need to change the submodels though.
 
This is what I wrote to correct the wiring for a model in my layout. It's crude, but it did the job for me. You will need to look at the loading of the mapping array. This was written for a matrix. It remaps the submodels. You'll need the new node layout of the model. Execution starts with the error handler.

Code:
' Files - change name to suit
Const ModelToRemap = "e:/work/source.xmodel"            ' custom model requiring re-mapping (includes submodels)
Const NewModelLayout = "e:/work/newlayout.xmodel"       ' custom model with new Node layout (submodels are ignored if present)
Const RemappedModel = "e:/work/remapped.xmodel"         ' Output - a custom model with submodels remapped to the new node layout

' Do not change anything below
Const ForReading = 1
Const ForWriting = 2
Dim ofs, errMsg, inpFile, inpLine, outFile, outLine, arryRow
Dim arry, arryLen                                        ' lookup table
'
' ASCII codes (in decimal) are used to determine values in strings
'  0 - 9 are from 48 - 58
'  double quote (") is 34
' end of line is per Unix standard (/n) vbLF

Function NodeSwap(numStr)                               ' find the new node and add it to the output line
  Dim arryPos
  If numStr = "" Then                                   ' nothing to re-map
    NodeSwap = -1
    Exit Function
  End If
  arryPos = arryLen                                     ' remap node here row 1 = new layout, row 2 = old layout
    Do While (arryPos > 0) And (arry(2, arryPos) <> numStr)
    arryPos = arryPos - 1
  Loop
  outLine = outLine & arry(1, arryPos)
  NodeSwap = arryPos
End Function


Sub remapSubmodel()
  Dim strPos, ascChr, numStr

  strPos = InStr(inpLine, """ line")
  Do While strPos > 0
    outLine = outLine & Left(inpLine, strPos)
    inpLine = Mid(inpLine, strPos + 1)
    strPos = InStr(inpLine, Chr(34))
    outLine = outLine & Left(inpLine, strPos)
    inpLine = Mid(inpLine, strPos + 1)
    strPos = 1
    ascChr = Asc(Mid(inpLine, strPos, 1))
    numStr = ""
    Do While ascChr <> 34                               ' lineX data handler
      If ((ascChr > 47) And (ascChr < 59)) Then
        numStr = numStr & Mid(inpLine, strPos, 1)
      Else
        If NodeSwap(numStr) = 0 Then
          errMsg = "Node not found"
          Exit Sub
        End If
        outLine = outLine & Mid(inpLine, strPos, 1)     ' include the node separator
        numStr = ""
      End If
      strPos = strPos + 1
      ascChr = Asc(Mid(inpLine, strPos, 1))
    Loop
    If NodeSwap(numStr) = 0 Then
      errMsg = "Node not found"
      Exit Sub
    End If

    inpLine = Mid(inpLine, strPos)                      ' remove line data
    strPos = InStr(inpLine, """ line")
  Loop
  outLine = outLine & inpLine & vbLf
End Sub


Sub LoadArray()                                         ' loads the remapping array
  Dim strPos, numStr, lineLen, x, y
  numStr = ""
  strPos = InStr(1, inpLine, "parm1=") + 7
  ' this grabs the number for parm1
  ascChr = Asc(Mid(inpLine, strPos, 1))
  Do While ((ascChr > 47) And (ascChr < 59))
    numStr = numStr & Mid(inpLine, strPos, 1)
    strPos = strPos + 1
    ascChr = Asc(Mid(inpLine, strPos, 1))
  Loop
  x = numStr
  numStr = ""
  strPos = InStr(1, inpLine, "parm2=") + 7
  ' this grabs the number for parm2
  ascChr = Asc(Mid(inpLine, strPos, 1))
  Do While ((ascChr > 47) And (ascChr < 59))
    numStr = numStr & Mid(inpLine, strPos, 1)
    strPos = strPos + 1
    ascChr = Asc(Mid(inpLine, strPos, 1))
  Loop
  y = numStr
  If arryRow = 1 Then                                 ' new martix layout
    arryLen = x * y
    ReDim arry(2, arryLen)                            ' expand the array to the needed size
  Else
    If arryLen <> (x * y) Then                        ' old matrix layout
      errMsg = "Matrices have different node counts"
      Exit Sub
    End If
  End If
  arryPos = 0                                         ' position within the array
  lineLen = Len(inpLine)
  strPos = InStr(1, inpLine, "CustomModel=") + 13     ' skip ahead to first node
  ascChr = Asc(Mid(inpLine, strPos, 1))
  Do
    numStr = ""
    Do While ((ascChr > 47) And (ascChr < 59))
      numStr = numStr & Mid(inpLine, strPos, 1)
      strPos = strPos + 1
      ascChr = Asc(Mid(inpLine, strPos, 1))
    Loop
    arryPos = arryPos + 1
    arry(arryRow, arryPos) = numStr
    If ascChr = 34 Then Exit Do                       ' Check for double quote. This is the end of the nodes
    Do While Not ((ascChr > 47) And (ascChr < 59))    ' skip over non-digits (0-9)
      strPos = strPos + 1
      ascChr = Asc(Mid(inpLine, strPos, 1))
    Loop
  Loop Until strPos >= lineLen                        ' should not be reached
           
' Err = MsgBox("Found: " & arryPos & " nodes", vbOKOnly, "Successs:")
End Sub


Sub Main()
  ' Check to ensure input files exist
  errMsg = ""
  Set ofs = CreateObject("Scripting.FileSystemObject")
  If Not ofs.FileExists(ModelToRemap) Then errMsg = "file for model To remap is missing" & vbCrLf
  If Not ofs.FileExists(NewModelLayout) Then errMsg = errMsg & "file with new node layout is missing" & vbCrLf
  If errMsg <> "" Then Exit Sub
  ' Delete the old output file if it exists
  If ofs.FileExists(RemappedModel) Then ofs.DeleteFile (RemappedModel)
  ' open the output file
  Set outFile = ofs.CreateTextFile(RemappedModel)

  ' Get the new layout
  Set inpFile = ofs.OpenTextFile(NewModelLayout, ForReading, TristateFalse)
  outLine = ""
  Do While inpFile.AtEndOfStream <> True
    inpLine = inpFile.ReadLine
    If inpFile.AtEndOfStream <> True Then       ' to ensure last line "</custommodel>" is not written
      outLine = inpLine & vbLf
      outFile.write outLine
      If InStr(inpLine, "parm1=") > 0 Then
        arryRow = 1
        Call LoadArray
        If errMsg <> "" Then Exit Sub
      End If
    End If
  Loop
  inpFile.Close

  ' Now process the file with the original layout
  Set inpFile = ofs.OpenTextFile(ModelToRemap, ForReading, TristateFalse)
  outLine = ""
  inpLine = inpFile.ReadLine
  Do While InStr(inpLine, "parm1=") < 1         ' skip past any lines before the model definition
    inpLine = inpFile.ReadLine
  Loop
  arryRow = 2
  Call LoadArray
  If errMsg <> "" Then Exit Sub
  Do While inpFile.AtEndOfStream <> True
    outLine = ""
    inpLine = inpFile.ReadLine
    ' detect & process submodels
    If InStr(inpLine, "<subModel") > 0 Then remapSubmodel
    If errMsg <> "" Then Exit Do                ' error re-mapping node
    If outLine = "" Then                        ' inpLine does not contain a submodel - copy it
      outLine = inpLine & vbLf
    End If
    outFile.write outLine                       ' write the line
  Loop
  inpFile.Close
  outFile.Close
End Sub


Sub ErrHandler()
  Call Main
  If errMsg = "" Then
    Err = MsgBox("Completed without errors", vbOKOnly, "Successs:")
  Else
    Err = MsgBox(errMsg, vbOKOnly, "Errors:")
  End If
End Sub
 
Last edited:
I like keithsw1111's answer the best. I interpreted the question slightly differently and I think what you might need to do is right click the model data and choose Reverse.
 
Thanks everyone for the suggestions, I've got it all right now!
 
Back
Top