Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ jobs:
# Keep the current repo LAST.
$buildOrder = @(
'SAM'
'SAM_Mollier'
$repo
)

Expand Down Expand Up @@ -140,6 +141,7 @@ jobs:
# Same build order as above (keep repo LAST)
$buildOrder = @(
'SAM'
'SAM_Mollier'
$repo
)

Expand All @@ -160,7 +162,43 @@ jobs:
& msbuild $sln /t:Rebuild @common
}

- name: Test SAM.Analytical.Systems.Tests
shell: pwsh
run: |
$ErrorActionPreference = 'Stop'

# The capability/template conformance suite must EXECUTE in CI, not merely compile. It is the
# only thing that checks CapabilityIndex.JSON against the shipped SystemEnergyCentre templates -
# that every template is accounted for, that a heat-recovery claim matches an exchanger in the
# file, and that no template models a summer bypass. A drifted index is otherwise invisible
# until it silently selects the wrong system for a dwelling.
#
# Targeted rather than a solution-wide `dotnet test`: this repo's other test project is already
# covered by its own history, and the conformance suite reads the repository's own resources
# from source, so it must run from the checkout rather than from a build output.
$project = Join-Path '${{ env.REPO_NAME }}' 'SAM.Analytical.Systems.Tests\SAM.Analytical.Systems.Tests.csproj'
if (-not (Test-Path $project)) { throw "Conformance test project not found: $project" }

# --no-build would need a matching Release layout; the solution Rebuild above already produced
# the dependencies this references, so a plain build here is cheap and avoids a config mismatch.
# /p:SAMVersion MATTERS. Three SAM_Systems projects write to the same build\ folder the artifact
# step publishes, so a test build without it recompiles them at the 1.0.0.0 local-dev fallback
# and silently overwrites the CI-stamped DLLs - shipping version-inconsistent assemblies.
& dotnet test $project -c Release "-p:SAMVersion=${{ steps.ver.outputs.samversion }}" --logger 'trx;LogFileName=SAM.Analytical.Systems.Tests.trx' --results-directory 'TestResults'
if ($LASTEXITCODE -ne 0) { throw "SAM.Analytical.Systems.Tests failed." }

- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: ${{ env.REPO_NAME }}-test-results
path: TestResults/*.trx
if-no-files-found: warn

- name: Upload build folders (optional)
# always(): a failing test must not also cost the build artifacts, which are what you need to
# diagnose it.
if: always()
uses: actions/upload-artifact@v4
with:
name: ${{ env.REPO_NAME }}-build-folders
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ bld/
[Oo]bj/
[Ll]og/
[Bb]uild/
build_tests/

# Visual Studio 2015/2017 cache/options directory
.vs/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using Grasshopper.Kernel;
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright (c) 2020-2026 Michal Dengusiak & Jakub Ziolkowski and contributors

using Grasshopper.Kernel;
using SAM.Analytical.Grasshopper.Systems.Properties;
using SAM.Core.Grasshopper;
using SAM.Core.Grasshopper.Systems;
Expand Down Expand Up @@ -32,7 +35,11 @@ public class SAMAnalyticalSystemAddSystemEnergyCentre : GH_SAMVariableOutputPara
/// </summary>
public SAMAnalyticalSystemAddSystemEnergyCentre()
: base("SAMAnalytical.AddSystemEnergyCentre", "SAMAnalytical.AddSystemEnergyCentre",
"Adds SystemEnergyCentre",
"Attaches a SystemEnergyCentre to a SAM AnalyticalModel.\n" +
"\n" +
"The energy centre (the building's air systems and plantrooms) is stored on the analytical\n" +
"model so it travels with the model through later steps and into simulation. The updated\n" +
"analytical model is returned together with the energy centre that was attached.",
"SAM", "Systems")
{
}
Expand All @@ -45,8 +52,8 @@ protected override GH_SAMParam[] Inputs
get
{
List<GH_SAMParam> result = new List<GH_SAMParam>();
result.Add(new GH_SAMParam(new GooAnalyticalModelParam() { Name = "_analyticalModel", NickName = "_analyticalModel", Description = "SAM AnalyticalModel", Access = GH_ParamAccess.item }, ParamVisibility.Binding));
result.Add(new GH_SAMParam(new GooSystemEnergyCentreParam() { Name = "_systemEnergyCentre_", NickName = "systemEnergyCentre", Description = "SAM SystemEnergyCentre", Optional = true, Access = GH_ParamAccess.item }, ParamVisibility.Binding));
result.Add(new GH_SAMParam(new GooAnalyticalModelParam() { Name = "_analyticalModel", NickName = "_analyticalModel", Description = "The SAM AnalyticalModel to attach the energy centre to. A copy is returned with the energy centre stored on it.", Access = GH_ParamAccess.item }, ParamVisibility.Binding));
result.Add(new GH_SAMParam(new GooSystemEnergyCentreParam() { Name = "_systemEnergyCentre_", NickName = "systemEnergyCentre", Description = "The SAM SystemEnergyCentre (air systems + plantrooms) to store on the analytical model.\n\nOptional: if omitted, any energy centre already present on the model is kept.", Optional = true, Access = GH_ParamAccess.item }, ParamVisibility.Binding));
return result.ToArray();
}
}
Expand All @@ -59,8 +66,8 @@ protected override GH_SAMParam[] Outputs
get
{
List<GH_SAMParam> result = new List<GH_SAMParam>();
result.Add(new GH_SAMParam(new GooAnalyticalModelParam() { Name = "analyticalModel", NickName = "analyticalModel", Description = "SAM AnalyticalModel", Access = GH_ParamAccess.item }, ParamVisibility.Binding));
result.Add(new GH_SAMParam(new GooSystemEnergyCentreParam() { Name = "systemEnergyCentre", NickName = "systemEnergyCentre", Description = "SAM SystemEnergyCentre", Access = GH_ParamAccess.item }, ParamVisibility.Binding));
result.Add(new GH_SAMParam(new GooAnalyticalModelParam() { Name = "analyticalModel", NickName = "analyticalModel", Description = "The SAM AnalyticalModel with the SystemEnergyCentre stored on it.", Access = GH_ParamAccess.item }, ParamVisibility.Binding));
result.Add(new GH_SAMParam(new GooSystemEnergyCentreParam() { Name = "systemEnergyCentre", NickName = "systemEnergyCentre", Description = "The SystemEnergyCentre that was attached to the analytical model.", Access = GH_ParamAccess.item }, ParamVisibility.Binding));
return result.ToArray();
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using SAM.Analytical.Grasshopper.Systems.Properties;
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright (c) 2020-2026 Michal Dengusiak & Jakub Ziolkowski and contributors

using SAM.Analytical.Grasshopper.Systems.Properties;
using SAM.Analytical.Systems;
using SAM.Core.Grasshopper;
using System;
Expand Down Expand Up @@ -27,7 +30,10 @@ public class SAMAnalyticalSystemComponentType : GH_SAMEnumComponent<AnalyticalSy
/// </summary>
public SAMAnalyticalSystemComponentType()
: base("SAM.AnalyticalSystemComponentType", "SAM.AnalyticalSystemComponentType",
"AnalyticalSystemComponentType",
"Selects an analytical air-handling component type (e.g. cooling coil, heating coil, fan,\n" +
"exchanger, humidifier) from a drop-down list.\n" +
"\n" +
"Use it to drive type-dependent logic or to filter/identify components by type.",
"SAM", "Systems")
{
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ public class SAMAnalyticalSystemConnectedSensor : GH_SAMVariableOutputParameterC
/// </summary>
public SAMAnalyticalSystemConnectedSensor()
: base("SAMAnalytical.ConnectedSensor", "SAMAnalytical.ConnectedSensor",
"Gets Connected SystemSensor",
"Finds the SystemSensor that a given system controller reads from, within a plantroom.\n" +
"\n" +
"A controller references a sensor by id; this component resolves that reference and returns the\n" +
"actual SystemSensor object from the plantroom so it can be inspected or rewired.",
"SAM", "Systems")
{
}
Expand All @@ -48,8 +51,8 @@ protected override GH_SAMParam[] Inputs
get
{
List<GH_SAMParam> result = [];
result.Add(new GH_SAMParam(new GooSystemPlantRoomParam() { Name = "_systemPlantRoom", NickName = "_systemPlantRoom", Description = "SystemPlantRoom", Access = GH_ParamAccess.item }, ParamVisibility.Binding));
result.Add(new GH_SAMParam(new GooSystemObjectParam() { Name = "_systemController", NickName = "_systemController", Description = "System Controller", Access = GH_ParamAccess.item}, ParamVisibility.Binding));
result.Add(new GH_SAMParam(new GooSystemPlantRoomParam() { Name = "_systemPlantRoom", NickName = "_systemPlantRoom", Description = "The SAM SystemPlantRoom that contains the controller and its sensor.", Access = GH_ParamAccess.item }, ParamVisibility.Binding));
result.Add(new GH_SAMParam(new GooSystemObjectParam() { Name = "_systemController", NickName = "_systemController", Description = "The system controller whose referenced sensor should be resolved.", Access = GH_ParamAccess.item}, ParamVisibility.Binding));

return [.. result];
}
Expand All @@ -63,7 +66,7 @@ protected override GH_SAMParam[] Outputs
get
{
List<GH_SAMParam> result = [];
result.Add(new GH_SAMParam(new GooSystemObjectParam() { Name = "systemSensor", NickName = "systemSensor", Description = "System Sensor", Access = GH_ParamAccess.item }, ParamVisibility.Binding));
result.Add(new GH_SAMParam(new GooSystemObjectParam() { Name = "systemSensor", NickName = "systemSensor", Description = "The SystemSensor referenced by the controller (the sensor it reads its measured value from).", Access = GH_ParamAccess.item }, ParamVisibility.Binding));
return [.. result];
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ public class SAMAnalyticalSystemConnectedSystemComponents : GH_SAMVariableOutput
/// </summary>
public SAMAnalyticalSystemConnectedSystemComponents()
: base("SAMAnalytical.ConnectedSystemComponents", "SAMAnalytical.ConnectedSystemComponents",
"Gets Connected System Components",
"Gets the components directly connected to a given component along a system.\n" +
"\n" +
"Starting from one component, this returns its immediate neighbours on the chosen system (e.g. an\n" +
"AirSystem) - those one step upstream (In), one step downstream (Out), or both when no direction\n" +
"is given. Use it to walk the connectivity of a plantroom one hop at a time.",
"SAM", "Systems")
{
}
Expand All @@ -48,10 +52,10 @@ protected override GH_SAMParam[] Inputs
get
{
List<GH_SAMParam> result = [];
result.Add(new GH_SAMParam(new GooSystemPlantRoomParam() { Name = "_systemPlantRoom", NickName = "_systemPlantRoom", Description = "SystemPlantRoom", Access = GH_ParamAccess.item }, ParamVisibility.Binding));
result.Add(new GH_SAMParam(new Core.Grasshopper.Systems.GooSystemParam() { Name = "_system", NickName = "_system", Description = "System", Access = GH_ParamAccess.item }, ParamVisibility.Binding));
result.Add(new GH_SAMParam(new GooSystemComponentParam() { Name = "_systemComponent", NickName = "_systemComponent", Description = "System Component", Access = GH_ParamAccess.item }, ParamVisibility.Binding));
result.Add(new GH_SAMParam(new global::Grasshopper.Kernel.Parameters.Param_String() { Name = "direction_", NickName = "direction_", Description = "Flow Direction", Access = GH_ParamAccess.item, Optional = true }, ParamVisibility.Binding));
result.Add(new GH_SAMParam(new GooSystemPlantRoomParam() { Name = "_systemPlantRoom", NickName = "_systemPlantRoom", Description = "The SAM SystemPlantRoom whose connectivity is queried.", Access = GH_ParamAccess.item }, ParamVisibility.Binding));
result.Add(new GH_SAMParam(new Core.Grasshopper.Systems.GooSystemParam() { Name = "_system", NickName = "_system", Description = "The system whose connections to follow (e.g. an AirSystem or LiquidSystem). A component can belong to several systems; this selects which network to traverse.", Access = GH_ParamAccess.item }, ParamVisibility.Binding));
result.Add(new GH_SAMParam(new GooSystemComponentParam() { Name = "_systemComponent", NickName = "_systemComponent", Description = "The component to find the neighbours of.", Access = GH_ParamAccess.item }, ParamVisibility.Binding));
result.Add(new GH_SAMParam(new global::Grasshopper.Kernel.Parameters.Param_String() { Name = "direction_", NickName = "direction_", Description = "Flow direction to search: \"In\" (upstream) or \"Out\" (downstream).\n\nOptional: leave empty to return neighbours in both directions.", Access = GH_ParamAccess.item, Optional = true }, ParamVisibility.Binding));

return [.. result];
}
Expand All @@ -65,7 +69,7 @@ protected override GH_SAMParam[] Outputs
get
{
List<GH_SAMParam> result = new List<GH_SAMParam>();
result.Add(new GH_SAMParam(new GooSystemComponentParam() { Name = "systemComponents", NickName = "systemComponents", Description = "System Components", Access = GH_ParamAccess.list }, ParamVisibility.Binding));
result.Add(new GH_SAMParam(new GooSystemComponentParam() { Name = "systemComponents", NickName = "systemComponents", Description = "The components directly connected to the input component along the chosen system and direction(s).", Access = GH_ParamAccess.list }, ParamVisibility.Binding));
return [.. result];
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ public class SAMAnalyticalSystemConnectedSystemGroups : GH_SAMVariableOutputPara
/// </summary>
public SAMAnalyticalSystemConnectedSystemGroups()
: base("SAMAnalytical.ConnectedSystemGroups", "SAMAnalytical.ConnectedSystemGroups",
"Gets Connected System Components",
"Gets the system groups that a given component belongs to within a plantroom.\n" +
"\n" +
"System groups are logical groupings of components (e.g. an air-handling unit). This returns every\n" +
"group related to the supplied component.",
"SAM", "Systems")
{
}
Expand All @@ -47,8 +50,8 @@ protected override GH_SAMParam[] Inputs
get
{
List<GH_SAMParam> result = [];
result.Add(new GH_SAMParam(new GooSystemPlantRoomParam() { Name = "_systemPlantRoom", NickName = "_systemPlantRoom", Description = "SystemPlantRoom", Access = GH_ParamAccess.item }, ParamVisibility.Binding));
result.Add(new GH_SAMParam(new GooSystemComponentParam() { Name = "_systemComponent", NickName = "_systemComponent", Description = "System Component", Access = GH_ParamAccess.item }, ParamVisibility.Binding));
result.Add(new GH_SAMParam(new GooSystemPlantRoomParam() { Name = "_systemPlantRoom", NickName = "_systemPlantRoom", Description = "The SAM SystemPlantRoom that holds the component and its groups.", Access = GH_ParamAccess.item }, ParamVisibility.Binding));
result.Add(new GH_SAMParam(new GooSystemComponentParam() { Name = "_systemComponent", NickName = "_systemComponent", Description = "The component whose owning system groups should be returned.", Access = GH_ParamAccess.item }, ParamVisibility.Binding));

return [.. result];
}
Expand All @@ -62,7 +65,7 @@ protected override GH_SAMParam[] Outputs
get
{
List<GH_SAMParam> result = [];
result.Add(new GH_SAMParam(new GooSystemObjectParam() { Name = "systemGroups", NickName = "systemGroups", Description = "System Groups", Access = GH_ParamAccess.list }, ParamVisibility.Binding));
result.Add(new GH_SAMParam(new GooSystemObjectParam() { Name = "systemGroups", NickName = "systemGroups", Description = "The system groups the component belongs to.", Access = GH_ParamAccess.list }, ParamVisibility.Binding));
return [.. result];
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ public class SAMAnalyticalSystemConnectedSystemObjects : GH_SAMVariableOutputPar
/// </summary>
public SAMAnalyticalSystemConnectedSystemObjects()
: base("SAMAnalytical.ConnectedSystemObjects", "SAMAnalytical.ConnectedSystemObjects",
"Gets Connected System Components",
"Gets every system object related to a given object within a plantroom.\n" +
"\n" +
"Returns all objects (components, connections, systems, sensors, groups, etc.) that the supplied\n" +
"object is related to - a general-purpose way to discover what an object touches in the plantroom.",
"SAM", "Systems")
{
}
Expand All @@ -47,8 +50,8 @@ protected override GH_SAMParam[] Inputs
get
{
List<GH_SAMParam> result = [];
result.Add(new GH_SAMParam(new GooSystemPlantRoomParam() { Name = "_systemPlantRoom", NickName = "_systemPlantRoom", Description = "SystemPlantRoom", Access = GH_ParamAccess.item }, ParamVisibility.Binding));
result.Add(new GH_SAMParam(new GooSystemObjectParam() { Name = "_systemObject", NickName = "_systemObject", Description = "System Object", Access = GH_ParamAccess.item }, ParamVisibility.Binding));
result.Add(new GH_SAMParam(new GooSystemPlantRoomParam() { Name = "_systemPlantRoom", NickName = "_systemPlantRoom", Description = "The SAM SystemPlantRoom whose relationships are queried.", Access = GH_ParamAccess.item }, ParamVisibility.Binding));
result.Add(new GH_SAMParam(new GooSystemObjectParam() { Name = "_systemObject", NickName = "_systemObject", Description = "The system object whose related objects should be returned.", Access = GH_ParamAccess.item }, ParamVisibility.Binding));

return [.. result];
}
Expand All @@ -62,7 +65,7 @@ protected override GH_SAMParam[] Outputs
get
{
List<GH_SAMParam> result = [];
result.Add(new GH_SAMParam(new GooSystemObjectParam() { Name = "systemObjects", NickName = "systemObjects", Description = "System Objects", Access = GH_ParamAccess.list }, ParamVisibility.Binding));
result.Add(new GH_SAMParam(new GooSystemObjectParam() { Name = "systemObjects", NickName = "systemObjects", Description = "All system objects related to the supplied object.", Access = GH_ParamAccess.list }, ParamVisibility.Binding));
return [.. result];
}
}
Expand Down
Loading
Loading