Esempio n. 1
0
 def main(self, run_directory, file_name, args):
     print(args['workflow location'])
     self.versionclass = Version()
     if 'workflow location' in args:
         self.transition_executable_files = self.find_transition_executable_files(
             args['workflow location'])
         if self.transition_executable_files:
             print(self.transition_executable_files)
             full_file_path = os.path.join(run_directory, file_name)
             if os.path.exists(full_file_path):
                 returned_success, returned_message = self.perform_transition(
                     full_file_path)
                 return EPLaunchWorkflowResponse1(success=returned_success,
                                                  message=returned_message,
                                                  column_data=[])
             else:
                 return EPLaunchWorkflowResponse1(
                     success=False,
                     message="Transition file not found: {}!".format(''),
                     column_data=[])
         else:
             return EPLaunchWorkflowResponse1(
                 success=False,
                 message="Transition exefile not found: {}!".format(''),
                 column_data=[])
     else:
         return EPLaunchWorkflowResponse1(
             success=False,
             message="Workflow location missing: {}!".format(
                 args['worflow location']),
             column_data=[])
Esempio n. 2
0
 def perform_transition(self, path_to_old_file):
     v = Version()
     is_version_found, original_version_string, original_version_number = v.check_energyplus_version(
         path_to_old_file)
     print(is_version_found, original_version_string,
           original_version_number)
     if original_version_number in self.transition_executable_files:
         current_version_number = original_version_number
         while current_version_number in self.transition_executable_files:
             current_version_string = v.string_version_from_number(
                 current_version_number)
             next_version_number, specific_transition_exe = self.transition_executable_files[
                 current_version_number]
             ok, msg = self.run_single_transition(specific_transition_exe,
                                                  path_to_old_file,
                                                  current_version_string)
             if not ok:
                 return False, 'Transition Failed!'
             current_version_number = next_version_number
         final_version_string = v.string_version_from_number(
             current_version_number)
         return True, 'Version update successful for IDF file {} originally version {} and now version {}'.format(
             path_to_old_file, original_version_string,
             final_version_string)
     else:
         return False, 'Updating the IDF file {} that is from version {} is not supported.'.format(
             path_to_old_file, original_version_string)
Esempio n. 3
0
    def test_check_energyplus_version(self):
        v = Version()

        # the version object is on one line
        file_path = os.path.join(os.path.dirname(__file__), "Minimal.idf")
        is_version_found, version_string, version_number = v.check_energyplus_version(
            file_path)
        self.assertTrue(is_version_found)
        self.assertEqual(version_string, "8.9")
        self.assertEqual(version_number, 80900)

        # the version object is spreads across two lines
        file_path = os.path.join(os.path.dirname(__file__), "Minimal2.idf")
        is_version_found, version_string, version_number = v.check_energyplus_version(
            file_path)
        self.assertTrue(is_version_found)
        self.assertEqual(version_string, "8.9.1")
        self.assertEqual(version_number, 80901)
Esempio n. 4
0
 def test_numeric_version_from_string(self):
     v = Version()
     self.assertEqual(v.numeric_version_from_string("8.1.0"), 80100)
     self.assertEqual(v.numeric_version_from_string("8.8.8"), 80808)
     self.assertEqual(v.numeric_version_from_string("8.7"), 80700)
     self.assertEqual(v.numeric_version_from_string("8.6-dfjsuy"), 80600)
     self.assertEqual(v.numeric_version_from_string("8.4.2-dfjsuy"), 80402)
     self.assertEqual(v.numeric_version_from_string("7.12.13"), 71213)
Esempio n. 5
0
class TransitionWorkflow(BaseEPLaunchWorkflow1):
    def name(self):
        return "Transition-${CMAKE_VERSION_MAJOR}.${CMAKE_VERSION_MINOR}.${CMAKE_VERSION_PATCH}"

    def context(self):
        return "EnergyPlus-${CMAKE_VERSION_MAJOR}.${CMAKE_VERSION_MINOR}.${CMAKE_VERSION_PATCH}-${CMAKE_VERSION_BUILD}"

    def description(self):
        return "Run Version Transition"

    def get_file_types(self):
        return ["*.idf"]

    def get_output_suffixes(self):
        return [".vcperr"]

    def get_extra_data(self):
        return {"Hey, it's extra": "data"}

    def main(self, run_directory, file_name, args):
        print(args['workflow location'])
        self.versionclass = Version()
        if 'workflow location' in args:
            self.transition_executable_files = self.find_transition_executable_files(
                args['workflow location'])
            if self.transition_executable_files:
                print(self.transition_executable_files)
                full_file_path = os.path.join(run_directory, file_name)
                if os.path.exists(full_file_path):
                    returned_success, returned_message = self.perform_transition(
                        full_file_path)
                    return EPLaunchWorkflowResponse1(success=returned_success,
                                                     message=returned_message,
                                                     column_data=[])
                else:
                    return EPLaunchWorkflowResponse1(
                        success=False,
                        message="Transition file not found: {}!".format(''),
                        column_data=[])
            else:
                return EPLaunchWorkflowResponse1(
                    success=False,
                    message="Transition exefile not found: {}!".format(''),
                    column_data=[])
        else:
            return EPLaunchWorkflowResponse1(
                success=False,
                message="Workflow location missing: {}!".format(
                    args['worflow location']),
                column_data=[])

    def find_transition_executable_files(self, worflow_location):
        energyplus_root_folder, _ = os.path.split(worflow_location)
        preprocess_folder = os.path.join(energyplus_root_folder, 'PreProcess')
        idfversionupdateer_folder = os.path.join(preprocess_folder,
                                                 'IDFVersionUpdater')
        transition_exes = [
            os.path.join(idfversionupdateer_folder, f)
            for f in os.listdir(idfversionupdateer_folder)
            if 'Transition-V' in f
        ]
        transition_exes.sort()
        transition_dict = {}
        for transition_exe in transition_exes:
            start_number, end_number = self.get_start_end_version_from_exe(
                transition_exe)
            transition_dict[start_number] = [end_number, transition_exe]
        return transition_dict

    def get_start_end_version_from_exe(self, exe_file_name):
        filename = os.path.basename(exe_file_name)
        if filename[:11] == 'Transition-':
            versions_string_with_maybe_ext = filename[11:]
            if '.' in versions_string_with_maybe_ext:
                versions_string, _ = versions_string_with_maybe_ext.split('.')
            else:
                versions_string = versions_string_with_maybe_ext
            start_version, end_version = versions_string.split('-to-')
            start_number = self.versionclass.numeric_version_from_dash_string(
                start_version)
            end_number = self.versionclass.numeric_version_from_dash_string(
                end_version)
            return start_number, end_number
        else:
            return 0, 0

    def perform_transition(self, path_to_old_file):
        v = Version()
        is_version_found, original_version_string, original_version_number = v.check_energyplus_version(
            path_to_old_file)
        print(is_version_found, original_version_string,
              original_version_number)
        if original_version_number in self.transition_executable_files:
            current_version_number = original_version_number
            while current_version_number in self.transition_executable_files:
                current_version_string = v.string_version_from_number(
                    current_version_number)
                next_version_number, specific_transition_exe = self.transition_executable_files[
                    current_version_number]
                ok, msg = self.run_single_transition(specific_transition_exe,
                                                     path_to_old_file,
                                                     current_version_string)
                if not ok:
                    return False, 'Transition Failed!'
                current_version_number = next_version_number
            final_version_string = v.string_version_from_number(
                current_version_number)
            return True, 'Version update successful for IDF file {} originally version {} and now version {}'.format(
                path_to_old_file, original_version_string,
                final_version_string)
        else:
            return False, 'Updating the IDF file {} that is from version {} is not supported.'.format(
                path_to_old_file, original_version_string)

    def run_single_transition(self, transition_exe_path, file_to_update,
                              old_verson_string):
        file_no_extension, _ = os.path.splitext(file_to_update)
        run_directory, _ = os.path.split(transition_exe_path)
        command_line_args = [transition_exe_path, file_to_update]
        idf_copy_of_old_file_temp = file_to_update + '_tempcopy'
        # make temporary copy that preserve file date
        shutil.copy2(file_to_update, idf_copy_of_old_file_temp)
        # see if rvi file is used
        rvi_copy_of_old_file_temp = ''
        orig_rvi_file = file_no_extension + '.rvi'
        if os.path.exists(orig_rvi_file):
            rvi_copy_of_old_file_temp = file_no_extension + '.rvi_tempcopy'
            shutil.copy2(orig_rvi_file, rvi_copy_of_old_file_temp)
        # see if mvi file is used
        mvi_copy_of_old_file_temp = ''
        orig_mvi_file = file_no_extension + '.mvi'
        if os.path.exists(orig_mvi_file):
            mvi_copy_of_old_file_temp = file_no_extension + '.mvi_tempcopy'
            shutil.copy2(orig_mvi_file, mvi_copy_of_old_file_temp)
        # perform transition
        try:
            for message in self.execute_for_callback(command_line_args,
                                                     run_directory):
                self.callback(message)
        except subprocess.CalledProcessError:
            self.callback("Transition Failed for this file")
            return False, 'Transition failed for file ' + file_to_update
        self.callback('Conversion using %s complete! Copying files' %
                      os.path.basename(transition_exe_path))
        # delete the extra outputs that are not needed
        idfnew_path = file_no_extension + '.idfnew'
        if os.path.exists(idfnew_path):
            os.remove(idfnew_path)
            idfold_path = file_no_extension + '.idfold'
            if os.path.exists(idfold_path):
                os.remove(idfold_path)
            # rename the previously copied file to preserve the old version
            idf_revised_old_path = file_no_extension + '_' + old_verson_string + '.idf'
            if os.path.exists(idf_copy_of_old_file_temp):
                os.rename(idf_copy_of_old_file_temp, idf_revised_old_path)
            # work on the rvi update
            rvinew_path = file_no_extension + '.rvinew'
            if os.path.exists(rvinew_path):
                os.remove(rvinew_path)
            rviold_path = file_no_extension + '.rviold'
            if os.path.exists(rviold_path):
                os.remove(rviold_path)
            rvi_revised_old_path = file_no_extension + '_' + old_verson_string + '.rvi'
            if os.path.exists(orig_rvi_file):
                os.rename(rvi_copy_of_old_file_temp, rvi_revised_old_path)
            # work on the rvi update
            mvinew_path = file_no_extension + '.mvinew'
            if os.path.exists(mvinew_path):
                os.remove(mvinew_path)
            mviold_path = file_no_extension + '.mviold'
            if os.path.exists(mviold_path):
                os.remove(mviold_path)
            mvi_revised_old_path = file_no_extension + '_' + old_verson_string + '.mvi'
            if os.path.exists(orig_mvi_file):
                os.rename(mvi_copy_of_old_file_temp, mvi_revised_old_path)
            # process any error file
            vcperr_file = file_no_extension + '.vcperr'
            if os.path.exists(vcperr_file):
                vcperr_revised_file = file_no_extension + '_' + old_verson_string + '.vcperr'
                os.rename(vcperr_file, vcperr_revised_file)
            return True, 'Successfully converted file: ' + file_to_update
        else:
            return False, 'Conversion problem for file: ' + file_to_update
