time experiment plus terminal addons

This commit is contained in:
shrlnm 2024-02-04 20:32:53 +03:00
parent 453982d474
commit c9b0a03051
5 changed files with 79 additions and 68 deletions

View File

@ -176,7 +176,7 @@ class DDT_MON():
self.sendAllow.clear() self.sendAllow.clear()
return return
ct = time.time() ct = mod_elm.pyren_time()
for f in buf.split('\n'): for f in buf.split('\n'):
f = f.strip() f = f.strip()
@ -433,7 +433,7 @@ def main():
kb = KBHit() kb = KBHit()
lt = ct = time.time() lt = ct = mod_elm.pyren_time()
show_loc = threading.Event() show_loc = threading.Event()
@ -467,7 +467,7 @@ def main():
#mon.framefilter = mon.framefilter + '<' + str(ord(c)) + '>' #mon.framefilter = mon.framefilter + '<' + str(ord(c)) + '>'
time.sleep( 0.03 ) time.sleep( 0.03 )
ct = time.time() ct = mod_elm.pyren_time()
if (ct-lt)>0.1: if (ct-lt)>0.1:
lt = ct lt = ct
show_loc.set() show_loc.set()

View File

@ -32,6 +32,7 @@ except ImportError:
import mod_globals import mod_globals
from mod_elm import AllowedList from mod_elm import AllowedList
from mod_elm import dnat from mod_elm import dnat
from mod_elm import pyren_time
import xml.etree.ElementTree as et import xml.etree.ElementTree as et
@ -436,13 +437,13 @@ class DDTScreen (tk.Frame):
self.decu.putToRotary(req) self.decu.putToRotary(req)
tb = time.time () tb = pyren_time()
# read results # read results
while not self.decu.rotaryResultsQueue.empty(): while not self.decu.rotaryResultsQueue.empty():
# no longer then 100ms # no longer then 100ms
if time.time()-tb > 0.1: if pyren_time()-tb > 0.1:
break break
# get from input queue # get from input queue
@ -451,7 +452,7 @@ class DDTScreen (tk.Frame):
self.updateScreenValues(req,rsp) self.updateScreenValues(req,rsp)
# re-launch update in x milliseconds # re-launch update in x milliseconds
tb = time.time () tb = pyren_time()
self.jid = self.root.after (self.updatePeriod, self.updateScreen) self.jid = self.root.after (self.updatePeriod, self.updateScreen)
self.tl = tb self.tl = tb
@ -1430,7 +1431,7 @@ class DDTScreen (tk.Frame):
return return
#debug #debug
#deb_time1 = time.time() #deb_time1 = pyren_time()
#print( "#"*50 ) #print( "#"*50 )
# stop ratary. Do not read ELM # stop ratary. Do not read ELM
@ -1440,7 +1441,7 @@ class DDTScreen (tk.Frame):
restart = True restart = True
#debug #debug
#print( f"DEBUG POINT1: {time.time()-deb_time1}") #print( f"DEBUG POINT1: {pyren_time()-deb_time1}")
ns = {'ns0': 'http://www-diag.renault.com/2002/ECU', ns = {'ns0': 'http://www-diag.renault.com/2002/ECU',
'ns1': 'http://www-diag.renault.com/2002/screens'} 'ns1': 'http://www-diag.renault.com/2002/screens'}

View File

