Skip to content

Instantly share code, notes, and snippets.

@jtrain
Created October 5, 2011 23:57

Revisions

  1. jtrain revised this gist Oct 6, 2011. 1 changed file with 23 additions and 27 deletions.
    50 changes: 23 additions & 27 deletions addgens_fromcsv.py
    Original file line number Diff line number Diff line change
    @@ -1,20 +1,14 @@
    """
    Add machines (gens and svcs) to the working case from a CSV file named:
    Add machines (gens and svcs) to the working case from a CSV file named:
    `` genslist.csv `` This csv file **must** exist in the current
    directory.
    ``genslist.csv ``
    For gens we add all to the case with status off. ECDI will take care of
    status.
    For SVCs we only want them to be in service in and after the year
    specified in the CSV.
    (Neither ECDI nor OPF [since fict SVCs control their own bus] will control
    status of fict SVCs)
    NOTE: Script only works correctly IF case name starts with
    "WP_201112..." (otherwise case_year will be wrong)
    This csv file **must** exist in the current directory. For
    gens we add all to the case with status off. ECDI will take care of status.
    For SVCs we only want them to be in service in and after the year specified in
    the CSV. (Neither ECDI nor OPF [since fict SVCs control their own bus] will
    control status of fict SVCs) NOTE: Script only works correctly IF case name
    starts with "WP_201112..." (otherwise case_year will be wrong)
    """

    from __future__ import with_statement
    @@ -31,28 +25,30 @@
    )

    # Location of libraries
    sys.path.append("C:\\Code\\trunk\\libs\\psselib") # psse_utilities
    sys.path.append("C:\\Code\\trunk\\libs\\filelib") # file utils
    sys.path.append("C:\\program files\\pti\\psse32\\pssbin") # psspy
    sys.path.append("C:\\Code\\trunk\\libs\\psselib") # psse_utilities
    sys.path.append("C:\\Code\\trunk\\libs\\filelib") # file utils
    sys.path.append("C:\\program files\\pti\\psse32\\pssbin") # psspy

    import psspy
    psspy.throwPsseExceptions = True

    #----------------------------------------------------------Exceptions
    class UnexpectedFileName(Exception):
    """Raised if the psse save file does not look like 5SBC_201112_lofl.sav"""
    """Raised if the psse save file does not look like WP_201112_lofl.sav"""


    #---------------------------------------------------------Main event.

    def machines(gens_list_csv_filename):
    """
    Add machines (gens and svcs) to the working case.
    For gens we add all to the case with status off. ECDI will take care of status.
    For SVCs we only want them to be in service in and after the year specified in the CSV.
    (Neither ECDI nor OPF [since fict SVCs control their own bus] will control status of fict SVCs)
    NOTE: Script only works correctly IF case name starts with "WP_201112..." (otherwise case_year will be wrong)
    Add machines (gens and svcs) to the working case. For gens we add all
    to the case with status off. ECDI will take care of status. For SVCs we
    only want them to be in service in and after the year specified in the CSV.
    (Neither ECDI nor OPF [since fict SVCs control their own bus] will control
    status of fict SVCs) NOTE: Script only works correctly IF case name starts
    with "WP_201112..." (otherwise case_year will be wrong)
    """

    Qlimit = 700

    full_savfilename, _ = psspy.sfiles()
    @@ -84,9 +80,9 @@ def machines(gens_list_csv_filename):

    def set_vsched_for_bus(busno, vsched):
    """
    set the scheduled voltage for the bus to the value supplied, otherwise set
    it to the current bus voltage.
    """
    set the scheduled voltage for the bus to the value supplied, otherwise set
    it to the current bus voltage.
    """
    try:
    rval = float(vsched)
    except ValueError
    @@ -102,7 +98,7 @@ def get_year_from_filename(filename):
    Return the case year from a filename. Provided the filename is of the
    format:
    WP_201112_lofl.sav
    WP_201112_lofl.sav
    raises UnexpectedFileName if filename doesnt fit the format.
    """
  2. jtrain created this gist Oct 5, 2011.
    155 changes: 155 additions & 0 deletions addgens_fromcsv.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,155 @@
    """
    Add machines (gens and svcs) to the working case from a CSV file named:
    `` genslist.csv `` This csv file **must** exist in the current
    directory.
    For gens we add all to the case with status off. ECDI will take care of
    status.
    For SVCs we only want them to be in service in and after the year
    specified in the CSV.
    (Neither ECDI nor OPF [since fict SVCs control their own bus] will control
    status of fict SVCs)
    NOTE: Script only works correctly IF case name starts with
    "WP_201112..." (otherwise case_year will be wrong)
    """

    from __future__ import with_statement
    import os
    import sys
    import csv
    import logging

    logging.basicConfig(
    level=logging.DEBUG,
    format='%(asctime)s %(levelname)s %(message)s',
    filename="add_gens_from_csv.log",
    filemode="w"
    )

    # Location of libraries
    sys.path.append("C:\\Code\\trunk\\libs\\psselib") # psse_utilities
    sys.path.append("C:\\Code\\trunk\\libs\\filelib") # file utils
    sys.path.append("C:\\program files\\pti\\psse32\\pssbin") # psspy

    import psspy
    psspy.throwPsseExceptions = True

    #----------------------------------------------------------Exceptions
    class UnexpectedFileName(Exception):
    """Raised if the psse save file does not look like 5SBC_201112_lofl.sav"""


    #---------------------------------------------------------Main event.

    def machines(gens_list_csv_filename):
    """
    Add machines (gens and svcs) to the working case.
    For gens we add all to the case with status off. ECDI will take care of status.
    For SVCs we only want them to be in service in and after the year specified in the CSV.
    (Neither ECDI nor OPF [since fict SVCs control their own bus] will control status of fict SVCs)
    NOTE: Script only works correctly IF case name starts with "WP_201112..." (otherwise case_year will be wrong)
    """
    Qlimit = 700

    full_savfilename, _ = psspy.sfiles()
    case_year = get_year_from_filename(full_savefilename)

    with open(gens_list_csv_filename) as open_csv:
    for row in csv.reader(open_csv):

    busno, genid, pgen, pmax, status = map(int, row[:5])
    excluded, vsched = row[5], row[6]

    # ignore entries marked as excluded.
    if excluded == "TRUE":
    continue

    set_vsched_for_bus(busno, vsched)

    add_machine({
    'busno': busno,
    'genid': str(genid),
    'pgen': pgen,
    'Qlimit': Qlimit,
    'pmax': pmax}, case_year < (status - 101))

    psspy.fnsl([1,1,0,1,0,0,99,0])


    #---------------------------------------------------------Helper functions.

    def set_vsched_for_bus(busno, vsched):
    """
    set the scheduled voltage for the bus to the value supplied, otherwise set
    it to the current bus voltage.
    """
    try:
    rval = float(vsched)
    except ValueError
    ierr, rval = psspy.busdat(busno, 'PU')
    rval = max(rval, 1.085)

    logging.debug("setting %s vsched to %0.2f" % (busno, rval))
    psspy.plant_data(busno, 0, [rval, 100.0])
    psspy.bus_data_2(busno, intgar1=2)

    def get_year_from_filename(filename):
    """
    Return the case year from a filename. Provided the filename is of the
    format:
    WP_201112_lofl.sav
    raises UnexpectedFileName if filename doesnt fit the format.
    """
    casename = os.path.basename(full_savefilename)
    try:
    caseyear = int(casename.split('_')[1])
    except (IndexError, ValueError):
    logging.error("raising UnexpectedFileName error, couldn't get a date"
    " from filename %s" % casename)
    raise UnexpectedFileName(
    "I expected a file like WP_201112_lofl.sav"
    " instead I got %s" % casename)

    logging.debug("found year %d from filename %s"
    % (caseyear, casename))
    return caseyear

    def add_machine(machine_info, inservice=False):
    """
    Add machine data given in the dictionary machine_info.
    The machine may be an SVC or a generator.
    Generators have a non-zero pmax. Generators are added as out of service,
    however svcs may be in service.
    """
    machine = machine_info.get

    if get('pmax') == 0:
    logging.debug("SVC %s is %s service" % (
    machine('busno'), "in" if inservice else "out of"))
    else:
    # all generators are added as out of service.
    inservice = 0

    psspy.machine_data_2(
    machine('busno'),
    machine('genid'),
    [int(inservice),1,0,0,0,0],
    [machine('pgen'),0.0,
    machine('Qlimit'),
    -machine('Qlimit'),
    machine('pmax'),
    0.0, 100.0,0.0, 1.0,0.0,0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
    )

    if __name__ == "__main__":

    csv_file = 'genslist.csv'

    machines(csv_file)