Run a.dyn from a Revit add-in?

Hi all,
Does anyone know if it’s possible to launch a Dynamo environment, and run a .dyn, from a Revit add-in?
So, doing just what the Dynamo Player does, but controlled by an add-in?

I can see on GitHub that there is a Dynamo api, which looks like it’s accessible from .Net, but I haven’t yet found either a ‘getting started’ guide or an obvious entry point in the code?? I’m guessing you somehow have to create a dynamo engine and then feed it a .dyn, but exactly how to do that??
Any hints on preconditions, event contexts, transactions, etc would be welcome…
Cheers,
David

1 Like

Try and take a look at Dyno Browser. Don’t know if it’s what you’re looking for but it is the only add-in for .dyn files I know :-).

1 Like

Thanks Christian,
Yes, like Dyno browser or Dynamo Player, I’m trying to drive Dynamo from an add-in that I’m coding. I just don’t know how to access Dynamo from my add-in code.
Cheers,
David

Ah ok, I misunderstood your question :slight_smile:

No problem Christian: Thanks for taking the time to reply!

Hi David,

Did you see this post: Open Dynamo in background while C# add-in executes ?

I feel like hzamaniM54WP was close with the following code, but I can’t figure out what he was doing wrong either.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Dynamo.Applications;
using Dynamo.Core;

namespace my_addin
{
    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    class DynamoTest : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {


            string Journal_Dynamo_Path = path_to_my_dyn_file;
            DynamoRevit dynamoRevit = new DynamoRevit()

            DynamoRevitCommandData dynamoRevitCommandData = new DynamoRevitCommandData();
            dynamoRevitCommandData.Application = commandData.Application;
            IDictionary<string, string> journalData = new Dictionary<string, string>
            {
                { Dynamo.Applications.JournalKeys.AutomationModeKey, true.ToString() },
                { Dynamo.Applications.JournalKeys.ShowUiKey, false.ToString() },
                { Dynamo.Applications.JournalKeys.DynPathKey, Journal_Dynamo_Path }
            };
            dynamoRevitCommandData.JournalData = journalData;       

            Result externalCommandResult = dynamoRevit.ExecuteCommand(dynamoRevitCommandData);

            return externalCommandResult;



        }
    }
}

And I’m getting this error:

image

Hi Kevin,

Welcome to the community!

That is interesting. I keep having a look at this problem, but haven’t managed to get it working just yet.

Next step could be to get DynamoRevit running in a debug session and examine the data structure passed to DynamoCore. Looks like @hzamaniM54WP’s code just needs to initialise one (or more) additional pieces of data in journalData.

Kind regards,

David

Okay I have it running.

Don’t use a transaction in the Plugin code, let dynamo handle the transaction independently.
I had to reference a lot of .dlls (see the image below) I may have went overboard.
You can only have one version of dynamo installed (2.x).

namespace DynamoTest
{
    [Transaction(TransactionMode.Manual)]
    [Regeneration(RegenerationOption.Manual)]
    public class RunDynamo : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            //Get application and documnet objects and start transaction
            UIApplication uiapp = commandData.Application;
            Document doc = uiapp.ActiveUIDocument.Document;           

            string Journal_Dynamo_Path = @"C:\Path To .Dyn\Test.dyn";
            DynamoRevit dynamoRevit = new DynamoRevit();

            DynamoRevitCommandData dynamoRevitCommandData = new DynamoRevitCommandData();
            dynamoRevitCommandData.Application = commandData.Application;
            IDictionary<string, string> journalData = new Dictionary<string, string>
            {
                { Dynamo.Applications.JournalKeys.ShowUiKey, false.ToString() }, // don't show DynamoUI at runtime
                { Dynamo.Applications.JournalKeys.AutomationModeKey, true.ToString() }, //run journal automatically
                { Dynamo.Applications.JournalKeys.DynPathKey, Journal_Dynamo_Path }, //run node at this file path
                { Dynamo.Applications.JournalKeys.DynPathExecuteKey, true.ToString() }, // The journal file can specify if the Dynamo workspace opened from DynPathKey will be executed or not. If we are in automation mode the workspace will be executed regardless of this key.
                { Dynamo.Applications.JournalKeys.ForceManualRunKey, false.ToString() }, // don't run in manual mode
                { Dynamo.Applications.JournalKeys.ModelShutDownKey, true.ToString() },
                { Dynamo.Applications.JournalKeys.ModelNodesInfo, false.ToString() }

            };

            dynamoRevitCommandData.JournalData = journalData;           
            Result externalCommandResult = dynamoRevit.ExecuteCommand(dynamoRevitCommandData);
            return externalCommandResult;

        }
    }
}

References

10 Likes

Brilliant work Kevin!
I’m travelling the next couple of days, but I’ll give it a go later on…
Looking forward to this!
Kind regards,
David

Hi,

This is working very well! Thanks a lot for sharing this code!

I have only some questions. I saw that you have to save the dynamo script with run set to automatically otherwise it doesn’t run. I tried to change { Dynamo.Applications.JournalKeys.ForceManualRunKey, false.ToString() }, to true but that doens’t work, not a big issue.

Second thing, would there be a possibility to run a code with more dynamo version installed on your computer? maybe something it always uses the newest version?

Thanks!

First of all: Thank you for sharing @klawson!

Have any of you managed to make this work for dynamo scripts containing a Python script Node?
I have a very simple dynamo script that writes to a parameter for all elements of a category. The Python node just adds a string to the input and “returns it”.

This script runs fine in dynamo itself but when i try to run it using the code above nothing changes in the Revit model.

dynamoRevit.ExecuteCommand(dynamoRevitCommandData); returns Result.Succeeded as if everything went as expected.

Hi MNLI, as @vanlion mentioned. Dynamo has to be set to run automatically, otherwise the script won’t run. It seems like {Dynamo.Applications.JournalKeys.ForceManualRunKey, true.ToString()} is supposed to override this, but it doesn’t.

1 Like

@klawson Amazing! Problem fixed :smiley:

Hi @Klawson,

Really interesting, great work!

Could I ask how you worked it out?

I’d like to play with adding inputs etc. but don’t know where to start! The Dynamo API documentation looks very sparse…

Any tips appreciated!

Mark

Dumb luck and the kindness of strangers.

I took what hzamaniM54WP did and added overloads from what I found in here: https://github.com/DynamoDS/DynamoRevit/blob/master/src/DynamoRevit/DynamoRevit.cs

3 Likes

It works :smiley:

I guess I’ll use data shapes to give inputs…

Repeat runs are as slow as the first… Player seems to keep the graphs loaded so repeat runs are quicker… I wonder if we could add a repeat button or something…

Cheers,

Mark

Thank you so much for sharing! Great work! I’ve had trouble adding the reference for “DynamoRevitDS”. The namespace “DynamoRevit” can not be found in my file. I’m continuing to look into this, but any advice would be greatly appreciated :slight_smile:

Actually, I just got it working. Sorry to bother you. If anyone else has trouble locating that dll file like me, it is in the folder “C:\Program Files\Dynamo\Dynamo Revit\2\Revit_2019” Thanks

1 Like

Everything else is here:

C:\Program Files\Dynamo\Dynamo Core\2\DynamoInstallDetective.dll

Remember to set “copy local” to false.

1 Like

Thank you all for sharing! Has anyone been able to figure out a way around the issue that @vanlion described? Two things that have been limiting are the fact that the Dynamo file has to be set to automatic to run properly(as he described) and the length of time and how the plug-in executes the script. One weird thing that we noticed when testing is that every time you run the plug-in, it executes the Dynamo script 3 times(see it the attached image). We thought that maybe this was due to the different Journal executions, but even after commenting some of them out, this issue persisted. The first two executions do nothing, but the 3rd one is the one that actually makes the changes from the script. Anyone have an idea about why this is happening?
image