Calling EES from Python
Python can call EES (version12.131 or newer) to:
em_Solve: Solve the program in an open EES application
em_SolveTable: Solve a specified Parametric table in an open EES application
em_RunMacroTab: Run a macro from a specified tab in the Macro window in an open EES application
em_RunMacroName: Run a external EES macro file (.emf), starting EES if needed.
In all of these cases, input information must be provided to EES from Python. This is done by Python writing text files that EES can import. Then EES exports calculated results that Python imports.
The communication between Python and EES relies on functions FindWindow and SendMessage in the Windows operating system and is quite fast. EES writes a file named EESCallfromApp.log in the EES directory that records all of the communications and error messages.
A simple example is used here to illustrate all of the options in the Python-EES communication. Python writes the name of a refrigerant (R$) and number of data points (N) in file Input.dat along with arrays of N temperatures and pressures in files T.dat and P.dat. When called from Python, EES reads these files with its $Import directive or Import macro command. EES uses the temperature and pressures to calculate an array of specific volumes, which are exported using the $Export directive or Export macro command to file v.dat. Python waits for EES to complete the calculations and then imports file v.dat. It should be understood that Python and EES can be modified to exchange any desired information in any number of files .
The EES program used in the example for the em_Solve command is:
The EES program and Parametric table used in the example for the em_SolveTable command is:
The EES program and Macro used in the example for the em_RunMacroTab command is:
The Macro used in the example for the em_RunMacroMacro command is:
The Python code follows. Comments in green font indicate the purpose of each function and explain how to use the program. Note that the exporttoEES and importEESFile functions will need be modified for other problems.
_________________________________________________________________________________________________________________
import win32api
import win32con
import win32gui
import time
import sys
import numpy as np
import os
import subprocess
em_DeleteLog=0
em_StopLog=1
em_StartLog=2
em_Solve=10
em_SolveTable=11
em_RunMacroTab=20
em_RunMacroName=30
em_TerminateEES=100
wm_RunEES=32777
notUsed=0
def exporttoEES():
#The user needs to write the files here that EES will import.
Refrig='R134a'
N=12
T=[10,20,30,40,50,60,70,80,90,100,110,120]
P=[20,20,20,20,20,20,20,20,20,20,20,20]
with open('c:/temp/Python_Example/Input.dat',"w") as file:
file.write(str(Refrig)+"\n")
file.write(str(N)+"\n")
np.savetxt('c:/temp/Python_Example/T.dat',T)
np.savetxt('c:/temp/Python_Example/P.dat',P)
return
def importEESFile(filename):
#The user needs to write this file to import the results exported by EES
if (not os.path.exists(filename)):
print(f"Output file "+filename+" was not found")
else:
v=np.loadtxt(filename) #load the array of specific volumes for this example
print(v) #print the results to verify that they were correctly imported from EES in this example
return
# Find an running instance of EES and return the window handle
def find_window():
EESClass="TEES_D"
try:
hwnd = win32gui.FindWindow(EESClass, None)
return hwnd
except win32api.error:
return None
def StopLog_EES(hwnd):
#Send EES a message to stop logging to EESCallFromApp.log and delete the log file
win32gui.SendMessage(hwnd,wm_RunEES,em_StopLog,notused)
return
def StartLog_EES(hwnd):
# Send EES a message to start logging to EESCallFromApp.log in the EES folder; The log file will be created if it does not exist.
win32gui.SendMessage(hwnd,wm_RunEES,em_StartLog,notused)
return
def Solve_EES(hwnd):
#Solve a previously-opened EES program. Use $Import and $Export in EES to read/write text files
errcode = win32gui.SendMessage(hwnd,wm_RunEES,em_Solve,notUsed)
return errcode
def Solve_EESTable(hwnd,TabNo):
#Solve a previously-opened EES program with one or more Parametric tables. Solve table TabNo
#The first table is TabNo=1. if TabNo<0, EES will show the Parametric Table dialog where the row range can be entered
errcode = win32gui.SendMessage(hwnd,wm_RunEES,em_SolveTable,TabNo)
return errcode
def solve_EESMacroTab(hwnd,TabNo):
#Solve macro file TabNo in the macro window of an open EES program.
errcode = win32gui.SendMessage(hwnd,wm_RunEES,em_RunMacroTab,TabNo)
return errcode
def solve_EESMacroName(hwnd,TabNo):
#Solve the macro file with file name provided in EESDirectory/EESMacroName.txt.
errcode = win32gui.SendMessage(hwnd,wm_RunEES,em_RunMacroName,notUsed)
return errcode
def wait_for_file(file_path, timeout=60, check_interval=1):
#Waits for a file to exist at the given path: Needed only when starting EES with the em_RunMacroName command.
start_time = time.time()
while not os.path.exists(file_path):
if time.time() - start_time > timeout:
# print(f"Timeout: File '{file_path}' did not appear within {timeout} seconds.")
return False
time.sleep(check_interval)
return True
if __name__ == "__main__":
exporttoEES #write text files that EES or an EES macro will import
vfile='c:/temp/Python_Example/v.dat' #name of file written by EES that will be imported
EESFolder='C:/EES32' #folder containing the EES application
logfile=EESFolder+'/EESCallFromApp.log' #name of the log file
try:
os.remove(vfile) #delete existing output file
except:
x=1 #do nothing
try:
os.remove(logfile) #delete existing log file
except:
x=1 #do nothing
hwnd = find_window() #find the handle of the open EES application
while True:
EESCode=input("Enter: em_DeleteLog em_StopLog, em_StartLog, em_Solve, em_SolveTable, EM_RunMacroTab, EM_RunMacroName or Quit: ")
match EESCode:
case 'em_DeleteLog':
if (os.path.exists(logfile)):
os.remove(logFile)
print(f"File "+logfile+" has been deleted")
case 'em_StopLog':
print(f"EM_StopLog: Stop logging to "+logfile)
if hwnd:
StopLog_EES(hwnd)
case 'em_StartLog':
print(f"EM:StartLog: Clear log and start logging to "+logfile)
if hwnd:
StartLog_EES(hwnd)
case 'em_Solve':
if hwnd:
print(f"Solving the currently open EES file using the Solve command")
errcode=Solve_EES(hwnd)
if errcode==0:
importEESFile(vfile)
else:
print(f"Error #"+str(errcode)+". The error message is shown in file EESCallFromApp.log in the EES directory.")
else:
print(f"Start EES and open the EES file that is to be solved")
case 'em_SolveTable':
TabNo=1 #the tab number of the Parametric Table that is to be solved. The first tab is 1
print(f"Solving Parametric table "+str(TabNo)+" in the currently open EES file")
#TabNo=-TabNo #if TabNo<0, show the Parametric Table dialog
if hwnd:
errcode=Solve_EESTable(hwnd,TabNo)
if errcode==0:
importEESFile(vfile)
else:
print(f"Error #"+str(errcode)+". The error message is shown in file EESCallFromApp.log in the EES directory.")
else:
print(f"Start EES and open the EES file that has the Parametric table that is to be solved")
case 'em_RunMacroTab':
TabNo=1 #the tab number in the EES Macro window that will be run. The first tab is 1
if hwnd:
errcode=solve_EESMacroTab(hwnd,TabNo)
if errcode==0:
importEESFile(vfile)
else:
print(f"Error #"+str(errcode)+". The error message is shown in file EESCallFromApp.log in the EES directory.")
else:
print(f"Start EES and open the EES file that has the macro file that is to be solved")
case 'em_RunMacroName':
theMacroName=input("Enter the full file name of the macro that you want to solve: ")
EESMacroFileName=EESFolder+'/EESMacroName.txt'
with open(EESMacroFileName,"w") as file:
file.write(str(theMacroName))
if hwnd:
errcode=solve_EESMacroName(hwnd,theMacroName)
if errcode==0:
importEESFile(vfile)
else:
print(f"Error #"+str(errcode)+". The error message is shown in file EESCallFromApp.log in the EES directory.")
else:
print(f"Starting EES")
EESApp=subprocess.Popen(EESFolder+'/EES.exe '+theMacroName)
if not wait_for_file(vfile, timeout=10):
print(f"File "+vfile+" was not found")
else:
importEESFile(vfile)
case 'em_TerminateEES': #closes the open EES application
subprocess.call(["taskkill", "/IM", "EES.exe", "/F"])
case 'Quit':
print(f"Quitting EES calls")
break
case _:
print (f"Input not recognized - try again")
_________________________________________________________________________________________________________________
To continue with this example, start EES and enter the small program shown in the first figure for the em_Solve command. Save the file in C:\temp\Python_Example\em_Solve.ees. Next copy the Python program listing above into Python and run it. Python will prompt you for a command. Enter em_Solve. You should then see the calculated specific volumes as shown below. Enter Quit to exit the Python program.
Enter: em_DeleteLog em_StopLog, em_StartLog, em_Solve, em_SolveTable, EM_RunMacroTab, EM_RunMacroName or Quit: em_Solve
Solving the currently open EES file using the Solve command
[1.1480915 1.18933484 1.23051515 1.27164302 1.31272684 1.35377334
1.394788 1.43577531 1.476739 1.51768217 1.55860743 1.59951699]
Enter: em_DeleteLog em_StopLog, em_StartLog, em_Solve, em_SolveTable, EM_RunMacroTab, EM_RunMacroName or Quit: Quit
Quitting EES calls
See also: Call Python from EES