@ -16,6 +16,7 @@ from mod_elm import ELM
from mod_elm import snat from mod_elm import snat
from mod_elm import dnat from mod_elm import dnat
from mod_elm import AllowedList from mod_elm import AllowedList
from mod_elm import pyren_time
if mod_globals.os != 'android': if mod_globals.os != 'android':
from mod_ddt import DDT from mod_ddt import DDT
@ -428,7 +429,7 @@ class ECU:
if mod_globals.opt_usrkey: csvline += ";User events" if mod_globals.opt_usrkey: csvline += ";User events"
csvline = pyren_encode(csvline) csvline = pyren_encode(csvline)
if nparams: if nparams:
csv_start_time = int(round(time.time() * 1000)) csv_start_time = int(round(pyren_time() * 1000))
csv_filename = datetime.now().strftime("%Y_%m_%d_%H_%M_%S") csv_filename = datetime.now().strftime("%Y_%m_%d_%H_%M_%S")
#here the problem with russian letters. and very long name #here the problem with russian letters. and very long name
csv_filename = csv_filename+'_'+self.ecudata['ecuname']+'_'+path csv_filename = csv_filename+'_'+self.ecudata['ecuname']+'_'+path
@ -453,7 +454,7 @@ class ECU:
kb = KBHit() kb = KBHit()
tb = time.time() #time of begining tb = pyren_time() #time of begining
if len(datarefs)==0 and 'DE' not in path: return if len(datarefs)==0 and 'DE' not in path: return
self.elm.clear_cache() self.elm.clear_cache()
@ -480,7 +481,7 @@ class ECU:
while(True): while(True):
strlst = [] strlst = []
datarefsRequestTime = int(round(time.time() * 1000)) datarefsRequestTime = int(round(pyren_time() * 1000))
if mod_globals.opt_csv_human and csvf!=0: if mod_globals.opt_csv_human and csvf!=0:
csvline = csvline + "\n" csvline = csvline + "\n"
@ -489,7 +490,7 @@ class ECU:
csvline = csvline.replace(';',mod_globals.opt_csv_sep) csvline = csvline.replace(';',mod_globals.opt_csv_sep)
csvf.write(csvline) csvf.write(csvline)
csvf.flush() csvf.flush()
time_diff = int(round(time.time() * 1000))-csv_start_time time_diff = int(round(pyren_time() * 1000))-csv_start_time
time_sec = str(time_diff//1000) time_sec = str(time_diff//1000)
time_ms = str((time_diff)%1000) time_ms = str((time_diff)%1000)
csvline = time_sec.zfill(2)+mod_globals.opt_csv_dec+time_ms.zfill(3) csvline = time_sec.zfill(2)+mod_globals.opt_csv_dec+time_ms.zfill(3)
@ -575,7 +576,7 @@ class ECU:
if mod_globals.opt_demo: if mod_globals.opt_demo:
self.minimumrefreshrate = 1 self.minimumrefreshrate = 1
tc = time.time() tc = pyren_time()
if ((tc - tb) < self.minimumrefreshrate): if ((tc - tb) < self.minimumrefreshrate):
time.sleep(tb + self.minimumrefreshrate - tc) time.sleep(tb + self.minimumrefreshrate - tc)
tb = tc tb = tc

View File

@ -130,6 +130,12 @@ negrsp = {"10": "NR: General Reject",
def log_tmstr(): def log_tmstr():
return datetime.now ().strftime ("%x %H:%M:%S.%f")[:21].ljust(21,'0') return datetime.now ().strftime ("%x %H:%M:%S.%f")[:21].ljust(21,'0')
def pyren_time():
if (sys.version_info[0]*100 + sys.version_info[1]) > 306:
return time.perf_counter_ns() / 1e9
else:
return time.time()
# noinspection PyBroadException,PyUnresolvedReferences # noinspection PyBroadException,PyUnresolvedReferences
class Port: class Port:
"""This is a serial port or a TCP-connection """This is a serial port or a TCP-connection
@ -267,7 +273,7 @@ class Port:
try: try:
if not self.rwLock and time.time () > self.lastReadTime + self.atKeepAlive: if not self.rwLock and pyren_time() > self.lastReadTime + self.atKeepAlive:
self.kaLock = True self.kaLock = True
data = 'AT\r' data = 'AT\r'
@ -279,7 +285,7 @@ class Port:
else: else:
self.hdr.write (data) self.hdr.write (data)
tb = time.time () # start time tb = pyren_time() # start time
tmpBuff = "" tmpBuff = ""
while True: while True:
if not mod_globals.opt_demo: if not mod_globals.opt_demo:
@ -290,7 +296,7 @@ class Port:
if byte == '\r': byte = '\n' if byte == '\r': byte = '\n'
tmpBuff += byte tmpBuff += byte
tc = time.time () tc = pyren_time()
if '>' in tmpBuff: if '>' in tmpBuff:
return return
if (tc - tb) > 0.01: if (tc - tb) > 0.01:
@ -299,7 +305,7 @@ class Port:
pass pass
finally: finally:
self.lastReadTime = time.time () self.lastReadTime = pyren_time()
self.kaLock = False self.kaLock = False
if self.ka_timer: if self.ka_timer:
self.ka_timer.cancel () self.ka_timer.cancel ()
@ -371,7 +377,7 @@ class Port:
def expect(self, pattern, time_out=1): def expect(self, pattern, time_out=1):
tb = time.time () # start time tb = pyren_time() # start time
self.buff = "" self.buff = ""
try: try:
while True: while True:
@ -382,19 +388,19 @@ class Port:
if '\r' in byte: byte = byte.replace('\r', '\n') if '\r' in byte: byte = byte.replace('\r', '\n')
self.buff += byte self.buff += byte
tc = time.time () tc = pyren_time()
if pattern in self.buff: if pattern in self.buff:
self.lastReadTime = time.time () self.lastReadTime = pyren_time()
self.rwLock = False self.rwLock = False
return self.buff return self.buff
if (tc - tb) > time_out: if (tc - tb) > time_out:
self.lastReadTime = time.time () self.lastReadTime = pyren_time()
self.rwLock = False self.rwLock = False
return self.buff + "TIMEOUT" return self.buff + "TIMEOUT"
except: except:
self.rwLock = False self.rwLock = False
pass pass
self.lastReadTime = time.time () self.lastReadTime = pyren_time()
self.rwLock = False self.rwLock = False
return '' return ''
@ -415,7 +421,7 @@ class Port:
self.write ("\r") self.write ("\r")
# search > string # search > string
tb = time.time () # start time tb = pyren_time() # start time
self.buff = "" self.buff = ""
while True: while True:
if not mod_globals.opt_demo: if not mod_globals.opt_demo:
@ -423,7 +429,7 @@ class Port:
else: else:
byte = '>' byte = '>'
self.buff += byte self.buff += byte
tc = time.time () tc = pyren_time()
if '>' in self.buff: if '>' in self.buff:
mod_globals.opt_speed = s mod_globals.opt_speed = s
print("\nStart COM speed: ", s) print("\nStart COM speed: ", s)
@ -466,7 +472,7 @@ class Port:
self.write ("at brd 8\r") self.write ("at brd 8\r")
# search OK # search OK
tb = time.time () # start time tb = pyren_time() # start time
self.buff = "" self.buff = ""
while True: while True:
if not mod_globals.opt_demo: if not mod_globals.opt_demo:
@ -477,7 +483,7 @@ class Port:
self.buff = "" self.buff = ""
continue continue
self.buff += byte self.buff += byte
tc = time.time () tc = pyren_time()
if 'OK' in self.buff: if 'OK' in self.buff:
break break
if (tc - tb) > 1: if (tc - tb) > 1:
@ -491,7 +497,7 @@ class Port:
self.write ("\r") self.write ("\r")
# search > # search >
tb = time.time () # start time tb = pyren_time() # start time
self.buff = "" self.buff = ""
while True: while True:
if not mod_globals.opt_demo: if not mod_globals.opt_demo:
@ -502,7 +508,7 @@ class Port:
self.buff = "" self.buff = ""
continue continue
self.buff += byte self.buff += byte
tc = time.time () tc = pyren_time()
if '>' in self.buff: if '>' in self.buff:
mod_globals.opt_rate = mod_globals.opt_speed mod_globals.opt_rate = mod_globals.opt_speed
break break
@ -726,7 +732,7 @@ class ELM:
coalescing_time = c_t coalescing_time = c_t
coalescing_frames = c_f coalescing_frames = c_f
lst = time.time () # last send time lst = pyren_time() # last send time
frameBuff = "" frameBuff = ""
frameBuffLen = 0 frameBuffLen = 0
buff = "" buff = ""
@ -747,7 +753,7 @@ class ELM:
else: else:
byte = self.debugMonitor () byte = self.debugMonitor ()
ct = time.time () # current time ct = pyren_time() # current time
if (ct - lst) > coalescing_time: # and frameBuffLen>0: if (ct - lst) > coalescing_time: # and frameBuffLen>0:
if self.monitorSendAllow is None or not self.monitorSendAllow.isSet (): if self.monitorSendAllow is None or not self.monitorSendAllow.isSet ():
self.monitorSendAllow.set () self.monitorSendAllow.set ()
@ -856,7 +862,7 @@ class ELM:
coalescing_time = c_t coalescing_time = c_t
coalescing_frames = c_f coalescing_frames = c_f
lst = time.time() # last send time lst = pyren_time() # last send time
frameBuff = "" frameBuff = ""
frameBuffLen = 0 frameBuffLen = 0
buff = "" buff = ""
@ -873,7 +879,7 @@ class ELM:
byte = self.port.read() byte = self.port.read()
ct = time.time() # current time ct = pyren_time() # current time
if (ct - lst) > coalescing_time: # and frameBuffLen>0: if (ct - lst) > coalescing_time: # and frameBuffLen>0:
if self.monitorSendAllow is None or not self.monitorSendAllow.isSet(): if self.monitorSendAllow is None or not self.monitorSendAllow.isSet():
self.monitorSendAllow.set() self.monitorSendAllow.set()
@ -992,9 +998,9 @@ class ELM:
sendAllow.clear() sendAllow.clear()
self.nr78_startMonitor( self.waitFramesCallBack, sendAllow, 0.1, 1 ) self.nr78_startMonitor( self.waitFramesCallBack, sendAllow, 0.1, 1 )
beg = time.time () beg = pyren_time()
while not self.endWaitingFrames and ( time.time()-beg < timeout ): while not self.endWaitingFrames and ( pyren_time()-beg < timeout ):
time.sleep(0.01) time.sleep(0.01)
#debug #debug
@ -1094,7 +1100,7 @@ class ELM:
if command in list(self.notSupportedCommands.keys()): if command in list(self.notSupportedCommands.keys()):
return self.notSupportedCommands[command] return self.notSupportedCommands[command]
tb = time.time () # start time tb = pyren_time() # start time
devmode = False devmode = False
@ -1103,7 +1109,7 @@ class ELM:
if ((tb - self.lastCMDtime) < (self.busLoad + self.srvsDelay)) and command.upper()[:2] not in ['AT','ST']: if ((tb - self.lastCMDtime) < (self.busLoad + self.srvsDelay)) and command.upper()[:2] not in ['AT','ST']:
time.sleep (self.busLoad + self.srvsDelay - tb + self.lastCMDtime) time.sleep (self.busLoad + self.srvsDelay - tb + self.lastCMDtime)
tb = time.time () # renew start time tb = pyren_time() # renew start time
# save current session # save current session
saveSession = self.startSession saveSession = self.startSession
@ -1115,7 +1121,7 @@ class ELM:
# open Development session # open Development session
self.start_session (mod_globals.opt_devses) self.start_session (mod_globals.opt_devses)
self.lastCMDtime = time.time () self.lastCMDtime = pyren_time()
# log switching event # log switching event
if self.lf != 0: if self.lf != 0:
@ -1135,7 +1141,7 @@ class ELM:
#if not mod_globals.opt_demo: #if not mod_globals.opt_demo:
# self.port.reinit() #experimental # self.port.reinit() #experimental
self.send_cmd (self.startSession) self.send_cmd (self.startSession)
self.lastCMDtime = time.time () # for not to get into infinite loop self.lastCMDtime = pyren_time() # for not to get into infinite loop
# send command and check for ask to wait # send command and check for ask to wait
cmdrsp = "" cmdrsp = ""
@ -1144,7 +1150,7 @@ class ELM:
rep_count = rep_count - 1 rep_count = rep_count - 1
no_negative_wait_response = True no_negative_wait_response = True
self.lastCMDtime = tc = time.time () self.lastCMDtime = tc = pyren_time()
cmdrsp = self.send_cmd (command) cmdrsp = self.send_cmd (command)
self.checkIfCommandUnsupported(command, cmdrsp) # check if response for this command is NR:12 self.checkIfCommandUnsupported(command, cmdrsp) # check if response for this command is NR:12
@ -1165,7 +1171,7 @@ class ELM:
elif nr in ['78']: elif nr in ['78']:
self.send_raw ('at at 0') self.send_raw ('at at 0')
self.send_raw ('at st ff') self.send_raw ('at st ff')
self.lastCMDtime = tc = time.time () self.lastCMDtime = tc = pyren_time()
cmdrsp = self.send_cmd (command) cmdrsp = self.send_cmd (command)
self.send_raw ('at at 1') self.send_raw ('at at 1')
break break
@ -1179,7 +1185,7 @@ class ELM:
# restore current session # restore current session
self.startSession = saveSession self.startSession = saveSession
self.start_session (self.startSession) self.start_session (self.startSession)
self.lastCMDtime = time.time () self.lastCMDtime = pyren_time()
# log switching event # log switching event
if self.lf != 0: if self.lf != 0:
@ -1195,7 +1201,7 @@ class ELM:
if line.startswith ("7F") and len (line) == 8 and line[6:8] in list(negrsp.keys ()) and self.currentprotocol != "can": if line.startswith ("7F") and len (line) == 8 and line[6:8] in list(negrsp.keys ()) and self.currentprotocol != "can":
# if not mod_globals.state_scan: print line, negrsp[line[6:8]] # if not mod_globals.state_scan: print line, negrsp[line[6:8]]
if self.lf != 0: if self.lf != 0:
# tm = str (time.time ()) # tm = str (pyren_time())
self.lf.write ("#[" + str (tc - tb) + "] rsp:" + line + ":" + negrsp[line[6:8]] + "\n") self.lf.write ("#[" + str (tc - tb) + "] rsp:" + line + ":" + negrsp[line[6:8]] + "\n")
self.lf.flush () self.lf.flush ()
if self.vf != 0: if self.vf != 0:
@ -1464,7 +1470,7 @@ class ELM:
while Fc < Fn: while Fc < Fn:
tb = time.time() # time of sending (ff) tb = pyren_time() # time of sending (ff)
if raw_command[Fc][:1] != '2': if raw_command[Fc][:1] != '2':
Fc = Fc + 1 Fc = Fc + 1
@ -1517,11 +1523,11 @@ class ELM:
burst_size_request = 'STPX D:' + burst_size_command + ",R:1" burst_size_request = 'STPX D:' + burst_size_command + ",R:1"
# Ensure time gap between frames according to FlowControl # Ensure time gap between frames according to FlowControl
tc = time.time() # current time tc = pyren_time() # current time
self.screenRefreshTime += ST /1000. self.screenRefreshTime += ST /1000.
if (tc - tb) * 1000. < ST: if (tc - tb) * 1000. < ST:
target_time = time.time() + (ST / 1000. - (tc - tb)) target_time = pyren_time() + (ST / 1000. - (tc - tb))
while time.time() < target_time: while pyren_time() < target_time:
pass pass
tb = tc tb = tc
@ -1678,7 +1684,7 @@ class ELM:
frsp = self.send_raw ('AT R1') frsp = self.send_raw ('AT R1')
self.ATR1 = True self.ATR1 = True
tb = time.time () # time of sending (ff) tb = pyren_time() # time of sending (ff)
if Fn > 1 and Fc == (Fn-1): # set elm timeout to maximum for last response on long command if Fn > 1 and Fc == (Fn-1): # set elm timeout to maximum for last response on long command
self.send_raw('ATSTFF') self.send_raw('ATSTFF')
@ -1750,7 +1756,7 @@ class ELM:
cf = cf - 1 cf = cf - 1
# Ensure time gap between frames according to FlowControl # Ensure time gap between frames according to FlowControl
tc = time.time () # current time tc = pyren_time() # current time
if (tc - tb) * 1000. < ST: if (tc - tb) * 1000. < ST:
time.sleep (ST / 1000. - (tc - tb)) time.sleep (ST / 1000. - (tc - tb))
tb = tc tb = tc
@ -1852,11 +1858,10 @@ class ELM:
command = command.upper () command = command.upper ()
tb = time.time () # start time tb = pyren_time() # start time
# save command to log # save command to log
if self.lf != 0: if self.lf != 0:
# tm = str(time.time())
self.lf.write (">[" + log_tmstr() + "]" + command + "\n") self.lf.write (">[" + log_tmstr() + "]" + command + "\n")
self.lf.flush () self.lf.flush ()
@ -1866,11 +1871,11 @@ class ELM:
# receive and parse responce # receive and parse responce
while True: while True:
tc = time.time () tc = pyren_time()
if mod_globals.opt_demo: if mod_globals.opt_demo:
break break
self.buff = self.port.expect ('>', self.portTimeout) self.buff = self.port.expect ('>', self.portTimeout)
tc = time.time () tc = pyren_time()
if (tc - tb) > self.portTimeout and "TIMEOUT" not in self.buff: if (tc - tb) > self.portTimeout and "TIMEOUT" not in self.buff:
self.buff += "TIMEOUT" self.buff += "TIMEOUT"
if "TIMEOUT" in self.buff: if "TIMEOUT" in self.buff:
@ -1903,7 +1908,6 @@ class ELM:
# save responce to log # save responce to log
if self.lf != 0: if self.lf != 0:
# tm = str(time.time())
self.lf.write ("<[" + str (round (roundtrip, 3)) + "]" + self.buff + "\n") self.lf.write ("<[" + str (round (roundtrip, 3)) + "]" + self.buff + "\n")
self.lf.flush () self.lf.flush ()
@ -1933,8 +1937,6 @@ class ELM:
self.lastMessage = '\n\n\tFake adapter !!!\n\n' self.lastMessage = '\n\n\tFake adapter !!!\n\n'
else: else:
self.lastMessage = '\n\n\tBroken or unsupported adapter !!!\n\n' self.lastMessage = '\n\n\tBroken or unsupported adapter !!!\n\n'
# sys.exit()
def init_can(self): def init_can(self):

View File

@ -225,7 +225,7 @@ def optParser():
parser.add_argument("--caf", parser.add_argument("--caf",
help="turn on CAN Auto Formatting. Available only for OBDLink", help="turn on CAN Auto Formatting. Available only for OBDLink",
dest="caf", dest="caf",
default=False, default=True,
action="store_true") action="store_true")
parser.add_argument("--n1c", parser.add_argument("--n1c",
@ -476,6 +476,8 @@ def term_cmd( c, elm ):
def bit_cmd( l, elm, fnc='set_bits' ): def bit_cmd( l, elm, fnc='set_bits' ):
global var
error_msg1 = '''ERROR: command should have 5 parameters: error_msg1 = '''ERROR: command should have 5 parameters:
<command> <lid> <rsp_len> <offset> <hex mask> <hex value> <command> <lid> <rsp_len> <offset> <hex mask> <hex value>
<lid> - ECUs local identifier. Length should be 2 simbols for KWP or 4 for CAN <lid> - ECUs local identifier. Length should be 2 simbols for KWP or 4 for CAN
@ -498,7 +500,7 @@ def bit_cmd( l, elm, fnc='set_bits' ):
''' '''
error_msg3 = '''ERROR: command should have 6 parameters: error_msg3 = '''ERROR: command should have 4 or 7 parameters:
<command> <lid> <rsp_len> <offset> <hex mask> <hex value> <label> <command> <lid> <rsp_len> <offset> <hex mask> <hex value> <label>
<lid> - ECUs local identifier. Length should be 2 simbols for KWP or 4 for CAN <lid> - ECUs local identifier. Length should be 2 simbols for KWP or 4 for CAN
<rsp_len> - lengt of command response including positive response bytes, equals MinBytes from ddt db <rsp_len> - lengt of command response including positive response bytes, equals MinBytes from ddt db
@ -651,7 +653,10 @@ def bit_cmd( l, elm, fnc='set_bits' ):
if fnc == 'value': if fnc == 'value':
res = (int_val*float(stp)+float(ofs))/float(div) res = (int_val*float(stp)+float(ofs))/float(div)
print('# LID(',lid,') =', res) var['$rawValue'] = str(int_val)
var['$scaledValue'] = str(res)
var['$hexValue'] = hex(int_val)[2:].upper()
print('# LID(',lid,') $rawValue =', var['$rawValue'], ' $scaledValue =', var['$scaledValue'], ' $hexValue =', var['$hexValue'])
return return
if rsp[:2]=='61': if rsp[:2]=='61':
@ -665,10 +670,10 @@ def bit_cmd( l, elm, fnc='set_bits' ):
def wait_kb( ttw ): def wait_kb( ttw ):
global key_pressed global key_pressed
st = time.time() st = mod_elm.pyren_time()
kb = mod_utils.KBHit() kb = mod_utils.KBHit()
while(time.time()<(st+ttw)): while(mod_elm.pyren_time()<(st+ttw)):
if kb.kbhit(): if kb.kbhit():
key_pressed = kb.getch() key_pressed = kb.getch()
time.sleep(0.1) time.sleep(0.1)
@ -727,14 +732,16 @@ def proc_line( l, elm ):
# find veriable usage # find veriable usage
m = re.search('\$\S+', l) m = re.search('\$\S+', l)
while m: if m:
vu = m.group(0) while m:
if vu in list(var.keys()): vu = m.group(0)
l = re.sub("\\" + vu, var[vu], l) if vu in list(var.keys()):
else: l = re.sub("\\" + vu, var[vu], l)
print('Error: unknown variable', vu) else:
return print('Error: unknown variable', vu)
m = re.search('\$\S+', l) return
m = re.search('\$\S+', l)
print( "#(subst)", l)
l_parts = l.split() l_parts = l.split()
if len(l_parts) > 0 and l_parts[0] in ['wait', 'sleep']: if len(l_parts) > 0 and l_parts[0] in ['wait', 'sleep']: