I am using a borrowed Python script which has two function definitions (get_data
and get_data_multiple
) within a class defined outside the main function
. The main
function calls get_data_multiple
which in turn calls get_data
. In short, my code fetches Pi Data using win32com module (from win32com.client.dynamic import Dispatch
).
The goal is to run the main
function every hour. I am doing this by using a while True:
loop and the time.time()
from time
module. In some rare cases, I find that call to get_data
takes too long to send a return value to get_data_multiple
. In those cases, my code crashes as by the time, the return value to main
arrives, its already past an hour.
I want to add a logic, where I terminate the call to get_data
and force it return a default value if the time spend within it has crossed beyond a certain time. I know that the function spends too much time in the line pi_values = tag.Data.InterpolatedValues2(t_start, t_end, t_interval, asynchStatus=None)
. How can I do this, when I don't have a return value available from function ?
def get_data(self, tag_name, t_start, t_end, t_interval):
"""Retrieve interpolated data from the PI-server
Args:
tag_name (str): PI tag name
t_start (str): PI time format (ex. '*-72h')
t_end (str): PI time format (ex. '*')
t_interval (str): PI time format (ex. '1h')
Returns:
pandas dataframe: index=datetime, col_1=interpolated values
"""
logger.info('get_data for tag `%s`' % tag_name)
tag = self.pi_srv.PIPoints(tag_name)
pi_values = tag.Data.InterpolatedValues2(t_start, t_end, t_interval, asynchStatus=None)
return (self.pivalues_to_df(pi_values, tag_name))
def get_data_multiple(self, tags, t_start, t_end, t_interval):
"""Retrieve interpolated data from the PI-server for multiple tags
Args:
tags (list): List of PI tag names
t_start (str): PI time format (ex. '*-72h')
t_end (str): PI time format (ex. '*')
t_interval (str): PI time format (ex. '1h')
Returns:
pandas dataframe: index=datetime, cols=interpolated values
"""
logger.info('getting data for %s tags' % len(tags))
list_of_values = []
pBar = ProgressBar()
for i,tag in enumerate(tags):
print(i)
df = None
while df is None:
try:
df = self.get_data(tag, t_start, t_end, t_interval)
except:
print('Connection Timeout. Retring.....')
pass
# drop duplicated indices -> result of summer-to-winter time
# transition. Not doing this results in the subsequent join() to
# spiral out of control
df = df[~df.index.duplicated()]
list_of_values.append(df)
df_values = pd.DataFrame().join(list_of_values, how='outer')
#print(df_values.columns)
return df_values