342 return self.Controller.ComputePouTransitionName( |
342 return self.Controller.ComputePouTransitionName( |
343 infos.get("pou_name"), infos.get("name")) |
343 infos.get("pou_name"), infos.get("name")) |
344 |
344 |
345 instance_tagname_xslt = etree.parse( |
345 instance_tagname_xslt = etree.parse( |
346 os.path.join(ScriptDirectory, "plcopen", "instance_tagname.xslt")) |
346 os.path.join(ScriptDirectory, "plcopen", "instance_tagname.xslt")) |
|
347 |
|
348 #------------------------------------------------------------------------------- |
|
349 # Helpers object for generating pou block instances list |
|
350 #------------------------------------------------------------------------------- |
|
351 |
|
352 _BoolValue = lambda x: x in ["true", "0"] |
|
353 |
|
354 _Point = namedtuple("Point", ["x", "y"]) |
|
355 |
|
356 _BlockInstanceInfos = namedtuple("BlockInstanceInfos", |
|
357 ["type", "id", "x", "y", "width", "height", "specific_values", "inputs", "outputs"]) |
|
358 |
|
359 _BlockSpecificValues = ( |
|
360 namedtuple("BlockSpecificValues", |
|
361 ["name", "execution_order"]), |
|
362 [str, int]) |
|
363 _VariableSpecificValues = ( |
|
364 namedtuple("VariableSpecificValues", |
|
365 ["name", "value_type", "execution_order"]), |
|
366 [str, str, int]) |
|
367 _ConnectionSpecificValues = ( |
|
368 namedtuple("ConnectionSpecificValues", ["name"]), |
|
369 [str]) |
|
370 |
|
371 _PowerRailSpecificValues = ( |
|
372 namedtuple("PowerRailSpecificValues", ["connectors"]), |
|
373 [int]) |
|
374 |
|
375 _LDElementSpecificValues = ( |
|
376 namedtuple("LDElementSpecificValues", |
|
377 ["name", "negated", "edge", "storage", "execution_order"]), |
|
378 [str, _BoolValue, str, str, int]) |
|
379 |
|
380 _DivergenceSpecificValues = ( |
|
381 namedtuple("DivergenceSpecificValues", ["connectors"]), |
|
382 [int]) |
|
383 |
|
384 _SpecificValuesTuples = { |
|
385 "comment": ( |
|
386 namedtuple("CommentSpecificValues", ["content"]), |
|
387 [str]), |
|
388 "input": _VariableSpecificValues, |
|
389 "output": _VariableSpecificValues, |
|
390 "inout": _VariableSpecificValues, |
|
391 "connector": _ConnectionSpecificValues, |
|
392 "continuation": _ConnectionSpecificValues, |
|
393 "leftPowerRail": _PowerRailSpecificValues, |
|
394 "rightPowerRail": _PowerRailSpecificValues, |
|
395 "contact": _LDElementSpecificValues, |
|
396 "coil": _LDElementSpecificValues, |
|
397 "step": ( |
|
398 namedtuple("StepSpecificValues", ["name", "initial", "action"]), |
|
399 [str, _BoolValue, lambda x: x]), |
|
400 "transition": ( |
|
401 namedtuple("TransitionSpecificValues", |
|
402 ["priority", "condition_type", "condition", "connection"]), |
|
403 [int, str, str, lambda x: x]), |
|
404 "selectionDivergence": _DivergenceSpecificValues, |
|
405 "selectionConvergence": _DivergenceSpecificValues, |
|
406 "simultaneousDivergence": _DivergenceSpecificValues, |
|
407 "simultaneousConvergence": _DivergenceSpecificValues, |
|
408 "jump": ( |
|
409 namedtuple("JumpSpecificValues", ["target"]), |
|
410 [str]), |
|
411 "actionBlock": ( |
|
412 namedtuple("ActionBlockSpecificValues", ["actions"]), |
|
413 [lambda x: x]), |
|
414 } |
|
415 |
|
416 _InstanceConnectionInfos = namedtuple("InstanceConnectionInfos", |
|
417 ["name", "negated", "edge", "position", "links"]) |
|
418 |
|
419 _ConnectionLinkInfos = namedtuple("ConnectionLinkInfos", |
|
420 ["refLocalId", "formalParameter", "points"]) |
|
421 |
|
422 _ActionInfos = namedtuple("ActionInfos", |
|
423 ["qualifier", "type", "value", "duration", "indicator"]) |
|
424 |
|
425 def _translate_args(translations, args): |
|
426 return [translate(arg[0]) if len(arg) > 0 else None |
|
427 for translate, arg in |
|
428 zip(translations, args)] |
|
429 |
|
430 class BlockInstanceFactory: |
|
431 |
|
432 def __init__(self, block_instances): |
|
433 self.BlockInstances = block_instances |
|
434 self.CurrentInstance = None |
|
435 self.SpecificValues = None |
|
436 self.CurrentConnection = None |
|
437 self.CurrentLink = None |
|
438 |
|
439 def SetSpecificValues(self, context, *args): |
|
440 self.SpecificValues = list(args) |
|
441 self.CurrentInstance = None |
|
442 self.CurrentConnection = None |
|
443 self.CurrentLink = None |
|
444 |
|
445 def AddBlockInstance(self, context, *args): |
|
446 specific_values_tuple, specific_values_translation = \ |
|
447 _SpecificValuesTuples.get(args[0][0], _BlockSpecificValues) |
|
448 |
|
449 if (args[0][0] == "step" and len(self.SpecificValues) < 3 or |
|
450 args[0][0] == "transition" and len(self.SpecificValues) < 4): |
|
451 self.SpecificValues.append([None]) |
|
452 elif args[0][0] == "actionBlock" and len(self.SpecificValues) < 1: |
|
453 self.SpecificValues.append([[]]) |
|
454 specific_values = specific_values_tuple(*_translate_args( |
|
455 specific_values_translation, self.SpecificValues)) |
|
456 self.SpecificValues = None |
|
457 |
|
458 self.CurrentInstance = _BlockInstanceInfos( |
|
459 *(_translate_args([str] + [int] * 5, args) + |
|
460 [specific_values, [], []])) |
|
461 |
|
462 self.BlockInstances[self.CurrentInstance.id] = self.CurrentInstance |
|
463 |
|
464 def AddInstanceConnection(self, context, *args): |
|
465 connection_args = _translate_args( |
|
466 [str, str, _BoolValue, str, int, int], args) |
|
467 |
|
468 self.CurrentConnection = _InstanceConnectionInfos( |
|
469 *(connection_args[1:4] + [ |
|
470 _Point(*connection_args[4:6]), []])) |
|
471 |
|
472 if self.CurrentInstance is not None: |
|
473 if connection_args[0] == "input": |
|
474 self.CurrentInstance.inputs.append(self.CurrentConnection) |
|
475 else: |
|
476 self.CurrentInstance.outputs.append(self.CurrentConnection) |
|
477 else: |
|
478 self.SpecificValues.append([self.CurrentConnection]) |
|
479 |
|
480 def AddConnectionLink(self, context, *args): |
|
481 self.CurrentLink = _ConnectionLinkInfos( |
|
482 *(_translate_args([int, str], args) + [[]])) |
|
483 self.CurrentConnection.links.append(self.CurrentLink) |
|
484 |
|
485 def AddLinkPoint(self, context, *args): |
|
486 self.CurrentLink.points.append(_Point( |
|
487 *_translate_args([int, int], args))) |
|
488 |
|
489 def AddAction(self, context, *args): |
|
490 if len(self.SpecificValues) == 0: |
|
491 self.SpecificValues.append([[]]) |
|
492 translated_args = _translate_args([str] * 5, args) |
|
493 if translated_args[0] is None: |
|
494 translated_args[0] = "" |
|
495 self.SpecificValues[0][0].append(_ActionInfos(*translated_args)) |
|
496 |
|
497 pou_block_instances_xslt = etree.parse( |
|
498 os.path.join(ScriptDirectory, "plcopen", "pou_block_instances.xslt")) |
347 |
499 |
348 #------------------------------------------------------------------------------- |
500 #------------------------------------------------------------------------------- |
349 # Undo Buffer for PLCOpenEditor |
501 # Undo Buffer for PLCOpenEditor |
350 #------------------------------------------------------------------------------- |
502 #------------------------------------------------------------------------------- |
351 |
503 |
2287 instance.setexecutionOrderId(0) |
2438 instance.setexecutionOrderId(0) |
2288 instance.translate(*diff) |
2439 instance.translate(*diff) |
2289 |
2440 |
2290 return new_id, connections |
2441 return new_id, connections |
2291 |
2442 |
2292 # Return the current pou editing instances idx |
2443 def GetEditedElementInstancesInfos(self, tagname, debug = False): |
2293 def GetEditedElementInstancesIds(self, tagname, debug = False): |
2444 element_instances = OrderedDict() |
2294 element = self.GetEditedElement(tagname, debug) |
2445 element = self.GetEditedElement(tagname, debug) |
2295 if element is not None: |
2446 if element is not None: |
2296 return element.getinstancesIds() |
2447 factory = BlockInstanceFactory(element_instances) |
2297 return [] |
2448 |
2298 |
2449 pou_block_instances_xslt_tree = etree.XSLT( |
2299 # Return the current pou editing informations |
2450 pou_block_instances_xslt, |
2300 def GetEditedElementInstanceInfos(self, tagname, id, debug = False): |
2451 extensions = { |
2301 element = self.GetEditedElement(tagname, debug) |
2452 ("pou_block_instances_ns", name): getattr(factory, name) |
2302 if element is not None: |
2453 for name in ["AddBlockInstance", "SetSpecificValues", |
2303 instance = element.getinstance(id) |
2454 "AddInstanceConnection", "AddConnectionLink", |
2304 if instance is not None: |
2455 "AddLinkPoint", "AddAction"]}) |
2305 infos = instance.getinfos() |
2456 |
2306 if infos["type"] in ["input", "output", "inout"]: |
2457 pou_block_instances_xslt_tree(element) |
2307 var_type = self.GetEditedElementVarValueType(tagname, infos["specific_values"]["name"], debug) |
2458 return element_instances |
2308 infos["specific_values"]["value_type"] = var_type |
|
2309 return infos |
|
2310 return None |
|
2311 |
2459 |
2312 def ClearEditedElementExecutionOrder(self, tagname): |
2460 def ClearEditedElementExecutionOrder(self, tagname): |
2313 element = self.GetEditedElement(tagname) |
2461 element = self.GetEditedElement(tagname) |
2314 if element is not None: |
2462 if element is not None: |
2315 element.resetexecutionOrder() |
2463 element.resetexecutionOrder() |
2316 |
2464 |
2317 def ResetEditedElementExecutionOrder(self, tagname): |
2465 def ResetEditedElementExecutionOrder(self, tagname): |
2318 element = self.GetEditedElement(tagname) |
2466 element = self.GetEditedElement(tagname) |
2319 if element is not None: |
2467 if element is not None: |
2320 element.compileexecutionOrder() |
2468 element.compileexecutionOrder() |
2321 |
|
2322 # Return the variable type of the given pou |
|
2323 def GetEditedElementVarValueType(self, tagname, varname, debug = False): |
|
2324 project = self.GetProject(debug) |
|
2325 if project is not None: |
|
2326 words = tagname.split("::") |
|
2327 if words[0] in ["P","T","A"]: |
|
2328 pou = self.Project.getpou(words[1]) |
|
2329 if pou is not None: |
|
2330 if words[0] == "T" and varname == words[2]: |
|
2331 return "BOOL" |
|
2332 if words[1] == varname: |
|
2333 return self.GetPouInterfaceReturnType(pou)[0] |
|
2334 for type, varlist in pou.getvars(): |
|
2335 for var in varlist.getvariable(): |
|
2336 if var.getname() == varname: |
|
2337 vartype_content = var.gettype().getcontent() |
|
2338 vartype_content_type = vartype_content.getLocalTag() |
|
2339 if vartype_content_type == "derived": |
|
2340 return vartype_content.getname() |
|
2341 else: |
|
2342 return vartype_content_type.upper() |
|
2343 return None |
|
2344 |
2469 |
2345 def SetConnectionWires(self, connection, connector): |
2470 def SetConnectionWires(self, connection, connector): |
2346 wires = connector.GetWires() |
2471 wires = connector.GetWires() |
2347 idx = 0 |
2472 idx = 0 |
2348 for wire, handle in wires: |
2473 for wire, handle in wires: |