1200 self.TracedIECPath = [] |
1200 self.TracedIECPath = [] |
1201 if self._connector is not None: |
1201 if self._connector is not None: |
1202 self.IECdebug_lock.acquire() |
1202 self.IECdebug_lock.acquire() |
1203 IECPathsToPop = [] |
1203 IECPathsToPop = [] |
1204 for IECPath,data_tuple in self.IECdebug_datas.iteritems(): |
1204 for IECPath,data_tuple in self.IECdebug_datas.iteritems(): |
1205 WeakCallableDict, data_log, status, fvalue = data_tuple |
1205 WeakCallableDict, data_log, status, fvalue, buffer_list = data_tuple |
1206 if len(WeakCallableDict) == 0: |
1206 if len(WeakCallableDict) == 0: |
1207 # Callable Dict is empty. |
1207 # Callable Dict is empty. |
1208 # This variable is not needed anymore! |
1208 # This variable is not needed anymore! |
1209 IECPathsToPop.append(IECPath) |
1209 IECPathsToPop.append(IECPath) |
1210 elif IECPath != "__tick__": |
1210 elif IECPath != "__tick__": |
1266 if IECdebug_data is None: |
1266 if IECdebug_data is None: |
1267 IECdebug_data = [ |
1267 IECdebug_data = [ |
1268 WeakKeyDictionary(), # Callables |
1268 WeakKeyDictionary(), # Callables |
1269 [], # Data storage [(tick, data),...] |
1269 [], # Data storage [(tick, data),...] |
1270 "Registered", # Variable status |
1270 "Registered", # Variable status |
1271 None] # Forced value |
1271 None, |
|
1272 buffer_list] # Forced value |
1272 self.IECdebug_datas[IECPath] = IECdebug_data |
1273 self.IECdebug_datas[IECPath] = IECdebug_data |
1273 |
1274 else: |
1274 IECdebug_data[0][callableobj]=(args, kwargs) |
1275 IECdebug_data[4] |= buffer_list |
|
1276 |
|
1277 IECdebug_data[0][callableobj]=(buffer_list, args, kwargs) |
1275 |
1278 |
1276 self.IECdebug_lock.release() |
1279 self.IECdebug_lock.release() |
1277 |
1280 |
1278 self.ReArmDebugRegisterTimer() |
1281 self.ReArmDebugRegisterTimer() |
1279 |
1282 |
1284 IECdebug_data = self.IECdebug_datas.get(IECPath, None) |
1287 IECdebug_data = self.IECdebug_datas.get(IECPath, None) |
1285 if IECdebug_data is not None: |
1288 if IECdebug_data is not None: |
1286 IECdebug_data[0].pop(callableobj,None) |
1289 IECdebug_data[0].pop(callableobj,None) |
1287 if len(IECdebug_data[0]) == 0: |
1290 if len(IECdebug_data[0]) == 0: |
1288 self.IECdebug_datas.pop(IECPath) |
1291 self.IECdebug_datas.pop(IECPath) |
|
1292 else: |
|
1293 IECdebug_data[4] = reduce( |
|
1294 lambda x, y: x|y, |
|
1295 [buffer_list for buffer_list,args,kwargs |
|
1296 in IECdebug_data[0].itervalues()], |
|
1297 False) |
1289 self.IECdebug_lock.release() |
1298 self.IECdebug_lock.release() |
1290 |
1299 |
1291 self.ReArmDebugRegisterTimer() |
1300 self.ReArmDebugRegisterTimer() |
1292 |
1301 |
1293 def UnsubscribeAllDebugIECVariable(self): |
1302 def UnsubscribeAllDebugIECVariable(self): |
1328 self.ReArmDebugRegisterTimer() |
1337 self.ReArmDebugRegisterTimer() |
1329 |
1338 |
1330 def CallWeakcallables(self, IECPath, function_name, *cargs): |
1339 def CallWeakcallables(self, IECPath, function_name, *cargs): |
1331 data_tuple = self.IECdebug_datas.get(IECPath, None) |
1340 data_tuple = self.IECdebug_datas.get(IECPath, None) |
1332 if data_tuple is not None: |
1341 if data_tuple is not None: |
1333 WeakCallableDict, data_log, status, fvalue = data_tuple |
1342 WeakCallableDict, data_log, status, fvalue, buffer_list = data_tuple |
1334 #data_log.append((debug_tick, value)) |
1343 #data_log.append((debug_tick, value)) |
1335 for weakcallable,(args,kwargs) in WeakCallableDict.iteritems(): |
1344 for weakcallable,(buffer_list,args,kwargs) in WeakCallableDict.iteritems(): |
1336 function = getattr(weakcallable, function_name, None) |
1345 function = getattr(weakcallable, function_name, None) |
1337 if function is not None: |
1346 if function is not None: |
1338 if status == "Forced" and cargs[1] == fvalue: |
1347 if buffer_list: |
1339 function(*(cargs + (True,) + args), **kwargs) |
1348 function(*(cargs + args), **kwargs) |
1340 else: |
1349 else: |
1341 function(*(cargs + args), **kwargs) |
1350 function(*(tuple([lst[-1] for lst in cargs]) + args), **kwargs) |
1342 # This will block thread if more than one call is waiting |
|
1343 |
1351 |
1344 def GetTicktime(self): |
1352 def GetTicktime(self): |
1345 return self._Ticktime |
1353 return self._Ticktime |
1346 |
1354 |
1347 def RemoteExec(self, script, **kwargs): |
1355 def RemoteExec(self, script, **kwargs): |
1363 plc_status = None |
1371 plc_status = None |
1364 debug_getvar_retry += 1 |
1372 debug_getvar_retry += 1 |
1365 #print [dict.keys() for IECPath, (dict, log, status, fvalue) in self.IECdebug_datas.items()] |
1373 #print [dict.keys() for IECPath, (dict, log, status, fvalue) in self.IECdebug_datas.items()] |
1366 if plc_status == "Started": |
1374 if plc_status == "Started": |
1367 self.IECdebug_lock.acquire() |
1375 self.IECdebug_lock.acquire() |
1368 if len(debug_vars) == len(self.DebugValuesBuffers): |
1376 if (len(debug_vars) == len(self.DebugValuesBuffers) and |
|
1377 len(debug_vars) == len(self.TracedIECPath)): |
1369 if debug_getvar_retry > DEBUG_RETRIES_WARN: |
1378 if debug_getvar_retry > DEBUG_RETRIES_WARN: |
1370 self.logger.write(_("... debugger recovered\n")) |
1379 self.logger.write(_("... debugger recovered\n")) |
1371 debug_getvar_retry = 0 |
1380 debug_getvar_retry = 0 |
1372 for values_buffer, value in zip(self.DebugValuesBuffers, debug_vars): |
1381 for IECPath, values_buffer, value in zip(self.TracedIECPath, self.DebugValuesBuffers, debug_vars): |
1373 if value is not None: |
1382 IECdebug_data = self.IECdebug_datas.get(IECPath, None) |
1374 values_buffer.append(value) |
1383 if IECdebug_data is not None and value is not None: |
|
1384 forced = IECdebug_data[2:4] == ["Forced", value] |
|
1385 if not IECdebug_data[4] and len(values_buffer) > 0: |
|
1386 values_buffer[-1] = (value, forced) |
|
1387 else: |
|
1388 values_buffer.append((value, forced)) |
1375 self.DebugTicks.append(debug_tick) |
1389 self.DebugTicks.append(debug_tick) |
1376 self.IECdebug_lock.release() |
1390 self.IECdebug_lock.release() |
1377 if debug_getvar_retry == DEBUG_RETRIES_WARN: |
1391 if debug_getvar_retry == DEBUG_RETRIES_WARN: |
1378 self.logger.write(_("Waiting debugger to recover...\n")) |
1392 self.logger.write(_("Waiting debugger to recover...\n")) |
1379 if debug_getvar_retry == DEBUG_RETRIES_REREGISTER: |
1393 if debug_getvar_retry == DEBUG_RETRIES_REREGISTER: |