Exemple #1
0
def faultPlot(bus_coord):
    ''' Plot fault study. '''
    dss.run_command('Solve Mode=FaultStudy')
    dss.run_command('Export fault faults.csv')
    faultData = pd.read_csv('faults.csv')
    bus_coord.columns = ['Bus', 'X', 'Y',
                         'radius']  # Add defined column names.
    faultDF = pd.concat([bus_coord, faultData], axis=1)
    faultDF.columns = faultDF.columns.str.strip()
    plt.scatter(faultDF['radius'], faultDF['3-Phase'])
    plt.xlabel('Distance [m]')
    plt.ylabel('Current [Amps]')
    plt.axis([-1, 6, 0, 8000])
    plt.savefig('3-Phase.png')
    plt.clf()
    plt.scatter(faultDF['radius'], faultDF['1-Phase'])
    plt.xlabel('Distance [m]')
    plt.ylabel('Current [Amps]')
    plt.savefig('1-phase.png')
    plt.axis([-1, 6, 0, 8000])
    plt.clf()
    plt.scatter(faultDF['radius'], faultDF['L-L'])
    plt.xlabel('Distance [m]')
    plt.ylabel('Current [Amps]')
    plt.axis([-1, 6, 0, 8000])
    plt.savefig('L-L.png')
    plt.clf()
    packagePlots('FaultPlots')
Exemple #2
0
def create_dict(output_dir):
    """Do the fault study for each reader and create a dictonary which contains the sequence impedances for each node.
     These values are used for comparison of fault study of readers"""
    comp_values = defaultdict()
    for case_dir in os.listdir(output_dir):
        comp_values[case_dir] = defaultdict()
        for dir_name in os.listdir(os.path.join(output_dir, case_dir)):
            comp_values[case_dir][dir_name] = {}
            with open(
                    os.path.join(output_dir, case_dir, dir_name, "Master.dss"),
                    "r") as rfile:
                filedata = rfile.read()
            filedata = filedata.replace("Solve", "Solve mode=faultstudy")
            with open(
                    os.path.join(output_dir, case_dir, dir_name,
                                 "Faultstudy_Master.dss"),
                    "w",
            ) as file:
                file.write(filedata)

            dss.run_command("Redirect {}".format(
                os.path.join(output_dir, case_dir, dir_name,
                             "Faultstudy_Master.dss")))
            for i in dss.Circuit.AllBusNames():
                dss.Circuit.SetActiveBus(i)
                comp_values[case_dir][dir_name][dss.Bus.Name()] = (
                    dss.Bus.Zsc0() + dss.Bus.Zsc1())

    return comp_values
Exemple #3
0
def _clean_data(data, class_name):
    import opendssdirect as dss

    for element in dss.ActiveClass.AllNames():
        name = "{class_name}.{element}".format(class_name=class_name,
                                               element=element)
        dss.ActiveClass.Name(element)

        if "nconds" in dss.Element.AllPropertyNames():
            nconds = int(data[name]["nconds"])
            x = []
            h = []
            units = []

            for cond in range(1, nconds + 1):
                dss.run_command("{name}.cond={cond}".format(name=name,
                                                            cond=cond))
                x.append(float(dss.run_command(
                    "? {name}.x".format(name=name))))
                h.append(float(dss.run_command(
                    "? {name}.h".format(name=name))))
                units.append(
                    dss.run_command("? {name}.units".format(name=name)))

            data[name]["x"] = x
            data[name]["h"] = h
            data[name]["units"] = units

    return data
Exemple #4
0
    def compile_feeder_initialize(self):
        self.break_flag = 0
        dss.run_command("Clear")
        dss.Basic.ClearAll()
        Master_file = os.path.join(self.Settings["Feeder_path"], self.folders,
                                   self.sub_folder, self.feeder, "Master.dss")
        print(Master_file)
        if not os.path.exists(Master_file):
            print("error {} does not exist".format(Master_file))
            self.break_flag = 1

        if self.break_flag == 0:
            try:
                # Solve base no DPV case: If base no DPV is outside ANSI B limits abort
                command_string = "Redirect {master}".format(master=Master_file)
                # self.write_dss_file(command_string)
                k = dss.run_command(command_string)
                if len(k) > 1:
                    self.break_flag = 1
                command_string = "Solve mode=snap"
                # self.write_dss_file(command_string)
                dss.run_command(command_string)
                self.sol.Solve()
            except:
                self.break_flag == 1
                print("here")
