Revision history  [back]

Using Popen with multiple args and piping the output to display the actual error message

Since subprocess.check_call shouldn't have stdout and stderr pipes, you should use Popeninstead.

See the subprocess documentation especially check_call and for Popen.

import subprocess

eplus_path = '/Applications/EnergyPlus-8-6-0/energyplus'
eplus_file = '5ZoneAirCooled.idf'
weather_file = 'USA_CO_Golden-NREL.724666_TMY3.epw'

df = subprocess.Popen([eplus_path, "-w", weather_file, eplus_file], stdout=subprocess.PIPE)        
output, err = df.communicate()
print(output.decode('utf-8'))
if not err is None:
    print(err.decode('utf-8'))

In a case where it goes well, I'll see something that starts with:

EnergyPlus Starting
EnergyPlus, Version 8.6.0-198c6a3cff, YMD=2017.01.17 23:46
Processing Data Dictionary
Processing Input File
... etc

In a case where for example I don't have the right idf file in my folder:

ERROR: Could not find input data file: /Users/julien/Software/RunningEPlusFromPython/2ZoneAirCooled.idf.
Type 'energyplus --help' for usage.

Shlex as helper to parse a command

Note that the subprocess calls expects a list of arguments. Using shlex to decompose a command line (that you can try directly in a terminal/cmd prompt) can be useful:

In [1]:
import shlex
command_line = '{eplus_path} -w {weather_file} {eplus_file}'.format(eplus_path= eplus_path, weather_file=weather_file, eplus_file=eplus_file)
print(command_line)

Out [1]:
/Applications/EnergyPlus-8-6-0/energyplus -w USA_CO_Golden-NREL.724666_TMY3.epw 5ZoneAirCooled.idf

In [2]: shlex.split(command_line)
Out[2]: ['/Applications/EnergyPlus-8-6-0/energyplus',
         '-w',
         'USA_CO_Golden-NREL.724666_TMY3.epw',
         '5ZoneAirCooled.idf']

Seeing the EnergyPlus simulation output in real time as the simulation runs

If you need to do this, here's how:

import subprocess
# If python 2.7: `from __future__ import print_function`

popen = subprocess.Popen([eplus_path, "-w", weather_file, eplus_file],
                         stdout=subprocess.PIPE, universal_newlines=True)

# Might need to use `#for stdout_line in iter(popen.stdout.readline, ""):` instead in python 2.7
for stdout_line in popen.stdout:
    print(stdout_line)

popen.stdout.close()
return_code = popen.wait()

if return_code:
    raise subprocess.CalledProcessError(return_code, popen.args)

Side note

From the docs on the energyplus CLI (command line interface), if you don't supply -w weather_file_path it searches for in.epw in the current directory (where it's called from). So a quick fix would be to make sure that your weather file is there an named in.epw. Just saying.

Using Popen with multiple args and piping the output to display the actual error message

Since subprocess.check_call shouldn't have stdout and stderr pipes, you should use Popeninstead.

See the subprocess documentation especially check_call and for Popen.

import subprocess

eplus_path = '/Applications/EnergyPlus-8-6-0/energyplus'
eplus_file = '5ZoneAirCooled.idf'
weather_file = 'USA_CO_Golden-NREL.724666_TMY3.epw'

df = subprocess.Popen([eplus_path, "-w", weather_file, eplus_file], stdout=subprocess.PIPE)        
output, err = df.communicate()
print(output.decode('utf-8'))
if not err is None:
    print(err.decode('utf-8'))

In a case where it goes well, I'll see something that starts with:

EnergyPlus Starting
EnergyPlus, Version 8.6.0-198c6a3cff, YMD=2017.01.17 23:46
Processing Data Dictionary
Processing Input File
... etc

In a case where for example I don't have the right idf file in my folder:

ERROR: Could not find input data file: /Users/julien/Software/RunningEPlusFromPython/2ZoneAirCooled.idf.
Type 'energyplus --help' for usage.

Shlex as helper to parse a command

Note that the subprocess calls expects a list of arguments. Using shlex to decompose a command line (that you can try directly in a terminal/cmd prompt) can be useful:

