예제 #1
0
def volt_vars_mode(vv_curves, vv_response_time, pwr_lvls, v_ref_value):

    result = script.RESULT_FAIL
    daq = None
    v_nom = None
    grid = None
    pv = None
    eut = None
    chil = None
    result_summary = None
    dataset_filename = None

    try:
        cat = ts.param_value('eut.cat')
        cat2 = ts.param_value('eut.cat2')
        sink_power = ts.param_value('eut.sink_power')
        p_rated = ts.param_value('eut.p_rated')
        p_rated_prime = ts.param_value('eut.p_rated_prime')
        var_rated = ts.param_value('eut.var_rated')
        s_rated = ts.param_value('eut.s_rated')

        #absorb_enable = ts.param_value('eut.abs_enabled')
        # DC voltages
        v_in_nom = ts.param_value('eut.v_in_nom')
        #v_min_in = ts.param_value('eut.v_in_min')
        #v_max_in = ts.param_value('eut.v_in_max')

        # AC voltages
        v_nom = ts.param_value('eut.v_nom')
        v_low = ts.param_value('eut.v_low')
        v_high = ts.param_value('eut.v_high')
        p_min = ts.param_value('eut.p_min')
        p_min_prime = ts.param_value('eut.p_min_prime')
        phases = ts.param_value('eut.phases')

        """
        Version validation
        """
        p1547.VersionValidation(script_version=ts.info.version)

        """
        A separate module has been create for the 1547.1 Standard
        """
        ActiveFunction = p1547.ActiveFunction(ts=ts,
                                              functions=[VV],
                                              script_name='Volt-Var',
                                              criteria_mode=[True, True, True])
        ts.log_debug("1547.1 Library configured for %s" % ActiveFunction.get_script_name())

        # result params
        result_params = ActiveFunction.get_rslt_param_plot()
        ts.log_debug(result_params)

        '''
        a) Connect the EUT according to the instructions and specifications provided by the manufacturer.
        '''
        ts.log_debug(15*"*"+"HIL initialization"+15*"*")

        # initialize HIL environment, if necessary
        chil = hil.hil_init(ts)
        if chil is not None:
            chil.config()
        ts.log_debug(15*"*"+"PVSIM initialization"+15*"*")
        # pv simulator is initialized with test parameters and enabled
        pv = pvsim.pvsim_init(ts, support_interfaces={'hil': chil}) 
        if pv is not None:
            pv.power_set(p_rated)
            pv.power_on()  # Turn on DC so the EUT can be initialized
            #daq.set_dc_measurement(pv)  # send pv obj to daq to get dc measurements
            ts.sleep(0.5)

        # DAS soft channels
        ts.log_debug(15*"*"+"DAS initialization"+15*"*")

        #das_points = {'sc': ('Q_TARGET', 'Q_TARGET_MIN', 'Q_TARGET_MAX', 'Q_MEAS', 'V_TARGET', 'V_MEAS', 'event')}
        das_points = ActiveFunction.get_sc_points()
        # initialize data acquisition system
        daq = das.das_init(ts, sc_points=das_points['sc'], support_interfaces={'hil': chil}) 

        daq.sc['V_TARGET'] = v_nom
        daq.sc['Q_TARGET'] = 100
        daq.sc['Q_TARGET_MIN'] = 100
        daq.sc['Q_TARGET_MAX'] = 100
        daq.sc['event'] = 'None'

        ts.log('DAS device: %s' % daq.info())

        '''
        b) Set all voltage trip parameters to the widest range of adjustability.  Disable all reactive/active power
        control functions.
        '''
        ts.log_debug(15*"*"+"EUT initialization"+15*"*")

        eut = der.der_init(ts, support_interfaces={'hil': chil}) 
        if eut is not None:
            eut.config()
            ts.log_debug(eut.measurements())

            #Deactivating all functions on EUT
            #eut.deactivate_all_fct()

            ts.log_debug('Voltage trip parameters set to the widest range: v_min: {0} V, '
                         'v_max: {1} V'.format(v_low, v_high))
            try:
                eut.vrt_stay_connected_high(params={'Ena': True, 'ActCrv': 0, 'Tms1': 3000,
                                                    'V1': v_high, 'Tms2': 0.16, 'V2': v_high})
            except Exception as e:
                ts.log_error('Could not set VRT Stay Connected High curve. %s' % e)
            try:
                eut.vrt_stay_connected_low(params={'Ena': True, 'ActCrv': 0, 'Tms1': 3000,
                                                   'V1': v_low, 'Tms2': 0.16, 'V2': v_low})
            except Exception as e:
                ts.log_error('Could not set VRT Stay Connected Low curve. %s' % e)
        else:
            ts.log_debug('Set L/HVRT and trip parameters set to the widest range of adjustability possible.')

        # # Special considerations for CHIL ASGC/Typhoon startup
        if chil is not None:
            if eut is not None:
                if eut.measurements() is not None:
                    inv_power = eut.measurements().get('W')
                    timeout = 120.
                    if inv_power <= p_rated * 0.85:
                        pv.irradiance_set(995)  # Perturb the pv slightly to start the inverter
                        ts.sleep(3)
                        eut.connect(params={'Conn': True})
                    while inv_power <= p_rated * 0.85 and timeout >= 0:
                        ts.log('Inverter power is at %0.1f. Waiting up to %s more seconds or until EUT starts...' %
                            (inv_power, timeout))
                        ts.sleep(1)
                        timeout -= 1
                        inv_power = eut.measurements().get('W')
                        if timeout == 0:
                            result = script.RESULT_FAIL
                            raise der.DERError('Inverter did not start.')
                    ts.log('Waiting for EUT to ramp up')
                    ts.sleep(8)
                    ts.log_debug('DAS data_read(): %s' % daq.data_read())

        '''
        c) Set all AC test source parameters to the nominal operating voltage and frequency.
        '''
        ts.log_debug(15*"*"+"GRIDSIM initialization"+15*"*")

        grid = gridsim.gridsim_init(ts,support_interfaces={'hil': chil})  # Turn on AC so the EUT can be initialized
        if grid is not None:
            grid.voltage(v_nom)
            if chil is not None:  # If using HIL, give the grid simulator the hil object
                grid.config()

        # open result summary file
        result_summary_filename = 'result_summary.csv'
        result_summary = open(ts.result_file_path(result_summary_filename), 'a+')
        ts.result_file(result_summary_filename)
        result_summary.write(ActiveFunction.get_rslt_sum_col_name())

        '''
        d) Adjust the EUT's available active power to Prated. For an EUT with an input voltage range, set the input
        voltage to Vin_nom. The EUT may limit active power throughout the test to meet reactive power requirements.
        For an EUT with an input voltage range.
        '''

        if pv is not None:
            pv.iv_curve_config(pmp=p_rated, vmp=v_in_nom)
            pv.irradiance_set(1000.)

        '''
        gg) Repeat steps g) through dd) for characteristics 2 and 3.
        '''
        for vv_curve in vv_curves:
            ts.log('Starting test with characteristic curve %s' % (vv_curve))
            ActiveFunction.reset_curve(vv_curve)
            ActiveFunction.reset_time_settings(tr=vv_response_time[vv_curve], number_tr=2)
            v_pairs = ActiveFunction.get_params(function=VV, curve=vv_curve)
            #ts.log_debug('v_pairs:%s' % v_pairs)

            '''
            ff) Repeat test steps d) through ee) at EUT power set at 20% and 66% of rated power.
            '''
            for power in pwr_lvls:
                ActiveFunction.reset_pwr(power)

                if pv is not None:
                    pv_power_setting = (p_rated * power)
                    pv.iv_curve_config(pmp=pv_power_setting, vmp=v_in_nom)
                    pv.irradiance_set(1000.)

                # Special considerations for CHIL ASGC/Typhoon startup #
                # Why does it need to appear twice, shouldn't this be at the driver level
                if chil is not None:
                    if eut is not None:
                        if  eut.measurements() is not None:
                            inv_power = eut.measurements().get('W')
                            timeout = 120.
                            if inv_power <= pv_power_setting * 0.85:
                                pv.irradiance_set(995)  # Perturb the pv slightly to start the inverter
                                ts.sleep(3)
                                eut.connect(params={'Conn': True})
                            while inv_power <= pv_power_setting * 0.85 and timeout >= 0:
                                ts.log('Inverter power is at %0.1f. Waiting up to %s more seconds or until EUT starts...' %
                                    (inv_power, timeout))
                                ts.sleep(1)
                                timeout -= 1
                                inv_power = eut.measurements().get('W')
                                if timeout == 0:
                                    result = script.RESULT_FAIL
                                    raise der.DERError('Inverter did not start.')
                            ts.log('Waiting for EUT to ramp up')
                            ts.sleep(8)
                    



                '''
                ee) Repeat test steps e) through dd) with Vref set to 1.05*VN and 0.95*VN, respectively.
                '''
                for v_ref in v_ref_value:
                    ts.log('Setting v_ref at %s %% of v_nom' % (int(v_ref * 100)))

                    #Setting grid to vnom before test
                    if grid is not None:
                        grid.voltage(v_nom)

                    if eut is not None:
                        '''
                        e) Set EUT volt-var parameters to the values specified by Characteristic 1.
                        All other function should be turned off. Turn off the autonomously adjusting reference voltage.
                        '''
                        # Activate volt-var function with following parameters
                        # SunSpec convention is to use percentages for V and Q points.
                        vv_curve_params = {
                            'v': [(v_pairs['V1'] / v_nom) , (v_pairs['V2'] / v_nom) ,
                                  (v_pairs['V3'] / v_nom), (v_pairs['V4'] / v_nom) ],
                            'var': [(v_pairs['Q1'] / s_rated), (v_pairs['Q2'] / s_rated) ,
                                    (v_pairs['Q3'] / s_rated) , (v_pairs['Q4'] / s_rated)],
                            'vref': v_ref,
                            'RmpPtTms': vv_response_time[vv_curve]
                        }
                        ts.log_debug('Sending VV points: %s' % vv_curve_params)
                        eut.volt_var(params={'Ena': True, 'ACTCRV': vv_curve, 'curve': vv_curve_params})
                        # TODO autonomous vref adjustment to be included
                        # eut.autonomous_vref_adjustment(params={'Ena': False})
                        '''
                        f) Verify volt-var mode is reported as active and that the correct characteristic is reported.
                        '''
                        ts.log_debug('Initial EUT VV settings are %s' % eut.volt_var())
                    if chil is not None:                        
                        ts.log('Start simulation of CHIL')  
                        chil.start_simulation()
                    v_steps_dict = ActiveFunction.create_vv_dict_steps(v_ref=v_ref)

                    dataset_filename = 'VV_%s_PWR_%d_vref_%d' % (vv_curve, power * 100, v_ref*100)
                    ActiveFunction.reset_filename(filename=dataset_filename)
                    #ts.log('------------{}------------'.format(dataset_filename))
                    # Start the data acquisition systems
                    daq.data_capture(True)

                    for step_label, v_step in v_steps_dict.items():

                        ts.log('Voltage step: setting Grid simulator voltage to %s (%s)' % (v_step, step_label))

                        ActiveFunction.start(daq=daq, step_label=step_label)
                        step_dict = {'V': v_step}

                        if grid is not None:
                            grid.voltage(step_dict['V'])

                        ActiveFunction.record_timeresponse(daq=daq)
                        ActiveFunction.evaluate_criterias(daq=daq, step_dict=step_dict)
                        result_summary.write(ActiveFunction.write_rslt_sum())

                    ts.log('Sampling complete')
                    dataset_filename = dataset_filename + ".csv"
                    daq.data_capture(False)
                    ds = daq.data_capture_dataset()
                    ts.log('Saving file: %s' % dataset_filename)
                    ds.to_csv(ts.result_file_path(dataset_filename))
                    result_params['plot.title'] = dataset_filename.split('.csv')[0]
                    ts.result_file(dataset_filename, params=result_params)
                    result = script.RESULT_COMPLETE



    except script.ScriptFail as e:
        reason = str(e)
        if reason:
            ts.log_error(reason)

    except Exception as e:
        if dataset_filename is not None:
            dataset_filename = dataset_filename + ".csv"
            daq.data_capture(False)
            ds = daq.data_capture_dataset()
            ts.log('Saving file: %s' % dataset_filename)
            ds.to_csv(ts.result_file_path(dataset_filename))
            result_params['plot.title'] = dataset_filename.split('.csv')[0]
            ts.result_file(dataset_filename, params=result_params)
        ts.log_error('Test script exception: %s' % traceback.format_exc())

    finally:
        if daq is not None:
            daq.close()
        if pv is not None:
            pv.close()
        if grid is not None:
            if v_nom is not None:
                grid.voltage(v_nom)
            grid.close()
        if chil is not None:
            chil.close()
        if eut is not None:
            #eut.volt_var(params={'Ena': False})
            eut.close()
        if result_summary is not None:
            result_summary.close()


    return result
예제 #2
0
            timeout = 120.
            if inv_power <= p_rated * 0.85:
                pv.irradiance_set(
                    995)  # Perturb the pv slightly to start the inverter
                ts.sleep(3)
                eut.connect(params={'Conn': True})
            while inv_power <= p_rated * 0.85 and timeout >= 0:
                ts.log(
                    'Inverter power is at %0.1f. Waiting up to %s more seconds or until EUT starts...'
                    % (inv_power, timeout))
                ts.sleep(1)
                timeout -= 1
                inv_power = eut.measurements().get('W')
                if timeout == 0:
                    result = script.RESULT_FAIL
                    raise der.DERError('Inverter did not start.')
            ts.log('Waiting for EUT to ramp up')
            ts.sleep(8)
            ts.log_debug('DAS data_read(): %s' % daq.data_read())
        '''
        c) Set all AC test source parameters to the nominal operating voltage and frequency.
        '''
        grid = gridsim.gridsim_init(
            ts)  # Turn on AC so the EUT can be initialized
        if grid is not None:
            grid.voltage(v_nom)

        # open result summary file
        result_summary_filename = 'result_summary.csv'
        result_summary = open(ts.result_file_path(result_summary_filename),
                              'a+')
