// create a Subscription from a Tariff @Test public void testSimpleSub() { TariffSubscription ts = tariffMarketService.subscribeToTariff(tariff, customer, 3); assertNotNull("non-null subscription", ts); assertEquals("correct customer", customer, ts.getCustomer()); assertEquals("correct tariff", tariff, ts.getTariff()); assertEquals("correct customer count", 3, ts.getCustomersCommitted()); }
private void usePower(Timeslot timeslot) { for (CapacityBundle bundle : capacityBundles) { List<TariffSubscription> subscriptions = getTariffSubscriptionRepo().findActiveSubscriptionsForCustomer(bundle.getCustomerInfo()); double totalCapacity = 0.0; double totalUsageCharge = 0.0; for (TariffSubscription subscription : subscriptions) { double usageSign = bundle.getPowerType().isConsumption() ? +1 : -1; double currCapacity = usageSign * useCapacity(subscription, bundle); if (Config.getInstance().isUsageChargesLogging()) { double charge = subscription .getTariff() .getUsageCharge(currCapacity, subscription.getTotalUsage(), false); totalUsageCharge += charge; } subscription.usePower(currCapacity); totalCapacity += currCapacity; } log.info( bundle.getName() + ": Total " + bundle.getPowerType() + " capacity for timeslot " + timeslot.getSerialNumber() + " = " + totalCapacity); logUsageCharges( bundle.getName() + ": Total " + bundle.getPowerType() + " usage charge for timeslot " + timeslot.getSerialNumber() + " = " + totalUsageCharge); } }
// Computes energy use by chargers in the current timeslot. // Remember that the plan has computed usage in terms of AC power, // while the energy going into the batteries is lower by // the chargeEfficiency value. double useEnergy(double regulation) { TariffSubscription subscription = getSubscription(); Tariff tariff = subscription.getTariff(); ensureCapacityPlan(tariff); // positive regulation means we lost energy in the last timeslot // and should make it up in the remainder of the shift addEnergyCharging(-regulation * chargeEfficiency); ShiftEnergy need = plan.getCurrentNeed(getNowInstant()); if (need.getDuration() <= 0) { log.error(getName() + " negative need duration " + need.getDuration()); } need.addEnergy(-regulation); // Compute the max and min we could possibly use in this timeslot // -- start with max and avail for remainder of shift double max = nChargers * maxChargeKW * need.getDuration(); // shift double avail = // for remainder of shift nBatteries * batteryCapacity - getCapacityInUse() - getEnergyCharging(); double maxUsable = Math.min(max, avail) / chargeEfficiency; double needed = need.getEnergyNeeded(); double used = 0; RegulationCapacity regCapacity = null; if (needed >= maxUsable) { // we just use the max, and allow no regulation capacity log.info( getName() + ": no slack - need " + needed + ", max " + max + ", avail " + avail + ", dur " + need.getDuration()); used = Math.min(maxUsable, (needed / need.getDuration())); regCapacity = new RegulationCapacity(subscription, 0.0, 0.0); } else if (tariff.isTimeOfUse() || tariff.isVariableRate()) { // if the current tariff is not a flat rate, we will just use the // planned amout, without offering regulation capacity // TODO - figure out how to combine variable prices with regulation used = need.getRecommendedUsage()[need.getUsageIndex()]; regCapacity = new RegulationCapacity(subscription, 0.0, 0.0); } else { // otherwise use energy to maximize regulation capacity double slack = (maxUsable - needed) / need.getDuration() / 2.0; log.info( getName() + " needed " + needed + ", maxUsable " + maxUsable + ", duration " + need.getDuration()); used = needed / need.getDuration() + slack; regCapacity = new RegulationCapacity(subscription, slack, -slack); } // use it addEnergyCharging(used * chargeEfficiency); getSubscription().setRegulationCapacity(regCapacity); log.info( getName() + " uses " + used + "kWh, reg cap (" + regCapacity.getUpRegulationCapacity() + ", " + regCapacity.getDownRegulationCapacity() + ")"); need.tick(); need.addEnergy(used); return used; }