35 from PLCGenerator import * |
35 from PLCGenerator import * |
36 |
36 |
37 duration_model = re.compile("(?:([0-9]{1,2})h)?(?:([0-9]{1,2})m(?!s))?(?:([0-9]{1,2})s)?(?:([0-9]{1,3}(?:.[0-9]*)?)ms)?") |
37 duration_model = re.compile("(?:([0-9]{1,2})h)?(?:([0-9]{1,2})m(?!s))?(?:([0-9]{1,2})s)?(?:([0-9]{1,3}(?:.[0-9]*)?)ms)?") |
38 |
38 |
39 [ITEM_UNEDITABLE, ITEM_PROJECT, ITEM_POU, ITEM_CLASS, ITEM_VARIABLE, |
39 [ITEM_UNEDITABLE, ITEM_PROJECT, ITEM_POU, ITEM_CLASS, ITEM_VARIABLE, |
40 ITEM_TRANSITION, ITEM_ACTION, ITEM_CONFIGURATION, ITEM_RESOURCE] = range(9) |
40 ITEM_TRANSITION, ITEM_ACTION, ITEM_CONFIGURATION, ITEM_RESOURCE, |
|
41 ITEM_DATATYPE] = range(10) |
|
42 |
|
43 ScriptDirectory = os.path.split(os.path.realpath(__file__))[0] |
41 |
44 |
42 """ |
45 """ |
43 pyxsval is not complete and the parts that are not supported print some error |
46 pyxsval is not complete and the parts that are not supported print some error |
44 reports. This class is used for not displaying them |
47 reports. This class is used for not displaying them |
45 """ |
48 """ |
261 |
272 |
262 # Return project informations |
273 # Return project informations |
263 def GetProjectInfos(self): |
274 def GetProjectInfos(self): |
264 if self.Project: |
275 if self.Project: |
265 infos = {"name": self.Project.getName(), "type": ITEM_PROJECT} |
276 infos = {"name": self.Project.getName(), "type": ITEM_PROJECT} |
|
277 datatypes = {"name": "Data Types", "type": ITEM_UNEDITABLE, "values":[]} |
|
278 for datatype in self.Project.getDataTypes(): |
|
279 datatypes["values"].append({"name": datatype.getName(), "type": ITEM_DATATYPE, "values": []}) |
266 pou_types = {"function": {"name": "Functions", "type": ITEM_UNEDITABLE, "values":[]}, |
280 pou_types = {"function": {"name": "Functions", "type": ITEM_UNEDITABLE, "values":[]}, |
267 "functionBlock": {"name": "Function Blocks", "type": ITEM_UNEDITABLE, "values":[]}, |
281 "functionBlock": {"name": "Function Blocks", "type": ITEM_UNEDITABLE, "values":[]}, |
268 "program": {"name": "Programs", "type": ITEM_UNEDITABLE, "values":[]}} |
282 "program": {"name": "Programs", "type": ITEM_UNEDITABLE, "values":[]}} |
269 for pou in self.Project.getPous(): |
283 for pou in self.Project.getPous(): |
270 pou_type = pou.getPouType().getValue() |
284 pou_type = pou.getPouType().getValue() |
292 resource_infos = {"name": resource_name, "type": ITEM_RESOURCE, "values": []} |
306 resource_infos = {"name": resource_name, "type": ITEM_RESOURCE, "values": []} |
293 resources["values"].append(resource_infos) |
307 resources["values"].append(resource_infos) |
294 config_infos["values"] = [resources] |
308 config_infos["values"] = [resources] |
295 configurations["values"].append(config_infos) |
309 configurations["values"].append(config_infos) |
296 infos["values"] = [{"name": "Properties", "type": ITEM_UNEDITABLE, "values": []}, |
310 infos["values"] = [{"name": "Properties", "type": ITEM_UNEDITABLE, "values": []}, |
297 pou_types["function"], pou_types["functionBlock"], |
311 datatypes, pou_types["function"], pou_types["functionBlock"], |
298 pou_types["program"], configurations] |
312 pou_types["program"], configurations] |
299 return infos |
313 return infos |
300 return None |
314 return None |
301 |
315 |
|
316 # Refresh the tree of user-defined data type cross-use |
|
317 def RefreshDataTypeUsingTree(self): |
|
318 # Reset the tree of user-defined pou cross-use |
|
319 self.DataTypeUsingTree = {} |
|
320 if self.Project: |
|
321 datatypes = self.Project.getDataTypes() |
|
322 # Reference all the user-defined data type names and initialize the tree of |
|
323 # user-defined data type cross-use |
|
324 datatypenames = [datatype.getName() for datatype in datatypes] |
|
325 for name in datatypenames: |
|
326 self.DataTypeUsingTree[name] = [] |
|
327 # Analyze each data type |
|
328 for datatype in datatypes: |
|
329 name = datatype.getName() |
|
330 basetype_content = datatype.getBaseType().getContent() |
|
331 if basetype_content["value"] is not None: |
|
332 if basetype_content["name"] == "derived": |
|
333 basetype_name = basetype_content["value"].getName() |
|
334 if basetype_name in datatypenames and name not in self.DataTypeUsingTree[basetype_name]: |
|
335 self.DataTypeUsingTree[basetype_name].append(name) |
|
336 elif basetype_content["name"] in ["subrangeSigned", "subrangeUnsigned", "array"]: |
|
337 base_type = basetype_content["value"].baseType.getContent() |
|
338 if base_type["value"] is not None: |
|
339 basetype_name = base_type["value"].getName() |
|
340 if basetype_name in datatypenames and name not in self.DataTypeUsingTree[basetype_name]: |
|
341 self.DataTypeUsingTree[basetype_name].append(name) |
|
342 |
302 # Refresh the tree of user-defined pou cross-use |
343 # Refresh the tree of user-defined pou cross-use |
303 def RefreshPouUsingTree(self): |
344 def RefreshPouUsingTree(self): |
304 # Reset the tree of user-defined pou cross-use |
345 # Reset the tree of user-defined pou cross-use |
305 self.PouUsingTree = {} |
346 self.PouUsingTree = {} |
306 if self.Project: |
347 if self.Project: |
315 name = pou.getName() |
356 name = pou.getName() |
316 if pou.interface: |
357 if pou.interface: |
317 # Extract variables from every varLists |
358 # Extract variables from every varLists |
318 for type, varlist in pou.getVars(): |
359 for type, varlist in pou.getVars(): |
319 for var in varlist.getVariable(): |
360 for var in varlist.getVariable(): |
320 var_type = var.getType().getValue() |
361 vartype_content = var.getType().getContent() |
321 if not isinstance(var_type, (StringType, UnicodeType)): |
362 if vartype_content["value"] is not None: |
322 typename = var_type.getName() |
363 typename = vartype_content["value"].getName() |
323 if typename in pounames and name not in self.PouUsingTree[typename]: |
364 if typename in pounames and name not in self.PouUsingTree[typename]: |
324 self.PouUsingTree[typename].append(name) |
365 self.PouUsingTree[typename].append(name) |
325 bodytype = pou.getBodyType() |
366 bodytype = pou.getBodyType() |
326 # If pou is written in a graphical language |
367 # If pou is written in a graphical language |
327 if bodytype in ["FBD","LD","SFC"]: |
368 if bodytype in ["FBD","LD","SFC"]: |
340 typename_model = re.compile("[ \t\n]%s[ \t\n]"%typename) |
381 typename_model = re.compile("[ \t\n]%s[ \t\n]"%typename) |
341 # Update tree if there is a cross-use |
382 # Update tree if there is a cross-use |
342 if typename != name and typename_model.search(text): |
383 if typename != name and typename_model.search(text): |
343 self.PouUsingTree[typename].append(name) |
384 self.PouUsingTree[typename].append(name) |
344 |
385 |
|
386 # Return if data type given by name is used by another data type or pou |
|
387 def DataTypeIsUsed(self, name): |
|
388 if name in self.DataTypeUsingTree: |
|
389 return len(self.DataTypeUsingTree[name]) > 0 |
|
390 return False |
|
391 |
345 # Return if pou given by name is used by another pou |
392 # Return if pou given by name is used by another pou |
346 def PouIsUsed(self, name): |
393 def PouIsUsed(self, name): |
347 if name in self.PouUsingTree: |
394 if name in self.PouUsingTree: |
348 return len(self.PouUsingTree[name]) > 0 |
395 return len(self.PouUsingTree[name]) > 0 |
|
396 return False |
|
397 |
|
398 # Return if data type given by name is directly or undirectly used by the reference data type |
|
399 def DataTypeIsUsedBy(self, name, reference): |
|
400 if name in self.DataTypeUsingTree: |
|
401 list = self.DataTypeUsingTree[name] |
|
402 # Test if data type is directly used by reference |
|
403 if reference in list: |
|
404 return True |
|
405 else: |
|
406 # Test if data type is undirectly used by reference, by testing if data types |
|
407 # that directly use data type is directly or undirectly used by reference |
|
408 used = False |
|
409 for element in list: |
|
410 used |= self.DataTypeIsUsedBy(element, reference) |
|
411 return used |
349 return False |
412 return False |
350 |
413 |
351 # Return if pou given by name is directly or undirectly used by the reference pou |
414 # Return if pou given by name is directly or undirectly used by the reference pou |
352 def PouIsUsedBy(self, name, reference): |
415 def PouIsUsedBy(self, name, reference): |
353 if name in self.PouUsingTree: |
416 if name in self.PouUsingTree: |
378 return False |
441 return False |
379 |
442 |
380 #------------------------------------------------------------------------------- |
443 #------------------------------------------------------------------------------- |
381 # Project Pous management functions |
444 # Project Pous management functions |
382 #------------------------------------------------------------------------------- |
445 #------------------------------------------------------------------------------- |
383 |
446 |
|
447 # Add a Data Type to Project |
|
448 def ProjectAddDataType(self, datatype_name): |
|
449 # Add the pou to project |
|
450 self.Project.appendDataType(datatype_name) |
|
451 self.RefreshDataTypeUsingTree() |
|
452 self.RefreshDataTypes() |
|
453 self.BufferProject() |
|
454 |
|
455 # Remove a Data Type from project |
|
456 def ProjectRemoveDataType(self, datatype_name): |
|
457 self.Project.removeDataType(datatype_name) |
|
458 self.RefreshDataTypeUsingTree() |
|
459 self.RefreshDataTypes() |
|
460 self.BufferProject() |
|
461 |
384 # Add a Pou to Project |
462 # Add a Pou to Project |
385 def ProjectAddPou(self, pou_name, pou_type, body_type): |
463 def ProjectAddPou(self, pou_name, pou_type, body_type): |
386 # Add the pou to project |
464 # Add the pou to project |
387 self.Project.appendPou(pou_name, pou_type, body_type) |
465 self.Project.appendPou(pou_name, pou_type, body_type) |
388 if pou_type == "function": |
466 if pou_type == "function": |
389 self.SetPouInterfaceReturnType(pou_name, "BOOL") |
467 self.SetPouInterfaceReturnType(pou_name, "BOOL") |
390 self.RefreshPouUsingTree() |
468 self.RefreshPouUsingTree() |
391 self.RefreshBlockTypes() |
469 self.RefreshBlockTypes() |
392 self.BufferProject() |
470 self.BufferProject() |
393 |
471 |
394 # Remove a pou from project |
472 # Remove a Pou from project |
395 def ProjectRemovePou(self, pou_name): |
473 def ProjectRemovePou(self, pou_name): |
396 self.Project.removePou(pou_name) |
474 self.Project.removePou(pou_name) |
397 self.RefreshPouUsingTree() |
475 self.RefreshPouUsingTree() |
398 self.RefreshBlockTypes() |
476 self.RefreshBlockTypes() |
399 self.BufferProject() |
477 self.BufferProject() |
400 |
478 |
401 # Add a configuration to Project |
479 # Add a configuration to Project |
402 def ProjectAddConfiguration(self, config_name): |
480 def ProjectAddConfiguration(self, config_name): |
403 self.Project.addConfiguration(config_name) |
481 self.Project.addConfiguration(config_name) |
404 self.RefreshPouUsingTree() |
|
405 self.RefreshBlockTypes() |
|
406 self.BufferProject() |
482 self.BufferProject() |
407 |
483 |
408 # Remove a configuration from project |
484 # Remove a configuration from project |
409 def ProjectRemoveConfiguration(self, config_name): |
485 def ProjectRemoveConfiguration(self, config_name): |
410 self.Project.removeConfiguration(config_name) |
486 self.Project.removeConfiguration(config_name) |
411 self.BufferProject() |
487 self.BufferProject() |
412 |
488 |
413 # Add a resource to a configuration of the Project |
489 # Add a resource to a configuration of the Project |
414 def ProjectAddConfigurationResource(self, config_name, resource_name): |
490 def ProjectAddConfigurationResource(self, config_name, resource_name): |
415 self.Project.addConfigurationResource(config_name, resource_name) |
491 self.Project.addConfigurationResource(config_name, resource_name) |
416 self.RefreshPouUsingTree() |
|
417 self.RefreshBlockTypes() |
|
418 self.BufferProject() |
492 self.BufferProject() |
419 |
493 |
420 # Remove a resource from a configuration of the project |
494 # Remove a resource from a configuration of the project |
421 def ProjectRemoveConfigurationResource(self, config_name, resource_name): |
495 def ProjectRemoveConfigurationResource(self, config_name, resource_name): |
422 self.Project.removeConfigurationResource(config_name, resource_name) |
496 self.Project.removeConfigurationResource(config_name, resource_name) |
448 if words[0] == "A" and words[1] == pou_name and words[2] == action_name: |
522 if words[0] == "A" and words[1] == pou_name and words[2] == action_name: |
449 self.RemoveElementEditing(i) |
523 self.RemoveElementEditing(i) |
450 pou = self.Project.getPou(pou_name) |
524 pou = self.Project.getPou(pou_name) |
451 pou.removeAction(action_name) |
525 pou.removeAction(action_name) |
452 self.BufferProject() |
526 self.BufferProject() |
453 |
527 |
|
528 # Change the name of a pou |
|
529 def ChangeDataTypeName(self, old_name, new_name): |
|
530 # Found the pou corresponding to old name and change its name to new name |
|
531 datatype = self.Project.getDataType(old_name) |
|
532 datatype.setName(new_name) |
|
533 self.Project.updateElementName(old_name, new_name) |
|
534 self.BufferProject() |
|
535 |
454 # Change the name of a pou |
536 # Change the name of a pou |
455 def ChangePouName(self, old_name, new_name): |
537 def ChangePouName(self, old_name, new_name): |
456 # Found the pou corresponding to old name and change its name to new name |
538 # Found the pou corresponding to old name and change its name to new name |
457 pou = self.Project.getPou(old_name) |
539 pou = self.Project.getPou(old_name) |
458 pou.setName(new_name) |
540 pou.setName(new_name) |
573 varlist.setConstant(True) |
655 varlist.setConstant(True) |
574 # Create variable and change its properties |
656 # Create variable and change its properties |
575 tempvar = plcopen.varListPlain_variable() |
657 tempvar = plcopen.varListPlain_variable() |
576 tempvar.setName(var["Name"]) |
658 tempvar.setName(var["Name"]) |
577 var_type = plcopen.dataType() |
659 var_type = plcopen.dataType() |
578 if GetBlockType(var["Type"]) != None: |
660 if var["Type"] not in var_type.getChoices(): |
579 derived_type = plcopen.derived() |
661 derived_type = plcopen.derived() |
580 derived_type.setName(var["Type"]) |
662 derived_type.setName(var["Type"]) |
581 var_type.setValue(derived_type) |
663 var_type.setContent("derived", derived_type) |
582 else: |
664 else: |
583 var_type.setValue(var["Type"]) |
665 var_type.setContent(var["Type"], None) |
584 tempvar.setType(var_type) |
666 tempvar.setType(var_type) |
585 if var["Initial Value"] != "": |
667 if var["Initial Value"] != "": |
586 value = plcopen.value() |
668 value = plcopen.value() |
587 value.setValue(var["Initial Value"]) |
669 value.setValue(var["Initial Value"]) |
588 tempvar.setInitialValue(value) |
670 tempvar.setInitialValue(value) |
613 if configuration: |
695 if configuration: |
614 # Extract variables from every varLists |
696 # Extract variables from every varLists |
615 for varlist in configuration.getGlobalVars(): |
697 for varlist in configuration.getGlobalVars(): |
616 for var in varlist.getVariable(): |
698 for var in varlist.getVariable(): |
617 tempvar = {"Name":var.getName(),"Class":"Global"} |
699 tempvar = {"Name":var.getName(),"Class":"Global"} |
618 var_type = var.getType().getValue() |
700 vartype_content = var.getType().getContent() |
619 if isinstance(var_type, (StringType, UnicodeType)): |
701 if vartype_content["value"] is None: |
620 tempvar["Type"] = var_type |
702 tempvar["Type"] = vartype_content["name"] |
621 else: |
703 else: |
622 tempvar["Type"] = var_type.getName() |
704 tempvar["Type"] = vartype_content["value"].getName() |
623 tempvar["Edit"] = True |
705 tempvar["Edit"] = True |
624 initial = var.getInitialValue() |
706 initial = var.getInitialValue() |
625 if initial: |
707 if initial: |
626 tempvar["Initial Value"] = initial.getValue() |
708 tempvar["Initial Value"] = initial.getValue() |
627 else: |
709 else: |
661 if resource: |
743 if resource: |
662 # Extract variables from every varLists |
744 # Extract variables from every varLists |
663 for varlist in resource.getGlobalVars(): |
745 for varlist in resource.getGlobalVars(): |
664 for var in varlist.getVariable(): |
746 for var in varlist.getVariable(): |
665 tempvar = {"Name":var.getName(),"Class":"Global"} |
747 tempvar = {"Name":var.getName(),"Class":"Global"} |
666 var_type = var.getType().getValue() |
748 vartype_content = var.getType().getContent() |
667 if isinstance(var_type, (StringType, UnicodeType)): |
749 if vartype_content["value"] is None: |
668 tempvar["Type"] = var_type |
750 tempvar["Type"] = vartype_content["name"] |
669 else: |
751 else: |
670 tempvar["Type"] = var_type.getName() |
752 tempvar["Type"] = vartype_content["value"].getName() |
671 tempvar["Edit"] = True |
753 tempvar["Edit"] = True |
672 initial = var.getInitialValue() |
754 initial = var.getInitialValue() |
673 if initial: |
755 if initial: |
674 tempvar["Initial Value"] = initial.getValue() |
756 tempvar["Initial Value"] = initial.getValue() |
675 else: |
757 else: |
702 if pou.interface: |
784 if pou.interface: |
703 # Extract variables from every varLists |
785 # Extract variables from every varLists |
704 for type, varlist in pou.getVars(): |
786 for type, varlist in pou.getVars(): |
705 for var in varlist.getVariable(): |
787 for var in varlist.getVariable(): |
706 tempvar = {"Name":var.getName(),"Class":type} |
788 tempvar = {"Name":var.getName(),"Class":type} |
707 var_type = var.getType().getValue() |
789 vartype_content = var.getType().getContent() |
708 if isinstance(var_type, (StringType, UnicodeType)): |
790 if vartype_content["value"] is None: |
709 tempvar["Type"] = var_type |
791 tempvar["Type"] = vartype_content["name"] |
710 tempvar["Edit"] = True |
792 tempvar["Edit"] = True |
711 else: |
793 else: |
712 tempvar["Type"] = var_type.getName() |
794 tempvar["Type"] = vartype_content["value"].getName() |
713 tempvar["Edit"] = not pou.hasBlock(tempvar["Name"]) |
795 tempvar["Edit"] = not pou.hasBlock(tempvar["Name"]) |
714 initial = var.getInitialValue() |
796 initial = var.getInitialValue() |
715 if initial: |
797 if initial: |
716 tempvar["Initial Value"] = initial.getValue() |
798 tempvar["Initial Value"] = initial.getValue() |
717 else: |
799 else: |
776 # Verify that the pou has an interface |
863 # Verify that the pou has an interface |
777 if pou.interface: |
864 if pou.interface: |
778 # Return the return type if there is one |
865 # Return the return type if there is one |
779 return_type = pou.interface.getReturnType() |
866 return_type = pou.interface.getReturnType() |
780 if return_type: |
867 if return_type: |
781 return return_type.getValue() |
868 returntype_content = return_type.getContent() |
|
869 if returntype_content["value"] is None: |
|
870 return returntype_content["name"] |
|
871 else: |
|
872 return returntype_content["value"].getName() |
782 return None |
873 return None |
783 |
874 |
|
875 # Update data types with user-defined data types added |
|
876 def RefreshDataTypes(self): |
|
877 ResetTypeHierarchy() |
|
878 ResetEnumeratedDataValues() |
|
879 if self.Project: |
|
880 for datatype in self.Project.getDataTypes(): |
|
881 name = datatype.getName() |
|
882 basetype_content = datatype.getBaseType().getContent() |
|
883 if basetype_content["value"] is None: |
|
884 AddDataTypeHierarchy(name, basetype_content["name"]) |
|
885 elif basetype_content["name"] == "derived": |
|
886 AddDataTypeHierarchy(name, basetype_content["value"].getName()) |
|
887 elif basetype_content["name"] in ["subrangeSigned", "subrangeUnsigned"]: |
|
888 base_type = basetype_content["value"].baseType.getContent() |
|
889 if base_type["value"] is None: |
|
890 AddDataTypeHierarchy(name, base_type["name"]) |
|
891 else: |
|
892 AddDataTypeHierarchy(name, base_type["value"].getName()) |
|
893 else: |
|
894 if basetype_content["name"] == "enum": |
|
895 values = [] |
|
896 for value in basetype_content["value"].values.getValue(): |
|
897 values.append(value.getName()) |
|
898 AddEnumeratedDataValues(values) |
|
899 AddDataTypeHierarchy(name, "ANY_DERIVED") |
|
900 |
784 # Update Block types with user-defined pou added |
901 # Update Block types with user-defined pou added |
785 def RefreshBlockTypes(self): |
902 def RefreshBlockTypes(self): |
786 if BlockTypes[-1]["name"] == "User-defined POUs": |
903 if BlockTypes[-1]["name"] == "User-defined POUs": |
787 BlockTypes[-1]["list"] = [] |
904 BlockTypes[-1]["list"] = [] |
788 else: |
905 else: |
797 "generate" : generate_block, "initialise" : initialise_block } |
914 "generate" : generate_block, "initialise" : initialise_block } |
798 if pou.getInterface(): |
915 if pou.getInterface(): |
799 for type, varlist in pou.getVars(): |
916 for type, varlist in pou.getVars(): |
800 if type == "InOut": |
917 if type == "InOut": |
801 for var in varlist.getVariable(): |
918 for var in varlist.getVariable(): |
802 block_infos["inputs"].append((var.getName(),var.getType().getValue(),"none")) |
919 var_type = var.type.getContent() |
803 block_infos["outputs"].append((var.getName(),var.getType().getValue(),"none")) |
920 if var_type["value"] is None: |
|
921 block_infos["inputs"].append((var.getName(),var_type["name"],"none")) |
|
922 block_infos["outputs"].append((var.getName(),var_type["name"],"none")) |
|
923 else: |
|
924 block_infos["inputs"].append((var.getName(),var_type["value"].getName(),"none")) |
|
925 block_infos["outputs"].append((var.getName(),var_type["value"].getName(),"none")) |
804 elif type == "Input": |
926 elif type == "Input": |
805 for var in varlist.getVariable(): |
927 for var in varlist.getVariable(): |
806 block_infos["inputs"].append((var.getName(),var.getType().getValue(),"none")) |
928 var_type = var.type.getContent() |
|
929 if var_type["value"] is None: |
|
930 block_infos["inputs"].append((var.getName(),var_type["name"],"none")) |
|
931 else: |
|
932 block_infos["inputs"].append((var.getName(),var_type["value"].getName(),"none")) |
807 elif type == "Output": |
933 elif type == "Output": |
808 for var in varlist.getVariable(): |
934 for var in varlist.getVariable(): |
809 block_infos["outputs"].append((var.getName(),var.getType().getValue(),"none")) |
935 var_type = var.type.getContent() |
|
936 if var_type["value"] is None: |
|
937 block_infos["outputs"].append((var.getName(),var_type["name"],"none")) |
|
938 else: |
|
939 block_infos["outputs"].append((var.getName(),var_type["value"].getName(),"none")) |
810 return_type = pou.interface.getReturnType() |
940 return_type = pou.interface.getReturnType() |
811 if return_type: |
941 if return_type: |
812 block_infos["outputs"].append(("",return_type.getValue(),"none")) |
942 var_type = return_type.getContent() |
|
943 if var_type["value"] is None: |
|
944 block_infos["outputs"].append(("",var_type["name"],"none")) |
|
945 else: |
|
946 block_infos["outputs"].append(("",var_type["value"].getName(),"none")) |
813 if pou.getBodyType() in ["FBD","LD","SFC"]: |
947 if pou.getBodyType() in ["FBD","LD","SFC"]: |
814 for instance in pou.getInstances(): |
948 for instance in pou.getInstances(): |
815 if isinstance(instance, plcopen.comment): |
949 if isinstance(instance, plcopen.comment): |
816 block_infos["comment"] = instance.getContentText() |
950 block_infos["comment"] = instance.getContentText() |
817 BlockTypes[-1]["list"].append(block_infos) |
951 BlockTypes[-1]["list"].append(block_infos) |
818 |
952 |
819 # Return Block types checking for recursion |
953 # Return Block types checking for recursion |
820 def GetBlockTypes(self, tagname = ""): |
954 def GetBlockTypes(self, tagname = ""): |
|
955 name = "" |
|
956 type = None |
821 if self.Project: |
957 if self.Project: |
822 words = tagname.split("::") |
958 words = tagname.split("::") |
823 if len(words) == 1: |
959 if words[0] in ["P","T","A"]: |
824 name = current_name |
|
825 else: |
|
826 name = words[1] |
960 name = words[1] |
827 type = self.GetPouType(name) |
961 type = self.GetPouType(name) |
828 else: |
|
829 name = "" |
|
830 type = None |
|
831 if type == "function": |
962 if type == "function": |
832 blocktypes = [] |
963 blocktypes = [] |
833 for category in BlockTypes[:-1] + PluginTypes: |
964 for category in BlockTypes[:-1] + PluginTypes: |
834 cat = {"name" : category["name"], "list" : []} |
965 cat = {"name" : category["name"], "list" : []} |
835 for block in category["list"]: |
966 for block in category["list"]: |
880 for pou in self.Project.getPous(): |
1008 for pou in self.Project.getPous(): |
881 if pou.pouType.getValue() == "program": |
1009 if pou.pouType.getValue() == "program": |
882 blocktypes.append(pou.getName()) |
1010 blocktypes.append(pou.getName()) |
883 return blocktypes |
1011 return blocktypes |
884 |
1012 |
|
1013 # Return Data Types checking for recursion |
|
1014 def GetDataTypes(self, tagname = "", basetypes = True): |
|
1015 if basetypes: |
|
1016 datatypes = self.GetBaseTypes() |
|
1017 else: |
|
1018 datatypes = [] |
|
1019 if self.Project: |
|
1020 words = tagname.split("::") |
|
1021 if words[0] in ["D"]: |
|
1022 name = words[1] |
|
1023 else: |
|
1024 name = "" |
|
1025 for datatype in self.Project.getDataTypes(): |
|
1026 datatype_name = datatype.getName() |
|
1027 if datatype_name != name and not self.DataTypeIsUsedBy(name, datatype_name): |
|
1028 datatypes.append(datatype_name) |
|
1029 return datatypes |
|
1030 |
|
1031 # Return Base Types |
|
1032 def GetBaseTypes(self): |
|
1033 return [value for value, parent in TypeHierarchy_list if not value.startswith("ANY")] |
|
1034 |
|
1035 # Return Subrange types |
|
1036 def GetSubrangeTypes(self): |
|
1037 return [value for value, range in DataTypeRange_list] |
|
1038 |
|
1039 # Return Enumerated Values |
|
1040 def GetEnumeratedDataValues(self): |
|
1041 return EnumeratedDataValues |
|
1042 |
885 #------------------------------------------------------------------------------- |
1043 #------------------------------------------------------------------------------- |
886 # Project Element tag name computation functions |
1044 # Project Element tag name computation functions |
887 #------------------------------------------------------------------------------- |
1045 #------------------------------------------------------------------------------- |
888 |
1046 |
889 # Compute a pou transition name |
1047 # Compute a data type name |
|
1048 def ComputeDataTypeName(self, datatype): |
|
1049 return "D::%s" % datatype |
|
1050 |
|
1051 # Compute a pou name |
890 def ComputePouName(self, pou): |
1052 def ComputePouName(self, pou): |
891 return "P::%s" % pou |
1053 return "P::%s" % pou |
892 |
1054 |
893 # Compute a pou transition name |
1055 # Compute a pou transition name |
894 def ComputePouTransitionName(self, pou, transition): |
1056 def ComputePouTransitionName(self, pou, transition): |
903 return "C::%s" % config |
1065 return "C::%s" % config |
904 |
1066 |
905 # Compute a pou name |
1067 # Compute a pou name |
906 def ComputeConfigurationResourceName(self, config, resource): |
1068 def ComputeConfigurationResourceName(self, config, resource): |
907 return "R::%s::%s" % (config, resource) |
1069 return "R::%s::%s" % (config, resource) |
|
1070 |
|
1071 #------------------------------------------------------------------------------- |
|
1072 # Project opened Data types management functions |
|
1073 #------------------------------------------------------------------------------- |
|
1074 |
|
1075 # Return the data type informations |
|
1076 def GetDataTypeInfos(self, tagname): |
|
1077 words = tagname.split("::") |
|
1078 if words[0] == "D": |
|
1079 infos = {} |
|
1080 datatype = self.Project.getDataType(words[1]) |
|
1081 basetype_content = datatype.baseType.getContent() |
|
1082 if basetype_content["value"] is None: |
|
1083 infos["type"] = "Directly" |
|
1084 infos["base_type"] = basetype_content["name"] |
|
1085 elif basetype_content["name"] == "derived": |
|
1086 infos["type"] = "Directly" |
|
1087 infos["base_type"] = basetype_content["value"].getName() |
|
1088 elif basetype_content["name"] in ["subrangeSigned", "subrangeUnsigned"]: |
|
1089 infos["type"] = "Subrange" |
|
1090 infos["min"] = basetype_content["value"].range.getLower() |
|
1091 infos["max"] = basetype_content["value"].range.getUpper() |
|
1092 base_type = basetype_content["value"].baseType.getContent() |
|
1093 if base_type["value"] is None: |
|
1094 infos["base_type"] = base_type["name"] |
|
1095 else: |
|
1096 infos["base_type"] = base_type["value"].getName() |
|
1097 elif basetype_content["name"] == "enum": |
|
1098 infos["type"] = "Enumerated" |
|
1099 infos["values"] = [] |
|
1100 for value in basetype_content["value"].values.getValue(): |
|
1101 infos["values"].append(value.getName()) |
|
1102 elif basetype_content["name"] == "array": |
|
1103 infos["type"] = "Array" |
|
1104 infos["dimensions"] = [] |
|
1105 for dimension in basetype_content["value"].getDimension(): |
|
1106 infos["dimensions"].append(str(dimension.getUpper())) |
|
1107 base_type = basetype_content["value"].baseType.getContent() |
|
1108 if base_type["value"] is None: |
|
1109 infos["base_type"] = base_type["name"] |
|
1110 else: |
|
1111 infos["base_type"] = base_type["value"].getName() |
|
1112 if datatype.initialValue is not None: |
|
1113 infos["initial"] = str(datatype.initialValue.getValue()) |
|
1114 else: |
|
1115 infos["initial"] = "" |
|
1116 return infos |
|
1117 return None |
|
1118 |
|
1119 # Change the data type informations |
|
1120 def SetDataTypeInfos(self, tagname, infos): |
|
1121 words = tagname.split("::") |
|
1122 if words[0] == "D": |
|
1123 datatype = self.Project.getDataType(words[1]) |
|
1124 if infos["type"] == "Directly": |
|
1125 if infos["base_type"] in self.GetBaseTypes(): |
|
1126 datatype.baseType.setContent(infos["base_type"], None) |
|
1127 else: |
|
1128 derived_datatype = plcopen.derived() |
|
1129 derived_datatype.setName(infos["base_type"]) |
|
1130 datatype.baseType.setContent("derived", derived_datatype) |
|
1131 elif infos["type"] == "Subrange": |
|
1132 if infos["base_type"] in GetSubTypes("ANY_UINT"): |
|
1133 subrange = plcopen.subrangeUnsigned() |
|
1134 datatype.baseType.setContent("subrangeUnsigned", subrange) |
|
1135 else: |
|
1136 subrange = plcopen.subrangeSigned() |
|
1137 datatype.baseType.setContent("subrangeSigned", subrange) |
|
1138 subrange.range.setLower(infos["min"]) |
|
1139 subrange.range.setUpper(infos["max"]) |
|
1140 if infos["base_type"] in self.GetBaseTypes(): |
|
1141 subrange.baseType.setContent(infos["base_type"], None) |
|
1142 else: |
|
1143 derived_datatype = plcopen.derived() |
|
1144 derived_datatype.setName(infos["base_type"]) |
|
1145 subrange.baseType.setContent("derived", derived_datatype) |
|
1146 elif infos["type"] == "Enumerated": |
|
1147 enumerated = plcopen.enum() |
|
1148 for enum_value in infos["values"]: |
|
1149 value = plcopen.values_value() |
|
1150 value.setName(enum_value) |
|
1151 enumerated.values.appendValue(value) |
|
1152 datatype.baseType.setContent("enum", enumerated) |
|
1153 elif infos["type"] == "Array": |
|
1154 array = plcopen.array() |
|
1155 for dimension in infos["dimensions"]: |
|
1156 dimension_range = plcopen.rangeSigned() |
|
1157 dimension_range.setLower(1) |
|
1158 dimension_range.setUpper(int(dimension)) |
|
1159 array.appendDimension(dimension_range) |
|
1160 if infos["base_type"] in self.GetBaseTypes(): |
|
1161 array.baseType.setContent(infos["base_type"], None) |
|
1162 else: |
|
1163 derived_datatype = plcopen.derived() |
|
1164 derived_datatype.setName(infos["base_type"]) |
|
1165 array.baseType.setContent("derived", derived_datatype) |
|
1166 datatype.baseType.setContent("array", array) |
|
1167 if infos["initial"] != "": |
|
1168 if datatype.initialValue is None: |
|
1169 datatype.initialValue = plcopen.value() |
|
1170 datatype.initialValue.setValue(infos["initial"]) |
|
1171 else: |
|
1172 datatype.initialValue = None |
|
1173 self.RefreshDataTypeUsingTree() |
|
1174 self.RefreshDataTypes() |
|
1175 self.BufferProject() |
908 |
1176 |
909 #------------------------------------------------------------------------------- |
1177 #------------------------------------------------------------------------------- |
910 # Project opened Pous management functions |
1178 # Project opened Pous management functions |
911 #------------------------------------------------------------------------------- |
1179 #------------------------------------------------------------------------------- |
912 |
1180 |
2029 extras = {"xmlns" : "http://www.plcopen.org/xml/tc6.xsd", |
2303 extras = {"xmlns" : "http://www.plcopen.org/xml/tc6.xsd", |
2030 "xmlns:xhtml" : "http://www.w3.org/1999/xhtml", |
2304 "xmlns:xhtml" : "http://www.w3.org/1999/xhtml", |
2031 "xmlns:xsi" : "http://www.w3.org/2001/XMLSchema-instance", |
2305 "xmlns:xsi" : "http://www.w3.org/2001/XMLSchema-instance", |
2032 "xsi:schemaLocation" : "http://www.plcopen.org/xml/tc6.xsd http://www.plcopen.org/xml/tc6.xsd"} |
2306 "xsi:schemaLocation" : "http://www.plcopen.org/xml/tc6.xsd http://www.plcopen.org/xml/tc6.xsd"} |
2033 text += self.Project.generateXMLText("project", 0, extras) |
2307 text += self.Project.generateXMLText("project", 0, extras) |
2034 |
2308 |
2035 if self.VerifyXML: |
2309 if self.VerifyXML: |
2036 if sys: |
2310 if sys: |
2037 sys.stdout = HolePseudoFile() |
2311 sys.stdout = HolePseudoFile() |
2038 pyxsval.parseAndValidateString(text, open(os.path.join(sys.path[0], "plcopen/TC6_XML_V10_B.xsd"),"r").read()) |
2312 pyxsval.parseAndValidateString(text, open(os.path.join(ScriptDirectory, "plcopen", "TC6_XML_V10_B.xsd"),"r").read()) |
2039 if sys: |
2313 if sys: |
2040 sys.stdout = sys.__stdout__ |
2314 sys.stdout = sys.__stdout__ |
2041 |
2315 |
2042 if filepath: |
2316 if filepath: |
2043 xmlfile = open(filepath,"w") |
2317 xmlfile = open(filepath,"w") |