Announcement

Collapse
No announcement yet.

Relationship Editing

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Relationship Editing

    A few scripts to print and edit relationships between devices - particularly useful with the new HS4 views (and hopefully more useful once they sort out the relationships mess on grid view). Output goes to the log.

    Lists all relationships on one line
    Code:
    Imports Scheduler.Classes
    
    Sub Main(parms as object)
      Dim enumerator as clsDeviceEnumeration = hs.GetDeviceEnumerator
    
      Dim dev as DeviceClass
      Dim dev2 as DeviceClass
      Dim output as String
    
      Do
        dev = enumerator.GetNext
    
        If dev Is Nothing Then Continue Do
    
        Log(dev.Ref(hs) & " " & dev.Name(hs) & " " & dev.Relationship(hs))
    
        Select Case CInt(dev.Relationship(hs))
          ' INDETERMINATE
          Case 1
            output = output & ",I" & dev.Ref(hs)
    
          ' PARENT
          Case 2
            output = output & ",P" & dev.Ref(hs)
    
            Dim assoc = dev.AssociatedDevices(hs)
    
            For i as Integer = 0 to assoc.Length - 1
              dev2 = GetDevice(assoc(i))
    
              If CInt(dev2.Relationship(hs)) <> 4 Then
                Log("ERROR: Parent " & dev.Ref(hs) & " has non-child (" & dev2.Relationship(hs) & ") association " & dev2.Ref(hs))
                Exit Sub
              End If
    
              output = output & ",C" & dev2.Ref(hs)
            Next
    
          ' STANDALONE
          Case 3
            output = output & ",S" & dev.Ref(hs)
    
          ' CHILD
          Case 4
            ' child, do nothing
    
          ' UNKNOWN
          Case Else
            output = output & ",U" & dev.Ref(hs)
    
        End Select
    
      Loop Until enumerator.Finished
    
      Log(output)
    End Sub
    
    Sub Log(str)
      hs.WriteLog("Relationships", str)
    End Sub
    
    Function GetDevice(ref) as DeviceClass
      Dim dev as DeviceClass = hs.GetDeviceByRef(ref)
    
      If dev Is Nothing Then
        Throw New Exception("Device " & ref & " not found")
      End If
    
      Return dev
    End Function
    Print relationships in (moderately) readable format. Note newline isn't shown, so copy the entry and use an editor to replace | with newline.
    Code:
    Imports Scheduler.Classes
    
    Sub Main(parms as object)
      Dim enumerator as clsDeviceEnumeration = hs.GetDeviceEnumerator
    
      Dim dev as DeviceClass
      Dim dev2 as DeviceClass
      Dim output as String
    
      Do
        dev = enumerator.GetNext
    
        If dev Is Nothing Then Continue Do
    
        Log(dev.Ref(hs) & " " & dev.Name(hs) & " " & dev.Relationship(hs))
    
        Select Case CInt(dev.Relationship(hs))
          ' INDETERMINATE
          Case 1
            output = output & "I " & dev.Ref(hs) & " " & dev.Name(hs) & " {" & dev.AssociatedDevices_List(hs) & "}|"
    
          ' PARENT
          Case 2
            output = output & "P " & dev.Ref(hs) & " " & dev.Name(hs) & " {" & dev.AssociatedDevices_List(hs) & "}|"
    
            Dim assoc = dev.AssociatedDevices(hs)
    
            For i as Integer = 0 to assoc.Length - 1
              dev2 = GetDevice(assoc(i))
    
              If CInt(dev2.Relationship(hs)) <> 4 Then
                Log("ERROR: Parent " & dev.Ref(hs) & " has non-child (" & dev2.Relationship(hs) & ") association " & dev2.Ref(hs))
                Exit Sub
              End If
    
              output = output & "--- C" & dev2.Ref(hs) & " " & dev2.Name(hs) & " {" & dev2.AssociatedDevices_List(hs) & "}|"
            Next
    
          ' STANDALONE
          Case 3
            output = output & "S " & dev.Ref(hs) & " " & dev.Name(hs) & " {" & dev.AssociatedDevices_List(hs) & "}|"
    
          ' CHILD
          Case 4
            ' child, do nothing
    
          ' UNKNOWN
          Case Else
            output = output & "? " & dev.Ref(hs) & " " & dev.Name(hs) & " {" & dev.AssociatedDevices_List(hs) & "}|"
    
        End Select
    
      Loop Until enumerator.Finished
    
      Log(output)
    End Sub
    
    Sub Log(str)
      hs.WriteLog("Relationships", str)
    End Sub
    
    Function GetDevice(ref) as DeviceClass
      Dim dev as DeviceClass = hs.GetDeviceByRef(ref)
    
      If dev Is Nothing Then
        Throw New Exception("Device " & ref & " not found")
      End If
    
      Return dev
    End Function
    Set relationships based on the script parameter provided
    Code:
    Imports Scheduler.Classes
    
    Sub Main(parms as object)
      Dim p() As String = CStr(parms).Split(",")
    
      Dim ref as Integer
      Dim dev as DeviceClass
      Dim parent as DeviceClass
      Dim action as String
    
      For n as Integer = 0 to p.Length - 1
    
        If p(n).Length < 2 Then
          Log("ERROR: Invalid command " & p(n))
          Exit Sub
        End If
    
        Log("Command " & p(n))
    
        action = p(n).Substring(0, 1)
        ref = CInt(p(n).Substring(1))
    
        dev = hs.GetDeviceByRef(ref)
    
        If dev Is Nothing Then
          Log("ERROR: Device " & ref & " not found")
          Exit Sub
        End If
    
        Select Case action
    
          ' STANDALONE
          Case "S"
            Log("Standalone " & ref & " " & dev.Name(hs))
            Disassociate(dev)
            dev.Relationship(hs) = 3 ' Standalone
            parent = Nothing
    
    
          ' PARENT
          Case "P"
            Log("Parent " & ref & " " & dev.Name(hs))
            If CInt(dev.Relationship(hs)) <> 2 Then ' not Parent
              Disassociate(dev)
            End If
    
            dev.Relationship(hs) = 2 ' Parent
    
            parent = dev
    
          ' CHILD
          Case "C"
            Log("Child " & ref & " " & dev.Name(hs))
            If parent is Nothing Then
              Log("ERROR: set child not valid without parent")
              Exit Sub
            End If
    
            If CInt(dev.Relationship(hs)) <> 4 Then ' not Child
              Disassociate(dev)
    
              parent.AssociatedDevice_Add(hs, ref)
              dev.AssociatedDevice_Add(hs, parent.Ref(hs))
              dev.Relationship(hs) = 4 ' Child
    
            ElseIf dev.AssociatedDevices_List(hs) <> CStr(parent.Ref(hs)) Then
              Disassociate(dev)
    
              parent.AssociatedDevice_Add(hs, ref)
              dev.AssociatedDevice_Add(hs, parent.Ref(hs))
              dev.Relationship(hs) = 4 ' Child
            End If
    
          ' UNKNOWN ACTION
          Case Else
            Log("ERROR: Unknown action " & action)
            Exit Sub
    
        End Select
    
      Next
    
      Log("Finished")  
    End Sub
    
    Sub Log(str)
      hs.WriteLog("Relationships", str)
    End Sub
    
    Function GetDevice(ref) as DeviceClass
      Dim dev as DeviceClass = hs.GetDeviceByRef(ref)
    
      If dev Is Nothing Then
        Throw New Exception("Device " & ref & " not found")
      End If
    
      Return dev
    End Function
    
    Sub Disassociate(dev as DeviceClass)
      Dim assoc() as Integer = dev.AssociatedDevices(hs)
    
      If assoc.Length = 0 Then
        Log("No associations")
        Exit Sub
      End If
    
      For i as Integer = 0 to assoc.Length - 1
        Dim dev2 as DeviceClass = GetDevice(assoc(i))
    
        Log("Disassociating " & dev.Ref(hs) & " from " & dev2.Ref(hs))
    
        dev2.AssociatedDevice_Remove(hs, dev.Ref(hs))
        dev.AssociatedDevice_Remove(hs, dev2.Ref(hs))
      Next
    End Sub
    For list and set, a specific format for the parameter / output is used:

    (action / type)(device reference),etc,etc

    action: S = standalone, P = parent, C = child (also U = unknown and I = indeterminate which don't make much sense)
    device reference = numeric device ref

    e.g. P10,C15,C26,S5

    Indicates / sets device 10 as the parent of devices 15 and 26, and device 5 as standalone

    Child or standalone devices will be unlinked from any parent if necessary. Child must immediately follow parent, and existing child devices of the parent are not affected.

    Bigger example: P101,C102,C104,C105,C106,C107,C108,C109,C111,P110,C103,S112, P113,C114,P116,C115,S117,P118,C119,C121,C122

    An advantage of this approach is that you can swap between configurations by running the script with different parameters, or event set up different events to run quickly.

    If you want a graphical approach, I recommend Jon00's grouping tool.
Working...
X