Exemple #5
0
def voltagePlot(filePath, PU=True):
    ''' Voltage plotting routine.'''
    dssFileLoc = os.path.dirname(os.path.abspath(filePath))
    volt_coord = runDSS(filePath)
    dss.run_command('Export voltages ' + dssFileLoc + '/volts.csv')
    # Generate voltage plots.
    voltage = pd.read_csv(dssFileLoc + '/volts.csv')
    volt_coord.columns = ['Bus', 'X', 'Y', 'radius']
    voltageDF = pd.merge(
        volt_coord, voltage,
        on='Bus')  # Merge on the bus axis so that all data is in one frame.
    plt.title('Voltage Profile')
    plt.xlabel('Distance from source[miles]')
    if PU:
        for i in range(1, 4):
            volt_ind = ' pu' + str(i)
            plt.scatter(voltageDF['radius'],
                        voltageDF[volt_ind],
                        label='Phase ' + str(i))
        plt.ylabel('Voltage [PU]')
        plt.legend()
        plt.savefig(dssFileLoc + '/Voltage Profile [PU].png')
    else:
        # plt.axis([1, 7, 2000, 3000]) # Ignore sourcebus-much greater-for overall magnitude.
        for i in range(1, 4):
            mag_ind = ' Magnitude' + str(i)
            plt.scatter(voltageDF['radius'],
                        voltageDF[mag_ind],
                        label='Phase ' + str(i))
        plt.ylabel('Voltage [V]')
        plt.legend()
        plt.savefig(dssFileLoc + '/Voltage Profile [V].png')
    plt.clf()
Exemple #6
0
def voltagePlots(volt_coord):
    ''' Voltage plotting routine.'''
    dss.run_command('Export voltages volts.csv')  # Generate voltage plots.
    voltage = pd.read_csv('volts.csv')
    volt_coord.columns = ['Bus', 'X', 'Y', 'radius']
    voltageDF = pd.merge(
        volt_coord, voltage,
        on='Bus')  # Merge on the bus axis so that all data is in one frame.
    for i in range(1, 4):
        volt_ind = ' pu' + str(i)
        mag_ind = ' Magnitude' + str(i)
        plt.scatter(voltageDF['radius'], voltageDF[volt_ind])
        plt.xlabel('Distance from source[miles]')
        plt.ylabel('Voltage [PU]')
        plt.title('Voltage profile for phase ' + str(i))
        plt.savefig('Pu Profile ' + str(i) + '.png')  # A per unit plot.
        plt.clf()
        plt.scatter(voltageDF['radius'], voltageDF[mag_ind])
        plt.xlabel('Distance from source[miles]')
        plt.ylabel('Volt [V]')
        plt.axis([1, 7, 2000, 3000
                  ])  # Ignore sourcebus-much greater-for overall magnitude.
        plt.title('Voltage profile for phase ' + str(i))
        plt.savefig('Magnitude Profile ' + str(i) + '.png')  # Actual voltages.
        plt.clf()
    packagePlots('voltagePlots')
def test_cyme_to_opendss():
    '''
        Test the Cyme to OpenDSS conversion.
    '''
    list_of_directories = []
    from ditto.store import Store
    from ditto.readers.cyme.read import Reader
    from ditto.writers.opendss.write import Writer
    import opendssdirect as dss
    cyme_models = [
        f for f in os.listdir(
            os.path.join(current_directory, 'data/small_cases/cyme/'))
        if not f.startswith('.')
    ]
    for model in cyme_models:
        print(model)
        m = Store()
        r = Reader(data_folder_path=os.path.join(
            current_directory, 'data/small_cases/cyme', model))
        r.parse(m)
        #TODO: Log properly
        # print('>Cyme model {model} read...'.format(model=model))
        output_path = tempfile.TemporaryDirectory()
        list_of_directories.append(output_path)
        w = Writer(output_path=output_path.name)
        w.write(m)
        #TODO: Log properly
        # print('>...and written to OpenDSS.\n')
        print(model)
        dss.run_command("clear")
Exemple #8
0
def THD(filePath):
    ''' Calculate and plot total harmonic distortion. '''
    dssFileLoc = os.path.dirname(os.path.abspath(filePath))
    bus_coords = runDSS(filePath)
    dss.run_command('Solve mode=harmonics')
    dss.run_command('Export voltages ' + dssFileLoc + '/voltharmonics.csv')
    # Clean up temp file.
    try:
        base = os.path.basename(filePath)
        fnameMinusExt = os.path.splitext(base)[0]
        os.remove('{}_SavedVoltages.dbl'.format(fnameMinusExt))
    except:
        pass
    voltHarmonics = pd.read_csv(dssFileLoc + '/voltharmonics.csv')
    bus_coords.columns = ['Bus', 'X', 'Y', 'radius']
    voltHarmonics.columns.str.strip()
    for index, row in voltHarmonics.iterrows():
        voltHarmonics['THD'] = row[' Magnitude1'] / (
            math.sqrt(row[' Magnitude2']**2 + row[' Magnitude3']**2))
    distortionDF = pd.merge(
        bus_coords, voltHarmonics,
        on='Bus')  # Merge on the bus axis so that all data is in one frame.
    plt.scatter(distortionDF['radius'], distortionDF['THD'])
    plt.xlabel('Distance from Source [miles]')
    plt.ylabel('THD [Percentage]')
    plt.title('Total Harmonic Distortion')
    plt.savefig(dssFileLoc + '/THD.png')
    plt.clf()
def DSS_lines_3ph(iline, timestep):
    # Helper function for DSS_lines
    r11 = iline.R[0, 0]
    r12 = iline.R[1, 0]
    r22 = iline.R[1, 1]
    r13 = iline.R[2, 0]
    r23 = iline.R[2, 1]
    r33 = iline.R[2, 2]

    x11 = iline.X[0, 0]
    x12 = iline.X[1, 0]
    x22 = iline.X[1, 1]
    x13 = iline.X[2, 0]
    x23 = iline.X[2, 1]
    x33 = iline.X[2, 2]

    dss.run_command("New Line." + iline.name + " Bus1=" +
                    iline.from_node.name + ".1.2.3 Bus2=" +
                    iline.to_node.name + ".1.2.3 BaseFreq=60 Phases=3" +
                    " rmatrix = (" + str(r11) + " | " + str(r12) + " " +
                    str(r22) + " | " + str(r13) + " " + str(r23) + " " +
                    str(r33) + ")" + " xmatrix = (" + str(x11) + " | " +
                    str(x12) + " " + str(x22) + " | " + str(x13) + " " +
                    str(x23) + " " + str(x33) + ")")
    return
Exemple #10
0
 def CreateBusObjects():
     dssBuses = {}
     BusNames = dss.Circuit.AllBusNames()
     dss.run_command('New  Fault.DEFAULT Bus1={} enabled=no r=0.01'.format(
         BusNames[0]))
     for BusName in BusNames:
         dss.Circuit.SetActiveBus(BusName)
         dssBuses[BusName] = dssBus()
     return dssBuses
Exemple #11
0
def loadDSS():
    current_directory = os.path.realpath(os.path.dirname(__file__))
    master_file = os.path.join(current_directory,
                               '../data/DSS_files/master.dss')
    dss.Basic.DataPath(current_directory)
    dss.run_command("clear")
    dss.run_command('compile {master}'.format(master=master_file))

    return dss
 def parse_DSS_file(self):
     print("Compiling DSS file in OpenDSS...")
     dss.run_command(r'{:}'.format(self.file))
     print("Parsing DSS file in LogV3LPF format...")
     DSScase.get_capacitors_from_dss(self)
     DSScase.get_transformers_from_dss(self)
     DSScase.get_loads_from_dss(self)
     DSScase.get_lines_from_dss(self)
     DSScase.get_regcontrols_from_dss(self)
     DSScase.get_buses_from_dss(self)
     DSScase.get_constants(self)
     DSScase.create_load_model(self)
     print("Done parsing")