def test_run():

    result = script.RESULT_FAIL
    daq = None
    grid = None
    pv = None
    eut = None
    chil = None
    result_summary = None
    dataset_filename = None
    v_nom = None

    try:

        settings_test = ts.param_value('iop.settings_test')
        monitoring_test = ts.param_value('iop.monitoring_test')

        v_nom = float(ts.param_value('eut.v_nom'))
        MSA_V = 0.01 * v_nom
        va_max = float(ts.param_value('eut.s_rated'))
        va_crg_max = va_max
        MSA_Q = 0.05 * float(ts.param_value('eut.s_rated'))
        MSA_P = 0.05 * float(ts.param_value('eut.s_rated'))
        MSA_F = 0.01
        f_nom = float(ts.param_value('eut.f_nom'))
        phases = ts.param_value('eut.phases')
        p_rated = float(ts.param_value('eut.p_rated'))
        w_max = p_rated
        p_min = p_rated
        w_crg_max = p_rated
        var_rated = float(ts.param_value('eut.var_rated'))
        var_max = float(ts.param_value('eut.var_rated'))

        # initialize DER configuration
        eut = der.der_init(ts)
        eut.config()

        das_points = {'sc': ('event')}
        daq = das.das_init(ts, sc_points=das_points['sc'])

        # initialize HIL environment, if necessary
        chil = hil.hil_init(ts)
        if chil is not None:
            chil.config()

        # pv simulator is initialized with test parameters and enabled
        pv = pvsim.pvsim_init(ts)
        if pv is not None:
            pv.power_set(p_rated)
            pv.power_on()  # Turn on DC so the EUT can be initialized

        # grid simulator is initialized with test parameters and enabled
        grid = gridsim.gridsim_init(
            ts)  # Turn on AC so the EUT can be initialized
        if grid is not None:
            grid.voltage(v_nom)

        lib_1547 = p1547.module_1547(ts=ts, aif='Interoperability Tests')
        ts.log_debug("1547.1 Library configured for %s" %
                     lib_1547.get_test_name())
        '''
        6.4 Nameplate data test
        a) Read from the DER each nameplate data item listed in Table 28 in IEEE Std 1547-2018.
        b) Compare each value received to the expected values from the manufacturer-provided expected values.

        Table 28 - Nameplate information
        ________________________________________________________________________________________________________________
        Parameter                                               Description
        ________________________________________________________________________________________________________________
        1. Active power rating at unity power factor            Active power rating in watts at unity power factor
           (nameplate active power rating)
        2. Active power rating at specified over-excited        Active power rating in watts at specified over-excited
           power factor                                         power factor
        3. Specified over-excited power factor                  Over-excited power factor as described in 5.2
        4. Active power rating at specified under-excited       Active power rating in watts at specified under-excited
           power factor                                         power factor
        5. Specified under-excited power factor                 Under-excited power factor as described in 5.2
        6. Apparent power maximum rating                        Maximum apparent power rating in voltamperes
        7. Normal operating performance category                Indication of reactive power and voltage/power control
                                                                capability. (Category A/B as described in 1.4)
        8. Abnormal operating performance category              Indication of voltage and frequency ride-through
                                                                capability Category I, II, or III, as described in 1.4
        9. Reactive power injected maximum rating               Maximum injected reactive power rating in vars
        10. Reactive power absorbed maximum rating              Maximum absorbed reactive power rating in vars
        11. Active power charge maximum rating                  Maximum active power charge rating in watts
        12. Apparent power charge maximum rating                Maximum apparent power charge rating in voltamperes. May
                                                                differ from the apparent power maximum rating
        13. AC voltage nominal rating                           Nominal AC voltage rating in RMS volts
        14. AC voltage maximum rating                           Maximum AC voltage rating in RMS volts
        15. AC voltage minimum rating                           Minimum AC voltage rating in RMS volts
        16. Supported control mode functions                    Indication of support for each control mode function
        17. Reactive susceptance that remains connected to      Reactive susceptance that remains connected to the Area
            the Area EPS in the cease to energize and trip      EPS in the cease to energize and trip state
            state
        18. Manufacturer                                        Manufacturer
        19. Model                                               Model
        20. Serial number                                       Serial number
        21. Version                                             Version
        '''

        ts.log('---')
        der_info = eut.info()
        nameplate = eut.nameplate()

        ts.log('DER Nameplate Information:')
        if nameplate is not None:
            ts.log(
                '  Active power rating at unity power factor (nameplate active power rating) [WRtg]: %s'
                % nameplate.get('WRtg'))
            ts.log(
                '  Active power rating at specified over-excited power factor: %s'
                % 'Unknown')
            ts.log('  Specified over-excited power factor [PFRtgQ1]: %s' %
                   nameplate.get('PFRtgQ1'))
            ts.log('  Specified under-excited power factor [PFRtgQ2]: %s' %
                   nameplate.get('PFRtgQ2'))
            ts.log('  Apparent power maximum rating: %s' %
                   nameplate.get('VARtg'))
            ts.log('  Normal operating performance category: %s' % 'Unknown')
            ts.log('  Abnormal operating performance category: %s' % 'Unknown')
            ts.log('  Reactive power injected maximum rating [VArRtgQ1]: %s' %
                   nameplate.get('VArRtgQ1'))
            ts.log('  Reactive power absorbed maximum rating [VArRtgQ4]: %s' %
                   nameplate.get('VArRtgQ4'))
            ts.log('  Apparent power charge maximum rating: %s' %
                   nameplate.get('MaxChrRte'))
            ts.log('  AC voltage nominal rating: %s' % 'Unknown')
            ts.log('  AC voltage maximum rating: %s' % 'Unknown')
            ts.log('  AC voltage minimum rating: %s' % 'Unknown')
        if der_info is not None:
            ts.log('  Supported control mode functions: %s' %
                   der_info.get('Options'))
        else:
            ts.log_warning('DER info not supported')
        if nameplate is not None:
            ts.log(
                '  Reactive susceptance that remains connected to the Area EPS in the cease to '
                'energize and trip state: %s' % 'Unknown')
        else:
            ts.log_warning('DER nameplate not supported')
        if der_info is not None:
            ts.log('  Manufacturer: %s' % (der_info.get('Manufacturer')))
            ts.log('  Model: %s' % (der_info.get('Model')))
            ts.log('  Serial Number: %s' % (der_info.get('SerialNumber')))
            ts.log('  Version: %s' % (der_info.get('Version')))
        else:
            ts.log_warning('DER info not supported')

        if settings_test:
            '''
            6.5 Basic settings information test

            a) Read from the DER each parameter identified in Table 42.
            b) For each, verify that the value reported matches the behavior of the DER measured though independent test
               equipment separate from the DER interface.
            c) Adjust values as identified in Table 42.
            d) Repeat steps a) and b) for the new values.
            e) Adjust parameters back to the initial values and verify that the value reported matches the initial
               values.

            Table 42 - Basic settings test levels
            ____________________________________________________________________________________________________________
            Parameter                           Adjustment required            Additional test instructions
            ____________________________________________________________________________________________________________
            Active Power Maximum                Set to 80% of Initial Value
            Apparent Power Maximum              Set to 80% of Initial Value
            Reactive Power Injected Maximum     Set to 80% of Initial Value
            Reactive Power Absorbed Maximum     Set to 80% of Initial Value
            Active Power Charge Maximum         Set to 80% of Initial Value     This test applies only to DER that
                                                                                include energy storage.
            Apparent Power Charge Maximum       Set to 80% of Initial Value     This test applies only to DER that
                                                                                include energy storage.
            AC Current Maximum                  Set to 80% of Initial Value
            Control Mode Functions              Not applicable
            Stated Energy Storage Capacity      Set to 80% of Initial Value     This test applies only to DER that
                                                                                include energy storage.
            Mode Enable Interval                Set to 5 s, set to 300 s
            '''

            # Special considerations for CHIL ASGC/Typhoon startup
            if chil is not None:
                inv_power = eut.measurements().get('W')
                timeout = 120.
                if inv_power <= p_rated * 0.85:
                    pv.irradiance_set(
                        995)  # Perturb the pv slightly to start the inverter
                    ts.sleep(3)
                    eut.connect(params={'Conn': True})
                while inv_power <= p_rated * 0.85 and timeout >= 0:
                    ts.log(
                        'Inverter power is at %0.1f. Waiting up to %s more seconds or until EUT starts...'
                        % (inv_power, timeout))
                    ts.sleep(1)
                    timeout -= 1
                    inv_power = eut.measurements().get('W')
                    if timeout == 0:
                        result = script.RESULT_FAIL
                        raise der.DERError('Inverter did not start.')
                ts.log('Waiting for EUT to ramp up')
                ts.sleep(8)
                # ts.log_debug('DAS data_read(): %s' % daq.data_read())

            settings = eut.settings()
            if settings is not None:
                # Active Power Maximum
                ts.log('  Active Power Maximum [WMax]: %s' %
                       (settings.get('WMax')))
                ts.log('  Setting WMax to %f.' % (0.8 * w_max))
                eut.settings(params={'WMax': 0.8 * w_max})
                ts.sleep(2)
                power = lib_1547.get_measurement_total(
                    data=daq.data_capture_read(), type_meas='P', log=True)
                ts.log('  Power was recorded to be: %f.' % power)
                ts.log('  Returning WMax to %f.' % w_max)
                eut.settings(params={'WMax': w_max})

                # Apparent Power Maximum
                ts.log('  Apparent Power Maximum [VAMax]: %s' %
                       (settings.get('VAMax')))
                ts.log('  Setting VAMax to %f.' % (0.8 * va_max))
                eut.settings(params={'VAMax': 0.8 * va_max})
                ts.sleep(2)
                va = lib_1547.get_measurement_total(
                    data=daq.data_capture_read(), type_meas='VA', log=True)
                ts.log('  Apparent Power was recorded to be: %f.' % va)
                ts.log('  Returning VAMax to %f.' % va_max)
                eut.settings(params={'VAMax': va_max})

                # Reactive Power Injected Maximum
                # TODO check on sign convention here
                ts.log('  Reactive Power Injected Maximum [VArMaxQ1]: %s' %
                       (settings.get('VArMaxQ1')))
                ts.log('  Setting VArMaxQ1 to %f.' % (0.8 * var_max))
                eut.settings(params={'VArMaxQ1': 0.8 * var_max})
                eut.reactive_power(params={
                    'Ena': True,
                    'VArPct_Mod': 'VArMax',
                    'VArMaxPct': 100
                })
                ts.sleep(2)
                q = lib_1547.get_measurement_total(
                    data=daq.data_capture_read(), type_meas='Q', log=True)
                ts.log('  Reactive Power Injected was recorded to be: %f.' % q)
                ts.log('  Returning VArMaxQ1 to %f.' % var_max)
                eut.settings(params={'VArMaxQ1': var_max})
                eut.reactive_power(params={'Ena': False})

                # Reactive Power Absorbed Maximum
                ts.log('  Reactive Power Absorbed Maximum [VArMaxQ4]: %s' %
                       (settings.get('VArMaxQ4')))
                ts.log('  Setting VArMaxQ4 to %f.' % (0.8 * var_max))
                eut.settings(params={'VArMaxQ4': 0.8 * var_max})
                eut.reactive_power(params={
                    'Ena': True,
                    'VArPct_Mod': 'VArMax',
                    'VArMaxPct': -100
                })
                ts.sleep(2)
                q = lib_1547.get_measurement_total(
                    data=daq.data_capture_read(), type_meas='Q', log=True)
                ts.log('  Reactive Power Absorbed was recorded to be: %f.' % q)
                ts.log('  Returning VArMaxQ4 to %f.' % var_max)
                eut.settings(params={'VArMaxQ4': var_max})
                eut.reactive_power(params={'Ena': False})

                # AC Current Maximum
                ts.log('  Apparent Power Maximum [VAMax]: %s' %
                       (settings.get('VAMax')))
                ts.log('  Setting VAMax to %f.' % (0.8 * va_max))
                eut.settings(params={'VAMax': 0.8 * va_max})
                ts.sleep(2)
                va = lib_1547.get_measurement_total(
                    data=daq.data_capture_read(), type_meas='VA', log=True)
                ts.log('  Apparent Power was recorded to be: %f.' % va)
                ts.log('  Returning VAMax to %f.' % va_max)
                eut.settings(params={'VAMax': va_max})

                # Mode Enable Interval
                # TODO add this assessment  {'ModeInterval': [5, 300]}

            else:
                ts.log_warning('DER settings not supported')

            storage = eut.storage()
            if storage is not None:
                # Active Power Charge Maximum
                ts.log('  Active Power Charge Maximum [WChaMax]: %s' %
                       (storage.get('WChaMax')))
                ts.log('  Setting WChaMax to %f.' % (0.8 * w_crg_max))
                eut.storage(params={'WChaMax': 0.8 * w_crg_max})
                ts.log('  Setting InWRte to %f %% of max charging rate.' %
                       100.)  # Percent of max charging rate.
                eut.storage(params={'InWRte': 100.})
                ts.sleep(2)
                power = lib_1547.get_measurement_total(
                    data=daq.data_capture_read(), type_meas='P', log=True)
                ts.log('  Apparent Power was recorded to be: %f.' % power)
                ts.log('  Returning WChaMax to %f.' % w_crg_max)
                eut.storage(params={'WChaMax': w_crg_max})
                eut.storage(params={'InWRte': 0.})

                # Apparent Power Charge Maximum
                ts.log('  Apparent Power Charge Maximum [VAChaMax]: %s' %
                       (storage.get('VAChaMax')))
                ts.log('  Setting WChaMax to %f.' % (0.8 * va_crg_max))
                eut.storage(params={'VAChaMax': 0.8 * va_crg_max})
                ts.log('  Setting InWRte to %f %% of max charging rate.' %
                       100.)  # Percent of max charging rate.
                eut.storage(params={'InWRte': 100.})
                ts.sleep(2)
                power = lib_1547.get_measurement_total(
                    data=daq.data_capture_read(), type_meas='VA', log=True)
                ts.log('  Apparent Power was recorded to be: %f.' % power)
                ts.log('  Returning VAChaMax to %f.' % va_crg_max)
                eut.storage(params={'VAChaMax': va_crg_max})
                eut.storage(params={'InWRte': 0.})

                # Stated Energy Storage Capacity
                # StorAval = State of charge (ChaState) minus storage reserve (MinRsvPct) times capacity rating (AhrRtg)
                # TODO add this assessment

            else:
                ts.log_warning('DER storage not supported')

        if monitoring_test:
            '''
            6.6 Monitoring information test

            a) Set the operating conditions of the DER to the values specified in the "Operating Point A" column in
               Table 43.
            b) Wait not less than 30 s, then read from the DER each monitoring information, and verify that the
               reported values match the operating conditions as identified.
            c) Change the operating conditions of the DER as specified in the "Operating Point B" column 16 in Table 43.
            d) Repeat step b).
            '''

            # Monitoring information parameter: Active Power
            # Operating Point A: 0 to 10% of DER "active power rating at unity power factor"
            # Operating Point B: 90 to 100% of DER "active power rating at unity power factor"
            # Pass/Fail Criteria: Reported values match test operating conditions within the accuracy requirements
            # specified in Table 3 in IEEE Std 1547-2018. (+/- 5% Srated)
            m = eut.measurements()
            if m is not None:
                ts.log('  Active Power reported from the EUT is: %s W' %
                       (m.get('W')))
                for setpoint in [5, 100]:
                    eut.limit_max_power(params={
                        'Ena': True,
                        'WMaxPct': setpoint
                    })  # curtial to 5% of power
                    inaccurate_measurement = True
                    while inaccurate_measurement:
                        power_pct = 100 * (eut.measurements().get('W') / w_max)
                        ts.log('    EUT power is currently %f%% Prated' %
                               power_pct)
                        if setpoint - 5. <= power_pct <= setpoint + 5.:  # +/- 5% Srated
                            ts.log(
                                'EUT has recorded power +/- 5%% Srated, as required by IEEE 1547-2018.'
                            )
                            ts.log('Returning EUT to rated power.')
                            inaccurate_measurement = False
                        ts.sleep(1)
                    eut.limit_max_power(params={'Ena': False})
            else:
                ts.log_warning('DER measurements not supported')
            ts.log('---')

            # Monitoring information parameter: Reactive Power
            # Operating Point A: 90 to 100% of DER "reactive power injected maximum rating"
            # Operating Point B: 90 to 100% of DER "reactive power absorbed maximum rating"
            # Pass/Fail Criteria: Reported values match test operating conditions within the accuracy requirements
            # specified in Table 3 in IEEE Std 1547-2018. (+/- 5% Srated)
            m = eut.measurements()
            if m is not None:
                ts.log('  Reactive Power reported from the EUT is: %f VAr' %
                       (m.get('VAr')))
                for setpoint in [5, 100]:
                    eut.reactive_power(params={
                        'Ena': True,
                        'VArPct_Mod': 'VArMax',
                        'VArMaxPct': 100
                    })
                    inaccurate_measurement = True
                    while inaccurate_measurement:
                        q_pct = 100 * (eut.measurements().get('VAr') / var_max)
                        ts.log(
                            '    EUT reactive power is currently %f%% Qrated' %
                            q_pct)
                        if setpoint - 5. <= q_pct <= setpoint + 5.:  # +/- 5% Srated
                            ts.log(
                                'EUT has recorded reactive power +/- 5%% Srated, as required by IEEE 1547-2018.'
                            )
                            ts.log('Returning EUT to rated power.')
                            inaccurate_measurement = False
                        ts.sleep(1)
                    eut.reactive_power(params={'Ena': False})
            else:
                ts.log_warning('DER measurements not supported')
            ts.log('---')

            # Monitoring information parameter: Voltage
            # Operating Point A: At or below 0.90x(AC voltage nominal rating)
            # Operating Point B: At or above 1.08x(AC voltage nominal rating)
            # Pass/Fail Criteria: Reported values match test operating conditions within the accuracy requirements
            # specified in Table 3 in IEEE Std 1547-2018. (+/-1% Vnom)

            for setpoint in [90, 108]:
                grid.voltage(setpoint)

                inaccurate_measurement = True
                while inaccurate_measurement:

                    voltages = []
                    if self.phases == 'Single phase':
                        voltages.append(eut.measurements()['PhVphA'])
                    elif self.phases == 'Split phase':
                        voltages.append(eut.measurements()['PhVphA'])
                        voltages.append(eut.measurements()['PhVphB'])
                    elif self.phases == 'Three phase':
                        voltages.append(eut.measurements()['PhVphB'] / v_nom)
                        voltages.append(eut.measurements()['PhVphB'] / v_nom)
                        voltages.append(eut.measurements()['PhVphC'] / v_nom)
                        # TODO: also check phase to phase voltages
                        voltages.append(eut.measurements()['PPVphAB'] /
                                        (v_nom * math.sqrt(3)))
                        voltages.append(eut.measurements()['PPVphBC'] /
                                        (v_nom * math.sqrt(3)))
                        voltages.append(eut.measurements()['PPVphCA'] /
                                        (v_nom * math.sqrt(3)))

                    ts.log('    EUT voltages are currently %s pu' % voltages)
                    pass_criteria = []
                    for voltage in voltages:
                        if setpoint / 100. - 0.01 <= voltage <= setpoint / 100. + 0.01:  # +/- 1% Vnom
                            pass_criteria.append(True)
                        else:
                            pass_criteria.append(True)

                    if all(pass_criteria):
                        ts.log(
                            'EUT has recorded voltage +/- 1%% Vnom, as required by IEEE 1547-2018.'
                        )
                        ts.log('Returning EUT to rated power.')
                        inaccurate_measurement = False
                    ts.sleep(1)

            grid.voltage(v_nom)

            # Monitoring information parameter: Frequency
            # Operating Point A: At or below 57.2Hz
            # Operating Point B: At or above 61.6Hz
            # Pass/Fail Criteria: Reported values match test operating conditions within the accuracy requirements
            # specified in Table 3 in IEEE Std 1547-2018. (10 mHz)

            # Monitoring information parameter: Operational State
            # Operating Point A: On
            # Operating Point B: Off
            # Pass/Fail Criteria: Reported Operational State matches the device present condition for on and off states.

            # Monitoring information parameter: Connection Status
            # Operating Point A: Connected: Enable Permit and AC conditions have been met to enter service as specified
            # in Table 39 of IEEE Std 1547-2018
            # Operating Point B: Disconnected: Permit service is disabled
            # Pass/Fail Criteria: Reported Connection Status matches the device present connection condition.
            status = eut.controls_status()
            if status is not None:
                ts.log('    Is Fixed_W enabled?: %s' % (status.get('Fixed_W')))
                ts.log('    Is Fixed_Var enabled?: %s' %
                       (status.get('Fixed_Var')))
                ts.log('    Is Fixed_PF enabled?: %s' %
                       (status.get('Fixed_PF')))
                ts.log('    Is Volt_Var enabled?: %s' %
                       (status.get('Volt_Var')))
                ts.log('    Is Freq_Watt_Param enabled?: %s' %
                       (status.get('Freq_Watt_Param')))
                ts.log('    Is Freq_Watt_Curve enabled?: %s' %
                       (status.get('Freq_Watt_Curve')))
                ts.log('    Is Dyn_Reactive_Power enabled?: %s' %
                       (status.get('Dyn_Reactive_Power')))
                ts.log('    Is LVRT enabled?: %s' % (status.get('LVRT')))
                ts.log('    Is HVRT enabled?: %s' % (status.get('HVRT')))
                ts.log('    Is Watt_PF enabled?: %s' % (status.get('Watt_PF')))
                ts.log('    Is Volt_Watt enabled?: %s' %
                       (status.get('Volt_Watt')))
                ts.log('    Is Scheduled enabled?: %s' %
                       (status.get('Scheduled')))
                ts.log('    Is LFRT enabled?: %s' % (status.get('LFRT')))
                ts.log('    Is HFRT enabled?: %s' % (status.get('HFRT')))

                ts.log('---')
                status = eut.conn_status()
                ts.log('    Is PV_Connected?: %s' %
                       (status.get('PV_Connected')))
                ts.log('    Is PV_Available?: %s' %
                       (status.get('PV_Available')))
                ts.log('    Is PV_Operating?: %s' %
                       (status.get('PV_Operating')))
                ts.log('    Is PV_Test?: %s' % (status.get('PV_Test')))
                ts.log('    Is Storage_Connected?: %s' %
                       (status.get('Storage_Connected')))
                ts.log('    Is Storage_Available?: %s' %
                       (status.get('Storage_Available')))
                ts.log('    Is Storage_Operating?: %s' %
                       (status.get('Storage_Operating')))
                ts.log('    Is Storage_Test?: %s' %
                       (status.get('Storage_Test')))
                ts.log('    Is EPC_Connected?: %s' %
                       (status.get('EPC_Connected')))
                ts.log('---')

            # Monitoring information parameter: Alarm Status
            # Operating Point A: Has alarms set
            # Operating Point B: No alarms set
            # Pass/Fail Criteria: Reported Alarm Status matches the device present alarm condition for alarm and no
            # alarm conditions. The DER manufacturer shall specify at least one way an alarm condition which is
            # supported in the protocol being tested can be set and cleared.

        return script.RESULT_COMPLETE

    except script.ScriptFail, e:
        reason = str(e)
        if reason:
            ts.log_error(reason)
예제 #4
0
def test_run():
    eut = None
    chil = None
    grid = None
    pv = None

    try:

        # Initialize DER configuration
        eut = der.der_init(ts)
        eut.config()

        # Initialize CHIL environment, if necessary
        chil = hil.hil_init(ts)
        if chil is not None:
            chil.config()

        # PV simulator is initialized with test parameters and enabled
        pv = pvsim.pvsim_init(ts)
        pv.irradiance_set(1000)
        pv.power_on()

        # grid simulator is initialized with test parameters and enabled
        grid = gridsim.gridsim_init(ts)

        # Get EUT nameplate power
        eut_nameplate_power = eut.nameplate().get('WRtg')

        inv_power = eut.measurements().get('W')
        timeout = 20.
        if inv_power <= eut_nameplate_power / 10.:
            eut.connect(params={'Conn': True})
            pv.irradiance_set(995)  # Perturb the pv slightly to start the inverter
        while inv_power <= eut_nameplate_power / 10. and timeout >= 0:
            ts.log('Inverter power is at %0.1f. Waiting %s more seconds or until EUT starts...' % (inv_power, timeout))
            ts.sleep(1)
            timeout -= 1
            inv_power = eut.measurements().get('W')
            if timeout == 0:
                result = script.RESULT_FAIL
                raise der.DERError('Inverter did not start.')

        fw_mode = 'Pointwise'
        if fw_mode == 'Parameters':
            eut.freq_watt_param(params={'HysEna': False, 'HzStr': 50.2,
                                        'HzStop': 51.5, 'WGra': 140.})
        else:  # Pointwise
            eut.freq_watt(params={'ActCrv': 1})
            f_points = [50, 50.2, 51.5, 53]
            p_points = [100, 100, 0, 0]
            parameters = {'hz': f_points, 'w': p_points}
            # ts.log_debug(parameters)
            eut.freq_watt_curve(id=1, params=parameters)
            eut.freq_watt(params={'Ena': True})
            ts.log_debug(eut.freq_watt())

        # Create list of frequencies to iterate over
        freq_values = list(np.linspace(49.5, 53, num=50))
        sleep_time = 1.0
        for freq in freq_values:
            grid.freq(freq)  # set grid frequency
            ts.log('      f = %0.3f Hz. Sleeping for %0.2f seconds...' % (freq, sleep_time))
            ts.sleep(sleep_time)

        # Disable the FW function
        eut.freq_watt(params={'Ena': False})
        ts.log('FW Disabled')

        result = script.RESULT_COMPLETE

    except Exception, e:
        ts.log_error('Script failure: %s' % e)
