Recursive Method Crashes Revit

When I try running create_system_node_nest it crashes Revit. I feel like there is something I’m not getting about the recursion aspect, but I have nothing to go off of other than Revit crashing with no errors.

# Classes
class SystemNode:
    def __init__(self, familyName, equipmentName, elecSystems):
        self.familyName = familyName
        self.equipmentName = equipmentName
        self.elecSystems = elecSystems
        self.children = []
        self.parent = None

    def add_child(self, child):
        child.parent = self
        self.children.append(child)


    def get_level(self):
        level = 0
        p = self.parent
        while p:
            level += 1
            p = p.parent
        return level

    def print_system(self):
        prefix = ".." * self.get_level()
        print(prefix + self.equipmentName)
        if self.children:
            for child in self.children:
                child.print_system()

    def create_system_node_nest(self):
        for e in self.elecSystems:
            elem = e.Elements
            if elem.Size == 1:
                for el in elem:
                    if el.Symbol.FamilyName in equipmentFam:
                        equipmentName = el.LookupParameter("Com_MarkInstance").AsString()
                        familyName = el.Symbol.FamilyName
                        elecSys = el.MEPModel.GetElectricalSystems()
                        newNode = SystemNode(familyName, equipmentName, elecSys)
                        self.add_child(newNode)
        if self.children:
            for child in self.children:
                child.create_system_node_nest()

################################################################################
# Collect the elements
equipmentCollection = FilteredElementCollector(doc).\
            OfCategory(DB.BuiltInCategory.OST_ElectricalEquipment).\
            WhereElementIsNotElementType().\
            ToElements()
# families to collect
equipmentFam = ["EQ - Panelboard", "EQ - Distribution Panel", "EQ - Transformer Dry Type",
                "EQ - Transformer Pad Mounted", "EQ - Automatic Transfer Switch", "EQ - Motor Control Center"]

################################################################################
#    Functions
################################################################################
equip = []
def get_system_viable_equipment():
    for eC in equipmentCollection:
        famName = eC.Symbol.FamilyName
        if famName in equipmentFam:
            equip.append(eC)

allSystems = []

def create_system_nodes_top():
    for e in equip:
        # print("____________________Equipment_______________________")
        equipmentName = get_equipment_name(e)
        supplyFrom = e.LookupParameter("Supply From").AsString()
        familyName = e.Symbol.FamilyName
        # print("NAME : " + equipmentName)
        # print(output.linkify(e.Id, equipmentName))
        # print("--- " + e.Symbol.FamilyName)
        # print("--- Fed from : " + e.LookupParameter("Supply From").AsString())

        # for eS in elecSys:
        #     print("--- --- Base family is : " + str(eS.BaseEquipment.Symbol.FamilyName))
        #     print("--- --- Base element name is : " + str(eS.BaseEquipment.LookupParameter("Com_MarkInstance").AsString()))
        #     elements = eS.Elements
        if supplyFrom == "":
            # print("--- Top Level")
            elecSys = e.MEPModel.GetElectricalSystems()
            # create Equipment class element
            newTop = SystemNode(familyName, equipmentName, elecSys)
            allSystems.append(newTop)
        else:
            pass

################################################################################
# Run
get_system_viable_equipment()
create_system_nodes_top()

print(allSystems)
# Crashes Revit. YAY!
for s in allSystems:
    s.create_system_node_nest()

for s in allSystems:
    s.print_system()

I would check if GetElectricalSystems is returning the upstream electrical connection. Something like the below:

elem = e.Elements
if elem.Size == 1:
    if elem[0].Id.Equals(hostingElement.Id):
        continue
1 Like

Good suggestion. I had to add some stuff to the class to get it to work. I also needed to set the parent attribute for the SystemNode class. While doing this I found that the recursion was also grabbing itself for some reason. This is the create_system_node_nest now:

    def create_system_node_nest(self):
        for e in self.elecSystems:
            elem = e.Elements
            if elem.Size == 1:
                for el in elem:
                    # print("SubElement :____" + str(el))
                    # print("SubElement ID :_" + str(el.Id))
                    # print("Self Element :__" + str(self.elementId))
                    try:
                        # print("Parent Id :_" + str(self.parent.elementId))
                        if el.Id.Equals(self.parent.elementId):
                            # print("This is the parent!")
                            break
                        elif el.Id.Equals(self.elementId):
                            # print("This is itself!")
                            break
                        else:
                            # print("not the parent")
                            if el.Symbol.FamilyName in equipmentFam:
                                equipmentName = el.LookupParameter("Com_MarkInstance").AsString()
                                familyName = el.Symbol.FamilyName
                                elecSys = el.MEPModel.GetElectricalSystems()
                                newNode = SystemNode(familyName, equipmentName, elecSys, el.Id)
                                newNode.parent = self
                                self.add_child(newNode)
                    except:
                        # print("No parent value")
                        if el.Symbol.FamilyName in equipmentFam:
                            equipmentName = el.LookupParameter("Com_MarkInstance").AsString()
                            familyName = el.Symbol.FamilyName
                            elecSys = el.MEPModel.GetElectricalSystems()
                            newNode = SystemNode(familyName, equipmentName, elecSys, el.Id)
                            newNode.parent = self
                            self.add_child(newNode)
        if self.children:
            for child in self.children:
                child.create_system_node_nest()
1 Like