Exemple #13
0
def networkPlot(coords):
    ''' Plot the physical topology of the circuit. '''
    dss.run_command('Export voltages volts.csv')
    volts = pd.read_csv('volts.csv')
    coords.columns = ['Bus', 'X', 'Y', 'radius']
    G = nx.Graph()  # Declare networkx object.
    pos = {}
    for index, row in coords.iterrows():  # Get the coordinates.
        if row['Bus'] == '799R':
            row['Bus'] = '799r'
        if row['Bus'] == 'SOURCEBUS':
            row['Bus'] = 'SourceBus'
        G.add_node(row['Bus'])
        pos[row['Bus']] = (row['X'], row['Y'])

    volt_values = {}
    labels = {}
    for index, row in volts.iterrows(
    ):  # We'll color the nodes according to voltage. FIX: pu1?
        if row['Bus'] == '799R':
            row['Bus'] = '799r'
        if row['Bus'] == 'SOURCEBUS':
            row['Bus'] = 'SourceBus'
        volt_values[row['Bus']] = row[' pu1']
        labels[row['Bus']] = row['Bus']

    colorCode = [volt_values[node] for node in G.nodes()]

    lines = dss.utils.lines_to_dataframe(
    )  # Get the connecting edges using Pandas.
    edges = []
    for index, row in lines.iterrows(
    ):  # For 799R, you need four charactesr. The others all have a period at the end, so splice that.
        bus1 = row['Bus1'][:4].replace('.', '')
        bus2 = row['Bus2'][:4].replace('.', '')
        edges.append((bus1, bus2))
    G.add_edges_from(edges)

    nodes = nx.draw_networkx_nodes(
        G, pos, node_color=colorCode
    )  # We must seperate this to create a mappable object for colorbar.
    edges = nx.draw_networkx_edges(G, pos)
    nx.draw_networkx_labels(G, pos,
                            labels)  # We'll draw the labels seperately.
    plt.colorbar(nodes)
    plt.xlabel('Distance [m]')
    plt.title('Network Voltage Layout')
    plt.savefig('networkPlot.png')
    plt.clf()
    packagePlots('networkPlots')
    def _constructYMatrix(self):
        '''
        Calculate the nodal admittance matrix YMatrix
            
        Returns
        -------
        numpy array
                It returns a complex array of Y admittance matrix        
        '''
        #- disconnect vsources and loads
        dss.run_command('vsource.source.enabled = no')
        dss.run_command('batchedit load..* enabled=no')
        #- extract YMatrix
        dss.Solution.Solve()
        Ybus = dss.Circuit.SystemY()  #--- slow
        Yres = np.reshape(Ybus, (self._nNodes, self._nNodes * 2))  #--- slow
        #- populate complex polyphase nodal Y
        Y = np.zeros((self._nNodes, self._nNodes), dtype=complex)
        for i in range(self._nNodes):  #--- very very slow
            Y[:, i] = Yres[:, 2 * i] + 1j * Yres[:, 2 * i + 1]
        self._YMatrixPrev = self._YMatrix
        self._YMatrix = Y
        #- reconnect vsources and loads
        dss.run_command('vsource.source.enabled = yes')
        dss.run_command('batchedit load..* enabled=yes')
        #- return to the previous solution
        dss.Solution.Solve()

        return Y
    def _readInelasticLoadPQ(self, file):
        '''
        Read inelastic load from file
        
        The class assumes that the file is in the current directory
        After the file is read, the load is inserted in the circuit and
        a new solution is calculated
        
        Parameters
        ----------
        arg1 : str
            Name of the file
            
        Returns
        -------
        numpy array
                It returns an array of P and Q tuples, for each node
        '''
        current_directory = os.path.dirname(os.path.realpath(__file__))
        pathToFile = os.path.abspath(os.path.join(current_directory, file))
        if not os.path.isfile(pathToFile):
            print('File does not exist: ' + pathToFile)
            sys.exit()
        else:
            with open(pathToFile, 'r') as csvFile:
                csvobj = csv.reader(csvFile)
                data = list(csvobj)

            PQ = np.zeros((self._nNodes, 2))
            for i in range(len(data)):
                nodeName = data[i][0]
                idx = self._terminal2node[nodeName]
                # If no such node in map, create one with zero load
                if (nodeName not in self._nodewithload.keys()):
                    self._nodewithload[nodeName] = 0
                if self._nodewithload[nodeName] > 0:
                    PQ[idx][0] = float(data[i][1])
                    PQ[idx][1] = float(data[i][2])
                    logging.debug('New Load.' + nodeName + ' Bus1=' +
                                  nodeName + ' kW=' + data[i][1] + ' kvar=' +
                                  data[i][2])
                    dss.run_command('New Load.' + nodeName + ' Bus1=' +
                                    nodeName + ' kW=' + data[i][1] + ' kvar=' +
                                    data[i][2])
            #-- after loading a new solution is necessary
            dss.Solution.Solve()

        return PQ
 def run(self, detailed_metrics=True):
     """ Run the experiment. """
     steps = self.horizon // self.period
     for t in tqdm(range(steps)):
         self.build_circuit()
         self.step_loads(t)
         dss.run_command("Solve")
         time = self.P.index[t]
         self.store_voltages(time)
         self.store_transformer_info(time)
         if detailed_metrics:
             self._summary_dict[time] = export_to_df("summary")
             self._overload_dict[time] = export_to_df("overload")
             self._capacity_dict[time] = export_to_df("capacity")
             self._currents_dict[time] = export_to_df("currents")
             self._profile_dict[time] = export_to_df("profile")
Exemple #17
0
def main():
    settings = ProjectModel(
        max_control_iterations=50,
        error_tolerance=0.0001,
    )
    dss.run_command(
        "compile tests/data/project/DSSfiles/Master_Spohn_existing_VV.dss")

    volt_var_model = PvControllerModel(
        Control1="VVar",
        Control2="None",
        Control3="None",
        pf=1,
        pfMin=0.8,
        pfMax=1,
        Pmin=0,
        Pmax=1,
        uMin=0.9399999999999999,
        uDbMin=0.97,
        uDbMax=1.03,
        uMax=1.06,
        QlimPU=0.44,
        PFlim=0.9,
        enable_pf_limit=False,
        uMinC=1.06,
        uMaxC=1.1,
        PminVW=10,
        VWtype="Rated Power",
        percent_p_cutin=10,
        percent_p_cutout=10,
        Efficiency=100,
        Priority="Var",
        DampCoef=0.8,
    )
    controller = CircuitElementController(volt_var_model)  # Use all elements.
    manager = ControllerManager.create([controller], settings)

    done = False
    while not done:
        has_converged = manager.run_controls()
        if has_converged:
            print("Reached convergence")
            done = True
        else:
            # TODO: just an example. Real code would have other logic.
            raise Exception("Failed to converge")
