-
Notifications
You must be signed in to change notification settings - Fork 197
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix #3369 - Add missing fields to AvailabilityManager:HybridVentilation #4037
Conversation
@kbenne ``` C++ exception with description "std::bad_cast" thrown in the test body. ```
N8 , \field Minimum HVAC Operation Time | ||
\note Minimum operation time when HVAC system is forced on. | ||
\type real | ||
\units minutes | ||
\minimum 0.0 | ||
\required-field | ||
N9 ; \field Minimum Ventilation Time | ||
\note Minimum ventilation time when natural ventilation is forced on. | ||
\type real | ||
\units minutes | ||
\minimum 0.0 | ||
\required-field |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two new fields. They have a default to 0.0 in E+.idd, but I'm making them required-field and setting it to 0.0 in the model CTor.
// AirflowNetwork Control Type Schedule Name | ||
if (auto oSch = modelObject.airflowNetworkControlTypeSchedule()) { | ||
auto idf = translateAndMapModelObject(oSch.get()); | ||
OS_ASSERT(idf); | ||
idfObject.setString(AvailabilityManager_HybridVentilationFields::AirflowNetworkControlTypeScheduleName, idf->nameString()); | ||
} | ||
|
||
// Simple Airflow Control Type Schedule Name | ||
if (auto oSch = modelObject.simpleAirflowControlTypeSchedule()) { | ||
auto idf = translateAndMapModelObject(oSch.get()); | ||
OS_ASSERT(idf); | ||
idfObject.setString(AvailabilityManager_HybridVentilationFields::SimpleAirflowControlTypeScheduleName, idf->nameString()); | ||
} | ||
|
||
// ZoneVentilation Object Name | ||
if (auto oMo = modelObject.zoneVentilationObject()) { | ||
auto idf = translateAndMapModelObject(oMo.get()); | ||
// Model API shouldn't allow setting a wrong type (other than ZV:DesignFlowRate or ZV:WindAndStackOpenArea) anyways | ||
// and E+ will throw a clear warning if that were the case, so no need to check here | ||
OS_ASSERT(idf); | ||
idfObject.setString(AvailabilityManager_HybridVentilationFields::ZoneVentilationObjectName, idf->nameString()); | ||
} | ||
|
||
// Minimum HVAC Operation Time | ||
{ | ||
auto value = modelObject.minimumHVACOperationTime(); | ||
idfObject.setDouble(AvailabilityManager_HybridVentilationFields::MinimumHVACOperationTime,value); | ||
} | ||
|
||
// Minimum Ventilation Time | ||
{ | ||
auto value = modelObject.minimumVentilationTime(); | ||
idfObject.setDouble(AvailabilityManager_HybridVentilationFields::MinimumVentilationTime,value); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FT for the three fields withing model API and the two new fields.
@@ -48,22 +56,149 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_AvailabilityManagerHybridVentilation | |||
Model m; | |||
|
|||
AvailabilityManagerHybridVentilation avm(m); | |||
avm.setName("My AvailabilityManagerHybridVentilation"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a full FT test (there was a VERY minimal one before only)
ModelObject AvailabilityManagerHybridVentilation_Impl::clone(Model model) const { | ||
auto avmClone = AvailabilityManager_Impl::clone(model).cast<AvailabilityManagerHybridVentilation>(); | ||
// Makes little sense to me to keep these two which are AirLoopHVAC specific. If you're cloning this object, it's to set to to ANOTHER AirLoopHVAC | ||
avmClone.resetControlledZone(); | ||
avmClone.resetZoneVentilationObject(); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clone override, cf inline comment for justification.
setMinimumHVACOperationTime(0.0); | ||
setMinimumVentilationTime(0.0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ctor setting the E+ default.
setMinimumHVACOperationTime(0.0); | ||
setMinimumVentilationTime(0.0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ctor setting the E+ default.
bool AvailabilityManagerHybridVentilation_Impl::setZoneVentilationObject(const ModelObject& mo) { | ||
bool result = false; | ||
|
||
switch(mo.iddObject().type().value()) | ||
{ | ||
case openstudio::IddObjectType::OS_ZoneVentilation_WindandStackOpenArea : | ||
{ | ||
result = true; | ||
break; | ||
} | ||
case openstudio::IddObjectType::OS_ZoneVentilation_DesignFlowRate : | ||
{ | ||
result = true; | ||
break; | ||
} | ||
default: | ||
{ | ||
LOG(Warn, "Unsupported or invalid IddObjectType, only ZoneVentilation:DesignFlowRate or ZoneVentilation:WindAndStackOpenArea are supported. " | ||
<< "Occurred in setZoneVentilationObject for " << this->briefDescription() << ", was passed " << mo.briefDescription()); | ||
result = false; | ||
} | ||
} | ||
|
||
if( result ) | ||
{ | ||
result = this->setPointer(OS_AvailabilityManager_HybridVentilationFields::ZoneVentilationObject, mo.handle()); | ||
} | ||
|
||
return result; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'Zone Ventilation Object' only accepts a ZV:DesignFlowRate or a ZV:WindandStackOpenArea, so check that.
(I checked the E+ source in SystemAvailabilityManager.cc to confirm this is the case)
if (iddname == "OS:AvailabilityManager:HybridVentilation") { | ||
// Added 2 new fields at end only, and made them required-field by setting their default in the Ctor, so VT needed | ||
|
||
auto iddObject = idd_3_1_0.getObject(iddname); | ||
IdfObject newObject(iddObject.get()); | ||
|
||
for (size_t i = 0; i < object.numFields(); ++i) { | ||
if ((value = object.getString(i))) { | ||
newObject.setString(i, value.get()); | ||
} | ||
} | ||
|
||
// Set new fields per IDD default, same as Model Ctor, since it was made required-field | ||
// Minimum HVAC Operation Time | ||
newObject.setDouble(17, 0.0); | ||
// Minimum Ventilation Time | ||
newObject.setDouble(18, 0.0); | ||
|
||
m_refactored.push_back(RefactoredObjectData(object, newObject)); | ||
ss << newObject; | ||
|
||
// No-op | ||
} else { | ||
ss << object; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Vt for new fields at end (required)
@@ -899,3 +899,48 @@ TEST_F(OSVersionFixture, update_3_0_0_to_3_0_1_CoilCoolingDXTwoSpeed_minOATCompr | |||
ASSERT_TRUE(c.getTarget(34)); | |||
EXPECT_EQ("Basin Heater Operating Schedule Name", c.getTarget(34)->nameString()); | |||
} | |||
|
|||
TEST_F(OSVersionFixture, update_3_0_1_to_3_1_0_AvailabilityManagerHybridVentilation) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
VT test
|
||
// Maximum Outdoor Temperature: Required Double | ||
EXPECT_TRUE(avm.setMaximumOutdoorTemperature(0.0)); | ||
EXPECT_EQ(0.0, avm.maximumOutdoorTemperature()); | ||
// Bad Value | ||
EXPECT_FALSE(avm.setMaximumOutdoorTemperature(-110.0)); | ||
EXPECT_EQ(0.0, avm.maximumOutdoorTemperature()); | ||
|
||
// Minimum Outdoor Enthalpy: Required Double | ||
EXPECT_TRUE(avm.setMinimumOutdoorEnthalpy(150000.0)); | ||
EXPECT_EQ(150000.0, avm.minimumOutdoorEnthalpy()); | ||
// Bad Value | ||
EXPECT_FALSE(avm.setMinimumOutdoorEnthalpy(-10.0)); | ||
EXPECT_EQ(150000.0, avm.minimumOutdoorEnthalpy()); | ||
|
||
// Maximum Outdoor Enthalpy: Required Double | ||
EXPECT_TRUE(avm.setMaximumOutdoorEnthalpy(150000.0)); | ||
EXPECT_EQ(150000.0, avm.maximumOutdoorEnthalpy()); | ||
// Bad Value | ||
EXPECT_FALSE(avm.setMaximumOutdoorEnthalpy(-10.0)); | ||
EXPECT_EQ(150000.0, avm.maximumOutdoorEnthalpy()); | ||
|
||
// Minimum Outdoor Dewpoint: Required Double | ||
EXPECT_TRUE(avm.setMinimumOutdoorDewpoint(0.0)); | ||
EXPECT_EQ(0.0, avm.minimumOutdoorDewpoint()); | ||
// Bad Value | ||
EXPECT_FALSE(avm.setMinimumOutdoorDewpoint(-110.0)); | ||
EXPECT_EQ(0.0, avm.minimumOutdoorDewpoint()); | ||
|
||
// Maximum Outdoor Dewpoint: Required Double | ||
EXPECT_TRUE(avm.setMaximumOutdoorDewpoint(0.0)); | ||
EXPECT_EQ(0.0, avm.maximumOutdoorDewpoint()); | ||
// Bad Value | ||
EXPECT_FALSE(avm.setMaximumOutdoorDewpoint(-110.0)); | ||
EXPECT_EQ(0.0, avm.maximumOutdoorDewpoint()); | ||
|
||
// Minimum Outdoor Ventilation Air Schedule: Optional Object but set in Ctor and non optional | ||
ScheduleConstant min_oa_sch(m); | ||
EXPECT_TRUE(avm.setMinimumOutdoorVentilationAirSchedule(min_oa_sch)); | ||
EXPECT_EQ(min_oa_sch, avm.minimumOutdoorVentilationAirSchedule()); | ||
|
||
// Opening Factor Function of Wind Speed Curve: Optional Object | ||
CurveLinear opening_factor_curve(m); | ||
EXPECT_FALSE(avm.openingFactorFunctionofWindSpeedCurve()); | ||
EXPECT_TRUE(avm.setOpeningFactorFunctionofWindSpeedCurve(opening_factor_curve)); | ||
ASSERT_TRUE(avm.openingFactorFunctionofWindSpeedCurve()); | ||
EXPECT_EQ(opening_factor_curve, avm.openingFactorFunctionofWindSpeedCurve().get()); | ||
avm.resetOpeningFactorFunctionofWindSpeedCurve(); | ||
EXPECT_FALSE(avm.openingFactorFunctionofWindSpeedCurve()); | ||
|
||
// AirflowNetwork Control Type Schedule: Optional Object | ||
ScheduleConstant afn_control_sch(m); | ||
EXPECT_FALSE(avm.airflowNetworkControlTypeSchedule()); | ||
EXPECT_TRUE(avm.setAirflowNetworkControlTypeSchedule(afn_control_sch)); | ||
ASSERT_TRUE(avm.airflowNetworkControlTypeSchedule()); | ||
EXPECT_EQ(afn_control_sch, avm.airflowNetworkControlTypeSchedule().get()); | ||
avm.resetAirflowNetworkControlTypeSchedule(); | ||
EXPECT_FALSE(avm.airflowNetworkControlTypeSchedule()); | ||
|
||
// Simple Airflow Control Type Schedule: Optional Object | ||
ScheduleConstant simple_control_sch(m); | ||
EXPECT_FALSE(avm.simpleAirflowControlTypeSchedule()); | ||
EXPECT_TRUE(avm.setSimpleAirflowControlTypeSchedule(simple_control_sch)); | ||
ASSERT_TRUE(avm.simpleAirflowControlTypeSchedule()); | ||
EXPECT_EQ(simple_control_sch, avm.simpleAirflowControlTypeSchedule().get()); | ||
avm.resetSimpleAirflowControlTypeSchedule(); | ||
EXPECT_FALSE(avm.simpleAirflowControlTypeSchedule()); | ||
|
||
// ZoneVentilation Object: Optional Object | ||
EXPECT_FALSE(avm.zoneVentilationObject()); | ||
ZoneVentilationDesignFlowRate zvd(m); | ||
EXPECT_TRUE(avm.setZoneVentilationObject(zvd)); | ||
ASSERT_TRUE(avm.zoneVentilationObject()); | ||
EXPECT_EQ(zvd, avm.zoneVentilationObject().get()); | ||
ZoneVentilationWindandStackOpenArea zvw(m); | ||
EXPECT_TRUE(avm.setZoneVentilationObject(zvw)); | ||
ASSERT_TRUE(avm.zoneVentilationObject()); | ||
EXPECT_EQ(zvw, avm.zoneVentilationObject().get()); | ||
// Bad type | ||
ZoneMixing zm(z); | ||
EXPECT_FALSE(avm.setZoneVentilationObject(zm)); | ||
ASSERT_TRUE(avm.zoneVentilationObject()); | ||
EXPECT_EQ(zvw, avm.zoneVentilationObject().get()); | ||
avm.resetZoneVentilationObject(); | ||
EXPECT_FALSE(avm.zoneVentilationObject()); | ||
|
||
// Minimum HVAC Operation Time: Required Double | ||
EXPECT_TRUE(avm.setMinimumHVACOperationTime(0.1)); | ||
EXPECT_EQ(0.1, avm.minimumHVACOperationTime()); | ||
// Bad Value | ||
EXPECT_FALSE(avm.setMinimumHVACOperationTime(-10.0)); | ||
EXPECT_EQ(0.1, avm.minimumHVACOperationTime()); | ||
|
||
// Minimum Ventilation Time: Required Double | ||
EXPECT_TRUE(avm.setMinimumVentilationTime(0.2)); | ||
EXPECT_EQ(0.2, avm.minimumVentilationTime()); | ||
// Bad Value | ||
EXPECT_FALSE(avm.setMinimumVentilationTime(-10.0)); | ||
EXPECT_EQ(0.2, avm.minimumVentilationTime()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a full new test for Model API, testing all getters/setters (before there was only a Ctor test)
ModelObject AvailabilityManagerHybridVentilation_Impl::clone(Model model) const { | ||
auto avmClone = AvailabilityManager_Impl::clone(model).cast<AvailabilityManagerHybridVentilation>(); | ||
|
||
// Makes little sense to me to keep these two which are AirLoopHVAC specific. If you're cloning this object, it's to set to to ANOTHER AirLoopHVAC |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. This seems like the correct thing to do.
@kbenne I did not add an integration test no. That would need to be a fully new test for the three existing fields that didn't have an implementation, and these fields are 1) weird and not straightforward (I'm not 100% sure how to produce a valid test, so it's going to require time and effort), 2) mutually exclusive. 3) this object is not one of the most common ones. 4) the existing test for AVMs is very minimal https://github.com/NREL/OpenStudio-resources/blob/a729a7c85f55cc05d7ba6d50c45d21b8621611c9/model/simulationtests/availability_managers.rb#L48-L49. Instead I tested a bunch here. I can add one if you really want to though. |
99aa952
to
9b82631
Compare
Linux and mac are happy, aside from the usual suspects:
Ready to drop in. (I need the VT part for another PR, so better sooner than later) @kbenne do I need to add an OpenStudio-resources test? |
Good with version bump! |
Windows seem to have failed with the same error as on #4029
@tijcolem https://ci.commercialbuildings.dev/blue/organizations/jenkins/openstudio-incremental-windows/detail/PR-4037/5/pipeline#step-34-log-99 |
Pull request overview
Bumped the version to 3.1.0-alpha since I needed VersionTranslation
Pull Request Author
Add to this list or remove from it as applicable. This is a simple templated set of guidelines.
src/model/test
)src/energyplus/Test
)src/osversion/VersionTranslator.cpp
)src/openstudio_lib/library/OpenStudioPolicy.xml
)Labels:
IDDChange
APIChange
Pull Request - Ready for CI
so that CI builds your PRReview Checklist
This will not be exhaustively relevant to every PR.