Java tutorial
/* * Copyright (c) 2011-2013 by John Collins. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.powertac.common; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.io.File; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.joda.time.Instant; import org.junit.AfterClass; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.powertac.common.enumerations.PowerType; import org.powertac.common.repo.TariffRepo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.util.ReflectionTestUtils; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:test-config.xml" }) @DirtiesContext public class TariffTests { @Autowired private TimeService timeService; // dependency injection @Autowired private TariffRepo repo; private TariffSpecification tariffSpec; // instance var private TariffSpecification productionSpec; // instance var private Instant start; private Instant exp; private Broker broker; @AfterClass public static void saveLogs() throws Exception { File state = new File("log/test.state"); state.renameTo(new File("log/TariffTests.state")); File trace = new File("log/test.trace"); trace.renameTo(new File("log/TariffTests.trace")); } @Before public void setUp() { start = new DateTime(2011, 1, 1, 12, 0, 0, 0, DateTimeZone.UTC).toInstant(); timeService.setCurrentTime(start); broker = new Broker("testBroker"); repo = new TariffRepo(); exp = new DateTime(2011, 3, 1, 12, 0, 0, 0, DateTimeZone.UTC).toInstant(); tariffSpec = new TariffSpecification(broker, PowerType.CONSUMPTION).withExpiration(exp) .withMinDuration(TimeService.WEEK * 8); productionSpec = new TariffSpecification(broker, PowerType.PRODUCTION).withExpiration(exp) .withMinDuration(TimeService.WEEK * 8); } // create a Tariff and inspect it @Test public void testCreate() { Rate r1 = new Rate().withValue(-0.121); tariffSpec.addRate(r1); Tariff te = new Tariff(tariffSpec); te.init(); assertNotNull("non-null result", te); assertEquals("correct TariffSpec", tariffSpec, te.getTariffSpecification()); assertEquals("correct initial realized price", 0.0, te.getRealizedPrice(), 1e-6); assertEquals("correct expiration in spec", exp, te.getTariffSpecification().getExpiration()); assertEquals("correct expiration", exp, te.getExpiration()); assertEquals("correct publication time", start, te.getOfferDate()); assertFalse("not expired", te.isExpired()); assertTrue("covered", te.isCovered()); } // check the realized price calculation @Test public void testRealizedPrice() { Rate r1 = new Rate().withValue(-0.121); tariffSpec.addRate(r1); Tariff te = new Tariff(tariffSpec); te.init(); te.totalUsage = 501.2; te.totalCost = -99.8; assertEquals("Correct realized price", -99.8 / 501.2, te.getRealizedPrice(), 1.0e-6); } // single fixed rate, check charges in past and future @Test public void testSimpleRate() { Rate r1 = new Rate().withValue(-0.121); tariffSpec.addRate(r1); Instant now = timeService.getCurrentTime(); Tariff te = new Tariff(tariffSpec); te.init(); assertEquals("correct charge, default case", -0.121, te.getUsageCharge(1.0, 0.0, false), 1e-6); assertEquals("correct charge, today", -1.21, te.getUsageCharge(10.0, 0.0, false), 1e-6); assertEquals("correct charge yesterday", -2.42, te.getUsageCharge(now.minus(TimeService.DAY), 20.0, 0.0), 1e-6); assertEquals("correct charge tomorrow", -12.1, te.getUsageCharge(now.plus(TimeService.DAY), 100.0, 0.0), 1e-6); assertEquals("correct charge an hour ago", -3.63, te.getUsageCharge(now.minus(TimeService.HOUR), 30.0, 0.0), 1e-6); assertEquals("correct charge an hour from now", -1.21, te.getUsageCharge(now.plus(TimeService.HOUR), 10.0, 0.0), 1e-6); //assertEquals("daily rate map", 1, te.rateMap.size()) //assertEquals("rate map has 24 entries", 24, te.rateMap[0].size()) assertTrue("covered", te.isCovered()); } @Test public void testSimpleProduction() { Rate r1 = new Rate().withValue(0.121); productionSpec.addRate(r1); Instant now = timeService.getCurrentTime(); Tariff te = new Tariff(productionSpec); te.init(); assertEquals("correct charge, default case", 0.121, te.getUsageCharge(-1.0, 0.0, false), 1e-6); assertEquals("correct charge, today", 1.21, te.getUsageCharge(-10.0, 0.0, false), 1e-6); assertEquals("correct charge yesterday", 2.42, te.getUsageCharge(now.minus(TimeService.DAY), -20.0, 0.0), 1e-6); assertEquals("correct charge tomorrow", 12.1, te.getUsageCharge(now.plus(TimeService.DAY), -100.0, 0.0), 1e-6); assertEquals("correct charge an hour ago", 3.63, te.getUsageCharge(now.minus(TimeService.HOUR), -30.0, 0.0), 1e-6); assertEquals("correct charge an hour from now", 1.21, te.getUsageCharge(now.plus(TimeService.HOUR), -10.0, 0.0), 1e-6); } // single fixed rate, check realized price after multiple rounds @Test public void testSimpleRateRealizedPrice() { Rate r1 = new Rate().withValue(-0.131); tariffSpec.addRate(r1); //Instant now = timeService.getCurrentTime(); Tariff te = new Tariff(tariffSpec); te.init(); te.getUsageCharge(20.0, 200.0, true); assertEquals("realized price 1", -0.131, te.getRealizedPrice(), 1e-6); te.getUsageCharge(10.0, 1000.0, true); assertEquals("realized price 2", -0.131, te.getRealizedPrice(), 1e-6); te.getUsageCharge(3.0, 20.0, true); assertEquals("realized price 3", -0.131, te.getRealizedPrice(), 1e-6); } // time-of-use rates: -0.15/kwh 7:00-18:00, -0.08/kwh 18:00-7:00 @Test public void testTimeOfUseDaily() { Rate r1 = new Rate().withValue(-0.15).withDailyBegin(7).withDailyEnd(17); Rate r2 = new Rate().withValue(-0.08).withDailyBegin(18).withDailyEnd(6); tariffSpec.addRate(r1); tariffSpec.addRate(r2); Tariff te = new Tariff(tariffSpec); te.init(); assertEquals("noon price", -3.0, te.getUsageCharge(20.0, 200.0, true), 1e-6); assertEquals("realized price", -0.15, te.getRealizedPrice(), 1e-6); timeService.setCurrentTime(new DateTime(2011, 1, 1, 18, 0, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("18:00 price", -0.8, te.getUsageCharge(10.0, 220.0, true), 1e-6); assertEquals("realized price 2", -3.8 / 30.0, te.getRealizedPrice(), 1e-6); timeService.setCurrentTime(new DateTime(2011, 1, 2, 0, 0, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("midnight price", -0.4, te.getUsageCharge(5.0, 230.0, true), 1e-6); assertEquals("realized price 3", -4.2 / 35.0, te.getRealizedPrice(), 1e-6); timeService.setCurrentTime(new DateTime(2011, 1, 2, 7, 0, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("7:00 price", -0.6, te.getUsageCharge(4.0, 235.0, true), 1e-6); assertEquals("realized price 4", -4.8 / 39.0, te.getRealizedPrice(), 1e-6); assertTrue("covered", te.isCovered()); } // time-of-use rates: 0.15/kwh 7:00-18:00, 0.08/kwh 19:00-7:00 @Test public void testTimeOfUseDailyGap() { Rate r1 = new Rate().withValue(-0.15).withDailyBegin(7).withDailyEnd(17); Rate r2 = new Rate().withValue(-0.08).withDailyBegin(19).withDailyEnd(6); tariffSpec.addRate(r1); tariffSpec.addRate(r2); Tariff te = new Tariff(tariffSpec); te.init(); assertFalse("not covered", te.isCovered()); } // time-of-use weekly: // - weekdays are 0.15/kwh 7:00-18:00, 0.08/kwh 18:00-7:00 // - weekends are 0.06 @Test public void testTimeOfUseWeekly() { Rate r1 = new Rate().withValue(-0.15).withDailyBegin(7).withDailyEnd(17); Rate r2 = new Rate().withValue(-0.08).withDailyBegin(18).withDailyEnd(6); Rate r3 = new Rate().withValue(-0.06).withWeeklyBegin(6).withWeeklyEnd(7); tariffSpec.addRate(r1); tariffSpec.addRate(r2); tariffSpec.addRate(r3); Tariff te = new Tariff(tariffSpec); te.init(); assertEquals("noon price Sat", -1.2, te.getUsageCharge(20.0, 200.0, true), 1e-6); assertEquals("realized price", -0.06, te.getRealizedPrice(), 1e-6); assertTrue("weekly map", te.isWeekly()); //assertEquals("rate map row has 168 entries", 168, te.rateMap[0].size()) assertTrue("covered", te.isCovered()); timeService.setCurrentTime(new DateTime(2011, 1, 1, 18, 0, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("18:00 price Sat", -0.6, te.getUsageCharge(10.0, 220.0, true), 1e-6); assertEquals("realized price 2", -1.8 / 30.0, te.getRealizedPrice(), 1e-6); timeService.setCurrentTime(new DateTime(2011, 1, 2, 0, 0, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("midnight price Sun", -0.3, te.getUsageCharge(5.0, 230.0, true), 1e-6); assertEquals("realized price 3", -2.1 / 35.0, te.getRealizedPrice(), 1e-6); timeService.setCurrentTime(new DateTime(2011, 1, 2, 7, 0, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("7:00 price Sun", -0.24, te.getUsageCharge(4.0, 235.0, true), 1e-6); assertEquals("realized price 4", -2.34 / 39.0, te.getRealizedPrice(), 1e-6); timeService.setCurrentTime(new DateTime(2011, 1, 3, 0, 0, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("midnight Mon", -0.32, te.getUsageCharge(4.0, 235.0, true), 1e-6); assertEquals("realized price 5", -2.66 / 43.0, te.getRealizedPrice(), 1e-6); timeService.setCurrentTime(new DateTime(2011, 1, 3, 6, 59, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("6:59 Mon", -0.48, te.getUsageCharge(6.0, 235.0, true), 1e-6); assertEquals("realized price 6", -3.14 / 49.0, te.getRealizedPrice(), 1e-6); timeService.setCurrentTime(new DateTime(2011, 1, 3, 7, 0, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("7:00 Mon", -1.2, te.getUsageCharge(8.0, 235.0, true), 1e-6); assertEquals("realized price 7", -4.34 / 57.0, te.getRealizedPrice(), 1e-6); timeService.setCurrentTime(new DateTime(2011, 1, 4, 12, 0, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("noon Tue", -1.5, te.getUsageCharge(10.0, 235.0, true), 1e-6); assertEquals("realized price 8", -5.84 / 67.0, te.getRealizedPrice(), 1e-6); timeService.setCurrentTime(new DateTime(2011, 1, 5, 17, 0, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("17:00 Wed", -1.05, te.getUsageCharge(7.0, 235.0, true), 1e-6); assertEquals("realized price 9", -6.89 / 74.0, te.getRealizedPrice(), 1e-6); timeService.setCurrentTime(new DateTime(2011, 1, 6, 18, 0, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("18:00 Thu", -0.72, te.getUsageCharge(9.0, 235.0, true), 1e-6); assertEquals("realized price 10", -7.61 / 83.0, te.getRealizedPrice(), 1e-6); timeService.setCurrentTime(new DateTime(2011, 1, 7, 23, 59, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("23:59 Fri", -0.96, te.getUsageCharge(12.0, 235.0, true), 1e-6); assertEquals("realized price 11", -8.57 / 95.0, te.getRealizedPrice(), 1e-6); timeService.setCurrentTime(new DateTime(2011, 1, 8, 12, 0, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("midnight Sat", -0.18, te.getUsageCharge(3.0, 235.0, true), 1e-6); assertEquals("realized price 12", -8.75 / 98.0, te.getRealizedPrice(), 1e-6); } // time-of-use weekly wrap-around @Test public void testTimeOfUseWeeklyWrap() { Rate r1 = new Rate().withValue(-0.15).withDailyBegin(6).withDailyEnd(17); Rate r2 = new Rate().withValue(-0.08).withDailyBegin(18).withDailyEnd(5); Rate r3 = new Rate().withValue(-0.06).withWeeklyBegin(7).withWeeklyEnd(2); // Sun-Tue tariffSpec.addRate(r1); tariffSpec.addRate(r2); tariffSpec.addRate(r3); Tariff te = new Tariff(tariffSpec); te.init(); timeService.setCurrentTime(new DateTime(2011, 1, 1, 23, 50, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("23:50 Sat", -0.8, te.getUsageCharge(10.0, 220.0, true), 1e-6); timeService.setCurrentTime(new DateTime(2011, 1, 2, 0, 0, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("midnight Sun", -0.3, te.getUsageCharge(5.0, 230.0, true), 1e-6); timeService.setCurrentTime(new DateTime(2011, 1, 3, 7, 0, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("7:00 price Mon", -0.24, te.getUsageCharge(4.0, 235.0, true), 1e-6); timeService.setCurrentTime(new DateTime(2011, 1, 3, 20, 0, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("20:00 Mon", -0.48, te.getUsageCharge(8.0, 235.0, true), 1e-6); timeService.setCurrentTime(new DateTime(2011, 1, 4, 1, 0, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("1:00 Tue", -0.12, te.getUsageCharge(2.0, 235.0, true), 1e-6); timeService.setCurrentTime(new DateTime(2011, 1, 4, 12, 0, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("noon Tue", -0.3, te.getUsageCharge(5.0, 235.0, true), 1e-6); timeService.setCurrentTime(new DateTime(2011, 1, 4, 23, 59, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("23:56 Tue", -3.0, te.getUsageCharge(50.0, 235.0, true), 1e-6); timeService.setCurrentTime(new DateTime(2011, 1, 5, 0, 0, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("midnight Wed", -0.64, te.getUsageCharge(8.0, 235.0, true), 1e-6); timeService.setCurrentTime(new DateTime(2011, 1, 5, 12, 0, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("noon Wed", -2.25, te.getUsageCharge(15.0, 235.0, true), 1e-6); } // tiers @Test public void testTimeOfUseTier() { Rate r1 = new Rate().withValue(-0.15).withDailyBegin(7).withDailyEnd(17); Rate r2 = new Rate().withValue(-0.08).withDailyBegin(18).withDailyEnd(6); Rate r3 = new Rate().withValue(-0.2).withTierThreshold(20); tariffSpec.addRate(r1); tariffSpec.addRate(r2); tariffSpec.addRate(r3); Tariff te = new Tariff(tariffSpec); te.init(); assertEquals("noon price, below", -1.5, te.getUsageCharge(10.0, 5.0, true), 1e-6); assertEquals("noon price, above", -2.0, te.getUsageCharge(10.0, 25.0, true), 1e-6); assertEquals("noon price, split", -1.75, te.getUsageCharge(10.0, 15.0, true), 1e-6); timeService.setCurrentTime(new DateTime(2011, 1, 2, 0, 0, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("midnight price, below", -0.4, te.getUsageCharge(5.0, 12.0, true), 1e-6); assertEquals("midnight price, above", -1.0, te.getUsageCharge(5.0, 22.0, true), 1e-6); assertEquals("midnight price, split", -0.76, te.getUsageCharge(5.0, 18.0, true), 1e-6); } // multiple TOU tiers @Test public void testTimeOfUseTier2() { Rate r1 = new Rate().withValue(-0.15).withDailyBegin(7).withDailyEnd(17); Rate r2 = new Rate().withValue(-0.08).withDailyBegin(18).withDailyEnd(6); Rate r3 = new Rate().withValue(-0.25).withTierThreshold(20).withDailyBegin(16).withDailyEnd(21); Rate r4 = new Rate().withValue(-0.21).withTierThreshold(20).withDailyBegin(22).withDailyEnd(15); tariffSpec.addRate(r1); tariffSpec.addRate(r2); tariffSpec.addRate(r4); tariffSpec.addRate(r3); Tariff te = new Tariff(tariffSpec); te.init(); assertEquals("noon price, below", -1.5, te.getUsageCharge(10.0, 5.0, true), 1e-6); assertEquals("noon price, above", -2.1, te.getUsageCharge(10.0, 25.0, true), 1e-6); assertEquals("noon price, split", -1.8, te.getUsageCharge(10.0, 15.0, true), 1e-6); timeService.setCurrentTime(new DateTime(2011, 1, 2, 0, 0, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("midnight price, below", -0.4, te.getUsageCharge(5.0, 12.0, true), 1e-6); assertEquals("midnight price, above", -1.05, te.getUsageCharge(5.0, 22.0, true), 1e-6); assertEquals("midnight price, split", -0.79, te.getUsageCharge(5.0, 18.0, true), 1e-6); timeService.setCurrentTime(new DateTime(2011, 1, 2, 18, 0, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("evening price, below", -0.8, te.getUsageCharge(10.0, 5.0, true), 1e-6); assertEquals("evening price, above", -2.5, te.getUsageCharge(10.0, 25.0, true), 1e-6); assertEquals("evening price, split", -1.65, te.getUsageCharge(10.0, 15.0, true), 1e-6); } // multiple TOU tiers - production @Test public void testTimeOfUseTierProd() { Rate r1 = new Rate().withValue(0.15).withDailyBegin(7).withDailyEnd(17); Rate r2 = new Rate().withValue(0.08).withDailyBegin(18).withDailyEnd(6); Rate r3 = new Rate().withValue(0.25).withTierThreshold(-20.0).withDailyBegin(16).withDailyEnd(21); Rate r4 = new Rate().withValue(0.21).withTierThreshold(-20.0).withDailyBegin(22).withDailyEnd(15); productionSpec.addRate(r1); productionSpec.addRate(r2); productionSpec.addRate(r4); productionSpec.addRate(r3); Tariff te = new Tariff(productionSpec); te.init(); assertEquals("noon price, below", 1.5, te.getUsageCharge(-10.0, -5.0, true), 1e-6); assertEquals("noon price, above", 2.1, te.getUsageCharge(-10.0, -25.0, true), 1e-6); assertEquals("noon price, split", 1.8, te.getUsageCharge(-10.0, -15.0, true), 1e-6); timeService.setCurrentTime(new DateTime(2011, 1, 2, 0, 0, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("midnight price, below", 0.4, te.getUsageCharge(-5.0, -12.0, true), 1e-6); assertEquals("midnight price, above", 1.05, te.getUsageCharge(-5.0, -22.0, true), 1e-6); assertEquals("midnight price, split", 0.79, te.getUsageCharge(-5.0, -18.0, true), 1e-6); timeService.setCurrentTime(new DateTime(2011, 1, 2, 18, 0, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("evening price, below", 0.8, te.getUsageCharge(-10.0, -5.0, true), 1e-6); assertEquals("evening price, above", 2.5, te.getUsageCharge(-10.0, -25.0, true), 1e-6); assertEquals("evening price, split", 1.65, te.getUsageCharge(-10.0, -15.0, true), 1e-6); } // multiple tiers @Test public void testMultiTiers() { Rate r1 = new Rate().withValue(-0.15).withTierThreshold(10); Rate r2 = new Rate().withValue(-0.1).withTierThreshold(5); Rate r3 = new Rate().withValue(-0.2).withTierThreshold(20); Rate r4 = new Rate().withValue(-0.07); tariffSpec.addRate(r1); tariffSpec.addRate(r2); tariffSpec.addRate(r3); tariffSpec.addRate(r4); Tariff te = new Tariff(tariffSpec); te.init(); assertEquals("first tier", -0.14, te.getUsageCharge(2.0, 2.0, true), 1e-6); assertEquals("first-second tier", -0.41, te.getUsageCharge(5.0, 2.0, true), 1e-6); assertEquals("second tier", -0.2, te.getUsageCharge(2.0, 6.0, true), 1e-6); assertEquals("second-third tier", -0.6, te.getUsageCharge(5.0, 7.0, true), 1e-6); assertEquals("third tier", -0.3, te.getUsageCharge(2.0, 12.0, true), 1e-6); assertEquals("third-fourth tier", -0.85, te.getUsageCharge(5.0, 17.0, true), 1e-6); assertEquals("fourth tier", -0.4, te.getUsageCharge(2.0, 22.0, true), 1e-6); assertEquals("second-fourth tier", -2.1, te.getUsageCharge(14.0, 8.0, true), 1e-6); } // variable @Test public void testVarRate() { Rate r1 = new Rate().withFixed(false).withMinValue(-0.05).withMaxValue(-0.50).withNoticeInterval(3) .withExpectedMean(-0.10).withDailyBegin(7).withDailyEnd(17); Rate r2 = new Rate().withValue(-0.08).withDailyBegin(18).withDailyEnd(6); tariffSpec.addRate(r1); tariffSpec.addRate(r2); Tariff te = new Tariff(tariffSpec); te.init(); // test r1 without hourly charge, uses expected mean assertEquals("current charge, noon Sunday", -1.0, te.getUsageCharge(10.0, 0.0, false), 1e-6); // test with hourly charges r1.addHourlyCharge( new HourlyCharge(new DateTime(2011, 1, 1, 12, 0, 0, 0, DateTimeZone.UTC).toInstant(), -0.09), true); r1.addHourlyCharge( new HourlyCharge(new DateTime(2011, 1, 1, 13, 0, 0, 0, DateTimeZone.UTC).toInstant(), -0.11), true); r1.addHourlyCharge( new HourlyCharge(new DateTime(2011, 1, 1, 14, 0, 0, 0, DateTimeZone.UTC).toInstant(), -0.13), true); r1.addHourlyCharge( new HourlyCharge(new DateTime(2011, 1, 1, 15, 0, 0, 0, DateTimeZone.UTC).toInstant(), -0.14)); assertEquals("current charge, noon Sunday", -0.9, te.getUsageCharge(10.0, 0.0, false), 1e-6); assertEquals("13:00 charge, noon Sunday", -1.1, te.getUsageCharge(new DateTime(2011, 1, 1, 13, 0, 0, 0, DateTimeZone.UTC).toInstant(), 10.0, 0.0), 1e-6); assertEquals("14:00 charge, noon Sunday", -1.3, te.getUsageCharge(new DateTime(2011, 1, 1, 14, 0, 0, 0, DateTimeZone.UTC).toInstant(), 10.0, 0.0), 1e-6); assertEquals("15:00 charge, noon Sunday", -1.4, te.getUsageCharge(new DateTime(2011, 1, 1, 15, 0, 0, 0, DateTimeZone.UTC).toInstant(), 10.0, 0.0), 1e-6); assertEquals("16:00 charge, noon Sunday", -1.0, te.getUsageCharge(new DateTime(2011, 1, 1, 16, 0, 0, 0, DateTimeZone.UTC).toInstant(), 10.0, 0.0), 1e-6); assertEquals("18:00 charge, noon Sunday", -0.8, te.getUsageCharge(new DateTime(2011, 1, 1, 18, 0, 0, 0, DateTimeZone.UTC).toInstant(), 10.0, 0.0), 1e-6); } // single rate, interruptible @Test public void testSimpleCurtailment() { TariffSpecification spec = new TariffSpecification(broker, PowerType.INTERRUPTIBLE_CONSUMPTION) .withExpiration(exp).withMinDuration(TimeService.WEEK * 8); Rate r1 = new Rate().withValue(-0.121).withMaxCurtailment(0.3); spec.addRate(r1); Tariff te = new Tariff(spec); te.init(); assertEquals("correct max curtailment 1", 9.0, te.getMaxUpRegulation(30.0, 0.0), 1e-6); assertEquals("correct max curtailment 1", 9.0, te.getMaxUpRegulation(30.0, 1000.0), 1e-6); timeService.setCurrentTime(new DateTime(2011, 1, 1, 18, 0, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("correct max curtailment 1", 9.0, te.getMaxUpRegulation(30.0, 0.0), 1e-6); } // single rate, not interruptible @Test public void testNoCurtailment() { TariffSpecification spec = new TariffSpecification(broker, PowerType.CONSUMPTION).withExpiration(exp) .withMinDuration(TimeService.WEEK * 8); Rate r1 = new Rate().withValue(-0.121).withMaxCurtailment(0.3); spec.addRate(r1); Tariff te = new Tariff(spec); te.init(); assertEquals("correct max curtailment 1", 0.0, te.getMaxUpRegulation(30.0, 0.0), 1e-6); } // multiple rates, single tier, one rate interruptible @Test public void testMultiRateCurtailment() { TariffSpecification spec = new TariffSpecification(broker, PowerType.INTERRUPTIBLE_CONSUMPTION) .withExpiration(exp).withMinDuration(TimeService.WEEK * 8); Rate r1 = new Rate().withValue(-0.15).withDailyBegin(7).withDailyEnd(17).withMaxCurtailment(0.1); Rate r2 = new Rate().withValue(-0.08).withDailyBegin(18).withDailyEnd(6).withMaxCurtailment(0.5); spec.addRate(r1); spec.addRate(r2); Tariff te = new Tariff(spec); te.init(); assertEquals("noon price", -3.0, te.getUsageCharge(20.0, 200.0, true), 1e-6); assertEquals("noon max curtailment", 3.0, te.getMaxUpRegulation(30.0, 0.0), 1e-6); timeService.setCurrentTime(new DateTime(2011, 1, 1, 18, 0, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("18:00 price", -0.8, te.getUsageCharge(10.0, 220.0, true), 1e-6); assertEquals("18:00 max curtailment", 15.0, te.getMaxUpRegulation(30.0, 0.0), 1e-6); timeService.setCurrentTime(new DateTime(2011, 1, 2, 0, 0, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("midnight price", -0.4, te.getUsageCharge(5.0, 230.0, true), 1e-6); assertEquals("midnight max curtailment", 15.0, te.getMaxUpRegulation(30.0, 0.0), 1e-6); timeService.setCurrentTime(new DateTime(2011, 1, 2, 7, 0, 0, 0, DateTimeZone.UTC).toInstant()); assertEquals("7:00 price", -0.6, te.getUsageCharge(4.0, 235.0, true), 1e-6); assertEquals("7:00 max curtailment", 3.0, te.getMaxUpRegulation(30.0, 0.0), 1e-6); } // multiple rates, multiple tiers, upper tier interruptible @Test public void testMultiTierCurtailment() { TariffSpecification spec = new TariffSpecification(broker, PowerType.INTERRUPTIBLE_CONSUMPTION) .withExpiration(exp).withMinDuration(TimeService.WEEK * 8); Rate r1 = new Rate().withValue(-0.15).withTierThreshold(10).withMaxCurtailment(0.5); Rate r2 = new Rate().withValue(-0.08).withMaxCurtailment(0.1); spec.addRate(r1); spec.addRate(r2); Tariff te = new Tariff(spec); te.init(); assertEquals("3.0 curtailment", 0.3, te.getMaxUpRegulation(3.0, 0.0), 1e-6); assertEquals("9.9 curtailment", 0.3, te.getMaxUpRegulation(3.0, 6.9), 1e-6); assertEquals("cross-boundary curtailment", 1.2, te.getMaxUpRegulation(4.0, 8.0), 1e-6); assertEquals("high curtailment", 2.0, te.getMaxUpRegulation(4.0, 11.0), 1e-6); } }