How to Copy and Paste Values into Electrical Circuits

I would like to input the following values into an Electrical Circuit in Revit:
1. The Total Load value from the connected Electrical Equipment
2. A custom parameter value from the connected Electrical Fixture

However, I’m a beginner in Dynamo, and even after trying some of the suggested methods from the forum, I keep running into errors.

Could anyone share a working script that actually runs? I’d really appreciate it!

Additionally, I’m using Revit 2021 — does this version have any major limitations for this kind of task?

We need to see what you’ve tried. Your process isn’t specific to electrical objects as it’s just reading values and writing values between parameters. If you can show us what failed (include the error message) then we can tell you what’s going wrong and how to fix it.

I was able to resolve the issue using the solution in this post:

Thanks!

Sorry, but I have a quick question.

I’m using the “get electrical system” script from the forum post above:

toList = lambda x : x if hasattr(x, '__iter__') else [x]
elems = toList(UnwrapElement(IN[0]))

def getSystem(elem):
    sys = elem.MEPModel.GetElectricalSystems()
    return [x for x in sys]

OUT = [[system for system in x.MEPModel.GetElectricalSystems()] for x in elems]

Is there a way to modify this so that it only returns circuits where the selected element is connected on the “From” side?

Assuming your input elements are panels (electrical equipment).

import clr
import sys
import System
#
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import Autodesk.DesignScript.Geometry as DS

#import Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB
#import specify namespace
from Autodesk.Revit.DB.Electrical import *


#import transactionManager and DocumentManager (RevitServices is specific to Dynamo)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument


def get_Child_ElecSystem(elem):
    if elem.Category.Id == ElementId(BuiltInCategory.OST_ElectricalEquipment):
        return [x for x in elem.MEPModel.GetElectricalSystems() if x.BaseEquipment.Id == elem.Id]
    else:
        print("the input Element is not a Panel ElectricalEquipment")
        return []

toList = lambda x : x if hasattr(x, "__iter__") and not isinstance(x, (str, System.String)) else [x]

#Preparing input from dynamo to revit
lstelems = toList(UnwrapElement(IN[0]))

OUT = [get_Child_ElecSystem(e) for e in lstelems]

Could you share some screenshots and a sample Revit file to help us understand your goal?

3 Likes

Thank you again for your help — I really appreciate it.

The script runs without any errors, and it functions well.
However, I’d like to adjust the direction in which the information is being processed.

Currently, the script traces from the panel downstream to the connected fixtures.
But I need the opposite: to start from an electrical fixture and trace upstream, moving through each connected panel until reaching the main source panel.

I’m trying to walk through the entire upstream connection path — from the fixture to its panel, then to any parent panel above that — and apply values accordingly along the way.

Also, the model contains many such connection chains. Right now, the script only detects one and applies the value to that.
I’d like to modify it so that it processes all relevant upstream connections, not just one.

Element:
3 Electrical Fixture →(Circuit)→ 2 Electrical Equipment→(Circuit)→ 1 Electrical Equipment
Value:
3 Value=A→(Value=A)→2 Value=B→(Value=B)→1 Value=C

Here an example (as I understand it)

import clr
import sys
import System
#
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import Autodesk.DesignScript.Geometry as DS

#import Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB
#import specify namespace
from Autodesk.Revit.DB.Electrical import *


#import transactionManager and DocumentManager (RevitServices is specific to Dynamo)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument


def get_Parent_Hierarchical(elem):
    elecSyst = next((x for x in elem.MEPModel.GetElectricalSystems() if x.SystemType in [ElectricalSystemType.PowerCircuit, 
                                                                                        ElectricalSystemType.PowerBalanced, 
                                                                                        ElectricalSystemType.PowerBalanced]),
                                                                                        None)
    #
    panel = elecSyst.BaseEquipment
    all_System_from_from_panel = [x for x in panel.MEPModel.GetElectricalSystems() if x.BaseEquipment.Id == panel.Id]
    all_System_from_from_panel.sort(key = lambda x : x.Name)
    index = next((i for i, item in enumerate(all_System_from_from_panel) if item.Id == elecSyst.Id), -1)
    # 
    hierarchical_sys = all_System_from_from_panel[:index + 1]
    return panel, hierarchical_sys

toList = lambda x : x if hasattr(x, "__iter__") and not isinstance(x, (str, System.String)) else [x]

#Preparing input from dynamo to revit
lstelems = toList(UnwrapElement(IN[0]))

OUT = [get_Parent_Hierarchical(e) for e in lstelems]
1 Like

Thank you for your support despite my insufficient explanation.
What I was hoping for was to copy the value as shown below.

However, your script seems to copy the value from the lowest-level element within the same hierarchy.

By default, junction boxes do not consume power, however, if you add power consumption (via parameter mapping to the connector), the total load current will appear automatically in the electrical system.

2 Likes

Yes, you are correct.

However, I want to create a custom panel schedule that includes not only calculated values, but also additional values required for local projects.

The problem is that these values are not being applied correctly to the specific circuits.

That’s why I’m trying to use Dynamo to resolve this issue.

here are two possible solutions with Python (there may be others).

  • If there aren’t many panels, I would opt for a solution using pandas (groupby() + sum()).
  • If the structure is more complex with several cascading panels, it might be better to opt for a Tree Data Structure solution.

Is it the same parameter (name) to copy and paste between elements/circuits/panels?

here is an example if it’s just to copy and paste a value element to electrical system

import clr
import sys
import System
#import net library
from System import Array
from System.Collections.Generic import List, IList, Dictionary
#
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import Autodesk.DesignScript.Geometry as DS

#import Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB
#import specify namespace
from Autodesk.Revit.DB.Electrical import *


#import transactionManager and DocumentManager (RevitServices is specific to Dynamo)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument

def get_elec_system(elem):
    elecSyst = next((x for x in elem.MEPModel.GetElectricalSystems() if x.SystemType in [ElectricalSystemType.PowerCircuit, 
                                                                                        ElectricalSystemType.PowerBalanced, 
                                                                                        ElectricalSystemType.PowerBalanced]),
                                                                                        None )
    return elecSyst
    
        
elemIds_processing = []
all_JunctionBox = UnwrapElement(IN[0])
parameter_Name = IN[1]
            #
#Do some action in a Transaction
TransactionManager.Instance.EnsureInTransaction(doc)


for jb in all_JunctionBox:
    elecSystem = get_elec_system(jb)
    para_to_copy = jb.LookupParameter(parameter_Name)
    if para_to_copy is None:
        para_to_copy = doc.GetElement(jb.GetTypeId()).LookupParameter(parameter_Name)
    if para_to_copy is not None and elecSystem is not None: 
        if para_to_copy.StorageType == StorageType.String\
                        and not System.String.IsNullOrEmpty(para_to_copy.AsValueString()):
            elecSystem.LookupParameter(parameter_Name).Set(para_to_copy.AsString())
        else:
            elecSystem.LookupParameter(parameter_Name).SetValueString(para_to_copy.AsValueString())
        panel = elecSystem.BaseEquipment
        # do same with hierarchical panels
        i = 0
        while i < 100:
            i += 1
            if panel is None or panel.Id in elemIds_processing:
                break
            else:
                elemIds_processing.append(panel.Id)
                parent_elecSystem = next((x for x in panel.MEPModel.GetElectricalSystems() if x.BaseEquipment.Id != panel.Id), None)
                if parent_elecSystem is None:
                    break
                else:
                    para_to_copy = panel.LookupParameter(parameter_Name)
                    if para_to_copy.StorageType == StorageType.String\
                                    and not System.String.IsNullOrEmpty(para_to_copy.AsValueString()):
                        parent_elecSystem.LookupParameter(parameter_Name).Set(para_to_copy.AsString())
                    else:
                        parent_elecSystem.LookupParameter(parameter_Name).SetValueString(para_to_copy.AsValueString())
                    # override panel
                    panel = parent_elecSystem.BaseEquipment 
        
        
TransactionManager.Instance.TransactionTaskDone()

OUT = all_JunctionBox
1 Like

I truly appreciate your response.

I’ll make sure to test it again once I’m back in the office and get back to you afterward.

This works perfectly. I sincerely thank you!

1 Like