Skip to content

Schedule:File gives EnergyPlus error Invalid String Position when using relative path #129

@nfette

Description

@nfette

We observed that under certain conditions, using a Schedule:File object can trigger an EnergyPlus error, but there are workarounds.

Example error

We are developing a residential measure setup for SWHC045, e.g. see internal review or example. The measure uses residential prototypes, runs in EnergyPlus v9.5. A unique feature of the measure is that the templates used by some cohorts use Schedule:File objects referenced by a relative path.

We run modelkit rake run and look for outputs we find:

instance-out.err

** Severe ** Invalid String Position

However, the model seems valid and there are no preceeding warnings or errors.

Debugging

The error occurs only when the Schedule:File objects use a relative path, likely due to the length of the string formed by concatenating the simulation folder and the relative path string.

prototypes/residential/MFm-1985-combi/templates/root.pxt near line 316

<% zones = ["01","02","03","04","05","06","07","08","09","10","11","12","13","14","15","16"]
 climate_zone_str = zones[climate_zone - 1] %>
 Schedule:File,
     site_mains_water_temp,  !- Name
     Temperature,                !- Schedule Type Limits Name
     ../../../../../../../../templates/hot water profile/site_mains_water_temp_CZ<%= climate_zone_str %>.csv,  !- File Name
     1,                       !- Column Number
     1,                       !- Rows to Skip at Top
     8760,                    !- Number of Hours of Data
     Comma,                   !- Column Separator
     No,                      !- Interpolate to Timestep	

The simulation runs in a folder like

C:/DEER-Prototypes-EnergyPlus/residential measures/SWHC045 Heat Pump HVAC Fuel Sub/SWHC045 Heat Pump HVAC Fuel Sub_MFm_Ex/runs/CZ01/MFm&0&rDXHW&Ex&DHW/RE-dxHW_equip-Boiler-AFUE82-Radiator-12.4-SEER2/instance1018114027

The path of this folder is already 217 characters long, approaching a limit in some instances of Windows and C++ routines. Internally, EnergyPlus would form the intermediate string path to the schedule file:

C:/DEER-Prototypes-EnergyPlus/residential measures/SWHC045 Heat Pump HVAC Fuel Sub/SWHC045 Heat Pump HVAC Fuel Sub_MFm_Ex/runs/CZ01/MFm&0&rDXHW&Ex&DHW/RE-dxHW_equip-Boiler-AFUE82-Radiator-12.4-SEER2/instance1018114027/../../../../../../../../templates/hot water profile/site_mains_water_temp_CZ01.csv

The absolute path would be simply:

C:/DEER-Prototypes-EnergyPlus/templates/hot water profile/site_mains_water_temp_CZ01.csv

However, it appears that EnergyPlus implementation has a limitation on handling the intermediate path string, in this case 300 characters long.

Workaround 1

The user can modify templates before starting a batch of simulations to replace all relative paths (e.g. starting with ../) with absolute paths (starting with C:/).

prototypes/residential/MFm-1985-combi/templates/root.pxt near line 316

<% zones = ["01","02","03","04","05","06","07","08","09","10","11","12","13","14","15","16"]
 climate_zone_str = zones[climate_zone - 1] %>
 Schedule:File,
     site_mains_water_temp,  !- Name
     Temperature,                !- Schedule Type Limits Name
     C:/DEER-Prototypes-EnergyPlus/templates/hot water profile/site_mains_water_temp_CZ<%= climate_zone_str %>.csv,  !- File Name
     1,                       !- Column Number
     1,                       !- Rows to Skip at Top
     8760,                    !- Number of Hours of Data
     Comma,                   !- Column Separator
     No,                      !- Interpolate to Timestep	

This is what we have been doing. However, we do not commit this change to the repository because it is not portable. Another user might need to install the repository at a different location other than "C:/DEER-Prototypes-EnergyPlus", for example, if working simultaneously with two branches. So, hard-coding the absolute path is not a real fix to the issue.

Workaround 2

We could create logic in the rakefile or template to insert the absolute path of the repository when composing the IDF model. Via Ruby functions,
the rakefile or template could determine the folder path where the rakefile is running ("study path") or a path defined in the config file,
and build the path of the repository relative to it.
Here is an example implementation using the rakefile to insert a set of global variables into the "site.pxt" file containing relevant directory paths.
The site.pxt file is a modelkit template that is generated during the modelkit compose step and each root prototype imports it near the beginning of the file. In modelkit, variables beginning with a "$" are global in scope, i.e. available to use in all templates without needing a new template parameter.

rakefile.rb near line 31

def generate_site_pxt(idd, ddy_path, site_path, study_dir, config)
  site_file = File.open(site_path, "w")

  repository_dir = File.expand_path(File.join(study_dir,'../../../'))

  # Pass directories from modelkit-config into site.pxt
  site_file.puts(<<-HEREDOC)
<%
# Directory paths
$study_dir = '#{study_dir}'
$prototypes_dir = '#{config[:prototypes_dir][0]}'
$templates_dir = '#{config[:templates_dir][0]}'
$weather_dir = '#{config[:weather_dir][0]}'
$codes_dir = '#{config[:codes_dir][0]}'
$repository_dir = '#{repository_dir}'
%>

  HEREDOC

