From 7fbe365599dfe54fe2fea58ddda8693c5024a830 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Thu, 4 Nov 2021 18:02:50 +1100 Subject: [PATCH] Implement new Brickschema project browser. --- src/blenderbim/Makefile | 33 + src/blenderbim/blenderbim/bim/__init__.py | 1 + .../blenderbim/bim/module/brick/__init__.py | 40 ++ .../blenderbim/bim/module/brick/data.py | 78 +++ .../blenderbim/bim/module/brick/operator.py | 84 +++ .../blenderbim/bim/module/brick/prop.py | 49 ++ .../blenderbim/bim/module/brick/ui.py | 67 ++ src/blenderbim/blenderbim/core/tool.py | 14 + src/blenderbim/blenderbim/tool/__init__.py | 1 + src/blenderbim/blenderbim/tool/brick.py | 137 ++++ src/blenderbim/pytest.ini | 1 + src/blenderbim/test/bim/feature/brick.feature | 32 + src/blenderbim/test/core/bootstrap.py | 7 + src/blenderbim/test/core/test_brick.py | 66 ++ src/blenderbim/test/files/building.ttl | 584 ++++++++++++++++++ src/blenderbim/test/tool/test_brick.py | 125 ++++ 16 files changed, 1319 insertions(+) create mode 100644 src/blenderbim/blenderbim/bim/module/brick/__init__.py create mode 100644 src/blenderbim/blenderbim/bim/module/brick/data.py create mode 100644 src/blenderbim/blenderbim/bim/module/brick/operator.py create mode 100644 src/blenderbim/blenderbim/bim/module/brick/prop.py create mode 100644 src/blenderbim/blenderbim/bim/module/brick/ui.py create mode 100644 src/blenderbim/blenderbim/tool/brick.py create mode 100644 src/blenderbim/test/bim/feature/brick.feature create mode 100644 src/blenderbim/test/core/test_brick.py create mode 100644 src/blenderbim/test/files/building.ttl create mode 100644 src/blenderbim/test/tool/test_brick.py diff --git a/src/blenderbim/Makefile b/src/blenderbim/Makefile index 06feae1f41..03715454e8 100644 --- a/src/blenderbim/Makefile +++ b/src/blenderbim/Makefile @@ -444,6 +444,39 @@ endif cd dist/working/olca-ipc-0.0.10/ && cp -r olca ../../blenderbim/libs/site/packages/ rm -rf dist/working + # Provides Brickschema fucntionality + mkdir dist/working + cd dist/working && wget https://files.pythonhosted.org/packages/ca/37/8309da9a72407d2f5eb5489c197ac3cfe96ee3ccba1902d2a0ecc7843f92/brickschema-0.5.1.tar.gz + cd dist/working && tar -xzvf brickschema* + # This is an evil hack because we don't want to bundle flask + echo "" > dist/working/brickschema-0.5.1/brickschema/web.py + cd dist/working/brickschema-0.5.1/ && cp -r brickschema ../../blenderbim/libs/site/packages/ + # For now lets bundle the latest nightly schema + cd dist/working && wget https://github.com/BrickSchema/Brick/releases/download/nightly/Brick.ttl + cd dist/working && cp Brick.ttl ../../blenderbim/bim/schema/Brick.ttl + rm -rf dist/working + + # Required by brickschema + mkdir dist/working + cd dist/working && wget https://files.pythonhosted.org/packages/c7/22/37bb938be8e5c20d443b0c9ba0a243573b671b01739efb0a19f81bc5b470/pyshacl-0.17.2.tar.gz + cd dist/working && tar -xzvf pyshacl* + cd dist/working/pyshacl-0.17.2/ && cp -r pyshacl ../../blenderbim/libs/site/packages/ + rm -rf dist/working + + # Required by brickschema + mkdir dist/working + cd dist/working && wget https://files.pythonhosted.org/packages/d2/a7/be8244688bfcee37c23733ab4fe8e6afa6d4403bd2674a3ae7bd2cecc77b/rdflib-6.0.2.tar.gz + cd dist/working && tar -xzvf rdflib* + cd dist/working/rdflib-6.0.2/ && cp -r rdflib ../../blenderbim/libs/site/packages/ + rm -rf dist/working + + # Required by brickschema + mkdir dist/working + cd dist/working && wget https://files.pythonhosted.org/packages/7d/c7/208aece36279e4f1236e437119358786e39530ecc1719d4e1afeddba5288/owlrl-6.0.2.tar.gz + cd dist/working && tar -xzvf owlrl* + cd dist/working/owlrl-6.0.2/ && cp -r owlrl ../../blenderbim/libs/site/packages/ + rm -rf dist/working + cd dist/blenderbim && sed -i "s/999999/$(VERSION)/" __init__.py cd dist && zip -r blenderbim-$(VERSION)-$(PYVERSION)-$(PLATFORM).zip ./* rm -rf dist/blenderbim diff --git a/src/blenderbim/blenderbim/bim/__init__.py b/src/blenderbim/blenderbim/bim/__init__.py index 57e29aaae0..356632626c 100644 --- a/src/blenderbim/blenderbim/bim/__init__.py +++ b/src/blenderbim/blenderbim/bim/__init__.py @@ -43,6 +43,7 @@ modules = { "sequence": None, "group": None, "system": None, + "brick": None, "structural": None, "boundary": None, "profile": None, diff --git a/src/blenderbim/blenderbim/bim/module/brick/__init__.py b/src/blenderbim/blenderbim/bim/module/brick/__init__.py new file mode 100644 index 0000000000..d9d6003110 --- /dev/null +++ b/src/blenderbim/blenderbim/bim/module/brick/__init__.py @@ -0,0 +1,40 @@ +# BlenderBIM Add-on - OpenBIM Blender Add-on +# Copyright (C) 2021 Dion Moult +# +# This file is part of BlenderBIM Add-on. +# +# BlenderBIM Add-on is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# BlenderBIM Add-on is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with BlenderBIM Add-on. If not, see . + +import bpy +from . import ui, prop, operator + +classes = ( + operator.CloseBrickProject, + operator.LoadBrickProject, + operator.RewindBrickClass, + operator.ViewBrickClass, + operator.ViewBrickItem, + prop.Brick, + prop.BIMBrickProperties, + ui.BIM_PT_brickschema, + ui.BIM_UL_bricks, +) + + +def register(): + bpy.types.Scene.BIMBrickProperties = bpy.props.PointerProperty(type=prop.BIMBrickProperties) + + +def unregister(): + del bpy.types.Scene.BIMBrickProperties diff --git a/src/blenderbim/blenderbim/bim/module/brick/data.py b/src/blenderbim/blenderbim/bim/module/brick/data.py new file mode 100644 index 0000000000..bd186e0973 --- /dev/null +++ b/src/blenderbim/blenderbim/bim/module/brick/data.py @@ -0,0 +1,78 @@ +# BlenderBIM Add-on - OpenBIM Blender Add-on +# Copyright (C) 2021 Dion Moult +# +# This file is part of BlenderBIM Add-on. +# +# BlenderBIM Add-on is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# BlenderBIM Add-on is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with BlenderBIM Add-on. If not, see . + +import bpy +import blenderbim.tool as tool +from blenderbim.tool.brick import BrickStore + + +def refresh(): + BrickschemaData.is_loaded = False + + +class BrickschemaData: + data = {} + is_loaded = False + + @classmethod + def load(cls): + cls.data = {"is_loaded": cls.get_is_loaded(), "attributes": cls.attributes()} + cls.is_loaded = True + + @classmethod + def get_is_loaded(cls): + return BrickStore.graph is not None + + @classmethod + def attributes(cls): + if BrickStore.graph is None: + return [] + props = bpy.context.scene.BIMBrickProperties + try: + brick = props.bricks[props.active_brick_index] + except: + return [] + results = [] + uri = brick.uri + query = BrickStore.graph.query( + """ + PREFIX brick: + PREFIX rdfs: + PREFIX rdf: + SELECT DISTINCT ?name ?value ?sp ?sv WHERE { + <{uri}> ?name ?value . + OPTIONAL { + { ?name rdfs:range brick:TimeseriesReference . } + UNION + { ?name a brick:EntityProperty . } + ?value ?sp ?sv } + } + """.replace( + "{uri}", uri + ) + ) + for row in query: + results.append( + { + "name": row.get("name").toPython().split("#")[-1], + "value": row.get("value").toPython().split("#")[-1], + "is_uri": "#" in row.get("value").toPython(), + "value_uri": row.get("value").toPython(), + } + ) + return results diff --git a/src/blenderbim/blenderbim/bim/module/brick/operator.py b/src/blenderbim/blenderbim/bim/module/brick/operator.py new file mode 100644 index 0000000000..bc11c4e296 --- /dev/null +++ b/src/blenderbim/blenderbim/bim/module/brick/operator.py @@ -0,0 +1,84 @@ +# BlenderBIM Add-on - OpenBIM Blender Add-on +# Copyright (C) 2021 Dion Moult +# +# This file is part of BlenderBIM Add-on. +# +# BlenderBIM Add-on is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# BlenderBIM Add-on is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with BlenderBIM Add-on. If not, see . + +import bpy +import ifcopenshell.api +import blenderbim.tool as tool +import blenderbim.core.brick as core +import blenderbim.bim.handler +from blenderbim.bim.ifc import IfcStore + + +class Operator: + def execute(self, context): + self._execute(context) + blenderbim.bim.handler.refresh_ui_data() + return {"FINISHED"} + + +class LoadBrickProject(bpy.types.Operator, Operator): + bl_idname = "bim.load_brick_project" + bl_label = "Load Brickschema Project" + bl_options = {"REGISTER", "UNDO"} + filepath: bpy.props.StringProperty(subtype="FILE_PATH") + filter_glob: bpy.props.StringProperty(default="*.ttl", options={"HIDDEN"}) + + def _execute(self, context): + core.load_brick_project(tool.Brick, filepath=self.filepath) + + def invoke(self, context, event): + context.window_manager.fileselect_add(self) + return {"RUNNING_MODAL"} + + +class ViewBrickClass(bpy.types.Operator, Operator): + bl_idname = "bim.view_brick_class" + bl_label = "View Brick Class" + bl_options = {"REGISTER", "UNDO"} + brick_class: bpy.props.StringProperty(name="Brick Class") + + def _execute(self, context): + core.view_brick_class(tool.Brick, brick_class=self.brick_class) + + +class ViewBrickItem(bpy.types.Operator, Operator): + bl_idname = "bim.view_brick_item" + bl_label = "View Brick Item" + bl_options = {"REGISTER", "UNDO"} + item: bpy.props.StringProperty(name="Brick Item") + + def _execute(self, context): + core.view_brick_item(tool.Brick, item=self.item) + + +class RewindBrickClass(bpy.types.Operator, Operator): + bl_idname = "bim.rewind_brick_class" + bl_label = "Rewind Brick Class" + bl_options = {"REGISTER", "UNDO"} + + def _execute(self, context): + core.rewind_brick_class(tool.Brick) + + +class CloseBrickProject(bpy.types.Operator, Operator): + bl_idname = "bim.close_brick_project" + bl_label = "Close Brick Project" + bl_options = {"REGISTER", "UNDO"} + + def _execute(self, context): + core.close_brick_project(tool.Brick) diff --git a/src/blenderbim/blenderbim/bim/module/brick/prop.py b/src/blenderbim/blenderbim/bim/module/brick/prop.py new file mode 100644 index 0000000000..8bd7f47d7e --- /dev/null +++ b/src/blenderbim/blenderbim/bim/module/brick/prop.py @@ -0,0 +1,49 @@ +# BlenderBIM Add-on - OpenBIM Blender Add-on +# Copyright (C) 2021 Dion Moult +# +# This file is part of BlenderBIM Add-on. +# +# BlenderBIM Add-on is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# BlenderBIM Add-on is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with BlenderBIM Add-on. If not, see . + +import bpy +from blenderbim.bim.module.brick.data import BrickschemaData +from blenderbim.bim.prop import StrProperty, Attribute +from bpy.types import PropertyGroup +from bpy.props import ( + PointerProperty, + StringProperty, + EnumProperty, + BoolProperty, + IntProperty, + FloatProperty, + FloatVectorProperty, + CollectionProperty, +) + + +def update_active_brick_index(self, context): + BrickschemaData.is_loaded = False + + +class Brick(PropertyGroup): + name: StringProperty(name="Name") + uri: StringProperty(name="URI") + total_items: IntProperty(name="Total Items") + + +class BIMBrickProperties(PropertyGroup): + active_brick_class: StringProperty(name="Active Brick Class") + brick_breadcrumbs: CollectionProperty(name="Brick Breadcrumbs", type=StrProperty) + bricks: CollectionProperty(name="Bricks", type=Brick) + active_brick_index: IntProperty(name="Active Brick Index", update=update_active_brick_index) diff --git a/src/blenderbim/blenderbim/bim/module/brick/ui.py b/src/blenderbim/blenderbim/bim/module/brick/ui.py new file mode 100644 index 0000000000..7854500ccb --- /dev/null +++ b/src/blenderbim/blenderbim/bim/module/brick/ui.py @@ -0,0 +1,67 @@ +# BlenderBIM Add-on - OpenBIM Blender Add-on +# Copyright (C) 2021 Dion Moult +# +# This file is part of BlenderBIM Add-on. +# +# BlenderBIM Add-on is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# BlenderBIM Add-on is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with BlenderBIM Add-on. If not, see . + +from bpy.types import Panel, UIList +from blenderbim.bim.module.brick.data import BrickschemaData + + +class BIM_PT_brickschema(Panel): + bl_label = "Brickschema Project" + bl_idname = "BIM_PT_brickschema" + bl_options = {"DEFAULT_CLOSED"} + bl_space_type = "PROPERTIES" + bl_region_type = "WINDOW" + bl_context = "scene" + + def draw(self, context): + if not BrickschemaData.is_loaded: + BrickschemaData.load() + self.props = context.scene.BIMBrickProperties + + if not BrickschemaData.data["is_loaded"]: + row = self.layout.row() + row.operator("bim.load_brick_project") + return + + row = self.layout.row(align=True) + if len(self.props.brick_breadcrumbs): + row.operator("bim.rewind_brick_class", text="", icon="FRAME_PREV") + row.label(text=self.props.active_brick_class) + row.operator("bim.close_brick_project", text="", icon="CANCEL") + + self.layout.template_list("BIM_UL_bricks", "", self.props, "bricks", self.props, "active_brick_index") + + for attribute in BrickschemaData.data["attributes"]: + row = self.layout.row(align=True) + row.label(text=attribute["name"]) + row.label(text=attribute["value"]) + if attribute["is_uri"]: + op = row.operator("bim.view_brick_item", text="", icon="DISCLOSURE_TRI_RIGHT") + op.item = attribute["value_uri"] + + +class BIM_UL_bricks(UIList): + def draw_item(self, context, layout, data, item, icon, active_data, active_propname): + if item: + row = layout.row(align=True) + if item.total_items: + op = row.operator("bim.view_brick_class", text="", icon="DISCLOSURE_TRI_RIGHT", emboss=False) + op.brick_class = item.name + row.label(text=item.name) + if item.total_items: + row.label(text=str(item.total_items)) diff --git a/src/blenderbim/blenderbim/core/tool.py b/src/blenderbim/blenderbim/core/tool.py index 73489a2d3c..b375c9d611 100644 --- a/src/blenderbim/blenderbim/core/tool.py +++ b/src/blenderbim/blenderbim/core/tool.py @@ -41,6 +41,20 @@ class Aggregate: class Blender: pass +@interface +class Brick: + def add_brick_breadcrumb(cls): pass + def clear_brick_browser(cls): pass + def clear_project(cls): pass + def get_item_class(cls, item): pass + def import_brick_classes(cls, brick_class): pass + def import_brick_items(cls, brick_class): pass + def load_brick_file(cls, filepath): pass + def pop_brick_breadcrumb(cls): pass + def select_browser_item(cls, item): pass + def set_active_brick_class(cls, brick_class): pass + + @interface class Collector: def assign(cls, obj): pass diff --git a/src/blenderbim/blenderbim/tool/__init__.py b/src/blenderbim/blenderbim/tool/__init__.py index a74888f16a..679ae4671e 100644 --- a/src/blenderbim/blenderbim/tool/__init__.py +++ b/src/blenderbim/blenderbim/tool/__init__.py @@ -18,6 +18,7 @@ from blenderbim.tool.aggregate import Aggregate from blenderbim.tool.blender import Blender +from blenderbim.tool.brick import Brick from blenderbim.tool.collector import Collector from blenderbim.tool.context import Context from blenderbim.tool.geometry import Geometry diff --git a/src/blenderbim/blenderbim/tool/brick.py b/src/blenderbim/blenderbim/tool/brick.py new file mode 100644 index 0000000000..7a581a8f46 --- /dev/null +++ b/src/blenderbim/blenderbim/tool/brick.py @@ -0,0 +1,137 @@ +# BlenderBIM Add-on - OpenBIM Blender Add-on +# Copyright (C) 2021 Dion Moult +# +# This file is part of BlenderBIM Add-on. +# +# BlenderBIM Add-on is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# BlenderBIM Add-on is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with BlenderBIM Add-on. If not, see . + +import os +import bpy +import brickschema +import blenderbim.core.tool +import blenderbim.tool as tool + + +class Brick(blenderbim.core.tool.Brick): + @classmethod + def set_user(cls, user): + bpy.context.scene.BIMOwnerProperties.active_user_id = user.id() + + @classmethod + def add_brick_breadcrumb(cls): + new = bpy.context.scene.BIMBrickProperties.brick_breadcrumbs.add() + new.name = bpy.context.scene.BIMBrickProperties.active_brick_class + + @classmethod + def clear_brick_browser(cls): + bpy.context.scene.BIMBrickProperties.bricks.clear() + + @classmethod + def clear_project(cls): + BrickStore.graph = None + bpy.context.scene.BIMBrickProperties.active_brick_class == "" + bpy.context.scene.BIMBrickProperties.brick_breadcrumbs.clear() + + @classmethod + def get_item_class(cls, item): + query = BrickStore.graph.query( + """ + PREFIX brick: + SELECT ?class WHERE { + <{item}> a ?class . + } + LIMIT 1 + """.replace( + "{item}", item + ) + ) + for row in query: + return row.get("class").toPython().split("#")[-1] + + @classmethod + def import_brick_classes(cls, brick_class): + query = BrickStore.graph.query( + """ + PREFIX brick: + PREFIX rdfs: + PREFIX rdf: + SELECT ?group (count(?item) as ?total_items) WHERE { + ?group rdfs:subClassOf brick:{brick_class} . + ?item rdf:type/rdfs:subClassOf* ?group + } + GROUP BY ?group + ORDER BY asc(?group) + """.replace( + "{brick_class}", brick_class + ) + ) + for row in query: + new = bpy.context.scene.BIMBrickProperties.bricks.add() + new.name = row.get("group").toPython().split("#")[-1] + new.uri = row.get("group").toPython() + new.total_items = row.get("total_items").toPython() + + @classmethod + def import_brick_items(cls, brick_class): + query = BrickStore.graph.query( + """ + PREFIX brick: + PREFIX rdfs: + PREFIX rdf: + SELECT ?item WHERE { + ?item rdf:type brick:{brick_class} + } + ORDER BY asc(?item) + """.replace( + "{brick_class}", brick_class + ) + ) + for row in query: + new = bpy.context.scene.BIMBrickProperties.bricks.add() + new.name = row.get("item").toPython().split("#")[-1] + new.uri = row.get("item").toPython() + + @classmethod + def load_brick_file(cls, filepath): + BrickStore.graph = brickschema.Graph() + cwd = os.path.dirname(os.path.realpath(__file__)) + schema_path = os.path.join(cwd, "..", "bim", "schema", "Brick.ttl") + BrickStore.graph.load_file(schema_path) + BrickStore.graph.load_file(filepath) + + @classmethod + def pop_brick_breadcrumb(cls): + crumb = bpy.context.scene.BIMBrickProperties.brick_breadcrumbs[-1] + name = crumb.name + last_index = len(bpy.context.scene.BIMBrickProperties.brick_breadcrumbs) - 1 + bpy.context.scene.BIMBrickProperties.brick_breadcrumbs.remove(last_index) + return name + + @classmethod + def select_browser_item(cls, item): + name = item.split("#")[-1] + props = bpy.context.scene.BIMBrickProperties + props.active_brick_index = props.bricks.find(name) + + @classmethod + def set_active_brick_class(cls, brick_class): + bpy.context.scene.BIMBrickProperties.active_brick_class = brick_class + + +class BrickStore: + graph = None + + @staticmethod + def purge(): + BrickStore.graph = None diff --git a/src/blenderbim/pytest.ini b/src/blenderbim/pytest.ini index 26176e123f..9998bc3007 100644 --- a/src/blenderbim/pytest.ini +++ b/src/blenderbim/pytest.ini @@ -3,6 +3,7 @@ markers = aggregate attribute bimtester + brick context geometry material diff --git a/src/blenderbim/test/bim/feature/brick.feature b/src/blenderbim/test/bim/feature/brick.feature new file mode 100644 index 0000000000..bdf940e1cf --- /dev/null +++ b/src/blenderbim/test/bim/feature/brick.feature @@ -0,0 +1,32 @@ +@brick +Feature: Brick + +Scenario: Load Brick project + Given an empty Blender session + When I press "bim.load_brick_project(filepath='{cwd}/test/files/building.ttl')" + Then nothing happens + +Scenario: View Brick class + Given an empty Blender session + And I press "bim.load_brick_project(filepath='{cwd}/test/files/building.ttl')" + When I press "bim.view_brick_class(brick_class='Equipment')" + Then nothing happens + +Scenario: View Brick item + Given an empty Blender session + And I press "bim.load_brick_project(filepath='{cwd}/test/files/building.ttl')" + When I press "bim.view_brick_item(item='https://brickschema.org/schema/Brick#Chiller')" + Then nothing happens + +Scenario: Rewind brick class + Given an empty Blender session + And I press "bim.load_brick_project(filepath='{cwd}/test/files/building.ttl')" + And I press "bim.view_brick_class(brick_class='Equipment')" + When I press "bim.rewind_brick_class()" + Then nothing happens + +Scenario: Close Brick project + Given an empty Blender session + And I press "bim.load_brick_project(filepath='{cwd}/test/files/building.ttl')" + When I press "bim.close_brick_project" + Then nothing happens diff --git a/src/blenderbim/test/core/bootstrap.py b/src/blenderbim/test/core/bootstrap.py index 4b32a6e8af..2757c36d32 100644 --- a/src/blenderbim/test/core/bootstrap.py +++ b/src/blenderbim/test/core/bootstrap.py @@ -35,6 +35,13 @@ def blender(): prophet.verify() +@pytest.fixture +def brick(): + prophet = Prophecy(blenderbim.core.tool.Brick) + yield prophet + prophet.verify() + + @pytest.fixture def aggregate(): prophet = Prophecy(blenderbim.core.tool.Aggregate) diff --git a/src/blenderbim/test/core/test_brick.py b/src/blenderbim/test/core/test_brick.py new file mode 100644 index 0000000000..0f34837b4d --- /dev/null +++ b/src/blenderbim/test/core/test_brick.py @@ -0,0 +1,66 @@ +# BlenderBIM Add-on - OpenBIM Blender Add-on +# Copyright (C) 2021 Dion Moult +# +# This file is part of BlenderBIM Add-on. +# +# BlenderBIM Add-on is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# BlenderBIM Add-on is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with BlenderBIM Add-on. If not, see . + +import blenderbim.core.brick as subject +from test.core.bootstrap import brick + + +class TestLoadBrickProject: + def test_run(self, brick): + brick.load_brick_file("filepath").should_be_called() + brick.import_brick_classes("Class").should_be_called() + brick.set_active_brick_class("Class").should_be_called() + subject.load_brick_project(brick, filepath="filepath") + + +class TestViewBrickClass: + def test_run(self, brick): + brick.add_brick_breadcrumb().should_be_called() + brick.clear_brick_browser().should_be_called() + brick.import_brick_classes("brick_class").should_be_called() + brick.import_brick_items("brick_class").should_be_called() + brick.set_active_brick_class("brick_class").should_be_called() + subject.view_brick_class(brick, brick_class="brick_class") + + +class TestViewBrickItem: + def test_run(self, brick): + brick.add_brick_breadcrumb().should_be_called() + brick.clear_brick_browser().should_be_called() + brick.get_item_class("item").should_be_called().will_return("brick_class") + brick.import_brick_classes("brick_class").should_be_called() + brick.import_brick_items("brick_class").should_be_called() + brick.set_active_brick_class("brick_class").should_be_called() + brick.select_browser_item("item").should_be_called() + subject.view_brick_item(brick, item="item") + + +class TestRewindBrickClass: + def test_run(self, brick): + brick.pop_brick_breadcrumb().should_be_called().will_return("previous_class") + brick.clear_brick_browser().should_be_called() + brick.import_brick_classes("previous_class").should_be_called() + brick.import_brick_items("previous_class").should_be_called() + brick.set_active_brick_class("previous_class").should_be_called() + subject.rewind_brick_class(brick) + + +class TestCloseBrickProject: + def test_run(self, brick): + brick.clear_project().should_be_called() + subject.close_brick_project(brick) diff --git a/src/blenderbim/test/files/building.ttl b/src/blenderbim/test/files/building.ttl new file mode 100644 index 0000000000..65ccf91396 --- /dev/null +++ b/src/blenderbim/test/files/building.ttl @@ -0,0 +1,584 @@ +@prefix brick: . +@prefix ns2: . +@prefix ns4: . +@prefix rdfs: . +@prefix unit: . + +ns2:AHU01 a brick:Air_Handler_Unit ; + brick:feeds ns2:VAVRM107A, + ns2:VAVRM107B, + ns2:VAVRM115, + ns2:VAVRM120 ; + brick:hasPoint ns2:AHU.AHU01.CCV, + ns2:AHU.AHU01.Cooling_Valve_Output, + ns2:AHU.AHU01.Mixed_Air_Temp, + ns2:AHU.AHU01.Outside_Air_Temp, + ns2:AHU.AHU01.Return_Air_Temp, + ns2:AHU.AHU01.Supply_Air_Pressure, + ns2:AHU.AHU01.Supply_Air_Temp, + ns2:AHU.AHU01.Supply_Air_Temp_Setpoint ; + brick:isFedBy ns2:chiller . + +ns2:AHU02 a brick:Air_Handler_Unit ; + brick:feeds ns2:VAVRM100, + ns2:VAVRM103, + ns2:VAVRM110, + ns2:VAVRM112 ; + brick:hasPoint ns2:AHU.AHU02.CCV, + ns2:AHU.AHU02.Cooling_Valve_Output, + ns2:AHU.AHU02.Mixed_Air_Temp, + ns2:AHU.AHU02.Outside_Air_Temp, + ns2:AHU.AHU02.Return_Air_Temp, + ns2:AHU.AHU02.Supply_Air_Pressure, + ns2:AHU.AHU02.Supply_Air_Temp ; + brick:isFedBy ns2:chiller . + +ns2:BLDG a brick:Building ; + brick:area [ brick:hasUnits unit:FT_2 ; + brick:value "9973^^" ] . + +ns2:damperVAVRM100 a brick:Damper ; + brick:hasPoint ns2:ZONE.AHU02.RM100.Zone_Air_Damper_Command ; + brick:isPartOf ns2:VAVRM100 . + +ns2:damperVAVRM103 a brick:Damper ; + brick:hasPoint ns2:ZONE.AHU02.RM103.Zone_Air_Damper_Command ; + brick:isPartOf ns2:VAVRM103 . + +ns2:damperVAVRM107A a brick:Damper ; + brick:hasPoint ns2:ZONE.AHU01.RM107A.Zone_Air_Damper_Command ; + brick:isPartOf ns2:VAVRM107A . + +ns2:damperVAVRM107B a brick:Damper ; + brick:hasPoint ns2:ZONE.AHU01.RM107B.Zone_Air_Damper_Command ; + brick:isPartOf ns2:VAVRM107B . + +ns2:damperVAVRM110 a brick:Damper ; + brick:hasPoint ns2:ZONE.AHU02.RM110.Zone_Air_Damper_Command ; + brick:isPartOf ns2:VAVRM110 . + +ns2:damperVAVRM112 a brick:Damper ; + brick:hasPoint ns2:ZONE.AHU02.RM112.Zone_Air_Damper_Command ; + brick:isPartOf ns2:VAVRM112 . + +ns2:damperVAVRM115 a brick:Damper ; + brick:hasPoint ns2:ZONE.AHU01.RM115.Zone_Air_Damper_Command ; + brick:isPartOf ns2:VAVRM115 . + +ns2:damperVAVRM120 a brick:Damper ; + brick:hasPoint ns2:ZONE.AHU01.RM120.Zone_Air_Damper_Command ; + brick:isPartOf ns2:VAVRM120 . + +ns2:floor1 a brick:Floor ; + brick:hasPart ns2:RM100_room, + ns2:RM103_room, + ns2:RM107A_room, + ns2:RM107B_room, + ns2:RM110_room, + ns2:RM112_room, + ns2:RM115_room, + ns2:RM120_room . + +ns2:AHU.AHU01.CCV a brick:Cooling_Command, + brick:Valve_Command ; + rdfs:label "AHU.AHU01.CCV" ; + brick:timeseries [ brick:hasTimeseriesId "849c17ad-343b-41b0-bb9b-a2e9d7c47c68" ] . + +ns2:AHU.AHU01.Cooling_Valve_Output a brick:Cooling_Command, + brick:Valve_Command ; + rdfs:label "AHU.AHU01.Cooling Valve Output" ; + brick:timeseries [ brick:hasTimeseriesId "d0209901-ed29-4ac8-bc26-1b26a680f40b" ] . + +ns2:AHU.AHU01.Mixed_Air_Temp a brick:Mixed_Air_Temperature_Sensor ; + rdfs:label "AHU.AHU01.Mixed Air Temp" . + +ns2:AHU.AHU01.Outside_Air_Temp a brick:Outside_Air_Temperature_Sensor ; + rdfs:label "AHU.AHU01.Outside Air Temp" ; + brick:timeseries [ brick:hasTimeseriesId "a52505ae-f1b6-451b-ab60-6a9018efcbb0" ] . + +ns2:AHU.AHU01.Return_Air_Temp a brick:Return_Air_Temperature_Sensor ; + rdfs:label "AHU.AHU01.Return Air Temp" ; + brick:timeseries [ brick:hasTimeseriesId "54317e55-d0b4-4c87-869a-cf15d8d25abc" ] . + +ns2:AHU.AHU01.Supply_Air_Pressure a brick:Supply_Air_Static_Pressure_Sensor ; + rdfs:label "AHU.AHU01.Supply Air Pressure" ; + brick:timeseries [ brick:hasTimeseriesId "3ce2fdb1-469b-47eb-9ca4-c8ebcde6c713" ] . + +ns2:AHU.AHU01.Supply_Air_Temp a brick:Supply_Air_Temperature_Sensor ; + rdfs:label "AHU.AHU01.Supply Air Temp" ; + brick:timeseries [ brick:hasTimeseriesId "0481a1cf-1092-4bd2-92ed-376f5c24bee5" ] . + +ns2:AHU.AHU01.Supply_Air_Temp_Setpoint a brick:Supply_Air_Temperature_Setpoint ; + rdfs:label "AHU.AHU01.Supply Air Temp Setpoint" ; + brick:timeseries [ brick:hasTimeseriesId "d50328c3-9410-4217-a667-38526546551c" ] . + +ns2:AHU.AHU02.CCV a brick:Cooling_Command, + brick:Valve_Command ; + rdfs:label "AHU.AHU02.CCV" ; + brick:timeseries [ brick:hasTimeseriesId "25f61eb5-d498-40b4-ad0e-9b01325c67b6" ] . + +ns2:AHU.AHU02.Cooling_Valve_Output a brick:Cooling_Command, + brick:Valve_Command ; + rdfs:label "AHU.AHU02.Cooling Valve Output" ; + brick:timeseries [ brick:hasTimeseriesId "f3bfc8c8-c769-41fa-9b56-367c61ba2ffa" ] . + +ns2:AHU.AHU02.Mixed_Air_Temp a brick:Mixed_Air_Temperature_Sensor ; + rdfs:label "AHU.AHU02.Mixed Air Temp" . + +ns2:AHU.AHU02.Outside_Air_Temp a brick:Outside_Air_Temperature_Sensor ; + rdfs:label "AHU.AHU02.Outside Air Temp" . + +ns2:AHU.AHU02.Return_Air_Temp a brick:Return_Air_Temperature_Sensor ; + rdfs:label "AHU.AHU02.Return Air Temp" ; + brick:timeseries [ brick:hasTimeseriesId "64abb724-b682-4f14-898d-db887359bc71" ] . + +ns2:AHU.AHU02.Supply_Air_Pressure a brick:Supply_Air_Static_Pressure_Sensor ; + rdfs:label "AHU.AHU02.Supply Air Pressure" ; + brick:timeseries [ brick:hasTimeseriesId "aa6cbab8-f5c7-4bde-a4c1-46ede7f17c42" ] . + +ns2:AHU.AHU02.Supply_Air_Temp a brick:Supply_Air_Temperature_Sensor ; + rdfs:label "AHU.AHU02.Supply Air Temp" ; + brick:timeseries [ brick:hasTimeseriesId "de577867-dc26-4a7f-afa5-c7257f2da030" ] . + +ns2:CHW.Building_Chilled_Water_Return_Temp a brick:Chilled_Water_Return_Temperature_Sensor ; + rdfs:label "CHW.Building Chilled Water Return Temp" ; + brick:timeseries [ brick:hasTimeseriesId "2fd18842-a01f-44cc-8376-036a332ca04f" ] . + +ns2:CHW.Building_Chilled_Water_Supply_Temp a brick:Chilled_Water_Supply_Temperature_Sensor ; + rdfs:label "CHW.Building Chilled Water Supply Temp" ; + brick:timeseries [ brick:hasTimeseriesId "a4232bbc-652c-4574-847b-4a7c4a4d966f" ] . + +ns2:CHW.ECONOMIZER a brick:Damper_Position_Command ; + rdfs:label "CHW.ECONOMIZER" ; + brick:timeseries [ brick:hasTimeseriesId "d79fd637-8854-4c84-abff-a787c97ca884" ] . + +ns2:CHW.Loop_Chilled_Water_Return_Temp a brick:Chilled_Water_Return_Temperature_Sensor ; + rdfs:label "CHW.Loop Chilled Water Return Temp" ; + brick:timeseries [ brick:hasTimeseriesId "64be6ecd-1960-4a12-bc62-d3454204e2c1" ] . + +ns2:CHW.Loop_Chilled_Water_Supply_Temp a brick:Chilled_Water_Supply_Temperature_Sensor ; + rdfs:label "CHW.Loop Chilled Water Supply Temp" ; + brick:timeseries [ brick:hasTimeseriesId "d7c6db4c-10e4-4569-b292-925b177b9dc6" ] . + +ns4:Stop a brick:Start_Stop_Command ; + rdfs:label "CHW.Pump1_Start/Stop" ; + brick:timeseries [ brick:hasTimeseriesId "ece06123-f7a2-4e0e-8292-d4ce667e8c3d" ] . + +ns2:ZONE.AHU01.RM107A.Zone_Air_Control_Temp a brick:Zone_Air_Temperature_Setpoint ; + rdfs:label "ZONE.AHU01.RM107A.Zone Air Control Temp" ; + brick:timeseries [ brick:hasTimeseriesId "a99860c0-f693-42b8-acce-342a2681efb2" ] . + +ns2:ZONE.AHU01.RM107A.Zone_Air_Damper_Command a brick:Damper_Position_Setpoint ; + rdfs:label "ZONE.AHU01.RM107A.Zone Air Damper Command" ; + brick:timeseries [ brick:hasTimeseriesId "30e70beb-717f-46fa-8ff4-52e4eb21cd89" ] . + +ns2:ZONE.AHU01.RM107A.Zone_Air_Temp a brick:Zone_Air_Temperature_Sensor ; + rdfs:label "ZONE.AHU01.RM107A.Zone Air Temp" ; + brick:timeseries [ brick:hasTimeseriesId "f1b2906b-2b63-47c1-9c1d-ae50618f9bb9" ] . + +ns2:ZONE.AHU01.RM107A.Zone_Air_Temp_Setpoint a brick:Zone_Air_Temperature_Setpoint ; + rdfs:label "ZONE.AHU01.RM107A.Zone Air Temp Setpoint" ; + brick:timeseries [ brick:hasTimeseriesId "97a6f762-bccb-400b-9da8-94a432151f5c" ] . + +ns2:ZONE.AHU01.RM107A.Zone_Heating_Mode a brick:Heating_Command ; + rdfs:label "ZONE.AHU01.RM107A.Zone Heating Mode" . + +ns2:ZONE.AHU01.RM107A.Zone_Percent_Air_Flow a brick:Air_Flow_Sensor ; + rdfs:label "ZONE.AHU01.RM107A.Zone Percent Air Flow" ; + brick:timeseries [ brick:hasTimeseriesId "29aeaf32-9827-49b1-8d9d-6d973ee2653c" ] . + +ns2:ZONE.AHU01.RM107A.Zone_Reheat_Valve_Command a brick:Command ; + rdfs:label "ZONE.AHU01.RM107A.Zone Reheat Valve Command" ; + brick:timeseries [ brick:hasTimeseriesId "80ea00dd-04fd-435b-a639-3663b2ebc24c" ] . + +ns2:ZONE.AHU01.RM107A.Zone_Supply_Air_Flow a brick:Supply_Air_Flow_Sensor ; + rdfs:label "ZONE.AHU01.RM107A.Zone Supply Air Flow" ; + brick:timeseries [ brick:hasTimeseriesId "069e8b5e-185f-4129-a243-03fc502239d4" ] . + +ns2:ZONE.AHU01.RM107A.Zone_Supply_Air_Temp a brick:Supply_Air_Temperature_Sensor ; + rdfs:label "ZONE.AHU01.RM107A.Zone Supply Air Temp" ; + brick:timeseries [ brick:hasTimeseriesId "0a07c546-320a-4a0b-9fc4-a3a54d5e8d90" ] . + +ns2:ZONE.AHU01.RM107B.Zone_Air_Control_Temp a brick:Zone_Air_Temperature_Setpoint ; + rdfs:label "ZONE.AHU01.RM107B.Zone Air Control Temp" ; + brick:timeseries [ brick:hasTimeseriesId "853d2889-1929-4b3c-9919-c3829973a753" ] . + +ns2:ZONE.AHU01.RM107B.Zone_Air_Damper_Command a brick:Damper_Position_Setpoint ; + rdfs:label "ZONE.AHU01.RM107B.Zone Air Damper Command" ; + brick:timeseries [ brick:hasTimeseriesId "713ad6f8-56ae-495b-a6e4-8158ad5460db" ] . + +ns2:ZONE.AHU01.RM107B.Zone_Air_Temp a brick:Zone_Air_Temperature_Sensor ; + rdfs:label "ZONE.AHU01.RM107B.Zone Air Temp" ; + brick:timeseries [ brick:hasTimeseriesId "ca0764b5-079c-431d-a4ee-60ff75b92bf8" ] . + +ns2:ZONE.AHU01.RM107B.Zone_Air_Temp_Setpoint a brick:Zone_Air_Temperature_Setpoint ; + rdfs:label "ZONE.AHU01.RM107B.Zone Air Temp Setpoint" ; + brick:timeseries [ brick:hasTimeseriesId "baa08d2c-f937-4188-a751-ae127e94c2d5" ] . + +ns2:ZONE.AHU01.RM107B.Zone_Heating_Mode a brick:Heating_Command ; + rdfs:label "ZONE.AHU01.RM107B.Zone Heating Mode" . + +ns2:ZONE.AHU01.RM107B.Zone_Percent_Air_Flow a brick:Air_Flow_Sensor ; + rdfs:label "ZONE.AHU01.RM107B.Zone Percent Air Flow" ; + brick:timeseries [ brick:hasTimeseriesId "88f751d8-9f64-4d6e-985d-590901669bda" ] . + +ns2:ZONE.AHU01.RM107B.Zone_Reheat_Valve_Command a brick:Command ; + rdfs:label "ZONE.AHU01.RM107B.Zone Reheat Valve Command" ; + brick:timeseries [ brick:hasTimeseriesId "220c62ce-0063-4f70-aec3-7c5caf7cf9bc" ] . + +ns2:ZONE.AHU01.RM107B.Zone_Supply_Air_Flow a brick:Supply_Air_Flow_Sensor ; + rdfs:label "ZONE.AHU01.RM107B.Zone Supply Air Flow" ; + brick:timeseries [ brick:hasTimeseriesId "4f04bb7d-260e-4cee-a7da-9ff5872a7866" ] . + +ns2:ZONE.AHU01.RM107B.Zone_Supply_Air_Temp a brick:Supply_Air_Temperature_Sensor ; + rdfs:label "ZONE.AHU01.RM107B.Zone Supply Air Temp" ; + brick:timeseries [ brick:hasTimeseriesId "e913807e-d3a1-497a-a072-01b738c4819f" ] . + +ns2:ZONE.AHU01.RM115.Zone_Air_Control_Temp a brick:Zone_Air_Temperature_Setpoint ; + rdfs:label "ZONE.AHU01.RM115.Zone Air Control Temp" ; + brick:timeseries [ brick:hasTimeseriesId "69bde0d1-20d1-444c-a4d5-4dc6ab86dc6b" ] . + +ns2:ZONE.AHU01.RM115.Zone_Air_Damper_Command a brick:Damper_Position_Setpoint ; + rdfs:label "ZONE.AHU01.RM115.Zone Air Damper Command" ; + brick:timeseries [ brick:hasTimeseriesId "d23760d3-f13d-438d-9144-ccbd363aa109" ] . + +ns2:ZONE.AHU01.RM115.Zone_Air_Temp a brick:Zone_Air_Temperature_Sensor ; + rdfs:label "ZONE.AHU01.RM115.Zone Air Temp" ; + brick:timeseries [ brick:hasTimeseriesId "8368a065-a593-4617-a92d-3d047861d86e" ] . + +ns2:ZONE.AHU01.RM115.Zone_Air_Temp_Setpoint a brick:Zone_Air_Temperature_Setpoint ; + rdfs:label "ZONE.AHU01.RM115.Zone Air Temp Setpoint" ; + brick:timeseries [ brick:hasTimeseriesId "d22d42e0-41c9-4a21-9141-e0a848208533" ] . + +ns2:ZONE.AHU01.RM115.Zone_Heating_Mode a brick:Heating_Command ; + rdfs:label "ZONE.AHU01.RM115.Zone Heating Mode" . + +ns2:ZONE.AHU01.RM115.Zone_Percent_Air_Flow a brick:Air_Flow_Sensor ; + rdfs:label "ZONE.AHU01.RM115.Zone Percent Air Flow" ; + brick:timeseries [ brick:hasTimeseriesId "2b07fbea-2907-4e86-a114-99ccd437df8a" ] . + +ns2:ZONE.AHU01.RM115.Zone_Reheat_Valve_Command a brick:Command ; + rdfs:label "ZONE.AHU01.RM115.Zone Reheat Valve Command" ; + brick:timeseries [ brick:hasTimeseriesId "58da756a-fc0c-447d-b3c1-bf1cbfb5feee" ] . + +ns2:ZONE.AHU01.RM115.Zone_Supply_Air_Flow a brick:Supply_Air_Flow_Sensor ; + rdfs:label "ZONE.AHU01.RM115.Zone Supply Air Flow" ; + brick:timeseries [ brick:hasTimeseriesId "062881ba-47d6-4ca3-a097-34bf186db590" ] . + +ns2:ZONE.AHU01.RM115.Zone_Supply_Air_Temp a brick:Supply_Air_Temperature_Sensor ; + rdfs:label "ZONE.AHU01.RM115.Zone Supply Air Temp" ; + brick:timeseries [ brick:hasTimeseriesId "1d412083-8513-4af4-ab6a-98ecc8719f38" ] . + +ns2:ZONE.AHU01.RM120.Zone_Air_Control_Temp a brick:Zone_Air_Temperature_Setpoint ; + rdfs:label "ZONE.AHU01.RM120.Zone Air Control Temp" ; + brick:timeseries [ brick:hasTimeseriesId "24c6c142-d5e8-4726-b056-154a4594d885" ] . + +ns2:ZONE.AHU01.RM120.Zone_Air_Damper_Command a brick:Damper_Position_Setpoint ; + rdfs:label "ZONE.AHU01.RM120.Zone Air Damper Command" ; + brick:timeseries [ brick:hasTimeseriesId "e4cfe3c2-7657-4e51-a94d-e2636f0aab18" ] . + +ns2:ZONE.AHU01.RM120.Zone_Air_Temp a brick:Zone_Air_Temperature_Sensor ; + rdfs:label "ZONE.AHU01.RM120.Zone Air Temp" ; + brick:timeseries [ brick:hasTimeseriesId "c35e8c50-55df-4d30-a816-acac325e46d4" ] . + +ns2:ZONE.AHU01.RM120.Zone_Air_Temp_Setpoint a brick:Zone_Air_Temperature_Setpoint ; + rdfs:label "ZONE.AHU01.RM120.Zone Air Temp Setpoint" ; + brick:timeseries [ brick:hasTimeseriesId "427bdd4a-7ab5-4315-82ba-5e8f819fcbb1" ] . + +ns2:ZONE.AHU01.RM120.Zone_Heating_Mode a brick:Heating_Command ; + rdfs:label "ZONE.AHU01.RM120.Zone Heating Mode" . + +ns2:ZONE.AHU01.RM120.Zone_Percent_Air_Flow a brick:Air_Flow_Sensor ; + rdfs:label "ZONE.AHU01.RM120.Zone Percent Air Flow" ; + brick:timeseries [ brick:hasTimeseriesId "b34ffaea-3f0a-4abd-9094-ccd18e5c56c9" ] . + +ns2:ZONE.AHU01.RM120.Zone_Reheat_Valve_Command a brick:Command ; + rdfs:label "ZONE.AHU01.RM120.Zone Reheat Valve Command" ; + brick:timeseries [ brick:hasTimeseriesId "4d975209-1ef5-4e36-9acc-e74b50d5ad31" ] . + +ns2:ZONE.AHU01.RM120.Zone_Supply_Air_Flow a brick:Supply_Air_Flow_Sensor ; + rdfs:label "ZONE.AHU01.RM120.Zone Supply Air Flow" ; + brick:timeseries [ brick:hasTimeseriesId "42619a81-4074-4309-9098-64b77235afeb" ] . + +ns2:ZONE.AHU01.RM120.Zone_Supply_Air_Temp a brick:Supply_Air_Temperature_Sensor ; + rdfs:label "ZONE.AHU01.RM120.Zone Supply Air Temp" ; + brick:timeseries [ brick:hasTimeseriesId "122d9f60-cc9c-4b28-95a0-5585713fc8e9" ] . + +ns2:ZONE.AHU02.RM100.Zone_Air_Control_Temp a brick:Zone_Air_Temperature_Setpoint ; + rdfs:label "ZONE.AHU02.RM100.Zone Air Control Temp" ; + brick:timeseries [ brick:hasTimeseriesId "bf982460-8151-432c-a928-87c924886d38" ] . + +ns2:ZONE.AHU02.RM100.Zone_Air_Damper_Command a brick:Damper_Position_Setpoint ; + rdfs:label "ZONE.AHU02.RM100.Zone Air Damper Command" ; + brick:timeseries [ brick:hasTimeseriesId "852b53c5-c805-4030-82f7-d58f73ab1b0b" ] . + +ns2:ZONE.AHU02.RM100.Zone_Air_Temp a brick:Zone_Air_Temperature_Sensor ; + rdfs:label "ZONE.AHU02.RM100.Zone Air Temp" ; + brick:timeseries [ brick:hasTimeseriesId "ce35a53a-bbf5-491f-a4cd-2685395d0665" ] . + +ns2:ZONE.AHU02.RM100.Zone_Air_Temp_Setpoint a brick:Zone_Air_Temperature_Setpoint ; + rdfs:label "ZONE.AHU02.RM100.Zone Air Temp Setpoint" ; + brick:timeseries [ brick:hasTimeseriesId "e283e0a5-99b1-47c6-9313-540ca777b7c5" ] . + +ns2:ZONE.AHU02.RM100.Zone_Heating_Mode a brick:Heating_Command ; + rdfs:label "ZONE.AHU02.RM100.Zone Heating Mode" . + +ns2:ZONE.AHU02.RM100.Zone_Percent_Air_Flow a brick:Air_Flow_Sensor ; + rdfs:label "ZONE.AHU02.RM100.Zone Percent Air Flow" ; + brick:timeseries [ brick:hasTimeseriesId "3178f935-2ef3-4a55-925b-d62c155237e1" ] . + +ns2:ZONE.AHU02.RM100.Zone_Reheat_Valve_Command a brick:Command ; + rdfs:label "ZONE.AHU02.RM100.Zone Reheat Valve Command" ; + brick:timeseries [ brick:hasTimeseriesId "78c103f8-1179-4df7-9b30-19f4bdd89dac" ] . + +ns2:ZONE.AHU02.RM100.Zone_Supply_Air_Flow a brick:Supply_Air_Flow_Sensor ; + rdfs:label "ZONE.AHU02.RM100.Zone Supply Air Flow" ; + brick:timeseries [ brick:hasTimeseriesId "28c78169-b187-4efd-951b-384d516cd504" ] . + +ns2:ZONE.AHU02.RM100.Zone_Supply_Air_Temp a brick:Supply_Air_Temperature_Sensor ; + rdfs:label "ZONE.AHU02.RM100.Zone Supply Air Temp" ; + brick:timeseries [ brick:hasTimeseriesId "ae92f608-859f-489d-9363-d461f18cea78" ] . + +ns2:ZONE.AHU02.RM103.Zone_Air_Control_Temp a brick:Zone_Air_Temperature_Setpoint ; + rdfs:label "ZONE.AHU02.RM103.Zone Air Control Temp" ; + brick:timeseries [ brick:hasTimeseriesId "66fcfc3c-ca14-429d-ae65-0633c111073e" ] . + +ns2:ZONE.AHU02.RM103.Zone_Air_Damper_Command a brick:Damper_Position_Setpoint ; + rdfs:label "ZONE.AHU02.RM103.Zone Air Damper Command" ; + brick:timeseries [ brick:hasTimeseriesId "eb74d290-3e79-4e46-ba4f-39acae483d72" ] . + +ns2:ZONE.AHU02.RM103.Zone_Air_Temp a brick:Zone_Air_Temperature_Sensor ; + rdfs:label "ZONE.AHU02.RM103.Zone Air Temp" ; + brick:timeseries [ brick:hasTimeseriesId "4e05069e-78cc-4bda-a8e2-ae3d15f1c604" ] . + +ns2:ZONE.AHU02.RM103.Zone_Air_Temp_Setpoint a brick:Zone_Air_Temperature_Setpoint ; + rdfs:label "ZONE.AHU02.RM103.Zone Air Temp Setpoint" ; + brick:timeseries [ brick:hasTimeseriesId "79d29db2-307b-4d96-b4e9-e9ebbaea00c0" ] . + +ns2:ZONE.AHU02.RM103.Zone_Heating_Mode a brick:Heating_Command ; + rdfs:label "ZONE.AHU02.RM103.Zone Heating Mode" . + +ns2:ZONE.AHU02.RM103.Zone_Percent_Air_Flow a brick:Air_Flow_Sensor ; + rdfs:label "ZONE.AHU02.RM103.Zone Percent Air Flow" ; + brick:timeseries [ brick:hasTimeseriesId "05d7494a-4653-4c30-8f66-9eaf964ee1a5" ] . + +ns2:ZONE.AHU02.RM103.Zone_Reheat_Valve_Command a brick:Command ; + rdfs:label "ZONE.AHU02.RM103.Zone Reheat Valve Command" ; + brick:timeseries [ brick:hasTimeseriesId "965b71e7-4315-4dd1-a94a-d47b3467ba35" ] . + +ns2:ZONE.AHU02.RM103.Zone_Supply_Air_Flow a brick:Supply_Air_Flow_Sensor ; + rdfs:label "ZONE.AHU02.RM103.Zone Supply Air Flow" ; + brick:timeseries [ brick:hasTimeseriesId "8d9f309f-9729-4fb8-9d47-d095b590d00d" ] . + +ns2:ZONE.AHU02.RM103.Zone_Supply_Air_Temp a brick:Supply_Air_Temperature_Sensor ; + rdfs:label "ZONE.AHU02.RM103.Zone Supply Air Temp" ; + brick:timeseries [ brick:hasTimeseriesId "9f8a2092-28f2-4731-ba2e-2d0608af219c" ] . + +ns2:ZONE.AHU02.RM110.Zone_Air_Control_Temp a brick:Zone_Air_Temperature_Setpoint ; + rdfs:label "ZONE.AHU02.RM110.Zone Air Control Temp" ; + brick:timeseries [ brick:hasTimeseriesId "69df025f-2405-4c8a-a64b-f4315229081e" ] . + +ns2:ZONE.AHU02.RM110.Zone_Air_Damper_Command a brick:Damper_Position_Setpoint ; + rdfs:label "ZONE.AHU02.RM110.Zone Air Damper Command" ; + brick:timeseries [ brick:hasTimeseriesId "e257e073-e0bf-426c-871e-ff5c1375c3b8" ] . + +ns2:ZONE.AHU02.RM110.Zone_Air_Temp a brick:Zone_Air_Temperature_Sensor ; + rdfs:label "ZONE.AHU02.RM110.Zone Air Temp" ; + brick:timeseries [ brick:hasTimeseriesId "1634482d-8b5d-45a2-bea1-661202b3e337" ] . + +ns2:ZONE.AHU02.RM110.Zone_Air_Temp_Setpoint a brick:Zone_Air_Temperature_Setpoint ; + rdfs:label "ZONE.AHU02.RM110.Zone Air Temp Setpoint" ; + brick:timeseries [ brick:hasTimeseriesId "83d51b64-b30d-498a-9526-52a597bf18b6" ] . + +ns2:ZONE.AHU02.RM110.Zone_Heating_Mode a brick:Heating_Command ; + rdfs:label "ZONE.AHU02.RM110.Zone Heating Mode" . + +ns2:ZONE.AHU02.RM110.Zone_Percent_Air_Flow a brick:Air_Flow_Sensor ; + rdfs:label "ZONE.AHU02.RM110.Zone Percent Air Flow" ; + brick:timeseries [ brick:hasTimeseriesId "01f5cba4-111b-42a4-bbb4-4844ec3ad6f6" ] . + +ns2:ZONE.AHU02.RM110.Zone_Reheat_Valve_Command a brick:Command ; + rdfs:label "ZONE.AHU02.RM110.Zone Reheat Valve Command" ; + brick:timeseries [ brick:hasTimeseriesId "d4011153-1c79-49fb-9697-90f5f3f6044a" ] . + +ns2:ZONE.AHU02.RM110.Zone_Supply_Air_Flow a brick:Supply_Air_Flow_Sensor ; + rdfs:label "ZONE.AHU02.RM110.Zone Supply Air Flow" ; + brick:timeseries [ brick:hasTimeseriesId "06b9bf19-c0a2-4804-b917-665857b495a2" ] . + +ns2:ZONE.AHU02.RM110.Zone_Supply_Air_Temp a brick:Supply_Air_Temperature_Sensor ; + rdfs:label "ZONE.AHU02.RM110.Zone Supply Air Temp" ; + brick:timeseries [ brick:hasTimeseriesId "6162aa89-3ac4-40bd-af5d-69711606181f" ] . + +ns2:ZONE.AHU02.RM112.Zone_Air_Control_Temp a brick:Zone_Air_Temperature_Setpoint ; + rdfs:label "ZONE.AHU02.RM112.Zone Air Control Temp" ; + brick:timeseries [ brick:hasTimeseriesId "fa630d31-f6eb-4fa5-91f2-73e94ed55694" ] . + +ns2:ZONE.AHU02.RM112.Zone_Air_Damper_Command a brick:Damper_Position_Setpoint ; + rdfs:label "ZONE.AHU02.RM112.Zone Air Damper Command" ; + brick:timeseries [ brick:hasTimeseriesId "cc5c6ad9-8b8c-4291-81d7-07f7cb8a685b" ] . + +ns2:ZONE.AHU02.RM112.Zone_Air_Temp a brick:Zone_Air_Temperature_Sensor ; + rdfs:label "ZONE.AHU02.RM112.Zone Air Temp" ; + brick:timeseries [ brick:hasTimeseriesId "b8f2ed23-f593-46a6-a139-1081d29d5a1d" ] . + +ns2:ZONE.AHU02.RM112.Zone_Air_Temp_Setpoint a brick:Zone_Air_Temperature_Setpoint ; + rdfs:label "ZONE.AHU02.RM112.Zone Air Temp Setpoint" ; + brick:timeseries [ brick:hasTimeseriesId "fb4379f0-a29c-4647-8228-ea88c3525cab" ] . + +ns2:ZONE.AHU02.RM112.Zone_Heating_Mode a brick:Heating_Command ; + rdfs:label "ZONE.AHU02.RM112.Zone Heating Mode" . + +ns2:ZONE.AHU02.RM112.Zone_Percent_Air_Flow a brick:Air_Flow_Sensor ; + rdfs:label "ZONE.AHU02.RM112.Zone Percent Air Flow" ; + brick:timeseries [ brick:hasTimeseriesId "060e62cb-546f-4312-a692-6f15521b3352" ] . + +ns2:ZONE.AHU02.RM112.Zone_Reheat_Valve_Command a brick:Command ; + rdfs:label "ZONE.AHU02.RM112.Zone Reheat Valve Command" ; + brick:timeseries [ brick:hasTimeseriesId "fc48ab24-1d7b-42c6-bef9-be82403eea9a" ] . + +ns2:ZONE.AHU02.RM112.Zone_Supply_Air_Flow a brick:Supply_Air_Flow_Sensor ; + rdfs:label "ZONE.AHU02.RM112.Zone Supply Air Flow" ; + brick:timeseries [ brick:hasTimeseriesId "d33f5c94-4738-47c8-b4d1-f83f7ed5f8b7" ] . + +ns2:ZONE.AHU02.RM112.Zone_Supply_Air_Temp a brick:Supply_Air_Temperature_Sensor ; + rdfs:label "ZONE.AHU02.RM112.Zone Supply Air Temp" ; + brick:timeseries [ brick:hasTimeseriesId "2c80a551-03e0-447a-a5fd-881688b1d866" ] . + +ns2:RM100 a brick:HVAC_Zone ; + brick:hasPart ns2:RM100_room . + +ns2:RM103 a brick:HVAC_Zone ; + brick:hasPart ns2:RM103_room . + +ns2:RM107A a brick:HVAC_Zone ; + brick:hasPart ns2:RM107A_room . + +ns2:RM107B a brick:HVAC_Zone ; + brick:hasPart ns2:RM107B_room . + +ns2:RM110 a brick:HVAC_Zone ; + brick:hasPart ns2:RM110_room . + +ns2:RM112 a brick:HVAC_Zone ; + brick:hasPart ns2:RM112_room . + +ns2:RM115 a brick:HVAC_Zone ; + brick:hasPart ns2:RM115_room . + +ns2:RM120 a brick:HVAC_Zone ; + brick:hasPart ns2:RM120_room . + +ns2:RM100_room a brick:Room . + +ns2:RM103_room a brick:Room . + +ns2:RM107A_room a brick:Room . + +ns2:RM107B_room a brick:Room . + +ns2:RM110_room a brick:Room . + +ns2:RM112_room a brick:Room . + +ns2:RM115_room a brick:Room . + +ns2:RM120_room a brick:Room . + +ns2:VAVRM100 a brick:VAV ; + brick:feeds ns2:RM100 ; + brick:hasPoint ns2:ZONE.AHU02.RM100.Zone_Air_Control_Temp, + ns2:ZONE.AHU02.RM100.Zone_Air_Temp, + ns2:ZONE.AHU02.RM100.Zone_Air_Temp_Setpoint, + ns2:ZONE.AHU02.RM100.Zone_Heating_Mode, + ns2:ZONE.AHU02.RM100.Zone_Percent_Air_Flow, + ns2:ZONE.AHU02.RM100.Zone_Reheat_Valve_Command, + ns2:ZONE.AHU02.RM100.Zone_Supply_Air_Flow, + ns2:ZONE.AHU02.RM100.Zone_Supply_Air_Temp . + +ns2:VAVRM103 a brick:VAV ; + brick:feeds ns2:RM103 ; + brick:hasPoint ns2:ZONE.AHU02.RM103.Zone_Air_Control_Temp, + ns2:ZONE.AHU02.RM103.Zone_Air_Temp, + ns2:ZONE.AHU02.RM103.Zone_Air_Temp_Setpoint, + ns2:ZONE.AHU02.RM103.Zone_Heating_Mode, + ns2:ZONE.AHU02.RM103.Zone_Percent_Air_Flow, + ns2:ZONE.AHU02.RM103.Zone_Reheat_Valve_Command, + ns2:ZONE.AHU02.RM103.Zone_Supply_Air_Flow, + ns2:ZONE.AHU02.RM103.Zone_Supply_Air_Temp . + +ns2:VAVRM107A a brick:VAV ; + brick:feeds ns2:RM107A ; + brick:hasPoint ns2:ZONE.AHU01.RM107A.Zone_Air_Control_Temp, + ns2:ZONE.AHU01.RM107A.Zone_Air_Temp, + ns2:ZONE.AHU01.RM107A.Zone_Air_Temp_Setpoint, + ns2:ZONE.AHU01.RM107A.Zone_Heating_Mode, + ns2:ZONE.AHU01.RM107A.Zone_Percent_Air_Flow, + ns2:ZONE.AHU01.RM107A.Zone_Reheat_Valve_Command, + ns2:ZONE.AHU01.RM107A.Zone_Supply_Air_Flow, + ns2:ZONE.AHU01.RM107A.Zone_Supply_Air_Temp . + +ns2:VAVRM107B a brick:VAV ; + brick:feeds ns2:RM107B ; + brick:hasPoint ns2:ZONE.AHU01.RM107B.Zone_Air_Control_Temp, + ns2:ZONE.AHU01.RM107B.Zone_Air_Temp, + ns2:ZONE.AHU01.RM107B.Zone_Air_Temp_Setpoint, + ns2:ZONE.AHU01.RM107B.Zone_Heating_Mode, + ns2:ZONE.AHU01.RM107B.Zone_Percent_Air_Flow, + ns2:ZONE.AHU01.RM107B.Zone_Reheat_Valve_Command, + ns2:ZONE.AHU01.RM107B.Zone_Supply_Air_Flow, + ns2:ZONE.AHU01.RM107B.Zone_Supply_Air_Temp . + +ns2:VAVRM110 a brick:VAV ; + brick:feeds ns2:RM110 ; + brick:hasPoint ns2:ZONE.AHU02.RM110.Zone_Air_Control_Temp, + ns2:ZONE.AHU02.RM110.Zone_Air_Temp, + ns2:ZONE.AHU02.RM110.Zone_Air_Temp_Setpoint, + ns2:ZONE.AHU02.RM110.Zone_Heating_Mode, + ns2:ZONE.AHU02.RM110.Zone_Percent_Air_Flow, + ns2:ZONE.AHU02.RM110.Zone_Reheat_Valve_Command, + ns2:ZONE.AHU02.RM110.Zone_Supply_Air_Flow, + ns2:ZONE.AHU02.RM110.Zone_Supply_Air_Temp . + +ns2:VAVRM112 a brick:VAV ; + brick:feeds ns2:RM112 ; + brick:hasPoint ns2:ZONE.AHU02.RM112.Zone_Air_Control_Temp, + ns2:ZONE.AHU02.RM112.Zone_Air_Temp, + ns2:ZONE.AHU02.RM112.Zone_Air_Temp_Setpoint, + ns2:ZONE.AHU02.RM112.Zone_Heating_Mode, + ns2:ZONE.AHU02.RM112.Zone_Percent_Air_Flow, + ns2:ZONE.AHU02.RM112.Zone_Reheat_Valve_Command, + ns2:ZONE.AHU02.RM112.Zone_Supply_Air_Flow, + ns2:ZONE.AHU02.RM112.Zone_Supply_Air_Temp . + +ns2:VAVRM115 a brick:VAV ; + brick:feeds ns2:RM115 ; + brick:hasPoint ns2:ZONE.AHU01.RM115.Zone_Air_Control_Temp, + ns2:ZONE.AHU01.RM115.Zone_Air_Temp, + ns2:ZONE.AHU01.RM115.Zone_Air_Temp_Setpoint, + ns2:ZONE.AHU01.RM115.Zone_Heating_Mode, + ns2:ZONE.AHU01.RM115.Zone_Percent_Air_Flow, + ns2:ZONE.AHU01.RM115.Zone_Reheat_Valve_Command, + ns2:ZONE.AHU01.RM115.Zone_Supply_Air_Flow, + ns2:ZONE.AHU01.RM115.Zone_Supply_Air_Temp . + +ns2:VAVRM120 a brick:VAV ; + brick:feeds ns2:RM120 ; + brick:hasPoint ns2:ZONE.AHU01.RM120.Zone_Air_Control_Temp, + ns2:ZONE.AHU01.RM120.Zone_Air_Temp, + ns2:ZONE.AHU01.RM120.Zone_Air_Temp_Setpoint, + ns2:ZONE.AHU01.RM120.Zone_Heating_Mode, + ns2:ZONE.AHU01.RM120.Zone_Percent_Air_Flow, + ns2:ZONE.AHU01.RM120.Zone_Reheat_Valve_Command, + ns2:ZONE.AHU01.RM120.Zone_Supply_Air_Flow, + ns2:ZONE.AHU01.RM120.Zone_Supply_Air_Temp . + +ns2:chiller a brick:Chiller ; + brick:hasPoint ns2:CHW.Building_Chilled_Water_Return_Temp, + ns2:CHW.Building_Chilled_Water_Supply_Temp, + ns2:CHW.ECONOMIZER, + ns2:CHW.Loop_Chilled_Water_Return_Temp, + ns2:CHW.Loop_Chilled_Water_Supply_Temp, + ns4:Stop . + +ns2:camera a brick:Surveillance_Camera . +ns2:temp a brick:Temperature_Sensor . diff --git a/src/blenderbim/test/tool/test_brick.py b/src/blenderbim/test/tool/test_brick.py new file mode 100644 index 0000000000..e8ed25273d --- /dev/null +++ b/src/blenderbim/test/tool/test_brick.py @@ -0,0 +1,125 @@ +# BlenderBIM Add-on - OpenBIM Blender Add-on +# Copyright (C) 2021 Dion Moult +# +# This file is part of BlenderBIM Add-on. +# +# BlenderBIM Add-on is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# BlenderBIM Add-on is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with BlenderBIM Add-on. If not, see . + +import os +import bpy +import ifcopenshell +import blenderbim.core.tool +import blenderbim.tool as tool +from test.bim.bootstrap import NewFile +from blenderbim.tool.brick import Brick as subject +from blenderbim.tool.brick import BrickStore + + +class TestImplementsTool(NewFile): + def test_run(self): + assert isinstance(subject(), blenderbim.core.tool.Brick) + + +class TestAddBrickBreadcrumb(NewFile): + def test_run(self): + subject.set_active_brick_class("brick_class") + subject.add_brick_breadcrumb() + assert bpy.context.scene.BIMBrickProperties.brick_breadcrumbs[0].name == "brick_class" + subject.add_brick_breadcrumb() + assert bpy.context.scene.BIMBrickProperties.brick_breadcrumbs[1].name == "brick_class" + + +class TestClearBrickBrowser(NewFile): + def test_run(self): + bpy.context.scene.BIMBrickProperties.bricks.add() + subject.clear_brick_browser() + assert len(bpy.context.scene.BIMBrickProperties.bricks) == 0 + + +class TestClearProject(NewFile): + def test_run(self): + BrickStore.graph = "graph" + bpy.context.scene.BIMBrickProperties.active_brick_class == "brick_class" + bpy.context.scene.BIMBrickProperties.brick_breadcrumbs.add().name = "foo" + subject.clear_project() + assert BrickStore.graph is None + assert bpy.context.scene.BIMBrickProperties.active_brick_class == "" + assert len(bpy.context.scene.BIMBrickProperties.brick_breadcrumbs) == 0 + + +class TestGetItemClass(NewFile): + def test_run(self): + TestLoadBrickFile().test_run() + assert subject.get_item_class("http://buildsys.org/ontologies/bldg#chiller") == "Chiller" + + +class TestImportBrickClasses(NewFile): + def test_run(self): + TestLoadBrickFile().test_run() + subject.import_brick_classes("Class") + assert len(bpy.context.scene.BIMBrickProperties.bricks) == 4 + brick = bpy.context.scene.BIMBrickProperties.bricks[0] + assert brick.name == "Equipment" + assert brick.uri == "https://brickschema.org/schema/Brick#Equipment" + assert brick.total_items == 20 + brick = bpy.context.scene.BIMBrickProperties.bricks[1] + assert brick.name == "Location" + assert brick.uri == "https://brickschema.org/schema/Brick#Location" + assert brick.total_items == 18 + + +class TestImportBrickItems(NewFile): + def test_run(self): + TestLoadBrickFile().test_run() + subject.import_brick_items("Room") + assert len(bpy.context.scene.BIMBrickProperties.bricks) == 8 + brick = bpy.context.scene.BIMBrickProperties.bricks[0] + assert brick.name == "RM100_room" + assert brick.uri == "http://buildsys.org/ontologies/bldg#RM100_room" + assert brick.total_items == 0 + brick = bpy.context.scene.BIMBrickProperties.bricks[1] + assert brick.name == "RM103_room" + assert brick.uri == "http://buildsys.org/ontologies/bldg#RM103_room" + assert brick.total_items == 0 + + +class TestLoadBrickFile(NewFile): + def test_run(self): + cwd = os.path.dirname(os.path.realpath(__file__)) + filepath = os.path.join(cwd, "..", "files", "building.ttl") + subject.load_brick_file(filepath) + assert BrickStore.graph + + +class TestPopBrickBreadcrumb(NewFile): + def test_run(self): + bpy.context.scene.BIMBrickProperties.brick_breadcrumbs.add().name = "foo" + bpy.context.scene.BIMBrickProperties.brick_breadcrumbs.add().name = "bar" + assert subject.pop_brick_breadcrumb() == "bar" + assert len(bpy.context.scene.BIMBrickProperties.brick_breadcrumbs) == 1 + assert bpy.context.scene.BIMBrickProperties.brick_breadcrumbs[0].name == "foo" + + +class TestSelectBrowserItem(NewFile): + def test_run(self): + subject.set_active_brick_class("brick_class") + assert bpy.context.scene.BIMBrickProperties.active_brick_class == "brick_class" + + +class TestSetActiveBrickClass(NewFile): + def test_run(self): + bpy.context.scene.BIMBrickProperties.bricks.add().name = "foo" + bpy.context.scene.BIMBrickProperties.bricks.add().name = "bar" + subject.select_browser_item("namespace#bar") + assert bpy.context.scene.BIMBrickProperties.active_brick_index == 1