Skip to content

Commit

Permalink
Updated HPWH_sizing logic, Added workflow testing
Browse files Browse the repository at this point in the history
  • Loading branch information
yunjoonjung-PNNL committed Aug 26, 2024
1 parent 89fcec8 commit 46bcbdd
Show file tree
Hide file tree
Showing 4 changed files with 287 additions and 27 deletions.
41 changes: 28 additions & 13 deletions constrain/library/hpwh_sizing.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from constrain.checklib import RuleCheckBase
import numpy as np

TEMP_TOLERANCE = 0.5 # deg C


class HPWH_sizing(RuleCheckBase):
Expand All @@ -8,24 +11,36 @@ class HPWH_sizing(RuleCheckBase):
"HeatingRate_waterheater1",
"HeatingRate_waterheater2",
"T_amb_parameter",
"HPWH_output_target_percent",
]

def hpwh_load(self, data):
total_hpwh_load = (
data["HeatingRate_dx_coil"]
+ data["HeatingRate_waterheater1"]
+ data["HeatingRate_waterheater2"]
def verify(self):
self.df["total_hpwh_load"] = (
self.df["HeatingRate_dx_coil"]
+ self.df["HeatingRate_waterheater1"]
+ self.df["HeatingRate_waterheater2"]
)

if data["T_amb"] <= data["T_amb_parameter"] or total_hpwh_load == 0.0:
return "untested"
elif data["HeatingRate_dx_coil"] / total_hpwh_load >= 1:
return True
else:
return False
self.df["HPWH_output"] = np.where(
self.df["total_hpwh_load"] != 0.0,
self.df["HeatingRate_dx_coil"] / self.df["total_hpwh_load"] * 100,
0.0,
)

def verify(self):
self.result = self.df.apply(lambda d: self.hpwh_load(d), axis=1)
min_hpwh_output = self.df[
(self.df["T_amb"] > self.df["T_amb_parameter"])
& (self.df["HPWH_output"] > 0.0)
]["HPWH_output"].min()
min_hpwh_output = 0.0 if min_hpwh_output is np.nan else min_hpwh_output

HPWH_output_target_percent = self.df["HPWH_output_target_percent"].iloc[0]

if min_hpwh_output >= HPWH_output_target_percent:
self.df["result"] = True
elif min_hpwh_output < HPWH_output_target_percent:
self.df["result"] = False

self.result = self.df["result"]

def check_bool(self):
if len(self.result[self.result == False] > 0):
Expand Down
94 changes: 94 additions & 0 deletions demo/hpwh_demo/hpwh_demo_workflow.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
{
"workflow_name": "HPWH workflow",
"meta": {
"author": "Yun Joon Jung",
"date": "08/26/2024",
"version": "1.0",
"description": "Demo workflow to showcase core Workflow API functionalities"
},
"imports": [
"numpy as np",
"pandas as pd",
"glob"
],
"states": {
"load timeseries data": {
"Type": "MethodCall",
"MethodCall": "DataProcessing",
"Parameters": {
"data_path": "./demo/hpwh_demo/IECC-state-current-5B_ApartmentMidRise_STD2021_WA-Spokane-WA.csv",
"data_source": "EnergyPlus"
},
"Payloads": {"data_processing_obj": "$", "data": "$.data"},
"Start": "True",
"Next": "load original verification case"
},
"load original verification case": {
"Type": "MethodCall",
"MethodCall": "VerificationCase",
"Parameters": {
"json_case_path": "./demo/hpwh_demo/hpwh_demo_verification_cases.json"
},
"Payloads": {
"verification_case_obj": "$",
"original_case_keys": "$.case_suite.keys()"
},
"Next": "setup verification"
},
"setup verification": {
"Type": "MethodCall",
"MethodCall": "Verification",
"Parameters": {"verifications": "Payloads['verification_case_obj']"},
"Payloads": {"verification_obj": "$"},
"Next": "configure verification runner"
},
"configure verification runner": {
"Type": "MethodCall",
"MethodCall": "Payloads['verification_obj'].configure",
"Parameters": {
"output_path": "./demo/hpwh_demo/outputs",
"lib_items_path": "./schema/library.json",
"plot_option": "+x None",
"fig_size": "+x (6, 5)",
"num_threads": 1,
"preprocessed_data": "Payloads['data']"
},
"Payloads": {},
"Next": "run verification"
},
"run verification": {
"Type": "MethodCall",
"MethodCall": "Payloads['verification_obj'].run",
"Parameters": {},
"Payloads": {"verification_return": "$"},
"Next": "reporting_object_instantiation"
},
"reporting_object_instantiation": {
"Type": "MethodCall",
"MethodCall": "Reporting",
"Parameters": {
"verification_json": "./demo/hpwh_demo/outputs/*_md.json",
"result_md_name": "report_summary.md",
"report_format": "markdown"
},
"Payloads": {"reporting_obj": "$"},
"Next": "report cases"
},
"report cases": {
"Type": "MethodCall",
"MethodCall": "Payloads['reporting_obj'].report_multiple_cases",
"Parameters": {},
"Payloads": {},
"Next": "Success"
},
"Success": {
"Type": "MethodCall",
"MethodCall": "print",
"Parameters": [
"Congratulations! the demo workflow is executed with expected results and no error!"
],
"Payloads": {},
"End": "True"
}
}
}
48 changes: 48 additions & 0 deletions schema/library.json
Original file line number Diff line number Diff line change
Expand Up @@ -1556,5 +1556,53 @@
" pass",
"end"
]
},
"HPWH_sizing": {
"library_item_id": 68,
"description_brief": "The algorithm verifies whether hpwh DX coil can achieve 100% heating rate at every time step.",
"description_index": [
"N/A"
],
"description_datapoints": {
"T_amb": "outdoor ambient temperature",
"HeatingRate_dx_coil": "HPWH coil's total water heating rate",
"HeatingRate_waterheater1": "HPWH 1 heating rate",
"HeatingRate_waterheater2": "HPWH 2 heating rate",
"T_amb_parameter": "outdoor ambient temperature parameter",
"HPWH_output_target_percent": "HPWH output target in percent"
},
"description_verification_type": "rule-based",
"assertions_type": "pass",
"description_assertions": [
"total_hpwh_load = HeatingRate_dx_coil + HeatingRate_waterheater1 + HeatingRate_waterheater2",
"if T_amb <= T_amb_parameter or HeatingRate_dx_coil / total_hpwh_load == 0.0:",
" untested",
"elif HeatingRate_dx_coil / total_hpwh_load >= 1:",
" pass",
"else: ",
" fail",
"end"
]
},
"DHW_tank_temperature": {
"library_item_id": 69,
"description_brief": "The algorithm verifies whether water temperature in the domestic hot water tank is within the deadband.",
"description_index": [
"N/A"
],
"description_datapoints": {
"T_dhw": "Water temperature in DHW tank",
"T_dhw_deadband": "DHW tank temperature deadband",
"T_dhw_design_parameter": "DHW tank design temperature"
},
"description_verification_type": "rule-based",
"assertions_type": "pass",
"description_assertions": [
"if abs(T_dhw - T_dhw_design_parameter) <= 0.5 * T_dhw_deadband:",
" pass",
"else: ",
" fail",
"end"
]
}
}
131 changes: 117 additions & 14 deletions tests/test_HPWH_sizing.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,148 @@
import unittest