In [1]:
import shlex
command_line = '{eplus_path} -w {weather_file} {eplus_file}'.format(eplus_path= eplus_path, weather_file=weather_file, eplus_file=eplus_file)
print(command_line)

Out [1]:
/Applications/EnergyPlus-8-6-0/energyplus -w USA_CO_Golden-NREL.724666_TMY3.epw 5ZoneAirCooled.idf

In [2]: shlex.split(command_line)
Out[2]: ['/Applications/EnergyPlus-8-6-0/energyplus',
         '-w',
         'USA_CO_Golden-NREL.724666_TMY3.epw',
         '5ZoneAirCooled.idf']

Seeing the EnergyPlus simulation output in real time as the simulation runs

If you need to do this, here's how:

import subprocess
# If python 2.7: `from __future__ import print_function`

popen = subprocess.Popen([eplus_path, "-w", weather_file, eplus_file],
                         stdout=subprocess.PIPE, universal_newlines=True)

# Might need to use `#for stdout_line in iter(popen.stdout.readline, ""):` instead in python 2.7
for stdout_line in popen.stdout:
    print(stdout_line)

popen.stdout.close()
return_code = popen.wait()

if return_code:
    raise subprocess.CalledProcessError(return_code, popen.args)

Side note

From the docs on the energyplus CLI (command line interface), if you don't supply -w weather_file_path it searches for in.epw in the current directory (where it's called from). So a quick fix would be to make sure that your weather file is there an named in.epw. Just saying.

Using Popen with multiple args and piping the output to display the actual error message

Since subprocess.check_call shouldn't have stdout and stderr pipes, you should use Popeninstead.

See the subprocess documentation especially check_call and for Popen.

import subprocess

eplus_path = '/Applications/EnergyPlus-8-6-0/energyplus'
eplus_file = '5ZoneAirCooled.idf'
weather_file = 'USA_CO_Golden-NREL.724666_TMY3.epw'

df = subprocess.Popen([eplus_path, "-w", weather_file, eplus_file], stdout=subprocess.PIPE)        
output, err = df.communicate()
print(output.decode('utf-8'))
if not err is None:
    print(err.decode('utf-8'))

In a case where it goes well, I'll see something that starts with:

EnergyPlus Starting
EnergyPlus, Version 8.6.0-198c6a3cff, YMD=2017.01.17 23:46
Processing Data Dictionary
Processing Input File
... etc

In a case where for example I don't have the right idf file in my folder:

ERROR: Could not find input data file: /Users/julien/Software/RunningEPlusFromPython/2ZoneAirCooled.idf.
Type 'energyplus --help' for usage.

Shlex as helper to parse a command

Note that the subprocess calls expects a list of arguments. Using shlex to decompose a command line (that you can try directly in a terminal/cmd prompt) can be useful:

In [1]:
import shlex
command_line = '{eplus_path} -w {weather_file} {eplus_file}'.format(eplus_path= eplus_path, weather_file=weather_file, eplus_file=eplus_file)
print(command_line)

Out [1]:
/Applications/EnergyPlus-8-6-0/energyplus -w USA_CO_Golden-NREL.724666_TMY3.epw 5ZoneAirCooled.idf

In [2]: shlex.split(command_line)
Out[2]: ['/Applications/EnergyPlus-8-6-0/energyplus',
         '-w',
         'USA_CO_Golden-NREL.724666_TMY3.epw',
         '5ZoneAirCooled.idf']

Seeing the EnergyPlus simulation output in real time as the simulation runs

If you need to do this, here's how:

import subprocess
# If python 2.7: `from __future__ import print_function`

popen = subprocess.Popen([eplus_path, "-w", weather_file, eplus_file],
                         stdout=subprocess.PIPE, universal_newlines=True)

# Might need to use `#for stdout_line in iter(popen.stdout.readline, ""):` instead in python 2.7
for stdout_line in popen.stdout:
    print(stdout_line)

popen.stdout.close()
return_code = popen.wait()

if return_code:
    raise subprocess.CalledProcessError(return_code, popen.args)

