
org.powertac.officecomplexcustomer.customers.OfficeComplex Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of officecomplex-customer Show documentation
Show all versions of officecomplex-customer Show documentation
Bottom-up model of an office complex energy customer
/*
* 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.officecomplexcustomer.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.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import org.joda.time.Instant;
import org.powertac.common.CapacityProfile;
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.Timeslot;
import org.powertac.common.WeatherReport;
import org.powertac.common.enumerations.PowerType;
import org.powertac.common.interfaces.CustomerModelAccessor;
import org.powertac.common.interfaces.TariffMarket;
import org.powertac.customer.AbstractCustomer;
import org.powertac.officecomplexcustomer.configurations.OfficeComplexConstants;
/**
* The office complex domain class is a set of offices that comprise a office
* building that consumes aggregated energy by the appliances installed in each
* office.
*
* @author Antonios Chrysopoulos
* @version 1.5, Date: 2.25.12
*/
public class OfficeComplex 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 = LogManager.getLogger(OfficeComplex.class.getName());
int seedId = 1;
/**
* These are the vectors containing aggregated each day's base load from the
* appliances installed inside the offices of each type.
**/
Vector> aggDailyBaseLoadNS = new Vector>();
Vector> aggDailyBaseLoadSS = new Vector>();
/**
* These are the vectors containing aggregated each day's controllable load
* from the appliances installed inside the offices.
**/
Vector> aggDailyControllableLoadNS = new Vector>();
Vector> aggDailyControllableLoadSS = new Vector>();
/**
* These are the vectors containing aggregated each day's weather sensitive
* load from the appliances installed inside the offices.
**/
Vector> aggDailyWeatherSensitiveLoadNS =
new Vector>();
Vector> aggDailyWeatherSensitiveLoadSS =
new Vector>();
/**
* These are the vectors containing aggregated each day's dominant load from
* the appliances installed inside the households of each type.
**/
Vector> aggDailyDominantLoadNS = new Vector>();
Vector> aggDailyDominantLoadSS = new Vector>();
/**
* These are the vectors containing aggregated each day's non dominant load
* from the appliances installed inside the households of each type.
**/
Vector> aggDailyNonDominantLoadNS = new Vector>();
Vector> aggDailyNonDominantLoadSS = new Vector>();
/**
* These are the aggregated vectors containing each day's base load of all the
* offices in hours.
**/
Vector> aggDailyBaseLoadInHoursNS = new Vector>();
Vector> aggDailyBaseLoadInHoursSS = new Vector>();
/**
* These are the aggregated vectors containing each day's controllable load of
* all the offices in hours.
**/
Vector> aggDailyControllableLoadInHoursNS =
new Vector>();
Vector> aggDailyControllableLoadInHoursSS =
new Vector>();
/**
* These are the aggregated vectors containing each day's weather sensitive
* load of all the offices in hours.
**/
Vector> aggDailyWeatherSensitiveLoadInHoursNS =
new Vector>();
Vector> aggDailyWeatherSensitiveLoadInHoursSS =
new Vector>();
/**
* These are the vectors containing aggregated each day's dominant load from
* the appliances installed inside the households of each type.
**/
Vector> aggDailyDominantLoadInHoursNS =
new Vector>();
Vector> aggDailyDominantLoadInHoursSS =
new Vector>();
/**
* These are the vectors containing aggregated each day's non dominant load
* from the appliances installed inside the households of each type.
**/
Vector> aggDailyNonDominantLoadInHoursNS =
new Vector>();
Vector> aggDailyNonDominantLoadInHoursSS =
new Vector>();
/**
* These are the mean consumption of the OfficeComplex types for the days with
* the
* dominant appliances working.
**/
double[] dominantLoadNS = new double[OfficeComplexConstants.HOURS_OF_DAY];
double[] dominantLoadSS = new double[OfficeComplexConstants.HOURS_OF_DAY];
/**
* These are the mean consumption of the OfficeComplex types for the days with
* the
* dominant appliances not working.
**/
double[] nonDominantLoadNS = new double[OfficeComplexConstants.HOURS_OF_DAY];
double[] nonDominantLoadSS = new double[OfficeComplexConstants.HOURS_OF_DAY];
protected final TariffEvaluationHelper tariffEvalHelper =
new TariffEvaluationHelper();
/**
* This variable is utilized for the creation of the random numbers and is
* taken from the service.
*/
RandomSeed gen;
/**
* These variables are mapping of the characteristics of the types of houses.
*/
Map numberOfOffices = new TreeMap();
Map tariffEvaluators;
Map officeMapping = new TreeMap();
/**
* These vectors contain the offices of type in the office complex. There are
* 2 types available: 1) Not Shifting offices: They do not change the tariff
* subscriptions during the game. 2) Smart Shifting offices: They change their
* tariff subscriptions in a smart way in order to minimize their costs.
*/
Vector notShiftingOffices = new Vector();
Vector smartShiftingOffices = new Vector();
/** This is the constructor function of the OfficeComplex customer */
public OfficeComplex (String name)
{
super(name);
ArrayList typeList = new ArrayList();
typeList.add("NS");
typeList.add("SS");
Comparator comp = new Comparator() {
@Override
public int compare (CustomerInfo customer1, CustomerInfo customer2)
{
return customer1.getName().compareToIgnoreCase(customer2.getName());
}
};
for (String type: typeList) {
numberOfOffices.put(type, null);
tariffEvaluators = new TreeMap(comp);
}
}
@Override
public void initialize ()
{
super.initialize();
}
/**
* This is the initialization function. It uses the variable values for the
* configuration file to create the office complex with its offices and then
* fill them with persons and appliances.
*/
public void initialize (Properties conf, int seed,
Map mapping)
{
this.initialize();
// Initializing variables
officeMapping = mapping;
numberOfOffices.put("NS", Integer.parseInt(conf
.getProperty("NotShiftingCustomers")));
numberOfOffices.put("SS", Integer.parseInt(conf
.getProperty("SmartShiftingCustomers")));
int days = Integer.parseInt(conf.getProperty("PublicVacationDuration"));
gen = service.getRandomSeedRepo()
.getRandomSeed(toString(), seed, "OfficeComplex Model" + seed);
Vector publicVacationVector = createPublicVacationVector(days);
for (int i = 0; i < numberOfOffices.get("NS"); i++) {
log.info("Initializing " + toString() + " NSoffice " + i);
Office of = new Office();
of.initialize(toString() + " NSoffice" + i, conf, publicVacationVector,
seedId++);
notShiftingOffices.add(of);
of.officeOf = this;
}
for (int i = 0; i < numberOfOffices.get("SS"); i++) {
log.info("Initializing " + toString() + " SSoffice " + i);
Office hh = new Office();
hh.initialize(toString() + " SSoffice" + i, conf, publicVacationVector,
seedId++);
smartShiftingOffices.add(hh);
hh.officeOf = this;
}
for (String type: numberOfOffices.keySet()) {
fillAggWeeklyLoad(type);
double weight =
gen.nextDouble() * OfficeComplexConstants.WEIGHT_INCONVENIENCE;
double weeks =
gen.nextInt(OfficeComplexConstants.MAX_DEFAULT_DURATION
- OfficeComplexConstants.MIN_DEFAULT_DURATION)
+ OfficeComplexConstants.MIN_DEFAULT_DURATION;
List customer =
service.getCustomerRepo().findByName(name + " " + type + " Base");
TariffEvaluationWrapper wrapper =
new TariffEvaluationWrapper(type, customer.get(0));
TariffEvaluator te = new TariffEvaluator(wrapper);
te.initializeInconvenienceFactors(OfficeComplexConstants.TOU_FACTOR,
OfficeComplexConstants.TIERED_RATE_FACTOR,
OfficeComplexConstants.VARIABLE_PRICING_FACTOR,
OfficeComplexConstants.INTERRUPTIBILITY_FACTOR);
te.withInconvenienceWeight(weight)
.withInertia(Double.parseDouble(conf
.getProperty(type + "Inertia")))
.withPreferredContractDuration(weeks
* OfficeComplexConstants.DAYS_OF_WEEK)
.withRationality(Double.parseDouble(conf
.getProperty(type + "Rationality")))
.withTariffEvalDepth(OfficeComplexConstants.TARIFF_COUNT)
.withTariffSwitchFactor(OfficeComplexConstants.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(OfficeComplexConstants.TOU_FACTOR,
OfficeComplexConstants.TIERED_RATE_FACTOR,
OfficeComplexConstants.VARIABLE_PRICING_FACTOR,
OfficeComplexConstants.INTERRUPTIBILITY_FACTOR);
te.withInconvenienceWeight(weight)
.withInertia(Double.parseDouble(conf
.getProperty(type + "Inertia")))
.withPreferredContractDuration(weeks
* OfficeComplexConstants.DAYS_OF_WEEK)
.withRationality(Double.parseDouble(conf
.getProperty(type + "Rationality")))
.withTariffEvalDepth(OfficeComplexConstants.TARIFF_COUNT)
.withTariffSwitchFactor(OfficeComplexConstants.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());
}
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 office complex offices for each quarter of the hour.
*
* @param type
* @return
*/
void fillAggWeeklyLoad (String type)
{
if (type.equals("NS")) {
for (int i = 0; i < OfficeComplexConstants.DAYS_OF_WEEK
* (OfficeComplexConstants.WEEKS_OF_COMPETITION + OfficeComplexConstants.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 {
for (int i = 0; i < OfficeComplexConstants.DAYS_OF_WEEK
* (OfficeComplexConstants.WEEKS_OF_COMPETITION + OfficeComplexConstants.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[OfficeComplexConstants.HOURS_OF_DAY];
double[] nonDominant = new double[OfficeComplexConstants.HOURS_OF_DAY];
Vector houses = getOffices(type);
for (int i = 0; i < houses.size(); i++) {
for (int j = 0; j < OfficeComplexConstants.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 {
dominantLoadSS = dominant;
nonDominantLoadSS = nonDominant;
}
}
/**
* This function is used in order to update the daily aggregated Load in case
* there are changes in the weather sensitive loads of the office complex's
* offices.
*
* @param type
* @return
*/
void updateAggDailyWeatherSensitiveLoad (String type, int day)
{
int dayTemp =
day
% (OfficeComplexConstants.DAYS_OF_BOOTSTRAP + OfficeComplexConstants.DAYS_OF_COMPETITION);
if (type.equals("NS")) {
aggDailyWeatherSensitiveLoadNS
.set(dayTemp, fillAggDailyWeatherSensitiveLoad(dayTemp, type));
aggDailyWeatherSensitiveLoadInHoursNS
.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 office complex's offices for each quarter of the hour.
*
* @param day
* @param type
* @return
*/
Vector fillAggDailyBaseLoad (int day, String type)
{
Vector offices = new Vector();
if (type.equals("NS")) {
offices = notShiftingOffices;
}
else {
offices = smartShiftingOffices;
}
Vector v = new Vector(OfficeComplexConstants.QUARTERS_OF_DAY);
long sum = 0;
for (int i = 0; i < OfficeComplexConstants.QUARTERS_OF_DAY; i++) {
sum = 0;
for (Office office: offices) {
sum = sum + office.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 office complex's offices for each quarter of the hour.
*
* @param day
* @param type
* @return
*/
Vector fillAggDailyControllableLoad (int day, String type)
{
Vector offices = new Vector();
if (type.equals("NS")) {
offices = notShiftingOffices;
}
else {
offices = smartShiftingOffices;
}
Vector v = new Vector(OfficeComplexConstants.QUARTERS_OF_DAY);
long sum = 0;
for (int i = 0; i < OfficeComplexConstants.QUARTERS_OF_DAY; i++) {
sum = 0;
for (Office office: offices) {
sum = sum + office.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 office complex's offices for each quarter of the
* hour.
*
* @param day
* @param type
* @return
*/
Vector fillAggDailyWeatherSensitiveLoad (int day, String type)
{
Vector offices = new Vector();
if (type.equals("NS")) {
offices = notShiftingOffices;
}
else {
offices = smartShiftingOffices;
}
Vector v = new Vector(OfficeComplexConstants.QUARTERS_OF_DAY);
long sum = 0;
for (int i = 0; i < OfficeComplexConstants.QUARTERS_OF_DAY; i++) {
sum = 0;
for (Office office: offices) {
sum = sum + office.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 office complex's offices for each quarter of the
* hour.
*
* @param day
* @param type
* @return
*/
Vector fillAggDailyDominantLoad (int day, String type)
{
Vector offices = new Vector();
if (type.equals("NS")) {
offices = notShiftingOffices;
}
else {
offices = smartShiftingOffices;
}
Vector v = new Vector(OfficeComplexConstants.QUARTERS_OF_DAY);
long sum = 0;
for (int i = 0; i < OfficeComplexConstants.QUARTERS_OF_DAY; i++) {
sum = 0;
for (Office office: offices) {
sum = sum + office.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 office complex's offices for each quarter of the
* hour.
*
* @param day
* @param type
* @return
*/
Vector fillAggDailyNonDominantLoad (int day, String type)
{
Vector offices = new Vector();
if (type.equals("NS")) {
offices = notShiftingOffices;
}
else {
offices = smartShiftingOffices;
}
Vector v = new Vector(OfficeComplexConstants.QUARTERS_OF_DAY);
long sum = 0;
for (int i = 0; i < OfficeComplexConstants.QUARTERS_OF_DAY; i++) {
sum = 0;
for (Office office: offices) {
sum = sum + office.weeklyNonDominantLoad.get(day).get(i);
}
v.add(sum);
}
return v;
}
/**
* This function is used in order to fill the daily Base Load of the office
* for each hour for a certain type of offices.
*
* @param day
* @param type
* @return
*/
Vector fillAggDailyBaseLoadInHours (int day, String type)
{
Vector daily = new Vector();
long sum = 0;
if (type.equals("NS")) {
for (int i = 0; i < OfficeComplexConstants.HOURS_OF_DAY; i++) {
sum = 0;
sum =
aggDailyBaseLoadNS.get(day)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR)
+ aggDailyBaseLoadNS.get(day)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR + 1)
+ aggDailyBaseLoadNS.get(day)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR + 2)
+ aggDailyBaseLoadNS.get(day)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR + 3);
daily.add(sum);
}
}
else {
for (int i = 0; i < OfficeComplexConstants.HOURS_OF_DAY; i++) {
sum = 0;
sum =
aggDailyBaseLoadSS.get(day)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR)
+ aggDailyBaseLoadSS.get(day)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR + 1)
+ aggDailyBaseLoadSS.get(day)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR + 2)
+ aggDailyBaseLoadSS.get(day)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR + 3);
daily.add(sum);
}
}
return daily;
}
/**
* This function is used in order to fill the daily Controllable Load of the
* office for each hour for a certain type of offices.
*
* @param day
* @param type
* @return
*/
Vector fillAggDailyControllableLoadInHours (int day, String type)
{
Vector daily = new Vector();
long sum = 0;
if (type.equals("NS")) {
for (int i = 0; i < OfficeComplexConstants.HOURS_OF_DAY; i++) {
sum = 0;
sum =
aggDailyControllableLoadNS.get(day)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR)
+ aggDailyControllableLoadNS.get(day)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR + 1)
+ aggDailyControllableLoadNS.get(day)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR + 2)
+ aggDailyControllableLoadNS.get(day)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR + 3);
daily.add(sum);
}
}
else {
for (int i = 0; i < OfficeComplexConstants.HOURS_OF_DAY; i++) {
sum = 0;
sum =
aggDailyControllableLoadSS.get(day)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR)
+ aggDailyControllableLoadSS.get(day)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR + 1)
+ aggDailyControllableLoadSS.get(day)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR + 2)
+ aggDailyControllableLoadSS.get(day)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR + 3);
daily.add(sum);
}
}
return daily;
}
/**
* This function is used in order to fill the daily weather sensitive Load of
* the office for each hour for a certain type of offices.
*
* @param day
* @param type
* @return
*/
Vector fillAggDailyWeatherSensitiveLoadInHours (int day, String type)
{
int dayTemp =
day
% (OfficeComplexConstants.DAYS_OF_BOOTSTRAP + OfficeComplexConstants.DAYS_OF_COMPETITION);
Vector daily = new Vector();
long sum = 0;
if (type.equals("NS")) {
for (int i = 0; i < OfficeComplexConstants.HOURS_OF_DAY; i++) {
sum = 0;
sum =
aggDailyWeatherSensitiveLoadNS.get(dayTemp)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR)
+ aggDailyWeatherSensitiveLoadNS.get(dayTemp)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR + 1)
+ aggDailyWeatherSensitiveLoadNS.get(dayTemp)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR + 2)
+ aggDailyWeatherSensitiveLoadNS.get(dayTemp)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR + 3);
daily.add(sum);
}
}
else {
for (int i = 0; i < OfficeComplexConstants.HOURS_OF_DAY; i++) {
sum = 0;
sum =
aggDailyWeatherSensitiveLoadSS.get(dayTemp)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR)
+ aggDailyWeatherSensitiveLoadSS.get(dayTemp)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR + 1)
+ aggDailyWeatherSensitiveLoadSS.get(dayTemp)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR + 2)
+ aggDailyWeatherSensitiveLoadSS.get(dayTemp)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR + 3);
daily.add(sum);
}
}
return daily;
}
/**
* This function is used in order to fill the daily dominant Load of
* the office for each hour for a certain type of offices.
*
* @param day
* @param type
* @return
*/
Vector fillAggDailyDominantLoadInHours (int day, String type)
{
int dayTemp =
day
% (OfficeComplexConstants.DAYS_OF_BOOTSTRAP + OfficeComplexConstants.DAYS_OF_COMPETITION);
Vector daily = new Vector();
long sum = 0;
if (type.equals("NS")) {
for (int i = 0; i < OfficeComplexConstants.HOURS_OF_DAY; i++) {
sum = 0;
sum =
aggDailyDominantLoadNS.get(dayTemp)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR)
+ aggDailyDominantLoadNS.get(dayTemp)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR + 1)
+ aggDailyDominantLoadNS.get(dayTemp)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR + 2)
+ aggDailyDominantLoadNS.get(dayTemp)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR + 3);
daily.add(sum);
}
}
else {
for (int i = 0; i < OfficeComplexConstants.HOURS_OF_DAY; i++) {
sum = 0;
sum =
aggDailyDominantLoadSS.get(dayTemp)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR)
+ aggDailyDominantLoadSS.get(dayTemp)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR + 1)
+ aggDailyDominantLoadSS.get(dayTemp)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR + 2)
+ aggDailyDominantLoadSS.get(dayTemp)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR + 3);
daily.add(sum);
}
}
return daily;
}
/**
* This function is used in order to fill the daily dominant Load of
* the office for each hour for a certain type of offices.
*
* @param day
* @param type
* @return
*/
Vector fillAggDailyNonDominantLoadInHours (int day, String type)
{
int dayTemp =
day
% (OfficeComplexConstants.DAYS_OF_BOOTSTRAP + OfficeComplexConstants.DAYS_OF_COMPETITION);
Vector daily = new Vector();
long sum = 0;
if (type.equals("NS")) {
for (int i = 0; i < OfficeComplexConstants.HOURS_OF_DAY; i++) {
sum = 0;
sum =
aggDailyNonDominantLoadNS.get(dayTemp)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR)
+ aggDailyNonDominantLoadNS.get(dayTemp)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR + 1)
+ aggDailyNonDominantLoadNS.get(dayTemp)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR + 2)
+ aggDailyNonDominantLoadNS.get(dayTemp)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR + 3);
daily.add(sum);
}
}
else {
for (int i = 0; i < OfficeComplexConstants.HOURS_OF_DAY; i++) {
sum = 0;
sum =
aggDailyNonDominantLoadSS.get(dayTemp)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR)
+ aggDailyNonDominantLoadSS.get(dayTemp)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR + 1)
+ aggDailyNonDominantLoadSS.get(dayTemp)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR + 2)
+ aggDailyNonDominantLoadSS.get(dayTemp)
.get(i * OfficeComplexConstants.QUARTERS_OF_HOUR + 3);
daily.add(sum);
}
}
return daily;
}
// =====CONSUMPTION FUNCTIONS===== //
//@Override
public void consumePower ()
{
Timeslot ts = service.getTimeslotRepo().currentTimeslot();
int serial;
for (CustomerInfo customer: getCustomerInfos()) {
List subscriptions =
service.getTariffSubscriptionRepo()
.findActiveSubscriptionsForCustomer(customer);
String temp = officeMapping.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 OfficeComplex Household Consumer.
*/
double
getConsumptionByTimeslot (int serial, String type, boolean controllable)
{
int day = (int) (serial / OfficeComplexConstants.HOURS_OF_DAY);
int hour = (int) (serial % OfficeComplexConstants.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 / OfficeComplexConstants.THOUSAND;
}
// =====GETTER FUNCTIONS===== //
/** This function returns the inertia Map variable of the village. */
public Map getOfficeMapping ()
{
return officeMapping;
}
/** This function returns the period Map variable of the village. */
public Map 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 offices.
*/
long getBaseConsumptions (int day, int hour, String type)
{
long summaryBase = 0;
int dayTemp =
day
% (OfficeComplexConstants.DAYS_OF_BOOTSTRAP + OfficeComplexConstants.DAYS_OF_COMPETITION);
if (type.equals("NS")) {
summaryBase = aggDailyBaseLoadInHoursNS.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 offices.
*/
long getControllableConsumptions (int day, int hour, String type)
{
long summaryControllable = 0;
int dayTemp =
day
% (OfficeComplexConstants.DAYS_OF_BOOTSTRAP + OfficeComplexConstants.DAYS_OF_COMPETITION);
if (type.equals("NS")) {
summaryControllable =
aggDailyControllableLoadInHoursNS.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 office.
*/
long getWeatherSensitiveConsumptions (int day, int hour, String type)
{
long summaryWeatherSensitive = 0;
int dayTemp =
day
% (OfficeComplexConstants.DAYS_OF_BOOTSTRAP + OfficeComplexConstants.DAYS_OF_COMPETITION);
if (type.equals("NS")) {
summaryWeatherSensitive =
aggDailyWeatherSensitiveLoadInHoursNS.get(dayTemp).get(hour);
}
else {
summaryWeatherSensitive =
aggDailyWeatherSensitiveLoadInHoursSS.get(dayTemp).get(hour);
}
log.debug("WeatherSensitive Load for " + type + ":"
+ summaryWeatherSensitive);
return summaryWeatherSensitive;
}
/**
* 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
% (OfficeComplexConstants.DAYS_OF_BOOTSTRAP + OfficeComplexConstants.DAYS_OF_COMPETITION);
if (type.equals("NS")) {
summaryNonDominant =
aggDailyNonDominantLoadInHoursNS.get(dayTemp).get(hour);
}
else {
summaryNonDominant =
aggDailyNonDominantLoadInHoursSS.get(dayTemp).get(hour);
}
log.debug("NonDominant Load for " + type + ":" + summaryNonDominant);
return summaryNonDominant;
}
/**
* This function returns the dominant Consumption Load for a certain type of
* houses
*/
public double[] getDominantLoad (String type)
{
if (type.equals("NS")) {
return dominantLoadNS;
}
else {
return dominantLoadSS;
}
}
/**
* This function returns the non dominant Consumption Load for a certain type
* of houses
*/
public double[] getNonDominantLoad (String type)
{
if (type.equals("NS")) {
return nonDominantLoadNS;
}
else {
return nonDominantLoadSS;
}
}
/**
* 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
% (OfficeComplexConstants.DAYS_OF_BOOTSTRAP + OfficeComplexConstants.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 {
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 offices.
*/
Vector getControllableConsumptions (int day, String type)
{
Vector controllableVector = new Vector();
int dayTemp =
day
% (OfficeComplexConstants.DAYS_OF_BOOTSTRAP + OfficeComplexConstants.DAYS_OF_COMPETITION);
if (type.equals("NS")) {
controllableVector = aggDailyControllableLoadInHoursNS.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 offices.
*/
Vector getWeatherSensitiveConsumptions (int day, String type)
{
Vector weatherSensitiveVector = new Vector();
int dayTemp =
day
% (OfficeComplexConstants.DAYS_OF_BOOTSTRAP + OfficeComplexConstants.DAYS_OF_COMPETITION);
if (type.equals("NS")) {
weatherSensitiveVector =
aggDailyWeatherSensitiveLoadInHoursNS.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 getNonDominantConsumptions (int day, String type)
{
Vector nonDominantVector = new Vector();
int dayTemp =
day
% (OfficeComplexConstants.DAYS_OF_BOOTSTRAP + OfficeComplexConstants.DAYS_OF_COMPETITION);
if (type.equals("NS")) {
nonDominantVector = aggDailyNonDominantLoadInHoursNS.get(dayTemp);
}
else {
nonDominantVector = aggDailyNonDominantLoadInHoursSS.get(dayTemp);
}
return nonDominantVector;
}
double[] getNonDominantUsage (int day, String type)
{
double[] nonDominantUsage = new double[OfficeComplexConstants.HOURS_OF_DAY];
for (int hour = 0; hour < OfficeComplexConstants.HOURS_OF_DAY; hour++) {
if (hour == OfficeComplexConstants.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;
}
/**
* This function returns a vector with all the offices that are present in
* this office complex.
*/
public Vector getOffices ()
{
Vector offices = new Vector();
for (Office office: notShiftingOffices)
offices.add(office);
for (Office office: smartShiftingOffices)
offices.add(office);
return offices;
}
/**
* This function returns a vector with all the offices of a certain type that
* are present in this office complex.
*/
public Vector getOffices (String type)
{
Vector offices = new Vector();
if (type.equals("NS")) {
for (Office office: notShiftingOffices) {
offices.add(office);
}
}
else {
for (Office office: smartShiftingOffices) {
offices.add(office);
}
}
return offices;
}
// =====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 newTariffs)
{
for (CustomerInfo customer: getCustomerInfos()) {
log.info("Customer " + customer.toString()
+ " is evaluating tariffs for timeslot "
+ service.getTimeslotRepo().currentSerialNumber());
TariffEvaluator evaluator = tariffEvaluators.get(customer);
evaluator.evaluateTariffs();
}
}
// =====SHIFTING FUNCTIONS===== //
/**
* This is the function that takes every office in the office complex 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
% (OfficeComplexConstants.DAYS_OF_BOOTSTRAP + OfficeComplexConstants.DAYS_OF_COMPETITION);
Vector offices = new Vector();
if (type.equals("NS")) {
offices = notShiftingOffices;
}
else {
offices = smartShiftingOffices;
}
for (Office office: offices) {
double[] temp =
office.dailyShifting(tariff, newControllableLoad, tariffEvalHelper,
dayTemp, nextStartOfDay());
log.debug("New Dominant Load for house " + office.toString()
+ " for Tariff " + tariff.toString() + ": "
+ Arrays.toString(temp));
for (int j = 0; j < OfficeComplexConstants.HOURS_OF_DAY; j++)
newControllableLoad[j] += temp[j];
}
log.debug("New Overall Load of OfficeComplex " + toString() + " type "
+ type + " for Tariff " + tariff.toString() + ": "
+ Arrays.toString(newControllableLoad));
return newControllableLoad;
}
// =====VECTOR CREATION===== //
/**
* This function is creating a certain number of random days that will be
* public vacation for the people living in the environment.
*
* @param days
* @param gen
* @return
*/
Vector createPublicVacationVector (int days)
{
// Creating auxiliary variables
Vector v = new Vector(days);
for (int i = 0; i < days; i++) {
int x =
gen.nextInt(OfficeComplexConstants.DAYS_OF_COMPETITION
+ OfficeComplexConstants.DAYS_OF_BOOTSTRAP);
ListIterator 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 / OfficeComplexConstants.HOURS_OF_DAY);
int hour = ts.getStartTime().getHourOfDay();
Instant now = ts.getStartInstant();
weatherCheck(day, hour, now);
// checkRevokedSubscriptions();
checkCurtailment(serial, day, hour);
consumePower();
// for (Office office: getOffices())
// office.test();
if (hour == 23) {
for (String type: numberOfOffices.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
% (OfficeComplexConstants.DAYS_OF_BOOTSTRAP + OfficeComplexConstants.DAYS_OF_COMPETITION);
WeatherReport wr =
service.getWeatherReportRepo().currentWeatherReport();
if (wr != null) {
double temperature = wr.getTemperature();
// log.debug("Temperature: " + temperature);
Vector offices = getOffices();
for (Office office: offices) {
office.weatherCheck(dayTemp, hour, now, temperature);
}
for (String type: numberOfOffices.keySet()) {
updateAggDailyWeatherSensitiveLoad(type, day);
if (dayTemp + 1 < OfficeComplexConstants.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 next timeslot.
*/
void checkCurtailment (int serial, int day, int hour)
{
int nextSerial =
service.getTimeslotRepo().currentSerialNumber() + 1;
int nextDay = (int) (nextSerial / OfficeComplexConstants.HOURS_OF_DAY);
int nextHour = (int) (nextSerial % OfficeComplexConstants.HOURS_OF_DAY);
int dayTemp =
day
% (OfficeComplexConstants.DAYS_OF_BOOTSTRAP + OfficeComplexConstants.DAYS_OF_COMPETITION);
int nextDayTemp =
nextDay
% (OfficeComplexConstants.DAYS_OF_BOOTSTRAP + OfficeComplexConstants.DAYS_OF_COMPETITION);
for (CustomerInfo customer: getCustomerInfos()) {
if (customer.getPowerType() == PowerType.INTERRUPTIBLE_CONSUMPTION) {
List subs =
service.getTariffSubscriptionRepo()
.findActiveSubscriptionsForCustomer(customer);
long curt =
(long) subs.get(0).getCurtailment() * OfficeComplexConstants.THOUSAND;
log.debug(this.toString() + " Subscription " + subs.get(0).toString()
+ " Curtailment " + curt);
if (curt > 0) {
String temp = officeMapping.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 / OfficeComplexConstants.HOURS_OF_DAY) + 1;
int dayTemp =
day % (OfficeComplexConstants.DAYS_OF_BOOTSTRAP + OfficeComplexConstants.DAYS_OF_COMPETITION);
double[] nonDominantUsage = getNonDominantUsage(dayTemp, type);
Vector controllableVector = new Vector();
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 < OfficeComplexConstants.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());
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(OfficeComplexConstants.DAYS_OF_BOOTSTRAP
+ OfficeComplexConstants.DAYS_OF_COMPETITION);
}
@Override
public CustomerInfo getCustomerInfo ()
{
return customerInfo;
}
public String getType ()
{
return type;
}
public int getPopulation ()
{
return getOffices(type).size();
}
@Override
public CapacityProfile getCapacityProfile (Tariff tariff)
{
double[] result = new double[OfficeComplexConstants.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] /= (OfficeComplexConstants.THOUSAND * getPopulation());
log.info("Usage:" + Arrays.toString(result));
return new CapacityProfile(result, nextStartOfDay());
}
@Override
public double getBrokerSwitchFactor (boolean isSuperseding)
{
double result = OfficeComplexConstants.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();
}
@Override
public double getShiftingInconvenienceFactor(Tariff tariff) {
// TODO Auto-generated method stub
return OfficeComplexConstants.TOU_FACTOR;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy