From 31fe98c30148c6e918474ccc2e5f6a20204bc9cd Mon Sep 17 00:00:00 2001 From: brgix Date: Tue, 5 Aug 2025 11:10:25 -0400 Subject: [PATCH 01/25] Tweaks 'genConstruction' (tested) --- src/osut/osut.py | 80 +++++++++++++++++++++++++--------------------- tests/test_osut.py | 35 ++++++++++++++++++++ 2 files changed, 78 insertions(+), 37 deletions(-) diff --git a/src/osut/osut.py b/src/osut/osut.py index deaa4fb..e23f458 100644 --- a/src/osut/osut.py +++ b/src/osut/osut.py @@ -107,8 +107,8 @@ class _CN: # Default (~1980s) envelope Uo (W/m2•K), based on surface type. _uo = dict( - shading = None, # N/A - partition = None, # N/A + shading = None, # N/A + partition = None, # N/A wall = 0.384, # rated R14.8 hr•ft2F/Btu roof = 0.327, # rated R17.6 hr•ft2F/Btu floor = 0.317, # rated R17.9 hr•ft2F/Btu (exposed floor) @@ -335,9 +335,8 @@ def genConstruction(model=None, specs=dict()): ide = "OSut.CON." + specs["type"] if specs["type"] not in uo(): return oslg.invalid("surface type", mth, 2, CN.ERR) - if "uo" not in specs: - specs["uo"] = uo()[ specs["type"] ] + if "uo" not in specs: specs["uo"] = uo()[ specs["type"] ] # can be None u = specs["uo"] if u: @@ -348,6 +347,8 @@ def genConstruction(model=None, specs=dict()): if u < 0: return oslg.negative(id + " Uo", mth, CN.ERR) + if round(u, 2) == 0: + return oslg.zero(id + " Uo", mth, CN.ERR) if u > 5.678: return oslg.invalid(id + " Uo (> 5.678)", mth, 2, CN.ERR) @@ -581,7 +582,7 @@ def genConstruction(model=None, specs=dict()): a["compo" ]["id" ] = "OSut." + mt + ".%03d" % int(d * 1000) elif specs["type"] == "window": - a["glazing"]["u" ] = specs["uo"] + a["glazing"]["u" ] = u if u else uo()["window"] a["glazing"]["shgc"] = 0.450 if "shgc" in specs: a["glazing"]["shgc"] = specs["shgc"] a["glazing"]["id" ] = "OSut.window" @@ -589,7 +590,7 @@ def genConstruction(model=None, specs=dict()): a["glazing"]["id" ] += ".SHGC%d" % (a["glazing"]["shgc"]*100) elif specs["type"] == "skylight": - a["glazing"]["u" ] = specs["uo"] + a["glazing"]["u" ] = u if u else uo()["skylight"] a["glazing"]["shgc"] = 0.450 if "shgc" in specs: a["glazing"]["shgc"] = specs["shgc"] a["glazing"]["id" ] = "OSut.skylight" @@ -599,14 +600,14 @@ def genConstruction(model=None, specs=dict()): if a["glazing"]: layers = openstudio.model.FenestrationMaterialVector() - u = a["glazing"]["u" ] + u0 = a["glazing"]["u" ] shgc = a["glazing"]["shgc"] lyr = model.getSimpleGlazingByName(a["glazing"]["id"]) if lyr: lyr = lyr.get() else: - lyr = openstudio.model.SimpleGlazing(model, u, shgc) + lyr = openstudio.model.SimpleGlazing(model, u0, shgc) lyr.setName(a["glazing"]["id"]) layers.append(lyr) @@ -635,49 +636,54 @@ def genConstruction(model=None, specs=dict()): layers.append(lyr) - c = openstudio.model.Construction(layers) + c = openstudio.model.Construction(layers) c.setName(ide) # Adjust insulating layer thickness or conductivity to match requested Uo. - if not a["glazing"]: - ro = 1 / specs["uo"] - film()[specs["type"]] if specs["uo"] else 0 + if u and not a["glazing"]: + ro = 1 / u - flm - if specs["type"] == "door": # 1x layer, adjust conductivity - layer = c.getLayer(0).to_StandardOpaqueMaterial() + if ro > 0: + if specs["type"] == "door": # 1x layer, adjust conductivity + layer = c.getLayer(0).to_StandardOpaqueMaterial() - if not layer: - return oslg.invalid(id + " standard material?", mth, 0) + if not layer: + return oslg.invalid(id + " standard material?", mth, 0) - layer = layer.get() - k = layer.thickness() / ro - layer.setConductivity(k) + layer = layer.get() + k = layer.thickness() / ro + layer.setConductivity(k) - elif ro > 0: # multiple layers, adjust insulating layer thickness - lyr = insulatingLayer(c) + else: # multiple layers, adjust insulating layer thickness + lyr = insulatingLayer(c) - if not lyr["index"] or not lyr["type"] or not lyr["r"]: - return oslg.invalid(id + " construction", mth, 0) + if not lyr["index"] or not lyr["type"] or not lyr["r"]: + return oslg.invalid(id + " construction", mth, 0) - index = lyr["index"] - layer = c.getLayer(index).to_StandardOpaqueMaterial() + index = lyr["index"] + layer = c.getLayer(index).to_StandardOpaqueMaterial() - if not layer: - return oslg.invalid(id + " material %d" % index, mth, 0) + if not layer: + return oslg.invalid(id + " material %d" % index, mth, 0) - layer = layer.get() - k = layer.conductivity() - d = (ro - rsi(c) + lyr["r"]) * k + layer = layer.get() + k = layer.conductivity() + d = (ro - rsi(c) + lyr["r"]) * k - if d < 0.03: - return oslg.invalid(id + " adjusted material thickness", mth, 0) + if d < 0.03: + m = id + " adjusted material thickness" + return oslg.invalid(m, mth, 0) - nom = re.sub(r'[^a-zA-Z]', '', layer.nameString()) - nom = re.sub(r'OSut', '', nom) - nom = "OSut." + nom + ".%03d" % int(d * 1000) + nom = re.sub(r'[^a-zA-Z]', '', layer.nameString()) + nom = re.sub(r'OSut', '', nom) + nom = "OSut." + nom + ".%03d" % int(d * 1000) - if not model.getStandardOpaqueMaterialByName(nom): - layer.setName(nom) - layer.setThickness(d) + if model.getStandardOpaqueMaterialByName(nom): + omat = model.getStandardOpaqueMaterialByName(nom).get() + c.setLayer(index, omat) + else: + layer.setName(nom) + layer.setThickness(d) return c diff --git a/tests/test_osut.py b/tests/test_osut.py index 76d1378..1799461 100644 --- a/tests/test_osut.py +++ b/tests/test_osut.py @@ -649,6 +649,41 @@ def test05_construction_generation(self): self.assertEqual(o.status(), 0) del model + # Invalid Uo (here, skylights and windows inherit default Uo values) + specs = dict(type="skylight", uo=None) + model = openstudio.model.Model() + c = osut.genConstruction(model, specs) + self.assertEqual(o.status(), 0) + self.assertFalse(o.logs()) + self.assertTrue(c) + self.assertTrue(isinstance(c, openstudio.model.Construction)) + self.assertEqual(c.nameString(), "OSut.CON.skylight") + self.assertTrue(c.layers()) + self.assertEqual(len(c.layers()), 1) + self.assertEqual(c.layers()[0].nameString(), "OSut.skylight.U3.5.SHGC45") + r = osut.rsi(c) + self.assertAlmostEqual(r, 1/osut.uo()["skylight"], places=3) + self.assertFalse(o.logs()) + self.assertEqual(o.status(), 0) + del model + + # Invalid Uo (here, Uo-adjustments are ignored altogether) + specs = dict(type="wall", uo=None) + model = openstudio.model.Model() + c = osut.genConstruction(model, specs) + self.assertEqual(o.status(), 0) + self.assertFalse(o.logs()) + self.assertTrue(c) + self.assertTrue(isinstance(c, openstudio.model.Construction)) + self.assertEqual(c.nameString(), "OSut.CON.wall") + self.assertTrue(c.layers()) + self.assertEqual(len(c.layers()), 4) + r = osut.rsi(c) + self.assertAlmostEqual(1/r, 2.23, places=2) # not matching any defaults + self.assertFalse(o.logs()) + self.assertEqual(o.status(), 0) + del model + def test06_internal_mass(self): o = osut.oslg self.assertEqual(o.status(), 0) From 0ca5976e74cf96b16d37908a13a229bc1a93c25c Mon Sep 17 00:00:00 2001 From: brgix Date: Wed, 6 Aug 2025 09:54:23 -0400 Subject: [PATCH 02/25] Fixes ScheduleInterval methods/tests --- src/osut/osut.py | 33 +++++++++++++++++++++++++++------ tests/test_osut.py | 38 ++++++++++++++++++++++++++++---------- 2 files changed, 55 insertions(+), 16 deletions(-) diff --git a/src/osut/osut.py b/src/osut/osut.py index e23f458..5cc36f3 100644 --- a/src/osut/osut.py +++ b/src/osut/osut.py @@ -1656,7 +1656,7 @@ def scheduleIntervalMinMax(sched=None) -> dict: - "min" (float): min temperature. (None if invalid inputs - see logs). - "max" (float): max temperature. (None if invalid inputs - see logs). """ - mth = "osut.scheduleCompactMinMax" + mth = "osut.scheduleIntervalMinMax" cl = openstudio.model.ScheduleInterval vals = [] res = dict(min=None, max=None) @@ -1664,10 +1664,20 @@ def scheduleIntervalMinMax(sched=None) -> dict: if not isinstance(sched, cl): return oslg.mismatch("sched", sched, cl, mth, CN.DBG, res) - vals = sched.timeSeries().values() + values = sched.timeSeries().values() + length = len(values) - res["min"] = min(values) - res["max"] = max(values) + for i in range(length): + try: + value = float(values[i]) + value = vals.append(value) + except: + oslg.invalid("numerical at %d" % i, mth, 1, CN.ERR) + + if not vals: return res + + res["min"] = min(vals) + res["max"] = max(vals) try: res["min"] = float(res["min"]) @@ -2601,6 +2611,17 @@ def availabilitySchedule(model=None, avl=""): return schedule +# ---- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---- # +# This final set of utilities targets OpenStudio geometry. Many of the +# following geometry methods rely on Boost as an OpenStudio dependency. +# As per Boost requirements, points (e.g. vertical polygon) must be 'aligned': +# - first rotated/tilted as to lay flat along XY plane (Z-axis ~= 0) +# - initial Z-axis values now become Y-axis values +# - points with the lowest X-axis values are 'aligned' along X-axis (0) +# - points with the lowest Z-axis values are 'aligned' along Y-axis (0) +# - for several Boost methods, points must be clockwise in sequence +# +# Check OSut's poly() method, which offers such Boost-related options. def transforms(group=None) -> dict: """"Returns OpenStudio site/space transformation & rotation angle. @@ -2704,7 +2725,7 @@ def p3Dv(pts=None) -> openstudio.Point3dVector: pts (list): OpenStudio 3D points. Returns: - openstudio.Point3dVector: Vector of 3D points (see logs if empty). + openstudio.Point3dVector: Vector of 3D points (see 'p3Dv' logs if empty). """ mth = "osut.p3Dv" @@ -6085,7 +6106,7 @@ def genSlab(pltz=[], z=0) -> openstudio.Point3dVector: slb = vtx # Once joined, re-adjust Z-axis coordinates. - if abs(z) > CN.TOL: + if round(z, 2) != 0.00: vtx = openstudio.Point3dVector() for pt in slb: vtx.append(openstudio.Point3d(pt.x(), pt.y(), z)) diff --git a/tests/test_osut.py b/tests/test_osut.py index 1799461..521aa7c 100644 --- a/tests/test_osut.py +++ b/tests/test_osut.py @@ -392,7 +392,7 @@ def test05_construction_generation(self): self.assertEqual(o.status(), 0) del model - # Insulated (conditioned), parking garage roof (polyiso under 8" slab). + # Roof above conditioned parking garage (polyiso under 8" slab). specs = dict(type="roof", uo=0.214, clad="heavy", frame="medium", finish="none") model = openstudio.model.Model() c = osut.genConstruction(model, specs) @@ -1731,9 +1731,27 @@ def test17_minmax_heatcool_setpoints(self): self.assertTrue(cc.setTemperatureCalculationRequestedAfterLayerNumber(1)) self.assertTrue(floor.setConstruction(cc)) + # Test 'fixed interval' schedule. Annual time series - no variation. + start = model.getYearDescription().makeDate(1, 1) + inter = openstudio.Time(0, 1, 0, 0) + values = openstudio.createVector([22.78] * 8760) + series = openstudio.TimeSeries(start, inter, values, "") + limits = openstudio.model.ScheduleTypeLimits(model) + limits.setName("Radiant Electric Heating Setpoint Schedule Type Limits") + self.assertTrue(limits.setNumericType("Continuous")) + self.assertTrue(limits.setUnitType("Temperature")) + + schedule = openstudio.model.ScheduleFixedInterval(model) + schedule.setName("Radiant Electric Heating Setpoint Schedule") + self.assertTrue(schedule.setTimeSeries(series)) + self.assertTrue(schedule.setTranslatetoScheduleFile(False)) + self.assertTrue(schedule.setScheduleTypeLimits(limits)) + + tvals = schedule.timeSeries().values() + self.assertTrue(isinstance(tvals, openstudio.Vector)) + for i in range(len(tvals)): self.assertTrue(isinstance(tvals[i], float)) + availability = osut.availabilitySchedule(model) - schedule = openstudio.model.ScheduleConstant(model) - self.assertTrue(schedule.setValue(22.78)) # reuse cooling setpoint # Create radiant electric heating. ht = (openstudio.model.ZoneHVACLowTemperatureRadiantElectric( @@ -5384,15 +5402,15 @@ def test35_facet_retrieval(self): translator = openstudio.osversion.VersionTranslator() - path = openstudio.path("./tests/files/osms/out/seb2.osm") + path = openstudio.path("./tests/files/osms/out/seb_ext2.osm") model = translator.loadModel(path) self.assertTrue(model) model = model.get() spaces = model.getSpaces() surfs = model.getSurfaces() subs = model.getSubSurfaces() - self.assertEqual(len(surfs), 56) - self.assertEqual(len(subs), 8) + self.assertEqual(len(surfs), 59) + self.assertEqual(len(subs), 14) # The solution is similar to: # OpenStudio::Model::Space::findSurfaces(minDegreesFromNorth, @@ -5416,15 +5434,15 @@ def test35_facet_retrieval(self): roofs1 = osut.facets(spaces, "Outdoors", "RoofCeiling", "top") roofs2 = osut.facets(spaces, "Outdoors", "RoofCeiling", "foo") - self.assertEqual(len(windows), 8) - self.assertEqual(len(skylights), 0) - self.assertEqual(len(walls), 26) + self.assertEqual(len(windows), 11) + self.assertEqual(len(skylights), 3) + self.assertEqual(len(walls), 28) self.assertFalse(northsouth) self.assertEqual(len(northeast), 8) self.assertEqual(len(north), 14) self.assertEqual(len(floors1a), 4) self.assertEqual(len(floors1b), 4) - self.assertEqual(len(roofs1), 4) + self.assertEqual(len(roofs1), 5) self.assertFalse(roofs2) # Concise variants, same output. In the SEB model, floors face "Ground". From 01f0f11deed776c4c4705b249bf7e40f3cbda7b0 Mon Sep 17 00:00:00 2001 From: brgix Date: Wed, 6 Aug 2025 10:07:01 -0400 Subject: [PATCH 03/25] Tweaks ScheduleInterval fix --- src/osut/osut.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/osut/osut.py b/src/osut/osut.py index 5cc36f3..adf437a 100644 --- a/src/osut/osut.py +++ b/src/osut/osut.py @@ -1665,12 +1665,11 @@ def scheduleIntervalMinMax(sched=None) -> dict: return oslg.mismatch("sched", sched, cl, mth, CN.DBG, res) values = sched.timeSeries().values() - length = len(values) - for i in range(length): + for i in range(len(values)): try: value = float(values[i]) - value = vals.append(value) + vals.append(value) except: oslg.invalid("numerical at %d" % i, mth, 1, CN.ERR) From f36e9a240dd6e8b920ae05cdeb5693b30094a158 Mon Sep 17 00:00:00 2001 From: brgix Date: Sat, 9 Aug 2025 08:08:51 -0400 Subject: [PATCH 04/25] Tweaks line intersection + tests --- src/osut/osut.py | 14 +++++++------- tests/test_osut.py | 15 +++++++++++++-- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/osut/osut.py b/src/osut/osut.py index adf437a..b013037 100644 --- a/src/osut/osut.py +++ b/src/osut/osut.py @@ -3470,13 +3470,13 @@ def lineIntersection(s1=[], s2=[]): xa1b1 = a.cross(a1b1) xa1b2 = a.cross(a1b2) - if xa1b1.length() < CN.TOL2: - if isPointAlongSegment(a1, [a2, b1]): return None - if isPointAlongSegment(a2, [a1, b1]): return None - - if xa1b2.length() < CN.TOL2: - if isPointAlongSegment(a1, [a2, b2]): return None - if isPointAlongSegment(a2, [a1, b2]): return None + # if xa1b1.length() < CN.TOL2: + # if isPointAlongSegment(a1, [a2, b1]): return None + # if isPointAlongSegment(a2, [a1, b1]): return None + # + # if xa1b2.length() < CN.TOL2: + # if isPointAlongSegment(a1, [a2, b2]): return None + # if isPointAlongSegment(a2, [a1, b2]): return None # Both segment endpoints can't be 'behind' point. if a.dot(a1b1) < 0 and a.dot(a1b2) < 0: return None diff --git a/tests/test_osut.py b/tests/test_osut.py index 521aa7c..bb1b67f 100644 --- a/tests/test_osut.py +++ b/tests/test_osut.py @@ -3659,7 +3659,7 @@ def test26_ulc_blc(self): # [70, 0, 0] # [70, 45, 0] # [ 0, 45, 0] - + def test27_polygon_attributes(self): o = osut.oslg self.assertEqual(o.status(), 0) @@ -5627,7 +5627,7 @@ def test36_slab_generation(self): self.assertEqual(len(surface.vertices()), 12) self.assertAlmostEqual(surface.grossArea(), 5 * 20 - 1, places=2) - # --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- # + # --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- # # Same as previous, yet overlapping 'plate' has both negative dX & dY, # while XY origin is set at top-right (not bottom-left) corner. # ____ ____ @@ -5655,6 +5655,17 @@ def test36_slab_generation(self): self.assertEqual(o.status(), 0) del model + # --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- # + # Invalid input case. + plates = ["osut"] + slab = osut.genSlab(plates, z0) + self.assertTrue(o.is_debug()) + self.assertEqual(len(o.logs()), 1) + self.assertTrue("str? expecting dict" in o.logs()[0]["message"]) + self.assertTrue(isinstance(slab, openstudio.Point3dVector)) + self.assertFalse(slab) + self.assertEqual(o.clean(), DBG) + def test37_roller_shades(self): o = osut.oslg self.assertEqual(o.status(), 0) From d4634bead68bf58083fdb79e3324fa61656eb0ff Mon Sep 17 00:00:00 2001 From: brgix Date: Sat, 9 Aug 2025 08:23:47 -0400 Subject: [PATCH 05/25] Deletes commented out lines --- src/osut/osut.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/osut/osut.py b/src/osut/osut.py index b013037..cea37cf 100644 --- a/src/osut/osut.py +++ b/src/osut/osut.py @@ -3470,14 +3470,6 @@ def lineIntersection(s1=[], s2=[]): xa1b1 = a.cross(a1b1) xa1b2 = a.cross(a1b2) - # if xa1b1.length() < CN.TOL2: - # if isPointAlongSegment(a1, [a2, b1]): return None - # if isPointAlongSegment(a2, [a1, b1]): return None - # - # if xa1b2.length() < CN.TOL2: - # if isPointAlongSegment(a1, [a2, b2]): return None - # if isPointAlongSegment(a2, [a1, b2]): return None - # Both segment endpoints can't be 'behind' point. if a.dot(a1b1) < 0 and a.dot(a1b2) < 0: return None From a57c25c00f629ad1f8efc600d1183cb28ec884cb Mon Sep 17 00:00:00 2001 From: brgix Date: Sat, 9 Aug 2025 15:16:26 -0400 Subject: [PATCH 06/25] Harmonizes n 'uniques' vs n 'collinears' --- src/osut/osut.py | 33 ++++++----------- tests/test_osut.py | 88 +++++++++++++++++++++++++++++++++++++++------- 2 files changed, 86 insertions(+), 35 deletions(-) diff --git a/src/osut/osut.py b/src/osut/osut.py index cea37cf..9e999e4 100644 --- a/src/osut/osut.py +++ b/src/osut/osut.py @@ -3205,7 +3205,8 @@ def uniques(pts=None, n=0) -> openstudio.Point3dVector: try: n = int(n) except: - return oslg.mismatch("n unique points", n, int, mth, CN.DBG, v) + oslg.mismatch("n points", n, int, mth, CN.DBG) + n = 0 for pt in pts: if not holds(v, pt): v.append(pt) @@ -3659,11 +3660,10 @@ def nonCollinears(pts=None, n=0) -> openstudio.Point3dVector: Requested number of non-collinears (0 returns all). Returns: - openstudio.Point3dVector: non-collinears (see logs if empty). + openstudio.Point3dVector: non-collinears (see logs). """ mth = "osut.nonCollinears" - v = openstudio.Point3dVector() a = [] pts = uniques(pts) if len(pts) < 3: return pts @@ -3671,12 +3671,8 @@ def nonCollinears(pts=None, n=0) -> openstudio.Point3dVector: try: n = int(n) except: - oslg.mismatch("n non-collinears", n, int, mth, CN.DBG, v) - - if n > len(pts): - return oslg.invalid("+n non-collinears", mth, 0, CN.ERR, v) - elif n < 0 and abs(n) > len(pts): - return oslg.invalid("-n non-collinears", mth, 0, CN.ERR, v) + oslg.mismatch("n points", n, int, mth, CN.DBG) + n = 0 # Evaluate cross product of vectors of 3x sequential points. for i2, p2 in enumerate(pts): @@ -3698,9 +3694,7 @@ def nonCollinears(pts=None, n=0) -> openstudio.Point3dVector: a.rotate(1) a = list(a) - if n > len(a): return p3Dv(a) - if n < 0 and abs(n) > len(a): return p3Dv(a) - + if abs(n) > len(a): n = 0 if n > 0: a = a[0:n] if n < 0: a = a[n:] @@ -3718,11 +3712,10 @@ def collinears(pts=None, n=0) -> openstudio.Point3dVector: Requested number of collinears (0 returns all). Returns: - openstudio.Point3dVector: collinears (see logs if empty). + openstudio.Point3dVector: collinears (see logs). """ mth = "osut.collinears" - v = openstudio.Point3dVector() a = [] pts = uniques(pts) if len(pts) < 3: return pts @@ -3730,12 +3723,8 @@ def collinears(pts=None, n=0) -> openstudio.Point3dVector: try: n = int(n) except: - oslg.mismatch("n collinears", n, int, mth, CN.DBG, v) - - if n > len(pts): - return oslg.invalid("+n collinears", mth, 0, CN.ERR, v) - elif n < 0 and abs(n) > len(pts): - return oslg.invalid("-n collinears", mth, 0, CN.ERR, v) + oslg.mismatch("n points", n, int, mth, CN.DBG) + n = 0 ncolls = nonCollinears(pts) if not ncolls: return pts @@ -3743,9 +3732,7 @@ def collinears(pts=None, n=0) -> openstudio.Point3dVector: for pt in pts: if pt not in ncolls: a.append(pt) - if n > len(a): return p3Dv(a) - if n < 0 and abs(n) > len(a): return p3Dv(a) - + if abs(n) > len(a): n = 0 if n > 0: a = a[0:n] if n < 0: a = a[n:] diff --git a/tests/test_osut.py b/tests/test_osut.py index bb1b67f..24bd44e 100644 --- a/tests/test_osut.py +++ b/tests/test_osut.py @@ -3308,48 +3308,112 @@ def test25_segments_triads_orientation(self): p7 = openstudio.Point3d(14, 20, -5) p8 = openstudio.Point3d(-9, -9, -5) - # Stress tests. - m1 = "Invalid '+n collinears' (osut.collinears)" - m2 = "Invalid '-n collinears' (osut.collinears)" + # Stress test 'uniques'. + m0 = "'n points' str? expecting int (osut.uniques)" + + # Invalid case. + uniks = osut.uniques([p0, p1, p2, p3], "osut") + self.assertTrue(isinstance(uniks, openstudio.Point3dVector)) + self.assertEqual(len(uniks), 4) + self.assertTrue(o.is_debug()) + self.assertEqual(len(o.logs()), 1) + self.assertEqual(o.logs()[0]["message"], m0) + self.assertEqual(o.clean(), DBG) + + # Valid, basic case. + uniks = osut.uniques([p0, p1, p2, p3]) + self.assertTrue(isinstance(uniks, openstudio.Point3dVector)) + self.assertEqual(len(uniks), 4) + self.assertEqual(o.status(), 0) + + uniks = osut.uniques([p0, p1, p2, p3], 0) + self.assertTrue(isinstance(uniks, openstudio.Point3dVector)) + self.assertEqual(len(uniks), 4) + self.assertEqual(o.status(), 0) + + # Valid, first 3 points. + uniks = osut.uniques([p0, p1, p2, p3], 3) + self.assertTrue(isinstance(uniks, openstudio.Point3dVector)) + self.assertEqual(len(uniks), 3) + self.assertEqual(o.status(), 0) + + # Valid, last 3 points. + uniks = osut.uniques([p0, p1, p2, p3], -3) + self.assertTrue(isinstance(uniks, openstudio.Point3dVector)) + self.assertEqual(len(uniks), 3) + self.assertEqual(o.status(), 0) + + # Valid, n = 5: returns original 4 uniques points. + uniks = osut.uniques([p0, p1, p2, p3], 5) + self.assertTrue(isinstance(uniks, openstudio.Point3dVector)) + self.assertEqual(len(uniks), 4) + self.assertEqual(o.status(), 0) + + # Valid, n = -5: returns original 4 uniques points. + uniks = osut.uniques([p0, p1, p2, p3], -5) + self.assertTrue(isinstance(uniks, openstudio.Point3dVector)) + self.assertEqual(len(uniks), 4) + self.assertEqual(o.status(), 0) + + # Stress tests collinears. + m0 = "'n points' str? expecting int (osut.collinears)" + + # Invalid case - raise DEBUG message, yet returns valid collinears. + collinears = osut.collinears([p0, p1, p3, p8], "osut") + self.assertTrue(isinstance(collinears, openstudio.Point3dVector)) + self.assertEqual(len(collinears), 1) + self.assertTrue(osut.areSame(collinears[0], p0)) + self.assertTrue(o.is_debug()) + self.assertEqual(len(o.logs()), 1) + self.assertEqual(o.logs()[0]["message"], m0) + self.assertEqual(o.clean(), DBG) + # Valid, basic case collinears = osut.collinears([p0, p1, p3, p8]) self.assertEqual(len(collinears), 1) self.assertTrue(osut.areSame(collinears[0], p0)) + collinears = osut.collinears([p0, p1, p3, p8], 0) + self.assertEqual(len(collinears), 1) + self.assertTrue(osut.areSame(collinears[0], p0)) + collinears = osut.collinears([p0, p1, p2, p3, p8]) self.assertEqual(len(collinears), 2) self.assertTrue(osut.areSame(collinears[0], p0)) self.assertTrue(osut.areSame(collinears[1], p1)) + # Only 2 collinears, so request for first 3 is ignored. collinears = osut.collinears([p0, p1, p2, p3, p8], 3) self.assertEqual(len(collinears), 2) self.assertTrue(osut.areSame(collinears[0], p0)) self.assertTrue(osut.areSame(collinears[1], p1)) + # First collinear (out of 2). collinears = osut.collinears([p0, p1, p2, p3, p8], 1) self.assertEqual(len(collinears), 1) self.assertTrue(osut.areSame(collinears[0], p0)) + # Last collinear (out of 2). collinears = osut.collinears([p0, p1, p2, p3, p8], -1) self.assertEqual(len(collinears), 1) self.assertTrue(osut.areSame(collinears[0], p1)) + # First two vs last two: same result. collinears = osut.collinears([p0, p1, p2, p3, p8], -2) self.assertEqual(len(collinears), 2) self.assertTrue(osut.areSame(collinears[0], p0)) self.assertTrue(osut.areSame(collinears[1], p1)) + # Ignore n request when abs(n) > number of actual collinears. collinears = osut.collinears([p0, p1, p2, p3, p8], 6) - self.assertTrue(o.is_error()) - self.assertEqual(len(o.logs()), 1) - self.assertEqual(o.logs()[0]["message"], m1) - self.assertEqual(o.clean(), DBG) + self.assertEqual(len(collinears), 2) + self.assertTrue(osut.areSame(collinears[0], p0)) + self.assertTrue(osut.areSame(collinears[1], p1)) collinears = osut.collinears([p0, p1, p2, p3, p8], -6) - self.assertTrue(o.is_error()) - self.assertEqual(len(o.logs()), 1) - self.assertEqual(o.logs()[0]["message"], m2) - self.assertEqual(o.clean(), DBG) + self.assertEqual(len(collinears), 2) + self.assertTrue(osut.areSame(collinears[0], p0)) + self.assertTrue(osut.areSame(collinears[1], p1)) # CASE a1: 2x end-to-end line segments (returns matching endpoints). self.assertTrue(osut.doesLineIntersect([p0, p1], [p1, p2])) @@ -3659,7 +3723,7 @@ def test26_ulc_blc(self): # [70, 0, 0] # [70, 45, 0] # [ 0, 45, 0] - + def test27_polygon_attributes(self): o = osut.oslg self.assertEqual(o.status(), 0) From 3c630f95f8b1b19c6507a871531b36de26f9806e Mon Sep 17 00:00:00 2001 From: brgix Date: Sun, 10 Aug 2025 14:52:08 -0400 Subject: [PATCH 07/25] Prep work for further harmonization with Ruby OSut --- src/osut/osut.py | 12 ++++++------ tests/test_osut.py | 8 +------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/osut/osut.py b/src/osut/osut.py index 9e999e4..0f1b27a 100644 --- a/src/osut/osut.py +++ b/src/osut/osut.py @@ -3194,7 +3194,7 @@ def uniques(pts=None, n=0) -> openstudio.Point3dVector: Requested number of unique points (0 returns all). Returns: - openstudio.Point3dVector: Unique points (see logs if empty). + openstudio.Point3dVector: Unique points (see logs). """ mth = "osut.uniques" @@ -3651,7 +3651,7 @@ def blc(pts=None) -> openstudio.Point3dVector: def nonCollinears(pts=None, n=0) -> openstudio.Point3dVector: - """Returns sequential non-collinear points in an OpenStudio 3D point vector. + """Returns non-collinear points in an OpenStudio 3D point vector. Args: pts (openstudio.Point3dVector): @@ -3703,7 +3703,7 @@ def nonCollinears(pts=None, n=0) -> openstudio.Point3dVector: def collinears(pts=None, n=0) -> openstudio.Point3dVector: """ - Returns sequential collinear points in an OpenStudio 3D point vector. + Returns collinear points in an OpenStudio 3D point vector. Args: pts (openstudio.Point3dVector): @@ -3716,7 +3716,7 @@ def collinears(pts=None, n=0) -> openstudio.Point3dVector: """ mth = "osut.collinears" - a = [] + a = openstudio.Point3dVector() pts = uniques(pts) if len(pts) < 3: return pts @@ -3727,7 +3727,7 @@ def collinears(pts=None, n=0) -> openstudio.Point3dVector: n = 0 ncolls = nonCollinears(pts) - if not ncolls: return pts + if not ncolls: return a for pt in pts: if pt not in ncolls: a.append(pt) @@ -3736,7 +3736,7 @@ def collinears(pts=None, n=0) -> openstudio.Point3dVector: if n > 0: a = a[0:n] if n < 0: a = a[n:] - return p3Dv(a) + return a def poly(pts=None, vx=False, uq=False, co=False, tt=False, sq="no") -> openstudio.Point3dVector: diff --git a/tests/test_osut.py b/tests/test_osut.py index 24bd44e..2178a20 100644 --- a/tests/test_osut.py +++ b/tests/test_osut.py @@ -3324,36 +3324,30 @@ def test25_segments_triads_orientation(self): uniks = osut.uniques([p0, p1, p2, p3]) self.assertTrue(isinstance(uniks, openstudio.Point3dVector)) self.assertEqual(len(uniks), 4) - self.assertEqual(o.status(), 0) uniks = osut.uniques([p0, p1, p2, p3], 0) self.assertTrue(isinstance(uniks, openstudio.Point3dVector)) self.assertEqual(len(uniks), 4) - self.assertEqual(o.status(), 0) # Valid, first 3 points. uniks = osut.uniques([p0, p1, p2, p3], 3) self.assertTrue(isinstance(uniks, openstudio.Point3dVector)) self.assertEqual(len(uniks), 3) - self.assertEqual(o.status(), 0) # Valid, last 3 points. uniks = osut.uniques([p0, p1, p2, p3], -3) self.assertTrue(isinstance(uniks, openstudio.Point3dVector)) self.assertEqual(len(uniks), 3) - self.assertEqual(o.status(), 0) # Valid, n = 5: returns original 4 uniques points. uniks = osut.uniques([p0, p1, p2, p3], 5) self.assertTrue(isinstance(uniks, openstudio.Point3dVector)) self.assertEqual(len(uniks), 4) - self.assertEqual(o.status(), 0) # Valid, n = -5: returns original 4 uniques points. uniks = osut.uniques([p0, p1, p2, p3], -5) self.assertTrue(isinstance(uniks, openstudio.Point3dVector)) self.assertEqual(len(uniks), 4) - self.assertEqual(o.status(), 0) # Stress tests collinears. m0 = "'n points' str? expecting int (osut.collinears)" @@ -5005,7 +4999,7 @@ def test33_leader_line_anchors_inserts(self): # [ 4, 14, 0] ... vs [16, 2, 20] # [ 0, 14, 0] ... vs [20, 2, 20] # [ 0, 0, 0] ... vs [20, 16, 20] - + def test34_generated_skylight_wells(self): o = osut.oslg self.assertEqual(o.status(), 0) From 02b8023822ef0350201a83988d21680faf6346cf Mon Sep 17 00:00:00 2001 From: brgix Date: Mon, 11 Aug 2025 08:14:26 -0400 Subject: [PATCH 08/25] Tweaks p3Dv (+ stress tests) --- src/osut/osut.py | 17 ++++---- tests/test_osut.py | 99 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 106 insertions(+), 10 deletions(-) diff --git a/src/osut/osut.py b/src/osut/osut.py index 0f1b27a..c7162f7 100644 --- a/src/osut/osut.py +++ b/src/osut/osut.py @@ -2737,7 +2737,10 @@ def p3Dv(pts=None) -> openstudio.Point3dVector: elif isinstance(pts, openstudio.Point3dVector): return pts elif isinstance(pts, openstudio.model.PlanarSurface): - pts = list(pts.vertices()) + for vt in pts.vertices(): + pt = openstudio.Point3d(vt.x(), vt.y(), vt.z()) + v.append(pt) + return v try: pts = list(pts) @@ -3056,7 +3059,7 @@ def nextUp(pts=None, pt=None): None: If invalid inputs (see logs). """ - mth = "osut.nextUP" + mth = "osut.nextUp" pts = p3Dv(pts) cl = openstudio.Point3d @@ -3341,7 +3344,7 @@ def isPointAlongSegment(p0=None, sg=[]) -> bool: Returns: bool: Whether a 3D point lies ~along a 3D point segment. - False: If invalid inputs. + False: If invalid inputs (see logs). """ mth = "osut.isPointAlongSegment" @@ -3350,12 +3353,10 @@ def isPointAlongSegment(p0=None, sg=[]) -> bool: if not isinstance(p0, cl1): return oslg.mismatch("point", p0, cl1, mth, CN.DBG, False) - if not isSegment(sg): - return oslg.mismatch("segment", sg, cl2, mth, CN.DBG, False) - + if not isSegment(sg): return False if holds(sg, p0): return True - a = sg[0] + a = sg[ 0] b = sg[-1] ab = b - a abn = b - a @@ -3397,7 +3398,7 @@ def isPointAlongSegments(p0=None, sgs=[]) -> bool: if not sgs: return oslg.empty("segments", mth, CN.DBG, False) if not isinstance(p0, cl1): - return oslg.mismatch("point", p0, cl, mth, CN.DBG, False) + return oslg.mismatch("point", p0, cl1, mth, CN.DBG, False) for sg in sgs: if isPointAlongSegment(p0, sg): return True diff --git a/tests/test_osut.py b/tests/test_osut.py index 2178a20..3649c12 100644 --- a/tests/test_osut.py +++ b/tests/test_osut.py @@ -66,7 +66,7 @@ def test03_dictionaries(self): self.assertTrue("skylight" in osut.film()) self.assertTrue("skylight" in osut.uo()) self.assertEqual(osut.film().keys(), osut.uo().keys()) - + def test04_materials(self): material = osut.mats()["material"] sand = osut.mats()["sand"] @@ -3308,6 +3308,84 @@ def test25_segments_triads_orientation(self): p7 = openstudio.Point3d(14, 20, -5) p8 = openstudio.Point3d(-9, -9, -5) + # Stress test 'to_p3Dv'. 4 valid input cases. + # Valid case #1: a single Point3d. + vtx = osut.p3Dv(p0) + self.assertTrue(isinstance(vtx, openstudio.Point3dVector)) + self.assertEqual(vtx[0], p0) # same object ID + + # Valid case #2: a Point3dVector. + vtxx = openstudio.Point3dVector() + vtxx.append(p0) + vtxx.append(p1) + vtxx.append(p2) + vtxx.append(p3) + vtx = osut.p3Dv(vtxx) + self.assertTrue(isinstance(vtx, openstudio.Point3dVector)) + self.assertEqual(vtx[ 0], p0) # same object ID + self.assertEqual(vtx[ 1], p1) # same object ID + self.assertEqual(vtx[ 2], p2) # same object ID + self.assertEqual(vtx[-1], p3) # same object ID + + # Valid case #3: Surface vertices. + model = openstudio.model.Model() + surface = openstudio.model.Surface(vtxx, model) + self.assertTrue(isinstance(surface.vertices(), tuple)) # ! Point3dVector + self.assertEqual(len(surface.vertices()), 4) + vtx = osut.p3Dv(vtxx) + self.assertTrue(isinstance(vtx, openstudio.Point3dVector)) + self.assertEqual(len(vtx), 4) + self.assertEqual(vtx[0], p0) + self.assertEqual(vtx[1], p1) + self.assertEqual(vtx[2], p2) + self.assertEqual(vtx[3], p3) + + # Valid case #4: Array. + vtx = osut.p3Dv([p0, p1, p2, p3]) + self.assertTrue(isinstance(vtx, openstudio.Point3dVector)) + self.assertEqual(len(vtx), 4) + self.assertEqual(vtx[0], p0) + self.assertEqual(vtx[1], p1) + self.assertEqual(vtx[2], p2) + self.assertEqual(vtx[3], p3) + + # Stress test 'nextUp'. + m0 = "Invalid 'points (2+)' arg #1 (osut.nextUp)" + + # Invalid case. + pt = osut.nextUp([], p0) + self.assertFalse(pt) + self.assertTrue(o.is_warn()) + self.assertEqual(len(o.logs()), 1) + self.assertEqual(o.logs()[0]["message"], m0) + self.assertEqual(o.clean(), DBG) + + # Valid case. + pt = osut.nextUp([p0, p1, p2, p3], p0) + self.assertTrue(isinstance(pt, openstudio.Point3d)) + self.assertEqual(pt, p1) + + pt = osut.nextUp([p0, p0, p0], p0) + self.assertTrue(isinstance(pt, openstudio.Point3d)) + self.assertEqual(pt, p0) + + # Stress test 'segments'. Invalid case. + sgs = osut.segments(p3) + self.assertTrue(isinstance(sgs, openstudio.Point3dVectorVector)) + self.assertFalse(sgs) + self.assertEqual(o.status(), 0) # nothing logged + + sgs = osut.segments([p3, p3]) + self.assertTrue(isinstance(sgs, openstudio.Point3dVectorVector)) + self.assertFalse(sgs) + self.assertEqual(o.status(), 0) # nothing logged + + # Valid case. + sgs = osut.segments([p0, p1, p2, p3]) + self.assertTrue(isinstance(sgs, openstudio.Point3dVectorVector)) + self.assertEqual(len(sgs), 4) + self.assertTrue(isinstance(sgs[-1], tuple)) # ! Point3dVector + # Stress test 'uniques'. m0 = "'n points' str? expecting int (osut.uniques)" @@ -3375,6 +3453,7 @@ def test25_segments_triads_orientation(self): self.assertEqual(len(collinears), 2) self.assertTrue(osut.areSame(collinears[0], p0)) self.assertTrue(osut.areSame(collinears[1], p1)) + self.assertTrue(osut.isPointAlongSegment(p0, sgs[0])) # Only 2 collinears, so request for first 3 is ignored. collinears = osut.collinears([p0, p1, p2, p3, p8], 3) @@ -3409,6 +3488,22 @@ def test25_segments_triads_orientation(self): self.assertTrue(osut.areSame(collinears[0], p0)) self.assertTrue(osut.areSame(collinears[1], p1)) + # Stress test isPointAlongSegment. + m0 = "'point' str? expecting Point3d (osut.p3Dv)" + + # Invalid case. + self.assertFalse(osut.isPointAlongSegment(p3, "osut")) + self.assertTrue(o.is_debug()) + self.assertEqual(len(o.logs()), 1) + self.assertEqual(o.logs()[0]["message"], m0) + self.assertEqual(o.clean(), DBG) + + # Valid case. + pts = openstudio.Point3dVector() + pts.append(p0) + pts.append(p1) + self.assertFalse(osut.isPointAlongSegment(p3, pts)) + # CASE a1: 2x end-to-end line segments (returns matching endpoints). self.assertTrue(osut.doesLineIntersect([p0, p1], [p1, p2])) pt = osut.lineIntersection([p0, p1], [p1, p2]) @@ -4999,7 +5094,7 @@ def test33_leader_line_anchors_inserts(self): # [ 4, 14, 0] ... vs [16, 2, 20] # [ 0, 14, 0] ... vs [20, 2, 20] # [ 0, 0, 0] ... vs [20, 16, 20] - + def test34_generated_skylight_wells(self): o = osut.oslg self.assertEqual(o.status(), 0) From ab70a662edd295957e301fef43492a2cd3b60320 Mon Sep 17 00:00:00 2001 From: brgix Date: Mon, 11 Aug 2025 08:50:40 -0400 Subject: [PATCH 09/25] Updates version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index a5bd941..611bdcc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "osut" -version = "0.6.0" +version = "0.6.1" description = "OpenStudio SDK utilities for Python" readme = "README.md" requires-python = ">=3.2" From a33b3b0251ec15ed13dbee72291c149c60e34ed9 Mon Sep 17 00:00:00 2001 From: brgix Date: Tue, 12 Aug 2025 08:13:09 -0400 Subject: [PATCH 10/25] Fixes (& tests) space width/height --- src/osut/osut.py | 31 +++++++++-------- tests/test_osut.py | 87 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 103 insertions(+), 15 deletions(-) diff --git a/src/osut/osut.py b/src/osut/osut.py index c7162f7..a4672b5 100644 --- a/src/osut/osut.py +++ b/src/osut/osut.py @@ -5243,15 +5243,12 @@ def spaceHeight(space=None) -> float: (float): Full height of space (0.0 if invalid input). """ - if not isinstance(space, openstudio.model.Space): - return 0 + hght = 0 + if not isinstance(space, openstudio.model.Space): return 0 - hght = 0 minZ = 10000 maxZ = -10000 - # The solution considers all surface types: "Floor", "Wall", "RoofCeiling". - # No presumption that floor are necessarily at ground level. for surface in space.surfaces(): zs = [pt.z() for pt in surface.vertices()] minZ = min(minZ, min(zs)) @@ -5294,21 +5291,19 @@ def spaceWidth(space=None) -> float: # - retain only other floor surfaces sharing same 3D plane # - recover potential union between floor surfaces # - fall back to largest floor surface if invalid union + # - return width of largest bounded box floors = sorted(floors, key=lambda fl: fl.grossArea(), reverse=True) floor = floors[0] plane = floor.plane() t = openstudio.Transformation.alignFace(floor.vertices()) polyg = list(poly(floor, False, True, True, t, "ulc")) - - if not polyg: - oslg.clean() - return 0 + if not polyg: return 0 polyg.reverse() - polyg = p3Dv(polyg) + # polyg = p3Dv(polyg) if len(floors) > 1: - floors = [flr for flr in floors if plane.equal(fl.plane(), 0.001)] + floors = [flr for flr in floors if plane.equal(flr.plane(), 0.001)] if len(floors) > 1: polygs = [poly(flr, False, True, True, t, "ulc") for flr in floors] @@ -5321,12 +5316,20 @@ def spaceWidth(space=None) -> float: union = openstudio.joinAll(polygs, 0.01)[0] polyg = poly(union, False, True, True) + if not polyg: return 0 + + polyg = list(polyg) + polyg.reverse() + # box = boundedBox(polyg) + + # A bounded box's 'height', at its narrowest, is its 'width'. + # return height(box) - box = boundedBox(polyg) - oslg.clean() + res = realignedFace(polyg) + if not res["box"]: return 0 # A bounded box's 'height', at its narrowest, is its 'width'. - return height(box) + return height(res["box"]) def genAnchors(s=None, sset=[], tag="box") -> int: diff --git a/tests/test_osut.py b/tests/test_osut.py index 3649c12..91cc3a9 100644 --- a/tests/test_osut.py +++ b/tests/test_osut.py @@ -66,7 +66,7 @@ def test03_dictionaries(self): self.assertTrue("skylight" in osut.film()) self.assertTrue("skylight" in osut.uo()) self.assertEqual(osut.film().keys(), osut.uo().keys()) - + def test04_materials(self): material = osut.mats()["material"] sand = osut.mats()["sand"] @@ -5890,5 +5890,90 @@ def test37_roller_shades(self): del model self.assertEqual(o.status(), 0) + def test37_roller_shades(self): + o = osut.oslg + self.assertEqual(o.status(), 0) + self.assertEqual(o.reset(DBG), DBG) + self.assertEqual(o.level(), DBG) + translator = openstudio.osversion.VersionTranslator() + + path = openstudio.path("./tests/files/osms/in/warehouse.osm") + model = translator.loadModel(path) + self.assertTrue(model) + model = model.get() + + fine = model.getSpaceByName("Zone2 Fine Storage") + self.assertTrue(fine) + fine = fine.get() + + # The Fine Storage space has 2 floors, at different Z-axis levels: + # - main ground floor (slab on grade), Z=0.00m + # - mezzanine floor, adjacent to the office space ceiling below, Z=4.27m + self.assertTrue(len(osut.facets(fine, "all", "floor")), 2) + groundfloor = model.getSurfaceByName("Fine Storage Floor") + mezzanine = model.getSurfaceByName("Office Roof Reversed") + self.assertTrue(groundfloor) + self.assertTrue(mezzanine) + groundfloor = groundfloor.get() + mezzanine = mezzanine.get() + + # The ground floor is L-shaped, floor surfaces have differenet Z=axis + # levels, etc. In the context of codes/standards like ASHRAE 90.1 or the + # Canadian NECB, determining what constitutes a space's 'height' and/or + # 'width' matters, namely with regards to geometry-based LPD rules + # (e.g. adjustments based on corridor 'width'). Not stating here what + # the definitive answers should be in all cases. There are however a few + # OSut functions that may be helpful. + # + # OSut's 'aligned' height and width functions were initially developed + # for non-flat surfaces, like walls and sloped roofs - particularly + # useful when such surfaces are rotated in 3D space. It's somewhat less + # intuitive when applied to horizontal surfaces like floors. In a + # nutshell, the functions lay out the surface in a 2D grid, aligning it + # along its 'bounded box'. It then determines a bounding box around the + # surface, once aligned: + # - 'aligned height' designates the narrowest edge of the bounding box + # - 'aligned width' designates the widest edge of the bounding box + # + # Useful? In some circumstances, maybe. One can argue that these may be + # of limited use for width-based LPD adjustment calculations. + self.assertAlmostEqual(osut.alignedHeight(groundfloor), 30.48, places=2) + self.assertAlmostEqual(osut.alignedWidth(groundfloor), 45.72, places=2) + self.assertAlmostEqual(osut.alignedHeight(mezzanine), 9.14, places=2) + self.assertAlmostEqual(osut.alignedWidth(mezzanine), 25.91, places=2) + + # OSut's 'spaceHeight' and 'spaceWidth' are more suitable for height- or + # width-based LPD adjustement calculations. OSut sets a space's width as + # the length of the narrowest edge of the largest bounded box that fits + # within a collection of neighbouring floor surfaces. This is considered + # reasonable for a long corridor, with varying widths along its full + # length (e.g. occasional alcoves). + # + # Achtung! The function can be time consuming (multiple iterations) for + # very convoluted spaces (e.g. long corridors with multiple concavities). + self.assertAlmostEqual(osut.spaceHeight(fine), 8.53, places=2) + self.assertAlmostEqual(osut.spaceWidth(fine), 21.33, places=2) + + # --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- # + path = openstudio.path("./tests/files/osms/out/seb_sky.osm") + model = translator.loadModel(path) + self.assertTrue(model) + model = model.get() + + openarea = model.getSpaceByName("Open area 1") + self.assertTrue(openarea) + openarea = openarea.get() + + floor = osut.facets(openarea, "all", "floor") + self.assertEqual(len(floor), 1) + floor = floor[0] + + self.assertAlmostEqual(osut.alignedHeight(floor), 6.88, places=2) + self.assertAlmostEqual(osut.alignedWidth(floor), 8.22, places=2) + self.assertAlmostEqual(osut.spaceHeight(openarea), 3.96, places=2) + self.assertAlmostEqual(osut.spaceWidth(openarea), 3.77, places=2) + + self.assertEqual(o.status(), 0) + if __name__ == "__main__": unittest.main() From efacdf85fbff396d7980220a577026d31d456319 Mon Sep 17 00:00:00 2001 From: brgix Date: Tue, 12 Aug 2025 08:24:23 -0400 Subject: [PATCH 11/25] Cleanup --- src/osut/osut.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/osut/osut.py b/src/osut/osut.py index a4672b5..36db366 100644 --- a/src/osut/osut.py +++ b/src/osut/osut.py @@ -5300,7 +5300,6 @@ def spaceWidth(space=None) -> float: if not polyg: return 0 polyg.reverse() - # polyg = p3Dv(polyg) if len(floors) > 1: floors = [flr for flr in floors if plane.equal(flr.plane(), 0.001)] @@ -5320,10 +5319,6 @@ def spaceWidth(space=None) -> float: polyg = list(polyg) polyg.reverse() - # box = boundedBox(polyg) - - # A bounded box's 'height', at its narrowest, is its 'width'. - # return height(box) res = realignedFace(polyg) if not res["box"]: return 0 From b294f502245a72125ba5976f53bf679fdebf3d51 Mon Sep 17 00:00:00 2001 From: brgix Date: Tue, 12 Aug 2025 08:34:27 -0400 Subject: [PATCH 12/25] Renames space height/width unit test --- tests/test_osut.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_osut.py b/tests/test_osut.py index 91cc3a9..395ed54 100644 --- a/tests/test_osut.py +++ b/tests/test_osut.py @@ -5890,7 +5890,7 @@ def test37_roller_shades(self): del model self.assertEqual(o.status(), 0) - def test37_roller_shades(self): + def test38_space_height_width(self): o = osut.oslg self.assertEqual(o.status(), 0) self.assertEqual(o.reset(DBG), DBG) From 8214f2f8e71fc296f2aa74ec51d4292a84f6dbd6 Mon Sep 17 00:00:00 2001 From: brgix Date: Tue, 12 Aug 2025 15:52:34 -0400 Subject: [PATCH 13/25] Bumps version to v070 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 611bdcc..0129ab5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "osut" -version = "0.6.1" +version = "0.7.0" description = "OpenStudio SDK utilities for Python" readme = "README.md" requires-python = ">=3.2" From 7a35d643c341534bc020f0d0ea506b108c5039fe Mon Sep 17 00:00:00 2001 From: brgix Date: Wed, 13 Aug 2025 08:52:33 -0400 Subject: [PATCH 14/25] Removes OpenStudio as dependency --- .github/workflows/pull_request.yml | 48 +++++++++++++++++------------- pyproject.toml | 3 +- 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 2c2b78b..b81e3a8 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -5,25 +5,25 @@ on: branches: develop jobs: - test_oslg_ubuntu_latest: - runs-on: ubuntu-latest - strategy: - matrix: - python-version: ["3.10", "3.x"] - - steps: - - name: Check out repository - uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: python -m pip install --upgrade pip setuptools wheel openstudio oslg - - name: Run unit tests - run: python -m unittest + # test_osut_ubuntu_latest: + # runs-on: ubuntu-latest + # strategy: + # matrix: + # python-version: ["3.10", "3.x"] + # + # steps: + # - name: Check out repository + # uses: actions/checkout@v4 + # - name: Set up Python + # uses: actions/setup-python@v5 + # with: + # python-version: ${{ matrix.python-version }} + # - name: Install dependencies + # run: python -m pip install --upgrade pip setuptools wheel openstudio oslg + # - name: Run unit tests + # run: python -m unittest - test_oslg_ubuntu_2204: + test_osut_ubuntu_2204: runs-on: ubuntu-22.04 strategy: matrix: @@ -37,6 +37,14 @@ jobs: with: python-version: ${{ matrix.python-version }} - name: Install dependencies - run: python -m pip install --upgrade pip setuptools wheel openstudio oslg + run: python -m pip install --upgrade pip setuptools wheel oslg - name: Run unit tests - run: python -m unittest + run: | + echo $(pwd) + echo $(ls) + docker pull nrel/openstudio:3.10.0 + docker run --name test --rm -d -t -v $(pwd):/work -w /work nrel/openstudio:3.10.0 + docker exec -t test pwd + docker exec -t test ls + docker python -m unittest + docker kill test diff --git a/pyproject.toml b/pyproject.toml index 0129ab5..163521e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,8 @@ readme = "README.md" requires-python = ">=3.2" authors = [ {name = "Denis Bourgeois", email = "denis@rd2.ca"} ] maintainers = [ {name = "Denis Bourgeois", email = "denis@rd2.ca"} ] -dependencies = ["oslg","openstudio>=3.6.1"] +# dependencies = ["oslg","openstudio>=3.6.1"] +dependencies = ["oslg"] license = "BSD-3-Clause" license-files = ["LICENSE"] classifiers = [ From 7fbf1a2edf0abff306f2f2badbdfd7d30cc56f57 Mon Sep 17 00:00:00 2001 From: brgix Date: Wed, 13 Aug 2025 08:54:53 -0400 Subject: [PATCH 15/25] Removes OpenStudio as dependency (redux) --- .github/workflows/pull_request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index b81e3a8..6e17685 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -46,5 +46,5 @@ jobs: docker run --name test --rm -d -t -v $(pwd):/work -w /work nrel/openstudio:3.10.0 docker exec -t test pwd docker exec -t test ls - docker python -m unittest + docker exec -t python -m unittest docker kill test From 372130406cb73dfeeb3e11b4868bc29404dddd8b Mon Sep 17 00:00:00 2001 From: brgix Date: Wed, 13 Aug 2025 09:00:07 -0400 Subject: [PATCH 16/25] Removes OpenStudio as dependency (p3) --- .github/workflows/pull_request.yml | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 6e17685..ed6eab3 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -37,14 +37,6 @@ jobs: with: python-version: ${{ matrix.python-version }} - name: Install dependencies - run: python -m pip install --upgrade pip setuptools wheel oslg + run: python -m pip install --upgrade pip setuptools wheel openstudio oslg - name: Run unit tests - run: | - echo $(pwd) - echo $(ls) - docker pull nrel/openstudio:3.10.0 - docker run --name test --rm -d -t -v $(pwd):/work -w /work nrel/openstudio:3.10.0 - docker exec -t test pwd - docker exec -t test ls - docker exec -t python -m unittest - docker kill test + run: python -m unittest From c212c30c9942c713569455a8cba5154d85e864da Mon Sep 17 00:00:00 2001 From: brgix Date: Wed, 13 Aug 2025 09:06:32 -0400 Subject: [PATCH 17/25] Cleanup --- .github/workflows/pull_request.yml | 34 +++++++++++++++--------------- pyproject.toml | 1 - 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index ed6eab3..bfa340a 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -5,23 +5,23 @@ on: branches: develop jobs: - # test_osut_ubuntu_latest: - # runs-on: ubuntu-latest - # strategy: - # matrix: - # python-version: ["3.10", "3.x"] - # - # steps: - # - name: Check out repository - # uses: actions/checkout@v4 - # - name: Set up Python - # uses: actions/setup-python@v5 - # with: - # python-version: ${{ matrix.python-version }} - # - name: Install dependencies - # run: python -m pip install --upgrade pip setuptools wheel openstudio oslg - # - name: Run unit tests - # run: python -m unittest + test_osut_ubuntu_latest: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.10", "3.x"] + + steps: + - name: Check out repository + uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: python -m pip install --upgrade pip setuptools wheel openstudio oslg + - name: Run unit tests + run: python -m unittest test_osut_ubuntu_2204: runs-on: ubuntu-22.04 diff --git a/pyproject.toml b/pyproject.toml index 163521e..dd69ce3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,6 @@ readme = "README.md" requires-python = ">=3.2" authors = [ {name = "Denis Bourgeois", email = "denis@rd2.ca"} ] maintainers = [ {name = "Denis Bourgeois", email = "denis@rd2.ca"} ] -# dependencies = ["oslg","openstudio>=3.6.1"] dependencies = ["oslg"] license = "BSD-3-Clause" license-files = ["LICENSE"] From c2129da6bcd45be327149e3fdac6d5a0b07a9245 Mon Sep 17 00:00:00 2001 From: brgix Date: Wed, 13 Aug 2025 09:14:06 -0400 Subject: [PATCH 18/25] Tests GH Actions matrix (OS versions) --- .github/workflows/pull_request.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index bfa340a..ae4e15f 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -10,6 +10,7 @@ jobs: strategy: matrix: python-version: ["3.10", "3.x"] + os-version: ["openstudio==3.6.1", "openstudio==3.10.0"] steps: - name: Check out repository @@ -19,7 +20,7 @@ jobs: with: python-version: ${{ matrix.python-version }} - name: Install dependencies - run: python -m pip install --upgrade pip setuptools wheel openstudio oslg + run: python -m pip install --upgrade pip setuptools wheel ${{ matrix.os-version }} oslg - name: Run unit tests run: python -m unittest @@ -28,6 +29,7 @@ jobs: strategy: matrix: python-version: ["3.10", "3.x"] + os-version: ["openstudio==3.6.1", "openstudio==3.10.0"] steps: - name: Check out repository @@ -37,6 +39,6 @@ jobs: with: python-version: ${{ matrix.python-version }} - name: Install dependencies - run: python -m pip install --upgrade pip setuptools wheel openstudio oslg + run: python -m pip install --upgrade pip setuptools wheel ${{ matrix.os-version }} oslg - name: Run unit tests run: python -m unittest From 5c33a238e757d5f260ce8a6d7b8e8546c83d0a88 Mon Sep 17 00:00:00 2001 From: brgix Date: Wed, 13 Aug 2025 09:23:17 -0400 Subject: [PATCH 19/25] Tests GH Actions matrix (OS versions) (redux) --- .github/workflows/pull_request.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index ae4e15f..627cb8f 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -10,7 +10,7 @@ jobs: strategy: matrix: python-version: ["3.10", "3.x"] - os-version: ["openstudio==3.6.1", "openstudio==3.10.0"] + openstudio-version: ["3.6.1", "3.10.0"] steps: - name: Check out repository @@ -20,7 +20,9 @@ jobs: with: python-version: ${{ matrix.python-version }} - name: Install dependencies - run: python -m pip install --upgrade pip setuptools wheel ${{ matrix.os-version }} oslg + run: | + python -m pip install --upgrade pip setuptools wheel oslg + python -m pip install openstudio==${{ matrix.openstudio-version }} - name: Run unit tests run: python -m unittest @@ -29,7 +31,7 @@ jobs: strategy: matrix: python-version: ["3.10", "3.x"] - os-version: ["openstudio==3.6.1", "openstudio==3.10.0"] + openstudio-version: ["3.6.1", "3.10.0"] steps: - name: Check out repository @@ -39,6 +41,8 @@ jobs: with: python-version: ${{ matrix.python-version }} - name: Install dependencies - run: python -m pip install --upgrade pip setuptools wheel ${{ matrix.os-version }} oslg + run: | + python -m pip install --upgrade pip setuptools wheel oslg + python -m pip install openstudio==${{ matrix.openstudio-version }} - name: Run unit tests run: python -m unittest From f24ad09d29ed186c85375b6bb2fcdf1cd2d8f928 Mon Sep 17 00:00:00 2001 From: brgix Date: Wed, 13 Aug 2025 09:26:12 -0400 Subject: [PATCH 20/25] Tests GH Actions matrix (OS versions) (p3) --- .github/workflows/pull_request.yml | 45 +++++++++++++++--------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 627cb8f..643deeb 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -5,26 +5,26 @@ on: branches: develop jobs: - test_osut_ubuntu_latest: - runs-on: ubuntu-latest - strategy: - matrix: - python-version: ["3.10", "3.x"] - openstudio-version: ["3.6.1", "3.10.0"] - - steps: - - name: Check out repository - uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - python -m pip install --upgrade pip setuptools wheel oslg - python -m pip install openstudio==${{ matrix.openstudio-version }} - - name: Run unit tests - run: python -m unittest + # test_osut_ubuntu_latest: + # runs-on: ubuntu-latest + # strategy: + # matrix: + # python-version: ["3.10", "3.x"] + # openstudio-version: ["3.6.1", "3.10.0"] + # + # steps: + # - name: Check out repository + # uses: actions/checkout@v4 + # - name: Set up Python + # uses: actions/setup-python@v5 + # with: + # python-version: ${{ matrix.python-version }} + # - name: Install dependencies + # run: | + # python -m pip install --upgrade pip setuptools wheel oslg + # python -m pip install openstudio==${{ matrix.openstudio-version }} + # - name: Run unit tests + # run: python -m unittest test_osut_ubuntu_2204: runs-on: ubuntu-22.04 @@ -42,7 +42,8 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | - python -m pip install --upgrade pip setuptools wheel oslg - python -m pip install openstudio==${{ matrix.openstudio-version }} + python -m pip install --upgrade pip + pip install setuptools wheel oslg + pip install openstudio==${{ matrix.openstudio-version }} - name: Run unit tests run: python -m unittest From 10087e14176dfa231f52fc1a017bcfe3ae7b514f Mon Sep 17 00:00:00 2001 From: brgix Date: Wed, 13 Aug 2025 09:34:21 -0400 Subject: [PATCH 21/25] Reverts to previous GH with OpenStudio versions --- .github/workflows/pull_request.yml | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 643deeb..f00ce94 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -26,13 +26,31 @@ jobs: # - name: Run unit tests # run: python -m unittest - test_osut_ubuntu_2204: + test_osut_ubuntu_2204_os361: runs-on: ubuntu-22.04 strategy: matrix: python-version: ["3.10", "3.x"] - openstudio-version: ["3.6.1", "3.10.0"] + steps: + - name: Check out repository + uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install setuptools wheel oslg + pip install openstudio==3.6.1 + - name: Run unit tests + run: python -m unittest + test_osut_ubuntu_2204_os3100: + runs-on: ubuntu-22.04 + strategy: + matrix: + python-version: ["3.10", "3.x"] steps: - name: Check out repository uses: actions/checkout@v4 @@ -44,6 +62,6 @@ jobs: run: | python -m pip install --upgrade pip pip install setuptools wheel oslg - pip install openstudio==${{ matrix.openstudio-version }} + pip install openstudio==3.10.0 - name: Run unit tests run: python -m unittest From 512e84b93b1da7d8822dcd5daf73baff67239c66 Mon Sep 17 00:00:00 2001 From: brgix Date: Wed, 13 Aug 2025 09:37:20 -0400 Subject: [PATCH 22/25] Simplifies GH Actions --- .github/workflows/pull_request.yml | 49 ++---------------------------- 1 file changed, 3 insertions(+), 46 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index f00ce94..95139d8 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -5,52 +5,12 @@ on: branches: develop jobs: - # test_osut_ubuntu_latest: - # runs-on: ubuntu-latest - # strategy: - # matrix: - # python-version: ["3.10", "3.x"] - # openstudio-version: ["3.6.1", "3.10.0"] - # - # steps: - # - name: Check out repository - # uses: actions/checkout@v4 - # - name: Set up Python - # uses: actions/setup-python@v5 - # with: - # python-version: ${{ matrix.python-version }} - # - name: Install dependencies - # run: | - # python -m pip install --upgrade pip setuptools wheel oslg - # python -m pip install openstudio==${{ matrix.openstudio-version }} - # - name: Run unit tests - # run: python -m unittest - - test_osut_ubuntu_2204_os361: - runs-on: ubuntu-22.04 + test_osut_ubuntu_latest: + runs-on: ubuntu-latest strategy: matrix: python-version: ["3.10", "3.x"] - steps: - - name: Check out repository - uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install setuptools wheel oslg - pip install openstudio==3.6.1 - - name: Run unit tests - run: python -m unittest - test_osut_ubuntu_2204_os3100: - runs-on: ubuntu-22.04 - strategy: - matrix: - python-version: ["3.10", "3.x"] steps: - name: Check out repository uses: actions/checkout@v4 @@ -59,9 +19,6 @@ jobs: with: python-version: ${{ matrix.python-version }} - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install setuptools wheel oslg - pip install openstudio==3.10.0 + run: python -m pip install --upgrade pip setuptools wheel oslg openstudio - name: Run unit tests run: python -m unittest From bb299a74e484f72b9651676fae8d6ea60140eb37 Mon Sep 17 00:00:00 2001 From: brgix Date: Wed, 13 Aug 2025 09:50:19 -0400 Subject: [PATCH 23/25] Updates README --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 1145bab..7d7249d 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,13 @@ Python implementation of the _OSut_ Ruby gem for the OpenStudio SDK. - Ruby GitHub [repository](https://github.com/rd2/osut) ---- + +_OSut_ interacts with _OpenStudio_: + +`pip install openstudio` + +---- + To download the _OSut_ Python package: `pip install --upgrade osut` From e4df93b906de8b849fc817c734bf64bfa1742f18 Mon Sep 17 00:00:00 2001 From: brgix Date: Wed, 13 Aug 2025 09:53:47 -0400 Subject: [PATCH 24/25] Adapts GH Actions for older OS versions --- .github/workflows/pull_request.yml | 38 +++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 95139d8..afbcf1b 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -5,7 +5,7 @@ on: branches: develop jobs: - test_osut_ubuntu_latest: + test_osut_ubuntu_latest_openstudio_latest: runs-on: ubuntu-latest strategy: matrix: @@ -22,3 +22,39 @@ jobs: run: python -m pip install --upgrade pip setuptools wheel oslg openstudio - name: Run unit tests run: python -m unittest + + test_osut_ubuntu_latest_openstudio_361: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.10", "3.x"] + + steps: + - name: Check out repository + uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: python -m pip install --upgrade pip setuptools wheel oslg openstudio==3.6.1 + - name: Run unit tests + run: python -m unittest + + test_osut_ubuntu_latest_openstudio_321: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.10", "3.x"] + + steps: + - name: Check out repository + uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: python -m pip install --upgrade pip setuptools wheel oslg openstudio==3.2.1 + - name: Run unit tests + run: python -m unittest From 1c3d672ae9383f5e556a9b920da3edfe48d42308 Mon Sep 17 00:00:00 2001 From: brgix Date: Wed, 13 Aug 2025 09:56:50 -0400 Subject: [PATCH 25/25] Reverts to OpenStudio latest --- .github/workflows/pull_request.yml | 36 ------------------------------ 1 file changed, 36 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index afbcf1b..ebeeaeb 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -22,39 +22,3 @@ jobs: run: python -m pip install --upgrade pip setuptools wheel oslg openstudio - name: Run unit tests run: python -m unittest - - test_osut_ubuntu_latest_openstudio_361: - runs-on: ubuntu-latest - strategy: - matrix: - python-version: ["3.10", "3.x"] - - steps: - - name: Check out repository - uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: python -m pip install --upgrade pip setuptools wheel oslg openstudio==3.6.1 - - name: Run unit tests - run: python -m unittest - - test_osut_ubuntu_latest_openstudio_321: - runs-on: ubuntu-latest - strategy: - matrix: - python-version: ["3.10", "3.x"] - - steps: - - name: Check out repository - uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: python -m pip install --upgrade pip setuptools wheel oslg openstudio==3.2.1 - - name: Run unit tests - run: python -m unittest