Since subprocess.check_call shouldn't have stdout and stderr pipes, you should use Popeninstead.

See the subprocess documentation especially check_call and for Popen.

import subprocess

eplus_path = '/Applications/EnergyPlus-8-6-0/energyplus'
eplus_file = '5ZoneAirCooled.idf'
weather_file = 'USA_CO_Golden-NREL.724666_TMY3.epw'

df = subprocess.Popen([eplus_path, "-w", weather_file, eplus_file], stdout=subprocess.PIPE)        
output, err = df.communicate()
print(output.decode('utf-8'))
if not err is None:
    print(err.decode('utf-8'))

In a case where it goes well, I'll see something that starts with:

EnergyPlus Starting
EnergyPlus, Version 8.6.0-198c6a3cff, YMD=2017.01.17 23:46
Processing Data Dictionary
Processing Input File
... etc

In a case where for example I don't have the right idf file in my folder:

ERROR: Could not find input data file: /Users/julien/Software/RunningEPlusFromPython/2ZoneAirCooled.idf.
Type 'energyplus --help' for usage.

Note that the subprocess calls expects a list of arguments. Using shlex to decompose a command line (that you can try directly in a terminal/cmd prompt) can be useful:

In [1]:
import shlex
command_line = '{eplus_path} -w {weather_file} {eplus_file}'.format(eplus_path= eplus_path, weather_file=weather_file, eplus_file=eplus_file)
print(command_line)

Out [1]:
/Applications/EnergyPlus-8-6-0/energyplus -w USA_CO_Golden-NREL.724666_TMY3.epw 5ZoneAirCooled.idf

In [2]: shlex.split(command_line)
Out[2]: ['/Applications/EnergyPlus-8-6-0/energyplus',
         '-w',
         'USA_CO_Golden-NREL.724666_TMY3.epw',
         '5ZoneAirCooled.idf']

Since subprocess.check_call shouldn't have stdout and stderr pipes, you should use Popeninstead.

See the instead (see subprocess documentation especially check_calldocumentation and for Popen.)

import subprocess

eplus_path = '/Applications/EnergyPlus-8-6-0/energyplus'
eplus_file = '5ZoneAirCooled.idf'
weather_file = 'USA_CO_Golden-NREL.724666_TMY3.epw'

df = subprocess.Popen([eplus_path, "-w", weather_file, eplus_file], stdout=subprocess.PIPE)        
output, err = df.communicate()
print(output.decode('utf-8'))
if not err is None:
    print(err.decode('utf-8'))

In a case where it goes well, I'll see something that starts with:

EnergyPlus Starting
EnergyPlus, Version 8.6.0-198c6a3cff, YMD=2017.01.17 23:46
Processing Data Dictionary
Processing Input File
... etc

In a case where for example I don't have the right idf file in my folder:

ERROR: Could not find input data file: /Users/julien/Software/RunningEPlusFromPython/2ZoneAirCooled.idf.
Type 'energyplus --help' for usage.

Since subprocess.check_call shouldn't have stdout and stderr pipes, piped, you should use Popeninstead (see subprocess documentation)instead.

import subprocess subprocess

eplus_path = '/Applications/EnergyPlus-8-6-0/energyplus' eplus_file = '5ZoneAirCooled.idf' weather_file = 'USA_CO_Golden-NREL.724666_TMY3.epw' 'USA_CO_Golden-NREL.724666_TMY3.epw'

df = subprocess.Popen([eplus_path, "-w", weather_file, eplus_file], stdout=subprocess.PIPE)
output, err = df.communicate() print(output.decode('utf-8')) if not err is None: print(err.decode('utf-8'))

In a case where it goes well, I'll see something that starts with:print(err.decode('utf-8'))

EnergyPlus Starting
EnergyPlus, Version 8.6.0-198c6a3cff, YMD=2017.01.17 23:46
Processing Data Dictionary
Processing Input File
... etc

In a case where for example I don't have the right idf file in my folder:

ERROR: Could not find input data file: /Users/julien/Software/RunningEPlusFromPython/2ZoneAirCooled.idf.
Type 'energyplus --help' for usage.