Getting the Available Conduit Sizes

I’m working on a graph that will automatically model conduit. So right now I have the user selecting from the available conduit types then manually entering the size (1/2", 3/4", 1", etc.).

What I would like to do is pull all the available conduit sizes from the Electrical Settings in Revit and make that into a Radio Button input.

I’ve been looking in the API to see how to do this and kinda running into a wall.

I’ve tried:
size = Autodesk.Revit.DB.Electrical.ConduitSizeSettings.GetConduitSizeSettings(doc)

This does get a Conduit Size Settings element just not sure what to do with it after that.

I’ve also tried this:
conset = Autodesk.Revit.DB.Electrical.ConduitSettings.GetConduitSettings(doc)

This gets a Conduit Settings element.

I’m wanting to get the OuterDiameter and NominalDiameter for each one.

Which I tried:
outdia = Autodesk.Revit.DB.Electrical.ConduitSize.OuterDiameter

But I believe you have to have an element selected to get that. Which I’m creating the conduit elements from a defined path.

Didn’t know if anyone had any pointers. I’ll make another go at this later and update if I find anything.

Wanted to give an update in case anyone else was looking for this.

Was able to get what I wanted. Still need to refine it into a usable list for my case, but I know how now so that’s a start.

If you use the following it will get you all the different types of conduit sizes (EMT, RMC, etc) in one list, the Nominal Diameter in another, and the Outer Diameter in another.

import clr
import sys
sys.path.append('C:\Program Files (x86)\IronPython 2.7\Lib')
import System
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.Elements)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
clr.AddReference('RevitAPI')
clr.AddReference('RevitAPIUI')
import Autodesk
from Autodesk.Revit.DB import *
from Autodesk.Revit.UI import *

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


sizetype = []
nomsize = []
outsize = []

sizes = Autodesk.Revit.DB.Electrical.ConduitSizeSettings.GetConduitSizeSettings(doc)


for size in sizes:
	sizetype.append(size)
	
	for dia in size.Value:
		
		nomsize.append(dia.NominalDiameter*12)
		outsize.append(dia.OuterDiameter*12)


OUT = [sizetype,nomsize,outsize]

Going to look into getting the input from the DataShapes UI to produce a list of available sizes. Or some other way.

Will update if I can get a list that is more usable than the list of all different types. Should be relatively easy just need to figure out a good way to decide which type to use.

2 Likes

What I’m trying to do now is get the OuterDiameter of a certain size conduit that that will be selected through a datashape node.

In the script I have above it can list all the ‘OuterDiameter’ for each of the sizes of each ‘Standard’.

Ok I want to follow up on this. So I was able to get the conduit sizes above.

But what I really want to do is get the OD of a user selected Conduit Type and Conduit Size.

Just to be clear what I’m working on the idea is there will be no conduit drawn so all this information has to be pulled with out a reference to a model element…which I think is possible just getting confused with the API.

Say a user has the DataShapes popup (above image). They select a Conduit Type and Input a Conduit Size.

I know I want to somehow find the ‘Standard’ value is for the Conduit Type.

Which looking at the API and the BuiltInParameter Enumeration I find that the parameter I need is:

CONDUIT_STANDARD_TYPE_PARAM

So I take the input of the above Element Type (of the Conduit Type) and input it into a Python node with:

con = UnwrapElement(IN[0])

constand = con.get_Parameter(BuiltInParameter.CONDUIT_STANDARD_TYPE_PARAM)

Setting OUT = constand I get:

constand_par

I’m not sure if my issue is that I’m trying to find the parameter value of and Element Type and not an actual Element.

I figured starting with identifying the correct sizing Standard was the way to go. From there I’ll need to pick the user choosen size from the Key/Value of the posts above. That I’m still working through.

Any help would be appreciated.

Ok. By doing some searching I was able to find out how to get the value from that parameter.

Had to change the code a bit. Don’t quite understand the difference in ‘get_Parameter’ and ‘GetParameters’.

con = UnwrapElement(IN[0])

constand = con.GetParameters("Standard")

Then to get the parameter name and its value I did.

for x in name:
	outlist.append(x.Definition.Name)
	outlist.append(x.AsValueString())

So I kinda understand that this is getting the name and the value of the parameter. Just not sure where in the API documentation I was supposed to find this.
Definitely something new to learn the ins and out of the Revit API and I haven’t even scracthed the surface.

Now that I figured that out I have to find out if this is what I need/want. To accomplish my end goal.

Wanted to see if anyone could tell me if there is a better way to do this?

All this is doing is providing a list of Conduit Types in your project as well as predefined Nominal diameter. You select both then it pops up with a dialog to tell you the Outer Diameter.

This is basically the result that I want, but in order to get there I create multiple lists of information and use .index() to search for values.

Also the code isn’t perfect, but you don’t have to draw anything this is puling information from the Electrical Settings not what is modeled.

conduit_select_example.dyn (38.7 KB)

@djforeman I’ve been following this topic and I would say great job on navigating your way through the API to get what you needed :clap:.

I’m not quite sure what you are trying to do with this python node if you just need to model a bunch of conduits :thinking:.

But here’s how I would have used a dictionary to avoid creating multiple unnecessary lists.


Conduit_Diameter_FromSettings.dyn (36.6 KB)

import clr
clr.AddReference('RevitAPI')
import Autodesk

clr.AddReference('RevitServices')
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument

clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI import TaskDialog

import System
from System.Collections.Generic import Dictionary

sizedict = Dictionary[System.String,System.Object]()

sizes = Autodesk.Revit.DB.Electrical.ConduitSizeSettings.GetConduitSizeSettings(doc)

for size in sizes:
	availSize = Dictionary[System.String,System.Object]()
	for dia in size.Value:
		availSize.Add(str(dia.NominalDiameter*12),round(dia.OuterDiameter*12,2))
	sizedict.Add(size.Key,availSize)

conduitType = UnwrapElement(IN[0])
conduitStandard = conduitType.LookupParameter("Standard").AsValueString()
conduitTypeName = conduitType.LookupParameter("Type Name").AsString()
conduitFamilyName = conduitType.LookupParameter("Family Name").AsString()

nominalDiamater = str(IN[1]) + "\""
outerDiameter = str(sizedict[conduitStandard][str(IN[1])]) + "\""

message = ["Conduit Type: {}".format(conduitTypeName),\
"Conduit Family: {}".format(conduitFamilyName),\
"Size: {}".format(nominalDiamater),\
"Outer Diameter: {}".format(outerDiameter)]

msgBox = TaskDialog
msgBox.Show("Selected Conduit Outer Diameter", "\n".join(message))

OUT = conduitStandard,conduitTypeName,conduitFamilyName,nominalDiamater,outerDiameter
3 Likes

@AmolShah I appreciate you following/responding.

Yeah the Revit API is definitely a completely different language.

So what I am showing here is a small part of what I’m working on. But the reason I want to do this is I’m having the user select the Conduit Type and Size then they say they want ‘x’ number of conduits on the rack spaced ‘x’ apart. Right now I’m using the nominal size and the space between the conduit is not accurate.
Also if you were wondering why I’m using a python node instead of OOTB/3rd Party nodes. It’s because I’m attempting to learn some of the Revit API and trying to use as few nodes as possible.

Now on to the dictionary. So I know what a dictionary is and kinda/sorta how to use one, but I’ve never created one or really used one.

The dictionary code is a lot shorter than what I had to do and from what I read a dictionary look up is a lot faster than looking through lists.

So I think I’m understanding how it works. It looks like you nested the dictionary of sizes for each standard (availSize) inside the dictionary of each standard (sizedict).

outerDiameter = str(sizedict[conduitStandard][str(IN[1])])

Here you are getting the outerDiameter from the dictionary you made above. The dictionary is ‘sizedict’ and you are using the ‘conduitStandard’ and ‘nominalDiameter’ to find it.

So hypothetically is there a way for me to input the ‘ConduitStandard’ and ‘outerDiameter’ and get the 'nominalDiameter? With how the dictionary is setup now? Or with a dictionary are you always retrieving the last value that is input for each entry? Hopefully that makes sense.

Also I like what you did with the output. Definitely a lot cleaner looking than my run on sentence I had. So I appreciate those tips as well.

I appreciate the help. This cleans up the code so much and less to manage compared to all my lists.

@djforeman You guessed it right, it’s a nested dictionary which looks like this:
image
The primary keys (circled red) are the conduit types with values (black) as a nested dictionary of available sizes. And for that nested dictionary the keys are the nominal sizes(blue) and values are outer diameters(green).
image

For example if you are passing IN[0] as a ConduitType of Standard=“EMT” and IN[1]=1" then
sizedict[conduitStandard] becomes sizedict[“EMT”] and it fetches this result:
image
Now on this result you are querying what is present at key 1.0 which gets you your answer of 1.16"
image

So, outerDiameter = sizedict[conduitStandard][str(IN[1])]) isn’t retrieving the last value that is input for each entry. It is getting the exact match for whatever is being passed through IN[0] & IN[1].

1 Like

@AmolShah

That is an amazing explanation. Exactly what I needed.

I really appreciate you taking the time to markup those pictures and explain it.

Thanks again for the help on improving my code.

You’re welcome @djforeman. Glad I could be of help.
Keep practicing and browsing through the forum.
Eventually that would make you better at coding.