Skip to content

Commit

Permalink
Merge 2a256ff into b8f348b
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris Mackey authored Jan 13, 2020
2 parents b8f348b + 2a256ff commit ad86c49
Show file tree
Hide file tree
Showing 9 changed files with 11,477 additions and 11,332 deletions.
113 changes: 89 additions & 24 deletions honeybee_schema/energy/hvac.py
Original file line number Diff line number Diff line change
@@ -1,57 +1,122 @@
"""Ideal Air Schema"""
from pydantic import BaseModel, Field, validator, constr
from pydantic import Field, validator, root_validator, constr
from typing import Union
from enum import Enum

from ._base import NamedEnergyBaseModel


class EconomizerType(str, Enum):
no_economizer = 'NoEconomizer'
differential_dry_bulb = 'DifferentialDryBulb'
differential_enthalpy = 'DifferentialEnthalpy'


class IdealAirSystem(BaseModel):
class IdealAirSystemAbridged(NamedEnergyBaseModel):
""" Provides a model for an ideal HVAC system."""

type: constr(regex='^IdealAirSystem$') = 'IdealAirSystem'
type: constr(regex='^IdealAirSystemAbridged$') = 'IdealAirSystemAbridged'

economizer_type: EconomizerType = Field(
EconomizerType.differential_dry_bulb,
description='Text to indicate the type of air-side economizer used on the '
'ideal air system. Economizers will mix in a greater amount of outdoor '
'air to cool the zone (rather than running the cooling system) when '
'the zone needs cooling and the outdoor air is cooler than the zone.'
)

demand_control_ventilation: bool = Field(
False,
description='Boolean to note whether demand controlled ventilation should '
'be used on the system, which will vary the amount of ventilation air '
'according to the occupancy schedule of the zone.'
)

sensible_heat_recovery: float = Field(
0,
ge=0,
le=1,
description='A number between 0 and 1 for the effectiveness of sensible '
'heat recovery within the system.'
)

latent_heat_recovery: float = Field(
0,
ge=0,
le=1,
description='A number between 0 and 1 for the effectiveness of latent '
'heat recovery within the system.'
)

heating_air_temperature: float = Field(
50,
gt=0,
lt=100,
description='A number for the maximum heating supply air temperature [C].'
)

cooling_air_temperature: float = Field(
13,
gt=-100,
lt=50,
description='A number for the minimum cooling supply air temperature [C].'
)

heating_limit: Union[float, str] = Field(
'autosize',
ge=0
ge=0,
description='A number for the maximum heating capacity in Watts. This '
'can also be the text "autosize" to indicate that the capacity should '
'be determined during the sizing calculation that happens before '
'EnergyPlus runs the simulation over the run period. If None, no limit '
'on heating capacity will be applied.'
)

@validator('heating_limit')
def check_string_heating_limit(cls, v):
if not isinstance(v ,float) and v != 'autosize' and v != 'NoLimit':
raise ValueError( 'This is not a valid entry for heating_limit')
def check_heating_limit(cls, v):
if v is not None and not isinstance(v ,float) and v != 'autosize':
raise ValueError( '"{}" is not a valid entry for heating_limit'.format(v))


cooling_limit: Union[float, str] = Field(
'autosize',
ge=0
ge=0,
description='A number for the maximum cooling capacity in Watts. This '
'can also be the text "autosize" to indicate that the capacity should '
'be determined during the sizing calculation that happens before '
'EnergyPlus runs the simulation over the run period. If None, no limit '
'on cooling capacity will be applied.'
)

@validator('cooling_limit')
def check_string_cooling_limit(cls, v):
if not isinstance(v, float) and v != 'autosize' and v != 'NoLimit':
raise ValueError( 'This is not a valid entry for cooling_limit')

economizer_type: EconomizerType = EconomizerType.differential_dry_bulb
def check_cooling_limit(cls, v):
if v is not None and not isinstance(v, float) and v != 'autosize':
raise ValueError( '"{}" is not a valid entry for cooling_limit'.format(v))

demand_control_ventilation: bool = Field(
False
heating_availability: str = Field(
None,
min_length=1,
max_length=100,
description='An optional name of a schedule to set the availability of '
'heating over the course of the simulation.'
)

sensible_heat_recovery: float = Field(
0,
ge=0,
le=1
cooling_availability: str = Field(
None,
min_length=1,
max_length=100,
description='An optional name of a schedule to set the availability of '
'cooling over the course of the simulation.'
)

latent_heat_recovery: float = Field(
0,
ge=0,
le=1
)
@root_validator
def check_heating_temp_gt_cooling_temp(cls, values):
"Ensure that the heating_air_temperature > cooling_air_temperature."
heat_temp = values.get('heating_air_temperature')
cool_temp = values.get('cooling_air_temperature')
assert heat_temp > cool_temp, 'IdealAirSystem heating_air_temperature must be ' \
'greater than cooling_air_temperature.'
return values


if __name__ == '__main__':
Expand Down
30 changes: 20 additions & 10 deletions honeybee_schema/energy/properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
GasEquipmentAbridged, InfiltrationAbridged, VentilationAbridged, SetpointAbridged
from .schedule import ScheduleTypeLimit, ScheduleRulesetAbridged, \
ScheduleFixedIntervalAbridged
from .hvac import IdealAirSystem
from .hvac import IdealAirSystemAbridged


class ShadeEnergyPropertiesAbridged(BaseModel):
Expand Down Expand Up @@ -110,8 +110,13 @@ class RoomEnergyPropertiesAbridged(BaseModel):
'for the Room. If None, the Room will have no loads or setpoints.'
)

hvac: IdealAirSystem = Field(
default=None
hvac: str = Field(
default=None,
min_length=1,
max_length=100,
description='An optional name of a HVAC system (such as an IdealAirSystem) '
'that specifies how the Room is conditioned. If None, it will be assumed '
'that the Room is not conditioned.'
)

people: PeopleAbridged = Field(
Expand Down Expand Up @@ -165,11 +170,6 @@ class ModelEnergyProperties(BaseModel):

terrain_type: TerrianTypes = TerrianTypes.city

construction_sets: List[ConstructionSetAbridged] = Field(
default=None,
description='List of all ConstructionSets in the Model.'
)

global_construction_set: str = Field(
default=None,
min_length=1,
Expand All @@ -179,6 +179,11 @@ class ModelEnergyProperties(BaseModel):
'ConstructionSet must appear under the Model construction_sets.'
)

construction_sets: List[ConstructionSetAbridged] = Field(
default=None,
description='List of all ConstructionSets in the Model.'
)

constructions: List[Union[OpaqueConstructionAbridged, WindowConstructionAbridged,
ShadeConstruction]] = Field(
...,
Expand All @@ -197,15 +202,20 @@ class ModelEnergyProperties(BaseModel):
'materials needed to make the Model constructions.'
)

program_types: List[ProgramTypeAbridged] = Field(
hvacs: List[IdealAirSystemAbridged] = Field(
default=None,
description='List of all ProgramTypes in the Model.'
)

program_types: List[ProgramTypeAbridged] = Field(
default=None,
description='List of all HVAC systems in the Model.'
)

schedules: List[Union[ScheduleRulesetAbridged, ScheduleFixedIntervalAbridged]] = Field(
default=None,
description='A list of all unique schedules in the model. This includes '
'schedules across all ProgramTypes, Rooms, and Shades.'
'schedules across all HVAC systems, ProgramTypes, Rooms, and Shades.'
)

schedule_type_limits: List[ScheduleTypeLimit] = Field(
Expand Down
13 changes: 9 additions & 4 deletions honeybee_schema/samples/ideal_air_detailed.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
{
"type": "IdealAirSystem",
"heating_limit": 2000.0,
"cooling_limit": 3500.0,
"type": "IdealAirSystemAbridged",
"name": "Passive House HVAC System",
"economizer_type": "DifferentialEnthalpy",
"demand_controlled_ventilation": true,
"sensible_heat_recovery": 0.75,
"latent_heat_recovery": 0.6
"latent_heat_recovery": 0.6,
"heating_air_temperature": 40.0,
"cooling_air_temperature": 15.0,
"heating_limit": 2000.0,
"cooling_limit": 3500.0,
"heating_availability": "HVAC Control",
"cooling_availability": "HVAC Control"
}
Loading

0 comments on commit ad86c49

Please sign in to comment.