Java tutorial
/* * Copyright 2009-2012 the original author or authors. * * 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.householdcustomer.customers; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.ListIterator; import java.util.Map; import java.util.Properties; import java.util.TreeMap; import java.util.Vector; import org.apache.log4j.Logger; import org.joda.time.Instant; import org.powertac.common.CustomerInfo; import org.powertac.common.RandomSeed; import org.powertac.common.Tariff; import org.powertac.common.TariffEvaluationHelper; import org.powertac.common.TariffEvaluator; import org.powertac.common.TariffSubscription; import org.powertac.common.TimeService; import org.powertac.common.Timeslot; import org.powertac.common.WeatherReport; import org.powertac.common.enumerations.PowerType; import org.powertac.common.interfaces.CustomerModelAccessor; import org.powertac.common.interfaces.CustomerServiceAccessor; import org.powertac.common.interfaces.TariffMarket; import org.powertac.common.repo.CustomerRepo; import org.powertac.common.repo.TariffRepo; import org.powertac.common.repo.TimeslotRepo; import org.powertac.common.repo.WeatherReportRepo; import org.powertac.common.spring.SpringApplicationContext; import org.powertac.customer.AbstractCustomer; import org.powertac.householdcustomer.configurations.VillageConstants; import org.springframework.beans.factory.annotation.Autowired; /** * The village domain class is a set of households that comprise a small village * that consumes aggregated energy by the appliances installed in each * household. * * @author Antonios Chrysopoulos * @version 1.5, Date: 2.25.12 */ public class Village extends AbstractCustomer { /** * logger for trace logging -- use log.info(), log.warn(), and log.error() * appropriately. Use log.debug() for output you want to see in testing or * debugging. */ static protected Logger log = Logger.getLogger(Village.class.getName()); int seedId = 1; /** * These are the vectors containing aggregated each day's base load from the * appliances installed inside the households of each type. **/ Vector<Vector<Long>> aggDailyBaseLoadNS = new Vector<Vector<Long>>(); Vector<Vector<Long>> aggDailyBaseLoadRaS = new Vector<Vector<Long>>(); Vector<Vector<Long>> aggDailyBaseLoadReS = new Vector<Vector<Long>>(); Vector<Vector<Long>> aggDailyBaseLoadSS = new Vector<Vector<Long>>(); /** * These are the vectors containing aggregated each day's controllable load * from the appliances installed inside the households. **/ Vector<Vector<Long>> aggDailyControllableLoadNS = new Vector<Vector<Long>>(); Vector<Vector<Long>> aggDailyControllableLoadRaS = new Vector<Vector<Long>>(); Vector<Vector<Long>> aggDailyControllableLoadReS = new Vector<Vector<Long>>(); Vector<Vector<Long>> aggDailyControllableLoadSS = new Vector<Vector<Long>>(); /** * These are the vectors containing aggregated each day's weather sensitive * load from the appliances installed inside the households. **/ Vector<Vector<Long>> aggDailyWeatherSensitiveLoadNS = new Vector<Vector<Long>>(); Vector<Vector<Long>> aggDailyWeatherSensitiveLoadRaS = new Vector<Vector<Long>>(); Vector<Vector<Long>> aggDailyWeatherSensitiveLoadReS = new Vector<Vector<Long>>(); Vector<Vector<Long>> aggDailyWeatherSensitiveLoadSS = new Vector<Vector<Long>>(); /** * These are the vectors containing aggregated each day's dominant load from * the appliances installed inside the households of each type. **/ Vector<Vector<Long>> aggDailyDominantLoadNS = new Vector<Vector<Long>>(); Vector<Vector<Long>> aggDailyDominantLoadRaS = new Vector<Vector<Long>>(); Vector<Vector<Long>> aggDailyDominantLoadReS = new Vector<Vector<Long>>(); Vector<Vector<Long>> aggDailyDominantLoadSS = new Vector<Vector<Long>>(); /** * These are the vectors containing aggregated each day's non dominant load * from the appliances installed inside the households of each type. **/ Vector<Vector<Long>> aggDailyNonDominantLoadNS = new Vector<Vector<Long>>(); Vector<Vector<Long>> aggDailyNonDominantLoadRaS = new Vector<Vector<Long>>(); Vector<Vector<Long>> aggDailyNonDominantLoadReS = new Vector<Vector<Long>>(); Vector<Vector<Long>> aggDailyNonDominantLoadSS = new Vector<Vector<Long>>(); /** * These are the aggregated vectors containing each day's base load of all the * households in hours. **/ Vector<Vector<Long>> aggDailyBaseLoadInHoursNS = new Vector<Vector<Long>>(); Vector<Vector<Long>> aggDailyBaseLoadInHoursRaS = new Vector<Vector<Long>>(); Vector<Vector<Long>> aggDailyBaseLoadInHoursReS = new Vector<Vector<Long>>(); Vector<Vector<Long>> aggDailyBaseLoadInHoursSS = new Vector<Vector<Long>>(); /** * These are the aggregated vectors containing each day's controllable load of * all the households in hours. **/ Vector<Vector<Long>> aggDailyControllableLoadInHoursNS = new Vector<Vector<Long>>(); Vector<Vector<Long>> aggDailyControllableLoadInHoursRaS = new Vector<Vector<Long>>(); Vector<Vector<Long>> aggDailyControllableLoadInHoursReS = new Vector<Vector<Long>>(); Vector<Vector<Long>> aggDailyControllableLoadInHoursSS = new Vector<Vector<Long>>(); /** * These are the aggregated vectors containing each day's weather sensitive * load of all the households in hours. **/ Vector<Vector<Long>> aggDailyWeatherSensitiveLoadInHoursNS = new Vector<Vector<Long>>(); Vector<Vector<Long>> aggDailyWeatherSensitiveLoadInHoursRaS = new Vector<Vector<Long>>(); Vector<Vector<Long>> aggDailyWeatherSensitiveLoadInHoursReS = new Vector<Vector<Long>>(); Vector<Vector<Long>> aggDailyWeatherSensitiveLoadInHoursSS = new Vector<Vector<Long>>(); /** * These are the vectors containing aggregated each day's dominant load from * the appliances installed inside the households of each type. **/ Vector<Vector<Long>> aggDailyDominantLoadInHoursNS = new Vector<Vector<Long>>(); Vector<Vector<Long>> aggDailyDominantLoadInHoursRaS = new Vector<Vector<Long>>(); Vector<Vector<Long>> aggDailyDominantLoadInHoursReS = new Vector<Vector<Long>>(); Vector<Vector<Long>> aggDailyDominantLoadInHoursSS = new Vector<Vector<Long>>(); /** * These are the vectors containing aggregated each day's non dominant load * from the appliances installed inside the households of each type. **/ Vector<Vector<Long>> aggDailyNonDominantLoadInHoursNS = new Vector<Vector<Long>>(); Vector<Vector<Long>> aggDailyNonDominantLoadInHoursRaS = new Vector<Vector<Long>>(); Vector<Vector<Long>> aggDailyNonDominantLoadInHoursReS = new Vector<Vector<Long>>(); Vector<Vector<Long>> aggDailyNonDominantLoadInHoursSS = new Vector<Vector<Long>>(); /** * These are the mean consumption of the village types for the days with the * dominant appliances working. **/ double[] dominantLoadNS = new double[VillageConstants.HOURS_OF_DAY]; double[] dominantLoadRaS = new double[VillageConstants.HOURS_OF_DAY]; double[] dominantLoadReS = new double[VillageConstants.HOURS_OF_DAY]; double[] dominantLoadSS = new double[VillageConstants.HOURS_OF_DAY]; /** * These are the mean consumption of the village types for the days with the * dominant appliances not working. **/ double[] nonDominantLoadNS = new double[VillageConstants.HOURS_OF_DAY]; double[] nonDominantLoadRaS = new double[VillageConstants.HOURS_OF_DAY]; double[] nonDominantLoadReS = new double[VillageConstants.HOURS_OF_DAY]; double[] nonDominantLoadSS = new double[VillageConstants.HOURS_OF_DAY]; protected final TariffEvaluationHelper tariffEvalHelper = new TariffEvaluationHelper(); /** * This variable is utilized for the creation of the RandomSeed numbers and is * taken from the service. */ RandomSeed gen; /** * These variables are mapping of the characteristics of the types of houses. */ Map<String, Integer> numberOfHouses = new TreeMap<String, Integer>(); Map<CustomerInfo, TariffEvaluator> tariffEvaluators; Map<CustomerInfo, String> houseMapping = new TreeMap<CustomerInfo, String>(); /** * These vectors contain the houses of type in the village. There are 4 types * available: 1) Not Shifting Houses: They do not change the tariff * subscriptions during the game. 2) Randomly Shifting Houses: They change * their tariff subscriptions in a RandomSeed way. 3) Regularly Shifting * Houses: * They change their tariff subscriptions during the game in regular time * periods. 4) Smart Shifting Houses: They change their tariff subscriptions * in a smart way in order to minimize their costs. */ Vector<Household> notShiftingHouses = new Vector<Household>(); Vector<Household> randomlyShiftingHouses = new Vector<Household>(); Vector<Household> regularlyShiftingHouses = new Vector<Household>(); Vector<Household> smartShiftingHouses = new Vector<Household>(); /** This is the constructor function of the Village customer */ public Village(String name) { super(name); ArrayList<String> typeList = new ArrayList<String>(); typeList.add("NS"); typeList.add("RaS"); typeList.add("ReS"); typeList.add("SS"); Comparator<CustomerInfo> comp = new Comparator<CustomerInfo>() { public int compare(CustomerInfo customer1, CustomerInfo customer2) { return customer1.getName().compareToIgnoreCase(customer2.getName()); } }; for (String type : typeList) { numberOfHouses.put(type, null); tariffEvaluators = new TreeMap<CustomerInfo, TariffEvaluator>(comp); } } @Override public void initialize() { super.initialize(); } /** * This is the initialization function. It uses the variable values for the * configuration file to create the village with its households and then fill * them with persons and appliances. * * @param conf * @param gen */ public void initialize(Properties conf, int seed, Map<CustomerInfo, String> mapping) { this.initialize(); // Initializing variables houseMapping = mapping; numberOfHouses.put("NS", Integer.parseInt(conf.getProperty("NotShiftingCustomers"))); numberOfHouses.put("RaS", Integer.parseInt(conf.getProperty("RegularlyShiftingCustomers"))); numberOfHouses.put("ReS", Integer.parseInt(conf.getProperty("RandomlyShiftingCustomers"))); numberOfHouses.put("SS", Integer.parseInt(conf.getProperty("SmartShiftingCustomers"))); int days = Integer.parseInt(conf.getProperty("PublicVacationDuration")); gen = service.getRandomSeedRepo().getRandomSeed(toString(), seed, "Village Model" + seed); Vector<Integer> publicVacationVector = createPublicVacationVector(days); for (int i = 0; i < numberOfHouses.get("NS"); i++) { log.info("Initializing " + toString() + " NSHouse " + i); Household hh = new Household(); hh.initialize(toString() + " NSHouse" + i, conf, publicVacationVector, seedId++); notShiftingHouses.add(hh); hh.householdOf = this; } for (int i = 0; i < numberOfHouses.get("RaS"); i++) { log.info("Initializing " + toString() + " RaSHouse " + i); Household hh = new Household(); hh.initialize(toString() + " RaSHouse" + i, conf, publicVacationVector, seedId++); randomlyShiftingHouses.add(hh); hh.householdOf = this; } for (int i = 0; i < numberOfHouses.get("ReS"); i++) { log.info("Initializing " + toString() + " ReSHouse " + i); Household hh = new Household(); hh.initialize(toString() + " ReSHouse" + i, conf, publicVacationVector, seedId++); regularlyShiftingHouses.add(hh); hh.householdOf = this; } for (int i = 0; i < numberOfHouses.get("SS"); i++) { log.info("Initializing " + toString() + " SSHouse " + i); Household hh = new Household(); hh.initialize(toString() + " SSHouse" + i, conf, publicVacationVector, seedId++); smartShiftingHouses.add(hh); hh.householdOf = this; } for (String type : numberOfHouses.keySet()) { fillAggWeeklyLoad(type); double weight = gen.nextDouble() * VillageConstants.WEIGHT_INCONVENIENCE; double weeks = gen .nextInt(VillageConstants.MAX_DEFAULT_DURATION - VillageConstants.MIN_DEFAULT_DURATION) + VillageConstants.MIN_DEFAULT_DURATION; List<CustomerInfo> customer = service.getCustomerRepo().findByName(name + " " + type + " Base"); TariffEvaluationWrapper wrapper = new TariffEvaluationWrapper(type, customer.get(0)); TariffEvaluator te = new TariffEvaluator(wrapper); te.initializeInconvenienceFactors(VillageConstants.TOU_FACTOR, VillageConstants.TIERED_RATE_FACTOR, VillageConstants.VARIABLE_PRICING_FACTOR, VillageConstants.INTERRUPTIBILITY_FACTOR); te.withInconvenienceWeight(weight).withInertia(Double.parseDouble(conf.getProperty(type + "Inertia"))) .withPreferredContractDuration(weeks * VillageConstants.DAYS_OF_WEEK) .withRationality(Double.parseDouble(conf.getProperty(type + "Rationality"))) .withTariffEvalDepth(VillageConstants.TARIFF_COUNT) .withTariffSwitchFactor(VillageConstants.TARIFF_SWITCH_FACTOR); tariffEvaluators.put(customer.get(0), te); customer = service.getCustomerRepo().findByName(name + " " + type + " Controllable"); wrapper = new TariffEvaluationWrapper(type, customer.get(0)); te = new TariffEvaluator(wrapper); te.initializeInconvenienceFactors(VillageConstants.TOU_FACTOR, VillageConstants.TIERED_RATE_FACTOR, VillageConstants.VARIABLE_PRICING_FACTOR, VillageConstants.INTERRUPTIBILITY_FACTOR); te.withInconvenienceWeight(weight).withInertia(Double.parseDouble(conf.getProperty(type + "Inertia"))) .withPreferredContractDuration(weeks * VillageConstants.DAYS_OF_WEEK) .withRationality(Double.parseDouble(conf.getProperty(type + "Rationality"))) .withTariffEvalDepth(VillageConstants.TARIFF_COUNT) .withTariffSwitchFactor(VillageConstants.TARIFF_SWITCH_FACTOR); tariffEvaluators.put(customer.get(0), te); } } // =====SUBSCRIPTION FUNCTIONS===== // //@Override public void subscribeDefault(TariffMarket tariffMarketService) { for (CustomerInfo customer : getCustomerInfos()) { Tariff candidate = tariffMarketService.getDefaultTariff(customer.getPowerType()); if (null == candidate) { log.error("No default tariff for " + customer.getPowerType().toString()); } else { log.info("Subscribe " + customer.getName() + " to " + candidate.getPowerType().toString()); } tariffMarketService.subscribeToTariff(candidate, customer, customer.getPopulation()); } } // =====LOAD FUNCTIONS===== // /** * This function is used in order to fill each week day of the aggregated * daily Load of the village households for each quarter of the hour. * * @param type * @return */ void fillAggWeeklyLoad(String type) { if (type.equals("NS")) { for (int i = 0; i < VillageConstants.DAYS_OF_WEEK * (VillageConstants.WEEKS_OF_COMPETITION + VillageConstants.WEEKS_OF_BOOTSTRAP); i++) { aggDailyBaseLoadNS.add(fillAggDailyBaseLoad(i, type)); aggDailyControllableLoadNS.add(fillAggDailyControllableLoad(i, type)); aggDailyWeatherSensitiveLoadNS.add(fillAggDailyWeatherSensitiveLoad(i, type)); aggDailyBaseLoadInHoursNS.add(fillAggDailyBaseLoadInHours(i, type)); aggDailyControllableLoadInHoursNS.add(fillAggDailyControllableLoadInHours(i, type)); aggDailyWeatherSensitiveLoadInHoursNS.add(fillAggDailyWeatherSensitiveLoadInHours(i, type)); aggDailyDominantLoadNS.add(fillAggDailyDominantLoad(i, type)); aggDailyNonDominantLoadNS.add(fillAggDailyNonDominantLoad(i, type)); aggDailyDominantLoadInHoursNS.add(fillAggDailyDominantLoadInHours(i, type)); aggDailyNonDominantLoadInHoursNS.add(fillAggDailyNonDominantLoadInHours(i, type)); } } else if (type.equals("RaS")) { for (int i = 0; i < VillageConstants.DAYS_OF_WEEK * (VillageConstants.WEEKS_OF_COMPETITION + VillageConstants.WEEKS_OF_BOOTSTRAP); i++) { aggDailyBaseLoadRaS.add(fillAggDailyBaseLoad(i, type)); aggDailyControllableLoadRaS.add(fillAggDailyControllableLoad(i, type)); aggDailyWeatherSensitiveLoadRaS.add(fillAggDailyWeatherSensitiveLoad(i, type)); aggDailyBaseLoadInHoursRaS.add(fillAggDailyBaseLoadInHours(i, type)); aggDailyControllableLoadInHoursRaS.add(fillAggDailyControllableLoadInHours(i, type)); aggDailyWeatherSensitiveLoadInHoursRaS.add(fillAggDailyWeatherSensitiveLoadInHours(i, type)); aggDailyDominantLoadRaS.add(fillAggDailyDominantLoad(i, type)); aggDailyNonDominantLoadRaS.add(fillAggDailyNonDominantLoad(i, type)); aggDailyDominantLoadInHoursRaS.add(fillAggDailyDominantLoadInHours(i, type)); aggDailyNonDominantLoadInHoursRaS.add(fillAggDailyNonDominantLoadInHours(i, type)); } } else if (type.equals("ReS")) { for (int i = 0; i < VillageConstants.DAYS_OF_WEEK * (VillageConstants.WEEKS_OF_COMPETITION + VillageConstants.WEEKS_OF_BOOTSTRAP); i++) { aggDailyBaseLoadReS.add(fillAggDailyBaseLoad(i, type)); aggDailyControllableLoadReS.add(fillAggDailyControllableLoad(i, type)); aggDailyWeatherSensitiveLoadReS.add(fillAggDailyWeatherSensitiveLoad(i, type)); aggDailyBaseLoadInHoursReS.add(fillAggDailyBaseLoadInHours(i, type)); aggDailyControllableLoadInHoursReS.add(fillAggDailyControllableLoadInHours(i, type)); aggDailyWeatherSensitiveLoadInHoursReS.add(fillAggDailyWeatherSensitiveLoadInHours(i, type)); aggDailyDominantLoadReS.add(fillAggDailyDominantLoad(i, type)); aggDailyNonDominantLoadReS.add(fillAggDailyNonDominantLoad(i, type)); aggDailyDominantLoadInHoursReS.add(fillAggDailyDominantLoadInHours(i, type)); aggDailyNonDominantLoadInHoursReS.add(fillAggDailyNonDominantLoadInHours(i, type)); } } else { for (int i = 0; i < VillageConstants.DAYS_OF_WEEK * (VillageConstants.WEEKS_OF_COMPETITION + VillageConstants.WEEKS_OF_BOOTSTRAP); i++) { aggDailyBaseLoadSS.add(fillAggDailyBaseLoad(i, type)); aggDailyControllableLoadSS.add(fillAggDailyControllableLoad(i, type)); aggDailyWeatherSensitiveLoadSS.add(fillAggDailyWeatherSensitiveLoad(i, type)); aggDailyBaseLoadInHoursSS.add(fillAggDailyBaseLoadInHours(i, type)); aggDailyControllableLoadInHoursSS.add(fillAggDailyControllableLoadInHours(i, type)); aggDailyWeatherSensitiveLoadInHoursSS.add(fillAggDailyWeatherSensitiveLoadInHours(i, type)); aggDailyDominantLoadSS.add(fillAggDailyDominantLoad(i, type)); aggDailyNonDominantLoadSS.add(fillAggDailyNonDominantLoad(i, type)); aggDailyDominantLoadInHoursSS.add(fillAggDailyDominantLoadInHours(i, type)); aggDailyNonDominantLoadInHoursSS.add(fillAggDailyNonDominantLoadInHours(i, type)); } } fillAggDominantLoads(type); } private void fillAggDominantLoads(String type) { double[] dominant = new double[VillageConstants.HOURS_OF_DAY]; double[] nonDominant = new double[VillageConstants.HOURS_OF_DAY]; Vector<Household> houses = getHouses(type); for (int i = 0; i < houses.size(); i++) { for (int j = 0; j < VillageConstants.HOURS_OF_DAY; j++) { dominant[j] += houses.get(i).getDominantConsumption(j); nonDominant[j] += houses.get(i).getNonDominantConsumption(j); } } if (type.equals("NS")) { dominantLoadNS = dominant; nonDominantLoadNS = nonDominant; } else if (type.equals("RaS")) { dominantLoadRaS = dominant; nonDominantLoadRaS = nonDominant; } else if (type.equals("ReS")) { dominantLoadReS = dominant; nonDominantLoadReS = nonDominant; } else { dominantLoadSS = dominant; nonDominantLoadSS = nonDominant; } } private double[] getDominantLoad(String type) { if (type.equals("NS")) return dominantLoadNS; else if (type.equals("RaS")) return dominantLoadRaS; else if (type.equals("ReS")) return dominantLoadReS; else return dominantLoadSS; } /** * This function is used in order to update the daily aggregated Load in case * there are changes in the weather sensitive loads of the village's * households. * * @param type * @return */ void updateAggDailyWeatherSensitiveLoad(String type, int day) { int dayTemp = day % (VillageConstants.DAYS_OF_BOOTSTRAP + VillageConstants.DAYS_OF_COMPETITION); if (type.equals("NS")) { aggDailyWeatherSensitiveLoadNS.set(dayTemp, fillAggDailyWeatherSensitiveLoad(dayTemp, type)); aggDailyWeatherSensitiveLoadInHoursNS.set(dayTemp, fillAggDailyWeatherSensitiveLoadInHours(dayTemp, type)); } else if (type.equals("RaS")) { aggDailyWeatherSensitiveLoadRaS.set(dayTemp, fillAggDailyWeatherSensitiveLoad(dayTemp, type)); aggDailyWeatherSensitiveLoadInHoursRaS.set(dayTemp, fillAggDailyWeatherSensitiveLoadInHours(dayTemp, type)); } else if (type.equals("ReS")) { aggDailyWeatherSensitiveLoadReS.set(dayTemp, fillAggDailyWeatherSensitiveLoad(dayTemp, type)); aggDailyWeatherSensitiveLoadInHoursReS.set(dayTemp, fillAggDailyWeatherSensitiveLoadInHours(dayTemp, type)); } else { aggDailyWeatherSensitiveLoadSS.set(dayTemp, fillAggDailyWeatherSensitiveLoad(dayTemp, type)); aggDailyWeatherSensitiveLoadInHoursSS.set(dayTemp, fillAggDailyWeatherSensitiveLoadInHours(dayTemp, type)); } } /** * This function is used in order to fill the aggregated daily Base Load of * the village's households for each quarter of the hour. * * @param day * @param type * @return */ Vector<Long> fillAggDailyBaseLoad(int day, String type) { Vector<Household> houses = new Vector<Household>(); if (type.equals("NS")) { houses = notShiftingHouses; } else if (type.equals("RaS")) { houses = randomlyShiftingHouses; } else if (type.equals("ReS")) { houses = regularlyShiftingHouses; } else { houses = smartShiftingHouses; } Vector<Long> v = new Vector<Long>(VillageConstants.QUARTERS_OF_DAY); long sum = 0; for (int i = 0; i < VillageConstants.QUARTERS_OF_DAY; i++) { sum = 0; for (Household house : houses) { sum = sum + house.weeklyBaseLoad.get(day).get(i); } v.add(sum); } return v; } /** * This function is used in order to fill the aggregated daily Controllable * Load of the village's households for each quarter of the hour. * * @param day * @param type * @return */ Vector<Long> fillAggDailyControllableLoad(int day, String type) { Vector<Household> houses = new Vector<Household>(); if (type.equals("NS")) { houses = notShiftingHouses; } else if (type.equals("RaS")) { houses = randomlyShiftingHouses; } else if (type.equals("ReS")) { houses = regularlyShiftingHouses; } else { houses = smartShiftingHouses; } Vector<Long> v = new Vector<Long>(VillageConstants.QUARTERS_OF_DAY); long sum = 0; for (int i = 0; i < VillageConstants.QUARTERS_OF_DAY; i++) { sum = 0; for (Household house : houses) { sum = sum + house.weeklyControllableLoad.get(day).get(i); } v.add(sum); } return v; } /** * This function is used in order to fill the aggregated daily weather * sensitive Load of the village's households for each quarter of the hour. * * @param day * @param type * @return */ Vector<Long> fillAggDailyWeatherSensitiveLoad(int day, String type) { Vector<Household> houses = new Vector<Household>(); if (type.equals("NS")) { houses = notShiftingHouses; } else if (type.equals("RaS")) { houses = randomlyShiftingHouses; } else if (type.equals("ReS")) { houses = regularlyShiftingHouses; } else { houses = smartShiftingHouses; } Vector<Long> v = new Vector<Long>(VillageConstants.QUARTERS_OF_DAY); long sum = 0; for (int i = 0; i < VillageConstants.QUARTERS_OF_DAY; i++) { sum = 0; for (Household house : houses) { sum = sum + house.weeklyWeatherSensitiveLoad.get(day).get(i); } v.add(sum); } return v; } /** * This function is used in order to fill the aggregated daily dominant * Load of the village's households for each quarter of the hour. * * @param day * @param type * @return */ Vector<Long> fillAggDailyDominantLoad(int day, String type) { Vector<Household> houses = new Vector<Household>(); if (type.equals("NS")) { houses = notShiftingHouses; } else if (type.equals("RaS")) { houses = randomlyShiftingHouses; } else if (type.equals("ReS")) { houses = regularlyShiftingHouses; } else { houses = smartShiftingHouses; } Vector<Long> v = new Vector<Long>(VillageConstants.QUARTERS_OF_DAY); long sum = 0; for (int i = 0; i < VillageConstants.QUARTERS_OF_DAY; i++) { sum = 0; for (Household house : houses) { sum = sum + house.weeklyDominantLoad.get(day).get(i); } v.add(sum); } return v; } /** * This function is used in order to fill the aggregated daily non dominant * Load of the village's households for each quarter of the hour. * * @param day * @param type * @return */ Vector<Long> fillAggDailyNonDominantLoad(int day, String type) { Vector<Household> houses = new Vector<Household>(); if (type.equals("NS")) { houses = notShiftingHouses; } else if (type.equals("RaS")) { houses = randomlyShiftingHouses; } else if (type.equals("ReS")) { houses = regularlyShiftingHouses; } else { houses = smartShiftingHouses; } Vector<Long> v = new Vector<Long>(VillageConstants.QUARTERS_OF_DAY); long sum = 0; for (int i = 0; i < VillageConstants.QUARTERS_OF_DAY; i++) { sum = 0; for (Household house : houses) { sum = sum + house.weeklyNonDominantLoad.get(day).get(i); } v.add(sum); } return v; } /** * This function is used in order to fill the daily Base Load of the household * for each hour for a certain type of households. * * @param day * @param type * @return */ Vector<Long> fillAggDailyBaseLoadInHours(int day, String type) { Vector<Long> daily = new Vector<Long>(); long sum = 0; if (type.equals("NS")) { for (int i = 0; i < VillageConstants.HOURS_OF_DAY; i++) { sum = 0; sum = aggDailyBaseLoadNS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR) + aggDailyBaseLoadNS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR + 1) + aggDailyBaseLoadNS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR + 2) + aggDailyBaseLoadNS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR + 3); daily.add(sum); } } else if (type.equals("RaS")) { for (int i = 0; i < VillageConstants.HOURS_OF_DAY; i++) { sum = 0; sum = aggDailyBaseLoadRaS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR) + aggDailyBaseLoadRaS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR + 1) + aggDailyBaseLoadRaS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR + 2) + aggDailyBaseLoadRaS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR + 3); daily.add(sum); } } else if (type.equals("ReS")) { for (int i = 0; i < VillageConstants.HOURS_OF_DAY; i++) { sum = 0; sum = aggDailyBaseLoadReS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR) + aggDailyBaseLoadReS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR + 1) + aggDailyBaseLoadReS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR + 2) + aggDailyBaseLoadReS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR + 3); daily.add(sum); } } else { for (int i = 0; i < VillageConstants.HOURS_OF_DAY; i++) { sum = 0; sum = aggDailyBaseLoadSS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR) + aggDailyBaseLoadSS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR + 1) + aggDailyBaseLoadSS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR + 2) + aggDailyBaseLoadSS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR + 3); daily.add(sum); } } return daily; } /** * This function is used in order to fill the daily Controllable Load of the * household for each hour for a certain type of households. * * @param day * @param type * @return */ Vector<Long> fillAggDailyControllableLoadInHours(int day, String type) { Vector<Long> daily = new Vector<Long>(); long sum = 0; if (type.equals("NS")) { for (int i = 0; i < VillageConstants.HOURS_OF_DAY; i++) { sum = 0; sum = aggDailyControllableLoadNS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR) + aggDailyControllableLoadNS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR + 1) + aggDailyControllableLoadNS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR + 2) + aggDailyControllableLoadNS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR + 3); daily.add(sum); } } else if (type.equals("RaS")) { for (int i = 0; i < VillageConstants.HOURS_OF_DAY; i++) { sum = 0; sum = aggDailyControllableLoadRaS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR) + aggDailyControllableLoadRaS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR + 1) + aggDailyControllableLoadRaS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR + 2) + aggDailyControllableLoadRaS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR + 3); daily.add(sum); } } else if (type.equals("ReS")) { for (int i = 0; i < VillageConstants.HOURS_OF_DAY; i++) { sum = 0; sum = aggDailyControllableLoadReS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR) + aggDailyControllableLoadReS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR + 1) + aggDailyControllableLoadReS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR + 2) + aggDailyControllableLoadReS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR + 3); daily.add(sum); } } else { for (int i = 0; i < VillageConstants.HOURS_OF_DAY; i++) { sum = 0; sum = aggDailyControllableLoadSS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR) + aggDailyControllableLoadSS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR + 1) + aggDailyControllableLoadSS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR + 2) + aggDailyControllableLoadSS.get(day).get(i * VillageConstants.QUARTERS_OF_HOUR + 3); daily.add(sum); } } return daily; } /** * This function is used in order to fill the daily weather sensitive Load of * the household for each hour for a certain type of households. * * @param day * @param type * @return */ Vector<Long> fillAggDailyWeatherSensitiveLoadInHours(int day, String type) { int dayTemp = day % (VillageConstants.DAYS_OF_BOOTSTRAP + VillageConstants.DAYS_OF_COMPETITION); Vector<Long> daily = new Vector<Long>(); long sum = 0; if (type.equals("NS")) { for (int i = 0; i < VillageConstants.HOURS_OF_DAY; i++) { sum = 0; sum = aggDailyWeatherSensitiveLoadNS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR) + aggDailyWeatherSensitiveLoadNS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR + 1) + aggDailyWeatherSensitiveLoadNS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR + 2) + aggDailyWeatherSensitiveLoadNS.get(dayTemp) .get(i * VillageConstants.QUARTERS_OF_HOUR + 3); daily.add(sum); } } else if (type.equals("RaS")) { for (int i = 0; i < VillageConstants.HOURS_OF_DAY; i++) { sum = 0; sum = aggDailyWeatherSensitiveLoadRaS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR) + aggDailyWeatherSensitiveLoadRaS.get(dayTemp) .get(i * VillageConstants.QUARTERS_OF_HOUR + 1) + aggDailyWeatherSensitiveLoadRaS.get(dayTemp) .get(i * VillageConstants.QUARTERS_OF_HOUR + 2) + aggDailyWeatherSensitiveLoadRaS.get(dayTemp) .get(i * VillageConstants.QUARTERS_OF_HOUR + 3); daily.add(sum); } } else if (type.equals("ReS")) { for (int i = 0; i < VillageConstants.HOURS_OF_DAY; i++) { sum = 0; sum = aggDailyWeatherSensitiveLoadReS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR) + aggDailyWeatherSensitiveLoadReS.get(dayTemp) .get(i * VillageConstants.QUARTERS_OF_HOUR + 1) + aggDailyWeatherSensitiveLoadReS.get(dayTemp) .get(i * VillageConstants.QUARTERS_OF_HOUR + 2) + aggDailyWeatherSensitiveLoadReS.get(dayTemp) .get(i * VillageConstants.QUARTERS_OF_HOUR + 3); daily.add(sum); } } else { for (int i = 0; i < VillageConstants.HOURS_OF_DAY; i++) { sum = 0; sum = aggDailyWeatherSensitiveLoadSS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR) + aggDailyWeatherSensitiveLoadSS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR + 1) + aggDailyWeatherSensitiveLoadSS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR + 2) + aggDailyWeatherSensitiveLoadSS.get(dayTemp) .get(i * VillageConstants.QUARTERS_OF_HOUR + 3); daily.add(sum); } } return daily; } /** * This function is used in order to fill the daily dominant Load of * the household for each hour for a certain type of households. * * @param day * @param type * @return */ Vector<Long> fillAggDailyDominantLoadInHours(int day, String type) { int dayTemp = day % (VillageConstants.DAYS_OF_BOOTSTRAP + VillageConstants.DAYS_OF_COMPETITION); Vector<Long> daily = new Vector<Long>(); long sum = 0; if (type.equals("NS")) { for (int i = 0; i < VillageConstants.HOURS_OF_DAY; i++) { sum = 0; sum = aggDailyDominantLoadNS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR) + aggDailyDominantLoadNS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR + 1) + aggDailyDominantLoadNS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR + 2) + aggDailyDominantLoadNS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR + 3); daily.add(sum); } } else if (type.equals("RaS")) { for (int i = 0; i < VillageConstants.HOURS_OF_DAY; i++) { sum = 0; sum = aggDailyDominantLoadRaS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR) + aggDailyDominantLoadRaS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR + 1) + aggDailyDominantLoadRaS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR + 2) + aggDailyDominantLoadRaS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR + 3); daily.add(sum); } } else if (type.equals("ReS")) { for (int i = 0; i < VillageConstants.HOURS_OF_DAY; i++) { sum = 0; sum = aggDailyDominantLoadReS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR) + aggDailyDominantLoadReS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR + 1) + aggDailyDominantLoadReS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR + 2) + aggDailyDominantLoadReS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR + 3); daily.add(sum); } } else { for (int i = 0; i < VillageConstants.HOURS_OF_DAY; i++) { sum = 0; sum = aggDailyDominantLoadSS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR) + aggDailyDominantLoadSS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR + 1) + aggDailyDominantLoadSS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR + 2) + aggDailyDominantLoadSS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR + 3); daily.add(sum); } } return daily; } /** * This function is used in order to fill the daily non dominant Load of * the household for each hour for a certain type of households. * * @param day * @param type * @return */ Vector<Long> fillAggDailyNonDominantLoadInHours(int day, String type) { int dayTemp = day % (VillageConstants.DAYS_OF_BOOTSTRAP + VillageConstants.DAYS_OF_COMPETITION); Vector<Long> daily = new Vector<Long>(); long sum = 0; if (type.equals("NS")) { for (int i = 0; i < VillageConstants.HOURS_OF_DAY; i++) { sum = 0; sum = aggDailyNonDominantLoadNS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR) + aggDailyNonDominantLoadNS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR + 1) + aggDailyNonDominantLoadNS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR + 2) + aggDailyNonDominantLoadNS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR + 3); daily.add(sum); } } else if (type.equals("RaS")) { for (int i = 0; i < VillageConstants.HOURS_OF_DAY; i++) { sum = 0; sum = aggDailyNonDominantLoadRaS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR) + aggDailyNonDominantLoadRaS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR + 1) + aggDailyNonDominantLoadRaS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR + 2) + aggDailyNonDominantLoadRaS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR + 3); daily.add(sum); } } else if (type.equals("ReS")) { for (int i = 0; i < VillageConstants.HOURS_OF_DAY; i++) { sum = 0; sum = aggDailyNonDominantLoadReS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR) + aggDailyNonDominantLoadReS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR + 1) + aggDailyNonDominantLoadReS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR + 2) + aggDailyNonDominantLoadReS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR + 3); daily.add(sum); } } else { for (int i = 0; i < VillageConstants.HOURS_OF_DAY; i++) { sum = 0; sum = aggDailyNonDominantLoadSS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR) + aggDailyNonDominantLoadSS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR + 1) + aggDailyNonDominantLoadSS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR + 2) + aggDailyNonDominantLoadSS.get(dayTemp).get(i * VillageConstants.QUARTERS_OF_HOUR + 3); daily.add(sum); } } return daily; } // // =====CONSUMPTION FUNCTIONS===== // public void consumePower() { Timeslot ts = service.getTimeslotRepo().currentTimeslot(); int serial; for (CustomerInfo customer : getCustomerInfos()) { List<TariffSubscription> subscriptions = service.getTariffSubscriptionRepo() .findActiveSubscriptionsForCustomer(customer); String temp = houseMapping.get(customer); String type = temp.substring(0, 2); boolean controllable = temp.contains("Controllable"); if (ts == null) { log.error("Current timeslot is null"); serial = 0; } else { log.debug("Timeslot Serial: " + ts.getSerialNumber()); serial = ts.getSerialNumber(); } double load = getConsumptionByTimeslot(serial, type, controllable); log.debug("Consumption Load for Customer " + customer.toString() + ": " + load + " for subscriptions " + subscriptions.toString()); if (subscriptions != null && subscriptions.size() != 0) { subscriptions.get(0).usePower(load); } } } /** * This method takes as an input the time-slot serial number (in order to know * in the current time) and estimates the consumption for this time-slot over * the population under the Village Household Consumer. */ double getConsumptionByTimeslot(int serial, String type, boolean controllable) { int day = (int) (serial / VillageConstants.HOURS_OF_DAY); int hour = (int) (serial % VillageConstants.HOURS_OF_DAY); long summary = 0; log.debug("Serial : " + serial + " Day: " + day + " Hour: " + hour); if (controllable) summary = getControllableConsumptions(day, hour, type); else summary = getBaseConsumptions(day, hour, type) + getWeatherSensitiveConsumptions(day, hour, type); return (double) summary / VillageConstants.THOUSAND; } // =====GETTER FUNCTIONS===== // /** This function returns the inertia Map variable of the village. */ public Map<CustomerInfo, String> getHouseMapping() { return houseMapping; } /** This function returns the period Map variable of the village. */ public Map<CustomerInfo, TariffEvaluator> getTariffEvaluators() { return tariffEvaluators; } /** * This function returns the quantity of base load for a specific day and hour * of that day for a specific type of households. */ long getBaseConsumptions(int day, int hour, String type) { long summaryBase = 0; int dayTemp = day % (VillageConstants.DAYS_OF_BOOTSTRAP + VillageConstants.DAYS_OF_COMPETITION); if (type.equals("NS")) { summaryBase = aggDailyBaseLoadInHoursNS.get(dayTemp).get(hour); } else if (type.equals("RaS")) { summaryBase = aggDailyBaseLoadInHoursRaS.get(dayTemp).get(hour); } else if (type.equals("ReS")) { summaryBase = aggDailyBaseLoadInHoursReS.get(dayTemp).get(hour); } else { summaryBase = aggDailyBaseLoadInHoursSS.get(dayTemp).get(hour); } log.debug("Base Load for " + type + ":" + summaryBase); return summaryBase; } /** * This function returns the quantity of controllable load for a specific day * and hour of that day for a specific type of households. */ long getControllableConsumptions(int day, int hour, String type) { long summaryControllable = 0; int dayTemp = day % (VillageConstants.DAYS_OF_BOOTSTRAP + VillageConstants.DAYS_OF_COMPETITION); if (type.equals("NS")) { summaryControllable = aggDailyControllableLoadInHoursNS.get(dayTemp).get(hour); } else if (type.equals("RaS")) { summaryControllable = aggDailyControllableLoadInHoursRaS.get(dayTemp).get(hour); } else if (type.equals("ReS")) { summaryControllable = aggDailyControllableLoadInHoursReS.get(dayTemp).get(hour); } else { summaryControllable = aggDailyControllableLoadInHoursSS.get(dayTemp).get(hour); } log.debug("Controllable Load for " + type + ":" + summaryControllable); return summaryControllable; } /** * This function returns the quantity of weather sensitive load for a specific * day and hour of that day for a specific type of household. */ long getNonDominantConsumptions(int day, int hour, String type) { long summaryNonDominant = 0; int dayTemp = day % (VillageConstants.DAYS_OF_BOOTSTRAP + VillageConstants.DAYS_OF_COMPETITION); if (type.equals("NS")) { summaryNonDominant = aggDailyNonDominantLoadInHoursNS.get(dayTemp).get(hour); } else if (type.equals("RaS")) { summaryNonDominant = aggDailyNonDominantLoadInHoursRaS.get(dayTemp).get(hour); } else if (type.equals("ReS")) { summaryNonDominant = aggDailyNonDominantLoadInHoursReS.get(dayTemp).get(hour); } else { summaryNonDominant = aggDailyNonDominantLoadInHoursSS.get(dayTemp).get(hour); } log.debug("NonDominant Load for " + type + ":" + summaryNonDominant); return summaryNonDominant; } /** * This function returns the quantity of non dominant load for a specific * day and hour of that day for a specific type of household. */ long getWeatherSensitiveConsumptions(int day, int hour, String type) { long summaryWeatherSensitive = 0; int dayTemp = day % (VillageConstants.DAYS_OF_BOOTSTRAP + VillageConstants.DAYS_OF_COMPETITION); if (type.equals("NS")) { summaryWeatherSensitive = aggDailyWeatherSensitiveLoadInHoursNS.get(dayTemp).get(hour); } else if (type.equals("RaS")) { summaryWeatherSensitive = aggDailyWeatherSensitiveLoadInHoursRaS.get(dayTemp).get(hour); } else if (type.equals("ReS")) { summaryWeatherSensitive = aggDailyWeatherSensitiveLoadInHoursReS.get(dayTemp).get(hour); } else { summaryWeatherSensitive = aggDailyWeatherSensitiveLoadInHoursSS.get(dayTemp).get(hour); } log.debug("WeatherSensitive Load for " + type + ":" + summaryWeatherSensitive); return summaryWeatherSensitive; } /** * This function curtails the quantity of controllable load given by the * subscription, by reducing current timeslots consumption and adding it to * the next timeslot. */ void curtailControllableConsumption(int day, int hour, String type, long curtail) { long before = 0, after = 0; int dayTemp = day % (VillageConstants.DAYS_OF_BOOTSTRAP + VillageConstants.DAYS_OF_COMPETITION); if (type.equals("NS")) { before = aggDailyControllableLoadInHoursNS.get(dayTemp).get(hour); aggDailyControllableLoadInHoursNS.get(dayTemp).set(hour, before + curtail); after = aggDailyControllableLoadInHoursNS.get(dayTemp).get(hour); } else if (type.equals("RaS")) { before = aggDailyControllableLoadInHoursRaS.get(dayTemp).get(hour); aggDailyControllableLoadInHoursRaS.get(dayTemp).set(hour, before + curtail); after = aggDailyControllableLoadInHoursRaS.get(dayTemp).get(hour); } else if (type.equals("ReS")) { before = aggDailyControllableLoadInHoursReS.get(dayTemp).get(hour); aggDailyControllableLoadInHoursReS.get(dayTemp).set(hour, before + curtail); after = aggDailyControllableLoadInHoursReS.get(dayTemp).get(hour); } else { before = aggDailyControllableLoadInHoursSS.get(dayTemp).get(hour); aggDailyControllableLoadInHoursSS.get(dayTemp).set(hour, before + curtail); after = aggDailyControllableLoadInHoursSS.get(dayTemp).get(hour); } log.debug( "Controllable Load for " + type + ": Before Curtailment " + before + " After Curtailment " + after); } /** * This function returns the quantity of controllable load for a specific day * in form of a vector for a certain type of households. */ Vector<Long> getControllableConsumptions(int day, String type) { Vector<Long> controllableVector = new Vector<Long>(); int dayTemp = day % (VillageConstants.DAYS_OF_BOOTSTRAP + VillageConstants.DAYS_OF_COMPETITION); if (type.equals("NS")) { controllableVector = aggDailyControllableLoadInHoursNS.get(dayTemp); } else if (type.equals("RaS")) { controllableVector = aggDailyControllableLoadInHoursRaS.get(dayTemp); } else if (type.equals("ReS")) { controllableVector = aggDailyControllableLoadInHoursReS.get(dayTemp); } else { controllableVector = aggDailyControllableLoadInHoursSS.get(dayTemp); } return controllableVector; } /** * This function returns the quantity of weather sensitive load for a specific * day in form of a vector for a certain type of households. */ Vector<Long> getWeatherSensitiveConsumptions(int day, String type) { Vector<Long> weatherSensitiveVector = new Vector<Long>(); int dayTemp = day % (VillageConstants.DAYS_OF_BOOTSTRAP + VillageConstants.DAYS_OF_COMPETITION); if (type.equals("NS")) { weatherSensitiveVector = aggDailyWeatherSensitiveLoadInHoursNS.get(dayTemp); } else if (type.equals("RaS")) { weatherSensitiveVector = aggDailyWeatherSensitiveLoadInHoursRaS.get(dayTemp); } else if (type.equals("ReS")) { weatherSensitiveVector = aggDailyWeatherSensitiveLoadInHoursReS.get(dayTemp); } else { weatherSensitiveVector = aggDailyWeatherSensitiveLoadInHoursSS.get(dayTemp); } return weatherSensitiveVector; } /** * This function returns the quantity of weather sensitive load for a specific * day in form of a vector for a certain type of households. */ Vector<Long> getNonDominantConsumptions(int day, String type) { Vector<Long> nonDominantVector = new Vector<Long>(); int dayTemp = day % (VillageConstants.DAYS_OF_BOOTSTRAP + VillageConstants.DAYS_OF_COMPETITION); if (type.equals("NS")) { nonDominantVector = aggDailyNonDominantLoadInHoursNS.get(dayTemp); } else if (type.equals("RaS")) { nonDominantVector = aggDailyNonDominantLoadInHoursRaS.get(dayTemp); } else if (type.equals("ReS")) { nonDominantVector = aggDailyNonDominantLoadInHoursReS.get(dayTemp); } else { nonDominantVector = aggDailyNonDominantLoadInHoursSS.get(dayTemp); } return nonDominantVector; } /** * This function returns a vector with all the houses that are present in this * village. */ public Vector<Household> getHouses() { Vector<Household> houses = new Vector<Household>(); for (Household house : notShiftingHouses) houses.add(house); for (Household house : regularlyShiftingHouses) houses.add(house); for (Household house : randomlyShiftingHouses) houses.add(house); for (Household house : smartShiftingHouses) houses.add(house); return houses; } /** * This function returns a vector with all the households of a certain type * that are present in this village. */ public Vector<Household> getHouses(String type) { Vector<Household> houses = new Vector<Household>(); if (type.equals("NS")) { for (Household house : notShiftingHouses) { houses.add(house); } } else if (type.equals("RaS")) { for (Household house : regularlyShiftingHouses) { houses.add(house); } } else if (type.equals("ReS")) { for (Household house : randomlyShiftingHouses) { houses.add(house); } } else { for (Household house : smartShiftingHouses) { houses.add(house); } } return houses; } double[] getNonDominantUsage(int day, String type) { double[] nonDominantUsage = new double[VillageConstants.HOURS_OF_DAY]; for (int hour = 0; hour < VillageConstants.HOURS_OF_DAY; hour++) { if (hour == VillageConstants.HOURS_OF_DAY - 1) nonDominantUsage[hour] = getNonDominantConsumptions(day, 0, type); else nonDominantUsage[hour] = getNonDominantConsumptions(day, hour + 1, type); log.debug("Non Dominant Usage for hour " + hour + ":" + nonDominantUsage[hour]); } return nonDominantUsage; } // =====EVALUATION FUNCTIONS===== // /** * This is the basic evaluation function, taking into consideration the * minimum cost without shifting the appliances' load but the tariff chosen * is * picked up randomly by using a possibility pattern. The better tariffs * have * more chances to be chosen. */ @Override public void evaluateTariffs(List<Tariff> tariffs) { for (CustomerInfo customer : getCustomerInfos()) { log.info("Customer " + customer.toString() + " evaluating tariffs for timeslot " + service.getTimeslotRepo().currentTimeslot().getId()); TariffEvaluator evaluator = tariffEvaluators.get(customer); evaluator.evaluateTariffs(); } } // =====SHIFTING FUNCTIONS===== // /** * This is the function that takes every household in the village and reads * the shifted Controllable Consumption for the needs of the tariff * evaluation. * * @param tariff * @param now * @param day * @param type * @return */ double[] dailyShifting(Tariff tariff, double[] nonDominantUsage, int day, String type) { double[] newControllableLoad = nonDominantUsage; int dayTemp = day % (VillageConstants.DAYS_OF_BOOTSTRAP + VillageConstants.DAYS_OF_COMPETITION); Vector<Household> houses = new Vector<Household>(); if (type.equals("NS")) { houses = notShiftingHouses; } else if (type.equals("RaS")) { houses = randomlyShiftingHouses; } else if (type.equals("ReS")) { houses = regularlyShiftingHouses; } else { houses = smartShiftingHouses; } for (Household house : houses) { double[] temp = house.dailyShifting(tariff, newControllableLoad, tariffEvalHelper, dayTemp, gen); log.debug("New Dominant Load for house " + house.toString() + " for Tariff " + tariff.toString() + ": " + Arrays.toString(temp)); for (int j = 0; j < VillageConstants.HOURS_OF_DAY; j++) newControllableLoad[j] += temp[j]; } log.debug("New Overall Load of Village " + toString() + " type " + type + " for Tariff " + tariff.toString() + ": " + Arrays.toString(newControllableLoad)); return newControllableLoad; } // =====VECTOR CREATION===== // /** * This function is creating a certain number of RandomSeed days that will be * public vacation for the people living in the environment. * * @param days * @param gen * @return */ Vector<Integer> createPublicVacationVector(int days) { // Creating auxiliary variables Vector<Integer> v = new Vector<Integer>(days); for (int i = 0; i < days; i++) { int x = gen.nextInt(VillageConstants.DAYS_OF_COMPETITION + VillageConstants.DAYS_OF_BOOTSTRAP); ListIterator<Integer> iter = v.listIterator(); while (iter.hasNext()) { int temp = (int) iter.next(); if (x == temp) { x = x + 1; iter = v.listIterator(); } } v.add(x); } java.util.Collections.sort(v); return v; } // =====STEP FUNCTIONS===== // @Override public void step() { int serial = service.getTimeslotRepo().currentSerialNumber(); Timeslot ts = service.getTimeslotRepo().currentTimeslot(); // TODO - this code assumes that games start at midnight. Bad assumption. int day = (int) (serial / VillageConstants.HOURS_OF_DAY); int hour = ts.getStartTime().getHourOfDay(); Instant now = ts.getStartInstant(); weatherCheck(day, hour, now); checkCurtailment(serial, day, hour); consumePower(); // for (Household house: getHouses()) // house.test(); if (hour == 23) { for (String type : numberOfHouses.keySet()) { if (!(type.equals("NS"))) { log.info("Rescheduling " + type); rescheduleNextDay(type); } } } } /** * This function is utilized in order to check the weather at each time tick * of the competition clock and reschedule the appliances that are weather * sensitive to work. */ void weatherCheck(int day, int hour, Instant now) { int dayTemp = day % (VillageConstants.DAYS_OF_BOOTSTRAP + VillageConstants.DAYS_OF_COMPETITION); WeatherReport wr = null; wr = service.getWeatherReportRepo().currentWeatherReport(); if (wr != null) { double temperature = wr.getTemperature(); // log.debug("Temperature: " + temperature); Vector<Household> houses = getHouses(); for (Household house : houses) { house.weatherCheck(dayTemp, hour, now, temperature); } for (String type : numberOfHouses.keySet()) { updateAggDailyWeatherSensitiveLoad(type, day); if (dayTemp + 1 < VillageConstants.DAYS_OF_COMPETITION) { updateAggDailyWeatherSensitiveLoad(type, dayTemp + 1); } } } } /** * This function is utilized in order to check the subscriptions * curtailments * for each time tick and move the controllable load at the nexttimeslot. */ void checkCurtailment(int serial, int day, int hour) { int nextSerial = service.getTimeslotRepo().currentSerialNumber() + 1; // (int) ((timeService.getCurrentTime().getMillis() - timeService.getBase()) / TimeService.HOUR) + 1; int nextDay = (int) (nextSerial / VillageConstants.HOURS_OF_DAY); int nextHour = (int) (nextSerial % VillageConstants.HOURS_OF_DAY); int dayTemp = day % (VillageConstants.DAYS_OF_BOOTSTRAP + VillageConstants.DAYS_OF_COMPETITION); int nextDayTemp = nextDay % (VillageConstants.DAYS_OF_BOOTSTRAP + VillageConstants.DAYS_OF_COMPETITION); for (CustomerInfo customer : getCustomerInfos()) { if (customer.getPowerType() == PowerType.INTERRUPTIBLE_CONSUMPTION) { List<TariffSubscription> subs = service.getTariffSubscriptionRepo() .findActiveSubscriptionsForCustomer(customer); long curt = (long) subs.get(0).getCurtailment() * VillageConstants.THOUSAND; log.debug(this.toString() + " Subscription " + subs.get(0).toString() + " Curtailment " + curt); if (curt > 0) { String temp = houseMapping.get(customer); String type = temp.substring(0, 2); curtailControllableConsumption(dayTemp, hour, type, -(long) (curt)); curtailControllableConsumption(nextDayTemp, nextHour, type, (long) (curt)); } } } } /** * This function is utilized in order to reschedule the consumption load for * the next day of the competition according to the tariff rates of the * subscriptions under contract. */ void rescheduleNextDay(String type) { int serial = service.getTimeslotRepo().currentSerialNumber(); int day = (int) (serial / VillageConstants.HOURS_OF_DAY) + 1; int dayTemp = day % (VillageConstants.DAYS_OF_BOOTSTRAP + VillageConstants.DAYS_OF_COMPETITION); double[] nonDominantUsage = getNonDominantUsage(dayTemp, type); Vector<Long> controllableVector = new Vector<Long>(); CustomerInfo customer = service.getCustomerRepo() .findByNameAndPowerType(name + " " + type + " Controllable", PowerType.INTERRUPTIBLE_CONSUMPTION); TariffSubscription sub = service.getTariffSubscriptionRepo().findActiveSubscriptionsForCustomer(customer) .get(0); log.debug("Old Consumption for day " + day + ": " + getControllableConsumptions(dayTemp, type).toString()); double[] newControllableLoad = dailyShifting(sub.getTariff(), nonDominantUsage, dayTemp, type); for (int i = 0; i < VillageConstants.HOURS_OF_DAY; i++) { String newControllableLoadString = Double.toString(newControllableLoad[i]); newControllableLoadString = newControllableLoadString.replace(".0", ""); controllableVector.add(Long.parseLong(newControllableLoadString)); } log.debug("New Consumption for day " + day + ": " + controllableVector.toString()); if (type.equals("RaS")) { aggDailyControllableLoadInHoursRaS.set(dayTemp, controllableVector); } else if (type.equals("ReS")) { aggDailyControllableLoadInHoursReS.set(dayTemp, controllableVector); } else { aggDailyControllableLoadInHoursSS.set(dayTemp, controllableVector); } } @Override public String toString() { return name; } public class TariffEvaluationWrapper implements CustomerModelAccessor { private String type; private int day; private CustomerInfo customerInfo; public TariffEvaluationWrapper(String type, CustomerInfo customer) { this.type = type; customerInfo = customer; day = gen.nextInt(VillageConstants.DAYS_OF_BOOTSTRAP + VillageConstants.DAYS_OF_COMPETITION); } @Override public CustomerInfo getCustomerInfo() { return customerInfo; } public String getType() { return type; } public int getPopulation() { return getHouses(type).size(); } @Override public double[] getCapacityProfile(Tariff tariff) { double[] result = new double[VillageConstants.HOURS_OF_DAY]; if (type.equalsIgnoreCase("NS")) result = Arrays.copyOf(getDominantLoad(type), getDominantLoad(type).length); else { double[] nonDominantUsage = getNonDominantUsage(day, type); result = dailyShifting(tariff, nonDominantUsage, day, type); } log.debug(Arrays.toString(result)); for (int i = 0; i < result.length; i++) result[i] /= (VillageConstants.THOUSAND * getPopulation()); log.info("Usage: " + Arrays.toString(result)); return result; } @Override public double getBrokerSwitchFactor(boolean isSuperseding) { double result = VillageConstants.BROKER_SWITCH_FACTOR; if (isSuperseding) return result * 5.0; return result; } @Override public double getTariffChoiceSample() { return gen.nextDouble(); } @Override public double getInertiaSample() { return gen.nextDouble(); } } }