Re-running Scripts

Each time the above script, is run, it will create a new workspace and a new book, destroying any previously saved changes. It would be more useful for the script to re-use a previously created workspace and book, if they exist, instead of blindly overwritting them. If the graph frames and graphs already exist inside the book, they should be reused. This will allow static content to be added to a report workspace, and the script will be used to only update the dynamic portions.

Workspace Exists?

Instead of blindly creating a new workspace, we will first attempt to load an existing one. If we can successfully load the workspace, we will retrieve a reference to the existing book. Only if the workspace did not exist will we create a new one.

Replace the following 4 lines:

    enerplot.new_workspace()
    enerplot.load_datafiles('C:\\Users\\Public\\Documents\\Enerplot\\1.0.0\\Examples\\DataFiles\\CSV_Files\\Cigre_47.csv', load_data=True)
    untitled = enerplot.book('Untitled')
    sheet1 = untitled.sheet('Sheet1')

with the following try: catch: structure:

    # Workspace & Book names
    folder = r"~\Documents"
    workspace_name = "ScriptDemo"
    book_name = "ScriptDemo"

    # Load the workspace if it exists, otherwise create a new one.
    try:
        enerplot.load_workspace(workspace_name, folder=folder)
        book = enerplot.book(book_name)
    except FileNotFoundError:
        enerplot.new_workspace()
        book = enerplot.book("Untitled")

    enerplot.load_datafiles('C:\\Users\\Public\\Documents\\Enerplot\\1.0.0\\Examples\\DataFiles\\CSV_Files\\Cigre_47.csv', load_data=True)
    sheet1 = book.sheet('Sheet1')

Change the last two lines of the script from:

    untitled.save_as('C:\\Users\\aneufeld\\Documents\\ScriptDemo.epbx')
    enerplot.save_workspace_as('C:\\Users\\aneufeld\\Documents\\ScriptDemo.epwx', save_projects=False)

to the following, using the variables defined above for the folder, book and workspace names:

    # Save the book and workspace
    book.save_as(book_name, folder=folder)
    enerplot.save_workspace_as(workspace_name, folder=folder)

Book Exists?

It is possible the workspace exists, but has been saved without the ScriptDemo book. In this case, the enerplot.book(book_name) command will fail. As above, we can catch that, and create the required book.

Replace the book = enerplot.book(book_name) command with the following:

        # Get reference to book, if exists, otherwise create a new one.
        try:
            book = enerplot.book(book_name)

        except ValueError:
            book = enerplot.new_book(book_name, folder=folder)

Sheet Exists?

Since sheets can be removed from a book, we need to ensure our required sheet is present, and create it if it isn’t.

Replace sheet1 = book.sheet('Sheet1') with:

    # Locate (or create) a sheet called "Sheet1"
    try:
        sheet1 = book.sheet("Sheet1")
    except ValueError:
        sheet1 = book.new_sheet("Sheet1")

Datafile Exists?

If the workspace was newly created, above, it won’t have any datafile in it. If the workspace exists, it should have our desired datafile, but it is possible the datafile was removed and then the workspace was saved. So we again must look for the datafile, and load it if not present.

Remove the enerplot.load_datafiles(...) line, and add the following before the code that creates the graph frame:

    # Locate (or load) "Cigre 47" datafile
    try:
        cigre = enerplot.datafile("Cigre_47.csv")
    except ValueError as e:
        cigre = enerplot.load_datafiles("DataFiles\\CSV_Files\\Cigre_47.csv",
                                        folder=enerplot.examples)[0]

    # Get references to Rectifier AC phase voltages
    ph_a = cigre["Rectifier\\AC Voltage:1"]
    ph_b = cigre["Rectifier\\AC Voltage:2"]
    ph_c = cigre["Rectifier\\AC Voltage:3"]

We’ve shorten the variable names holding the channels here. We’ll fix the references to those variables in a later step.

Graph Frame?

Again, just because the workspace, book, and sheet all exists does not guarentee that our graph frame exists. If it does, we’ll assume it still has our Phase voltage graph set up properly. If not, we’ll need to create it.

Replace the following lines, which create the graph frame and first graph:

    gf = sheet1.graph_frame()
    gf.position(1, 1)
    gf.extents(1, 1, 45, 32)
    gf.properties(title="Rectifier AC Voltage")
    graph = gf.panel(0)
    graph.properties(title="Phase Voltages (kV)")
    cigre_47 = enerplot.datafile('Cigre_47.csv')
    rectifier_ac_voltage_1 = cigre_47.channel('Rectifier\\AC Voltage:1')
    graph.add_curves(rectifier_ac_voltage_1)
    rectifier_ac_voltage_2 = cigre_47.channel('Rectifier\\AC Voltage:2')
    graph.add_curves(rectifier_ac_voltage_2)
    rectifier_ac_voltage_3 = cigre_47.channel('Rectifier\\AC Voltage:3')
    graph.add_curves(rectifier_ac_voltage_3)
    graph.zoom(xmin=0, xmax=0.2, ymin=-0.2, ymax=1.2)

with the following shorter code which does approximately the same thing:

    # Locate (or create) a Graph Frame with "Rectifier AC Voltage" title
    frame = sheet1.find("GraphFrame", title="Rectifier AC Voltage")
    if not frame:
        frame = sheet1.graph_frame(1, 1, 45, 32,
                                   title="Rectifier AC Voltage", xtitle="Time")
        top = frame.panel(0)
        top.properties(title="Phase Voltages (kV)")
        top.add_curves(ph_a, ph_b, ph_c)
        top.zoom(xmin=0, xmax=0.2, ymax=1.2, ymin=-0.2)

Here, we are searching sheet1 for a Graph Frame which has the given title. If it is not found, we create it, combining creating the graph frame, positioning it, sizing it and setting the title into one step. If we create the graph frame, we set the title of the first graph, add three channels to the graph in one step, and then set the zoom for the graph.

Overlay Graph?

Finally, just because the graph frame exists doesn’t mean our second overlay graph hasn’t been removed. We need to check for it, and if not found, create it.

Replace the two graph2 lines with:

    # Locate (or create) the Graph with title "Zero Sequence Voltage (V)"
    bottom = frame.find(title="Zero Sequence Voltage (V)")
    if not bottom:
        bottom = frame.add_overlay_graph()
        bottom.properties(title="Zero Sequence Voltage (V)")

Creating New Data

Finally, it is time to compute and add the zero sequence voltage to the graph.

Since it is possible to save the book with a zero sequence voltage channel added to the graph, but loading the book will not recreate the actual zero sequence channel, we will need to remove any previously saved channel from the graph before adding the new channel to the graph.

Add the following lines:

    # Remove any curves accidentally saved in "bottom" graph
    curves = bottom.list()
    if curves:
        for curve in curves:
            curve.cut()

    # Calculate and add the Zero Sequence channel
    v_zero = (ph_a + ph_b + ph_c) * 1000
    zero_seq = cigre.set_channel(v_zero, "Zero Sequence", "Script Output")
    bottom.add_curves(zero_seq)

Testing the Script

You can run this script several times. It should be resilient against various changes such as deleting the workspace, and adding or deleting books, sheets, graph frames, graphs, and other components. Each time it runs, if a component exists, it should find and reuse it, or recreate it if it is missing.

Any addition items you choose to save in the book and workspace should persist when the script is run.