@@ -952,7 +952,7 @@ def defaultConstructionSet(s=None):
952952
953953
954954def are_standardOpaqueLayers (lc = None ) -> bool :
955- """Validates if every material in a layered construction is standard & opaque.
955+ """Validates if every material in a layered construction is standard/ opaque.
956956
957957 Args:
958958 lc (openstudio.model.LayeredConstruction):
@@ -1002,7 +1002,7 @@ def thickness(lc=None) -> float:
10021002 return d
10031003
10041004
1005- def glazingAirFilmRSi (usi = 5.85 ):
1005+ def glazingAirFilmRSi (usi = 5.85 ) -> float :
10061006 """Returns total air film resistance of a fenestrated construction (m2•K/W).
10071007
10081008 Args:
@@ -1180,7 +1180,7 @@ def insulatingLayer(lc=None) -> dict:
11801180 return res
11811181
11821182
1183- def is_spandrel (s = None ):
1183+ def is_spandrel (s = None ) -> bool :
11841184 """Validates whether opaque surface can be considered as a curtain wall
11851185 (or similar technology) spandrel, regardless of construction layers, by
11861186 looking up AdditionalProperties or its identifier.
@@ -1217,7 +1217,7 @@ def is_spandrel(s=None):
12171217 return "spandrel" in s .nameString ().lower ()
12181218
12191219
1220- def is_fenestration (s = None ):
1220+ def is_fenestration (s = None ) -> bool :
12211221 """Validates whether a sub surface is fenestrated.
12221222
12231223 Args:
@@ -1249,7 +1249,31 @@ def is_fenestration(s=None):
12491249 return True
12501250
12511251
1252- def scheduleRulesetMinMax (sched = None ):
1252+ def has_airLoopsHVAC (model = None ) -> bool :
1253+ """Validates if model has zones with HVAC air loops.
1254+
1255+ Args:
1256+ model (openstudio.model.Model):
1257+ An OpenStudio model.
1258+
1259+ Returns:
1260+ bool: Whether model has HVAC air loops.
1261+ False: If invalid input (see logs).
1262+ """
1263+ mth = "osut.has_airLoopsHVAC"
1264+ cl = openstudio .model .Model
1265+
1266+ if not isinstance (model , cl ):
1267+ return oslg .mismatch ("model" , model , cl , mth , CN .DBG , False )
1268+
1269+ for zone in model .getThermalZones ():
1270+ if zone .canBePlenum (): continue
1271+ if zone .airLoopHVACs () or zone .isPlenum (): return True
1272+
1273+ return False
1274+
1275+
1276+ def scheduleRulesetMinMax (sched = None ) -> dict :
12531277 """Returns MIN/MAX values of a schedule (ruleset).
12541278
12551279 Args:
@@ -1272,7 +1296,7 @@ def scheduleRulesetMinMax(sched=None):
12721296 res = dict (min = None , max = None )
12731297
12741298 if not isinstance (sched , cl ):
1275- return oslg .invalid ("sched" , mth , 0 , CN .DBG , res )
1299+ return oslg .mismatch ("sched" , sched , cl , mth , CN .DBG , res )
12761300
12771301 values = list (sched .defaultDaySchedule ().values ())
12781302
@@ -1294,6 +1318,134 @@ def scheduleRulesetMinMax(sched=None):
12941318 return res
12951319
12961320
1321+ def scheduleConstantMinMax (sched = None ) -> dict :
1322+ """Returns MIN/MAX values of a schedule (constant).
1323+
1324+ Args:
1325+ sched (openstudio.model.ScheduleConstant):
1326+ A schedule.
1327+
1328+ Returns:
1329+ dict:
1330+ - "min" (float): min temperature. (None if invalid inputs - see logs).
1331+ - "max" (float): max temperature. (None if invalid inputs - see logs).
1332+ """
1333+ # Largely inspired from David Goldwasser's
1334+ # "schedule_constant_annual_min_max_value":
1335+ #
1336+ # github.com/NREL/openstudio-standards/blob/
1337+ # 99cf713750661fe7d2082739f251269c2dfd9140/lib/openstudio-standards/
1338+ # standards/Standards.ScheduleConstant.rb#L21
1339+ mth = "osut.scheduleConstantMinMax"
1340+ cl = openstudio .model .ScheduleConstant
1341+ res = dict (min = None , max = None )
1342+
1343+ if not isinstance (sched , cl ):
1344+ return oslg .mismatch ("sched" , sched , cl , mth , CN .DBG , res )
1345+
1346+ try :
1347+ value = float (sched .value ())
1348+ except :
1349+ return None
1350+
1351+ res ["min" ] = value
1352+ res ["max" ] = value
1353+
1354+ return res
1355+
1356+
1357+ def scheduleCompactMinMax (sched = None ) -> dict :
1358+ """Returns MIN/MAX values of a schedule (compact).
1359+
1360+ Args:
1361+ sched (openstudio.model.ScheduleCompact):
1362+ A schedule.
1363+
1364+ Returns:
1365+ dict:
1366+ - "min" (float): min temperature. (None if invalid inputs - see logs).
1367+ - "max" (float): max temperature. (None if invalid inputs - see logs).
1368+ """
1369+ # Largely inspired from Andrew Parker's
1370+ # "schedule_compact_annual_min_max_value":
1371+ #
1372+ # github.com/NREL/openstudio-standards/blob/
1373+ # 99cf713750661fe7d2082739f251269c2dfd9140/lib/openstudio-standards/
1374+ # standards/Standards.ScheduleCompact.rb#L8
1375+ mth = "osut.scheduleCompactMinMax"
1376+ cl = openstudio .model .ScheduleCompact
1377+ vals = []
1378+ prev = ""
1379+ res = dict (min = None , max = None )
1380+
1381+ if not isinstance (sched , cl ):
1382+ return oslg .mismatch ("sched" , sched , cl , mth , CN .DBG , res )
1383+
1384+ for eg in sched .extensibleGroups ():
1385+ if "until" in prev :
1386+ if eg .getDouble (0 ): vals .append (eg .getDouble (0 ).get ())
1387+
1388+ str = eg .getString (0 )
1389+
1390+ if str : prev = str .get ().lower ()
1391+
1392+ if not vals :
1393+ return oslg .empty ("compact sched values" , mth , CN .WRN , res )
1394+
1395+ res ["min" ] = min (vals )
1396+ res ["max" ] = max (vals )
1397+
1398+ try :
1399+ res ["min" ] = float (res ["min" ])
1400+ except :
1401+ res ["min" ] = None
1402+
1403+ try :
1404+ res ["max" ] = float (res ["max" ])
1405+ except :
1406+ res ["max" ] = None
1407+
1408+ return res
1409+
1410+
1411+ def scheduleIntervalMinMax (sched = None ) -> dict :
1412+ """Returns MIN/MAX values of a schedule (interval).
1413+
1414+ Args:
1415+ sched (openstudio.model.ScheduleInterval):
1416+ A schedule.
1417+
1418+ Returns:
1419+ dict:
1420+ - "min" (float): min temperature. (None if invalid inputs - see logs).
1421+ - "max" (float): max temperature. (None if invalid inputs - see logs).
1422+ """
1423+ mth = "osut.scheduleCompactMinMax"
1424+ cl = openstudio .model .ScheduleInterval
1425+ vals = []
1426+ res = dict (min = None , max = None )
1427+
1428+ if not isinstance (sched , cl ):
1429+ return oslg .mismatch ("sched" , sched , cl , mth , CN .DBG , res )
1430+
1431+ vals = sched .timeSeries ().values ()
1432+
1433+ res ["min" ] = min (values )
1434+ res ["max" ] = max (values )
1435+
1436+ try :
1437+ res ["min" ] = float (res ["min" ])
1438+ except :
1439+ res ["min" ] = None
1440+
1441+ try :
1442+ res ["max" ] = float (res ["max" ])
1443+ except :
1444+ res ["max" ] = None
1445+
1446+ return res
1447+
1448+
12971449def transforms (group = None ) -> dict :
12981450 """"Returns OpenStudio site/space transformation & rotation angle.
12991451
0 commit comments