Esempio n. 6
0
 def setUp(self):
     self.v = Version()
Esempio n. 7
0
class TestVersion(unittest.TestCase):
    def setUp(self):
        self.v = Version()

    def test_numeric_version_from_string(self):
        self.assertEqual(self.v.numeric_version_from_string("8.1.0"), 80100)
        self.assertEqual(self.v.numeric_version_from_string("8.8.8"), 80800)
        self.assertEqual(self.v.numeric_version_from_string("8.7"), 80700)
        self.assertEqual(self.v.numeric_version_from_string("8.6-dfjsuy"),
                         80600)
        self.assertEqual(self.v.numeric_version_from_string("8.4.2-dfjsuy"),
                         80400)
        self.assertEqual(self.v.numeric_version_from_string("7.12.13"), 71200)

    def test_line_with_no_comment(self):
        self.assertEqual(
            self.v.line_with_no_comment(" object, ! this is a comment"),
            "object,")
        self.assertEqual(self.v.line_with_no_comment("! this is a comment"),
                         "")
        self.assertEqual(self.v.line_with_no_comment(" object, "), "object,")

    def test_check_energyplus_version_one_line(self):
        file_path = os.path.join(os.path.dirname(__file__), "Minimal.idf")
        is_version_found, version_string, version_number = self.v.check_energyplus_version(
            file_path)
        self.assertTrue(is_version_found)
        self.assertEqual(version_string, "8.9")
        self.assertEqual(version_number, 80900)

    def test_check_energyplus_version_imf(self):
        file_path = os.path.join(os.path.dirname(__file__), "Minimal.imf")
        is_version_found, version_string, version_number = self.v.check_energyplus_version(
            file_path)
        self.assertTrue(is_version_found)
        self.assertEqual(version_string, "8.9")
        self.assertEqual(version_number, 80900)

    def test_check_energyplus_version_two_lines(self):
        file_path = os.path.join(os.path.dirname(__file__), "Minimal2.idf")
        is_version_found, version_string, version_number = self.v.check_energyplus_version(
            file_path)
        self.assertTrue(is_version_found)
        self.assertEqual(version_string, "8.9.1")
        self.assertEqual(version_number, 80900)

    def test_check_energyplus_version_epJSON(self):
        file_path = os.path.join(os.path.dirname(__file__), "Minimal.epJSON")
        is_version_found, version_string, version_number = self.v.check_energyplus_version(
            file_path)
        self.assertTrue(is_version_found)
        self.assertEqual(version_string, "8.9")
        self.assertEqual(version_number, 80900)

    def test_check_energyplus_version_bad_extension(self):
        file_path = os.path.join(os.path.dirname(__file__), "hi.txt")
        is_version_found, version_string, version_number = self.v.check_energyplus_version(
            file_path)
        self.assertFalse(is_version_found)
        self.assertEqual('', version_string)
        self.assertEqual(0, version_number)

    def test_check_energyplus_version_epJSON_no_version(self):
        file_path = os.path.join(os.path.dirname(__file__),
                                 "Minimal_No_Version.epJSON")
        is_version_found, version_string, version_number = self.v.check_energyplus_version(
            file_path)
        self.assertFalse(is_version_found)
        self.assertEqual('', version_string)
        self.assertEqual(0, version_number)

    @unittest.skipUnless(
        Platform.get_current_platform() == Platform.LINUX,
        "Test badly encoded file on Linux systems, test fails on Windows")
    def test_check_energyplus_version_bad_file(self):
        file_path = os.path.join(os.path.dirname(__file__), "Minimal_820.idf")
        is_version_found, version_string, version_number = self.v.check_energyplus_version(
            file_path)
        self.assertFalse(is_version_found)
        self.assertEqual('', version_string)
        self.assertEqual('', version_number)

    def test_numeric_version_from_dash_string(self):
        dash_string = 'V0-2'
        numeric = self.v.numeric_version_from_dash_string(dash_string)
        self.assertEqual(
            numeric, 200
        )  # even though it has a zero appended, it comes back an integer
        dash_string = 'V1-2-0'
        numeric = self.v.numeric_version_from_dash_string(dash_string)
        self.assertEqual(numeric, 10200)
        dash_string = '2-3-0'
        numeric = self.v.numeric_version_from_dash_string(dash_string)
        self.assertEqual(numeric, 20300)
        dash_string = '13-4-0'
        numeric = self.v.numeric_version_from_dash_string(dash_string)
        self.assertEqual(numeric, 130400)

    def test_string_version_from_number(self):
        original_number = 10000
        string_version = self.v.string_version_from_number(original_number)
        self.assertEqual('V010000', string_version)
class TransitionWorkflow(BaseEPLaunchWorkflow1):
    def name(self):
        return "Transition-9.0.1"

    def context(self):
        return "EnergyPlus-9.0.1-bb7ca4f0da"

    def description(self):
        return "Run Version Transition"

    def get_file_types(self):
        return ["*.idf"]

    def get_output_suffixes(self):
        return [".vcperr"]

    def get_extra_data(self):
        return {"Hey, it's extra": "data"}

    def main(self, run_directory, file_name, args):
        print(args['workflow location'])
        self.versionclass = Version()
        if 'workflow location' in args:
            self.transition_executable_files = self.find_transition_executable_files(
                args['workflow location'])
            if self.transition_executable_files:
                print(self.transition_executable_files)
                full_file_path = os.path.join(run_directory, file_name)
                if os.path.exists(full_file_path):
                    returned_success, returned_message = self.perform_transition(
                        full_file_path)
                    return EPLaunchWorkflowResponse1(success=returned_success,
                                                     message=returned_message,
                                                     column_data=[])
                else:
                    return EPLaunchWorkflowResponse1(
                        success=False,
                        message="Transition file not found: {}!".format(''),
                        column_data=[])
            else:
                return EPLaunchWorkflowResponse1(
                    success=False,
                    message="Transition exefile not found: {}!".format(''),
                    column_data=[])
        else:
            return EPLaunchWorkflowResponse1(
                success=False,
                message="Workflow location missing: {}!".format(
                    args['worflow location']),
                column_data=[])

    def find_transition_executable_files(self, worflow_location):
        energyplus_root_folder, _ = os.path.split(worflow_location)
        preprocess_folder = os.path.join(energyplus_root_folder, 'PreProcess')
        idfversionupdateer_folder = os.path.join(preprocess_folder,
                                                 'IDFVersionUpdater')
        transition_exes = [
            os.path.join(idfversionupdateer_folder, f)
            for f in os.listdir(idfversionupdateer_folder)
            if 'Transition-V' in f
        ]
        transition_exes.sort()
        transition_dict = {}
        for transition_exe in transition_exes:
            start_number, end_number = self.get_start_end_version_from_exe(
                transition_exe)
            transition_dict[start_number] = [end_number, transition_exe]
        return transition_dict

    def get_start_end_version_from_exe(self, exe_file_name):
        if '\\' in exe_file_name:
            parts = exe_file_name.split('\\')
            filename = parts[-1]
        else:
            filename = exe_file_name
        # Transition-V8-8-0-to-V8-9-0.exe
        # 01234567890123456789012345678901234567890
        if filename[:11] == 'Transition-':
            versions_string_with_ext = filename[11:]
            versions_string, _ = versions_string_with_ext.split('.')
            start_version, end_version = versions_string.split('-to-')
            start_number = self.versionclass.numeric_version_from_dash_string(
                start_version)
            end_number = self.versionclass.numeric_version_from_dash_string(
                end_version)
            return start_number, end_number
        else:
            return 0, 0

    def perform_transition(self, path_to_old_file):
        v = Version()
        is_version_found, original_version_string, original_version_number = v.check_energyplus_version(
            path_to_old_file)
        print(is_version_found, original_version_string,
              original_version_number)
        if original_version_number in self.transition_executable_files:
            current_version_number = original_version_number
            while current_version_number in self.transition_executable_files:
                current_version_string = v.string_version_from_number(
                    current_version_number)
                next_version_number, specific_transition_exe = self.transition_executable_files[
                    current_version_number]
                self.run_single_transition(specific_transition_exe,
                                           path_to_old_file,
                                           current_version_string)
                current_version_number = next_version_number
            final_version_string = v.string_version_from_number(
                current_version_number)
            return True, 'Version update successful for IDF file {} originally version {} and now version {}'.format(
                path_to_old_file, original_version_string,
                final_version_string)
        else:
            return False, 'Updating the IDF file {} that is from version {} is not supported.'.format(
                path_to_old_file, original_version_string)

    def run_single_transition(self, transition_exe_path, file_to_update,
                              old_verson_string):
        file_no_extension, _ = os.path.splitext(file_to_update)
        run_directory, _ = os.path.split(transition_exe_path)
        command_line_args = [transition_exe_path, file_to_update]
        idf_copy_of_old_file_temp = file_to_update + '_tempcopy'
        # make temporary copy that preserve file date
        shutil.copy2(file_to_update, idf_copy_of_old_file_temp)
        # see if rvi file is used
        orig_rvi_file = file_no_extension + '.rvi'
        if os.path.exists(orig_rvi_file):
            rvi_copy_of_old_file_temp = file_no_extension + '.rvi_tempcopy'
            shutil.copy2(orig_rvi_file, rvi_copy_of_old_file_temp)
        # see if mvi file is used
        orig_mvi_file = file_no_extension + '.mvi'
        if os.path.exists(orig_mvi_file):
            mvi_copy_of_old_file_temp = file_no_extension + '.mvi_tempcopy'
            shutil.copy2(orig_mvi_file, mvi_copy_of_old_file_temp)
        # perform transition
        process = subprocess.run(command_line_args,
                                 creationflags=subprocess.CREATE_NEW_CONSOLE,
                                 cwd=run_directory)
        if process.returncode == 0:
            print('convertion complete')
            # delete the extra outputs that are not needed
            idfnew_path = file_no_extension + '.idfnew'
            if os.path.exists(idfnew_path):
                os.remove(idfnew_path)
                idfold_path = file_no_extension + '.idfold'
                if os.path.exists(idfold_path):
                    os.remove(idfold_path)
                # rename the previously copied file to preserve the old version
                idf_revised_old_path = file_no_extension + '_' + old_verson_string + '.idf'
                if os.path.exists(idf_copy_of_old_file_temp):
                    os.rename(idf_copy_of_old_file_temp, idf_revised_old_path)
                # work on the rvi update
                rvinew_path = file_no_extension + '.rvinew'
                if os.path.exists(rvinew_path):
                    os.remove(rvinew_path)
                rviold_path = file_no_extension + '.rviold'
                if os.path.exists(rviold_path):
                    os.remove(rviold_path)
                rvi_revised_old_path = file_no_extension + '_' + old_verson_string + '.rvi'
                if os.path.exists(orig_rvi_file):
                    os.rename(rvi_copy_of_old_file_temp, rvi_revised_old_path)
                # work on the rvi update
                mvinew_path = file_no_extension + '.mvinew'
                if os.path.exists(mvinew_path):
                    os.remove(mvinew_path)
                mviold_path = file_no_extension + '.mviold'
                if os.path.exists(mviold_path):
                    os.remove(mviold_path)
                mvi_revised_old_path = file_no_extension + '_' + old_verson_string + '.mvi'
                if os.path.exists(orig_mvi_file):
                    os.rename(mvi_copy_of_old_file_temp, mvi_revised_old_path)
                # process any error file
                vcperr_file = file_no_extension + '.vcperr'
                if os.path.exists(vcperr_file):
                    vcperr_revised_file = file_no_extension + '_' + old_verson_string + '.vcperr'
                    os.rename(vcperr_file, vcperr_revised_file)
                return True
            else:
                print('convertion problem-2', transition_exe_path,
                      file_to_update)
                return False
        else:
            print('convertion problem-1', transition_exe_path, file_to_update)
            return False
    def run_energyplus(self, isIP, run_directory, file_name, args):

        full_file_path = os.path.join(run_directory, file_name)
        file_name_no_ext, extension = os.path.splitext(file_name)
        # the following is the same when .idf is used

        if 'workflow location' in args:
            energyplus_root_folder, _ = os.path.split(
                args['workflow location'])

            # Run EnergyPlus binary
            if platform.system() == 'Windows':
                energyplus_binary = os.path.join(energyplus_root_folder,
                                                 'energyplus.exe')
            else:
                energyplus_binary = os.path.join(energyplus_root_folder,
                                                 'energyplus')
            if not os.path.exists(energyplus_binary):
                return EPLaunchWorkflowResponse1(
                    success=False,
                    message="EnergyPlus binary not found: {}!".format(
                        energyplus_binary),
                    column_data=[])
        else:
            return EPLaunchWorkflowResponse1(
                success=False,
                message="Workflow location missing: {}!".format(
                    args['worflow location']),
                column_data=[])

        v = Version()
        is_found, current_version, numeric_version = v.check_energyplus_version(
            full_file_path)
        if is_found:
            if numeric_version >= 80300:  # EnergyPlus 8.3.0 was the first with command line options.

                # start with the binary name, obviously
                command_line_args = [energyplus_binary]

                if extension == '.imf':
                    command_line_args += ['--epmacro']

                if extension != '.epJSON':
                    command_line_args += ['--expandobjects']

                if not isIP:  # if using SI output units just use readvars CLI option
                    command_line_args += ['--readvars']

                # add some config parameters
                command_line_args += [
                    '--output-prefix', file_name_no_ext, '--output-suffix', 'C'
                ]

                # add in simulation control args
                if 'weather' in args and args['weather']:
                    command_line_args += ['--weather', args['weather']]
                else:
                    command_line_args += ['--design-day']

                # and at the very end, add the file to run
                command_line_args += [full_file_path]

                # run E+ and gather (for now fake) data
                try:
                    for message in self.execute_for_callback(
                            command_line_args, run_directory):
                        self.callback(message)
                except subprocess.CalledProcessError:
                    self.callback("E+ FAILED")
                    return EPLaunchWorkflowResponse1(
                        success=False,
                        message="EnergyPlus failed for file: %s!" %
                        full_file_path,
                        column_data={})

                if isIP:
                    # set up the ESO and MTR output files for either unit conversion or just ReadVarsESO
                    # *.eso back to eplusout.eso
                    eso_path = os.path.join(run_directory,
                                            file_name_no_ext + '.eso')
                    eplusouteso_path = os.path.join(run_directory,
                                                    'eplusout.eso')
                    shutil.copy(eso_path, eplusouteso_path)
                    # *.mtr back to eplusout.mtr
                    mtr_path = os.path.join(run_directory,
                                            file_name_no_ext + '.mtr')
                    eplusoutmtr_path = os.path.join(run_directory,
                                                    'eplusout.mtr')
                    shutil.copy(mtr_path, eplusoutmtr_path)

                    # run the ConvertESOMTR program to create IP versions of the timestep based output files
                    if platform.system() == 'Windows':
                        convertESOMTR_binary = os.path.join(
                            energyplus_root_folder, 'PostProcess',
                            'convertESOMTRpgm', 'convertESOMTR.exe')
                    else:
                        convertESOMTR_binary = os.path.join(
                            energyplus_root_folder, 'PostProcess',
                            'convertESOMTRpgm', 'convertESOMTR')
                    if os.path.exists(convertESOMTR_binary):
                        converttxt_orig_path = os.path.join(
                            energyplus_root_folder, 'PostProcess',
                            'convertESOMTRpgm', 'convert.txt')
                        converttxt_run_path = os.path.join(
                            run_directory, 'convert.txt')
                        shutil.copy(converttxt_orig_path, converttxt_run_path)

                        command_line_args = [convertESOMTR_binary]
                        try:
                            for message in self.execute_for_callback(
                                    command_line_args, run_directory):
                                self.callback(message)
                        except subprocess.CalledProcessError:
                            self.callback("ConvertESOMTR FAILED")
                            return EPLaunchWorkflowResponse1(
                                success=False,
                                message="ConvertESOMTR failed for file: %s!" %
                                full_file_path,
                                column_data={})
                        # copy converted IP version of ESO file to users *.eso file
                        ipeso_path = os.path.join(run_directory, 'ip.eso')
                        if os.path.exists(ipeso_path):
                            shutil.copy(ipeso_path, eso_path)
                            os.replace(ipeso_path, eplusouteso_path)
                        # copy converted IP version of MTR file to users *.mtr file
                        ipmtr_path = os.path.join(run_directory, 'ip.mtr')
                        if os.path.exists(ipmtr_path):
                            shutil.copy(ipmtr_path, mtr_path)
                            os.replace(ipmtr_path, eplusoutmtr_path)
                        os.remove(converttxt_run_path)

                    # run ReadVarsESO to convert the timestep based output files to CSV files
                    if platform.system() == 'Windows':
                        readvarseso_binary = os.path.join(
                            energyplus_root_folder, 'PostProcess',
                            'ReadVarsESO.exe')
                    else:
                        readvarseso_binary = os.path.join(
                            energyplus_root_folder, 'PostProcess',
                            'ReadVarsESO')
                    if os.path.exists(readvarseso_binary):

                        command_line_args = [readvarseso_binary]
                        rvi_path = os.path.join(run_directory,
                                                file_name_no_ext + '.rvi')
                        eplusout_rvi_path = os.path.join(
                            run_directory, 'eplusout.rvi')
                        if os.path.exists(rvi_path):
                            shutil.copy(rvi_path, eplusout_rvi_path)
                            command_line_args.append('eplusout.rvi')
                        else:
                            command_line_args.append(' ')
                        command_line_args.append(
                            'unlimited')  # no number of column limit

                        try:
                            for message in self.execute_for_callback(
                                    command_line_args, run_directory):
                                self.callback(message)
                        except subprocess.CalledProcessError:
                            self.callback("ReadVarsESO FAILED on ESO file")
                            return EPLaunchWorkflowResponse1(
                                success=False,
                                message="ReadVarsESO failed for ESO file: %s!"
                                % full_file_path,
                                column_data={})
                        vari_csv_path = os.path.join(run_directory,
                                                     file_name_no_ext + '.csv')
                        eplusout_csv_path = os.path.join(
                            run_directory, 'eplusout.csv')
                        if os.path.exists(eplusout_csv_path):
                            os.replace(eplusout_csv_path, vari_csv_path)

                        command_line_args = [readvarseso_binary]
                        mvi_path = os.path.join(run_directory,
                                                file_name_no_ext + '.mvi')
                        temp_mvi_path = os.path.join(run_directory, 'temp.mvi')
                        eplusout_mvi_path = os.path.join(
                            run_directory, 'eplusout.mvi')
                        if os.path.exists(mvi_path):
                            shutil.copy(mvi_path, eplusout_mvi_path)
                            command_line_args.append('eplusout.mvi')
                        else:
                            f = open(temp_mvi_path, "w+")
                            f.write('eplusout.mtr')
                            f.write('eplusmtr.csv')
                            f.close()
                            command_line_args.append('temp.mvi')
                            command_line_args.append(
                                'unlimited')  # no number of column limit
                        try:
                            for message in self.execute_for_callback(
                                    command_line_args, run_directory):
                                self.callback(message)
                        except subprocess.CalledProcessError:
                            self.callback("ReadVarsESO FAILED on MTR file")
                            return EPLaunchWorkflowResponse1(
                                success=False,
                                message="ReadVarsESO failed for MTR file: %s!"
                                % full_file_path,
                                column_data={})
                        mtr_csv_path = os.path.join(
                            run_directory, file_name_no_ext + 'Meter.csv')
                        eplusmtr_csv_path = os.path.join(
                            run_directory, 'eplusmtr.csv')
                        if os.path.exists(eplusmtr_csv_path):
                            os.replace(eplusmtr_csv_path, mtr_csv_path)

                        readvars_audit_path = os.path.join(
                            run_directory, 'readvars.audit')
                        rv_audit_path = os.path.join(
                            run_directory, file_name_no_ext + '.rvaudit')
                        if os.path.exists(readvars_audit_path):
                            os.replace(readvars_audit_path, rv_audit_path)

                    # clean up
                    if os.path.exists(temp_mvi_path):
                        os.remove(temp_mvi_path)
                    if os.path.exists(eplusouteso_path):
                        os.remove(eplusouteso_path)
                    if os.path.exists(eplusoutmtr_path):
                        os.remove(eplusoutmtr_path)
                    if os.path.exists(eplusout_rvi_path):
                        os.remove(eplusout_rvi_path)
                    if os.path.exists(eplusout_mvi_path):
                        os.remove(eplusout_mvi_path)
                    audit_out_path = os.path.join(run_directory, 'audit.out')
                    if os.path.exists(audit_out_path):
                        os.remove(audit_out_path)
                    expanded_idf_path = os.path.join(run_directory,
                                                     'expanded.idf')
                    if os.path.exists(expanded_idf_path):
                        os.remove(expanded_idf_path)
                    out_idf_path = os.path.join(run_directory, 'out.idf')
                    if os.path.exists(out_idf_path):
                        os.remove(out_idf_path)

                # run HVAC-Diagram
                if platform.system() == 'Windows':
                    hvac_diagram_binary = os.path.join(energyplus_root_folder,
                                                       'PostProcess',
                                                       'HVAC-Diagram.exe')
                else:
                    hvac_diagram_binary = os.path.join(energyplus_root_folder,
                                                       'PostProcess',
                                                       'HVAC-Diagram')
                if os.path.exists(hvac_diagram_binary):
                    bnd_path = os.path.join(run_directory,
                                            file_name_no_ext + '.bnd')
                    eplusout_bnd_path = os.path.join(run_directory,
                                                     'eplusout.bnd')
                    if os.path.exists(bnd_path):
                        shutil.copy(bnd_path, eplusout_bnd_path)
                        command_line_args = [hvac_diagram_binary]
                    try:
                        for message in self.execute_for_callback(
                                command_line_args, run_directory):
                            self.callback(message)
                    except subprocess.CalledProcessError:
                        self.callback("HVAC-Diagram FAILED on BND file")
                        return EPLaunchWorkflowResponse1(
                            success=False,
                            message="HVAC-Diagram failed for BND file: %s!" %
                            full_file_path,
                            column_data={})
                    svg_path = os.path.join(run_directory,
                                            file_name_no_ext + '.svg')
                    eplusout_svg_path = os.path.join(run_directory,
                                                     'eplusout.svg')
                    if os.path.exists(eplusout_svg_path):
                        os.replace(eplusout_svg_path, svg_path)
                    if os.path.exists(eplusout_bnd_path):
                        os.remove(eplusout_bnd_path)

                # check on .end file and finish up
                end_file_name = "{0}.end".format(file_name_no_ext)
                end_file_path = os.path.join(run_directory, end_file_name)
                success, errors, warnings, runtime = EPlusRunManager.get_end_summary(
                    end_file_path)

                column_data = {
                    ColumnNames.Errors: errors,
                    ColumnNames.Warnings: warnings,
                    ColumnNames.Runtime: runtime,
                    ColumnNames.Version: current_version
                }

                # now leave
                return EPLaunchWorkflowResponse1(
                    success=True,
                    message="Ran EnergyPlus OK for file: %s!" % file_name,
                    column_data=column_data)
            else:
                errors = "wrong version"
                column_data = {
                    ColumnNames.Errors: errors,
                    ColumnNames.Warnings: '',
                    ColumnNames.Runtime: 0,
                    ColumnNames.Version: current_version
                }

                # now leave
                return EPLaunchWorkflowResponse1(
                    success=False,
                    message="Incorrect Version found {}: {}!".format(
                        current_version, file_name),
                    column_data=column_data)
        else:

            errors = "wrong version"
            column_data = {
                ColumnNames.Errors: errors,
                ColumnNames.Warnings: '',
                ColumnNames.Runtime: 0,
                ColumnNames.Version: current_version
            }

            # now leave
            return EPLaunchWorkflowResponse1(
                success=False,
                message="Incorrect Version found {}: {}!".format(
                    current_version, file_name),
                column_data=column_data)
