def test_roundtrip(self):
     filename = os.path.join(self.data_dir, "test_1.mo")
     new_filename = os.path.join(self.output_dir, "test_1_output_1.mo")
     f = InputParser(filename)
     f.save_as(new_filename)
     # Previous file should be the same as the updated file
     self.assertTrue(filecmp.cmp(filename, new_filename))
    def test_remove_connection(self):
        filename = os.path.abspath('tests/modelica/data/test_1.mo')
        new_filename = os.path.abspath('tests/modelica/output/test_1_output_8.mo')
        f1 = InputParser(filename)
        f1.remove_connect_string('weaDat.weaBus', 'weaBus')
        f1.save_as(new_filename)

        f2 = InputParser(new_filename)
        self.assertFalse(filecmp.cmp(filename, new_filename))
        index, c = f2.find_connect('weaDat.weaBus', 'weaBus')
        # the connection should no longer exist
        self.assertIsNone(index)
    def test_remove_connection(self):
        filename = os.path.join(self.data_dir, "test_1.mo")
        new_filename = os.path.join(self.output_dir, "test_1_output_8.mo")
        f1 = InputParser(filename)
        f1.remove_connect_string('weaDat.weaBus', 'weaBus')
        f1.save_as(new_filename)

        f2 = InputParser(new_filename)
        self.assertFalse(filecmp.cmp(filename, new_filename))
        index, c = f2.find_connect('weaDat.weaBus', 'weaBus')
        # the connection should no longer exist
        self.assertIsNone(index)
    def test_gsub_connect(self):
        filename = os.path.join(self.data_dir, "test_1.mo")
        new_filename = os.path.join(self.output_dir, "test_1_output_6.mo")
        f1 = InputParser(filename)
        f1.add_connect(
            "port_a",
            "thermalZoneTwoElements.intGainsConv",
            "annotation (Line(points={{0,100},{96,100},{96,20},{92,20}}, color={191,0,0}))",
        )
        f1.save_as(new_filename)

        # verify in the new file that the new model object exists
        f2 = InputParser(new_filename)
        self.assertFalse(filecmp.cmp(filename, new_filename))
        index, c = f2.find_connect("port_a", "thermalZoneTwoElements.intGainsConv")
        self.assertGreaterEqual(index, 0)
    def test_add_model_obj(self):
        filename = os.path.join(self.data_dir, "test_1.mo")
        new_filename = os.path.join(self.output_dir, "test_1_output_5.mo")
        f1 = InputParser(filename)
        data = [
            'annotation (Placement(transformation(extent={{-10,90},{10,110}}), iconTransformation(extent={{-10,90},{10,110}})));'  # noqa
        ]
        f1.add_model_object(
            "Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a", "port_a", data
        )
        f1.save_as(new_filename)

        # verify in the new file that the new model object exists
        f2 = InputParser(new_filename)
        index, model = f2.find_model_object(
            "Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a"
        )
        self.assertFalse(filecmp.cmp(filename, new_filename))
        self.assertGreaterEqual(index, 0)
    def test_gsub_field(self):
        filename = os.path.join(self.data_dir, "test_1.mo")
        new_filename = os.path.join(self.output_dir, "test_1_output_3.mo")
        f1 = InputParser(filename)
        # This example is actually updating an annotation object, not a model, but leave it here for now.
        f1.replace_model_string(
            "Modelica.Blocks.Sources.CombiTimeTable",
            "internalGains",
            "Internals",
            "NotInternals",
        )
        f1.save_as(new_filename)

        f2 = InputParser(new_filename)
        index, model = f2.find_model_object(
            "Modelica.Blocks.Sources.CombiTimeTable internalGains"
        )
        self.assertFalse(filecmp.cmp(filename, new_filename))
        # the 5th index is the rotation... non-ideal look up
        self.assertTrue("NotInternals" in model)
    def test_rename_filename(self):
        filename = os.path.join(self.data_dir, "test_1.mo")
        new_filename = os.path.join(self.output_dir, "test_1_output_4.mo")
        f1 = InputParser(filename)
        # This example is actually updating an annotation object, not a model, but leave it here for now.
        f1.replace_model_string(
            'Modelica.Blocks.Sources.CombiTimeTable',
            'internalGains',
            'modelica://Project/B5a6b99ec37f4de7f94020090/B5a6b99ec37f4de7f94020090_Models/InternalGains_B5a6b99ec37f4de7f94020090Floor.mat',  # noqa
            'modelica://a/new/path.mat'
        )
        f1.save_as(new_filename)

        f2 = InputParser(new_filename)
        index, model = f2.find_model_object(
            "Modelica.Blocks.Sources.CombiTimeTable internalGains"
        )
        self.assertFalse(filecmp.cmp(filename, new_filename))
        # the 5th index is the rotation... non-ideal look up
        self.assertTrue("a/new/path.mat" in model)
    def test_modelica_parameter(self):
        filename = os.path.join(self.data_dir, "test_1.mo")
        new_filename = os.path.join(self.output_dir, "test_1_output_9.mo")
        f1 = InputParser(filename)
        f1.add_parameter('Real', 'aVarNam', 0.8, "A description where aVarName is 0.8")
        f1.add_parameter('String', 'aVarNamStr', 'A-string-value', "A description string A-string-value")
        f1.save_as(new_filename)

        # just read the file and ensure that the string exists
        test_strs = [
            'parameter String aVarNamStr="A-string-value" "A description string A-string-value";',
            'parameter Real aVarNam=0.8 "A description where aVarName is 0.8";'
        ]
        with open(new_filename) as f:
            file_data = f.read()
            for test_str in test_strs:
                self.assertIn(test_str, file_data)
