Conversation
|
|
||
| elif specs["type"] == "window": | ||
| a["glazing"]["u" ] = specs["uo"] | ||
| a["glazing"]["u" ] = u if u else uo()["window"] |
There was a problem hiding this comment.
A user could set a glazing assembly's specs["uo"] to None. This is caught and reset here.
| 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 |
There was a problem hiding this comment.
For opaque construction, adjusting insulating layer thickness (to meet a requested assembly Uo factor) is skipped entirely if the requested Uo isn't:
- successfully converted to a float
- within postulated (acceptable) range
| 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) |
There was a problem hiding this comment.
In the case of fenestrated assemblies, an invalid Uo request is ignored and the glazing assembly inherits a default OSut Uo (here 3.5 W/m2.K for a skylight).
| - "max" (float): max temperature. (None if invalid inputs - see logs). | ||
| """ | ||
| mth = "osut.scheduleCompactMinMax" | ||
| mth = "osut.scheduleIntervalMinMax" |
|
|
||
| # Once joined, re-adjust Z-axis coordinates. | ||
| if abs(z) > CN.TOL: | ||
| if round(z, 2) != 0.00: |
| # 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) |
There was a problem hiding this comment.
OSut enabled ScheduleFixedInterval checks, e.g.:
- min/max setpoint temperatures
- is space UNCONDITIONED, etc.
Yet no unit test had been in place.
| translator = openstudio.osversion.VersionTranslator() | ||
|
|
||
| path = openstudio.path("./tests/files/osms/out/seb2.osm") | ||
| path = openstudio.path("./tests/files/osms/out/seb_ext2.osm") |
There was a problem hiding this comment.
Harmonizing with Ruby test.
| try: | ||
| value = float(values[i]) | ||
| value = vals.append(value) | ||
| vals.append(value) |
| self.assertTrue("str? expecting dict" in o.logs()[0]["message"]) | ||
| self.assertTrue(isinstance(slab, openstudio.Point3dVector)) | ||
| self.assertFalse(slab) | ||
| self.assertEqual(o.clean(), DBG) |
There was a problem hiding this comment.
Stress-test: when requested floor plates (input) aren't dictionaries.
| # if xa1b2.length() < CN.TOL2: | ||
| # if isPointAlongSegment(a1, [a2, b2]): return None | ||
| # if isPointAlongSegment(a2, [a1, b2]): return None | ||
|
|
| except: | ||
| return oslg.mismatch("n unique points", n, int, mth, CN.DBG, v) | ||
| oslg.mismatch("n points", n, int, mth, CN.DBG) | ||
| n = 0 |
There was a problem hiding this comment.
There are 3 OSut functions that take in n as argument:
uniques(pts, n=0):collinear(pts, n=0)noncollinears(pts, n=0)
... where n is an (optional) user-requested number of points to return. For instance, a user may request the first 3 points of a hexagon (6 points) to determine a plane equation.
Unfortunately, all three functions did not share the same validation checks and treatment of n - an inconsistency and source of confusion. Furthermore, DEBUG or ERROR messages shouldn't be logged when users incorrectly guess in advance what the admissible range of points may be. So these changes:
- reduce the volume a bit
- harmonize the treatment of
nacross all three methods - introduces stress tests
| for vt in pts.vertices(): | ||
| pt = openstudio.Point3d(vt.x(), vt.y(), vt.z()) | ||
| v.append(pt) | ||
| return v |
There was a problem hiding this comment.
No point in validating planar surface .vertices() individually.
| if not isSegment(sg): | ||
| return oslg.mismatch("segment", sg, cl2, mth, CN.DBG, False) | ||
|
|
||
| if not isSegment(sg): return False |
There was a problem hiding this comment.
Lowering the log volume: isPointAlongSegment calls isSegment, which in turn calls p3Dv. The latter will log an inadmissible object.
| 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) |
| # Valid case #1: a single Point3d. | ||
| vtx = osut.p3Dv(p0) | ||
| self.assertTrue(isinstance(vtx, openstudio.Point3dVector)) | ||
| self.assertEqual(vtx[0], p0) # same object ID |
There was a problem hiding this comment.
All 4 valid p3Dv use cases systematically return an openstudio.Point3dVector (and not occasionally a list).
|
|
||
| # A bounded box's 'height', at its narrowest, is its 'width'. | ||
| return height(box) | ||
| return height(res["box"]) |
| # 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) |
There was a problem hiding this comment.
The value returned by spaceHeight (8.53 m) corresponds to the tallest floor-to-ceiling distance (along Z-axis).
The floor section circumscribed (and crisscrossed) with red dotted lines corresponds to the largest bounded box that fits in the (large) L-shaped floor surface. The length of the narrowest edge of this bounded box (21.33 m) is what spaceWidth returns.
| 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) |
There was a problem hiding this comment.
- in red: full height of space, including skylight wells
- in green: width of bounding box of space floor(s) ... outline is very approximate!
- in blue: width of largest bounded box that can fit within grouped floor surfaces
The latter is retained here as the most adequate measure of what could be considered a room's width, e.g. for LPD adjustment calculations.
| maintainers = [ {name = "Denis Bourgeois", email = "denis@rd2.ca"} ] | ||
| dependencies = ["oslg","openstudio>=3.6.1"] | ||
| # dependencies = ["oslg","openstudio>=3.6.1"] | ||
| dependencies = ["oslg"] |
There was a problem hiding this comment.
Setting aside OpenStudio as a dependency.
| @@ -22,39 +22,3 @@ jobs: | |||
| run: python -m pip install --upgrade pip setuptools wheel oslg openstudio | |||
| - name: Run unit tests | |||
| run: python -m unittest | |||
There was a problem hiding this comment.
Unsuccessful in pulling more than one OpenStudio SDK package/module. Sticking to latest version for now.
Around 40-odd typos (and other oddities) were identified in the original Ruby implementation of OSut, while developing this Python counterpart. In some cases, these are simple fixes in the Ruby code (no impact on the Python implementation). In other cases (like this first commit), they reveal weaknesses (to fix), such as not adequately catching bad user input. Over the next day or so, a number of such fixes are expected to be introduced, before re-releasing an upcoming pyOSut v0.6.1.