Esempio n. 10
0
    def run_energyplus(self, isIP, run_directory, file_name, args, by_api):

        full_file_path = os.path.join(run_directory, file_name)
        file_name_no_ext, extension = os.path.splitext(file_name)
        # the following is the same when .idf is used

        if 'workflow location' in args:
            energyplus_root_folder, _ = os.path.split(
                args['workflow location'])

            # Run EnergyPlus binary
            if platform.system() == 'Windows':
                energyplus_binary = os.path.join(energyplus_root_folder,
                                                 'energyplus.exe')
            else:
                energyplus_binary = os.path.join(energyplus_root_folder,
                                                 'energyplus')
            if not os.path.exists(energyplus_binary):
                return EPLaunchWorkflowResponse1(
                    success=False,
                    message="EnergyPlus binary not found: {}!".format(
                        energyplus_binary),
                    column_data=[])
        else:
            return EPLaunchWorkflowResponse1(
                success=False,
                message="Workflow location missing: {}!".format(
                    args['workflow location']),
                column_data=[])

        v = Version()
        is_found, current_version, numeric_version = v.check_energyplus_version(
            full_file_path)
        if is_found:
            if by_api:
                # if calling through API, then the arguments don't include the E+ binary
                command_line_args = []
            else:
                command_line_args = [energyplus_binary]

            if extension == '.imf':
                command_line_args += ['--epmacro']

            # should be able to do this once we get pyExpandObjects going
            if extension != '.epJSON':
                command_line_args += ['--expandobjects']

            # TODO: add -d run_directory support to the E+ call here

            # if not isIP:  # if using SI output units just use readvars CLI option
            #     command_line_args += ['--readvars']

            # add some config parameters
            command_line_args += [
                '--output-prefix', file_name_no_ext, '--output-suffix', 'C'
            ]

            # add in simulation control args
            if 'weather' in args and args['weather']:
                command_line_args += ['--weather', args['weather']]
            else:
                command_line_args += ['--design-day']

            # and at the very end, add the file to run
            command_line_args += [full_file_path]

            # run E+
            if by_api:
                # if by API then find the API wrapper relative to this workflow, import it, set up a callback, and run
                eplus_dir = Path(__file__).parent.parent.absolute()
                sys.path.insert(0, str(eplus_dir))
                from pyenergyplus.api import EnergyPlusAPI
                x = lambda msg: self.callback("API Callback: " + str(msg))
                api = EnergyPlusAPI()
                state = api.state_manager.new_state()
                api.runtime.callback_message(state, x)
                api.runtime.set_console_output_status(state, False)
                cur_dir = os.getcwd()
                os.chdir(run_directory)
                eplus_return = api.runtime.run_energyplus(
                    state, command_line_args)
                os.chdir(cur_dir)
                if eplus_return != 0:
                    self.callback("E+ FAILED")
                    return EPLaunchWorkflowResponse1(
                        success=False,
                        message="EnergyPlus failed for file: %s!" %
                        full_file_path,
                        column_data={})
            else:
                # if by CLI then just execute the full command line
                try:
                    for message in self.execute_for_callback(
                            command_line_args, run_directory):
                        self.callback(message)
                except subprocess.CalledProcessError:
                    self.callback("E+ FAILED")
                    return EPLaunchWorkflowResponse1(
                        success=False,
                        message="EnergyPlus failed for file: %s!" %
                        full_file_path,
                        column_data={})

            # if isIP:
            # set up the ESO and MTR output files for either unit conversion or just ReadVarsESO
            # *.eso back to eplusout.eso
            eso_path = os.path.join(run_directory, file_name_no_ext + '.eso')
            eplusouteso_path = os.path.join(run_directory, 'eplusout.eso')
            if os.path.exists(eso_path):
                shutil.copy(eso_path, eplusouteso_path)
            # *.mtr back to eplusout.mtr
            mtr_path = os.path.join(run_directory, file_name_no_ext + '.mtr')
            eplusoutmtr_path = os.path.join(run_directory, 'eplusout.mtr')
            if os.path.exists(mtr_path):
                shutil.copy(mtr_path, eplusoutmtr_path)

            if isIP:
                # run the ConvertESOMTR program to create IP versions of the timestep based output files
                if platform.system() == 'Windows':
                    convertESOMTR_binary = os.path.join(
                        energyplus_root_folder, 'PostProcess',
                        'convertESOMTRpgm', 'convertESOMTR.exe')
                else:
                    convertESOMTR_binary = os.path.join(
                        energyplus_root_folder, 'PostProcess',
                        'convertESOMTRpgm', 'convertESOMTR')
                if os.path.exists(convertESOMTR_binary):
                    converttxt_orig_path = os.path.join(
                        energyplus_root_folder, 'PostProcess',
                        'convertESOMTRpgm', 'convert.txt')
                    converttxt_run_path = os.path.join(run_directory,
                                                       'convert.txt')
                    shutil.copy(converttxt_orig_path, converttxt_run_path)

                    command_line_args = [convertESOMTR_binary]
                    try:
                        for message in self.execute_for_callback(
                                command_line_args, run_directory):
                            self.callback(message)
                    except subprocess.CalledProcessError:
                        self.callback("ConvertESOMTR FAILED")
                        return EPLaunchWorkflowResponse1(
                            success=False,
                            message="ConvertESOMTR failed for file: %s!" %
                            full_file_path,
                            column_data={})
                    # copy converted IP version of ESO file to users *.eso file
                    ipeso_path = os.path.join(run_directory, 'ip.eso')
                    if os.path.exists(ipeso_path):
                        shutil.copy(ipeso_path, eso_path)
                        os.replace(ipeso_path, eplusouteso_path)
                    # copy converted IP version of MTR file to users *.mtr file
                    ipmtr_path = os.path.join(run_directory, 'ip.mtr')
                    if os.path.exists(ipmtr_path):
                        shutil.copy(ipmtr_path, mtr_path)
                        os.replace(ipmtr_path, eplusoutmtr_path)
                    os.remove(converttxt_run_path)

            # run ReadVarsESO to convert the timestep based output files to CSV files
            if platform.system() == 'Windows':
                readvarseso_binary = os.path.join(energyplus_root_folder,
                                                  'PostProcess',
                                                  'ReadVarsESO.exe')
            else:
                readvarseso_binary = os.path.join(energyplus_root_folder,
                                                  'PostProcess', 'ReadVarsESO')
            if os.path.exists(readvarseso_binary):

                command_line_args = [readvarseso_binary]
                rvi_path = os.path.join(run_directory,
                                        file_name_no_ext + '.rvi')
                temp_rvi_path = os.path.join(run_directory, 'temp.rvi')
                eplusout_rvi_path = os.path.join(run_directory, 'eplusout.rvi')
                if os.path.exists(rvi_path):
                    shutil.copy(rvi_path, eplusout_rvi_path)
                    command_line_args.append('eplusout.rvi')
                else:
                    f = open(temp_rvi_path, "w+")
                    f.write('eplusout.eso \n')
                    f.write('eplusout.csv \n')
                    f.close()
                    command_line_args.append('temp.rvi')
                command_line_args.append(
                    'unlimited')  # no number of column limit

                try:
                    for message in self.execute_for_callback(
                            command_line_args, run_directory):
                        self.callback(message)
                except subprocess.CalledProcessError:
                    self.callback("ReadVarsESO FAILED on ESO file")
                    return EPLaunchWorkflowResponse1(
                        success=False,
                        message="ReadVarsESO failed for ESO file: %s!" %
                        full_file_path,
                        column_data={})
                vari_csv_path = os.path.join(run_directory,
                                             file_name_no_ext + '.csv')
                eplusout_csv_path = os.path.join(run_directory, 'eplusout.csv')
                if os.path.exists(eplusout_csv_path):
                    os.replace(eplusout_csv_path, vari_csv_path)

                command_line_args = [readvarseso_binary]
                mvi_path = os.path.join(run_directory,
                                        file_name_no_ext + '.mvi')
                temp_mvi_path = os.path.join(run_directory, 'temp.mvi')
                eplusout_mvi_path = os.path.join(run_directory, 'eplusout.mvi')
                if os.path.exists(mvi_path):
                    shutil.copy(mvi_path, eplusout_mvi_path)
                    command_line_args.append('eplusout.mvi')
                else:
                    f = open(temp_mvi_path, "w+")
                    f.write('eplusout.mtr \n')
                    f.write('eplusmtr.csv \n')
                    f.close()
                    command_line_args.append('temp.mvi')
                command_line_args.append(
                    'unlimited')  # no number of column limit

                try:
                    for message in self.execute_for_callback(
                            command_line_args, run_directory):
                        self.callback(message)
                except subprocess.CalledProcessError:
                    self.callback("ReadVarsESO FAILED on MTR file")
                    return EPLaunchWorkflowResponse1(
                        success=False,
                        message="ReadVarsESO failed for MTR file: %s!" %
                        full_file_path,
                        column_data={})
                mtr_csv_path = os.path.join(run_directory,
                                            file_name_no_ext + 'Meter.csv')
                eplusmtr_csv_path = os.path.join(run_directory, 'eplusmtr.csv')
                if os.path.exists(eplusmtr_csv_path):
                    os.replace(eplusmtr_csv_path, mtr_csv_path)

                readvars_audit_path = os.path.join(run_directory,
                                                   'readvars.audit')
                rv_audit_path = os.path.join(run_directory,
                                             file_name_no_ext + '.rvaudit')
                if os.path.exists(readvars_audit_path):
                    os.replace(readvars_audit_path, rv_audit_path)

                # clean up things inside this IF block
                if os.path.exists(temp_rvi_path):
                    os.remove(temp_rvi_path)
                if os.path.exists(temp_mvi_path):
                    os.remove(temp_mvi_path)
                if os.path.exists(eplusout_rvi_path):
                    os.remove(eplusout_rvi_path)
                if os.path.exists(eplusout_mvi_path):
                    os.remove(eplusout_mvi_path)

            # clean up more things
            if os.path.exists(eplusouteso_path):
                os.remove(eplusouteso_path)
            if os.path.exists(eplusoutmtr_path):
                os.remove(eplusoutmtr_path)
            audit_out_path = os.path.join(run_directory, 'audit.out')
            if os.path.exists(audit_out_path):
                os.remove(audit_out_path)
            expanded_idf_path = os.path.join(run_directory, 'expanded.idf')
            if os.path.exists(expanded_idf_path):
                os.remove(expanded_idf_path)
            out_idf_path = os.path.join(run_directory, 'out.idf')
            if os.path.exists(out_idf_path):
                os.remove(out_idf_path)

            # run HVAC-Diagram
            if platform.system() == 'Windows':
                hvac_diagram_binary = os.path.join(energyplus_root_folder,
                                                   'PostProcess',
                                                   'HVAC-Diagram.exe')
            else:
                hvac_diagram_binary = os.path.join(energyplus_root_folder,
                                                   'PostProcess',
                                                   'HVAC-Diagram')
            if os.path.exists(hvac_diagram_binary):
                bnd_path = os.path.join(run_directory,
                                        file_name_no_ext + '.bnd')
                eplusout_bnd_path = os.path.join(run_directory, 'eplusout.bnd')
                if os.path.exists(bnd_path):
                    shutil.copy(bnd_path, eplusout_bnd_path)
                    command_line_args = [hvac_diagram_binary]
                try:
                    for message in self.execute_for_callback(
                            command_line_args, run_directory):
                        self.callback(message)
                except subprocess.CalledProcessError:
                    self.callback("HVAC-Diagram FAILED on BND file")
                    return EPLaunchWorkflowResponse1(
                        success=False,
                        message="HVAC-Diagram failed for BND file: %s!" %
                        full_file_path,
                        column_data={})
                svg_path = os.path.join(run_directory,
                                        file_name_no_ext + '.svg')
                eplusout_svg_path = os.path.join(run_directory, 'eplusout.svg')
                if os.path.exists(eplusout_svg_path):
                    os.replace(eplusout_svg_path, svg_path)
                if os.path.exists(eplusout_bnd_path):
                    os.remove(eplusout_bnd_path)

            # check on .end file and finish up
            err_file_name = "{0}.err".format(file_name_no_ext)
            err_file_path = os.path.join(run_directory, err_file_name)
            success, errors, warnings, runtime = EPlusRunManager.get_end_summary_from_err(
                err_file_path)

            column_data = {
                ColumnNames.Errors: errors,
                ColumnNames.Warnings: warnings,
                ColumnNames.Runtime: runtime,
                ColumnNames.Version: current_version
            }

            # now leave
            return EPLaunchWorkflowResponse1(
                success=True,
                message="Ran EnergyPlus OK for file: %s!" % file_name,
                column_data=column_data)
        else:

            errors = "wrong version"
            column_data = {
                ColumnNames.Errors: errors,
                ColumnNames.Warnings: '',
                ColumnNames.Runtime: 0,
                ColumnNames.Version: current_version
            }

            # now leave
            return EPLaunchWorkflowResponse1(
                success=False,
                message="Incorrect Version found {}: {}!".format(
                    current_version, file_name),
                column_data=column_data)
