-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
20 changed files
with
537,365 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
#!/usr/bin/perl | ||
#================================================================================================================= | ||
# This file is part of Appliance_Lighting_Generator. This is a set of scripts used to generate sub-hourly annual | ||
# occupancy, and appliance and lighting demand profiles for residential buildings. The subroutines expressed in | ||
# this package are adopted from the CREST model developed and distributed by the Centre for Renewable Energy | ||
# Systems Technology at the University of Loughborough. The subroutines contained in this file are based on the | ||
# version of CREST described by: | ||
# | ||
# Richardson, I., Thomson, M., Infield, D., & Clifford, C. (2010). Domestic electricity use: A high-resolution | ||
# energy demand model. Energy and buildings, 42(10), 1878-1887. | ||
# | ||
# For latest developments of the CREST model please see https://www.lboro.ac.uk/research/crest/demand-model/ | ||
# | ||
# This software is a MODIFICATION and ADAPTATION of the CREST model licensed under the GNU General Public License | ||
# version 3. This modified software is documented in the publication: | ||
# | ||
# Wills, A. D., Beausoleil-Morrison, I., & Ugursal, V. I. (2018). Adaptation and validation of an existing | ||
# bottom-up model for simulating temporal and inter-dwelling variations of residential appliance and lighting | ||
# demands. Journal of Building Performance Simulation, 11(3), 350-368. | ||
# | ||
#=========================================================== | ||
# Appliance_Lighting_Generator Copyright (C) 2022 National Research Council Canada | ||
# | ||
# Appliance_Lighting_Generator is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU General Public License as published by | ||
# the Free Software Foundation, either version 3 of the License, or | ||
# (at your option) any later version. | ||
# | ||
# Appliance_Lighting_Generator is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License | ||
# along with Appliance_Lighting_Generator. If not, see <https://www.gnu.org/licenses/>. | ||
#================================================================================================================= | ||
# -------------------------------------------------------------------- | ||
# Declare modules which are used | ||
# -------------------------------------------------------------------- | ||
# CPAN Modules | ||
use warnings; | ||
use strict; | ||
use XML::Simple; # to parse the XML results files | ||
use Data::Dumper; | ||
|
||
# Local Modules | ||
use lib qw(modules); | ||
use OccupancyProfiles; | ||
|
||
# INPUTS | ||
my $sInputFile; # Path and filename of input | ||
my $ActStatpth = 'data/activity_stats.csv'; # Appliance activity probabilities | ||
my $ApplianceData = 'data/appliance_database.xml'; | ||
|
||
# INTERMEDIATES | ||
my @TotalOther; | ||
my @TotalAL; | ||
my $Activity = &ActiveStatParser($ActStatpth); | ||
my $MeanActOcc=0; | ||
|
||
# OUTPUTS | ||
my $sOccFile = "Occupancy_Profile.csv"; | ||
my $sLightFile = "Aggregate_Lighting_Demand.csv"; | ||
my $sAppFile = "Aggregate_Appliance_Demand.csv"; | ||
my $sTotal = "Aggregate_App_Lighting_Demand.csv"; | ||
|
||
# -------------------------------------------------------------------- | ||
# Read the command line input arguments | ||
# -------------------------------------------------------------------- | ||
if (@ARGV > 1) {die "Only 1 argument required\n";}; # check for proper argument count | ||
$sInputFile = shift @ARGV; | ||
|
||
# Parse the input | ||
my $hInput = XMLin($sInputFile); | ||
# Parse the appliance database | ||
my $hApplianceData = XMLin($ApplianceData); | ||
|
||
print "\n Appliance_Lighting_Generator.pl Copyright (C) 2019\n\n"; | ||
print " This program comes with ABSOLUTELY NO WARRANTY\n"; | ||
print " This is free software, and you are welcome to redistribute it\n"; | ||
print " under certain conditions\n\n"; | ||
|
||
# -------------------------------------------------------------------- | ||
# Generate the occupancy profile | ||
# -------------------------------------------------------------------- | ||
my $ref_Occ = &getNewOccupancyProfile($hInput->{'inputs'}->{'num_of_occ'}, $hInput->{'sim_parameters'}->{'start_day'}); | ||
my @Occ = @$ref_Occ; | ||
open(my $fid, '>', $sOccFile) or die "Could not create output $sOccFile: $!\n"; | ||
print $fid "total_occ,$hInput->{'inputs'}->{'num_of_occ'}\n"; | ||
print $fid "start_day,$hInput->{'sim_parameters'}->{'start_day'}\n"; | ||
print $fid "day_of_year,num_active_occ\n"; | ||
my $iHour=1; | ||
foreach my $fActive (@Occ) { | ||
print $fid "$iHour,$fActive\n"; | ||
$iHour+= (1.0/1440.0); | ||
}; | ||
close $fid; | ||
# Determine the mean active occupancy | ||
foreach my $Step (@Occ) { | ||
if($Step>0) {$MeanActOcc++}; | ||
}; | ||
$MeanActOcc=$MeanActOcc/($#Occ+1); # Fraction of time occupants are active | ||
print " Generating active occupant profile complete\n"; | ||
print " - Starting lighting profile\n"; | ||
# -------------------------------------------------------------------- | ||
# Generate the lighting profile | ||
# -------------------------------------------------------------------- | ||
my @Bulbs=(); # Initialize array of household lightbulb wattages | ||
foreach my $val (@{$hInput->{'inputs'}->{'lighting_fixtures'}->{'fixture'}}) { | ||
push(@Bulbs,$val->{'power'}); | ||
}; | ||
my $ref_Light = getLightingLoad($hInput->{'inputs'}->{'irr_path'},\@Bulbs,$hInput->{'sim_parameters'}->{'lighting_calibration'},$hInput->{'sim_parameters'}->{'lightning_threshold'}->{'mean'},$hInput->{'sim_parameters'}->{'lightning_threshold'}->{'std_dev'},\@Occ); | ||
my @fLight = @$ref_Light; | ||
open($fid, '>', $sLightFile) or die "Could not create output $sLightFile: $!\n"; | ||
print $fid "day_of_year,agg_lighting_W\n"; | ||
$iHour=1; | ||
foreach my $fActive (@fLight) { | ||
my $fActiveWatts = $fActive*1000.0; | ||
print $fid "$iHour,$fActiveWatts\n"; | ||
$iHour+= (1.0/1440.0); | ||
}; | ||
close $fid; | ||
print " - Lighting profile complete\n"; | ||
print " - Starting appliance profile\n"; | ||
# -------------------------------------------------------------------- | ||
# Generate the appliance profile | ||
# -------------------------------------------------------------------- | ||
# Initialize the appliance demand with unallocated baseload | ||
my $ThisBase = $hInput->{'sim_parameters'}->{'base_load'}; # Constant baseload power [W] | ||
if($ThisBase>0) { | ||
$ThisBase = getRandomBaseload($ThisBase,$hInput->{'sim_parameters'}->{'base_dev'}); | ||
}; | ||
if($ThisBase<0) {$ThisBase=0}; | ||
@TotalOther = ($ThisBase) x 525600; | ||
|
||
# Cold appliances first | ||
if (exists($hInput->{'inputs'}->{'cold_appliances'})) { | ||
my @hColdApps=(); | ||
|
||
if(ref($hInput->{'inputs'}->{'cold_appliances'}->{'appliance'}) eq 'ARRAY') { | ||
push(@hColdApps,@{$hInput->{'inputs'}->{'cold_appliances'}->{'appliance'}}); | ||
} else { | ||
push(@hColdApps,$hInput->{'inputs'}->{'cold_appliances'}->{'appliance'}); | ||
}; | ||
foreach my $ref (@hColdApps) { | ||
my $Cold_Ref = &getColdApplianceLoad($ref->{'uec'},$ref->{'base_cycles'},$ref->{'mean_cycle_L'},$ref->{'restart_delay'}); | ||
my @ThisCold = @$Cold_Ref; | ||
|
||
# Update the total appliance power draw [W] | ||
for (my $k=0; $k<=$#ThisCold;$k++) { | ||
$TotalOther[$k]=$TotalOther[$k]+$ThisCold[$k]; | ||
}; | ||
}; | ||
}; | ||
# All other appliances | ||
my @ApplianceStock = @{$hInput->{'inputs'}->{'general_appliances'}->{'appliance'}}; | ||
foreach my $item (@ApplianceStock) { # For each appliance in the dwelling | ||
if (not exists($hApplianceData->{$item})) {die "Appliance $item is not defined in $ApplianceData\n";} | ||
my $App = $hApplianceData->{$item}; | ||
my $ThisApp_ref = &getApplianceProfile(\@Occ,$MeanActOcc,$item,$App,$Activity,$hInput->{'sim_parameters'}->{'appliance_calibration'},$hInput->{'sim_parameters'}->{'start_day'}); | ||
my @ThisApp = @$ThisApp_ref; | ||
|
||
# Update the TotalOther array [W] | ||
for(my $k=0;$k<=$#TotalOther;$k++) { | ||
$TotalOther[$k]=$TotalOther[$k]+$ThisApp[$k]; | ||
}; | ||
}; | ||
print " - Appliance profile complete\n"; | ||
open($fid, '>', $sAppFile) or die "Could not create output $sAppFile: $!\n"; | ||
print $fid "day_of_year,agg_appliance_W\n"; | ||
$iHour=1; | ||
foreach my $fActive (@TotalOther) { | ||
print $fid "$iHour,$fActive\n"; | ||
$iHour+= (1.0/1440.0); | ||
}; | ||
close $fid; | ||
# -------------------------------------------------------------------- | ||
# Get aggregated appliance and lighting loads | ||
# -------------------------------------------------------------------- | ||
print " - Printing out aggregate appliance and lighting loads\n"; | ||
foreach (my $i=0;$i<=$#fLight;$i++) { | ||
my $fSum = $TotalOther[$i]+($fLight[$i]*1000.0); | ||
push(@TotalAL,$fSum); | ||
}; | ||
open($fid, '>', $sTotal) or die "Could not create output $sTotal: $!\n"; | ||
print $fid "day_of_year,agg_appliance_light_W\n"; | ||
$iHour=1; | ||
foreach my $fActive (@TotalAL) { | ||
print $fid "$iHour,$fActive\n"; | ||
$iHour+= (1.0/1440.0); | ||
}; | ||
close $fid; | ||
print "\n -- Process complete --\n"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,84 @@ | ||
# appliance-lighting-load-generator | ||
# Occupancy and Appliance and Lighting Profile Generator | ||
|
||
Sub-hourly residential appliance and lighting load generator — Générateur de charge subhoraire d'appareils résidentiels et d'éclairage | ||
|
||
This set of scripts and subroutines are derived works of the CREST model for generating residential occupancy, and appliance and lighting profiles. The CREST tools and models may be accessed for free [here](https://www.lboro.ac.uk/research/crest/demand-model/) and are distributed under the GNU General Public License version 3. | ||
|
||
This derived work of the CREST model is for modelling the Canadian residential sector as described in "Adaptation and validation of an existing bottom-up model for simulating temporal and inter-dwelling variations of residential appliance and lighting demands" by A.D Wills, I. Beausoleil-Morrison, and V.I. Ugursal, *Journal of Building Performance Simulation*, Volume 11, 2018 - Issue 3 which may be accessed [here](https://www.tandfonline.com/doi/full/10.1080/19401493.2017.1369570). | ||
|
||
The modifications implemented in this adaptation of the tool are as follows: | ||
|
||
- Updated the transition probability matrices and activity probabilites based on the time of use surveys from the Canadian 2010 General Social Survey; | ||
- Updated appliance electrical characteristics to reflect North American appliances; | ||
- Added unallocated constant baseload; | ||
- Seasonal variation of dryer usage based on data from the 2011 Survey of Household Energy Use (SHEU). | ||
|
||
## License | ||
Unless otherwise noted, the source code for this project is protected by the Crown copyright of the Government of Canada and distributed under the [GPLv3 license](License.md). | ||
|
||
The "Canada" wordmark and related graphic elements relating to this distribution are protected under trademark and copyright laws. No permission is granted for their use outside the parameters of the Government of Canada's Branding Coordination Program. For more information on this subject, please consult the [Branding Requirements](https://www.canada.ca/en/secretariat-conseil-tresor/sujets/communications-gouvernementales/exigences-image-brand.html). | ||
|
||
## Contributing | ||
When contributing, post comments and discuss changes you wish to make via Issues. | ||
|
||
Feel free to propose changes by creating Pull Requests. If you don't have write access, editing a file will create a Fork of this project for you to save your proposed changes to. Submitting a change to a file will write it to a new Branch in your Fork, so you can send a Pull Request. | ||
|
||
If this is your first time contributing on GitHub, don't worry! Let us know if you have any questions. | ||
|
||
## Set-up | ||
|
||
### Windows | ||
In order to run the profile generator Perl will need to be installed on Windows. Please search for and select a Windows Perl interpreter online. | ||
### Linux | ||
Perl is typically bundled with Linux distributions. If not, install Perl using the method for your distribution. | ||
|
||
### Dependancies | ||
Before running the profile generator for the first time the PERL module dependencies need to be installed. This can be done by running the following from the command line in the project folder: | ||
```sh | ||
$ perl install_Dependancies.pl | ||
``` | ||
|
||
## Usage | ||
Annual single dwelling occupancy and lighting and appliance profiles, at a 1-minute timestep, are generated by issuing the following command: | ||
```sh | ||
$ perl Appliance_Lighting_Generator.pl <input>.xml | ||
``` | ||
|
||
This will generate four output files (annual 1-minute timestep): | ||
- Occupancy_Profile.csv; | ||
- Aggregate_Lighting_Demand.csv; | ||
- Aggregate_Appliance_Demand.csv; | ||
- Aggregate_App_Lighting_Demand.csv. | ||
|
||
The occupancy profile indicates for each timestep the number of active occupants in the dwelling. This profile is also used as an input into the appliance and lighting profile generator. The other three profiles are self explanatory, and provides the real power demands. The appliance, lighting, and aggregated appliance and lighting profiles are in Watts. | ||
|
||
## Model Input Files | ||
Example input files are provided. The input is in XML format, and divided into two major sections: | ||
1. sim_parameters; | ||
2. inputs. | ||
### Sim Parameters | ||
All items in **sim_parameters** shown in the example input files are required for generating profiles. | ||
- The lighting and appliance calibration scalars correspond to $C_{light,calibrate}$ and $C_{appl,calibrate}$ as described by [Wills et al. (2018)](https://www.tandfonline.com/doi/full/10.1080/19401493.2017.1369570). They used 0.00808657549621997 and 2.52628443733964, respectively, for Ontario single-detached dwellings. | ||
- The lighting threshold is the level [W/m2] in which natural light levels are low enough such that artificial lighting may be required. See [Richardson et al. (2009)](https://www.sciencedirect.com/science/article/pii/S0378778809000449) for details. A standard deviation for this threshold is also required to create variance across dwellings. Richardson et al. (2009) used a mean threshold of 60 W/m2 with a standard deviation of 10 W/m2. | ||
- The baseload inputs, in Watts, represents the unallocated baseload demands of the dwelling. A mean and standard deviation value is also required for this input. Wills et al. (2018) used 250 W with a standard deviation of 70 W for Ontario single-detached homes. | ||
|
||
### Inputs | ||
The **inputs** section is divided into several subsections: | ||
1. **num_of_occ** is the number of dwelling occupants [1-5]; | ||
2. **irr_path** is the relative path the to global horizontal irradiance data [W/m2]. The data must be tab or space delimited, with the irradiance data in the *second* column. The data must be for a full year at a 1-minute timestep. The sample climates provided in the climate folder were generated using hourly CWEC weather data processed using the radiation algorithms in TRNSYS. | ||
3. The **lighting_fixtures** section is populated entries for each individual fixture in the dwelling. Each entry includes the fixture's rated power in Watts, as well as a description. The description is not used by the profile generator, but is included for input documentation. | ||
4. The **cold_appliances** input includes dwelling fridges and freezers. The following items must be included for each entry: | ||
- uec - Unit energy consumption of the appliance [kWh/yr]; | ||
- base_cycles - Base (uncalibrated) number of cycles per year; | ||
- mean_cycle_L - Mean cycle length [min]; | ||
- restart_delay - Delay restart after cycle [min]; | ||
- description - For input documentation. | ||
5. The **general_appliances** lists each appliance present in the dwelling. There may be duplicates of the same appliance. The full description general appliance inputs is located in *data/appliance_database.xml*. | ||
|
||
#### Cold Appliances | ||
[Wills et al. (2018)](https://www.tandfonline.com/doi/full/10.1080/19401493.2017.1369570) classified three types of cold appliances with the following inputs: | ||
1. *Refrigerator * - base_cycles = 6116, mean_cycle_L = 35, restart_delay = 35; | ||
2. *Upright_Freezer * - base_cycles = 6116, mean_cycle_L = 20, restart_delay = 40; | ||
3. *Chest_Freezer * - base_cycles = 6116, mean_cycle_L = 14, restart_delay = 56; | ||
|
||
The *uec* values were selected from data available in the report titled *Energy consumption of Major Household Appliances Shipped in Canada: Trends for 1990-2010*. |
Oops, something went wrong.