sys.path.append("./constrain")
import datetime

import pandas as pd
from lib_unit_test_runner import *


class TestHPWHSizing(unittest.TestCase):
def test_HPWH_sizing(self):
def test_HPWH_sizing_pass(self):
points = [
"T_amb",
"HeatingRate_dx_coil",
"HeatingRate_waterheater1",
"HeatingRate_waterheater2",
"T_amb_parameter",
"HPWH_output_target_percent",
]

timestamp = [
datetime(2024, 1, 1, 12, 0, 0),
datetime(2024, 1, 1, 13, 0, 0),
datetime(2024, 1, 1, 14, 0, 0),
datetime(2024, 1, 1, 15, 0, 0),
]

data = [
[3.0, 50, 0, 50, 2.7, 50],
[3.0, 60, 0, 60, 2.7, 50],
[5.0, 60, 10, 30, 2.7, 50],
[5.0, 80, 40, 40, 2.7, 50],
]

df = pd.DataFrame(data, columns=points, index=timestamp)

verification_obj = run_test_verification_with_data("HPWH_sizing", df)

results = pd.Series(list(verification_obj.result))
expected_results = pd.Series(
[
True,
True,
True,
True,
]
)
self.assertTrue(results.equals(expected_results))

binary_result = verification_obj.check_bool()
self.assertTrue(binary_result)

def test_HPWH_sizing_fail(self):
points = [
"T_amb",
"HeatingRate_dx_coil",
"HeatingRate_waterheater1",
"HeatingRate_waterheater2",
"T_amb_parameter",
"HPWH_output_target_percent",
]

timestamp = [
datetime(2024, 1, 1, 12, 0, 0),
datetime(2024, 1, 1, 13, 0, 0),
datetime(2024, 1, 1, 14, 0, 0),
datetime(2024, 1, 1, 15, 0, 0),
]

data = [
[3.0, 0, 0, 0, 3.7], # untested - when T_amb <= T_amb_parameter,
[5, 0, 0, 0, 3.7], # untested - when total_hpwh_load == 0
[3.0, 50, 0, 50, 2.7, 50],
[3.0, 60, 0, 60, 2.7, 50],
[5.0, 60, 10, 30, 2.7, 50],
[
5.0,
30,
0,
0,
3.7,
], # pass - when `HeatingRate_dx_coil` can meet all the load
40,
40,
2.7,
50,
], # fail because of this line (e.g., 30 / (30+40+40) < 50)
]

df = pd.DataFrame(data, columns=points, index=timestamp)

verification_obj = run_test_verification_with_data("HPWH_sizing", df)

results = pd.Series(list(verification_obj.result))
expected_results = pd.Series(
[
5.0,
False,
False,
False,
False,
]
)
self.assertTrue(results.equals(expected_results))

binary_result = verification_obj.check_bool()
self.assertFalse(binary_result)

def test_HPWH_sizing_fail_all_temps_less_than_temp_param(self):
points = [
"T_amb",
"HeatingRate_dx_coil",
"HeatingRate_waterheater1",
"HeatingRate_waterheater2",
"T_amb_parameter",
"HPWH_output_target_percent",
]

timestamp = [
datetime(2024, 1, 1, 12, 0, 0),
datetime(2024, 1, 1, 13, 0, 0),
datetime(2024, 1, 1, 14, 0, 0),
datetime(2024, 1, 1, 15, 0, 0),
]

data = [
[1.0, 50, 0, 50, 2.7, 50],
[1.0, 60, 0, 60, 2.7, 50],
[2.0, 60, 10, 30, 2.7, 50],
[
2.0,
30,
0,
20,
3.7,
], # fail - when `HeatingRate_dx_coil` cannot meet all the load
40,
40,
2.7,
50,
],
]

df = pd.DataFrame(data, columns=points)
df = pd.DataFrame(data, columns=points, index=timestamp)

verification_obj = run_test_verification_with_data("HPWH_sizing", df)

results = pd.Series(list(verification_obj.result))
expected_results = pd.Series(["untested", "untested", True, False])
expected_results = pd.Series(
[
False,
False,
False,
False,
]
)
self.assertTrue(results.equals(expected_results))

binary_result = verification_obj.check_bool()
Expand Down

0 comments on commit 46bcbdd

Please sign in to comment.