Esempio n. 11
0
 def test_line_with_no_comment(self):
     v = Version()
     self.assertEqual(
         v.line_with_no_comment(" object, ! this is a comment"), "object,")
     self.assertEqual(v.line_with_no_comment("! this is a comment"), "")
     self.assertEqual(v.line_with_no_comment(" object, "), "object,")
Esempio n. 12
0
    def run_energyplus(self, isIP, run_directory, file_name, args, by_api):

        full_file_path = os.path.join(run_directory, file_name)
        file_name_no_ext, extension = os.path.splitext(file_name)
        output_directory = os.path.join(run_directory,
                                        f"EPLaunchRun_{file_name_no_ext}")
        if os.path.exists(output_directory):
            shutil.rmtree(output_directory)
        os.makedirs(output_directory)

        def delete_if_exists(file_path):
            if os.path.exists(file_path):
                os.remove(file_path)

        if 'workflow location' in args:
            energyplus_root_folder, _ = os.path.split(
                args['workflow location'])

            # Run EnergyPlus binary
            if platform.system() == 'Windows':
                energyplus_binary = os.path.join(energyplus_root_folder,
                                                 'energyplus.exe')
            else:
                energyplus_binary = os.path.join(energyplus_root_folder,
                                                 'energyplus')
            if not os.path.exists(energyplus_binary):
                return EPLaunchWorkflowResponse1(
                    success=False,
                    message="EnergyPlus binary not found: {}!".format(
                        energyplus_binary),
                    column_data=[])
        else:
            return EPLaunchWorkflowResponse1(
                success=False,
                message="Workflow location missing: {}!".format(
                    args['workflow location']),
                column_data=[])

        v = Version()
        is_found, current_version, numeric_version = v.check_energyplus_version(
            full_file_path)
        if not is_found:
            errors = "wrong version"
            column_data = {
                ColumnNames.Errors: errors,
                ColumnNames.Warnings: '',
                ColumnNames.Runtime: 0,
                ColumnNames.Version: current_version
            }
            return EPLaunchWorkflowResponse1(
                success=False,
                message="Incorrect Version found {}: {}!".format(
                    current_version, file_name),
                column_data=column_data)

        if by_api:
            # if calling through API, then the arguments don't include the E+ binary
            command_line_args = []
        else:
            command_line_args = [energyplus_binary]

        if extension == '.imf':
            command_line_args += ['--epmacro']

        # So...ExpandObjects is weird in E+.  It doesn't like running things in directories and accidentally symlinks
        # things into the current working directory even if you specify an output directory
        # We're just going to run it ourselves.  (Side note it could be a similar problem for EPMacro)
        if extension != '.epJSON':
            if platform.system() == 'Windows':
                expand_objects = os.path.join(energyplus_root_folder,
                                              'ExpandObjects.exe')
            else:
                expand_objects = os.path.join(energyplus_root_folder,
                                              'ExpandObjects')
            if not os.path.exists(expand_objects):
                return EPLaunchWorkflowResponse1(
                    success=False,
                    message="ExpandObjects binary not found: {}!".format(
                        expand_objects),
                    column_data=[])
            # go ahead and copy the target IDF and original IDD into the output_dir/in.idf for running ExpandObjects
            idf_path_in_output_dir = os.path.join(output_directory, 'in.idf')
            shutil.copy(full_file_path, idf_path_in_output_dir)
            idd_path = os.path.join(
                energyplus_root_folder,
                'Energy+.idd')  # yes for now we still need it
            idd_path_in_output_dir = os.path.join(output_directory,
                                                  'Energy+.idd')
            shutil.copy(idd_path, idd_path_in_output_dir)
            # run ExpandObjects
            try:
                for message in self.execute_for_callback([expand_objects],
                                                         output_directory):
                    self.callback(message)
            except subprocess.CalledProcessError:
                self.callback("E+ FAILED")
                return EPLaunchWorkflowResponse1(
                    success=False,
                    message="EnergyPlus failed for file: %s!" % full_file_path,
                    column_data={})
            # regardless of what happened, clean up the temp files
            delete_if_exists(idf_path_in_output_dir)
            delete_if_exists(idd_path_in_output_dir)
            # if expanded.idf does not exist then we don't need to do anything, assume it just didn't have any templates
            # but if it does exist, then this needs to be the IDF that we run, *however* we can't just leave it here
            # as it may reference some other files back in the original directory.  I'm going to go with a new file name
            # in the original directory of "FileName_Expanded.idf"
            expanded_path_in_output_dir = os.path.join(output_directory,
                                                       'expanded.idf')
            if os.path.exists(expanded_path_in_output_dir):
                target_expanded_file_name = os.path.join(
                    run_directory, f"{file_name_no_ext}_Expanded.idf")
                shutil.copy(expanded_path_in_output_dir,
                            target_expanded_file_name)
                full_file_path = target_expanded_file_name

        # Run EnergyPlus in a subdirectory
        command_line_args += ['-d', output_directory]

        # if not isIP:  # if using SI output units just use readvars CLI option
        #     command_line_args += ['--readvars']

        # add some config parameters
        command_line_args += [
            '--output-prefix', file_name_no_ext, '--output-suffix', 'C'
        ]

        # add in simulation control args
        if 'weather' in args and args['weather']:
            command_line_args += ['--weather', args['weather']]
        else:
            command_line_args += ['--design-day']

        # and at the very end, add the file to run
        command_line_args += [full_file_path]

        # run E+
        if by_api:
            # if by API then find the API wrapper relative to this workflow, import it, set up a callback, and run
            eplus_dir = Path(__file__).parent.parent.absolute()
            sys.path.insert(0, str(eplus_dir))
            from pyenergyplus.api import EnergyPlusAPI
            x = lambda msg: self.callback("(E+API) " + msg.decode(
                'utf-8', errors='ignore'))
            # x = lambda msg: print("(E+ API) : " + str(msg))
            api = EnergyPlusAPI()
            state = api.state_manager.new_state()
            api.runtime.callback_message(state, x)
            api.runtime.set_console_output_status(state, False)
            # cur_dir = os.getcwd()
            # os.chdir(output_directory)
            eplus_return = api.runtime.run_energyplus(state, command_line_args)
            # os.chdir(cur_dir)
            if eplus_return != 0:
                self.callback("E+ FAILED")
                return EPLaunchWorkflowResponse1(
                    success=False,
                    message="EnergyPlus failed for file: %s!" % full_file_path,
                    column_data={})
        else:
            # if by CLI then just execute the full command line
            try:
                for message in self.execute_for_callback(
                        command_line_args, output_directory):
                    self.callback(message)
            except subprocess.CalledProcessError:
                self.callback("E+ FAILED")
                return EPLaunchWorkflowResponse1(
                    success=False,
                    message="EnergyPlus failed for file: %s!" % full_file_path,
                    column_data={})

        # if isIP:
        # set up the ESO and MTR output files for either unit conversion or just ReadVarsESO
        # *.eso back to eplusout.eso
        eso_path = os.path.join(output_directory, file_name_no_ext + '.eso')
        eplusouteso_path = os.path.join(output_directory, 'eplusout.eso')
        if os.path.exists(eso_path):
            shutil.copy(eso_path, eplusouteso_path)
        # *.mtr back to eplusout.mtr
        mtr_path = os.path.join(output_directory, file_name_no_ext + '.mtr')
        eplusoutmtr_path = os.path.join(output_directory, 'eplusout.mtr')
        if os.path.exists(mtr_path):
            shutil.copy(mtr_path, eplusoutmtr_path)

        if isIP:
            # run the ConvertESOMTR program to create IP versions of the timestep based output files
            if platform.system() == 'Windows':
                converter = os.path.join(energyplus_root_folder, 'PostProcess',
                                         'convertESOMTRpgm',
                                         'convertESOMTR.exe')
            else:
                converter = os.path.join(energyplus_root_folder, 'PostProcess',
                                         'convertESOMTRpgm', 'convertESOMTR')
            if os.path.exists(converter):
                txt_orig_path = os.path.join(energyplus_root_folder,
                                             'PostProcess', 'convertESOMTRpgm',
                                             'convert.txt')
                txt_run_path = os.path.join(output_directory, 'convert.txt')
                shutil.copy(txt_orig_path, txt_run_path)

                command_line_args = [converter]
                try:
                    for message in self.execute_for_callback(
                            command_line_args, output_directory):
                        self.callback(message)
                except subprocess.CalledProcessError:
                    self.callback("ConvertESOMTR FAILED")
                    return EPLaunchWorkflowResponse1(
                        success=False,
                        message="ConvertESOMTR failed for file: %s!" %
                        full_file_path,
                        column_data={})
                # copy converted IP version of ESO file to users *.eso file
                ipeso_path = os.path.join(output_directory, 'ip.eso')
                if os.path.exists(ipeso_path):
                    shutil.copy(ipeso_path, eso_path)
                    os.replace(ipeso_path, eplusouteso_path)
                # copy converted IP version of MTR file to users *.mtr file
                ipmtr_path = os.path.join(output_directory, 'ip.mtr')
                if os.path.exists(ipmtr_path):
                    shutil.copy(ipmtr_path, mtr_path)
                    os.replace(ipmtr_path, eplusoutmtr_path)
                os.remove(txt_run_path)

        # run ReadVarsESO to convert the timestep based output files to CSV files
        if platform.system() == 'Windows':
            readvarseso_binary = os.path.join(energyplus_root_folder,
                                              'PostProcess', 'ReadVarsESO.exe')
        else:
            readvarseso_binary = os.path.join(energyplus_root_folder,
                                              'PostProcess', 'ReadVarsESO')
        if os.path.exists(readvarseso_binary):

            command_line_args = [readvarseso_binary]
            rvi_path = os.path.join(run_directory, file_name_no_ext + '.rvi')
            temp_rvi_path = os.path.join(output_directory, 'temp.rvi')
            eplusout_rvi_path = os.path.join(output_directory, 'eplusout.rvi')
            if os.path.exists(rvi_path):
                shutil.copy(rvi_path, eplusout_rvi_path)
                command_line_args.append('eplusout.rvi')
            else:
                with open(temp_rvi_path, "w") as f:
                    f.write('eplusout.eso \n')
                    f.write('eplusout.csv \n')
                command_line_args.append('temp.rvi')
            command_line_args.append('unlimited')  # no number of column limit

            try:
                for message in self.execute_for_callback(
                        command_line_args, output_directory):
                    self.callback(message)
            except subprocess.CalledProcessError:
                self.callback("ReadVarsESO FAILED on ESO file")
                return EPLaunchWorkflowResponse1(
                    success=False,
                    message="ReadVarsESO failed for ESO file: %s!" %
                    full_file_path,
                    column_data={})
            vari_csv_path = os.path.join(run_directory, file_name_no_ext +
                                         '.csv')  # TODO: What is this?
            eplusout_csv_path = os.path.join(output_directory, 'eplusout.csv')
            if os.path.exists(eplusout_csv_path):
                os.replace(eplusout_csv_path, vari_csv_path)

            command_line_args = [readvarseso_binary]
            mvi_path = os.path.join(run_directory, file_name_no_ext + '.mvi')
            temp_mvi_path = os.path.join(output_directory, 'temp.mvi')
            eplusout_mvi_path = os.path.join(output_directory, 'eplusout.mvi')
            if os.path.exists(mvi_path):
                shutil.copy(mvi_path, eplusout_mvi_path)
                command_line_args.append('eplusout.mvi')
            else:
                with open(temp_mvi_path, "w+") as f:
                    f.write('eplusout.mtr \n')
                    f.write('eplusmtr.csv \n')
                command_line_args.append('temp.mvi')
            command_line_args.append('unlimited')  # no number of column limit

            try:
                for message in self.execute_for_callback(
                        command_line_args, output_directory):
                    self.callback(message)
            except subprocess.CalledProcessError:
                self.callback("ReadVarsESO FAILED on MTR file")
                return EPLaunchWorkflowResponse1(
                    success=False,
                    message="ReadVarsESO failed for MTR file: %s!" %
                    full_file_path,
                    column_data={})
            mtr_csv_path = os.path.join(output_directory,
                                        file_name_no_ext + 'Meter.csv')
            eplusmtr_csv_path = os.path.join(output_directory, 'eplusmtr.csv')
            if os.path.exists(eplusmtr_csv_path):
                os.replace(eplusmtr_csv_path, mtr_csv_path)

            readvars_audit_path = os.path.join(output_directory,
                                               'readvars.audit')
            rv_audit_path = os.path.join(output_directory,
                                         file_name_no_ext + '.rvaudit')
            if os.path.exists(readvars_audit_path):
                os.replace(readvars_audit_path, rv_audit_path)

            # clean up things inside this IF block
            delete_if_exists(temp_rvi_path)
            delete_if_exists(temp_mvi_path)
            delete_if_exists(eplusout_rvi_path)
            delete_if_exists(eplusout_mvi_path)

        # clean up more things
        delete_if_exists(eplusouteso_path)
        delete_if_exists(eplusoutmtr_path)
        audit_out_path = os.path.join(output_directory, 'audit.out')
        delete_if_exists(audit_out_path)
        expanded_idf_path = os.path.join(output_directory, 'expanded.idf')
        delete_if_exists(expanded_idf_path)
        out_idf_path = os.path.join(output_directory, 'out.idf')
        delete_if_exists(out_idf_path)

        # run HVAC-Diagram
        if platform.system() == 'Windows':
            hvac_diagram_binary = os.path.join(energyplus_root_folder,
                                               'PostProcess',
                                               'HVAC-Diagram.exe')
        else:
            hvac_diagram_binary = os.path.join(energyplus_root_folder,
                                               'PostProcess', 'HVAC-Diagram')
        if os.path.exists(hvac_diagram_binary):
            bnd_path = os.path.join(output_directory,
                                    file_name_no_ext + '.bnd')
            eplusout_bnd_path = os.path.join(output_directory, 'eplusout.bnd')
            if os.path.exists(bnd_path):
                shutil.copy(bnd_path, eplusout_bnd_path)
                command_line_args = [hvac_diagram_binary]
            try:
                for message in self.execute_for_callback(
                        command_line_args, output_directory):
                    self.callback(message)
            except subprocess.CalledProcessError:
                self.callback("HVAC-Diagram FAILED on BND file")
                return EPLaunchWorkflowResponse1(
                    success=False,
                    message="HVAC-Diagram failed for BND file: %s!" %
                    full_file_path,
                    column_data={})
            svg_path = os.path.join(output_directory,
                                    file_name_no_ext + '.svg')
            eplusout_svg_path = os.path.join(output_directory, 'eplusout.svg')
            if os.path.exists(eplusout_svg_path):
                os.replace(eplusout_svg_path, svg_path)
            if os.path.exists(eplusout_bnd_path):
                os.remove(eplusout_bnd_path)

        # Now the last thing to do is to collect all the relevant output files for this simulation and put them back
        # in the original run directory.  This is because EP Launch will expect to find them right there.
        file_names_to_copy = [
            f for f in os.listdir(output_directory)
            if f.startswith(file_name_no_ext)
        ]
        for f in file_names_to_copy:
            shutil.copy(os.path.join(output_directory, f),
                        os.path.join(run_directory, f))

        # check on .end file and finish up
        err_file_name = "{0}.err".format(file_name_no_ext)
        err_file_path = os.path.join(output_directory, err_file_name)
        success, errors, warnings, runtime = EPlusRunManager.get_end_summary_from_err(
            err_file_path)

        column_data = {
            ColumnNames.Errors: errors,
            ColumnNames.Warnings: warnings,
            ColumnNames.Runtime: runtime,
            ColumnNames.Version: current_version
        }

        # now leave
        return EPLaunchWorkflowResponse1(
            success=True,
            message="Ran EnergyPlus OK for file: %s!" % file_name,
            column_data=column_data)