Application Level Macro - Flow Mismatch

Application Level Macro - Flow Mismatch

wils02
Enthusiast Enthusiast
1,120 Views
9 Replies
Message 1 of 10

Application Level Macro - Flow Mismatch

wils02
Enthusiast
Enthusiast

I hope this is the right spot...

 

After many thanks to people on the forums, I wanted to post the solution we came up with to find the mismatch with flow! This is an application level Macro so enjoy! Little backstory first though.

 

Sometimes us engineers like to screw things up, so we occasionally will hook up ductwork or piping by attaching to a connector that has a different system classification. Everything visually looks great, but when it comes time to running a pressure loss report Revit does not see a "well connected" system. This equals lots of frustration (especially on larger jobs) to try and track down where the flow mismatch is exactly. Nonetheless, without further adieu, the attached codes will tell you, by "Mark", which family instance has a mismatch between the connector's assigned system and the attached system.

 

Please, please, please feel free to improve this code and point out stupid things I did; I am definitely an improving coder. Just don't be a jerk about it it (we all know those forum posts....) .Capture.PNG

 

Also, a fair amount of code was taken from lots of @jeremytammik solutions so thanks Jeremy, and thanks to @MarryTookMyCoffe for getting me unstuck!

 

wils

0 Likes
Accepted solutions (1)
1,121 Views
9 Replies
Replies (9)
Message 2 of 10

MarryTookMyCoffe
Collaborator
Collaborator

One suggestion, I thing that there should be "<="

        static bool IsDesirableSystemPredicate(MEPSystem s)
        {
            return s is MechanicalSystem || s is PipingSystem
              && !s.Name.Equals("unassigned")
              && 1 <= s.Elements.Size;
        }

Good job with macro

 

But maybe easier would be:
1 get connectors check all Allrefs if connected to this connector

2 do simple connector.PipeSystemType == refcon.PipeSystemType(or duct )

3 if not you can disconnect it for example.

 

-------------------------------------------------------------
--------------------------------|\/\/|------------------------
do not worry it only gonna take Autodesk 5 years to fix bug
0 Likes
Message 3 of 10

jeremytammik
Autodesk
Autodesk
Accepted solution

Dear Wils,

 

Thank you for your appreciation and nice sample utility macro.

 

I looked at the code and just happened to notice that your unused utility methods getSheets and getViewPorts are extremely ineffective, cf.:

 

http://thebuildingcoder.typepad.com/blog/2012/09/findelement-and-collector-optimisation.html

 

They are not used here, and they should be removed (and not used anywhere else either).

 

Thank you to @MarryTookMyCoffe for his question... I wonder too.

 

In case he is right, I prefer writing `0 < s.Elements.Size` instead of `1 <=`.

  

What do you think about his suggestion? He is probably more experienced...

 

Looking further at your code: 

 

If `elemConnector.MEPSystem` can ever be null, then you must check for that before calling its `Name` property, not afterwards.

 

As soon as you call the property on a null object, .NET will throw an exception.

 

There is no need to call `GetOrderedParameters` and iterate over all parameters to find the "Mark" one.

 

You can retrieve it directly using the built-in parameter `ALL_MODEL_MARK`:

 

  // No need to iterate over all parameters:

  IList<Parameter> eParams = e.GetOrderedParameters();
  foreach( Parameter p in eParams )
  {
    if( p.Definition.Name.Equals( "Mark" ) )
    {
      sb.Append( "Family Instance: " + p.AsString() );
      sb.Append( " has a connector {" + cnctrSys + "} which is connected to a {" + cnntdSys + "} system..." + "\n\n" );
    }
  }

  // Also, you should not use the display name if you can avoid it:

  Parameter p2 = e.LookupParameter( "Mark" );

  // Always use the built-in parameter enum if you can:

  Parameter p3 = e.get_Parameter( 
    BuiltInParameter.ALL_MODEL_MARK );

  sb.Append( "Family Instance: " + p3.AsString() );
  sb.Append( " has a connector {" + cnctrSys 
    + "} which is connected to a {" + cnntdSys 
    + "} system..." + "\n\n" );

 

 I ended up cleaning it up by implementing a helper method:

 

  /// <summary>
  /// Add a system mismatch entry to the string builder
  /// </summary>
  static void ReportSystemMistmatch(
    StringBuilder sb,
    Element e,
    string cnctrSys,
    string cnntdSys )
  {
    Parameter p = e.get_Parameter(
      BuiltInParameter.ALL_MODEL_MARK );

    sb.Append( string.Format( "Family instance '{0}' "
      + "has a connector {{{1}}} that is connected to a "
      + "{{{2}}} system...\n\n",
      p.AsString(), cnctrSys, cnntdSys ) );
  }

 Then the code can be reduced to this:

 

  /// <summary>
  /// Report MEP system mismatches
  /// </summary>
  static void FindMismatch( Document doc )
  {
    string cnntdSys = "";
    string cnctrSys = "";

    StringBuilder sb = new StringBuilder();

    FilteredElementCollector systems
      = new FilteredElementCollector( doc )
        .OfClass( typeof( MEPSystem ) );

    IEnumerable<MEPSystem> desirableSystems = systems
      .Cast<MEPSystem>()
      .Where<MEPSystem>( s
        => IsDesirableSystemPredicate( s ) );

    foreach( MEPSystem system in desirableSystems )
    {
      if( system.GetType() == typeof( PipingSystem ) )
      {
        cnntdSys = ( system as PipingSystem ).SystemType.ToString();
      }
      if( system.GetType() == typeof( MechanicalSystem ) )
      {
        cnntdSys = ( system as MechanicalSystem ).SystemType.ToString();
      }

      ElementSet mepSet = system.Elements;
      foreach( Element e in mepSet )
      {
        ConnectorSet mepCS = MepSystemSearch.GetConnectors( e );

        foreach( Connector elemConnector in mepCS )
        {
          if( elemConnector.Domain.Equals(
            Domain.DomainPiping ) )
          {
            cnctrSys = elemConnector.PipeSystemType.ToString();

            if( elemConnector.MEPSystem != null
              && elemConnector.MEPSystem.Name.Equals(
                system.Name ) )
            {
              if( elemConnector.PipeSystemType.Equals(
                ( system as PipingSystem ).SystemType ) )
              {
                // Do Nothing
              }
              else
              {
                ReportSystemMistmatch( sb, e,
                  cnctrSys, cnntdSys );
              }
            }
          }

          if( null != elemConnector.MEPSystem
            && elemConnector.Domain.Equals(
              Domain.DomainHvac ) )
          {
            cnctrSys = elemConnector.DuctSystemType.ToString();

            if( elemConnector.MEPSystem.Name.Equals(
              system.Name ) )
            {
              if( elemConnector.DuctSystemType.Equals(
                ( system as MechanicalSystem ).SystemType ) )
              {
                // Do Nothing
              }
              else
              {
                ReportSystemMistmatch( sb, e, 
                  cnctrSys, cnntdSys );
              }
            }
          }
        }
      }
    }
    TaskDialog.Show( "Flow Mismatch", sb + "\n" );
  }

 I added the edited code to The Building Coder samples for preservation for posterity:

 

