From 0cf2fd8a338ad155670c0490b6c137ace77f6be5 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Thu, 12 Dec 2024 09:39:36 -0700 Subject: [PATCH 1/8] Add dummy py script with import from plugin script. --- .../simulationtests/python_plugin_program.py | 38 ----- .../python_plugin_search_paths.rb | 134 ++++++++++++++++++ .../python_plugin_search_paths_script.py | 1 + model_tests.rb | 4 + 4 files changed, 139 insertions(+), 38 deletions(-) delete mode 100644 model/simulationtests/python_plugin_program.py create mode 100644 model/simulationtests/python_plugin_search_paths.rb create mode 100644 model/simulationtests/python_plugin_search_paths_script.py diff --git a/model/simulationtests/python_plugin_program.py b/model/simulationtests/python_plugin_program.py deleted file mode 100644 index e500e2aea..000000000 --- a/model/simulationtests/python_plugin_program.py +++ /dev/null @@ -1,38 +0,0 @@ -from pyenergyplus.plugin import EnergyPlusPlugin - -class AverageZoneTemps(EnergyPlusPlugin): - - def __init__(self): - super().__init__() - self.do_setup = True - - def on_end_of_zone_timestep_before_zone_reporting(self, state) -> int: - if self.do_setup: - self.data['zone_volumes'] = [] - self.data['zone_temps'] = [] - zone_names = ["Story 1 Core Thermal Zone", "Story 1 East Perimeter Thermal Zone", "Story 1 North Perimeter Thermal Zone", "Story 1 South Perimeter Thermal Zone", "Story 1 West Perimeter Thermal Zone"] - for zone_name in zone_names: - handle = self.api.exchange.get_internal_variable_handle(state, 'Zone Air Volume', zone_name) - zone_volume = self.api.exchange.get_internal_variable_value(state, handle) - self.data['zone_volumes'].append(zone_volume) - self.data['zone_temps'].append( - self.api.exchange.get_variable_handle(state, 'Zone Mean Air Temperature', zone_name) - ) - self.data['avg_temp_variable'] = self.api.exchange.get_global_handle(state, 'AverageBuildingTemp') - self.data['trend'] = self.api.exchange.get_trend_handle(state, 'Running Averaged Building Temperature') - self.data['running_avg_temp_variable'] = self.api.exchange.get_global_handle(state, 'RunningAverageBuildingTemp') - self.do_setup = False - zone_temps = list() - for t_handle in self.data['zone_temps']: - zone_temps.append(self.api.exchange.get_variable_value(state, t_handle)) - numerator = 0.0 - denominator = 0.0 - for i in range(len(self.data['zone_volumes'])): - numerator += self.data['zone_volumes'][i] * zone_temps[i] - denominator += self.data['zone_volumes'][i] - average_temp = numerator / denominator - self.api.exchange.set_global_value(state, self.data['avg_temp_variable'], average_temp) - - past_daily_avg_temp = self.api.exchange.get_trend_average(state, self.data['trend'], 96) - self.api.exchange.set_global_value(state, self.data['running_avg_temp_variable'], past_daily_avg_temp) - return 0 diff --git a/model/simulationtests/python_plugin_search_paths.rb b/model/simulationtests/python_plugin_search_paths.rb new file mode 100644 index 000000000..6fc724b8c --- /dev/null +++ b/model/simulationtests/python_plugin_search_paths.rb @@ -0,0 +1,134 @@ +# frozen_string_literal: true + +require 'openstudio' +require_relative 'lib/baseline_model' +require 'tmpdir' + +model = BaselineModel.new + +# make a 1 story, 100m X 50m, 5 zone core/perimeter building +model.add_geometry({ 'length' => 100, + 'width' => 50, + 'num_floors' => 1, + 'floor_to_floor_height' => 4, + 'plenum_height' => 0, + 'perimeter_zone_depth' => 3 }) + +# assign constructions from a local library to the walls/windows/etc. in the model +model.set_constructions + +# set whole building space type; simplified 90.1-2004 Large Office Whole Building +model.set_space_type + +# add design days to the model (Chicago) +model.add_design_days + +zone_names = model.getThermalZones.map(&:nameString).sort + +zone_names_str_list = '["' + zone_names.join('", "') + '"]' + +# Add a PythonPlugin:Variable (all OS SDK PythonPluginVariable objects are +# translated to a single E+ PythonPlugin:Variables (extensible object)) +py_var = OpenStudio::Model::PythonPluginVariable.new(model) +py_var.setName('AverageBuildingTemp') + +# Add a PythonPlugin:OutputVariable for that variable +py_out_var = OpenStudio::Model::PythonPluginOutputVariable.new(py_var) +py_out_var.setName('Averaged Building Temperature') +py_out_var.setTypeofDatainVariable('Averaged') +py_out_var.setUpdateFrequency('ZoneTimestep') +py_out_var.setUnits('C') + +# Add a regular Output:Variable that references it +out_var = OpenStudio::Model::OutputVariable.new('PythonPlugin:OutputVariable', model) +out_var.setKeyValue(py_out_var.nameString) +out_var.setReportingFrequency('Timestep') + +# Add output variables for Zone Mean Air Temperature, so we can compare +outputVariable = OpenStudio::Model::OutputVariable.new('Zone Mean Air Temperature', model) +outputVariable.setReportingFrequency('Timestep') + +# Trend Variable: while this is a fully functioning object, you're probably +# best just using a storage variable on the Python side (eg: a list) +py_trend_var = OpenStudio::Model::PythonPluginTrendVariable.new(py_var) +py_trend_var.setName('Running Averaged Building Temperature') +n_timesteps = 24 * model.getTimestep.numberOfTimestepsPerHour +py_trend_var.setNumberofTimestepstobeLogged(n_timesteps) + +py_var2 = OpenStudio::Model::PythonPluginVariable.new(model) +py_var2.setName('RunningAverageBuildingTemp') + +py_out_trend_var = OpenStudio::Model::PythonPluginOutputVariable.new(py_var2) +py_out_trend_var.setName('Running Averaged Building Temperature') +py_out_trend_var.setTypeofDatainVariable('Averaged') +py_out_trend_var.setUpdateFrequency('ZoneTimestep') +py_out_trend_var.setUnits('C') + +out_trend_var = OpenStudio::Model::OutputVariable.new('PythonPlugin:OutputVariable', model) +out_trend_var.setReportingFrequency('Timestep') + +pluginClassName = 'AverageZoneTemps' + +python_plugin_file_content = ''"from pyenergyplus.plugin import EnergyPlusPlugin +import python_plugin_search_paths_script + +class #{pluginClassName}(EnergyPlusPlugin): + + def __init__(self): + super().__init__() + self.do_setup = True + + def on_end_of_zone_timestep_before_zone_reporting(self, state) -> int: + if self.do_setup: + self.data['zone_volumes'] = [] + self.data['zone_temps'] = [] + zone_names = #{zone_names_str_list} + for zone_name in zone_names: + handle = self.api.exchange.get_internal_variable_handle(state, 'Zone Air Volume', zone_name) + zone_volume = self.api.exchange.get_internal_variable_value(state, handle) + self.data['zone_volumes'].append(zone_volume) + self.data['zone_temps'].append( + self.api.exchange.get_variable_handle(state, 'Zone Mean Air Temperature', zone_name) + ) + self.data['avg_temp_variable'] = self.api.exchange.get_global_handle(state, '#{py_var.nameString}') + self.data['trend'] = self.api.exchange.get_trend_handle(state, '#{py_trend_var.nameString}') + self.data['running_avg_temp_variable'] = self.api.exchange.get_global_handle(state, '#{py_var2.nameString}') + self.do_setup = False + zone_temps = list() + for t_handle in self.data['zone_temps']: + zone_temps.append(self.api.exchange.get_variable_value(state, t_handle)) + numerator = 0.0 + denominator = 0.0 + for i in range(len(self.data['zone_volumes'])): + numerator += self.data['zone_volumes'][i] * zone_temps[i] + denominator += self.data['zone_volumes'][i] + average_temp = numerator / denominator + self.api.exchange.set_global_value(state, self.data['avg_temp_variable'], average_temp) + + past_daily_avg_temp = self.api.exchange.get_trend_average(state, self.data['trend'], #{n_timesteps}) + self.api.exchange.set_global_value(state, self.data['running_avg_temp_variable'], past_daily_avg_temp) + return 0 +"'' + +# Write it to a temporary directory so we don't pollute the current directory +# ExternalFile will copy it +pluginPath = File.join(Dir.tmpdir, 'python_plugin_program.py') +File.write(pluginPath, python_plugin_file_content) + +# create the external file object +external_file = OpenStudio::Model::ExternalFile.getExternalFile(model, pluginPath) +external_file = external_file.get + +# create the python plugin instance object +python_plugin_instance = OpenStudio::Model::PythonPluginInstance.new(external_file, pluginClassName) +python_plugin_instance.setRunDuringWarmupDays(false) + +# create the python plugin search paths object (this test should fail without it) +python_plugin_search_paths = model.getPythonPluginSearchPaths +python_plugin_search_paths.setAddCurrentWorkingDirectorytoSearchPath(true) +python_plugin_search_paths.setAddInputFileDirectorytoSearchPath(true) +python_plugin_search_paths.setAddepinEnvironmentVariabletoSearchPath(true) +python_plugin_search_paths.addSearchPath(File.dirname(__FILE__)) + +# save the OpenStudio model (.osm) +model.save_openstudio_osm({ 'osm_save_directory' => Dir.pwd, 'osm_name' => 'in.osm' }) diff --git a/model/simulationtests/python_plugin_search_paths_script.py b/model/simulationtests/python_plugin_search_paths_script.py new file mode 100644 index 000000000..00950d9ac --- /dev/null +++ b/model/simulationtests/python_plugin_search_paths_script.py @@ -0,0 +1 @@ +print('hello world') \ No newline at end of file diff --git a/model_tests.rb b/model_tests.rb index e9275dd3f..c83779b69 100644 --- a/model_tests.rb +++ b/model_tests.rb @@ -1511,6 +1511,10 @@ def test_python_plugin_osm result = sim_test('python_plugin.osm') end + def test_python_plugin_search_paths_rb + result = sim_test('python_plugin_search_paths.rb') + end + def test_refrigeration_system_rb result = sim_test('refrigeration_system.rb') end From a6e4771a6f48721dbf67239f58c159583e6c94d4 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Fri, 13 Dec 2024 14:44:13 -0700 Subject: [PATCH 2/8] Add commented osm test in model_tests. --- model_tests.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/model_tests.rb b/model_tests.rb index c83779b69..05eceb130 100644 --- a/model_tests.rb +++ b/model_tests.rb @@ -1511,6 +1511,11 @@ def test_python_plugin_osm result = sim_test('python_plugin.osm') end + # TODO: To be added in the next official release after: 3.9.0 + # def test_python_plugin_search_paths_osm + # result = sim_test('python_plugin_search_paths.osm') + # end + def test_python_plugin_search_paths_rb result = sim_test('python_plugin_search_paths.rb') end From dc5b2066e9449ffdf9b5419a29c4fe8ad13e4550 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Thu, 19 Dec 2024 11:16:29 +0100 Subject: [PATCH 3/8] Put back the python_plugin_program.py --- .../simulationtests/python_plugin_program.py | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 model/simulationtests/python_plugin_program.py diff --git a/model/simulationtests/python_plugin_program.py b/model/simulationtests/python_plugin_program.py new file mode 100644 index 000000000..e500e2aea --- /dev/null +++ b/model/simulationtests/python_plugin_program.py @@ -0,0 +1,38 @@ +from pyenergyplus.plugin import EnergyPlusPlugin + +class AverageZoneTemps(EnergyPlusPlugin): + + def __init__(self): + super().__init__() + self.do_setup = True + + def on_end_of_zone_timestep_before_zone_reporting(self, state) -> int: + if self.do_setup: + self.data['zone_volumes'] = [] + self.data['zone_temps'] = [] + zone_names = ["Story 1 Core Thermal Zone", "Story 1 East Perimeter Thermal Zone", "Story 1 North Perimeter Thermal Zone", "Story 1 South Perimeter Thermal Zone", "Story 1 West Perimeter Thermal Zone"] + for zone_name in zone_names: + handle = self.api.exchange.get_internal_variable_handle(state, 'Zone Air Volume', zone_name) + zone_volume = self.api.exchange.get_internal_variable_value(state, handle) + self.data['zone_volumes'].append(zone_volume) + self.data['zone_temps'].append( + self.api.exchange.get_variable_handle(state, 'Zone Mean Air Temperature', zone_name) + ) + self.data['avg_temp_variable'] = self.api.exchange.get_global_handle(state, 'AverageBuildingTemp') + self.data['trend'] = self.api.exchange.get_trend_handle(state, 'Running Averaged Building Temperature') + self.data['running_avg_temp_variable'] = self.api.exchange.get_global_handle(state, 'RunningAverageBuildingTemp') + self.do_setup = False + zone_temps = list() + for t_handle in self.data['zone_temps']: + zone_temps.append(self.api.exchange.get_variable_value(state, t_handle)) + numerator = 0.0 + denominator = 0.0 + for i in range(len(self.data['zone_volumes'])): + numerator += self.data['zone_volumes'][i] * zone_temps[i] + denominator += self.data['zone_volumes'][i] + average_temp = numerator / denominator + self.api.exchange.set_global_value(state, self.data['avg_temp_variable'], average_temp) + + past_daily_avg_temp = self.api.exchange.get_trend_average(state, self.data['trend'], 96) + self.api.exchange.set_global_value(state, self.data['running_avg_temp_variable'], past_daily_avg_temp) + return 0 From 7f2fee34daca1ae52c15c3cfe4dffedea3b42da9 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Thu, 19 Dec 2024 11:17:43 +0100 Subject: [PATCH 4/8] Clarify how/for which tests .py script files are used --- model/simulationtests/python_plugin_program.py | 1 + model/simulationtests/python_plugin_search_paths_script.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/model/simulationtests/python_plugin_program.py b/model/simulationtests/python_plugin_program.py index e500e2aea..b1725488a 100644 --- a/model/simulationtests/python_plugin_program.py +++ b/model/simulationtests/python_plugin_program.py @@ -1,3 +1,4 @@ +# This file is used by python_plugin.osm from pyenergyplus.plugin import EnergyPlusPlugin class AverageZoneTemps(EnergyPlusPlugin): diff --git a/model/simulationtests/python_plugin_search_paths_script.py b/model/simulationtests/python_plugin_search_paths_script.py index 00950d9ac..2814d386e 100644 --- a/model/simulationtests/python_plugin_search_paths_script.py +++ b/model/simulationtests/python_plugin_search_paths_script.py @@ -1 +1,2 @@ -print('hello world') \ No newline at end of file +# This file is used by python_plugin_search_paths +print('hello world') From 96a35a50dad71e57bb7fad385d17811cedd3426b Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Thu, 19 Dec 2024 12:38:37 +0100 Subject: [PATCH 5/8] Add a python version, make the python_plugin use a program name that's based on the stem and prepare for the new OSM test --- model/simulationtests/python_plugin.py | 2 +- model/simulationtests/python_plugin.rb | 3 +- .../python_plugin_search_paths.py | 132 ++++++++++++++++++ .../python_plugin_search_paths.rb | 5 +- model_tests.rb | 6 +- test_helpers.rb | 5 +- 6 files changed, 147 insertions(+), 6 deletions(-) create mode 100644 model/simulationtests/python_plugin_search_paths.py diff --git a/model/simulationtests/python_plugin.py b/model/simulationtests/python_plugin.py index 52d498611..405c83fa1 100644 --- a/model/simulationtests/python_plugin.py +++ b/model/simulationtests/python_plugin.py @@ -107,7 +107,7 @@ def on_end_of_zone_timestep_before_zone_reporting(self, state) -> int: # Write it to a temporary directory so we don't pollute the current directory # ExternalFile will copy it -pluginPath = Path(tempfile.gettempdir()) / "python_plugin_program.py" +pluginPath = Path(tempfile.gettempdir()) / f"{Path(__file__).stem}_program.py" pluginPath.write_text(python_plugin_file_content) # create the external file object diff --git a/model/simulationtests/python_plugin.rb b/model/simulationtests/python_plugin.rb index 361973f64..4cd4fa40b 100644 --- a/model/simulationtests/python_plugin.rb +++ b/model/simulationtests/python_plugin.rb @@ -111,7 +111,8 @@ def on_end_of_zone_timestep_before_zone_reporting(self, state) -> int: # Write it to a temporary directory so we don't pollute the current directory # ExternalFile will copy it -pluginPath = File.join(Dir.tmpdir, 'python_plugin_program.py') +stem = File.basename(__FILE__, File.extname(__FILE__)) +pluginPath = File.join(Dir.tmpdir, "#{stem}_program.py") File.write(pluginPath, python_plugin_file_content) # create the external file object diff --git a/model/simulationtests/python_plugin_search_paths.py b/model/simulationtests/python_plugin_search_paths.py new file mode 100644 index 000000000..dae5fcd77 --- /dev/null +++ b/model/simulationtests/python_plugin_search_paths.py @@ -0,0 +1,132 @@ +import tempfile +from pathlib import Path + +import openstudio + +from lib.baseline_model import BaselineModel + +model = BaselineModel() + +# make a 1 story, 100m X 50m, 5 zone core/perimeter building +model.add_geometry(length=100, width=50, num_floors=1, floor_to_floor_height=4, plenum_height=0, perimeter_zone_depth=3) + +# assign constructions from a local library to the walls/windows/etc. in the model +model.set_constructions() + +# set whole building space type; simplified 90.1-2004 Large Office Whole Building +model.set_space_type() + +# add design days to the model (Chicago) +model.add_design_days() + +zone_names = sorted([x.nameString() for x in model.getThermalZones()]) + +zone_names_str_list = '["' + '", "'.join(zone_names) + '"]' + +# Add a PythonPlugin:Variable (all OS SDK PythonPluginVariable objects are +# translated to a single E+ PythonPlugin:Variables (extensible object)) +py_var = openstudio.model.PythonPluginVariable(model) +py_var.setName("AverageBuildingTemp") + +# Add a PythonPlugin:OutputVariable for that variable +py_out_var = openstudio.model.PythonPluginOutputVariable(py_var) +py_out_var.setName("Averaged Building Temperature") +py_out_var.setTypeofDatainVariable("Averaged") +py_out_var.setUpdateFrequency("ZoneTimestep") +py_out_var.setUnits("C") + +# Add a regular Output:Variable that references it +out_var = openstudio.model.OutputVariable("PythonPlugin:OutputVariable", model) +out_var.setKeyValue(py_out_var.nameString()) +out_var.setReportingFrequency("Timestep") + +# Add output variables for Zone Mean Air Temperature, so we can compare +outputVariable = openstudio.model.OutputVariable("Zone Mean Air Temperature", model) +outputVariable.setReportingFrequency("Timestep") + +# Trend Variable: while this is a fully functioning object, you're probably +# best just using a storage variable on the Python side (eg: a list) +py_trend_var = openstudio.model.PythonPluginTrendVariable(py_var) +py_trend_var.setName("Running Averaged Building Temperature") +n_timesteps = 24 * model.getTimestep().numberOfTimestepsPerHour() +py_trend_var.setNumberofTimestepstobeLogged(n_timesteps) + +py_var2 = openstudio.model.PythonPluginVariable(model) +py_var2.setName("RunningAverageBuildingTemp") + +py_out_trend_var = openstudio.model.PythonPluginOutputVariable(py_var2) +py_out_trend_var.setName("Running Averaged Building Temperature") +py_out_trend_var.setTypeofDatainVariable("Averaged") +py_out_trend_var.setUpdateFrequency("ZoneTimestep") +py_out_trend_var.setUnits("C") + +out_trend_var = openstudio.model.OutputVariable("PythonPlugin:OutputVariable", model) +out_trend_var.setReportingFrequency("Timestep") + +pluginClassName = "AverageZoneTemps" + +python_plugin_file_content = f"""from pyenergyplus.plugin import EnergyPlusPlugin +# NOTE: This external script must be locatable, so we'll add it to the PythonPluginSearchPaths +import python_plugin_search_paths_script + + +class {pluginClassName}(EnergyPlusPlugin): + + def __init__(self): + super().__init__() + self.do_setup = True + + def on_end_of_zone_timestep_before_zone_reporting(self, state) -> int: + if self.do_setup: + self.data['zone_volumes'] = [] + self.data['zone_temps'] = [] + zone_names = {zone_names_str_list} + for zone_name in zone_names: + handle = self.api.exchange.get_internal_variable_handle(state, 'Zone Air Volume', zone_name) + zone_volume = self.api.exchange.get_internal_variable_value(state, handle) + self.data['zone_volumes'].append(zone_volume) + self.data['zone_temps'].append( + self.api.exchange.get_variable_handle(state, 'Zone Mean Air Temperature', zone_name) + ) + self.data['avg_temp_variable'] = self.api.exchange.get_global_handle(state, '{py_var.nameString()}') + self.data['trend'] = self.api.exchange.get_trend_handle(state, '{py_trend_var.nameString()}') + self.data['running_avg_temp_variable'] = self.api.exchange.get_global_handle(state, '{py_var2.nameString()}') + self.do_setup = False + zone_temps = list() + for t_handle in self.data['zone_temps']: + zone_temps.append(self.api.exchange.get_variable_value(state, t_handle)) + numerator = 0.0 + denominator = 0.0 + for i in range(len(self.data['zone_volumes'])): + numerator += self.data['zone_volumes'][i] * zone_temps[i] + denominator += self.data['zone_volumes'][i] + average_temp = numerator / denominator + self.api.exchange.set_global_value(state, self.data['avg_temp_variable'], average_temp) + + past_daily_avg_temp = self.api.exchange.get_trend_average(state, self.data['trend'], {n_timesteps}) + self.api.exchange.set_global_value(state, self.data['running_avg_temp_variable'], past_daily_avg_temp) + return 0 +""" + +# Write it to a temporary directory so we don't pollute the current directory +# ExternalFile will copy it +pluginPath = Path(tempfile.gettempdir()) / f"{Path(__file__).stem}_program.py" +pluginPath.write_text(python_plugin_file_content) + +# create the external file object +external_file = openstudio.model.ExternalFile.getExternalFile(model, str(pluginPath)) +external_file = external_file.get() + +# create the python plugin instance object +python_plugin_instance = openstudio.model.PythonPluginInstance(external_file, pluginClassName) +python_plugin_instance.setRunDuringWarmupDays(False) + +# create the python plugin search paths object (this test should fail without it) +python_plugin_search_paths = model.getPythonPluginSearchPaths() +python_plugin_search_paths.setAddCurrentWorkingDirectorytoSearchPath(True) +python_plugin_search_paths.setAddInputFileDirectorytoSearchPath(True) +python_plugin_search_paths.setAddepinEnvironmentVariabletoSearchPath(True) +python_plugin_search_paths.addSearchPath(str(Path(__file__).parent)) + +# save the OpenStudio model (.osm) +model.save_openstudio_osm(osm_save_directory=None, osm_name="in.osm") diff --git a/model/simulationtests/python_plugin_search_paths.rb b/model/simulationtests/python_plugin_search_paths.rb index 6fc724b8c..acdd7bfbc 100644 --- a/model/simulationtests/python_plugin_search_paths.rb +++ b/model/simulationtests/python_plugin_search_paths.rb @@ -70,8 +70,10 @@ pluginClassName = 'AverageZoneTemps' python_plugin_file_content = ''"from pyenergyplus.plugin import EnergyPlusPlugin +# NOTE: This external script must be locatable, so we'll add it to the PythonPluginSearchPaths import python_plugin_search_paths_script + class #{pluginClassName}(EnergyPlusPlugin): def __init__(self): @@ -112,7 +114,8 @@ def on_end_of_zone_timestep_before_zone_reporting(self, state) -> int: # Write it to a temporary directory so we don't pollute the current directory # ExternalFile will copy it -pluginPath = File.join(Dir.tmpdir, 'python_plugin_program.py') +stem = File.basename(__FILE__, File.extname(__FILE__)) +pluginPath = File.join(Dir.tmpdir, "#{stem}_program.py") File.write(pluginPath, python_plugin_file_content) # create the external file object diff --git a/model_tests.rb b/model_tests.rb index 05eceb130..d9d395519 100644 --- a/model_tests.rb +++ b/model_tests.rb @@ -1513,13 +1513,17 @@ def test_python_plugin_osm # TODO: To be added in the next official release after: 3.9.0 # def test_python_plugin_search_paths_osm - # result = sim_test('python_plugin_search_paths.osm') + # result = sim_test('python_plugin_search_paths.osm') # end def test_python_plugin_search_paths_rb result = sim_test('python_plugin_search_paths.rb') end + def test_python_plugin_search_paths_py + result = sim_test('python_plugin_search_paths.py') + end + def test_refrigeration_system_rb result = sim_test('refrigeration_system.rb') end diff --git a/test_helpers.rb b/test_helpers.rb index 2820f823d..dba5807ff 100644 --- a/test_helpers.rb +++ b/test_helpers.rb @@ -708,11 +708,12 @@ def sim_test(filename, options = {}) cbor_target_path = File.join(files_dir, File.basename(cbor_ori_path)) FileUtils.cp(cbor_ori_path, cbor_target_path) - when 'python_plugin.osm' + when 'python_plugin.osm', 'python_plugin_search_paths' # We need to manually copy the supporting schedule into # the testruns folder for the simulation to be able to find it + program_file_name = "#{File.basename(filename, File.extname(filename))}_program.py" plugin_ori_path = File.join(File.dirname(__FILE__), - 'model/simulationtests/python_plugin_program.py') + 'model/simulationtests', program_file_name) plugin_ori_path = File.realpath(plugin_ori_path) # Have to make the directory first From 7d5f06efb27d8fd0fc137908ba0d87ad0b0be537 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Tue, 7 Jan 2025 17:51:11 +0100 Subject: [PATCH 6/8] Replace with an actual Path --- model/simulationtests/python_plugin_search_paths.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/simulationtests/python_plugin_search_paths.py b/model/simulationtests/python_plugin_search_paths.py index dae5fcd77..8fccdb2e6 100644 --- a/model/simulationtests/python_plugin_search_paths.py +++ b/model/simulationtests/python_plugin_search_paths.py @@ -126,7 +126,7 @@ def on_end_of_zone_timestep_before_zone_reporting(self, state) -> int: python_plugin_search_paths.setAddCurrentWorkingDirectorytoSearchPath(True) python_plugin_search_paths.setAddInputFileDirectorytoSearchPath(True) python_plugin_search_paths.setAddepinEnvironmentVariabletoSearchPath(True) -python_plugin_search_paths.addSearchPath(str(Path(__file__).parent)) +python_plugin_search_paths.addSearchPath(Path(__file__).parent) # save the OpenStudio model (.osm) model.save_openstudio_osm(osm_save_directory=None, osm_name="in.osm") From 9682d66d4797252638e02cfab51146adc2dd77fa Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Tue, 10 Jun 2025 18:42:50 +0200 Subject: [PATCH 7/8] Ignore python_plugin_search_paths_script.py --- highlevel_tests.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/highlevel_tests.rb b/highlevel_tests.rb index 62b3ba78c..8c2dd24be 100644 --- a/highlevel_tests.rb +++ b/highlevel_tests.rb @@ -64,7 +64,7 @@ def test_rbs_are_defined_sim_tests def test_pys_are_defined_sim_tests all_python_paths = Dir.glob(File.join($ModelDir, '*.py')) all_python_filenames = all_python_paths.map { |p| File.basename(p) } - all_python_filenames -= ['python_plugin_program.py'] + all_python_filenames -= ['python_plugin_program.py', 'python_plugin_search_paths_script.py'] content = File.read('model_tests.rb') sim_test_re = Regexp.new('def test_.*\n(?:\s*#)*\s+result = sim_test\(\'(?.*\.py)\'\)\n(?:\s*#)*\s+end') From f0a6873b6265a0c77e4a09bf641be5c5e17ed433 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Tue, 10 Jun 2025 22:43:57 +0200 Subject: [PATCH 8/8] Update test_helpers.rb --- test_helpers.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_helpers.rb b/test_helpers.rb index baad9c080..b57d0d6bf 100644 --- a/test_helpers.rb +++ b/test_helpers.rb @@ -708,7 +708,7 @@ def sim_test(filename, options = {}) cbor_target_path = File.join(files_dir, File.basename(cbor_ori_path)) FileUtils.cp(cbor_ori_path, cbor_target_path) - when 'python_plugin.osm', 'python_plugin_search_paths' + when 'python_plugin.osm', 'python_plugin_search_paths.osm' # We need to manually copy the supporting schedule into # the testruns folder for the simulation to be able to find it program_file_name = "#{File.basename(filename, File.extname(filename))}_program.py"