Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Changing Loss Method and Loss Method setting from code

7 REPLIES 7
Reply
Message 1 of 8
dsmith
1644 Views, 7 Replies

Changing Loss Method and Loss Method setting from code

Hi

 

Looking for some info on how to change the

'Loss Method' to use 'Specific Loss'

 

and

 

'Loss Method Settings' to a specific value from Code.

 

Can anyone out there point me in the right direction.

 

Thank you in advance.

Tags (1)
7 REPLIES 7
Message 2 of 8
arnostlobel
in reply to: dsmith

Hello dsmith:

I am not an MEP guy here, thus I am not sure I will give you the right information at this moment, but with more input from you I can redirect your MEP questions to the MEP team.

For what I know, there are three ways to provide a custom pressure loss - one is for loss in an individual fitting, another for particular piping, loss the other is for the "pressure drop" method itself. Altering either one can be done by providing an External Server to an appropriate External Service in Revit. There is one service per each of the cases I mentioned above:


1. Coefficient from ASHRAE Table

2. Specific Coefficient

3. Specific Loss

Each of the services uses a default servers provided by Revit. However, any user can provide his or her own external server, which can modify the default calculations.

While customizing Revit via external services is not terribly difficult to do, it is not a perfect API beginners either. I believe there are samples in our SDK (and probably some snippets in the CHM file).

Again, once I know what that is exactly what you want to know (in language I can pass onto our MEP team), I'll do that.

Arno?t
Arnošt Löbel
Message 3 of 8
dsmith
in reply to: arnostlobel

Arnošt

 

Thanks for your reply. I have searched the web for a while now and cannot find a way via the api to simply change

the 'Loss Method' of an MEP Family instance from  'Coefficient from ASHRAE Table' to 'Specific Loss'

and then also set the 'Loss Method Setting' Value.

Message 4 of 8
arnostlobel
in reply to: dsmith

Hello dsmith:

 

I am not surprised that you could not Google up anything about the external services. It is not exactly your regular Revit API 1.0.1 feature. It is rather an advanced technique not many user use or even know about, hence the lack of references out there.

 

However, that is not an excuse for the lack of documentation in our Revit SDK. I have searched and could not find one example or snippet of using MEP servers. The documentation in the RevitAPI.chm file is also less than satisfactory,in my opinion. I have had raised it as I critical issue and assigned it to the responsible MEP team. I will be monitoring their effort and progress, and hopefully we’ll see some concrete improvements soon.

 

In the meantime, however, I may be of some assistance, or the ADN group if you are a member. I know a big deal about External Services is Revit, and I can tell you all about it. I am not, however, an MEP person, thus I do know nearly nothing about the MEP-related services and how they are supposed to be implemented. At the very least, though, I can point you to the right place so you can at least familiarize yourself with the concept of customizing Revit MEP calculations via external services.

 

The best place to start is probably the Autodesk.Revit.DB.ExternalService namespace as described in the RevitAPI.chm. It lists all the basic classes (not the derived MEP classes) with decent amount of documentation.

 

All external services available in Revit are listed it the ExternalServices.BuiltInExternalServices enum.

 

Out of all those there are five of them related to MEP calculations:

  1. DuctFittingAndAccessoryPressureDropService
  2. DuctPressureDropService
  3. PipeFittingAndAccessoryPressureDropService
  4. PipePlumbingFixtureFlowService
  5. PipePressureDropService

 

User can provide their own external servers for each of the services to use (instead of using the Revit default calculation methods). Such servers implement their respective interfaces of server classes. There are listed here in the same order as above:

  1. IDuctFittingAndAccessoryPressureDropServer
  2. IDuctPressureDropServer
  3. IPipeFittingAndAccessoryPressureDropServer
  4. IPipePlumbingFixtureFlowServer
  5. IPipePressureDropServer

 

To find out more about what each of the servers are expected to do, you need to look those classes up in the CHM file. For example, an implementation of the IDuctPressureDropServer is expected to implement (besides some basic methods) the Calculate method, which Revit will call at times it needs to calculate a pressure drop for a duct.

 

Once you have your custom server implemented, you need to register it within Revit and then set it as the active server for the particular service. One of such a way is doing it in the OnStartup method as I am going to show here:

 

public ExternalDBApplicationResult OnStartup(ControlledApplication application)
{
   // Get a particular service from Revit
   ExternalService service = ExternalServiceRegistry.GetService(ExternalServices.BuiltInExternalServices.IDuctPressureDropServer);
 
   if (service == null)
   return Failed;
 
   // Create an instance of your server and register it with the Service.
   MyDuctPressureDropCalculator myServer = MyDuctPressureDropCalculator();
   service.AddServer(new MyDuctPressureDropCalculator());
 
   // Make Revit to use this server instead of the default one
   service.SetActiveServer(myServer.GetServerId())
 
   return Succeeded;
}

  

There is a lot, lot more, as you will learn when you start using it. The above is just a basic information, but it should get you started, or at least show you what is available.

 