예제 #9
0
    def post_process(self, scaffold, building_names, keep_original_models=False):
        """
        Cleanup the export of the TEASER files into a format suitable for the district-based analysis. This includes
        the following:

            * Update the partial to inherit from the GeojsonExport class defined in MBL.
            * Rename the files to remove the names of the buildings
            * Move the files to the Loads level and remove the Project folder (default export method from TEASER)
            * Add heat port
            * Add return temperature
            * Remove weaDat and rely on weaBus

        :param project_name: string, name of the project which will be used to set the package.mo file
        :param root_building_dir: string, where the project will be ultimately saved
        :param building_names: list, names of the buildings that need to be cleaned up after export
        :return: None
        """
        for b in building_names:
            # create a list of strings that we need to replace in all the file as we go along
            string_replace_list = []

            # create a new modelica based path for the buildings # TODO: make this work at the toplevel, somehow.
            b_modelica_path = ModelicaPath(f"B{b}", scaffold.loads_path.files_dir, True)

            # copy over the entire model to the new location
            copytree(
                os.path.join(scaffold.loads_path.files_dir, f"Project/B{b}/B{b}_Models"),
                b_modelica_path.files_dir,
            )

            # read in the package to apply the changes as they other files are processed
            # TODO: these should be linked, so a rename method should act across the model and the package.order
            package = PackageParser(os.path.join(scaffold.loads_path.files_dir, f"B{b}"))

            # move the internal gains files to a new resources folder
            mat_files = glob.glob(os.path.join(scaffold.loads_path.files_dir, f"B{b}/*.txt"))
            for f in mat_files:
                new_file_name = os.path.basename(f).replace(f"B{b}", "")
                os.rename(f, f"{b_modelica_path.resources_dir}/{new_file_name}")
                string_replace_list.append(
                    (
                        f"Project/B{b}/B{b}_Models/{os.path.basename(f)}",
                        f"Loads/{b_modelica_path.resources_relative_dir}/{new_file_name}",
                    )
                )

            # process each of the building models
            mo_files = glob.glob(os.path.join(scaffold.loads_path.files_dir, f"B{b}/*.mo"))
            for f in mo_files:
                # ignore the package.mo file
                if os.path.basename(f) == "package.mo":
                    continue

                mofile = InputParser(f)

                # previous paths and replace with the new one.
                # Make sure to update the names of any resources as well.
                mofile.replace_within_string(f"{scaffold.project_name}.Loads.B{b}")

                # remove ReaderTMY3
                mofile.remove_object("ReaderTMY3")

                # updating path to internal loads
                for s in string_replace_list:
                    mofile.replace_model_string("Modelica.Blocks.Sources.CombiTimeTable", "internalGains", s[0], s[1])

                # add heat port
                data = [
                    "annotation (Placement(transformation(extent={{-10,90},{10,110}}), "
                    "iconTransformation(extent={{-10,90},{10,110}})));"
                ]
                mofile.add_model_object(
                    "Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a", "port_a", data,
                )

                # add TAir output
                # TODO: read in the object by name -- parse the parenthetic content
                instance = 'TAir(\n    quantity="ThermodynamicTemperature", unit="K", displayUnit="degC")'
                data = [
                    '"Room air temperature"',
                    "annotation (Placement(transformation(extent={{100,-10},{120,10}})));",
                ]
                mofile.add_model_object(
                    "Buildings.Controls.OBC.CDL.Interfaces.RealOutput", instance, data
                )

                # All existing weaDat.weaBus connections need to be updated to simply weaBus
                mofile.replace_connect_string('weaDat.weaBus', None, 'weaBus', None, True)
                # Now remove the redundant weaBus -> weaBus connection
                mofile.remove_connect_string('weaBus', 'weaBus')

                # add new port connections
                if self.system_parameters.get_param(
                        "buildings.default.load_model_parameters.rc.order", default=2) == 1:
                    data = "annotation (Line(points={{0,100},{96,100},{96,20},{92,20}}, color={191,0,0}))"
                    mofile.add_connect("port_a", "thermalZoneOneElement.intGainsConv", data)

                    data = "annotation (Line(points={{93,32},{98,32},{98,0},{110,0}}, color={0,0,127}))"
                    mofile.add_connect("thermalZoneOneElement.TAir", "TAir", data)
                elif self.system_parameters.get_param(
                        "buildings.default.load_model_parameters.rc.order", default=2) == 2:
                    data = "annotation (Line(points={{0,100},{96,100},{96,20},{92,20}}, color={191,0,0}))"
                    mofile.add_connect("port_a", "thermalZoneTwoElements.intGainsConv", data)

                    data = "annotation (Line(points={{93,32},{98,32},{98,0},{110,0}}, color={0,0,127}))"
                    mofile.add_connect("thermalZoneTwoElements.TAir", "TAir", data)
                elif self.system_parameters.get_param(
                        "buildings.default.load_model_parameters.rc.order", default=2) == 4:
                    data = "annotation (Line(points={{0,100},{96,100},{96,20},{92,20}}, color={191,0,0}))"
                    mofile.add_connect("port_a", "thermalZoneFourElements.intGainsConv", data)

                    data = "annotation (Line(points={{93,32},{98,32},{98,0},{110,0}}, color={0,0,127}))"
                    mofile.add_connect("thermalZoneFourElements.TAir", "TAir", data)

                # change the name of the modelica model to remove the building id, update in package too!
                new_model_name = mofile.model["name"].split("_")[1]
                package.rename_model(mofile.model["name"], new_model_name)
                mofile.model["name"] = new_model_name

                # Save as the new filename (without building ID)
                new_filename = os.path.join(
                    scaffold.loads_path.files_dir, f'B{b}/{os.path.basename(f).split("_")[1]}'
                )
                mofile.save_as(new_filename)
                os.remove(f)

            # save the updated package.mo and package.order.
            new_package = PackageParser.new_from_template(
                package.path, f"B{b}", package.order, within=f"{scaffold.project_name}.Loads"
            )
            new_package.save()

        # remaining clean up tasks across the entire exported project
        if not keep_original_models:
            shutil.rmtree(os.path.join(scaffold.loads_path.files_dir, "Project"))

        # now create the Loads level package. This (for now) will create the package without considering any existing
        # files in the Loads directory.
        # add in the silly 'B' before the building names
        package = PackageParser.new_from_template(
            scaffold.loads_path.files_dir,
            "Loads", ["B" + b for b in building_names],
            within=f"{scaffold.project_name}"
        )
        package.save()
    def test_remove_object(self):
        filename = os.path.join(self.data_dir, "test_1.mo")
        new_filename = os.path.join(self.output_dir, "test_1_output_2.mo")
        f1 = InputParser(filename)
        f1.remove_object("ReaderTMY3")
        f1.save_as(new_filename)
        self.assertFalse(filecmp.cmp(filename, new_filename))

        f1.reload()
        f2 = InputParser(new_filename)
        self.assertGreater(len(f1.model["objects"]), len(f2.model["objects"]))
        # verify that it exists in f1 but not in f2
        self.assertGreaterEqual(f1.find_model_object("ReaderTMY3")[0], 0)
        self.assertIsNone(f2.find_model_object("ReaderTMY3")[0])
 def test_missing_file(self):
     fn = "non-existent-path"
     with self.assertRaises(Exception) as exc:
         InputParser(fn)
     self.assertEqual(f"Modelica file does not exist: {fn}", str(exc.exception))
    def test_rename_connection(self):
        filename = os.path.join(self.data_dir, "test_1.mo")
        new_filename = os.path.join(self.output_dir, "test_1_output_7.mo")
        f1 = InputParser(filename)
        # connect(weaDat.weaBus, HDifTil[3].weaBus)
        f1.replace_connect_string(
            "eqAirTemp.TEqAir", "prescribedTemperature.T", "NothingOfImportance", None
        )
        f1.replace_connect_string("weaDat.weaBus", None, "weaBus", None, True)
        f1.save_as(new_filename)

        f2 = InputParser(new_filename)
        self.assertFalse(filecmp.cmp(filename, new_filename))
        index, c = f2.find_connect('weaBus', 'weaBus')
        # there should exist the new connection
        self.assertGreaterEqual(index, 0)

        # the old one should not exist
        index, c = f2.find_connect('weaDat.weaBus', 'weaBus')
        self.assertIsNone(index)
 def test_roundtrip(self):
     filename = os.path.abspath("tests/modelica/data/test_1.mo")
     new_filename = os.path.abspath("tests/modelica/output/test_1_output_1.mo")
     f = InputParser(filename)
     f.save_as(new_filename)
     self.assertTrue(filecmp.cmp(filename, new_filename))