Exemple #18
0
def THD(bus_coords):
	''' Calculate and plot harmonics. '''
	dss.run_command('Solve mode=harmonics')
	dss.run_command('Export voltages voltharmonics.csv')
	voltHarmonics = pd.read_csv('voltharmonics.csv')
	bus_coords.columns = ['Bus', 'X', 'Y', 'radius']
	voltHarmonics.columns.str.strip()
	for index, row in voltHarmonics.iterrows():
		voltHarmonics['THD'] = row[' Magnitude1']/(math.sqrt(row[' Magnitude2']**2 + row[' Magnitude3']**2))
	distortionDF = pd.merge(bus_coords, voltHarmonics, on='Bus') # Merge on the bus axis so that all data is in one frame.
	plt.scatter(distortionDF['radius'], distortionDF['THD'])
	plt.xlabel('Radius [m]')
	plt.ylabel('THD [Percentage]')
	plt.title('Total Harmonic Distortion')
	plt.savefig('THD.png')
	packagePlots('THD')
	plt.clf()
Exemple #19
0
    def init(self,
             sid,
             topofile,
             nwlfile,
             loadgen_interval,
             ilpqfile="",
             verbose=0):
        self.sid = sid
        self.verbose = verbose
        self.loadgen_interval = loadgen_interval

        self.swpos = 0
        self.swcycle = 35

        if (self.verbose > 0): print('simulator_pflow::init', self.sid)
        if (self.verbose > 1):
            print('simulator_pflow::init', topofile, nwlfile, ilpqfile,
                  verbose)

        #--- start opendss
        self.dssObj = SimDSS(topofile, nwlfile, ilpqfile)
        if (self.verbose > 2):
            self.dssObj.showLoads()
            self.dssObj.showVNodes()
            self.dssObj.showIinout()
            self.dssObj.showVMagAnglePu()
            dss.run_command("Show Voltages LN nodes")
            dss.run_command("Show Buses")

        #--- Generate and save AdjMatrix and YMatrix
#         self.dssObj.createAdjMatrix("config/IEEE33_AdjMatrixFull.txt")
#         YMatrix = self.dssObj.getYMatrix()
#         np.save('config/IEEE33_YMatrixFull.npy', YMatrix)

#--- create instance of LoadGenerator
        self.objLoadGen = LoadGenerator(nwlfile,
                                        PFLimInf=1.0,
                                        PFLimSup=1.0,
                                        LoadLimInf=0.4,
                                        LoadLimSup=0.9,
                                        AmpGain=0.25,
                                        Freq=1. / 1250,
                                        PhaseShift=math.pi)

        return self.meta
Exemple #20
0
def currentPlots(curr_coord):
	''' Current plotting function.'''
	dss.run_command('Export current currents.csv')
	current = pd.read_csv('currents.csv')
	curr_coord.columns = ['Index', 'X', 'Y', 'radius'] # DSS buses don't have current, but are connected to it. 
	curr_hyp = []
	currentDF = pd.concat([curr_coord, current], axis=1)
	for i in range(1, 3):
		for j in range(1, 4):
			cur_ind = ' I' + str(i) + '_' + str(j)
			plt.scatter(currentDF['radius'], currentDF[cur_ind])
			plt.xlabel('Distance from source [km]')
			plt.ylabel('Current [Amps]')
			plt.title('Current profile for ' + cur_ind)
			plt.savefig('Profile ' + str(i) +'.png')
			plt.clf()
	packagePlots('currentPlots')
	plt.clf()
Exemple #21
0
def networkPlot(filePath):
    ''' Plot the physical topology of the circuit. '''
    dssFileLoc = os.path.dirname(os.path.abspath(filePath))
    coords = runDSS(filePath)
    dss.run_command('Export voltages ' + dssFileLoc + '/volts.csv')
    volts = pd.read_csv(dssFileLoc + '/volts.csv')
    coords.columns = ['Bus', 'X', 'Y', 'radius']
    G = nx.Graph()
    # Get the coordinates.
    pos = {}
    for index, row in coords.iterrows():
        try:
            bus_name = str(int(row['Bus']))
        except:
            bus_name = row['Bus']
        G.add_node(bus_name)
        pos[bus_name] = (row['X'], row['Y'])

# Get the connecting edges using Pandas.
    lines = dss.utils.lines_to_dataframe()
    edges = []
    for index, row in lines.iterrows():
        #HACK: dss upercases everything in the outputs.
        bus1 = row['Bus1'][:4].upper().replace('.', '')
        bus2 = row['Bus2'][:4].upper().replace('.', '')
        edges.append((bus1, bus2))
    G.add_edges_from(edges)
    # We'll color the nodes according to voltage.
    volt_values = {}
    labels = {}
    for index, row in volts.iterrows():
        volt_values[row['Bus']] = row[' pu1']
        labels[row['Bus']] = row['Bus']
    colorCode = [volt_values.get(node, 0.0) for node in G.nodes()]
    # Start drawing.
    nodes = nx.draw_networkx_nodes(G, pos, node_color=colorCode)
    edges = nx.draw_networkx_edges(G, pos)
    nx.draw_networkx_labels(G, pos, labels, font_size=8)
    plt.colorbar(nodes)
    plt.xlabel('Distance [m]')
    plt.title('Network Voltage Layout')
    plt.savefig(dssFileLoc + '/networkPlot.png')
    plt.clf()
    def setLoads(self, ePQ):
        '''
        Update circuit state with new set of loads. Add new load set to the 
        inelastic loads 

        Parameters
        ----------
        arg1 : numpy array
            Array with <nodeName, P, Q> tuples for each node in the system        
        '''

        #-- for each load record received
        for i in range(len(ePQ)):
            #-- extract the node
            nodeName = ePQ[i][0]
            #-- find the index according to terminal2node map
            idx = self._terminal2node[nodeName]
            #-- if the number of homes in the load is greater than zero
            if self._nodewithload[nodeName] > 0:
                if (self._hasIPQ == True):
                    logging.debug('New Load.' + nodeName + ' Bus1=' +
                                  nodeName + ' kW=' +
                                  str(self._iPQ[idx][0] + ePQ[i][1]) +
                                  ' kvar=' +
                                  str(self._iPQ[idx][1] + ePQ[i][2]))

                    dss.run_command('New Load.' + nodeName + ' Bus1=' +
                                    nodeName + ' kW=' +
                                    str(self._iPQ[idx][0] + ePQ[i][1]) +
                                    ' kvar=' +
                                    str(self._iPQ[idx][1] + ePQ[i][2]))
                else:
                    logging.debug('New Load.' + nodeName + ' Bus1=' +
                                  nodeName + ' kW=' + str(ePQ[i][1]) +
                                  ' kvar=' + str(ePQ[i][2]))

                    dss.run_command('New Load.' + nodeName + ' Bus1=' +
                                    nodeName + ' kW=' + str(ePQ[i][1]) +
                                    ' kvar=' + str(ePQ[i][2]))

        #-- after setting a new load, a new system state has to be calculated
        self._updateSystemState()
Exemple #23
0
def DSS_lines_2ph(iline, timestep):
    # Helper function for DSS_lines
    Zmat = iline.R + 1j * iline.X

    if Zmat[0][1] > 1e-7:
        Rtemp = iline.R[0:2][:, 0:2]
        Xtemp = iline.X[0:2][:, 0:2]
    elif Zmat[1][2] > 1e-7:
        Rtemp = iline.R[1:3][:, 1:3]
        Xtemp = iline.X[1:3][:, 1:3]
    elif Zmat[0][2] > 1e-7:
        Rtemp = np.array([[iline.R[0][0], iline.R[0][2]],
                          [iline.R[2][0], iline.R[2][2]]])
        Xtemp = np.array([[iline.X[0][0], iline.X[0][2]],
                          [iline.X[2][0], iline.X[2][2]]])

    r11 = Rtemp[0, 0]
    r12 = Rtemp[1, 0]
    r22 = Rtemp[1, 1]

    x11 = Xtemp[0, 0]
    x12 = Xtemp[1, 0]
    x22 = Xtemp[1, 1]

    phasestr = "."
    if iline.phasevec[0, 0] == 1:
        phasestr = phasestr + "1."
    if iline.phasevec[1, 0] == 1:
        phasestr = phasestr + "2."
    if iline.phasevec[2, 0] == 1:
        phasestr = phasestr + "3."
    if phasestr[len(phasestr) - 1] == ".":
        phasestr = phasestr[:-1]

    dss.run_command("New Line." + iline.name + " Bus1=" +
                    iline.from_node.name + phasestr + " Bus2=" +
                    iline.to_node.name + phasestr + " BaseFreq=60 Phases=2" +
                    " rmatrix = (" + str(r11) + " | " + str(r12) + " " +
                    str(r22) + ")" + " xmatrix = (" + str(x11) + " | " +
                    str(x12) + " " + str(x22) + ")")
    return
Exemple #24
0
def dynamicPlot(filePath, time_step, iterations):
    ''' Do a dynamic, long-term study of the powerflow. time_step is in seconds. '''
    dssFileLoc = os.path.dirname(os.path.abspath(filePath))
    runDSS(filePath)
    dss.run_command('Solve')
    dynamicCommand = 'Solve mode=dynamics stepsize=%d number=%d' % (time_step,
                                                                    iterations)
    dss.run_command(dynamicCommand)
    for i in range(iterations):
        voltString = 'Export voltages ' + dssFileLoc + '/dynamicVolt%d.csv' % i
        currentString = 'Export currents ' + dssFileLoc + '/dynamicCurrent%d.csv' % i
        dss.run_command(voltString)
        dss.run_command(currentString)
    powerData = []
    for j in range(iterations):
        curVolt = 'dynamicvolt%d.csv' % j
        curCurrent = 'dynamiccurrent%d.csv' % j
        voltProfile = pd.read_csv(dssFileLoc + '/' + curVolt)
        voltProfile.columns = voltProfile.columns.str.replace(' ', '')
        curProfile = pd.read_csv(dssFileLoc + '/' + curCurrent)
        curProfile.columns = curProfile.columns.str.replace(' ', '')
        sourceVoltage = voltProfile.loc[voltProfile['Bus'] == 'SOURCEBUS']
        sourceCurrent = curProfile.loc[curProfile['Element'] ==
                                       'Vsource.SOURCE']
        data_summary = {
            'Volts': (sourceVoltage['Magnitude1'], sourceVoltage['Magnitude2'],
                      sourceVoltage['Magnitude3']),
            'Currents': (sourceCurrent['I1_1'], sourceCurrent['I1_2'],
                         sourceCurrent['I1_3'])
        }
        power_triplet = (data_summary['Volts'][0] *
                         data_summary['Currents'][0],
                         data_summary['Volts'][1] *
                         data_summary['Currents'][1],
                         data_summary['Volts'][2] *
                         data_summary['Currents'][2])
        powerData.append(power_triplet)
    first_phase = [item[0] for item in powerData]
    second_phase = [item[1] for item in powerData]
    third_phase = [item[2] for item in powerData]
    plt.plot(first_phase, label='Phase one')
    plt.plot(second_phase, label='Phase two')
    plt.plot(third_phase, label='Phase three')
    plt.legend()
    plt.xlim(0, iterations - 1)
    plt.xlabel('Time [s]')
    plt.ylabel('Power [kW]')
    plt.title('Dynamic Simulation Power Plot')
    plt.savefig(dssFileLoc + '/DynamicPowerPlot.png')
    os.system('rm ' + dssFileLoc + '/dynamicvolt* ' + dssFileLoc +
              '/dynamiccurrent*')
Exemple #25
0
    def volt_var(self):

        # Setting XY curve for PV volt_var
        yarray = [str(el) for el in self.config_dict['volt_var']['yarray']]
        xarray = [str(el) for el in self.config_dict['volt_var']['xarray']]

        assert len(xarray) == len(yarray), 'length of xarray and yarray must be same !!'
        
        self.dss_instance.run_command(f"New XYCurve.vv_curve npts={len(xarray)}" \
             + " Yarray=(" + ','.join(yarray) + ") Xarray=(" + ','.join(xarray) +")")

        # Increment PVSystem
        flag = self.dss_instance.PVsystems.First()

        while flag>0:
            pv_name = self.dss_instance.PVsystems.Name()
            dss.run_command(f"New InvControl.InvPVCtrl_{pv_name} PVSystemList={pv_name} mode=VOLTVAR voltage_curvex_ref=rated "
                "vvc_curve1=vv_curve deltaQ_factor=0.08 varchangetolerance=0.00025 voltagechangetolerance=0.00001 "
                "Eventlog=No VV_RefReactivePower=VARMAX_VARS")

            flag = self.dss_instance.PVsystems.Next() 
Exemple #26
0
def currentPlot(filePath):
    ''' Current plotting function.'''
    dssFileLoc = os.path.dirname(os.path.abspath(filePath))
    curr_coord = runDSS(filePath)
    dss.run_command('Export currents ' + dssFileLoc + '/currents.csv')
    current = pd.read_csv(dssFileLoc + '/currents.csv')
    curr_coord.columns = [
        'Index', 'X', 'Y', 'radius'
    ]  # DSS buses don't have current, but are connected to it.
    curr_hyp = []
    currentDF = pd.concat([curr_coord, current], axis=1)
    plt.xlabel('Distance from source [km]')
    plt.ylabel('Current [Amps]')
    plt.title('Current Profile')
    for i in range(1, 3):
        for j in range(1, 4):
            cur_ind = ' I' + str(i) + '_' + str(j)
            plt.scatter(currentDF['radius'], currentDF[cur_ind], label=cur_ind)
    plt.legend()
    plt.savefig(dssFileLoc + '/Current Profile.png')
    plt.clf()
def DSS_actuators(feeder, timestep):
    # Uses DSS commands to add the previously solved-for values of actuator dispatch to the model as negative loads.
    for key, iact in feeder.actdict.items():
        Pvec = -iact.Pgen[:, timestep].value
        #print('P:',Pvec) #jasper
        Qvec = -iact.Qgen[:, timestep].value
        #print('Q:',Qvec) #jasper
        for idx in range(0, 3):
            if iact.phasevec[0, 0] == 1:
                dss.run_command("New Load." + iact.name + "a Bus1=" +
                                iact.node.name +
                                ".1 Phases=1 Conn=Wye Model=1 kV=" +
                                str(iact.node.kVbase_phg) + " kW=" +
                                str(Pvec[0] * iact.node.kVAbase) + " kvar=" +
                                str(Qvec[0] * iact.node.kVAbase) +
                                " Vminpu=0.8 Vmaxpu=1.2")
            if iact.phasevec[1, 0] == 1:
                dss.run_command("New Load." + iact.name + "b Bus1=" +
                                iact.node.name +
                                ".2 Phases=1 Conn=Wye Model=1 kV=" +
                                str(iact.node.kVbase_phg) + " kW=" +
                                str(Pvec[1] * iact.node.kVAbase) + " kvar=" +
                                str(Qvec[1] * iact.node.kVAbase) +
                                " Vminpu=0.8 Vmaxpu=1.2")
            if iact.phasevec[2, 0] == 1:
                dss.run_command("New Load." + iact.name + "c Bus1=" +
                                iact.node.name +
                                ".3 Phases=1 Conn=Wye Model=1 kV=" +
                                str(iact.node.kVbase_phg) + " kW=" +
                                str(Pvec[2] * iact.node.kVAbase) + " kvar=" +
                                str(Qvec[2] * iact.node.kVAbase) +
                                " Vminpu=0.8 Vmaxpu=1.2")
    return
Exemple #28
0
def capacityPlot(filePath):
    ''' Plot power vs. distance '''
    dssFileLoc = os.path.dirname(os.path.abspath(filePath))
    coords = runDSS(filePath)
    dss.run_command('Export Capacity ' + dssFileLoc + '/capacity.csv')
    capacityData = pd.read_csv(dssFileLoc + '/capacity.csv')
    coords.columns = ['Index', 'X', 'Y', 'radius']
    capacityDF = pd.concat([coords, capacityData], axis=1)
    fig, ax1 = plt.subplots()
    ax1.set_xlabel('Distance From Source [Miles]')
    ax1.set_ylabel('Power [kW]')
    ax1.scatter(capacityDF['radius'], capacityData[' kW'], label='Power')
    ax2 = ax1.twinx()
    ax2.set_ylabel('Maximum transformer percentage (One-side)')
    ax2.scatter(capacityDF['radius'],
                capacityDF.iloc[:, 2] + capacityDF.iloc[:, 3],
                label='Transformer Loading',
                color='red')
    fig.tight_layout()  # otherwise the right y-label is slightly clipped
    fig.legend()
    plt.savefig(dssFileLoc + '/Capacity Profile.png')
    plt.clf()
Exemple #29
0
def DSSrunsnap(dss, show=False):
    dss.run_command('set mode=snap')
    dss.run_command('Solve')

    if show == True:
        dss.run_command('show Powers kva Elements')

    return dss
Exemple #30
0
def capacityPlot(coords):
    ''' Plot power vs. distance '''
    dss.run_command('Export Capacity capacity.csv')
    capacityData = pd.read_csv('capacity.csv')
    coords.columns = ['Index', 'X', 'Y', 'radius']
    capacityDF = pd.concat([coords, capacityData], axis=1)
    plt.scatter(capacityDF['radius'], capacityData[' kW'])
    plt.xlabel('Distance [m]')
    plt.ylabel('Power [kW]')
    plt.savefig('PowerLoad.png')
    plt.clf()
    plt.scatter(capacityDF['radius'], capacityData[' Imax'])
    plt.xlabel('Distance [m]')
    plt.ylabel('Current [Amps]')
    plt.savefig('CurrentLoad.png')
    plt.clf()
    plt.scatter(capacityDF['radius'],
                capacityDF.iloc[:, 2] + capacityDF.iloc[:, 3])
    plt.xlabel('Distance [m]')
    plt.ylabel('Maximum transformer percentage (One-side)')
    plt.savefig('CurrentLoad.png')
    plt.clf()
    packagePlots('capacityPlots')