rakefile.rb near line 378

    # generate site.pxt from .ddy file
    file site_path => [weather_path, ddy_path] do
      idd = open_data_dictionary
      pathname = Pathname.new(site_path).relative_path_from(runs_pathname)
      puts "Generating: #{pathname}\n"
      generate_site_pxt(idd, ddy_path, site_path, study_dir, config)
    end

prototypes/residential/MFm-1985-combi/templates/root.pxt near line 316

<% zones = ["01","02","03","04","05","06","07","08","09","10","11","12","13","14","15","16"]
 climate_zone_str = zones[climate_zone - 1] %>
 Schedule:File,
     site_mains_water_temp,  !- Name
     Temperature,                !- Schedule Type Limits Name
     <%= repository_dir %>/templates/hot water profile/site_mains_water_temp_CZ<%= climate_zone_str %>.csv,  !- File Name
     1,                       !- Column Number
     1,                       !- Rows to Skip at Top
     8760,                    !- Number of Hours of Data
     Comma,                   !- Column Separator
     No,                      !- Interpolate to Timestep	

The advantage of this approach is that it would fix the issue for other users running these models. A disadvantage of this approach is that all file paths would be hard-coded, so if we share a model composed on one computer and try to run it on another, the user may need to update the paths of all schedule files in the model.

Dead end workarounds

In order to make a more portable solution where it is easier to run the IDF files in a different location, we could (a) try to create a single parameter in the IDF file that all schedules reference, or (b) adapt the rakefile to place a copy of the schedules into the simulation run folder to avoid the need for an absolute path. Option (a) approaches are described below but seem to be a dead end. Option (b) could introduce excessive complication and require a modification to modelkit.

IDF file parameter via EP-Macro definition

EnergyPlus has a macro processor that allows some parameters to be defined and referenced throughout the model. We could
utilize EP-Macro definitions to insert the path of the repository as a macro variable, and then each Schedule:File object would reference the macro.
However, EP-Macro has a 40 character limit and will truncate any path that is longer without warning the user, so this is not a reliable solution.

prototypes/residential/MFm-1985-combi/templates/root.pxt

<%# Inserting repository path macro %>
##set1 DEERROOT C:/DEER-Prototypes-EnergyPlus

...

<% zones = ["01","02","03","04","05","06","07","08","09","10","11","12","13","14","15","16"]
 climate_zone_str = zones[climate_zone - 1] %>
 Schedule:File,
     site_mains_water_temp,  !- Name
     Temperature,                !- Schedule Type Limits Name
     DEERROOT[]/templates/hot water profile/site_mains_water_temp_CZ<%= climate_zone_str %>.csv,  !- File Name
     1,                       !- Column Number
     1,                       !- Rows to Skip at Top
     8760,                    !- Number of Hours of Data
     Comma,                   !- Column Separator
     No,                      !- Interpolate to Timestep	

To enable the EP-Macro preprocessor, pass the -m flag to modelkit-energyplus in the rakefile, within the logic blocks for size_sql_path and run_sql_path:

          # Run sizing input files for design days only.
          file size_sql_path => size_idf_path do
            pathname = Pathname.new(size_idf_path).relative_path_from(runs_pathname)
            puts "Running size run: #{pathname}\n"

-            command = "modelkit-energyplus energyplus-run --weather=\"#{epw_path}\" \"#{size_idf_path}\""
+            command = "modelkit-energyplus energyplus-run -m --weather=\"#{epw_path}\" \"#{size_idf_path}\""
            run_process(command, size_dir)

During simulation run, the EP-macro preprocessor will expand the macros and save a new file (in.IDF) that EnergyPlus can run.

EnergyPlus ParametricValueForRun

Without macros, we can define a parameter in an EnergyPlus model via the ParametricValueForRun object.
In theory, this would allow another user to easily adjust the paths to the schedule files
for use on another computer.
However, an EnergyPlus model with a Parametric object must be pre-processed by Parametric Preprocessor
before running in EnergyPlus simulation engine, and modelkit does not support this workflow.

prototypes/residential/MFm-1985-combi/templates/root.pxt

Parametric:SetValueForRun,
  $scheduleFileMainsTemperature,                       !- Name
  <%= $repository_dir %>/templates/hot water profile/site_mains_water_temp_CZ<%= climate_zone_str %>.csv; !- Value for Run 1

...

<% zones = ["01","02","03","04","05","06","07","08","09","10","11","12","13","14","15","16"]
 climate_zone_str = zones[climate_zone - 1] %>
 Schedule:File,
     site_mains_water_temp,  !- Name
     Temperature,                !- Schedule Type Limits Name
    $scheduleFileMainsTemperature,  !- File Name
     1,                       !- Column Number
     1,                       !- Rows to Skip at Top
     8760,                    !- Number of Hours of Data
     Comma,                   !- Column Separator
     No,                      !- Interpolate to Timestep	

Conclusion

No action is required since users may apply workaround 1. However, standardizing on an approach to introduce a global variable like repository_dir might save some time for new users and testing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions