From e69c04cda208480d6888bec775526103478c1aa7 Mon Sep 17 00:00:00 2001 From: Lucas Tan Date: Sun, 13 Jul 2025 15:52:48 +0100 Subject: [PATCH] working on load profiling simulation --- .gitignore | 2 ++ LoadProfile.py | 24 ++++++++++++++++++++++++ Utilities/Time.py | 21 +++++++++++++++++++++ YAMLs/config.yml | 7 +++++++ YAMLs/site_info.yaml | 34 ++++++++++++++++++++++++++++++++++ main.py | 21 +++++++++++++++++++++ requirements.txt | 6 ++++++ 7 files changed, 115 insertions(+) create mode 100644 .gitignore create mode 100644 LoadProfile.py create mode 100644 Utilities/Time.py create mode 100644 YAMLs/config.yml create mode 100644 YAMLs/site_info.yaml create mode 100644 main.py create mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e0f31ed --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +venv/ +*.pyc \ No newline at end of file diff --git a/LoadProfile.py b/LoadProfile.py new file mode 100644 index 0000000..75bfdb6 --- /dev/null +++ b/LoadProfile.py @@ -0,0 +1,24 @@ +import numpy as np +from Utilities.Time import generate_timestrings + + +def get_no_of_peaks(peak_bounds): + peak_occurences = np.random.randint(peak_bounds["min"], peak_bounds["max"], 1) + return peak_occurences + + +def generate_peak_info(c, dt): + no_of_peaks = get_no_of_peaks(c["site_info"]["no_of_peaks"]) + operating_hours = generate_timestrings( + c["site_info"]["operating hours"]["start"], + c["site_info"]["operating hours"]["end"], + dt, + ) + peak_times = np.random.choice(operating_hours, no_of_peaks, replace=False) + + print(f"Peak times: {peak_times}") + return peak_times + + +def get_load_profile(c, dt): + return generate_peak_info(c, dt) diff --git a/Utilities/Time.py b/Utilities/Time.py new file mode 100644 index 0000000..40e54ba --- /dev/null +++ b/Utilities/Time.py @@ -0,0 +1,21 @@ +import time +from datetime import datetime, timedelta + + +def get_current_time(): + """Returns the current time in seconds since the epoch.""" + return time.time() + + +def generate_timestrings(start_time_str, end_time_str, dt): + """Generates a list of timestamps from start_time to end_time, which are strings such + as 19:00.""" + + timestamps = [] + current_time = datetime.strptime(start_time_str, "%H:%M") + end_time = datetime.strptime(end_time_str, "%H:%M") + while current_time <= end_time: + timestamps.append(current_time) + current_time += timedelta(seconds=dt) + timestrings = [dt.strftime("%H:%M") for dt in timestamps] + return timestrings diff --git a/YAMLs/config.yml b/YAMLs/config.yml new file mode 100644 index 0000000..9b33893 --- /dev/null +++ b/YAMLs/config.yml @@ -0,0 +1,7 @@ +sim_time: + time_step_minutes: 1 + batch_process_hours: 24 # compute load profile of 24 hours at a time + duration_days: 60 + +paths: + site_info: YAMLs/site_info.yaml diff --git a/YAMLs/site_info.yaml b/YAMLs/site_info.yaml new file mode 100644 index 0000000..0fbb761 --- /dev/null +++ b/YAMLs/site_info.yaml @@ -0,0 +1,34 @@ +# site consumption info to simulate load profile with + +sites: + - name: Aetas Damansara + daily_consumption_kWh: 308 + maximum_demand_kW: 145 + location: 3.132000, 101.623000 + - name: Alora + daily_consumption_kWh: 432 + maximum_demand_kW: 203 + location: 2.997419, 101.589894 + - name: Alira + daily_consumption_kWh: 449 + maximum_demand_kW: 211 + location: 3.057000, 101.582000 + - name: Amika + daily_consumption_kWh: 533 + maximum_demand_kW: 251 + location: 3.048500, 101.634000 + - name: Lakeside Sanderling + daily_consumption_kWh: 736 + maximum_demand_kW: 346 + location: 3.040300, 101.610100 +operating hours: + start: "07:00" + end: "19:00" +time zone: Asia/Kuala_Lumpur +no_of_peaks: + min: 30 + max: 100 +peak_duration: + unit: minutes + min: 0.5 + max: 2 diff --git a/main.py b/main.py new file mode 100644 index 0000000..813b764 --- /dev/null +++ b/main.py @@ -0,0 +1,21 @@ +import yaml +from Utilities.Time import get_current_time +from LoadProfile import get_load_profile + +# read config file +c = yaml.safe_load(open("YAMLs/config.yml")) + +## simulation time setup +# get current time +c["sim_start_time"] = get_current_time() +# get time step in minutes, then convert to seconds +dt = c["sim_time"]["time_step_minutes"] * 60 +# compute end time based on duration in days +duration = c["sim_time"]["duration_days"] * 24 * 60 * 60 +c["sim_end_time"] = c["sim_start_time"] + duration + +# load site info +c["site_info"] = yaml.safe_load(open(c["paths"]["site_info"])) + +# generate load profiles +get_load_profile(c, dt) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..07ac851 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,6 @@ +numpy==2.3.1 +pandas==2.3.1 +python-dateutil==2.9.0.post0 +pytz==2025.2 +six==1.17.0 +tzdata==2025.2