Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ on:
push:
branches: [main, dev]
pull_request:
branches: [main, dev]
# Run on all pull requests
types: [opened, synchronize, reopened]

jobs:
test:
Expand Down Expand Up @@ -61,9 +62,8 @@ jobs:
pip install ruff

- name: Run ruff linter
run: ruff check ochre/ --output-format=github
run: ruff check . --output-format=github
continue-on-error: true

- name: Run ruff formatter check
run: ruff format ochre/ --check --diff
continue-on-error: true
run: ruff format . --check --diff
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ docs/_build
*.code-workspace

ochre/defaults/Input Files/OCHRE*
.history
23 changes: 12 additions & 11 deletions bin/compare_energyplus.py
Original file line number Diff line number Diff line change
@@ -1,38 +1,39 @@
import os

from ochre import Analysis, CreateFigures, Dwelling
from ochre import Analysis, CreateFigures

# Script to compare OCHRE and E+ outputs for generic model. Assumes both models have been run in the same folder

# File locations
main_path = os.path.join('path', 'to', 'ochre_folder')
eplus_file = os.path.join(main_path, 'results_timeseries.csv')
simulation_name = 'ochre' # name for OCHRE files
main_path = os.path.join("path", "to", "ochre_folder")
eplus_file = os.path.join(main_path, "results_timeseries.csv")
simulation_name = "ochre" # name for OCHRE files


if __name__ == '__main__':
if __name__ == "__main__":
# Load OCHRE files
ochre_exact, ochre_metrics, ochre = Analysis.load_ochre(main_path, simulation_name, load_main=False,
combine_schedule=True)
ochre_exact, ochre_metrics, ochre = Analysis.load_ochre(
main_path, simulation_name, load_main=False, combine_schedule=True
)

# Load E+ files
eplus = Analysis.load_eplus_file(eplus_file, year=ochre.index[0].year)

# keep days from OCHRE simulation
eplus = eplus.loc[ochre.index[0]: ochre.index[-1]]
eplus = eplus.loc[ochre.index[0] : ochre.index[-1]]
eplus_metrics = Analysis.calculate_metrics(eplus, metrics_verbosity=6)

# Compare metrics and save to file
compare_metrics = Analysis.create_comparison_metrics(ochre, eplus, ochre_metrics, eplus_metrics)
metrics_file = os.path.join(main_path, simulation_name + '_comparison.csv')
metrics_file = os.path.join(main_path, simulation_name + "_comparison.csv")
compare_metrics.to_csv(metrics_file)

print(f'Comparison Metrics for {simulation_name}:')
print(f"Comparison Metrics for {simulation_name}:")
print(compare_metrics)

# show plots
# data = {'OCHRE (exact)': ochre_exact, 'OCHRE': ochre, 'E+': eplus}
data = {'OCHRE': ochre, 'E+': eplus}
data = {"OCHRE": ochre, "E+": eplus}
# CreateFigures.plot_external(data)
CreateFigures.plot_envelope(data)
# CreateFigures.plot_hvac(data)
Expand Down
11 changes: 3 additions & 8 deletions bin/run_cosimulation.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import os
import json
import datetime as dt
import shutil
import sys
import click
import helics
Expand Down Expand Up @@ -53,9 +52,7 @@

# Note: see documentation for where to download other weather files
# https://ochre-nrel.readthedocs.io/en/latest/InputsAndArguments.html#weather-file
default_weather_file = os.path.join(
default_input_path, "Weather", "USA_CO_Denver.Intl.AP.725650_TMY3.epw"
)
default_weather_file = os.path.join(default_input_path, "Weather", "USA_CO_Denver.Intl.AP.725650_TMY3.epw")

# control parameters - keep net load within +/- 1 kW per house
min_net_load = -1 * n
Expand Down Expand Up @@ -97,7 +94,7 @@ def step_to(time, fed, offset=0):
if t_new >= t_requested:
return
time.sleep(0.01)


@click.group()
def cli():
Expand Down Expand Up @@ -209,9 +206,7 @@ def aggregator():
results.append(total_powers)

# determine battery setpoints to maintain net load limits
nonbattery_power = (
total_powers["Total Electric Power (kW)"] - total_powers["Battery Electric Power (kW)"]
)
nonbattery_power = total_powers["Total Electric Power (kW)"] - total_powers["Battery Electric Power (kW)"]
if nonbattery_power > max_net_load:
battery_power = max_net_load - nonbattery_power
elif nonbattery_power < min_net_load:
Expand Down
15 changes: 6 additions & 9 deletions bin/run_dwelling.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import datetime as dt

from ochre import Dwelling, CreateFigures

# from ochre import Analysis
from ochre.utils import default_input_path

Expand All @@ -12,27 +13,23 @@
#
# Timing parameters
"start_time": dt.datetime(2018, 1, 1, 0, 0), # year, month, day, hour, minute
"time_res": dt.timedelta(minutes=60), # time resolution of the simulation
"duration": dt.timedelta(days=1), # duration of the simulation
"time_res": dt.timedelta(minutes=60), # time resolution of the simulation
"duration": dt.timedelta(days=1), # duration of the simulation
"initialization_time": dt.timedelta(days=1), # used to create realistic starting temperature
# "time_zone": None, # option to specify daylight savings, in development
#
# Input files
"hpxml_file": os.path.join(default_input_path, "Input Files", "bldg0112631-up11.xml"),
"hpxml_schedule_file": os.path.join(
default_input_path, "Input Files", "bldg0112631_schedule.csv"
),
"weather_file": os.path.join(
default_input_path, "Weather", "USA_CO_Denver.Intl.AP.725650_TMY3.epw"
),
"hpxml_schedule_file": os.path.join(default_input_path, "Input Files", "bldg0112631_schedule.csv"),
"weather_file": os.path.join(default_input_path, "Weather", "USA_CO_Denver.Intl.AP.725650_TMY3.epw"),
# note: weather_path can be used when Weather Station is specified in HPXML file
# "weather_path": weather_path,
#
# Output parameters
# "verbosity": 3, # verbosity of time series files (0-9)
# "metrics_verbosity": 3, # verbosity of metrics file (0-9)
# "save_results": False, # saves results to files. Defaults to True if verbosity > 0
"output_path": os.getcwd(), # defaults to hpxml_file path
"output_path": os.getcwd(), # defaults to hpxml_file path
# "save_args_to_json": True, # includes data from this dictionary in the json file
# "output_to_parquet": True, # saves time series files as parquet files (False saves as csv files)
# "save_schedule_columns": [], # list of time series inputs to save to schedule file
Expand Down
35 changes: 18 additions & 17 deletions bin/run_equipment.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
ElectricResistanceWaterHeater,
AirConditioner,
ScheduledLoad,
EventBasedLoad,
EventDataLoad,
)
from ochre import CreateFigures
Expand Down Expand Up @@ -45,7 +44,7 @@ def run_equipment_from_house_model(end_use):

# Extract equipment by its name or end use
equipment = dwelling.get_equipment_by_end_use(end_use)

# Update simulation properties to save results
equipment.main_simulator = True
equipment.save_results = True
Expand Down Expand Up @@ -130,8 +129,7 @@ def run_battery_from_schedule():
# Note: can also be done at each time step, see run_external_control.py
# for examples
schedule = np.random.randint(-5, 5, len(battery.sim_times))
battery.schedule = pd.DataFrame({"Battery Electric Power (kW)": schedule},
index=battery.sim_times)
battery.schedule = pd.DataFrame({"Battery Electric Power (kW)": schedule}, index=battery.sim_times)
battery.reset_time() # initializes the new schedule

# Simulate equipment
Expand Down Expand Up @@ -264,20 +262,24 @@ def run_hvac():

# create example HVAC schedule
# TODO: add solar radiation to schedule (in H_LIV)
times = pd.date_range(timing["start_time"], timing["start_time"] + timing["duration"], freq=timing["time_res"],
inclusive="left")
times = pd.date_range(
timing["start_time"], timing["start_time"] + timing["duration"], freq=timing["time_res"], inclusive="left"
)
deadband = (2 + 1 * np.random.randn(len(times))).clip(min=1)
ambient_temp = 27 - np.abs(times.hour.values - 14) / 2 + 0.5 * np.random.randn(len(times))
internal_gains = 100 + 30 * np.random.randn(len(times))
schedule = pd.DataFrame({
"HVAC Cooling Setpoint (C)": 22,
"HVAC Cooling Deadband (C)": deadband,
"Ambient Dry Bulb (C)": ambient_temp,
"Ambient Humidity Ratio (-)": 0.001,
# "Ambient Pressure (kPa)": 101,
# "T_EXT": ambient_temp,
"Internal Gains (W)": internal_gains,
}, index=times)
schedule = pd.DataFrame(
{
"HVAC Cooling Setpoint (C)": 22,
"HVAC Cooling Deadband (C)": deadband,
"Ambient Dry Bulb (C)": ambient_temp,
"Ambient Humidity Ratio (-)": 0.001,
# "Ambient Pressure (kPa)": 101,
# "T_EXT": ambient_temp,
"Internal Gains (W)": internal_gains,
},
index=times,
)

envelope_args = {
"capacitances": {
Expand Down Expand Up @@ -319,8 +321,7 @@ def run_hvac():

print()
# print(df.head())
CreateFigures.plot_daily_profile(df, "HVAC Cooling Electric Power (kW)",
plot_max=False, plot_min=False)
CreateFigures.plot_daily_profile(df, "HVAC Cooling Electric Power (kW)", plot_max=False, plot_min=False)
CreateFigures.plot_hvac({"": df})
# CreateFigures.plot_envelope({"": df})
CreateFigures.plt.show()
Expand Down
12 changes: 6 additions & 6 deletions bin/run_fleet.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ def run_ev_fleet(n=4, n_parallel=2):
df.plot()
CreateFigures.plt.show()


def setup_wh(i):
start_time = dt.datetime(2018, 1, 1, 0, 0) # year, month, day, hour, minute
time_res = dt.timedelta(minutes=1)
Expand Down Expand Up @@ -102,6 +103,7 @@ def setup_wh(i):
# Initialize equipment
return ElectricResistanceWaterHeater(**equipment_args)


def run_water_heater_fleet(n=5):
# Initialize equipment
fleet = [setup_wh(i + 1) for i in range(n)]
Expand All @@ -113,7 +115,7 @@ def run_water_heater_fleet(n=5):
all_data[wh.name] = df

cols_to_plot = [
"Water Heating Electric Power (kW)",
"Water Heating Electric Power (kW)",
"Hot Water Outlet Temperature (C)",
"Hot Water Delivered (L/min)",
]
Expand Down Expand Up @@ -142,11 +144,9 @@ def setup_battery(i):
# Note: can also be done at each time step, see run_external_control.py
# for examples
schedule = np.random.randint(-capacity, capacity, len(battery.sim_times))
battery.schedule = pd.DataFrame(
{"Battery Electric Power (kW)": schedule}, index=battery.sim_times
)
battery.schedule = pd.DataFrame({"Battery Electric Power (kW)": schedule}, index=battery.sim_times)
battery.reset_time() # initializes the new schedule

return battery


Expand All @@ -170,7 +170,7 @@ def run_battery_fleet(n=4):
CreateFigures.plt.show()


if __name__ == '__main__':
if __name__ == "__main__":
run_ev_fleet()
# run_water_heater_fleet()
# run_battery_fleet()
6 changes: 2 additions & 4 deletions bin/run_multiple.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import shutil

from ochre import Analysis
from ochre.cli import create_dwelling, limit_input_paths, run_multiple_local, run_multiple_hpc
from ochre.cli import create_dwelling
from ochre.utils import default_input_path

# Examples to download and run multiple Dwellings. Uses OCHRE's command line
Expand Down Expand Up @@ -48,9 +48,7 @@ def compile_results(main_path, n_max=None):
df.to_csv(os.path.join(output_path, "all_ochre_inputs.csv"))

# combine metrics files
metrics_files = {
name: os.path.join(path, "ochre_metrics.csv") for name, path in run_names.items()
}
metrics_files = {name: os.path.join(path, "ochre_metrics.csv") for name, path in run_names.items()}
df = Analysis.combine_metrics_files(metrics_files)
df.to_csv(os.path.join(output_path, "all_ochre_metrics.csv"))

Expand Down
18 changes: 10 additions & 8 deletions bin/run_panel_controls.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@
# Example code for running an building with smart panel controls.

main_output_path = dwelling_args.pop("output_path", os.getcwd())
dwelling_args.update({
"name": "ochre",
"time_res": dt.timedelta(minutes=2), # time resolution of the simulation
"duration": dt.timedelta(days=10), # duration of the simulation
"verbosity": 6, # verbosity of time series files (0-9)
'seed': 1,
})
dwelling_args.update(
{
"name": "ochre",
"time_res": dt.timedelta(minutes=2), # time resolution of the simulation
"duration": dt.timedelta(days=10), # duration of the simulation
"verbosity": 6, # verbosity of time series files (0-9)
"seed": 1,
}
)


def circuit_sharing_control(dwelling, tech1, tech2):
Expand Down Expand Up @@ -209,7 +211,7 @@ def my_print(*args):

# case 1, circuit sharing with cooking range (primary) and WH (secondary)
run_simulation(
"circuit_sharing",
"circuit_sharing",
tech1="Cooking Range",
tech2="Water Heating",
)
Expand Down
3 changes: 3 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

### OCHRE v0.9.3
- Allow 120V (aka low power) heat pump water heaters
- Applied ruff code formatting to entire codebase
- Fixed ruff lint errors across codebase
- Updated CI to run tests on all pull requests

### OCHRE v0.9.2
- Restrict pint version to avoid colab issues [#196](https://github.com/NREL/OCHRE/issues/196)
Expand Down
Loading