예제 #5
0
def watt_var_mode(wv_curves, wv_response_time, pwr_lvls):

    result = script.RESULT_FAIL
    daq = None
    v_nom = None
    grid = None
    pv = None
    eut = None
    chil = None
    result_summary = None
    dataset_filename = None

    try:
        cat = ts.param_value('eut.cat')
        cat2 = ts.param_value('eut.cat2')
        sink_power = ts.param_value('eut.sink_power')
        p_rated = ts.param_value('eut.p_rated')
        p_rated_prime = ts.param_value('eut.p_rated_prime')
        var_rated = ts.param_value('eut.var_rated')
        s_rated = ts.param_value('eut.s_rated')

        # DC voltages
        v_in_nom = ts.param_value('eut.v_in_nom')
        #v_min_in = ts.param_value('eut.v_in_min')
        #v_max_in = ts.param_value('eut.v_in_max')

        # AC voltages
        v_nom = ts.param_value('eut.v_nom')
        v_low = ts.param_value('eut.v_low')
        v_high = ts.param_value('eut.v_high')
        p_min = ts.param_value('eut.p_min')
        p_min_prime = ts.param_value('eut.p_min_prime')
        phases = ts.param_value('eut.phases')

        # EUI Absorb capabilities
        absorb = {}
        absorb['ena'] = ts.param_value('eut_cpf.sink_power')

        """
        A separate module has been create for the 1547.1 Standard
        """
        #lib_1547 = p1547.module_1547(ts=ts, aif='WV', criteria)
        ActiveFunction = p1547.ActiveFunction(ts=ts,
                                              functions=[WV],
                                              script_name='Watt-Var',
                                              criteria_mode=[True, True, True])
        ts.log_debug("1547.1 Library configured for %s" % ActiveFunction.get_script_name())

        # result params
        result_params = ActiveFunction.get_rslt_param_plot()

        '''
        a) Connect the EUT according to the instructions and specifications provided by the manufacturer.
        '''

        # initialize HIL environment, if necessary
        chil = hil.hil_init(ts)
        if chil is not None:
            chil.config()

        # pv simulator is initialized with test parameters and enabled
        pv = pvsim.pvsim_init(ts)
        if pv is not None:
            pv.power_set(p_rated)
            pv.power_on()  # Turn on DC so the EUT can be initialized

        # DAS soft channels
        das_points = ActiveFunction.get_sc_points()

        # initialize data acquisition system
        daq = das.das_init(ts, sc_points=das_points['sc'])

        ts.log_debug(0.05 * ts.param_value('eut.s_rated'))
        daq.sc['P_TARGET'] = v_nom
        daq.sc['Q_TARGET'] = 100
        daq.sc['Q_TARGET_MIN'] = 100
        daq.sc['Q_TARGET_MAX'] = 100
        daq.sc['event'] = 'None'

        ts.log('DAS device: %s' % daq.info())

        '''
        b) Set all voltage trip parameters to the widest range of adjustability.  Disable all reactive/active power
        control functions.
        '''

        eut = der.der_init(ts)
        if eut is not None:
            eut.config()
            ts.log_debug(eut.measurements())

            #Disable all functions on EUT
            eut.deactivate_all_fct()

            ts.log_debug('Voltage trip parameters set to the widest range: v_min: {0} V, '
                         'v_max: {1} V'.format(v_low, v_high))
            try:
                eut.vrt_stay_connected_high(params={'Ena': True, 'ActCrv': 0, 'Tms1': 3000,
                                                    'V1': v_high, 'Tms2': 0.16, 'V2': v_high})
            except Exception as e:
                ts.log_error('Could not set VRT Stay Connected High curve. %s' % e)
            try:
                eut.vrt_stay_connected_low(params={'Ena': True, 'ActCrv': 0, 'Tms1': 3000,
                                                   'V1': v_low, 'Tms2': 0.16, 'V2': v_low})
            except Exception as e:
                ts.log_error('Could not set VRT Stay Connected Low curve. %s' % e)
        else:
            ts.log_debug('Set L/HVRT and trip parameters set to the widest range of adjustability possible.')

        # Special considerations for CHIL ASGC/Typhoon startup
        if chil is not None:
            inv_power = eut.measurements().get('W')
            timeout = 120.
            if inv_power <= p_rated * 0.85:
                pv.irradiance_set(995)  # Perturb the pv slightly to start the inverter
                ts.sleep(3)
                eut.connect(params={'Conn': True})
            while inv_power <= p_rated * 0.85 and timeout >= 0:
                ts.log('Inverter power is at %0.1f. Waiting up to %s more seconds or until EUT starts...' %
                       (inv_power, timeout))
                ts.sleep(1)
                timeout -= 1
                inv_power = eut.measurements().get('W')
                if timeout == 0:
                    result = script.RESULT_FAIL
                    raise der.DERError('Inverter did not start.')
            ts.log('Waiting for EUT to ramp up')
            ts.sleep(8)
            ts.log_debug('DAS data_read(): %s' % daq.data_read())

        '''
        c) Set all AC test source parameters to the nominal operating voltage and frequency.
        '''
        grid = gridsim.gridsim_init(ts, support_interfaces={'hil': chil})  # Turn on AC so the EUT can be initialized
        if grid is not None:
            grid.voltage(v_nom)

        # open result summary file
        result_summary_filename = 'result_summary.csv'
        result_summary = open(ts.result_file_path(result_summary_filename), 'a+')
        ts.result_file(result_summary_filename)
        result_summary.write(ActiveFunction.get_rslt_sum_col_name())

        '''
        d) Adjust the EUT's available active power to Prated. For an EUT with an input voltage range, set the input
        voltage to Vin_nom. The EUT may limit active power throughout the test to meet reactive power requirements.
        For an EUT with an input voltage range.
        '''

        if pv is not None:
            pv.iv_curve_config(pmp=p_rated, vmp=v_in_nom)
            pv.irradiance_set(1000.)

        '''
        dd) Repeat steps e) through dd) for characteristics 2 and 3.
        '''

        #TODO 1.Add absorb option possibility for EUT
        #TODO 2.Add communication with EUT

        for wv_curve in wv_curves:
            ts.log('Starting test with characteristic curve %s' % (wv_curve))
            ActiveFunction.reset_curve(wv_curve)
            ActiveFunction.reset_time_settings(tr=wv_response_time[wv_curve], number_tr=2)
            p_pairs = ActiveFunction.get_params(function=WV, curve=wv_curve)
            '''
            d2) Set EUT volt-var parameters to the values specified by Characteristic 1.
            All other function should be turned off. Turn off the autonomously adjusting reference voltage.
            '''
            if eut is not None:
                # Activate watt-var function with following parameters
                # SunSpec convention is to use percentages for P and Q points.
                wv_curve_params = {'w': [p_pairs['P0']*(100/p_rated),
                                         p_pairs['P1']*(100/p_rated),
                                         p_pairs['P2']*(100/p_rated),
                                         p_pairs['P3']*(100/p_rated)],
                                   'var': [p_pairs['Q0']*(100/var_rated),
                                           p_pairs['Q1']*(100/var_rated),
                                           p_pairs['Q2']*(100/var_rated),
                                           p_pairs['Q3']*(100/var_rated)]}
                ts.log_debug('Sending WV points: %s' % wv_curve_params)
                eut.watt_var(params={'Ena': True, 'curve': wv_curve_params})


                '''
                e) Verify volt-var mode is reported as active and that the correct characteristic is reported.
                '''
                ts.log_debug('Initial EUT VV settings are %s' % eut.watt_var())

            '''
            cc) Repeat test steps d) through cc) at EUT power set at 20% and 66% of rated power.
            '''
            for power in pwr_lvls:
                ActiveFunction.reset_pwr(pwr=power)
                if pv is not None:
                    pv_power_setting = (p_rated * power)
                    pv.iv_curve_config(pmp=pv_power_setting, vmp=v_in_nom)
                    pv.irradiance_set(1000.)

                # Special considerations for CHIL ASGC/Typhoon startup #
                if chil is not None:
                    inv_power = eut.measurements().get('W')
                    timeout = 120.
                    if inv_power <= pv_power_setting * 0.85:
                        pv.irradiance_set(995)  # Perturb the pv slightly to start the inverter
                        ts.sleep(3)
                        eut.connect(params={'Conn': True})
                    while inv_power <= pv_power_setting * 0.85 and timeout >= 0:
                        ts.log('Inverter power is at %0.1f. Waiting up to %s more seconds or until EUT starts...' %
                               (inv_power, timeout))
                        ts.sleep(1)
                        timeout -= 1
                        inv_power = eut.measurements().get('W')
                        if timeout == 0:
                            result = script.RESULT_FAIL
                            raise der.DERError('Inverter did not start.')
                    ts.log('Waiting for EUT to ramp up')
                    ts.sleep(8)

                #Create Watt-Var Dictionary
                p_steps_dict = ActiveFunction.create_wv_dict_steps()

                filename = 'WV_%s_PWR_%d' % (wv_curve, power * 100)
                ActiveFunction.reset_filename(filename=filename)
                ts.log('------------{}------------'.format(dataset_filename))

                # Start the data acquisition systems
                daq.data_capture(True)

                for step_label, p_step in p_steps_dict.items():
                    ts.log('Power step: setting Grid power to %s (W)(%s)' % (p_step, step_label))
                    ActiveFunction.start(daq=daq, step_label=step_label)
                    step_dict = {'V': v_nom, 'P': p_step}
                    if pv is not None:
                        pv.power_set(step_dict['P'])

                    ActiveFunction.record_timeresponse(daq=daq)
                    ActiveFunction.evaluate_criterias(daq=daq, step_dict=step_dict)
                    result_summary.write(ActiveFunction.write_rslt_sum())

                ts.log('Sampling complete')
                dataset_filename = filename + ".csv"
                daq.data_capture(False)
                ds = daq.data_capture_dataset()
                ts.log('Saving file: %s' % dataset_filename)
                ds.to_csv(ts.result_file_path(dataset_filename))
                result_params['plot.title'] = dataset_filename.split('.csv')[0]
                ts.result_file(dataset_filename, params=result_params)
                result = script.RESULT_COMPLETE

    except script.ScriptFail as e:
        reason = str(e)
        if reason:
            ts.log_error(reason)

    except Exception as e:
        if dataset_filename is not None:
            dataset_filename = dataset_filename + ".csv"
            daq.data_capture(False)
            ds = daq.data_capture_dataset()
            ts.log('Saving file: %s' % dataset_filename)
            ds.to_csv(ts.result_file_path(dataset_filename))
            result_params['plot.title'] = dataset_filename.split('.csv')[0]
            ts.result_file(dataset_filename, params=result_params)
        ts.log_error('Test script exception: %s' % traceback.format_exc())

    finally:
        if daq is not None:
            daq.close()
        if pv is not None:
            pv.power_set(p_rated)
            pv.close()
        if grid is not None:
            if v_nom is not None:
                grid.voltage(v_nom)
            grid.close()
        if chil is not None:
            chil.close()
        if eut is not None:
            eut.deactivate_all_fct()
            eut.close()
        if result_summary is not None:
            result_summary.close()

    return result
예제 #6
0
def test_run():

    eut = None
    chil = None
    daq = None
    pv = None
    result_summary = None
    result = script.RESULT_FAIL

    # result params
    result_params = {
        'plot.title': ts.name,
        'plot.x.title': 'Time (sec)',
        'plot.x.points': 'TIME',
        'plot.y.points': 'W_TARG, W_TOTAL, W_INV',
        'plot.y.title': 'EUT Power (W)',
    }

    try:
        # Initialize DER configuration
        eut = der.der_init(ts)
        eut.config()

        # Initialize CHIL environment, if necessary
        chil = hil.hil_init(ts)
        if chil is not None:
            chil.config()

        # PV simulator is initialized with test parameters and enabled
        pv = pvsim.pvsim_init(ts)
        pv.irradiance_set(1000)
        pv.power_on()

        # Initialize data acquisition with soft channels (sc) that include data that doesn't come from the DAQ
        sc_points = ['W_TARG', 'W_TOTAL', 'W_INV']
        daq = das.das_init(ts, sc_points=sc_points)
        ts.log('DAS device: %s' % daq.info())

        # Open result summary file - this will include a selection of DAQ data to evaluate performance of the EUT
        result_summary_filename = 'result_summary.csv'
        result_summary = open(ts.result_file_path(result_summary_filename),
                              'a+')  # Open .csv file
        ts.result_file(
            result_summary_filename)  # create result file in the GUI
        # Write result summary header
        result_summary.write(
            'Test Name, Power Setting (%), Inverter-Reported Power (W), DAS Power (W), '
            'Inverter-Reported Power (%), DAS Power (%)\n')

        # Get EUT nameplate power
        eut_nameplate_power = eut.nameplate().get('WRtg')

        inv_power = eut.measurements().get('W')
        timeout = 20.
        if inv_power <= eut_nameplate_power / 10.:
            eut.connect(params={'Conn': True})
            pv.irradiance_set(
                995)  # Perturb the pv slightly to start the inverter
        while inv_power <= eut_nameplate_power / 10. and timeout >= 0:
            ts.log(
                'Inverter power is at %0.1f. Waiting %s more seconds or until EUT starts...'
                % (inv_power, timeout))
            ts.sleep(1)
            timeout -= 1
            inv_power = eut.measurements().get('W')
            if timeout == 0:
                result = script.RESULT_FAIL
                raise der.DERError('Inverter did not start.')

        for time_loop in range(2):
            daq.data_capture(True)  # Begin data capture for this power loop

            for power_limit_pct in [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]:
                daq.sc['W_TARG'] = eut_nameplate_power * (
                    float(power_limit_pct) / 100.)
                eut.limit_max_power(params={
                    'Ena': True,
                    'WMaxPct': power_limit_pct
                })
                ts.log('EUT power set to %0.2f%%' % power_limit_pct)
                ts.sleep(2)
                daq.sc['W_INV'] = eut.measurements().get(
                    'W')  # Get the inverter-measured power and save it.
                daq.data_sample(
                )  # force a data capture point after the sleep and add this to the dataset
                daq_data = daq.data_capture_read(
                )  # read the last data point dictionary from the daq object
                try:  # if 3 phase device add up the power from each phase
                    daq.sc['W_TOTAL'] = daq_data['AC_P_1'] + daq_data[
                        'AC_P_2'] + daq_data['AC_P_2']
                except Exception, e:  # if single phase device
                    daq.sc['W_TOTAL'] = daq_data['AC_P_1']
                # Record 1 set of power values for each power level setting
                result_summary.write(
                    '%s, %s, %s, %s, %s, %s\n' %
                    (time_loop + 1, power_limit_pct, daq.sc['W_INV'],
                     daq.sc['W_TOTAL'], daq.sc['W_INV'] / eut_nameplate_power,
                     daq.sc['W_TOTAL'] / eut_nameplate_power))

            daq.data_capture(False)  # Stop data capture
            ds = daq.data_capture_dataset(
            )  # generate dataset from the daq data that was recorded
            testname = 'CurtailmentRun_%s' % (str(time_loop + 1)
                                              )  # Pick name for the DAS data
            filename = testname + '.csv'  # Pick name for the DAS .csv data file
            ds.to_csv(
                ts.result_file_path(filename))  # Convert data to .cvs file
            result_params[
                'plot.title'] = testname  # update title for the excel plot for this dataset
            ts.result_file(
                filename, params=result_params
            )  # Add results info to .xml log, which will be used to plot
            ts.log('Saving data capture: %s' % filename)

        result = script.RESULT_COMPLETE
예제 #7
0
def volt_watt_mode(vw_curves, vw_response_time, pwr_lvls):

    result = script.RESULT_FAIL
    daq = None
    data = None
    p_rated = None
    v_nom = None
    grid = None
    pv = None
    eut = None
    chil = None
    result_summary = None
    dataset_filename = None

    try:

        p_rated = ts.param_value('eut.p_rated')
        s_rated = ts.param_value('eut.s_rated')

        # DC voltages
        v_in_nom = ts.param_value('eut.v_in_nom')
        v_min_in = ts.param_value('eut.v_in_min')
        v_max_in = ts.param_value('eut.v_in_max')

        # AC voltages
        v_nom = ts.param_value('eut.v_nom')
        v_min = ts.param_value('eut.v_low')
        v_max = ts.param_value('eut.v_high')
        p_min = ts.param_value('eut.p_min')
        phases = ts.param_value('eut.phases')

        # EUI Absorb capabilities
        absorb = {}
        absorb['ena'] = ts.param_value('eut_vw.sink_power')
        absorb['p_rated_prime'] = ts.param_value('eut_vw.p_rated_prime')
        absorb['p_min_prime'] = ts.param_value('eut_vw.p_min_prime')
        """
        Version validation
        """
        p1547.VersionValidation(script_version=ts.info.version)
        """
        A separate module has been create for the 1547.1 Standard
        """
        ActiveFunction = p1547.ActiveFunction(ts=ts,
                                              functions=[VW],
                                              script_name='Volt-Watt',
                                              criteria_mode=[True, True, True])
        ts.log_debug("1547.1 Library configured for %s" %
                     ActiveFunction.get_script_name())

        # result params
        result_params = ActiveFunction.get_rslt_param_plot()
        '''
        a) Connect the EUT according to the instructions and specifications provided by the manufacturer.
        '''
        ts.log_debug(15 * "*" + "HIL initialization" + 15 * "*")

        # initialize HIL environment, if necessary
        chil = hil.hil_init(ts)
        if chil is not None:
            chil.config()
        ts.log_debug(15 * "*" + "PVSIM initialization" + 15 * "*")

        # pv simulator is initialized with test parameters and enabled
        pv = pvsim.pvsim_init(ts)
        if pv is not None:
            pv.power_set(p_rated)
            pv.power_on()  # Turn on DC so the EUT can be initialized

        ts.log_debug(15 * "*" + "DAS initialization" + 15 * "*")

        # DAS soft channels
        #das_points = {'sc': ('P_TARGET', 'P_TARGET_MIN', 'P_TARGET_MAX', 'P_MEAS', 'V_TARGET','V_MEAS','event')}
        das_points = ActiveFunction.get_sc_points()

        # initialize data acquisition system
        das_points = ActiveFunction.get_sc_points()
        daq = das.das_init(ts,
                           sc_points=das_points['sc'],
                           support_interfaces={'hil': chil})
        if daq is not None:
            daq.sc['P_TARGET'] = p_rated
            daq.sc['P_TARGET_MIN'] = 100
            daq.sc['P_TARGET_MAX'] = 100
            daq.sc['V_TARGET'] = v_nom
            daq.sc['event'] = 'None'
            ts.log('DAS device: %s' % daq.info())
        '''
        b) Set all voltage trip parameters to the widest range of adjustability. Disable all reactive/active power
        control functions.
        '''
        ts.log_debug(15 * "*" + "EUT initialization" + 15 * "*")

        eut = der.der_init(ts, support_interfaces={'hil': chil})
        if eut is not None:
            eut.config()
            #Disable all functions on EUT
            eut.deactivate_all_fct()
            ts.log_debug(eut.measurements())
            ts.log_debug(
                'L/HVRT and trip parameters set to the widest range : v_min: {0} V, v_max: {1} V'
                .format(v_min, v_max))
            try:
                eut.vrt_stay_connected_high(
                    params={
                        'Ena': True,
                        'ActCrv': 0,
                        'Tms1': 3000,
                        'V1': v_max,
                        'Tms2': 0.16,
                        'V2': v_max
                    })
            except Exception as e:
                ts.log_error(
                    'Could not set VRT Stay Connected High curve. %s' % e)
            try:
                eut.vrt_stay_connected_low(
                    params={
                        'Ena': True,
                        'ActCrv': 0,
                        'Tms1': 3000,
                        'V1': v_min,
                        'Tms2': 0.16,
                        'V2': v_min
                    })
            except Exception as e:
                ts.log_error('Could not set VRT Stay Connected Low curve. %s' %
                             e)
        else:
            ts.log_debug(
                'Set L/HVRT and trip parameters set to the widest range of adjustability possible.'
            )
        '''
        c) Set all AC test source parameters to the nominal operating voltage and frequency.
        '''
        ts.log_debug(15 * "*" + "GRIDSIM initialization" + 15 * "*")

        # grid simulator is initialized with test parameters and enabled
        grid = gridsim.gridsim_init(ts, support_interfaces={
            'hil': chil
        })  # Turn on AC so the EUT can be initialized
        if grid is not None:
            grid.voltage(v_nom)

        # open result summary file
        result_summary_filename = 'result_summary.csv'
        result_summary = open(ts.result_file_path(result_summary_filename),
                              'a+')
        ts.result_file(result_summary_filename)
        result_summary.write(ActiveFunction.get_rslt_sum_col_name())
        '''
        v) Test may be repeated for EUT's that can also absorb power using the P' values in the characteristic
        definition.
        '''
        # TODO: add P' tests (Like CPF -> for absorb_power in absorb_powers:)
        '''
        u) Repeat steps d) through u) for characteristics 2 and 3.
        '''
        for vw_curve in vw_curves:
            ts.log('Starting test with characteristic curve %s' % (vw_curve))
            ActiveFunction.reset_curve(vw_curve)
            ActiveFunction.reset_time_settings(tr=vw_response_time[vw_curve],
                                               number_tr=2)
            v_pairs = ActiveFunction.get_params(curve=vw_curve, function=VW)
            '''
            t) Repeat steps d) through t) at EUT power set at 20% and 66% of rated power.
            '''
            for power in pwr_lvls:
                ActiveFunction.reset_pwr(pwr=power)
                '''
                d) Adjust the EUT's available active power to Prated. For an EUT with an input voltage range, set the input
                voltage to Vin_nom. The EUT may limit active power throughout the test to meet reactive power requirements.
                For an EUT with an input voltage range.
                '''
                if pv is not None:
                    pv_power_setting = (p_rated * power)
                    pv.iv_curve_config(pmp=pv_power_setting, vmp=v_in_nom)
                    pv.irradiance_set(1000.)

                # Special considerations for CHIL ASGC/Typhoon startup #
                if chil is not None:
                    if eut is not None:
                        if eut.measurements() is not None:
                            inv_power = eut.measurements().get('W')
                            timeout = 120.
                            if inv_power <= pv_power_setting * 0.85:
                                pv.irradiance_set(
                                    995
                                )  # Perturb the pv slightly to start the inverter
                                ts.sleep(3)
                                eut.connect(params={'Conn': True})
                            while inv_power <= pv_power_setting * 0.85 and timeout >= 0:
                                ts.log(
                                    'Inverter power is at %0.1f. Waiting up to %s more seconds or until EUT starts...'
                                    % (inv_power, timeout))
                                ts.sleep(1)
                                timeout -= 1
                                inv_power = eut.measurements().get('W')
                                if timeout == 0:
                                    result = script.RESULT_FAIL
                                    raise der.DERError(
                                        'Inverter did not start.')
                            ts.log('Waiting for EUT to ramp up')
                            ts.sleep(8)
                '''
                e) Set EUT volt-watt parameters to the values specified by Characteristic 1. All other functions should
                   be turned off.
                '''
                if eut is not None:
                    vw_curve_params = {
                        'v': [v_pairs['V1'] / v_nom, v_pairs['V2'] / v_nom],
                        'w':
                        [v_pairs['P1'] / p_rated, v_pairs['P2'] / p_rated],
                        'DeptRef': 'W_MAX_PCT',
                        "RmpTms": vw_response_time[vw_curve]
                    }

                    vw_params = {
                        'Ena': True,
                        'ActCrv': 1,
                        'curve': vw_curve_params
                    }
                    ts.log_debug('Writing the following params to EUT: %s' %
                                 vw_params)
                    eut.volt_watt(params=vw_params)
                    '''
                    f) Verify volt-watt mode is reported as active and that the correct characteristic is reported.
                    '''
                    ts.log_debug('Initial EUT VW settings are %s' %
                                 eut.volt_watt())
                if chil is not None:
                    ts.log('Start simulation of CHIL')
                    chil.start_simulation()
                '''
                Refer to P1547 Library and IEEE1547.1 standard for steps 
                '''
                v_steps_dict = ActiveFunction.create_vw_dict_steps()

                # Configure the data acquisition system
                ts.log('Starting data capture for power = %s' % power)
                dataset_filename = ('VW_{0}_PWR_{1}'.format(vw_curve, power))
                ActiveFunction.reset_filename(filename=dataset_filename)
                ts.log('------------{}------------'.format(dataset_filename))
                daq.data_capture(True)

                for step_label, v_step in v_steps_dict.items():
                    ts.log(
                        'Voltage step: setting Grid simulator voltage to %s (%s)'
                        % (v_step, step_label))
                    ActiveFunction.start(daq=daq, step_label=step_label)

                    step_dict = {'V': v_step}
                    if grid is not None:
                        grid.voltage(step_dict['V'])

                    ActiveFunction.record_timeresponse(daq=daq)
                    ActiveFunction.evaluate_criterias(daq=daq,
                                                      step_dict=step_dict)
                    result_summary.write(ActiveFunction.write_rslt_sum())

                # create result workbook
                ts.log('Sampling complete')
                dataset_filename = dataset_filename + ".csv"
                daq.data_capture(False)
                ds = daq.data_capture_dataset()
                ts.log('Saving file: %s' % dataset_filename)
                ds.to_csv(ts.result_file_path(dataset_filename))
                result_params['plot.title'] = dataset_filename.split('.csv')[0]
                ts.result_file(dataset_filename, params=result_params)
                result = script.RESULT_COMPLETE

    except script.ScriptFail as e:
        reason = str(e)
        if reason:
            ts.log_error(reason)

    except Exception as e:
        if dataset_filename is not None:
            dataset_filename = dataset_filename + ".csv"
            daq.data_capture(False)
            ds = daq.data_capture_dataset()
            ts.log('Saving file: %s' % dataset_filename)
            ds.to_csv(ts.result_file_path(dataset_filename))
            result_params['plot.title'] = dataset_filename.split('.csv')[0]
            ts.result_file(dataset_filename, params=result_params)
        ts.log_error('Test script exception: %s' % traceback.format_exc())
        raise

    finally:
        if daq is not None:
            daq.close()
        if pv is not None:
            if p_rated is not None:
                pv.power_set(p_rated)
            pv.close()
        if grid is not None:
            if v_nom is not None:
                grid.voltage(v_nom)
            grid.close()
        if chil is not None:
            chil.close()
        if eut is not None:
            eut.close()
        if result_summary is not None:
            result_summary.close()

    return result
예제 #8
0
def watt_var_mode(wv_curves, wv_response_time):

    result = script.RESULT_FAIL
    daq = None
    v_nom = None
    grid = None
    pv = None
    eut = None
    chil = None
    result_summary = None
    dataset_filename = None

    try:
        cat = ts.param_value('eut.cat')
        cat2 = ts.param_value('eut.cat2')
        sink_power = ts.param_value('eut.sink_power')
        p_rated = ts.param_value('eut.p_rated')
        p_rated_prime = ts.param_value('eut.p_rated_prime')
        var_rated = ts.param_value('eut.var_rated')
        s_rated = ts.param_value('eut.s_rated')

        # DC voltages
        v_in_nom = ts.param_value('eut.v_in_nom')
        #v_min_in = ts.param_value('eut.v_in_min')
        #v_max_in = ts.param_value('eut.v_in_max')

        # AC voltages
        v_nom = ts.param_value('eut.v_nom')
        v_low = ts.param_value('eut.v_low')
        v_high = ts.param_value('eut.v_high')
        p_min = ts.param_value('eut.p_min')
        p_min_prime = ts.param_value('eut.p_min_prime')
        phases = ts.param_value('eut.phases')

        # EUI Absorb capabilities
        absorb = {}
        absorb['ena'] = ts.param_value('eut_cpf.sink_power')
        """
        A separate module has been create for the 1547.1 Standard
        """
        lib_1547 = p1547.module_1547(ts=ts, aif='WV', absorb=absorb)
        ts.log_debug("1547.1 Library configured for %s" %
                     lib_1547.get_test_name())

        # result params
        result_params = lib_1547.get_rslt_param_plot()
        '''
        a) Connect the EUT according to the instructions and specifications provided by the manufacturer.
        '''

        # initialize HIL environment, if necessary
        chil = hil.hil_init(ts)
        if chil is not None:
            chil.config()

        # DAS soft channels
        das_points = lib_1547.get_sc_points()
        # initialize data acquisition system
        daq = das.das_init(ts, sc_points=das_points['sc'])
        daq.sc['P_TARGET'] = p_min
        daq.sc['Q_TARGET'] = 100
        daq.sc['Q_TARGET_MIN'] = 100
        daq.sc['Q_TARGET_MAX'] = 100
        daq.sc['event'] = 'None'
        ts.log('DAS device: %s' % daq.info())

        # pv simulator is initialized with test parameters and enabled
        pv = pvsim.pvsim_init(ts)
        if pv is not None:
            pv.power_set(p_rated)
            pv.power_on()  # Turn on DC so the EUT can be initialized
            if callable(getattr(daq, "set_dc_measurement", None)
                        ):  # for DAQs that don't natively have dc measurements
                daq.set_dc_measurement(
                    pv)  # send pv obj to daq to get dc measurements
                ts.sleep(0.5)

        eut = der.der_init(ts)
        if eut is not None:
            eut.config()
            ts.log_debug(eut.measurements())

        # Special considerations for CHIL ASGC/Typhoon startup
        if chil is not None:
            if chil.hil_info()['mode'] == 'Typhoon':
                inv_power = eut.measurements().get('W')
                timeout = 120.
                if inv_power <= p_rated * 0.85:
                    pv.irradiance_set(
                        995)  # Perturb the pv slightly to start the inverter
                    ts.sleep(3)
                    eut.connect(params={'Conn': True})
                while inv_power <= p_rated * 0.85 and timeout >= 0:
                    ts.log(
                        'Inverter power is at %0.1f. Waiting up to %s more seconds or until EUT starts...'
                        % (inv_power, timeout))
                    ts.sleep(1)
                    timeout -= 1
                    inv_power = eut.measurements().get('W')
                    if timeout == 0:
                        result = script.RESULT_FAIL
                        raise der.DERError('Inverter did not start.')
                ts.log('Waiting for EUT to ramp up')
                ts.sleep(8)
                ts.log_debug('DAS data_read(): %s' % daq.data_read())
        '''
        b) Set all AC test source parameters to the nominal operating voltage and frequency.
        '''
        grid = gridsim.gridsim_init(
            ts)  # Turn on AC so the EUT can be initialized
        if grid is not None:
            # for HIL-based gridsim objects, link the chil parameters to voltage/frequency simulink parameters
            if callable(getattr(grid, "gridsim_info", None)):
                if grid.gridsim_info()['mode'] == 'Opal':
                    grid.config(hil_object=chil)
            grid.voltage(v_nom)

        # open result summary file
        result_summary_filename = 'result_summary.csv'
        result_summary = open(ts.result_file_path(result_summary_filename),
                              'a+')
        ts.result_file(result_summary_filename)
        result_summary.write(lib_1547.get_rslt_sum_col_name())
        '''
        c) Set all EUT parameters to the rated active power conditions for the EUT.
        '''
        if pv is not None:
            pv.iv_curve_config(pmp=p_rated, vmp=v_in_nom)
            pv.irradiance_set(1000.)
            ts.log('Waiting for EUT to power up. Sleeping 30 sec.')
            ts.sleep(30)
        '''
        d) Set all voltage trip parameters to default settings.
        '''
        try:
            eut.vrt_stay_connected_high(
                params={
                    'Ena': True,
                    'ActCrv': 0,
                    'Tms1': 3000,
                    'V1': v_high,
                    'Tms2': 0.16,
                    'V2': v_high
                })
        except Exception, e:
            ts.log_error('Could not set VRT Stay Connected High curve. %s' % e)
        try:
            eut.vrt_stay_connected_low(
                params={
                    'Ena': True,
                    'ActCrv': 0,
                    'Tms1': 3000,
                    'V1': v_low,
                    'Tms2': 0.16,
                    'V2': v_low
                })
        except Exception, e:
            ts.log_error('Could not set VRT Stay Connected Low curve. %s' % e)
예제 #9
0
def test_run():

    result = script.RESULT_FAIL
    grid = None
    pv = p_rated = None
    daq = None
    eut = None
    rs = None
    chil = None
    result_summary = None
    step = None
    q_initial = None
    dataset_filename = None

    try:

        cat = ts.param_value('eut.cat')
        cat2 = ts.param_value('eut.cat2')
        sink_power = ts.param_value('eut.sink_power')
        p_rated = ts.param_value('eut.p_rated')
        p_rated_prime = ts.param_value('eut.p_rated_prime')
        s_rated = ts.param_value('eut.s_rated')

        # DC voltages
        v_nom_in_enabled = ts.param_value('cpf.v_in_nom')
        v_min_in_enabled = ts.param_value('cpf.v_in_min')
        v_max_in_enabled = ts.param_value('cpf.v_in_max')

        v_nom_in = ts.param_value('eut.v_in_nom')
        v_min_in = ts.param_value('eut_cpf.v_in_min')
        v_max_in = ts.param_value('eut_cpf.v_in_max')

        # AC voltages
        v_nom = ts.param_value('eut.v_nom')
        v_min = ts.param_value('eut.v_low')
        v_max = ts.param_value('eut.v_high')
        p_min = ts.param_value('eut.p_min')
        p_min_prime = ts.param_value('eut.p_min_prime')
        phases = ts.param_value('eut.phases')
        pf_response_time = ts.param_value('cpf.pf_response_time')

        # Imbalance configuration
        imbalance_fix = ts.param_value('cpf.imbalance_fix')

        # EUI Absorb capabilities
        absorb = {}
        absorb['ena'] = ts.param_value('eut_cpf.sink_power')
        absorb['p_rated_prime'] = ts.param_value('eut_cpf.p_rated_prime')
        absorb['p_min_prime'] = ts.param_value('eut_cpf.p_min_prime')
        """
        A separate module has been create for the 1547.1 Standard
        """
        lib_1547 = p1547.module_1547(ts=ts, aif='CPF', absorb=absorb)
        ts.log_debug("1547.1 Library configured for %s" %
                     lib_1547.get_test_name())

        # result params
        result_params = lib_1547.get_rslt_param_plot()

        # get target power factors
        pf_targets = {}
        if ts.param_value('cpf.pf_min_inj') == 'Enabled':
            pf_targets['cpf_min_ind'] = float(
                ts.param_value('cpf.pf_min_inj_value'))
        if ts.param_value('cpf.pf_mid_inj') == 'Enabled':
            pf_targets['cpf_mid_ind'] = float(
                ts.param_value('cpf.pf_mid_inj_value'))
        if ts.param_value('cpf.pf_min_ab') == 'Enabled':
            pf_targets['cpf_min_cap'] = float(
                ts.param_value('cpf.pf_min_ab_value'))
        if ts.param_value('cpf.pf_mid_ab') == 'Enabled':
            pf_targets['cpf_mid_cap'] = float(
                ts.param_value('cpf.pf_mid_ab_value'))

        v_in_targets = {}

        if v_nom_in_enabled == 'Enabled':
            v_in_targets['v_nom_in'] = v_nom_in
        if v_min_in != v_nom_in and v_min_in_enabled == 'Enabled':
            v_in_targets['v_min_in'] = v_min_in
        if v_max_in != v_nom_in and v_max_in_enabled == 'Enabled':
            v_in_targets['v_max_in'] = v_max_in
        if not v_in_targets:
            ts.log_error('No V_in target specify. Please select a V_IN test')
            raise
        """
        a) Connect the EUT according to the instructions and specifications provided by the manufacturer.
        """
        # initialize HIL environment, if necessary
        chil = hil.hil_init(ts)
        if chil is not None:
            chil.config()

        # grid simulator is initialized with test parameters and enabled
        grid = gridsim.gridsim_init(
            ts)  # Turn on AC so the EUT can be initialized
        if grid is not None:
            grid.voltage(v_nom)

        # pv simulator is initialized with test parameters and enabled
        pv = pvsim.pvsim_init(ts)
        if pv is not None:
            pv.power_set(p_rated)
            pv.power_on()  # Turn on DC so the EUT can be initialized

        # DAS soft channels
        #das_points = {'sc': ('V_MEAS', 'P_MEAS', 'Q_MEAS', 'Q_TARGET_MIN', 'Q_TARGET_MAX', 'PF_TARGET', 'event')}
        das_points = lib_1547.get_sc_points()
        # initialize data acquisition
        daq = das.das_init(ts, sc_points=das_points['sc'])

        if daq is not None:
            daq.sc['V_MEAS'] = 120
            daq.sc['P_MEAS'] = 100
            daq.sc['Q_MEAS'] = 100
            daq.sc['Q_TARGET_MIN'] = 100
            daq.sc['Q_TARGET_MAX'] = 100
            daq.sc['PF_TARGET'] = 1
            daq.sc['event'] = 'None'
            ts.log('DAS device: %s' % daq.info())
        """
        b) Set all voltage trip parameters to the widest range of adjustability. Disable all reactive/active power
        control functions.
        """
        # it is assumed the EUT is on
        eut = der.der_init(ts)
        if eut is not None:
            eut.config()
            # disable volt/var curve
            #eut.volt_var(params={'Ena': False})
            ts.log_debug(
                'If not done already, set L/HVRT and trip parameters to the widest range of adjustability.'
            )

        # Special considerations for CHIL ASGC/Typhoon startup #
        if chil is not None:
            inv_power = eut.measurements().get('W')
            timeout = 120.
            if inv_power <= p_rated * 0.85:
                pv.irradiance_set(
                    995)  # Perturb the pv slightly to start the inverter
                ts.sleep(3)
                eut.connect(params={'Conn': True})
            while inv_power <= p_rated * 0.85 and timeout >= 0:
                ts.log(
                    'Inverter power is at %0.1f. Waiting up to %s more seconds or until EUT starts...'
                    % (inv_power, timeout))
                ts.sleep(1)
                timeout -= 1
                inv_power = eut.measurements().get('W')
                if timeout == 0:
                    result = script.RESULT_FAIL
                    raise der.DERError('Inverter did not start.')
            ts.log('Waiting for EUT to ramp up')
            ts.sleep(8)
        """
        c) Set all AC test source parameters to the nominal operating voltage and frequency.
        """
        if grid is not None:
            grid.voltage(v_nom)

        # open result summary file
        result_summary_filename = 'result_summary.csv'
        result_summary = open(ts.result_file_path(result_summary_filename),
                              'a+')
        ts.result_file(result_summary_filename)
        result_summary.write(lib_1547.get_rslt_sum_col_name())
        """
        d) Adjust the EUT's available active power to Prated. For an EUT with an input voltage range, set the input
        voltage to Vin_nom. The EUT may limit active power throughout the test to meet reactive power requirements.

        s) For an EUT with an input voltage range, repeat steps d) through o) for Vin_min and Vin_max.
        """
        # TODO: Include step t)
        """
        t) Steps d) through q) may be repeated to test additional communication protocols - Run with another test.
        """

        # For PV systems, this requires that Vmpp = Vin_nom and Pmpp = Prated.
        for v_in_label, v_in in v_in_targets.iteritems():
            ts.log('Starting test %s at v_in = %s' % (v_in_label, v_in))
            a_v = lib_1547.MRA_V * 1.5
            if pv is not None:
                pv.iv_curve_config(pmp=p_rated, vmp=v_in)
                pv.irradiance_set(1000.)
            """
            e) Enable constant power factor mode and set the EUT power factor to PFmin,inj.
            r) Repeat steps d) through o) for additional power factor settings: PFmin,ab, PFmid,inj, PFmid,ab.

            Only the user-selected PF setting will be tested.
            """
            for pf_test_name, pf_target in pf_targets.iteritems():

                if grid is not None:
                    grid.voltage(v_nom)
                #Setting up step label
                lib_1547.set_step_label(starting_label='F')

                ts.log('Starting data capture for pf = %s' % pf_target)
                if imbalance_fix == "Yes":
                    dataset_filename = ('{0}_{1}_FIX'.format(
                        v_in_label.upper(), pf_test_name.upper()))
                else:
                    dataset_filename = ('{0}_{1}'.format(
                        v_in_label.upper(), pf_test_name.upper()))
                ts.log('------------{}------------'.format(dataset_filename))
                # Start the data acquisition systems
                daq.data_capture(True)
                daq.sc['PF_TARGET'] = pf_target
                if eut is not None:
                    parameters = {'Ena': True, 'PF': pf_target}
                    ts.log('PF set: %s' % parameters)
                    eut.fixed_pf(params=parameters)
                    pf_setting = eut.fixed_pf()
                    ts.log('PF setting read: %s' % pf_setting)
                """
                f) Wait for steady state to be reached.

                Every time a parameter is stepped or ramped, measure and record the time domain current and voltage
                response for at least 4 times the maximum expected response time after the stimulus, and measure or
                derive, active power, apparent power, reactive power, and power factor.
                """
                step = lib_1547.get_step_label()
                daq.sc['event'] = step
                daq.data_sample()
                ts.log('Wait for steady state to be reached')
                ts.sleep(2 * pf_response_time)
                """
                g) Step the EUT's active power to Pmin.
                """
                if pv is not None:
                    step = lib_1547.get_step_label()
                    ts.log(
                        'Power step: setting PV simulator power to %s (%s)' %
                        (p_min, step))
                    initial_values = lib_1547.get_initial_value(daq=daq,
                                                                step=step)
                    step_dict = {'V': v_nom, 'P': p_min, 'PF': pf_target}
                    pv.power_set(step_dict['P'])
                    lib_1547.process_data(
                        daq=daq,
                        tr=pf_response_time,
                        step=step,
                        #curve=vw_curve,
                        pwr_lvl=1.0,
                        x_target=step_dict,
                        initial_value=initial_values,
                        result_summary=result_summary,
                        filename=dataset_filename)
                """
                h) Step the EUT's available active power to Prated.
                """
                if pv is not None:
                    step = lib_1547.get_step_label()
                    ts.log(
                        'Power step: setting PV simulator power to %s (%s)' %
                        (p_rated, step))
                    initial_values = lib_1547.get_initial_value(daq=daq,
                                                                step=step)
                    step_dict = {'V': v_nom, 'P': p_rated, 'PF': pf_target}
                    pv.power_set(step_dict['P'])
                    lib_1547.process_data(
                        daq=daq,
                        tr=pf_response_time,
                        step=step,
                        #curve=vw_curve,
                        pwr_lvl=1.0,
                        x_target=step_dict,
                        initial_value=initial_values,
                        result_summary=result_summary,
                        filename=dataset_filename)

                if grid is not None:

                    # i) Step the AC test source voltage to (VL + av)
                    step = lib_1547.get_step_label()
                    ts.log(
                        'Voltage step: setting Grid simulator voltage to %s (%s)'
                        % ((v_min + a_v), step))
                    #q_initial = lib_1547.get_initial(daq=daq,step=step)
                    initial_values = lib_1547.get_initial_value(daq=daq,
                                                                step=step)
                    step_dict = {
                        'V': v_min + a_v,
                        'P': p_rated,
                        'PF': pf_target
                    }
                    grid.voltage(step_dict['V'])
                    lib_1547.process_data(daq=daq,
                                          tr=pf_response_time,
                                          step=step,
                                          pwr_lvl=1.0,
                                          x_target=step_dict,
                                          initial_value=initial_values,
                                          result_summary=result_summary,
                                          filename=dataset_filename)

                    #   j) Step the AC test source voltage to (VH - av)
                    step = lib_1547.get_step_label()
                    ts.log(
                        'Voltage step: setting Grid simulator voltage to %s (%s)'
                        % ((v_max - a_v), step))
                    initial_values = lib_1547.get_initial_value(daq=daq,
                                                                step=step)
                    step_dict = {
                        'V': v_min - a_v,
                        'P': p_rated,
                        'PF': pf_target
                    }
                    grid.voltage(step_dict['V'])
                    lib_1547.process_data(
                        daq=daq,
                        tr=pf_response_time,
                        step=step,
                        #curve=vw_curve,
                        pwr_lvl=1.0,
                        x_target=step_dict,
                        initial_value=initial_values,
                        result_summary=result_summary,
                        filename=dataset_filename)

                    #   k) Step the AC test source voltage to (VL + av)
                    step = lib_1547.get_step_label()
                    ts.log(
                        'Voltage step: setting Grid simulator voltage to %s (%s)'
                        % (v_nom, step))
                    #q_initial = lib_1547.get_initial(daq=daq,step=step)
                    initial_values = lib_1547.get_initial_value(daq=daq,
                                                                step=step)
                    step_dict = {
                        'V': v_min + a_v,
                        'P': p_rated,
                        'PF': pf_target
                    }
                    grid.voltage(step_dict['V'])
                    lib_1547.process_data(
                        daq=daq,
                        tr=pf_response_time,
                        step=step,
                        #curve=vw_curve,
                        pwr_lvl=1.0,
                        x_target=step_dict,
                        initial_value=initial_values,
                        result_summary=result_summary,
                        filename=dataset_filename)

                if grid is not None and phases is 'Three phase':
                    """
                    l) For multiphase units, step the AC test source voltage to Vnom.
                    """
                    step = lib_1547.get_step_label()
                    ts.log(
                        'Voltage step: setting Grid simulator voltage to %s (%s)'
                        % (v_nom, step))
                    initial_values = lib_1547.get_initial_value(daq=daq,
                                                                step=step)
                    step_dict = {'V': v_nom, 'P': p_rated, 'PF': pf_target}
                    grid.voltage(step_dict['V'])
                    lib_1547.process_data(daq=daq,
                                          tr=pf_response_time,
                                          step=step,
                                          pwr_lvl=1.0,
                                          x_target=step_dict,
                                          initial_value=initial_values,
                                          result_summary=result_summary,
                                          filename=dataset_filename)

                if grid is not None and phases is 'Three phase':
                    """
                    m) For multiphase units, step the AC test source voltage to Case A from Table 24.
                    """
                    step = lib_1547.get_step_label()
                    ts.log(
                        'Voltage step: setting Grid simulator voltage to %s (%s)'
                        % (v_nom, step))
                    initial_values = lib_1547.get_initial_value(daq=daq,
                                                                step=step)
                    step_dict = {
                        'V': v_nom * (1.07 + 0.91 + 0.91) / 3,
                        'P': p_rated,
                        'PF': pf_target
                    }
                    lib_1547.set_grid_asymmetric(grid=grid, case='case_a')
                    #grid.voltage(step_dict['V'])
                    lib_1547.process_data(daq=daq,
                                          tr=pf_response_time,
                                          step=step,
                                          pwr_lvl=1.0,
                                          x_target=step_dict,
                                          initial_value=initial_values,
                                          result_summary=result_summary,
                                          filename=dataset_filename)
                """
                n) For multiphase units, step the AC test source voltage to VN.
                """

                if grid is not None and phases is 'Three phase':
                    step = lib_1547.get_step_label()
                    ts.log(
                        'Voltage step: setting Grid simulator voltage to %s (%s)'
                        % (v_nom, step))
                    initial_values = lib_1547.get_initial_value(daq=daq,
                                                                step=step)
                    step_dict = {'V': v_nom, 'P': p_rated, 'PF': pf_target}
                    grid.voltage(step_dict['V'])
                    lib_1547.process_data(daq=daq,
                                          tr=pf_response_time,
                                          step=step,
                                          pwr_lvl=1.0,
                                          x_target=step_dict,
                                          initial_value=initial_values,
                                          result_summary=result_summary,
                                          filename=dataset_filename)
                '''
                o) For multiphase units, step the AC test source voltage to Case B from Table 24.
                '''
                if grid is not None and phases is 'Three phase':
                    step = lib_1547.get_step_label()
                    ts.log(
                        'Voltage step: setting Grid simulator to case B (IEEE 1547.1-Table 24)(%s)'
                        % step)
                    initial_values = lib_1547.get_initial_value(daq=daq,
                                                                step=step)
                    # TODO READJUST WITH INVERTER CALCULATION WITH IMBALANCED GRID
                    step_dict = {
                        'V': v_nom * (0.91 + 1.07 + 1.07) / 3,
                        'P': p_rated,
                        'PF': pf_target
                    }
                    lib_1547.set_grid_asymmetric(grid=grid, case='case_b')
                    lib_1547.process_data(daq=daq,
                                          tr=pf_response_time,
                                          step=step,
                                          pwr_lvl=1.0,
                                          x_target=step_dict,
                                          initial_value=initial_values,
                                          result_summary=result_summary,
                                          filename=dataset_filename)
                """
                p) For multiphase units, step the AC test source voltage to Vnom.
                """
                if grid is not None and phases is 'Three phase':
                    step = lib_1547.get_step_label()
                    ts.log(
                        'Voltage step: setting Grid simulator voltage to %s (%s)'
                        % (v_nom, step))
                    initial_values = lib_1547.get_initial_value(daq=daq,
                                                                step=step)
                    step_dict = {'V': v_nom, 'P': p_rated, 'PF': pf_target}
                    grid.voltage(step_dict['V'])
                    lib_1547.process_data(daq=daq,
                                          tr=pf_response_time,
                                          step=step,
                                          pwr_lvl=1.0,
                                          x_target=step_dict,
                                          initial_value=initial_values,
                                          result_summary=result_summary,
                                          filename=dataset_filename)
                """
                q) Disable constant power factor mode. Power factor should return to unity.
                """
                if eut is not None:
                    #parameters = {'Ena': False, 'PF': 1.0}
                    #ts.log('PF set: %s' % parameters)
                    #eut.fixed_pf(params=parameters)
                    step = lib_1547.get_step_label()
                    pf_setting = eut.fixed_pf()
                    ts.log('PF setting read: %s' % pf_setting)
                    daq.sc['event'] = 'Step %s' % step
                    daq.data_sample()
                    ts.sleep(2 * pf_response_time)
                    daq.sc['event'] = 'T_settling_done'
                    daq.data_sample()
                """
                r) Verify all reactive/active power control functions are disabled.
                """
                if eut is not None:
                    ts.log(
                        'Reactive/active power control functions are disabled.'
                    )
                    # TODO Implement ts.prompt functionality?
                    #meas = eut.measurements()
                    #ts.log('EUT PF is now: %s' % (data.get('AC_PF_1')))
                    #ts.log('EUT Power: %s, EUT Reactive Power: %s' % (meas['W'], meas['VAr']))

                ts.log('Sampling complete')
                dataset_filename = dataset_filename + ".csv"
                daq.data_capture(False)
                ds = daq.data_capture_dataset()
                ts.log('Saving file: %s' % dataset_filename)
                ds.to_csv(ts.result_file_path(dataset_filename))
                result_params['plot.title'] = dataset_filename.split('.csv')[0]
                ts.result_file(dataset_filename, params=result_params)
                result = script.RESULT_COMPLETE

    except script.ScriptFail, e:
        reason = str(e)
        if reason:
            ts.log_error(reason)
예제 #10
0
def volt_watt_mode_imbalanced_grid(imbalance_resp, vw_curves,
                                   vw_response_time):

    result = script.RESULT_FAIL
    daq = None
    p_rated = None
    grid = None
    pv = None
    eut = None
    chil = None
    result_summary = None

    try:
        cat = ts.param_value('eut.cat')
        cat2 = ts.param_value('eut.cat2')
        p_rated = ts.param_value('eut.p_rated')
        s_rated = ts.param_value('eut.s_rated')

        # DC voltages
        v_in_nom = ts.param_value('eut.v_in_nom')

        # AC voltages
        v_nom = ts.param_value('eut.v_nom')
        v_min = ts.param_value('eut.v_low')
        v_max = ts.param_value('eut.v_high')
        p_min = ts.param_value('eut.p_min')
        phases = ts.param_value('eut.phases')
        imbalance_fix = ts.param_value('vw.imbalance_fix')

        # EUI Absorb capabilities
        absorb = {}
        absorb['ena'] = ts.param_value('eut_vw.sink_power')
        absorb['p_rated_prime'] = ts.param_value('eut_vw.p_rated_prime')
        absorb['p_min_prime'] = ts.param_value('eut_vw.p_min_prime')
        """
        A separate module has been create for the 1547.1 Standard
        """
        ActiveFunction = p1547.ActiveFunction(ts=ts,
                                              functions=[VW],
                                              script_name='Volt-Watt',
                                              criteria_mode=[True, True, True])
        ts.log_debug('1547.1 Library configured for %s' %
                     ActiveFunction.get_script_name())

        ActiveFunction.set_imbalance_config(imbalance_angle_fix=imbalance_fix)
        ts.log_debug('1547.1 Library configured for %s' %
                     ActiveFunction.get_script_name())
        '''
        a) Connect the EUT according to the instructions and specifications provided by the manufacturer.
        '''
        ts.log_debug(15 * "*" + "HIL initialization" + 15 * "*")

        # initialize HIL environment, if necessary
        chil = hil.hil_init(ts)
        if chil is not None:
            chil.config()
        ts.log_debug(15 * "*" + "GRIDSIM initialization" + 15 * "*")
        # grid simulator is initialized with test parameters and enabled
        grid = gridsim.gridsim_init(ts, support_interfaces={
            'hil': chil
        })  # Turn on AC so the EUT can be initialized
        if grid is not None:
            grid.voltage(v_nom)
        ts.log_debug(15 * "*" + "PVSIM initialization" + 15 * "*")
        # pv simulator is initialized with test parameters and enabled
        pv = pvsim.pvsim_init(ts)
        if pv is not None:
            pv.power_set(p_rated)
            pv.power_on()  # Turn on DC so the EUT can be initialized
        ts.log_debug(15 * "*" + "DAS initialization" + 15 * "*")
        # DAS soft channels
        #das_points = {'sc': ('P_TARGET', 'P_TARGET_MIN', 'P_TARGET_MAX', 'P_MEAS', 'V_TARGET', 'V_MEAS', 'event')}
        das_points = ActiveFunction.get_sc_points()

        # initialize data acquisition system
        daq = das.das_init(ts,
                           sc_points=das_points['sc'],
                           support_interfaces={'hil': chil})

        if daq is not None:
            daq.sc['P_TARGET'] = p_rated
            daq.sc['P_TARGET_MIN'] = 100
            daq.sc['P_TARGET_MAX'] = 100
            daq.sc['V_TARGET'] = v_nom
            daq.sc['event'] = 'None'

        ts.log('DAS device: %s' % daq.info())
        '''
        b) Set all voltage trip parameters to the widest range of adjustability. Disable all reactive/active power
        control functions.
        '''
        ts.log_debug(15 * "*" + "EUT initialization" + 15 * "*")

        eut = der.der_init(ts, support_interfaces={'hil': chil})
        if eut is not None:
            eut.config()
            #Disable all functions on EUT
            #eut.deactivate_all_fct()
            ts.log_debug(eut.measurements())
            ts.log_debug(
                'L/HVRT and trip parameters set to the widest range : v_min: {0} V, v_max: {1} V'
                .format(v_min, v_max))
            try:
                eut.vrt_stay_connected_high(
                    params={
                        'Ena': True,
                        'ActCrv': 0,
                        'Tms1': 3000,
                        'V1': v_max,
                        'Tms2': 0.16,
                        'V2': v_max
                    })
            except Exception as e:
                ts.log_error(
                    'Could not set VRT Stay Connected High curve. %s' % e)
            try:
                eut.vrt_stay_connected_low(
                    params={
                        'Ena': True,
                        'ActCrv': 0,
                        'Tms1': 3000,
                        'V1': v_min,
                        'Tms2': 0.16,
                        'V2': v_min
                    })
            except Exception as e:
                ts.log_error('Could not set VRT Stay Connected Low curve. %s' %
                             e)
        else:
            ts.log_debug(
                'Set L/HVRT and trip parameters set to the widest range of adjustability possible.'
            )

        # Special considerations for CHIL ASGC/Typhoon startup
        if chil is not None:
            if eut is not None:
                inv_power = eut.measurements().get('W')
                timeout = 120.
                if inv_power <= p_rated * 0.85:
                    pv.irradiance_set(
                        995)  # Perturb the pv slightly to start the inverter
                    ts.sleep(3)
                    eut.connect(params={'Conn': True})
                while inv_power <= p_rated * 0.85 and timeout >= 0:
                    ts.log(
                        'Inverter power is at %0.1f. Waiting up to %s more seconds or until EUT starts...'
                        % (inv_power, timeout))
                    ts.sleep(1)
                    timeout -= 1
                    inv_power = eut.measurements().get('W')
                    if timeout == 0:
                        result = script.RESULT_FAIL
                        raise der.DERError('Inverter did not start.')
                ts.log('Waiting for EUT to ramp up')
                ts.sleep(8)
        '''
        c) Set all AC test source parameters to the nominal operating voltage and frequency.
        '''
        if grid is not None:
            grid.voltage(v_nom)

        # open result summary file
        result_summary_filename = 'result_summary.csv'
        result_summary = open(ts.result_file_path(result_summary_filename),
                              'a+')
        ts.result_file(result_summary_filename)
        result_summary.write(ActiveFunction.get_rslt_sum_col_name())
        '''
        d) Adjust the EUT's available active power to Prated. For an EUT with an input voltage range, set the input
        voltage to Vin_nom.
        '''
        if pv is not None:
            pv.iv_curve_config(pmp=p_rated, vmp=v_in_nom)
            pv.irradiance_set(1000.)

        for imbalance_response in imbalance_resp:
            for vw_curve in vw_curves:
                '''
                e) Set EUT volt-watt parameters to the values specified by Characteristic 1. All other function be
                turned off.
                '''
                if eut is not None:
                    #eut.deactivate_all_fct()
                    pass
                ts.log('Starting test with characteristic curve %s' %
                       (vw_curve))
                ActiveFunction.reset_curve(vw_curve)
                ActiveFunction.reset_time_settings(
                    tr=vw_response_time[vw_curve], number_tr=2)
                v_pairs = ActiveFunction.get_params(curve=vw_curve,
                                                    function=VW)

                # it is assumed the EUT is on
                eut = der.der_init(ts)
                if eut is not None:
                    vw_curve_params = {
                        'v': [
                            round(v_pairs['V1'] * (v_nom), 2),
                            round(v_pairs['V2'] * (v_nom), 2)
                        ],
                        'w': [
                            round(v_pairs['P1'] * (p_rated), 2),
                            round(v_pairs['P2'] * (p_rated), 2)
                        ],
                        'DeptRef':
                        'W_MAX_PCT'
                    }
                    vw_params = {
                        'Ena': True,
                        'ActCrv': 1,
                        'curve': vw_curve_params
                    }
                    '''
                    f) Verify volt-watt mode is reported as active and that the correct characteristic is reported
                    '''
                    eut.volt_watt(params=vw_params)
                    ts.log_debug('Initial EUT VW settings are %s' %
                                 eut.volt_watt())
                    ts.log_debug('curve points:  %s' % v_pairs)
                '''
                g) Once steady state is reached, begin the adjustment of phase voltages.
                '''
                """
                Test start
                """
                ActiveFunction.set_step_label('G')
                daq.sc['event'] = ActiveFunction.get_step_label()
                daq.data_sample()
                ts.log('Wait for steady state to be reached')
                ts.sleep(2 * vw_response_time[vw_curve])
                ts.log('Starting imbalance test with VW mode at %s (%s)' %
                       (imbalance_response, imbalance_fix))

                dataset_filename = 'VW_IMB_%s_%s' % (imbalance_response,
                                                     imbalance_fix)
                ts.log('------------{}------------'.format(dataset_filename))
                # Start the data acquisition systems
                daq.data_capture(True)
                '''
                Step h) For multiphase units, step the AC test source voltage to Case A from Table 24
                '''

                if grid is not None:
                    step_label = ActiveFunction.get_step_label()
                    ts.log(
                        'Voltage step: setting Grid simulator to case A (IEEE 1547.1-Table 24)(%s)'
                        % step_label)
                    ActiveFunction.start(daq=daq, step_label=step_label)
                    v_target = ActiveFunction.set_grid_asymmetric(
                        grid=grid, case='case_a')
                    step_dict = {'V': v_target}
                    ActiveFunction.record_timeresponse(daq=daq)
                    ActiveFunction.evaluate_criterias(daq=daq,
                                                      step_dict=step_dict)
                    result_summary.write(ActiveFunction.write_rslt_sum())
                '''
                Step i) For multiphase units, step the AC test source voltage to VN.
                '''
                if grid is not None:
                    step_label = ActiveFunction.get_step_label()
                    ts.log(
                        'Voltage step: setting Grid simulator voltage to %s (%s)'
                        % (v_nom, step_label))
                    ActiveFunction.start(daq=daq, step_label=step_label)
                    v_target = v_nom
                    grid.voltage(v_target)
                    step_dict = {'V': v_target}
                    ActiveFunction.record_timeresponse(daq=daq)
                    ActiveFunction.evaluate_criterias(daq=daq,
                                                      step_dict=step_dict)
                    result_summary.write(ActiveFunction.write_rslt_sum())
                '''
                Step j) For multiphase units, step the AC test source voltage to Case B from Table 24
                '''
                if grid is not None:
                    step_label = ActiveFunction.get_step_label()
                    ts.log(
                        'Voltage step: setting Grid simulator to case B (IEEE 1547.1-Table 24)(%s)'
                        % step_label)
                    ActiveFunction.start(daq=daq, step_label=step_label)
                    v_target = ActiveFunction.set_grid_asymmetric(
                        grid=grid, case='case_b')
                    step_dict = {'V': v_target}
                    ActiveFunction.record_timeresponse(daq=daq)
                    ActiveFunction.evaluate_criterias(daq=daq,
                                                      step_dict=step_dict)
                    result_summary.write(ActiveFunction.write_rslt_sum())
                '''
                Step k) For multiphase units, step the AC test source voltage to VN.
                '''
                if grid is not None:
                    step_label = ActiveFunction.get_step_label()
                    ts.log(
                        'Voltage step: setting Grid simulator voltage to %s (%s)'
                        % (v_nom, step_label))
                    ActiveFunction.start(daq=daq, step_label=step_label)
                    v_target = v_nom
                    grid.voltage(v_target)
                    step_dict = {'V': v_target}
                    ActiveFunction.record_timeresponse(daq=daq)
                    ActiveFunction.evaluate_criterias(daq=daq,
                                                      step_dict=step_dict)
                    result_summary.write(ActiveFunction.write_rslt_sum())

                # Get the rslt parameters for plot
                result_params = ActiveFunction.get_rslt_param_plot()
                ts.log('Sampling complete')
                dataset_filename = dataset_filename + ".csv"
                daq.data_capture(False)
                ds = daq.data_capture_dataset()
                ts.log('Saving file: %s' % dataset_filename)
                ds.to_csv(ts.result_file_path(dataset_filename))
                result_params['plot.title'] = dataset_filename.split('.csv')[0]
                ts.result_file(dataset_filename, params=result_params)
                result = script.RESULT_COMPLETE

    except script.ScriptFail as e:
        reason = str(e)
        if reason:
            ts.log_error(reason)

    finally:
        if daq is not None:
            daq.close()
        if pv is not None:
            if p_rated is not None:
                pv.power_set(p_rated)
            pv.close()
        if grid is not None:
            if v_nom is not None:
                grid.voltage(v_nom)
            grid.close()
        if chil is not None:
            chil.close()
        if eut is not None:
            eut.volt_var(params={'Ena': False})
            eut.volt_watt(params={'Ena': False})
            eut.close()
        if result_summary is not None:
            result_summary.close()

    return result
예제 #11
0
def test_run():

    result = script.RESULT_FAIL
    grid = None
    pv = p_rated = None
    daq = None
    eut = None
    rs = None
    chil = None
    result_summary = None
    step = None
    q_initial = None
    dataset_filename = None
    fw_curves = []
    fw_response_time = [0, 0, 0]
    filename = None
    result_params = None

    try:
        cat = ts.param_value('eut.cat')
        cat2 = ts.param_value('eut.cat2')
        sink_power = ts.param_value('eut.sink_power')
        p_rated = ts.param_value('eut.p_rated')
        p_rated_prime = ts.param_value('eut.p_rated_prime')
        s_rated = ts.param_value('eut.s_rated')

        # DC voltages
        v_nom_in = ts.param_value('eut.v_in_nom')
        v_min_in = ts.param_value('eut.v_in_min')
        v_max_in = ts.param_value('eut.v_in_max')

        # AC voltages
        v_nom = ts.param_value('eut.v_nom')
        v_min = ts.param_value('eut.v_low')
        v_max = ts.param_value('eut.v_high')
        p_min = ts.param_value('eut.p_min')
        phases = ts.param_value('eut.phases')

        # EUI Absorb capabilities
        absorb = {}
        absorb['ena'] = ts.param_value('eut_vw.sink_power')
        absorb['p_rated_prime'] = ts.param_value('eut_vw.p_rated_prime')
        absorb['p_min_prime'] = ts.param_value('eut_vw.p_min_prime')

        # AC voltages
        f_nom = ts.param_value('eut.f_nom')
        f_min = ts.param_value('eut.f_min')
        f_max = ts.param_value('eut.f_max')
        p_min = ts.param_value('eut.p_min')
        phases = ts.param_value('eut.phases')
        # EUI FW parameters
        absorb_enable = ts.param_value('eut_fw.sink_power')
        p_rated_prime = ts.param_value('eut_fw.p_rated_prime')
        p_min_prime = ts.param_value('eut_fw.p_min_prime')
        p_small = ts.param_value('eut_fw.p_small')

        if ts.param_value('fw.test_1') == 'Enabled':
            fw_curves.append(1)
            fw_response_time[1] = float(ts.param_value('fw.test_1_tr'))
        if ts.param_value('fw.test_2') == 'Enabled':
            fw_curves.append(2)
            fw_response_time[2] = float(ts.param_value('fw.test_2_tr'))

        # VW parameters
        absorb = {}
        absorb['ena'] = ts.param_value('eut_vw.sink_power')
        """
        A separate module has been create for the 1547.1 Standard
        """
        ActiveFunction = p1547.ActiveFunction(ts=ts,
                                              functions=[LAP, FW, VW],
                                              script_name='Limit Active Power',
                                              criteria_mode=[True, True, True])
        ts.log_debug("1547.1 Library configured for %s" %
                     ActiveFunction.get_script_name())

        # result params
        result_params = ActiveFunction.get_rslt_param_plot()

        #  Set Test parameter
        act_pwrs = ts.param_value('lap.act_pwr')

        # List of power level for tests
        ts.log_debug('%s' % (act_pwrs))
        if act_pwrs == '0%':
            act_pwrs_limits = [0.0]
        elif act_pwrs == '33%':
            act_pwrs_limits = [0.33]
        elif act_pwrs == '66%':
            act_pwrs_limits = [0.66]
        else:
            act_pwrs_limits = [0.66, 0.33, 0.0]

        # 5.13.2 Procedure asks for three repetitions
        n_iters = list(range(1, int(ts.param_value('lap.iter')) + 1))

        # Take the highest value for the steady state wait time
        tr_min = min(ts.param_value('lap.test_vw_1_tr'),
                     ts.param_value('lap.test_fw_1_tr'))
        tr_vw = ts.param_value('lap.test_vw_1_tr')
        """
        a) - Connect the EUT according to the instructions and specifications provided by the manufacturer.
           - Apply the default settings from IEEE std 1547 for voltage-active power mode 
             (Minimum setting of table 10 of IEEE 1547)
           
           - Apply the default settings from frequency droop response in IEE std 1547 for abnormal operating perfomance
             category of the DER
           - Enable voltage active power mode
        """
        # initialize HIL environment, if necessary
        chil = hil.hil_init(ts)
        if chil is not None:
            chil.config()

        # grid simulator is initialized with test parameters and enabled
        grid = gridsim.gridsim_init(ts, support_interfaces={
            'hil': chil
        })  # Turn on AC so the EUT can be initialized
        if grid is not None:
            grid.voltage(v_nom)

        # pv simulator is initialized with test parameters and enabled
        pv = pvsim.pvsim_init(ts)
        if pv is not None:
            pv.power_set(p_rated)
            pv.power_on()  # Turn on DC so the EUT can be initialized

        # DAS soft channels
        das_points = ActiveFunction.get_sc_points()
        ts.log(das_points)
        # initialize data acquisition
        daq = das.das_init(ts,
                           sc_points=das_points['sc'],
                           support_interfaces={
                               'pvsim': pv,
                               'hil': chil
                           })

        if daq is not None:
            ts.log('DAS device: %s' % daq.info())

        eut = der.der_init(ts, support_interfaces={'hil': chil})
        if eut is not None:
            eut.config()
            # Enable volt/watt curve and configure default settings
            v_pairs = ActiveFunction.get_params(curve=1, function=VW)
            vw_curve_params = {
                'v': (round(v_pairs['V1'] / v_nom,
                            2), round(v_pairs['V2'] / v_nom, 2)),
                'w': (round(v_pairs['P1'] / p_rated,
                            2), round(v_pairs['P2'] / p_rated, 2)),
                'DeptRef':
                'W_MAX_PCT',
                'RmpTms':
                tr_vw
            }
            vw_params = {'Ena': True, 'ActCrv': 1, 'curve': vw_curve_params}
            eut.volt_watt(params=vw_params)
            # Enable freq/watt curve and configure default settings
            fw_curve_params = ActiveFunction.get_params(function=FW, curve=1)
            fw_params = {
                'Ena': True,
                'curve': 1,
                'dbf': fw_curve_params['dbf'],
                'kof': fw_curve_params['kof'],
                'RspTms': fw_curve_params['TR']
            }
            eut.freq_watt(fw_params)
            try:
                eut.vrt_stay_connected_high(
                    params={
                        'Ena': True,
                        'ActCrv': 0,
                        'Tms1': 3000,
                        'V1': v_max,
                        'Tms2': 0.16,
                        'V2': v_max
                    })
            except Exception as e:
                ts.log_error(
                    'Could not set VRT Stay Connected High curve. %s' % e)
            try:
                eut.frt_stay_connected_high(
                    params={
                        'Ena': True,
                        'ActCrv': 0,
                        'Tms1': 3000,
                        'Hz1': f_max,
                        'Tms2': 160,
                        'Hz2': f_max
                    })
            except Exception as e:
                ts.log_error(
                    'Could not set FRT Stay Connected High curve. %s' % e)
            try:
                eut.vrt_stay_connected_low(
                    params={
                        'Ena': True,
                        'ActCrv': 0,
                        'Tms1': 3000,
                        'V1': v_min,
                        'Tms2': 0.16,
                        'V2': v_min
                    })
            except Exception as e:
                ts.log_error('Could not set VRT Stay Connected Low curve. %s' %
                             e)
            try:
                eut.frt_stay_connected_low(
                    params={
                        'Ena': True,
                        'ActCrv': 0,
                        'Tms1': 3000,
                        'Hz1': f_min,
                        'Tms2': 160,
                        'Hz2': f_min
                    })
            except Exception as e:
                ts.log_error('Could not set FRT Stay Connected Low curve. %s' %
                             e)

            ts.log_debug(
                'If not done already, set L/HVRT and trip parameters to the widest range of adjustability.'
            )

        # Special considerations for CHIL ASGC/Typhoon startup #
        if chil is not None:
            if chil.hil_info()['mode'] == 'Typhoon':
                inv_power = eut.measurements().get('W')
                timeout = 120.
                if inv_power <= p_rated * 0.85:
                    pv.irradiance_set(
                        995)  # Perturb the pv slightly to start the inverter
                    ts.sleep(3)
                    eut.connect(params={'Conn': True})
                while inv_power <= p_rated * 0.85 and timeout >= 0:
                    ts.log(
                        'Inverter power is at %0.1f. Waiting up to %s more seconds or until EUT starts...'
                        % (inv_power, timeout))
                    ts.sleep(1)
                    timeout -= 1
                    inv_power = eut.measurements().get('W')
                    if timeout == 0:
                        result = script.RESULT_FAIL
                        raise der.DERError('Inverter did not start.')
                ts.log('Waiting for EUT to ramp up')
                ts.sleep(8)

        # Configure Grid simulator
        if grid is not None:
            grid.voltage(v_nom)

        # open result summary file
        result_summary_filename = 'result_summary.csv'
        result_summary = open(ts.result_file_path(result_summary_filename),
                              'a+')
        ts.result_file(result_summary_filename)
        result_summary.write(ActiveFunction.get_rslt_sum_col_name())
        """
        g) Repeat steps b) through f using active power limits of 33% and zero

        h) Repeat steps b) through g) twice for a total of three repetitions
        """
        if chil is not None:
            ts.log('Start simulation of CHIL')
            chil.start_simulation()

        for n_iter in n_iters:
            for act_pwrs_limit in act_pwrs_limits:
                """
                 b) - Establish nominal operating conditions as specified by the manufacturer at the terminals 
                      of the EUT.
                    - Make available sufficient input power for the EUT to reach its rated active power.
                    - Allow (or command) the EUT to reach steady-state output at its rated active power
                    - Begin recording EUT active power
                 """
                ts.log('Starting test no. %s with active power limit to %s ' %
                       (n_iter, act_pwrs_limit))
                ActiveFunction.reset_pwr(pwr=act_pwrs_limit)
                ActiveFunction.reset_time_settings(tr=tr_min)

                # For PV systems, this requires that Vmpp = Vin_nom and Pmpp = Prated.
                if pv is not None:
                    pv.iv_curve_config(pmp=p_rated, vmp=v_nom_in)
                    pv.irradiance_set(1000.)

                ts.log('EUT Config: setting Active Power Limit to 100%')
                if eut is not None:
                    # limit maximum power
                    eut.limit_max_power(
                        params={
                            'Ena': True,
                            'WMaxPct': 100,
                            'WinTms': 0,
                            'RmpTms': 0,
                            'RvrtTms': 0.0
                        })
                ts.sleep(2 * tr_min)
                daq.data_capture(True)
                filename = ('LAP_{0}_{1}'.format(act_pwrs_limit, n_iter))
                ActiveFunction.reset_filename(filename=filename)
                ts.log('------------{}------------'.format(filename))
                """
                c)  - Apply an active power limit to the EUT of 66% of its rated power.
                    - Wait until the EUT active power reaches a new steady state
                """
                # Setting up step label
                ActiveFunction.set_step_label(starting_label='C')
                step_label = ActiveFunction.get_step_label()
                daq.sc['event'] = step
                ActiveFunction.start(daq=daq, step_label=step_label)
                #initial_values = ActiveFunction.get_initial_value(daq=daq, step=step)
                ts.log('EUT Config: setting Active Power Limit to %s (%s)' %
                       (act_pwrs_limit, step))
                if eut is not None:
                    # limit maximum power
                    eut.limit_max_power(
                        params={
                            'MaxLimWEna': True,
                            'MaxLimW_PCT': act_pwrs_limit * 100,
                            'WinTms': 0,
                            'RmpTms': 0,
                            'RvrtTms': 0.0
                        })
                step_dict = {'V': v_nom, 'F': f_nom, 'P': act_pwrs_limit}
                #target_dict = {'P': act_pwrs_limit}
                ActiveFunction.record_timeresponse(daq=daq)
                ts.log_debug(f'daq={daq}')
                ActiveFunction.evaluate_criterias(daq=daq,
                                                  step_dict=step_dict,
                                                  y_criterias_mod={'P': LAP})
                result_summary.write(ActiveFunction.write_rslt_sum())
                """
                d)  - Reduce the frequency of the AC test to 59 Hz and hold until EUT active power reaches a new steady 
                      state
                    - Return AC test frequency to nominal and Hold until new states reached
                """
                f_steps = [59.0, f_nom]
                step_label = ActiveFunction.get_step_label()
                if grid is not None:
                    for f_step in f_steps:
                        step_ = step_label + "_" + str(f_step)
                        ts.log(
                            'Frequency step: setting Grid simulator frequency to %s (%s)'
                            % (f_step, step_))
                        ActiveFunction.start(daq=daq, step_label=step_)
                        #initial_values = ActiveFunction.get_initial_value(daq=daq,step=step_)
                        grid.freq(f_step)
                        step_dict = {
                            'V': v_nom,
                            'F': f_step,
                            'P': act_pwrs_limit
                        }
                        ActiveFunction.record_timeresponse(daq=daq)
                        ActiveFunction.evaluate_criterias(
                            daq=daq,
                            step_dict=step_dict,
                            y_criterias_mod={'P': FW})
                        result_summary.write(ActiveFunction.write_rslt_sum())
                """
                e)  - Increase the frequency of the AC test to 61 Hz and hold until EUT active power reaches a new steady 
                      state
                    - Return AC test frequency to nominal and Hold until new states reached
                """
                f_steps = [61.0, f_nom]
                step_label = ActiveFunction.get_step_label()
                if grid is not None:
                    for f_step in f_steps:
                        step_ = step_label + "_" + str(f_step)
                        ts.log(
                            'Frequency step: setting Grid simulator frequency to %s (%s)'
                            % (f_step, step_))
                        ActiveFunction.start(daq=daq, step_label=step_)
                        #initial_values = ActiveFunction.get_initial_value(daq=daq,step=step_)
                        grid.freq(f_step)
                        step_dict = {
                            'V': v_nom,
                            'F': f_step,
                            'P': act_pwrs_limit
                        }
                        ActiveFunction.record_timeresponse(daq=daq)
                        ActiveFunction.evaluate_criterias(
                            daq=daq,
                            step_dict=step_dict,
                            y_criterias_mod={'P': FW})
                        result_summary.write(ActiveFunction.write_rslt_sum())
                """
                f)  - Increase the voltage of the AC test to 1.08 times nominal and hold until EUT active power 
                      reaches a new steady state
                    - Return AC test voltage to nominal and Hold until new states reached
                """
                v_steps = [1.08 * v_nom, v_nom]
                step_label = ActiveFunction.get_step_label()
                if grid is not None:
                    for v_step in v_steps:
                        step_ = step_label + "_" + str(v_step)
                        ts.log(
                            'Voltage step: setting Grid simulator voltage to %s (%s)'
                            % (v_step, step_))
                        #initial_values = ActiveFunction.get_initial_value(daq=daq,step=step_)
                        ActiveFunction.start(daq=daq, step_label=step_)
                        grid.voltage(v_step)
                        step_dict = {
                            'V': v_step,
                            'F': f_nom,
                            'P': act_pwrs_limit
                        }
                        ActiveFunction.record_timeresponse(daq=daq)
                        ActiveFunction.evaluate_criterias(
                            daq=daq,
                            step_dict=step_dict,
                            y_criterias_mod={'P': VW})
                        result_summary.write(ActiveFunction.write_rslt_sum())

                ts.log('Sampling complete')
                dataset_filename = filename + ".csv"
                daq.data_capture(False)
                ds = daq.data_capture_dataset()
                ts.log('Saving file: %s' % dataset_filename)
                ds.to_csv(ts.result_file_path(dataset_filename))
                result_params['plot.title'] = dataset_filename.split('.csv')[0]
                ts.result_file(dataset_filename, params=result_params)
                result = script.RESULT_COMPLETE

    except script.ScriptFail as e:
        reason = str(e)
        if reason:
            ts.log_error(reason)

    except Exception as e:
        if dataset_filename is not None:
            dataset_filename = filename + ".csv"
            daq.data_capture(False)
            ds = daq.data_capture_dataset()
            ts.log('Saving file: %s' % dataset_filename)
            ds.to_csv(ts.result_file_path(dataset_filename))
            result_params['plot.title'] = dataset_filename.split('.csv')[0]
            ts.result_file(dataset_filename, params=result_params)
        ts.log_error('Test script exception: %s' % traceback.format_exc())

    finally:
        if grid is not None:
            grid.close()
        if pv is not None:
            if p_rated is not None:
                pv.power_set(p_rated)
            pv.close()
        if daq is not None:
            daq.close()
        if eut is not None:
            #eut.fixed_pf(params={'Ena': False, 'PF': 1.0})
            eut.close()
        if rs is not None:
            rs.close()
        if chil is not None:
            chil.close()

        if result_summary is not None:
            result_summary.close()

        # create result workbook
        excelfile = ts.config_name() + '.xlsx'
        rslt.result_workbook(excelfile, ts.results_dir(), ts.result_dir())
        ts.result_file(excelfile)

    return result
예제 #12
0
def test_run():
    result = script.RESULT_FAIL
    grid = None
    pv = p_rated = None
    daq = None
    eut = None
    rs = None
    chil = None
    result_summary = None
    step_label = None
    q_initial = None
    dataset_filename = None

    try:

        cat = ts.param_value('eut.cat')
        cat2 = ts.param_value('eut.cat2')
        sink_power = ts.param_value('eut.sink_power')
        p_rated = ts.param_value('eut.p_rated')
        p_rated_prime = ts.param_value('eut.p_rated_prime')
        s_rated = ts.param_value('eut.s_rated')
        var_rated = ts.param_value('eut.var_rated')

        # DC voltages
        v_nom_in_enabled = ts.param_value('crp.v_in_nom')
        v_min_in_enabled = ts.param_value('crp.v_in_min')
        v_max_in_enabled = ts.param_value('crp.v_in_max')

        v_nom_in = ts.param_value('eut.v_in_nom')
        v_min_in = ts.param_value('eut_crp.v_in_min')
        v_max_in = ts.param_value('eut_crp.v_in_max')

        # AC voltages
        v_nom = ts.param_value('eut.v_nom')
        v_min = ts.param_value('eut.v_low')
        v_max = ts.param_value('eut.v_high')
        p_min = ts.param_value('eut.p_min')
        p_min_prime = ts.param_value('eut.p_min_prime')
        phases = ts.param_value('eut.phases')
        pf_response_time = ts.param_value('crp.pf_response_time')

        # Pass/fail accuracies
        pf_msa = ts.param_value('eut.pf_msa')

        # Imbalance configuration
        imbalance_fix = ts.param_value('crp.imbalance_fix')

        # EUI Absorb capabilities
        absorb = {}
        absorb['ena'] = ts.param_value('eut_crp.sink_power')
        absorb['p_rated_prime'] = ts.param_value('eut_crp.p_rated_prime')
        absorb['p_min_prime'] = ts.param_value('eut_crp.p_min_prime')
        """
        Version validation
        """
        p1547.VersionValidation(script_version=ts.info.version)
        """
        A separate module has been create for the 1547.1 Standard
        """
        ActiveFunction = p1547.ActiveFunction(
            ts=ts,
            functions='CRP',
            script_name='Constant Reactive Power',
            criteria_mode=[True, False, False])
        ActiveFunction.set_imbalance_config(imbalance_angle_fix=imbalance_fix)
        ts.log_debug("1547.1 Library configured for %s" %
                     ActiveFunction.get_script_name())

        # result params
        result_params = ActiveFunction.get_rslt_param_plot()

        #get target q relative value
        q_targets = {}

        if ts.param_value('crp.q_max_abs_enable') == 'Enabled':
            q_targets['crp_q_max_abs'] = float(
                ts.param_value('crp.q_max_abs_value'))
        if ts.param_value('crp.q_max_inj_enable') == 'Enabled':
            q_targets['crp_q_max_inj'] = float(
                ts.param_value('crp.q_max_inj_value'))
        if ts.param_value('crp.half_q_max_abs_enable') == 'Enabled':
            q_targets['crp_half_q_max_abs'] = 0.5 * float(
                ts.param_value('crp.q_max_abs_value'))
        if ts.param_value('crp.half_q_max_inj_enable') == 'Enabled':
            q_targets['crp_half_q_max_inj'] = 0.5 * float(
                ts.param_value('crp.q_max_inj_value'))

        #get q max value
        #q_max_value = ts.param_value('crp.q_max_value')

        v_in_targets = {}

        if v_nom_in_enabled == 'Enabled':
            v_in_targets['v_nom_in'] = v_nom_in
        if v_min_in != v_nom_in and v_min_in_enabled == 'Enabled':
            v_in_targets['v_min_in'] = v_min_in
        if v_max_in != v_nom_in and v_max_in_enabled == 'Enabled':
            v_in_targets['v_max_in'] = v_max_in
        if not v_in_targets:
            ts.log_error('No V_in target specify. Please select a V_IN test')
        """
        a) Connect the EUT according to the instructions and specifications provided by the manufacturer.
        """
        # initialize HIL environment, if necessary
        chil = hil.hil_init(ts)
        if chil is not None:
            chil.config()

        # grid simulator is initialized with test parameters and enabled
        grid = gridsim.gridsim_init(ts, support_interfaces={
            'hil': chil
        })  # Turn on AC so the EUT can be initialized
        if grid is not None:
            grid.voltage(v_nom)

        # pv simulator is initialized with test parameters and enabled
        pv = pvsim.pvsim_init(ts)
        if pv is not None:
            pv.power_set(p_rated)
            pv.power_on()  # Turn on DC so the EUT can be initialized

        # DAS soft channels
        #das_points = {'sc': ('V_MEAS', 'P_MEAS', 'Q_MEAS', 'Q_TARGET_MIN', 'Q_TARGET_MAX', 'PF_TARGET', 'event')}
        das_points = ActiveFunction.get_sc_points()

        # initialize data acquisition
        daq = das.das_init(ts, sc_points=das_points['sc'])

        if daq is not None:
            daq.sc['V_MEAS'] = 100
            daq.sc['P_MEAS'] = 100
            daq.sc['Q_MEAS'] = 100
            daq.sc['Q_TARGET_MIN'] = 100
            daq.sc['Q_TARGET_MAX'] = 100
            daq.sc['PF_TARGET'] = 1
            daq.sc['event'] = 'None'
            ts.log('DAS device: %s' % daq.info())
        """
        b) Set all voltage trip parameters to the widest range of adjustability. Disable all reactive/active power
        control functions.
        """
        # it is assumed the EUT is on
        eut = der.der_init(ts)
        if eut is not None:
            eut.config()
            # disable volt/var curve
            #eut.volt_var(params={'Ena': False})
            ts.log_debug(
                'If not done already, set L/HVRT and trip parameters to the widest range of adjustability.'
            )

        # Special considerations for CHIL ASGC/Typhoon startup #
        if chil is not None:
            inv_power = eut.measurements().get('W')
            timeout = 120.
            if inv_power <= p_rated * 0.85:
                pv.irradiance_set(
                    995)  # Perturb the pv slightly to start the inverter
                ts.sleep(3)
                eut.connect(params={'Conn': True})
            while inv_power <= p_rated * 0.85 and timeout >= 0:
                ts.log(
                    'Inverter power is at %0.1f. Waiting up to %s more seconds or until EUT starts...'
                    % (inv_power, timeout))
                ts.sleep(1)
                timeout -= 1
                inv_power = eut.measurements().get('W')
                if timeout == 0:
                    result = script.RESULT_FAIL
                    raise der.DERError('Inverter did not start.')
            ts.log('Waiting for EUT to ramp up')
            ts.sleep(8)
        """
        c) Set all AC test source parameters to the nominal operating voltage and frequency.
        """
        if grid is not None:
            grid.voltage(v_nom)

        # open result summary file
        result_summary_filename = 'result_summary.csv'
        result_summary = open(ts.result_file_path(result_summary_filename),
                              'a+')
        ts.result_file(result_summary_filename)
        result_summary.write(ActiveFunction.get_rslt_sum_col_name())
        """
        d) Adjust the EUT's available active power to Prated. For an EUT with an input voltage range, set the input
        voltage to Vin_nom. The EUT may limit active power throughout the test to meet reactive power requirements.

        s) For an EUT with an input voltage range, repeat steps d) through o) for Vin_min and Vin_max.
        """
        # TODO: Include step t)
        """
        t) Steps d) through q) may be repeated to test additional communication protocols - Run with another test.
        """

        # For PV systems, this requires that Vmpp = Vin_nom and Pmpp = Prated.
        for v_in_label, v_in in v_in_targets.items():
            ts.log('Starting test %s at v_in = %s' % (v_in_label, v_in))
            a_v = ActiveFunction.MRA['V'] * 1.5
            #Set response time recording
            ActiveFunction.reset_time_settings(tr=pf_response_time)

            if pv is not None:
                pv.iv_curve_config(pmp=p_rated, vmp=v_in)
                pv.irradiance_set(1000.)
            """
            e) Enable constant power factor mode and set the EUT power factor to PFmin,inj.
            r) Repeat steps d) through o) for additional power factor settings: PFmin,ab, PFmid,inj, PFmid,ab.

            Only the user-selected PF setting will be tested.
            """
            for q_test_name, q_target in q_targets.items():

                # Setting up step label
                ActiveFunction.set_step_label(starting_label='F')

                q_target *= var_rated

                ts.log('Starting data capture for fixed Q relative = %s' %
                       q_target)

                if imbalance_fix == "Yes":
                    dataset_filename = ('{0}_{1}_FIX'.format(
                        v_in_label.upper(), q_test_name.upper()))
                else:
                    dataset_filename = ('{0}_{1}'.format(
                        v_in_label.upper(), q_test_name.upper()))
                ts.log('------------{}------------'.format(dataset_filename))
                ActiveFunction.reset_filename(filename=dataset_filename)
                # Start the data acquisition systems
                daq.data_capture(True)

                daq.sc['Q_TARGET'] = q_target

                if eut is not None:
                    parameters = {'Ena': True, 'Q': q_target, 'Wmax': p_rated}
                    ts.log('Parameters set: %s' % parameters)
                    eut.reactive_power(params=parameters)
                    vars_setting = eut.reactive_power(params=parameters)
                    ts.log('fixed vars setting read: %s' % vars_setting)
                """
                f) Verify Constant Var mode is reported as active and that the power factor setting is reported 
                as Qmax,inj.

                """
                step_label = ActiveFunction.get_step_label()
                daq.sc['event'] = step_label
                daq.data_sample()
                ts.log('Wait for steady state to be reached')
                ts.sleep(2 * pf_response_time)
                """
                g) Step the EUT's active power to 20% of Prated or Pmin, whichever is less.
                """
                if pv is not None:
                    step_label = ActiveFunction.get_step_label()
                    ts.log(
                        'Power step: setting PV simulator power to %s (%s)' %
                        (p_min, step_label))
                    ActiveFunction.start(daq=daq, step_label=step_label)
                    if p_rated * 0.2 > p_min:
                        p_target = p_min
                    else:
                        p_target = p_rated * 0.2
                    step_dict = {
                        'V': v_nom,
                        'P': round(p_target, 2),
                        'Q': q_target
                    }
                    pv.power_set(step_dict['P'])
                    ActiveFunction.record_timeresponse(daq=daq)
                    ActiveFunction.evaluate_criterias(daq=daq,
                                                      step_dict=step_dict)
                    result_summary.write(ActiveFunction.write_rslt_sum())
                """
                h) Step the EUT's active power to 5% of Prated or Pmin, whichever is less.
                """
                if pv is not None:
                    step_label = ActiveFunction.get_step_label()
                    ts.log(
                        'Power step: setting PV simulator power to %s (%s)' %
                        (p_min, step_label))
                    ActiveFunction.start(daq=daq, step_label=step_label)
                    if p_rated * 0.05 > p_min:
                        p_target = p_min
                    else:
                        p_target = p_rated * 0.05
                    step_dict = {
                        'V': v_nom,
                        'P': round(p_target, 2),
                        'Q': q_target
                    }
                    pv.power_set(step_dict['P'])
                    ActiveFunction.record_timeresponse(daq=daq)
                    ActiveFunction.evaluate_criterias(daq=daq,
                                                      step_dict=step_dict)
                    result_summary.write(ActiveFunction.write_rslt_sum())
                """
                i) Step the EUT's available active power to Prated.
                """
                if pv is not None:
                    step_label = ActiveFunction.get_step_label()
                    ts.log(
                        'Power step: setting PV simulator power to %s (%s)' %
                        (p_rated, step_label))
                    ActiveFunction.start(daq=daq, step_label=step_label)
                    step_dict = {'V': v_nom, 'P': p_rated, 'Q': q_target}
                    pv.power_set(step_dict['P'])
                    ActiveFunction.record_timeresponse(daq=daq)
                    ActiveFunction.evaluate_criterias(daq=daq,
                                                      step_dict=step_dict)
                    result_summary.write(ActiveFunction.write_rslt_sum())

                if grid is not None:
                    #   J) Step the AC test source voltage to (VL + av)
                    step_label = ActiveFunction.get_step_label()
                    ts.log(
                        'Voltage step: setting Grid simulator voltage to %s (%s)'
                        % ((v_min + a_v), step_label))
                    ActiveFunction.start(daq=daq, step_label=step_label)
                    step_dict = {'V': v_min + a_v, 'P': p_rated, 'Q': q_target}
                    grid.voltage(step_dict['V'])
                    ActiveFunction.record_timeresponse(daq=daq)
                    ActiveFunction.evaluate_criterias(daq=daq,
                                                      step_dict=step_dict)
                    result_summary.write(ActiveFunction.write_rslt_sum())

                    #   k) Step the AC test source voltage to (VH - av)
                    step_label = ActiveFunction.get_step_label()
                    ts.log(
                        'Voltage step: setting Grid simulator voltage to %s (%s)'
                        % ((v_max - a_v), step_label))
                    ActiveFunction.start(daq=daq, step_label=step_label)
                    step_dict = {'V': v_max - a_v, 'P': p_rated, 'Q': q_target}
                    grid.voltage(step_dict['V'])
                    ActiveFunction.record_timeresponse(daq=daq)
                    ActiveFunction.evaluate_criterias(daq=daq,
                                                      step_dict=step_dict)
                    result_summary.write(ActiveFunction.write_rslt_sum())

                    #   l) Step the AC test source voltage to (VL + av)
                    step_label = ActiveFunction.get_step_label()
                    ts.log(
                        'Voltage step: setting Grid simulator voltage to %s (%s)'
                        % ((v_min + a_v), step_label))
                    ActiveFunction.start(daq=daq, step_label=step_label)
                    step_dict = {'V': v_min + a_v, 'P': p_rated, 'Q': q_target}
                    grid.voltage(step_dict['V'])
                    ActiveFunction.record_timeresponse(daq=daq)
                    ActiveFunction.evaluate_criterias(daq=daq,
                                                      step_dict=step_dict)
                    result_summary.write(ActiveFunction.write_rslt_sum())

                    if phases == 'Three phase':
                        #   m) For multiphase units, step the AC test source voltage to VN
                        step_label = ActiveFunction.get_step_label()
                        ts.log(
                            'Voltage step: setting Grid simulator voltage to %s (%s)'
                            % (v_nom, step_label))
                        ActiveFunction.start(daq=daq, step_label=step_label)
                        step_dict = {'V': v_nom, 'P': p_rated, 'Q': q_target}
                        grid.voltage(step_dict['V'])
                        ActiveFunction.record_timeresponse(daq=daq)
                        ActiveFunction.evaluate_criterias(daq=daq,
                                                          step_dict=step_dict)
                        result_summary.write(ActiveFunction.write_rslt_sum())
                    '''
                    n) For multiphase units, step the AC test source voltage to Case A from Table 24.
                    '''

                    if grid is not None and phases == 'Three phase':
                        step_label = ActiveFunction.get_step_label()
                        ts.log(
                            'Voltage step: setting Grid simulator to case A (IEEE 1547.1-Table 24)(%s)'
                            % step_label)
                        ActiveFunction.start(daq=daq, step_label=step_label)
                        v_target = ActiveFunction.set_grid_asymmetric(
                            grid=grid, case='case_a')
                        step_dict = {
                            'V': v_target,
                            'P': p_rated,
                            'Q': q_target
                        }
                        ActiveFunction.record_timeresponse(daq=daq)
                        ActiveFunction.evaluate_criterias(daq=daq,
                                                          step_dict=step_dict)
                        result_summary.write(ActiveFunction.write_rslt_sum())
                    """
                    o) For multiphase units, step the AC test source voltage to VN.
                    """

                    if grid is not None and phases == 'Three phase':
                        step_label = ActiveFunction.get_step_label()
                        ts.log(
                            'Voltage step: setting Grid simulator voltage to %s (%s)'
                            % (v_nom, step_label))
                        ActiveFunction.start(daq=daq, step_label=step_label)
                        step_dict = {'V': v_nom, 'P': p_rated, 'Q': q_target}
                        grid.voltage(step_dict['V'])
                        ActiveFunction.record_timeresponse(daq=daq)
                        ActiveFunction.evaluate_criterias(daq=daq,
                                                          step_dict=step_dict)
                        result_summary.write(ActiveFunction.write_rslt_sum())
                    """
                    p) For multiphase units, step the AC test source voltage to Case B from Table 24.
                    """
                    if grid is not None and phases == 'Three phase':
                        step_label = ActiveFunction.get_step_label()
                        ts.log(
                            'Voltage step: setting Grid simulator to case B (IEEE 1547.1-Table 24)(%s)'
                            % step_label)
                        ActiveFunction.start(daq=daq, step_label=step_label)
                        v_target = ActiveFunction.set_grid_asymmetric(
                            grid=grid, case='case_b')
                        step_dict = {
                            'V': v_target,
                            'P': p_rated,
                            'Q': q_target
                        }
                        ActiveFunction.record_timeresponse(daq=daq)
                        ActiveFunction.evaluate_criterias(daq=daq,
                                                          step_dict=step_dict)
                        result_summary.write(ActiveFunction.write_rslt_sum())
                    """
                    q) For multiphase units, step the AC test source voltage to VN
                    """
                    if grid is not None and phases == 'Three phase':
                        step_label = ActiveFunction.get_step_label()
                        ts.log(
                            'Voltage step: setting Grid simulator voltage to %s (%s)'
                            % (v_nom, step_label))
                        ActiveFunction.start(daq=daq, step_label=step_label)
                        step_dict = {'V': v_nom, 'P': p_rated, 'Q': q_target}
                        grid.voltage(step_dict['V'])
                        ActiveFunction.record_timeresponse(daq=daq)
                        ActiveFunction.evaluate_criterias(daq=daq,
                                                          step_dict=step_dict)
                        result_summary.write(ActiveFunction.write_rslt_sum())
                """
                r) Disable constant power factor mode. Power factor should return to unity.
                """
                if eut is not None:
                    parameters = {'Ena': False}
                    #ts.log('PF set: %s' % parameters)
                    eut.fixed_var(params=parameters)
                    var_setting = eut.fixed_var()
                    ts.log('Reactive Power setting read: %s' % vars_setting)
                    daq.sc['event'] = ActiveFunction.get_step_label()
                    daq.data_sample()
                    ts.sleep(4 * pf_response_time)
                    daq.sc['event'] = 'T_settling_done'
                    daq.data_sample()
                """
                q) Verify all reactive/active power control functions are disabled.
                """
                if eut is not None:
                    ts.log(
                        'Reactive/active power control functions are disabled.'
                    )
                    # TODO Implement ts.prompt functionality?
                    # meas = eut.measurements()
                    # ts.log('EUT PF is now: %s' % (data.get('AC_PF_1')))
                    # ts.log('EUT Power: %s, EUT Reactive Power: %s' % (meas['W'], meas['VAr']))

                ts.log('Sampling complete')
                dataset_filename = dataset_filename + ".csv"
                daq.data_capture(False)
                ds = daq.data_capture_dataset()
                ts.log('Saving file: %s' % dataset_filename)
                ds.to_csv(ts.result_file_path(dataset_filename))
                result_params['plot.title'] = dataset_filename.split('.csv')[0]
                ts.result_file(dataset_filename, params=result_params)
                result = script.RESULT_COMPLETE

    except script.ScriptFail as e:
        reason = str(e)
        if reason:
            ts.log_error(reason)

    except Exception as e:
        if dataset_filename is not None:
            dataset_filename = dataset_filename + ".csv"
            daq.data_capture(False)
            ds = daq.data_capture_dataset()
            ts.log('Saving file: %s' % dataset_filename)
            ds.to_csv(ts.result_file_path(dataset_filename))
            result_params['plot.title'] = dataset_filename.split('.csv')[0]
            ts.result_file(dataset_filename, params=result_params)
        ts.log_error('Test script exception: %s' % traceback.format_exc())

    finally:

        if grid is not None:
            grid.close()
        if pv is not None:
            if p_rated is not None:
                pv.power_set(p_rated)
            pv.close()
        if daq is not None:
            daq.close()
        if eut is not None:
            #eut.reactive_power(params={'Ena': False})
            eut.close()
        if rs is not None:
            rs.close()
        if chil is not None:
            chil.close()

        if result_summary is not None:
            result_summary.close()

        # create result workbook
        excelfile = ts.config_name() + '.xlsx'
        rslt.result_workbook(excelfile, ts.results_dir(), ts.result_dir())
        ts.result_file(excelfile)

    return result
예제 #13
0
def test_run():
    eut = None
    chil = None
    pv = None
    result = script.RESULT_FAIL

    try:
        # Get the parameters for the test from the UI
        pf_start = ts.param_value('test.pf_start')
        pf_end = ts.param_value('test.pf_stop')
        steps = ts.param_value('test.pf_steps_per_side')
        sleep_time = ts.param_value('test.wait_time')

        # Initialize DER configuration
        eut = der.der_init(ts)
        eut.config()

        # Initialize CHIL environment, if necessary
        chil = hil.hil_init(ts)
        if chil is not None:
            chil.config()

        # PV simulator is initialized with test parameters and enabled
        pv = pvsim.pvsim_init(ts)
        pv.irradiance_set(800)
        pv.power_on()
        # Print information from the DER
        ts.log('---')
        info = eut.info()
        if info is not None:
            ts.log('DER info:')
            ts.log('  Manufacturer: %s' % (info.get('Manufacturer')))
            ts.log('  Model: %s' % (info.get('Model')))
            ts.log('  Options: %s' % (info.get('Options')))
            ts.log('  Version: %s' % (info.get('Version')))
            ts.log('  Serial Number: %s' % (info.get('SerialNumber')))
        else:
            ts.log_warning('DER info not supported')
        ts.log('---')
        fixed_pf = eut.fixed_pf()
        if fixed_pf is not None:
            ts.log('DER fixed_pf:')
            ts.log('  Ena: %s' % (fixed_pf.get('Ena')))
            ts.log('  PF: %s' % (fixed_pf.get('PF')))
            ts.log('  WinTms: %s' % (fixed_pf.get('WinTms')))
            ts.log('  RmpTms: %s' % (fixed_pf.get('RmpTms')))
            ts.log('  RvrtTms: %s' % (fixed_pf.get('RvrtTms')))
        else:
            ts.log_warning('DER fixed_pf not supported')
        ts.log('---')

        # Get EUT nameplate power
        eut_nameplate_power = eut.nameplate().get('WRtg')

        # disable volt/var, VW, FW
        eut.volt_var(params={'Ena': False})
        eut.volt_watt(params={'Ena': False})
        eut.freq_watt(params={'Ena': False})

        inv_power = eut.measurements().get('W')
        timeout = 120.
        if inv_power <= eut_nameplate_power / 10.:
            pv.irradiance_set(800)  # Perturb the pv slightly to start the inverter
            ts.sleep(3)
            eut.connect(params={'Conn': True})
        while inv_power <= eut_nameplate_power / 10. and timeout >= 0:
            ts.log('Inverter power is at %0.1f. Waiting %s more seconds or until EUT starts...' % (inv_power, timeout))
            ts.sleep(1)
            timeout -= 1
            inv_power = eut.measurements().get('W')
            if timeout == 0:
                result = script.RESULT_FAIL
                raise der.DERError('Inverter did not start.')



        # Create list of the power factor values to iterate over
        pf_values = list(np.linspace(pf_start, 1.0, num=steps)) + list(np.linspace(-1.0, pf_end, num=steps)[1:])
        # ts.log('Setting DER to the following PF values: %s' % pf_values)

        # Run the test for 3 different irradiance values
        for irr in [1000, 600, 300]:
            pv.irradiance_set(irr)  # Set irradiance of the PV simulator

            for pf in pf_values:
                # Send PF setting to the equipment under test (EUT)
                eut.fixed_pf(params={'Ena': True, 'PF': pf, 'WinTms': 0, 'RmpTms': 0, 'RvrtTms': 0})
                ts.log('Power Factor set to %0.3f. Sleeping for %0.2f seconds...' % (pf, sleep_time))
                ts.sleep(sleep_time)

        # Disable the PF function
        eut.fixed_pf(params={'Ena': False})
        ts.log('Power Factor Disabled')

        result = script.RESULT_COMPLETE

    except Exception, e:
        ts.log_error('Script failure: %s' % e)
예제 #14
0
def test_run():
    result = script.RESULT_FAIL
    grid = None
    pv = p_rated = None
    daq = None
    eut = None
    rs = None
    chil = None
    result_summary = None
    step = None
    q_initial = None
    dataset_filename = None
    result_params = None

    try:

        cat = ts.param_value('eut.cat')
        cat2 = ts.param_value('eut.cat2')
        sink_power = ts.param_value('eut.sink_power')
        p_rated = ts.param_value('eut.p_rated')
        p_rated_prime = ts.param_value('eut.p_rated_prime')
        s_rated = ts.param_value('eut.s_rated')
        var_rated = ts.param_value('eut.var_rated')

        # DC voltages
        v_nom_in_enabled = ts.param_value('crp.v_in_nom')
        v_min_in_enabled = ts.param_value('crp.v_in_min')
        v_max_in_enabled = ts.param_value('crp.v_in_max')

        v_nom_in = ts.param_value('eut.v_in_nom')
        v_min_in = ts.param_value('eut_crp.v_in_min')
        v_max_in = ts.param_value('eut_crp.v_in_max')

        # AC voltages
        v_nom = ts.param_value('eut.v_nom')
        v_min = ts.param_value('eut.v_low')
        v_max = ts.param_value('eut.v_high')
        p_min = ts.param_value('eut.p_min')
        p_min_prime = ts.param_value('eut.p_min_prime')
        phases = ts.param_value('eut.phases')
        response_time = ts.param_value('crp.response_time')

        # Imbalance configuration
        imbalance_fix = ts.param_value('crp.imbalance_fix')

        # EUI Absorb capabilities
        absorb = {}
        absorb['ena'] = ts.param_value('eut_crp.sink_power')
        absorb['p_rated_prime'] = ts.param_value('eut_crp.p_rated_prime')
        absorb['p_min_prime'] = ts.param_value('eut_crp.p_min_prime')
        """
        A separate module has been create for the 1547.1 Standard
        """
        lib_1547 = p1547.module_1547(ts=ts, aif='CRP', absorb=absorb)
        ts.log_debug("1547.1 Library configured for %s" %
                     lib_1547.get_test_name())

        # result params
        result_params = lib_1547.get_rslt_param_plot()

        # get target q relative value
        q_targets = {}
        if ts.param_value('crp.q_max_abs_enable') == 'Enabled':
            q_targets['crp_q_max_abs'] = float(
                ts.param_value('crp.q_max_abs_value'))
        if ts.param_value('crp.q_max_inj_enable') == 'Enabled':
            q_targets['crp_q_max_inj'] = float(
                ts.param_value('crp.q_max_inj_value'))
        if ts.param_value('crp.half_q_max_abs_enable') == 'Enabled':
            q_targets['crp_half_q_max_abs'] = 0.5 * float(
                ts.param_value('crp.q_max_abs_value'))
        if ts.param_value('crp.half_q_max_inj_enable') == 'Enabled':
            q_targets['crp_half_q_max_inj'] = 0.5 * float(
                ts.param_value('crp.q_max_inj_value'))
        ts.log('Evaluating the following Reactive Power Targets: %s' %
               q_targets)

        v_in_targets = {}
        if v_nom_in_enabled == 'Enabled':
            v_in_targets['v_nom_in'] = v_nom_in
        if v_min_in != v_nom_in and v_min_in_enabled == 'Enabled':
            v_in_targets['v_min_in'] = v_min_in
        if v_max_in != v_nom_in and v_max_in_enabled == 'Enabled':
            v_in_targets['v_max_in'] = v_max_in
        if not v_in_targets:
            raise ts.log_error(
                'No V_in target specify. Please select a V_IN test')
        """
        a) Connect the EUT according to the instructions and specifications provided by the manufacturer.
        """
        # initialize HIL environment, if necessary
        chil = hil.hil_init(ts)
        if chil is not None:
            chil.config()

        # grid simulator is initialized with test parameters and enabled
        grid = gridsim.gridsim_init(ts, support_interfaces={
            'hil': chil
        })  # Turn on AC so the EUT can be initialized
        if grid is not None:
            grid.voltage(v_nom)

        # pv simulator is initialized with test parameters and enabled
        pv = pvsim.pvsim_init(ts)
        if pv is not None:
            pv.power_set(p_rated)
            pv.power_on()  # Turn on DC so the EUT can be initialized
            start_up = 60
            ts.log('Waiting for EUT to power up. Sleeping %s sec.' % start_up)
            ts.sleep(start_up)

        das_points = lib_1547.get_sc_points()  # DAS soft channels
        # initialize data acquisition
        daq = das.das_init(ts,
                           sc_points=das_points['sc'],
                           support_interfaces={
                               'pvsim': pv,
                               'hil': chil
                           })
        if daq is not None:
            daq.sc['V_MEAS'] = None
            daq.sc['P_MEAS'] = None
            daq.sc['Q_MEAS'] = None
            daq.sc['Q_TARGET_MIN'] = None
            daq.sc['Q_TARGET_MAX'] = None
            daq.sc['PF_TARGET'] = None
            daq.sc['event'] = 'None'
            ts.log('DAS device: %s' % daq.info())
        """
        b) Set all voltage trip parameters to the widest range of adjustability. Disable all reactive/active power
        control functions.
        """
        # it is assumed the EUT is on
        eut = der.der_init(ts)
        if eut is not None:
            eut.config()
            eut.volt_var(params={'Ena': False})  # disable volt/var curve
            eut.watt_var(params={'Ena': False})
            eut.volt_watt(params={'Ena': False})
            ts.log_debug(
                'If not done already, set L/HVRT and trip parameters to the widest range of adjustability.'
            )

        # Special considerations for CHIL ASGC/Typhoon startup #
        if chil is not None:
            if chil.hil_info()['mode'] == 'Typhoon':
                inv_power = eut.measurements().get('W')
                timeout = 120.
                if inv_power <= p_rated * 0.85:
                    pv.irradiance_set(
                        995)  # Perturb the pv slightly to start the inverter
                    ts.sleep(3)
                    eut.connect(params={'Conn': True})
                while inv_power <= p_rated * 0.85 and timeout >= 0:
                    ts.log(
                        'Inverter power is at %0.1f. Waiting up to %s more seconds or until EUT starts...'
                        % (inv_power, timeout))
                    ts.sleep(1)
                    timeout -= 1
                    inv_power = eut.measurements().get('W')
                    if timeout == 0:
                        result = script.RESULT_FAIL
                        raise der.DERError('Inverter did not start.')
                ts.log('Waiting for EUT to ramp up')
                ts.sleep(8)
        """
        c) Set all AC test source parameters to the nominal operating voltage and frequency.
        """
        if grid is not None:
            grid.voltage(v_nom)

        # open result summary file
        result_summary_filename = 'result_summary.csv'
        result_summary = open(ts.result_file_path(result_summary_filename),
                              'a+')
        ts.result_file(result_summary_filename)
        result_summary.write(lib_1547.get_rslt_sum_col_name())
        """
        v) Steps d) through s) may be repeated to test additional protocols methods. (Rerun script in those cases)
        
        u) For an EUT with an input voltage range, repeat steps d) through t) for Vin_min and Vin_max
        """
        # For PV systems, this requires that Vmpp = Vin_nom and Pmpp = Prated.
        for v_in_label, v_in in v_in_targets.iteritems():
            ts.log('Starting test %s at v_in = %s' % (v_in_label, v_in))
            a_v = lib_1547.MRA_V * 1.5
            if pv is not None:
                pv.iv_curve_config(pmp=p_rated, vmp=v_in)
                pv.irradiance_set(1000.)
                ts.sleep(60.)  # Give EUT time to track new I-V Curve
            """
            t) Repeat steps d) through s) for additional reactive power settings: Qmax,ab, 0.5Qmax,inj, 0.5Qmax,ab.
            
            d) Adjust the EUT's active power to Prated. For an EUT with an input voltage range, set the input 
               voltage to Vin_nom.  (previously completed)
                
            e) Enable constant power factor mode and set the EUT power factor to PFmin,inj.
            """
            for q_test_name, q_target in q_targets.iteritems():
                dataset_filename = '%s_v=%0.1f' % (q_test_name, v_in)
                ts.log('------------{}------------'.format(dataset_filename))

                q_target *= var_rated
                ts.log('Starting data capture for fixed Q relative = %s' %
                       q_target)
                daq.data_capture(True)  # Start the data acquisition systems
                daq.sc['Q_TARGET'] = q_target

                if eut is not None:
                    parameters = {
                        'Ena': True,
                        'VArPct_Mod': 1,  # 1 = WMax percentage
                        'VArWMaxPct': (100. * q_target) / var_rated
                    }
                    ts.log('Parameters set: %s' % parameters)
                    eut.reactive_power(params=parameters)
                """
                f) Verify Constant Var mode is reported as active and that the reactive power setting is reported as 
                Qmax,inj.
                """
                ts.log('Waiting 15 seconds before reading back parameters')
                ts.sleep(15)
                vars_setting = eut.reactive_power()
                ts.log('fixed vars setting read: %s' % vars_setting)
                """
                g) Step the EUT's active power to 20% of Prated or Pmin, whichever is less.
                h) Step the EUT's active power to 5% of Prated or Pmin, whichever is less.
                i) Step the EUT's available active power to Prated.
                j) Step the AC test source voltage to (VL + av).
                k) Step the AC test source voltage to (VH - av).
                l) Step the AC test source voltage to (VL + av).
                m) For multiphase units, step the AC test source voltage to VN.
                n) For multiphase units, step the AC test source voltage to Case A from Table 24.
                o) For multiphase units, step the AC test source voltage to VN.
                p) For multiphase units, step the AC test source voltage to Case B from Table 24.
                q) For multiphase units, step the AC test source voltage to VN.
                """

                lib_1547.set_step_label(starting_label='G')
                crp_dict = collections.OrderedDict()
                crp_dict[lib_1547.get_step_label()] = {
                    'p_pv': min(0.2 * p_rated, p_min)
                }  # G
                crp_dict[lib_1547.get_step_label()] = {
                    'p_pv': min(0.05 * p_rated, p_min)
                }  # H
                crp_dict[lib_1547.get_step_label()] = {'p_pv': p_rated}  # I
                crp_dict[lib_1547.get_step_label()] = {'V': v_min + a_v}  # J
                crp_dict[lib_1547.get_step_label()] = {'V': v_max - a_v}  # K
                crp_dict[lib_1547.get_step_label()] = {'V': v_min + a_v}  # L
                crp_dict[lib_1547.get_step_label()] = {'V': v_nom}  # M
                if imbalance_fix == "Yes":
                    crp_dict[lib_1547.get_step_label()] = {
                        'V': [v_nom * 1.07, v_nom * 0.91, v_nom * 0.91]
                    }  # N
                    crp_dict[lib_1547.get_step_label()] = {'V': v_nom}  # O
                    crp_dict[lib_1547.get_step_label()] = {
                        'V': [v_nom * 0.91, v_nom * 1.07, v_nom * 1.07]
                    }  # P
                    crp_dict[lib_1547.get_step_label()] = {'V': v_nom}  # Q

                for step_label, step_change in crp_dict.iteritems():

                    daq.data_sample()
                    initial_values = lib_1547.get_initial_value(
                        daq=daq, step=step_label)
                    if pv is not None and step_change.get('p_pv') is not None:
                        pwr_lvl = step_change.get('p_pv')
                        ts.log(
                            'Power step: setting PV simulator power to %s (%s)'
                            % (pwr_lvl, step))
                        pv.power_set(pwr_lvl)

                    if grid is not None and step_change.get('V') is not None:
                        volt = step_change.get('V')
                        ts.log(
                            'Voltage step: setting grid simulator voltage to %s (%s)'
                            % (volt, step))
                        grid.voltage(volt)

                    lib_1547.process_data(daq=daq,
                                          tr=response_time,
                                          step=step_label,
                                          pwr_lvl=1.0,
                                          y_target=q_target,
                                          initial_value=initial_values,
                                          result_summary=result_summary,
                                          filename=dataset_filename,
                                          number_of_tr=1)
                """
                r) Disable constant reactive power mode. Reactive power should return to zero.
                s) Verify all reactive/active power control functions are disabled.
                """
                if eut is not None:
                    ts.log('Reactive Power disabled. Readback: %s' %
                           eut.reactive_power(params={'Ena': False}))

                step_label = lib_1547.get_step_label()
                ts.log(
                    'Waiting %s seconds to get the next Tr data for analysis...'
                    % response_time)
                ts.sleep(response_time)
                daq.data_sample()  # sample new data
                data = daq.data_capture_read(
                )  # Return dataset created from last data capture
                q_meas = lib_1547.get_measurement_total(data=data,
                                                        type_meas='Q',
                                                        log=False)
                daq.sc['Q_MEAS'] = q_meas
                daq.sc['Q_TARGET'] = 0.0
                daq.sc['EVENT'] = "{0}_TR_1".format(step_label)
                daq.sc[
                    'Q_TARGET_MIN'] = daq.sc['Q_TARGET'] - 1.5 * lib_1547.MRA_Q
                daq.sc[
                    'Q_TARGET_MAX'] = daq.sc['Q_TARGET'] + 1.5 * lib_1547.MRA_Q
                if daq.sc['Q_TARGET_MIN'] <= daq.sc['Q_MEAS'] <= daq.sc[
                        'Q_TARGET_MAX']:
                    daq.sc['90%_BY_TR=1'] = 'Pass'
                else:
                    daq.sc['90%_BY_TR=1'] = 'Fail'
                ts.log_debug(
                    'Disabled CRP: q_min [%s] <= q_meas [%s] <= q_max [%s] = %s'
                    % (daq.sc['Q_TARGET_MIN'], daq.sc['Q_MEAS'],
                       daq.sc['Q_TARGET_MAX'], daq.sc['90%_BY_TR=1']))
                daq.data_sample()

                # 90%_BY_TR=1, V_MEAS, V_TARGET, P_MEAS, P_TARGET, Q_MEAS, Q_TARGET, Q_TARGET_MIN,
                # Q_TARGET_MAX, PF_MEAS, STEP, FILENAME
                row_data = []
                row_data.append(str(daq.sc['90%_BY_TR=1']))
                row_data.append(
                    str(
                        lib_1547.get_measurement_total(data=data,
                                                       type_meas='V',
                                                       log=False)))
                row_data.append('None')
                row_data.append(
                    str(
                        lib_1547.get_measurement_total(data=data,
                                                       type_meas='P',
                                                       log=False)))
                row_data.append('None')
                row_data.append(str(daq.sc['Q_MEAS']))
                row_data.append(str(daq.sc['Q_TARGET']))
                row_data.append(str(daq.sc['Q_TARGET_MIN']))
                row_data.append(str(daq.sc['Q_TARGET_MAX']))
                row_data.append(
                    str(
                        lib_1547.get_measurement_total(data=data,
                                                       type_meas='PF',
                                                       log=False)))
                row_data.append(str(step_label))
                row_data.append(str(dataset_filename))
                row_data_str = ','.join(row_data) + '\n'
                result_summary.write(row_data_str)

                ts.log('Sampling complete')
                dataset_filename = dataset_filename + ".csv"
                daq.data_capture(False)
                ds = daq.data_capture_dataset()
                ts.log('Saving file: %s' % dataset_filename)
                ds.to_csv(ts.result_file_path(dataset_filename))
                result_params['plot.title'] = dataset_filename.split('.csv')[0]
                ts.result_file(dataset_filename, params=result_params)
                result = script.RESULT_COMPLETE

    except script.ScriptFail, e:
        reason = str(e)
        if reason:
            ts.log_error(reason)
예제 #15
0
def test_run():
    eut = None
    chil = None
    grid = None
    pv = None
    result_summary = None
    result = script.RESULT_FAIL

    try:
        v_nom = ts.param_value('test.v_nom')

        # Initialize DER configuration
        eut = der.der_init(ts)
        eut.config()

        # Initialize CHIL environment, if necessary
        chil = hil.hil_init(ts)
        if chil is not None:
            chil.config()

        # PV simulator is initialized with test parameters and enabled
        pv = pvsim.pvsim_init(ts)
        pv.irradiance_set(800)
        pv.power_on()

        # grid simulator is initialized with test parameters and enabled
        grid = gridsim.gridsim_init(ts)
        # sometimes when there's a xfmr between the gridsim and EUT, V_nom at EUT != V_nom_grid (gridsim nominal)
        try:
            v_nom_grid = grid.v_nom_param
        except Exception, e:
            v_nom_grid = v_nom

        # Get EUT nameplate power
        eut_nameplate_power = eut.nameplate().get('WRtg')

        inv_power = eut.measurements().get('W')
        timeout = 120.
        if inv_power <= eut_nameplate_power/10.:
            eut.connect(params={'Conn': True})
            pv.irradiance_set(800)  # Perturb the pv slightly to start the inverter
        while inv_power <= eut_nameplate_power/10. and timeout >= 0:
            ts.log('Inverter power is at %0.1f. Waiting %s more seconds or until EUT starts...' % (inv_power, timeout))
            ts.sleep(1)
            timeout -= 1
            inv_power = eut.measurements().get('W')
            if timeout == 0:
                result = script.RESULT_FAIL
                raise der.DERError('Inverter did not start.')

        eut.volt_var_curve(1, params={'v': [95, 98, 102, 105], 'var': [100, 0, 0, -100]})
        eut.volt_var(params={'ActCrv': 1, 'Ena': True})
        parameters = eut.volt_var()
        ts.log_debug('EUT VV settings (readback): %s' % parameters)

        # Create list of voltages to iterate over
        voltage_values = list(np.linspace(95, 105, num=50))
        sleep_time = 1.
        for voltage in voltage_values:
            v = ((voltage/100.) * v_nom_grid)
            grid.voltage(v)  # set grid voltage
            ts.log('      V = %0.3f V (%0.3f%%). Sleeping for %0.2f seconds...' % (v, voltage, sleep_time))
            ts.sleep(sleep_time)

        # Disable the VV function
        eut.volt_var(params={'Ena': False})
        ts.log('VV Disabled')

        # Close the connection to the CHIL
        if chil is not None:
            chil.close()

        result = script.RESULT_COMPLETE