Thank you

Arnošt Löbel
Message 5 of 8
dsmith
in reply to: arnostlobel

Thanks for your reply, but I have finally resolved this issue. For your info

 

to change Loss Method

 

ParameterSet pp = elem.Parameters;
IEnumerator enumerator = pp.GetEnumerator();
enumerator.Reset();
while (enumerator.MoveNext())
    {
        Parameter i = enumerator.Current as Parameter;
         if (i.Definition.Name == "Loss Method")
         {
            i.Set("46245996-eebb-4536-ac17-9c1cd917d8cf");
         }
     }

 

 

to change pressure Loss Method (in Extended Storage)

 

Schema sch = Schema.Lookup(new Guid("5c8b4686-656e-4ab5-8382-ec43c3026b4e"));
                            if (sch != null)
                            {
                                string LossCurr = "0.0";
                                Entity ent1 = elem.GetEntity(sch);
                                try
                                {
                                    LossCurr = ent1.Get<string>(sch.GetField("PressureLoss"));
                                    ent1.Set<string>(sch.GetField("PressureLoss"), flowLoss.ToString());
                                    elem.SetEntity(ent1);
                                }
                                catch (System.Exception e)
                                {
                                    Entity ent = new Entity(sch);
                                    elem.SetEntity(ent);
                                    Entity ent2 = elem.GetEntity(sch);
                                    ent2.Set<string>(sch.GetField("PressureLoss"), flowLoss.ToString());
                                    elem.SetEntity(ent2);
                                }                                                      
                            }

 

 

 

Message 6 of 8
arnostlobel
in reply to: dsmith

I see.

I did not know about that some MEP parameters used external storage. How did you find out? Where did you find the GUIDs?

By the way, I would advise against the way you handle exceptions. Typically, exception handling should be as simple as possible, and should not invoke method that can possible throw, which does not seem to be the case of the code inside your CATCH. If any of the methods there throw, it will bring Revit to its knees. I presume that what you've shown is just for demonstration purposes.

Thank you
Arnošt Löbel
Message 7 of 8
dsmith
in reply to: arnostlobel

GUID was in the Journal file, external storage I found using snoop and your correct about the exception.

 

Thanks for you comments.

 

 

Message 8 of 8
arnostlobel
in reply to: dsmith

Hello dmsith:

 

I thought about your sample and solution last night, and finally figured it out before I fell asleep. This morning you also confirmed my conclusion, which is that you found about the GUIDs in Revit journals.

 

In spate of the fact that your approach works for you, I am afraid I have to state that it is quite a hacky thing what you do there. I do not like “hacky”, and I cannot therefore ok it. However, I do not blame you for using the code as you did. You were looking for a solution to a reasonable task, and you could not find it anywhere. I blame us, or the MEP team specifically for not documenting the MEP custom calculations and the mechanism of how it is all expected to be used. I have already started serious discussion with the team and I can promise it’ll be improved.

 

For you and all the readers of this post I am going to show a sample of an API code that does what you wanted to do, only it’s the proper way this time:

// This method can be called with server name == "Specific Loss", for example
private void SetPressureDropServer (Document document, string serverName)
{
    // in this example we only deal with one of the built-in services
    ExternalServiceId serviceId = ExternalServices.BuiltInExternalServices.DuctFittingAndAccessoryPressureDropService;
    
    // assuming we are dealing with a multi-server service (not single-server service)
    MultiServerService service = ExternalServiceRegistry.GetService(serviceId) as MultiServerService;

    if (service !=  null)
    {
        //go through all servers currently registered for the service
        foreach(Guid serverId in service.GetRegisteredServerIds())
        {
            // try to find the one with the given name
            IExternalServer server = service.GetServer(serverId);
            if (server.GetName() == serverName)
            {
                using (Transaction trans = new Transaction(document))
                {
                    trans.Start("Changing pressure-drop server");

                    // multi-server list may have more than one active server,
                    // but for this case here we assume we only want to use one
                    IList<Guid> newActiveServers = new List<Guid>();
                    newActiveServers.Add(serverId);

                    // note: this will activate it in just the given document.
                    // there is another method that can activate it globally.
                    service.SetActiveServers(newActiveServers, document);
                    
                    trans.Commit();
                }
                break;
            }
        }
    }
} 

 

Keep in mind this is just a very simple example of how external services (which is what MEP calculations now are) are to be used. I only wrote this small example to make it do what you were after. There is however a lot that can be achieved with services. Plus there are other external services available in Revit, such as IFC export, external resource data, code checking, etc. They all allow for some serious customization of Revit.

 

As I was poking around in my attempt to find out more about available documentation, I was told about this article that was posted on Jeremy’s blog a while ago: User MEP Calculation Sample..

 

Martin Schmid from one of our MEP group introduces the MEP external services there and writes about how to use them. I recommend reading it for anyone interested in customizing or programmatically controlling MEP calculations in Revit.

 

I hope it all helps somehow.

 

Thank you

Arnošt Löbel

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report