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)
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))