diff --git a/Utilities/LoadProfile.py b/Utilities/LoadProfile.py index 4518635..cbd5f65 100644 --- a/Utilities/LoadProfile.py +++ b/Utilities/LoadProfile.py @@ -1,6 +1,7 @@ import numpy as np from Utilities.Time import generate_timestrings, index_peak_times, index_operating_hours from scipy.optimize import root_scalar +import pandas as pd def get_no_of_peaks(peak_bounds): @@ -34,12 +35,15 @@ def generate_out_of_hours_consumption_ratio(c): return ratio -def generate_realistic_profile(site, peak_indices, out_of_hours_ratio): - pass +def recompute_load_profile( + load_profile, + offset, +): + # apply offset to the load profile + load_profile += offset -def objective(x): - pass + return load_profile def get_load_profile(c, dt, batch_start_time, batch_process_duration): @@ -54,19 +58,53 @@ def get_load_profile(c, dt, batch_start_time, batch_process_duration): # generate timeseries from start to end time start_time = batch_start_time end_time = start_time + batch_process_duration + batch_process_duration_hours = batch_process_duration / 3600 # convert to hours timestamps = np.arange(start_time, end_time + 1, dt) - operating_hours_indices = index_operating_hours( + idx_operating_hours = index_operating_hours( timestamps, c["site_info"]["operating hours"] ) + no_of_operating_hours = np.sum(idx_operating_hours > 0) # loop through each site in the configuration for site in c["site_info"]["sites"]: + # Initialise the load profile + load_profile = np.zeros(len(timestamps)) + + # generate noise to make the profile more realistic + noise = np.random.normal( + 1 - c["noise"]["range"], 1 + c["noise"]["range"], len(timestamps) + ) # Generate peak times and durations peak_times, peak_durations = generate_peak_info(c, dt) # Generate peak times and durations - peak_indices = index_peak_times(timestamps, peak_times, peak_durations) + idx_peak = index_peak_times(timestamps, peak_times, peak_durations) # Generate out-of-hours consumption ratio # The % of energy used outside of the operating hours out_of_hours_ratio = generate_out_of_hours_consumption_ratio(c) + + # start by computing average consumption during operating hours + # and outside of operating hours + operating_hour_consumption = site["daily_consumption_kWh"] * ( + 1 - out_of_hours_ratio + ) + out_of_hours_consumption = site["daily_consumption_kWh"] * out_of_hours_ratio + + avg_operating_hour_consumption = ( + operating_hour_consumption / no_of_operating_hours + ) + avg_out_of_hours_consumption = out_of_hours_consumption / ( + batch_process_duration_hours - no_of_operating_hours + ) + + # assign base load profile + load_profile[idx_operating_hours > 0] = avg_operating_hour_consumption + load_profile[idx_operating_hours == 0] = avg_out_of_hours_consumption + + # apply peak loads + for i in range(1, np.max(idx_peak) + 1): + load_profile[idx_peak == i] = site["maximum_demand_kW"] + + # apply noise to the load profile, including max demand + load_profile = load_profile * noise diff --git a/YAMLs/config.yml b/YAMLs/config.yml index 9b33893..283dfc3 100644 --- a/YAMLs/config.yml +++ b/YAMLs/config.yml @@ -3,5 +3,8 @@ sim_time: batch_process_hours: 24 # compute load profile of 24 hours at a time duration_days: 60 +noise: + range: 0.15 + paths: site_info: YAMLs/site_info.yaml