Iron Python Exception from API method crashing revit & Dynamo

Hi I modified a dynamo node from a package called RIE nodes specifically the power nodes, node from that package. I’ve modified the node/code to first circuit element individually rather than creating one big circuit for whatever list was passed to it. I also tried integrating try & except into the code because the ElectricaSystem.create method will throw an exception if you give it a element that already has a circuit created for it. Therefore I tried adding the try& except code so I wouldn’t have to filter element before they reach the node containing the code I’ve posted to remove elements with circuits. My code works fine if I give it a list of element that are uncircuited, but if I feed it elements that are circuited revit & dynamo just instantly close upon running, can some one help me please get this code running how I’d like? Also sorry for any simple mistakes in my code I’m new to python.

  import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
from System.Collections.Generic import *

clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.Elements)

clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Electrical import *
from Autodesk.Revit.DB import MEPSystem

clr.AddReference('DSCoreNodes')
import DSCore
from DSCore.List import *

import sys
pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib'
sys.path.append(pyt_path)

# Import List ( ICollection(ElementId) = List[ElementId]() )
clr.AddReference("System")
from System.Collections.Generic import List 

def tolist(obj):
    if isinstance(obj, list):
        return UnwrapElement(obj)
    else:
        return [UnwrapElement(obj)]

#The inputs to this node will be stored as a list in the IN variables.
input = tolist(IN[0])

electComponents = List[ElementId]()


for i in input:
    electComponents.Add(i.Id)


doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application
uidoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument




OUT=[]


for C, i in enumerate(electComponents):
	TransactionManager.Instance.EnsureInTransaction(doc)    
	try:
		b=electComponents[C]
		bb=tolist(b)
		newcircuit = ElectricalSystem.Create(doc, bb, ElectricalSystemType.PowerCircuit)
		
		OUT.append(newcircuit)
	except: #Exception
		
		OUT.append(None)
		continue
	TransactionManager.Instance.TransactionTaskDone()
1 Like
import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB.Electrical import ElectricalSystem, ElectricalSystemType
from Autodesk.Revit.Exceptions import ArgumentException

clr.AddReference('RevitServices')
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

from System.Collections.Generic import List

def tolist(obj):
    if isinstance(obj, list):
        return UnwrapElement(obj)
    else:
        return [UnwrapElement(obj)]

doc = DocumentManager.Instance.CurrentDBDocument
input = tolist(IN[0])
# Create list of ElementIds from elements in input using a list comprehension
ids = [element.Id for element in input]

OUT = []
# Use a single transaction for the loop
TransactionManager.Instance.EnsureInTransaction(doc)
for id in ids:
    # Make single ElementId into a self-contained List
	id_list = List[ElementId]([id])
	try:
	    new_circuit = ElectricalSystem.Create(doc, id_list, ElectricalSystemType.PowerCircuit)
	except ArgumentException:
	    OUT.append(None)
    else:
        OUT.append(new_circuit)
TransactionManager.Instance.TransactionTaskDone()

I’ve cleaned up the imports to remove redundancy and include only what is necessary for the script to run, so hopefully it makes it a bit easier to follow. NOTE: I can’t test the above code in Revit as I do not currently have access, so it may still not work. Regardless, the below snippet may be the cause of your issue:

b=electComponents[C]
    bb=tolist(b)
    newcircuit = ElectricalSystem.Create(doc, bb, ElectricalSystemType.PowerCircuit)

The Create method of the ElectricalSystem requires a Document, IList of ElementIds, and an ElectricalSystemType. By using the tolist() function after already creating the List of ElementIds, you are instead wrapping the elements in a Python list, which is a different data type, thus undoing the work previously done. In other words:

[id] != List[ElementId]([id])

I am also assuming the specific exception you are getting is an ArgumentException (which I import after adding a reference to the RevitAPI dll):

from Autodesk.Revit.Exceptions import ArgumentException

The fact that Revit crashes makes this particularly difficult to debug, but hopefully this provides some guidance.

Thanks for the help I got it to work with your simplified solution. Here’s the funny thing I tried mixing and matching your code with what I did to see what was causing the problem and it was the continue statement in the except block that was causing the crash. Thanks again all good now.

No problem. What most likely happened is that the continue statement forced the TransactionTaskDone() function to be skipped before initiating a new transaction.