Adding Parameters through Revit API Revit 2024

Hi,

I´ve got a querstion about adding Parameters in Revit with Python.

Using the custom nodes from @GavinCrump (thanks for the awesome package) it just throws following error:
“No method matches given arguments for AddParameter”


(sorry for only the image since I am a new user I can´t upload the whole file)
Using the complete code from the Crumple-Package down below.
The only difference I am already feeding a forgeTypeId (for my understanding) instead of the BuiltInParameterGroups.

According to the Revit API it should work, or am I getting something completely wrong?
https://apidocs.co/apps/revit/2024/fb4f8475-440f-6454-768f-777388a7fdd4.htm

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

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

# Functions
def tolist(input):
    result = input if isinstance(input, list) else [input]
    return result

def uwlist(input):
    result = input if isinstance(input, list) else [input]
    return UnwrapElement(result)

#detect if document is not set
if IN[0] == None:
    docs = [DocumentManager.Instance.CurrentDBDocument]
else:
        docs = tolist(IN[0])

#unwrap all elements to use with API
definitions = tolist(IN[1])
forgeType = tolist(IN[2])
isInstance = tolist(IN[3])

outcomes = []

# Collect values
for doc in docs:

        if doc.IsFamilyDocument:

                outcome = []

                # "Start" the transaction
                TransactionManager.Instance.EnsureInTransaction(doc)

                for d,b,i in zip(definitions, forgeType, isInstance):
                    new = doc.FamilyManager.AddParameter(d,b,i)
                    outcome.append(new)
#                    outcome.append("Parameter not added.")

                # "End" the transaction
                TransactionManager.Instance.ForceCloseTransaction()

        else:
                outcome = "Document is not a family document."

        outcomes.append(outcome)

OUT = outcomes

screenshot of the errror:
image

Might be an unwrapping issue; remove the ‘ToList’ and see if using lists with single items in them as unwrapped inputs works.

Sadly still same error

line 43 equals following line:
new = doc.FamilyManager.AddParameter(d,b,i)

with and without UnwrapElement…

Can you post a preview of the data going into the Python node, as well the results of an Object.Type node for each? Now that we’ve ruled out unwrapping we need to confirm you’re using the right object types.

Should be an ExternalDefinition, a ForgeTypeId and a Boolean.

Also, what Revit version are you in?


hope you meant this

The Node “GroupType.ByTypeId” takes an ForgeType but returns an GroupType
should still be correct as for my understanding of ForgeTypes?

Revit Build Version: 24.0.4.427 so First Customer Ship
thought about that aswell had no oppportunity yet to test in the newest version.

Can you post your .dyn as it currently stands and a data set to use it on? There is a lot to build up here (multiple Python nodes with no code exposed) and I’d prefer to not have to reinvent the wheel for what you have working as my availability to help is pretty limited.

Sure wanted to do it in the beginning since I´m an new user i can´t upload.
Heres a OneDrive Link:
Dynamo_BIM

Basically all of the python nodes are from the Crumple Package just converted to CPython3.

Goal of the script is to add the parameters to the families in the directory and then load them back into the Project (extra step now where i have to look into a bit more with namespaces…)

thanks in advance

1 Like

Ok… this was a bit confusing but I solved it.

There is no method which takes (ExternalDefinition, GroupType, Boolean). By converting the string consisting of the ForgeTypeId to a GroupType you are adding an extra step. Instead create a ForgeTypeId from the string using this code:
forgeGroupType = ForgeTypeId(groupTypeString)

The net result is something like this:

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

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

import traceback

#inputs and global variables
if IN[0] == None: #detect if document is not set and set it to the current document if so
    docs = [DocumentManager.Instance.CurrentDBDocument]
else:
    docs = UnwrapElement(IN[0]) #the document objects
definitions = UnwrapElement(IN[1]) #the external definition objects
forgeTypeStrings = IN[2] #the string representation for the Forge Type Id representing the group type
isInstance = IN[3] #the booleans indicating an instance parameter or not
outcomes = [] #an empty list to hold all the outcomes

# iterate the documents
for doc in docs:
    if doc.IsFamilyDocument:
        outcome = [] #an empty list to hold the outcome
        # "Start" the transaction
        TransactionManager.Instance.EnsureInTransaction(doc)
        #for external defintion, grup string, and instance boolean in the respective zipped list(s)
        for extDef,groupString,instanceBool in zip(definitions, forgeTypeStrings, isInstance):
            forgeGroupId = ForgeTypeId(groupString) #get the Forge Group Type Id object
            try: #try to add the parameter to the family
                new = doc.FamilyManager.AddParameter(extDef,forgeGroupId,instanceBool) #add the parameter to the document
            except: #if it fails report on why
                new = traceback.format_exc() #format the exception for use
            outcome.append(new) #append the parameter or exception message to the outcome list 
        # "End" the transaction
        TransactionManager.Instance.ForceCloseTransaction()
    else:
        outcome = "Document is not a family document."
    outcomes.append(outcome) #append the outcome to the outcomes list
OUT = outcomes #return the outcomes to the Dynamo environment

That said, with the amount of Python nodes you’ve got floating around, I recommend you compact them into a single node. You’ll get drastically better performance as well as you won’t ever have more than one family document open at a time.

2 Likes

Thank you so much, works like a charm

Regarding one single node, will do that since I´m new to the Python environment i like to debug them seperatly.
Will post the whole code once it´s finished.

1 Like

Yep to add to that I just haven’t had time to go and build in this route to the node. API deprecations are brutal for package developers, generally. I am unlikely to update it anytime soon but thanks for solving this Jacob!

Yeah. This is one of the reasons the teams have a pretty significant process for deprecating things, and does what they can go give us as much heads up as possible. The hard part and something that is perhaps unforeseen in all of this is that the API was written back when the intent was that you’d have a version of your automation tool for each Revit release, building it uniquely for each Revit version. Some of those builds would be exactly the same, but others would requier some legwork, which generally wasn’t bad when you had a year or more worth of notification that the change was coming.

Then Dynamo came along and ruined all of that by allowing the same .dyn to run in Revit 2016 to 2024. From a ‘Dynamo for Revit’ standpoint the team is in fact building a unique build each year, referencing only one version of the Revit API in any build, but allowing migration tools to map stuff like “Select by ID” to push the API changes as they come, accounting for the 64 bit element ID change in 2024 without having to change your .dyn. But for package authors who’re pushing package build X to every user and expecting it to work… that just doesn’t seem feasible without multiple switches in your code, and even then it’s a nightmare. This is why we get stuff like the archi-lab versioning issues. Hopefully the team will come up with a good fix to this ever expanding issue. And if not we’ll get through this all by modifying each other’s code, which is the true beauty of the many ‘source available’ tools we’re producing.

2 Likes