https://github.com/jeremytammik/the_building_coder_samples

 

In the new module CmdFlowMismatch.cs:

 

https://github.com/jeremytammik/the_building_coder_samples/blob/master/BuildingCoder/BuildingCoder/C...

 

I hope this helps.

 

Can you provide a small sample model to test run it in?

 

Thank you!

 

Cheers,

 

Jeremy

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 4 of 10

wils02
Enthusiast
Enthusiast

Awesome, thanks @MarryTookMyCoffe and @jeremytammik. I realized I was inconsistent with checking if the system was null, so I updated that.

 

 

 

if( elemConnector.Domain.Equals(
              Domain.DomainPiping ) )
            {
              cnctrSys = elemConnector.PipeSystemType.ToString();

              if( elemConnector.MEPSystem != null
                && elemConnector.MEPSystem.Name.Equals(
                  system.Name ) )
              {
                if( elemConnector.PipeSystemType.Equals(
                  ( system as PipingSystem ).SystemType ) )
                {
                  // Do Nothing
                }
                else
                {
                  ReportSystemMistmatch( sb, e,
                    cnctrSys, cnntdSys );
                }
              }
            }

            if( null != elemConnector.MEPSystem
              && elemConnector.Domain.Equals(
                Domain.DomainHvac ) )
            {
              cnctrSys = elemConnector.DuctSystemType.ToString();

              if( elemConnector.MEPSystem != null 
&& elemConnector.MEPSystem.Name.Equals( system.Name ) ) { if( elemConnector.DuctSystemType.Equals( ( system as MechanicalSystem ).SystemType ) ) { // Do Nothing } else { ReportSystemMistmatch( sb, e, cnctrSys, cnntdSys ); } }

 

 

Other than this, it seems to be working well! I have attached a small sample where I threw together different systems and connected them in weird ways. On small projects these are easy to find issues, but on larger projects, the code just helps narrow down faster where the problem lies by calling out the "Mark" of the instance.

 

wils 

 

 

0 Likes
Message 5 of 10

wils02
Enthusiast
Enthusiast

...how do I attach the sample project? I cant seem to do it the regular way of attaching a file.

0 Likes
Message 6 of 10

jeremytammik
Autodesk
Autodesk

Sure you can. Attachments > Browse files to attach.

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 7 of 10

jeremytammik
Autodesk
Autodesk

Waiting for sample model...

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 8 of 10

wils02
Enthusiast
Enthusiast

Is there another way to get you the file? I really can't attach the file, and I am not sure why. I browse and attach, but after clicking post my screen just resets and removes the attachment.

0 Likes
Message 9 of 10

jeremytammik
Autodesk
Autodesk

Sure. Dropbox, Wetransfer, email, your ftp server, you name it...

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 10 of 10

jeremytammik
Autodesk
Autodesk

Thank you for the sample model by private email.

 

Now for further ideas...

 

You could even add a modeless list of problems detected and a zoom-to functionality for it like I implemented for my modeless loose connector navigator way back then:

 

http://thebuildingcoder.typepad.com/blog/2011/09/yet-another-modeless-update.html

 

In fact, it addresses a task very closely related to (a subset of?) the one you have solved here.

 

Cheers,

 

Jeremy

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder