Exemple #1
0
def forecastWork(modelDir, ind):
    ''' Run the model in its directory.'''

    (cellCapacity, dischargeRate, chargeRate, cellQuantity, cellCost) = \
     [float(ind[x]) for x in ('cellCapacity', 'dischargeRate', 'chargeRate', 'cellQuantity', 'cellCost')]
    demandCharge = float(ind['demandCharge'])
    retailCost = float(ind['retailCost'])

    battEff = float(ind.get("batteryEfficiency")) / 100.0
    dodFactor = float(ind.get('dodFactor')) / 100.0
    projYears = int(ind.get('projYears'))
    batteryCycleLife = int(ind.get('batteryCycleLife'))
    battCapacity = cellQuantity * float(ind['cellCapacity']) * dodFactor

    o = {}

    try:
        with open(pJoin(modelDir, 'hist.csv'), 'w') as f:
            f.write(ind['histCurve'].replace('\r', ''))
        df = pd.read_csv(pJoin(modelDir, 'hist.csv'), parse_dates=['dates'])
        df['month'] = df['dates'].dt.month
        df['dayOfYear'] = df['dates'].dt.dayofyear
        assert df.shape[0] >= 26280  # must be longer than 3 years
        assert df.shape[1] == 5
    except:
        raise Exception("CSV file is incorrect format.")

    confidence = float(ind['confidence']) / 100

    # ---------------------- MAKE PREDICTIONS ------------------------------- #
    # train model on previous data
    all_X = fc.makeUsefulDf(df)
    all_y = df['load']
    predictions = fc.neural_net_predictions(all_X, all_y)

    dailyLoadPredictions = [
        predictions[i:i + 24] for i in range(0, len(predictions), 24)
    ]
    weather = df['tempc'][-8760:]
    dailyWeatherPredictions = [
        weather[i:i + 24] for i in range(0, len(weather), 24)
    ]
    month = df['month'][-8760:]

    dispatched = [False] * 365
    # decide to implement VBAT every day for a year
    VB_power, VB_energy = [], []
    for i, (load24, temp24, m) in enumerate(
            zip(dailyLoadPredictions, dailyWeatherPredictions, month)):
        peak = max(load24)
        if fc.shouldDispatchPS(peak, m, df, confidence):
            dispatched[i] = True
            vbp, vbe = fc.pulp24hrBattery(load24, dischargeRate * cellQuantity,
                                          cellCapacity * cellQuantity, battEff)
            VB_power.extend(vbp)
            VB_energy.extend(vbe)
        else:
            VB_power.extend([0] * 24)
            VB_energy.extend([0] * 24)

    # -------------------- MODEL ACCURACY ANALYSIS -------------------------- #
    o['predictedLoad'] = predictions
    o['trainAccuracy'] = 0  #round(model.score(X_train, y_train) * 100, 2)
    o['testAccuracy'] = 0  #round(model.score(X_test, y_test) * 100, 2)

    # PRECISION AND RECALL
    maxDays = []
    for month in range(1, 13):
        test = df[df['month'] == month]
        maxDays.append(test.loc[test['load'].idxmax()]['dayOfYear'])

    shouldHaveDispatched = [False] * 365
    for day in maxDays:
        shouldHaveDispatched[day] = True

    truePositive = len([
        b
        for b in [i and j for (i, j) in zip(dispatched, shouldHaveDispatched)]
        if b
    ])
    falsePositive = len([
        b for b in
        [i and (not j) for (i, j) in zip(dispatched, shouldHaveDispatched)]
        if b
    ])
    falseNegative = len([
        b for b in [(not i) and j
                    for (i, j) in zip(dispatched, shouldHaveDispatched)] if b
    ])
    o['precision'] = round(
        truePositive / float(truePositive + falsePositive) * 100, 2)
    o['recall'] = round(
        truePositive / float(truePositive + falseNegative) * 100, 2)
    o['number_of_dispatches'] = len([i for i in dispatched if i])
    o['MAE'] = round(
        sum([
            abs(l - m) / m * 100
            for l, m in zip(predictions, list(all_y[-8760:]))
        ]) / 8760., 2)

    # ---------------------- FINANCIAL ANALYSIS ----------------------------- #

    # Calculate monthHours
    year = df[-8760:].copy()
    year.reset_index(inplace=True)
    year['hour'] = list(year.index)
    start = list(year.groupby('month').first()['hour'])
    finish = list(year.groupby('month').last()['hour'])
    monthHours = [(s, f + 1) for (s, f) in zip(start, finish)]

    demand = list(all_y[-8760:])
    peakDemand = [max(demand[s:f]) for s, f in monthHours]
    demandAdj = [d + p for d, p in zip(demand, VB_power)]
    peakDemandAdj = [max(demandAdj[s:f]) for s, f in monthHours]
    discharges = [f if f < 0 else 0 for f in VB_power]

    # Monthly Cost Comparison Table
    o['monthlyDemand'] = peakDemand
    o['monthlyDemandRed'] = peakDemandAdj
    o['ps'] = [p - s for p, s in zip(peakDemand, peakDemandAdj)]
    o['benefitMonthly'] = [x * demandCharge for x in o['ps']]

    # Demand Before and After Storage Graph
    o['demand'] = demand
    o['demandAfterBattery'] = demandAdj
    o['batteryDischargekW'] = VB_power
    o['batteryDischargekWMax'] = max(VB_power)

    batteryCycleLife = float(ind['batteryCycleLife'])
    # Battery State of Charge Graph
    # Turn dc's SoC into a percentage, with dodFactor considered.

    o['batterySoc'] = SoC = [100 - (e / battCapacity * 100) for e in VB_energy]

    # Estimate number of cyles the battery went through. Sums the percent of SoC.
    cycleEquivalents = sum([
        SoC[i] - SoC[i + 1]
        for i, x in enumerate(SoC[:-1]) if SoC[i + 1] < SoC[i]
    ]) / 100.0
    o['cycleEquivalents'] = cycleEquivalents
    o['batteryLife'] = batteryCycleLife / cycleEquivalents

    # Cash Flow Graph
    # inserting battery efficiency only into the cashflow calculation
    # cashFlowCurve is $ in from peak shaving minus the cost to recharge the battery every day of the year
    cashFlowCurve = [sum(o['ps']) * demandCharge for year in range(projYears)]
    cashFlowCurve.insert(0, -1 * cellCost *
                         cellQuantity)  # insert initial investment
    # simplePayback is also affected by the cost to recharge the battery every day of the year
    o['SPP'] = (cellCost * cellQuantity) / (sum(o['ps']) * demandCharge)
    o['netCashflow'] = cashFlowCurve
    o['cumulativeCashflow'] = [
        sum(cashFlowCurve[:i + 1]) for i, d in enumerate(cashFlowCurve)
    ]
    o['NPV'] = npv(float(ind['discountRate']), cashFlowCurve)

    battCostPerCycle = cellQuantity * cellCost / batteryCycleLife
    lcoeTotCost = cycleEquivalents * retailCost + battCostPerCycle * cycleEquivalents
    o['LCOE'] = lcoeTotCost / (cycleEquivalents * battCapacity)

    # Other
    o['startDate'] = '2011-01-01'  # dc[0]['datetime'].isoformat()
    o['stderr'] = ''
    # Seemingly unimportant. Ask permission to delete.
    o['stdout'] = 'Success'
    o['months'] = [
        "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct",
        "Nov", "Dec"
    ]

    return o
Exemple #2
0
def workForecast(modelDir, ind):
    ''' Run the model in its directory.'''
    o = {}

    # Grab data from CSV,
    try:
        with open(pJoin(modelDir, 'hist.csv'), 'w') as f:
            f.write(ind['histCurve'].replace('\r', ''))
        df = pd.read_csv(pJoin(modelDir, 'hist.csv'), parse_dates=['dates'])
        df['month'] = df['dates'].dt.month
        df['dayOfYear'] = df['dates'].dt.dayofyear
        assert df.shape[0] >= 26280  # must be longer than 3 years
        assert df.shape[1] == 5
    except:
        raise Exception("CSV file is incorrect format.")

    # train model on previous data
    all_X = fc.makeUsefulDf(df)
    all_y = df['load']
    X_train, y_train = all_X[:-8760], all_y[:-8760]
    clf = linear_model.SGDRegressor(max_iter=10000, tol=1e-4)
    clf.fit(X_train, y_train)

    # ---------------------- MAKE PREDICTIONS ------------------------------- #
    X_test, y_test = all_X[-8760:], all_y[-8760:]
    predictions = clf.predict(X_test)
    dailyLoadPredictions = [
        predictions[i:i + 24] for i in range(0, len(predictions), 24)
    ]

    P_lower, P_upper, E_UL = vbat24hr(ind, df['tempc'][-8760:])
    dailyPl = [P_lower[i:i + 24] for i in range(0, len(P_lower), 24)]
    dailyPu = [P_upper[i:i + 24] for i in range(0, len(P_upper), 24)]
    dailyEu = [E_UL[i:i + 24] for i in range(0, len(E_UL), 24)]

    vbp, vbe = [], []
    dispatched_d = [False] * 365
    # Decide what days to dispatch
    zipped = zip(dailyLoadPredictions, df['month'][-8760:], dailyPl, dailyPu,
                 dailyEu)
    for i, (load, m, pl, pu, eu) in enumerate(zipped):
        peak = max(load)
        if fc.shouldDispatchPS(peak, m, df, float(ind['confidence']) / 100):
            dispatched_d[i] = True
            p, e = fc.pulp24hrVbat(ind, load, pl, pu, eu)
            vbp.extend(p)
            vbe.extend(e)
        else:
            vbp.extend([0] * 24)
            vbe.extend([0] * 24)

    ### TESTING FOR ACCURACY ###
    assert len(dailyPl) == 365
    assert all([len(i) == 24 for i in dailyPl])

    VB_power, VB_energy = vbp, vbe

    # -------------------- MODEL ACCURACY ANALYSIS -------------------------- #

    o['predictedLoad'] = list(clf.predict(X_test))
    o['trainAccuracy'] = round(clf.score(X_train, y_train) * 100, 2)
    o['testAccuracy'] = round(clf.score(X_test, y_test) * 100, 2)

    # PRECISION AND RECALL
    maxDays = []
    for month in range(1, 13):
        test = df[df['month'] == month]
        maxDays.append(test.loc[test['load'].idxmax()]['dayOfYear'])

    shouldHaveDispatched = [False] * 365
    for day in maxDays:
        shouldHaveDispatched[day] = True

    truePositive = len([
        b for b in
        [i and j for (i, j) in zip(dispatched_d, shouldHaveDispatched)] if b
    ])
    falsePositive = len([
        b for b in
        [i and (not j) for (i, j) in zip(dispatched_d, shouldHaveDispatched)]
        if b
    ])
    falseNegative = len([
        b for b in [(not i) and j
                    for (i, j) in zip(dispatched_d, shouldHaveDispatched)] if b
    ])
    o['confidence'] = ind['confidence']
    o['precision'] = round(
        truePositive / float(truePositive + falsePositive) * 100, 2)
    o['recall'] = round(
        truePositive / float(truePositive + falseNegative) * 100, 2)
    o['number_of_dispatches'] = len([i for i in dispatched_d if i])
    o['MAE'] = round(
        sum([abs(l - m) / m * 100
             for l, m in zip(predictions, list(y_test))]) / 8760., 2)

    # ---------------------- FINANCIAL ANALYSIS ----------------------------- #

    o['VBpower'], o['VBenergy'] = list(VB_power), list(VB_energy)

    # Calculate monthHours
    year = df[-8760:].copy()
    year.reset_index(inplace=True)
    year['hour'] = list(year.index)
    start = list(year.groupby('month').first()['hour'])
    finish = list(year.groupby('month').last()['hour'])
    monthHours = [(s, f + 1) for (s, f) in zip(start, finish)]

    demand = list(y_test)
    peakDemand = [max(demand[s:f]) for s, f in monthHours]
    energyMonthly = [sum(demand[s:f]) for s, f in monthHours]
    demandAdj = [d + p for d, p in zip(demand, o['VBpower'])]
    peakAdjustedDemand = [max(demandAdj[s:f]) for s, f in monthHours]
    energyAdjustedMonthly = [sum(demandAdj[s:f]) for s, f in monthHours]

    o['demand'] = demand
    o['peakDemand'] = peakDemand
    o['energyMonthly'] = energyMonthly
    o['demandAdjusted'] = demandAdj
    o['peakAdjustedDemand'] = peakAdjustedDemand
    o['energyAdjustedMonthly'] = energyAdjustedMonthly

    cellCost = float(ind['unitDeviceCost']) * float(ind['number_devices'])
    eCost = float(ind['electricityCost'])
    dCharge = float(ind['demandChargeCost'])

    o['VBdispatch'] = [dal - d for dal, d in zip(demandAdj, demand)]
    o['energyCost'] = [em * eCost for em in energyMonthly]
    o['energyCostAdjusted'] = [eam * eCost for eam in energyAdjustedMonthly]
    o['demandCharge'] = [peak * dCharge for peak in peakDemand]
    o['demandChargeAdjusted'] = [
        pad * dCharge for pad in o['peakAdjustedDemand']
    ]
    o['totalCost'] = [
        ec + dcm for ec, dcm in zip(o['energyCost'], o['demandCharge'])
    ]
    o['totalCostAdjusted'] = [
        eca + dca
        for eca, dca in zip(o['energyCostAdjusted'], o['demandChargeAdjusted'])
    ]
    o['savings'] = [
        tot - tota for tot, tota in zip(o['totalCost'], o['totalCostAdjusted'])
    ]

    annualEarnings = sum(o['savings']) - float(ind['unitUpkeepCost']) * float(
        ind['number_devices'])
    cashFlowList = [annualEarnings] * int(ind['projectionLength'])
    cashFlowList.insert(0, -1 * cellCost)

    o['NPV'] = np.npv(float(ind['discountRate']) / 100, cashFlowList)
    o['SPP'] = cellCost / annualEarnings
    o['netCashflow'] = cashFlowList
    o['cumulativeCashflow'] = [
        sum(cashFlowList[:i + 1]) for i, d in enumerate(cashFlowList)
    ]

    o['stdout'] = 'Success'
    return o
def work(modelDir, ind):
    #print(ind)
    ''' Run the model in its directory.'''
    # drop inverter efficiency
    # drop DoD
    (cellCapacity, dischargeRate, chargeRate, cellQuantity, cellCost) = \
     [float(ind[x]) for x in ('cellCapacity', 'dischargeRate', 'chargeRate', 'cellQuantity', 'cellCost')]
    battEff = float(ind.get("batteryEfficiency")) / 100.0
    dodFactor = float(ind.get('dodFactor')) / 100.0
    projYears = int(ind.get('projYears'))
    batteryCycleLife = int(ind.get('batteryCycleLife'))

    o = {}

    try:
        with open(pJoin(modelDir, 'hist.csv'), 'w') as f:
            f.write(ind['historicalData'].replace('\r', ''))
        df = pd.read_csv(pJoin(modelDir, 'hist.csv'), parse_dates=['dates'])
        df['month'] = df['dates'].dt.month
        df['dayOfYear'] = df['dates'].dt.dayofyear
        assert df.shape[0] >= 26280  # must be longer than 3 years
        assert df.shape[1] == 5
    except:
        raise Exception("CSV file is incorrect format.")

    # retrieve goal
    goal = ind['goal']
    threshold = float(ind['transformerThreshold']) * 1000
    confidence = float(ind['confidence']) / 100

    # train model on previous data
    all_X = fc.makeUsefulDf(df)
    all_y = df['load']
    X_train, y_train = all_X[:-8760], all_y[:-8760]
    clf = linear_model.SGDRegressor(max_iter=10000, tol=1e-4)
    clf.fit(X_train, y_train)

    # ---------------------- MAKE PREDICTIONS ------------------------------- #
    X_test, y_test = all_X[-8760:], all_y[-8760:]

    # Collect data necessary for dispatch calculations
    predictions = clf.predict(X_test)
    dailyLoadPredictions = [
        predictions[i:i + 24] for i in range(0, len(predictions), 24)
    ]
    weather = df['tempc'][-8760:]
    dailyWeatherPredictions = [
        weather[i:i + 24] for i in range(0, len(weather), 24)
    ]
    month = df['month'][-8760:]

    dispatched = [False] * 365
    # decide to implement VBAT every day for a year
    VB_power, VB_energy = [], []
    for i, (load24, temp24, m) in enumerate(
            zip(dailyLoadPredictions, dailyWeatherPredictions, month)):
        peak = max(load24)
        if fc.shouldDispatchPS(peak, m, df, confidence):
            dispatched[i] = True
            vbp, vbe = fc.pulp24hrBattery(load24, dischargeRate * cellQuantity,
                                          cellCapacity * cellQuantity, battEff)
            VB_power.extend(vbp)
            VB_energy.extend(vbe)
        else:
            VB_power.extend([0] * 24)
            VB_energy.extend([0] * 24)

    # -------------------- MODEL ACCURACY ANALYSIS -------------------------- #

    o['predictedLoad'] = list(clf.predict(X_test))
    o['trainAccuracy'] = round(clf.score(X_train, y_train) * 100, 2)
    o['testAccuracy'] = round(clf.score(X_test, y_test) * 100, 2)

    # PRECISION AND RECALL
    maxDays = []
    for month in range(1, 13):
        test = df[df['month'] == month]
        maxDays.append(test.loc[test['load'].idxmax()]['dayOfYear'])

    shouldHaveDispatched = [False] * 365
    for day in maxDays:
        shouldHaveDispatched[day] = True

    truePositive = len([
        b
        for b in [i and j for (i, j) in zip(dispatched, shouldHaveDispatched)]
        if b
    ])
    falsePositive = len([
        b for b in
        [i and (not j) for (i, j) in zip(dispatched, shouldHaveDispatched)]
        if b
    ])
    falseNegative = len([
        b for b in [(not i) and j
                    for (i, j) in zip(dispatched, shouldHaveDispatched)] if b
    ])
    o['precision'] = round(
        truePositive / float(truePositive + falsePositive) * 100, 2)
    o['recall'] = round(
        truePositive / float(truePositive + falseNegative) * 100, 2)
    o['number_of_dispatches'] = len([i for i in dispatched if i])
    o['MAE'] = round(
        sum([abs(l - m) / m * 100
             for l, m in zip(predictions, list(y_test))]) / 8760., 2)

    # ---------------------- FINANCIAL ANALYSIS ----------------------------- #

    o['VBpower'], o['VBenergy'] = list(VB_power), list(VB_energy)

    # Calculate monthHours
    year = df[-8760:].copy()
    year.reset_index(inplace=True)
    year['hour'] = list(year.index)
    start = list(year.groupby('month').first()['hour'])
    finish = list(year.groupby('month').last()['hour'])
    monthHours = [(s, f + 1) for (s, f) in zip(start, finish)]

    demand = list(y_test)
    peakDemand = [max(demand[s:f]) for s, f in monthHours]
    energyMonthly = [sum(demand[s:f]) for s, f in monthHours]
    demandAdj = [d + p for d, p in zip(demand, o['VBpower'])]
    peakAdjustedDemand = [max(demandAdj[s:f]) for s, f in monthHours]
    energyAdjustedMonthly = [sum(demandAdj[s:f]) for s, f in monthHours]

    o['demand'] = demand
    o['peakDemand'] = peakDemand
    o['energyMonthly'] = energyMonthly
    o['demandAdjusted'] = demandAdj
    o['peakAdjustedDemand'] = peakAdjustedDemand
    o['energyAdjustedMonthly'] = energyAdjustedMonthly

    initInvestment = cellCost * cellQuantity
    eCost = float(ind['electricityCost'])
    dCharge = float(ind['demandChargeCost'])

    o['VBdispatch'] = [dal - d for dal, d in zip(demandAdj, demand)]
    o['energyCost'] = [em * eCost for em in energyMonthly]
    o['energyCostAdjusted'] = [eam * eCost for eam in energyAdjustedMonthly]
    o['demandCharge'] = [peak * dCharge for peak in peakDemand]
    o['demandChargeAdjusted'] = [
        pad * dCharge for pad in o['peakAdjustedDemand']
    ]
    o['totalCost'] = [
        ec + dcm for ec, dcm in zip(o['energyCost'], o['demandCharge'])
    ]
    o['totalCostAdjusted'] = [
        eca + dca
        for eca, dca in zip(o['energyCostAdjusted'], o['demandChargeAdjusted'])
    ]
    o['savings'] = [
        tot - tota for tot, tota in zip(o['totalCost'], o['totalCostAdjusted'])
    ]

    annualEarnings = sum(o['savings'])  # - something!
    cashFlowList = [annualEarnings] * int(ind['projectionLength'])
    cashFlowList.insert(0, -1 * initInvestment)

    o['NPV'] = np.npv(float(ind['discountRate']) / 100, cashFlowList)
    o['SPP'] = initInvestment / annualEarnings
    o['netCashflow'] = cashFlowList
    o['cumulativeCashflow'] = [
        sum(cashFlowList[:i + 1]) for i, d in enumerate(cashFlowList)
    ]

    o['dataCheck'] = 'Threshold exceeded' if any(
        [threshold > i for i in demandAdj]) and goal == 'deferral' else ''
    o['transformerThreshold'] = threshold if goal == 'deferral' else None

    o['stdout'] = 'Success'
    return o