486 slave_info.setName(type_infos["device_type"]) |
494 slave_info.setName(type_infos["device_type"]) |
487 slave_info.setVendorId(ExtractHexDecValue(type_infos["vendor"])) |
495 slave_info.setVendorId(ExtractHexDecValue(type_infos["vendor"])) |
488 slave_info.setProductCode(ExtractHexDecValue(type_infos["product_code"])) |
496 slave_info.setProductCode(ExtractHexDecValue(type_infos["product_code"])) |
489 slave_info.setRevisionNo(ExtractHexDecValue(type_infos["revision_number"])) |
497 slave_info.setRevisionNo(ExtractHexDecValue(type_infos["revision_number"])) |
490 setattr(cls, "setType", setType) |
498 setattr(cls, "setType", setType) |
491 |
499 |
492 class _EthercatCTN: |
500 def getInitCmds(self, create_default=False): |
493 XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?> |
501 Mailbox = self.getMailbox() |
|
502 if Mailbox is None: |
|
503 if create_default: |
|
504 self.addMailbox() |
|
505 Mailbox = self.getMailbox() |
|
506 else: |
|
507 return None |
|
508 CoE = Mailbox.getCoE() |
|
509 if CoE is None: |
|
510 if create_default: |
|
511 Mailbox.addCoE() |
|
512 CoE = Mailbox.getCoE() |
|
513 else: |
|
514 return None |
|
515 InitCmds = CoE.getInitCmds() |
|
516 if InitCmds is None and create_default: |
|
517 CoE.addInitCmds() |
|
518 InitCmds = CoE.getInitCmds() |
|
519 return InitCmds |
|
520 setattr(cls, "getInitCmds", getInitCmds) |
|
521 |
|
522 def getStartupCommands(self): |
|
523 pos = self.getInfo().getPhysAddr() |
|
524 InitCmds = self.getInitCmds() |
|
525 if InitCmds is None: |
|
526 return [] |
|
527 commands = [] |
|
528 for idx, InitCmd in enumerate(InitCmds.getInitCmd()): |
|
529 comment = InitCmd.getComment() |
|
530 if comment is None: |
|
531 comment = "" |
|
532 commands.append({ |
|
533 "command_idx": idx, |
|
534 "Position": pos, |
|
535 "Index": InitCmd.getIndex(), |
|
536 "Subindex": InitCmd.getSubIndex(), |
|
537 "Value": InitCmd.getData(), |
|
538 "Description": comment}) |
|
539 commands.sort(sort_commands) |
|
540 return commands |
|
541 setattr(cls, "getStartupCommands", getStartupCommands) |
|
542 |
|
543 def appendStartupCommand(self, command_infos): |
|
544 InitCmds = self.getInitCmds(True) |
|
545 command = EtherCATConfigClasses["InitCmds_InitCmd"]() |
|
546 command.setIndex(command_infos["Index"]) |
|
547 command.setSubIndex(command_infos["Subindex"]) |
|
548 command.setData(command_infos["Value"]) |
|
549 command.setComment(command_infos["Description"]) |
|
550 InitCmds.appendInitCmd(command) |
|
551 return len(InitCmds.getInitCmd()) - 1 |
|
552 setattr(cls, "appendStartupCommand", appendStartupCommand) |
|
553 |
|
554 def setStartupCommand(self, command_infos): |
|
555 InitCmds = self.getInitCmds() |
|
556 if InitCmds is not None: |
|
557 commands = InitCmds.getInitCmd() |
|
558 if command_infos["command_idx"] < len(commands): |
|
559 command = commands[command_infos["command_idx"]] |
|
560 command.setIndex(command_infos["Index"]) |
|
561 command.setSubIndex(command_infos["Subindex"]) |
|
562 command.setData(command_infos["Value"]) |
|
563 command.setComment(command_infos["Description"]) |
|
564 setattr(cls, "setStartupCommand", setStartupCommand) |
|
565 |
|
566 def removeStartupCommand(self, command_idx): |
|
567 InitCmds = self.getInitCmds() |
|
568 if InitCmds is not None: |
|
569 if command_idx < len(InitCmds.getInitCmd()): |
|
570 InitCmds.removeInitCmd(command_idx) |
|
571 setattr(cls, "removeStartupCommand", removeStartupCommand) |
|
572 |
|
573 ProcessVariablesXSD = """<?xml version="1.0" encoding="ISO-8859-1" ?> |
494 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> |
574 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> |
495 <xsd:element name="EtherlabNode"> |
575 <xsd:element name="ProcessVariables"> |
496 <xsd:complexType> |
576 <xsd:complexType> |
497 <xsd:attribute name="MasterNumber" type="xsd:integer" use="optional" default="0"/> |
577 <xsd:sequence> |
|
578 <xsd:element name="variable" minOccurs="0" maxOccurs="unbounded"> |
|
579 <xsd:complexType> |
|
580 <xsd:sequence> |
|
581 <xsd:element name="ReadFrom" type="LocationDesc" minOccurs="0"/> |
|
582 <xsd:element name="WriteTo" type="LocationDesc" minOccurs="0"/> |
|
583 </xsd:sequence> |
|
584 <xsd:attribute name="Name" type="xsd:string" use="required"/> |
|
585 <xsd:attribute name="Comment" type="xsd:string" use="required"/> |
|
586 </xsd:complexType> |
|
587 </xsd:element> |
|
588 </xsd:sequence> |
498 </xsd:complexType> |
589 </xsd:complexType> |
499 </xsd:element> |
590 </xsd:element> |
|
591 <xsd:complexType name="LocationDesc"> |
|
592 <xsd:attribute name="Position" type="xsd:integer" use="required"/> |
|
593 <xsd:attribute name="Index" type="xsd:integer" use="required"/> |
|
594 <xsd:attribute name="SubIndex" type="xsd:integer" use="required"/> |
|
595 </xsd:complexType> |
500 </xsd:schema> |
596 </xsd:schema> |
501 """ |
597 """ |
|
598 |
|
599 ProcessVariablesClasses = GenerateClassesFromXSDstring(ProcessVariablesXSD) |
|
600 |
|
601 class _EthercatCTN: |
502 |
602 |
503 CTNChildrenTypes = [("EthercatSlave", _EthercatSlaveCTN, "Ethercat Slave")] |
603 CTNChildrenTypes = [("EthercatSlave", _EthercatSlaveCTN, "Ethercat Slave")] |
504 if HAS_MCL: |
604 if HAS_MCL: |
505 CTNChildrenTypes.append(("EthercatCIA402Slave", _EthercatCIA402SlaveCTN, "Ethercat CIA402 Slave")) |
605 CTNChildrenTypes.append(("EthercatCIA402Slave", _EthercatCIA402SlaveCTN, "Ethercat CIA402 Slave")) |
|
606 EditorType = MasterEditor |
506 |
607 |
507 def __init__(self): |
608 def __init__(self): |
508 filepath = self.ConfigFileName() |
609 config_filepath = self.ConfigFileName() |
509 |
610 config_is_saved = False |
510 self.Config = EtherCATConfigClasses["EtherCATConfig"]() |
611 self.Config = EtherCATConfigClasses["EtherCATConfig"]() |
511 if os.path.isfile(filepath): |
612 if os.path.isfile(config_filepath): |
512 xmlfile = open(filepath, 'r') |
613 config_xmlfile = open(config_filepath, 'r') |
513 tree = minidom.parse(xmlfile) |
614 config_tree = minidom.parse(config_xmlfile) |
514 xmlfile.close() |
615 config_xmlfile.close() |
515 |
616 |
516 for child in tree.childNodes: |
617 for child in config_tree.childNodes: |
517 if child.nodeType == tree.ELEMENT_NODE and child.nodeName == "EtherCATConfig": |
618 if child.nodeType == config_tree.ELEMENT_NODE and child.nodeName == "EtherCATConfig": |
518 self.Config.loadXMLTree(child) |
619 self.Config.loadXMLTree(child) |
519 self.CreateConfigBuffer(True) |
620 config_is_saved = True |
|
621 |
|
622 process_filepath = self.ProcessVariablesFileName() |
|
623 process_is_saved = False |
|
624 self.ProcessVariables = ProcessVariablesClasses["ProcessVariables"]() |
|
625 if os.path.isfile(process_filepath): |
|
626 process_xmlfile = open(process_filepath, 'r') |
|
627 process_tree = minidom.parse(process_xmlfile) |
|
628 process_xmlfile.close() |
|
629 |
|
630 for child in process_tree.childNodes: |
|
631 if child.nodeType == process_tree.ELEMENT_NODE and child.nodeName == "ProcessVariables": |
|
632 self.ProcessVariables.loadXMLTree(child) |
|
633 process_is_saved = True |
|
634 |
|
635 if config_is_saved and process_is_saved: |
|
636 self.CreateBuffer(True) |
520 else: |
637 else: |
521 self.CreateConfigBuffer(False) |
638 self.CreateBuffer(False) |
522 self.OnCTNSave() |
639 self.OnCTNSave() |
523 |
640 |
524 def ExtractHexDecValue(self, value): |
641 def ExtractHexDecValue(self, value): |
525 return ExtractHexDecValue(value) |
642 return ExtractHexDecValue(value) |
526 |
643 |
527 def GetSizeOfType(self, type): |
644 def GetSizeOfType(self, type): |
528 return TYPECONVERSION.get(self.GetCTRoot().GetBaseType(type), None) |
645 return TYPECONVERSION.get(self.GetCTRoot().GetBaseType(type), None) |
529 |
646 |
530 def ConfigFileName(self): |
647 def ConfigFileName(self): |
531 return os.path.join(self.CTNPath(), "config.xml") |
648 return os.path.join(self.CTNPath(), "config.xml") |
532 |
649 |
|
650 def ProcessVariablesFileName(self): |
|
651 return os.path.join(self.CTNPath(), "process_variables.xml") |
|
652 |
533 def GetSlaves(self): |
653 def GetSlaves(self): |
534 slaves = [] |
654 slaves = [] |
535 for slave in self.Config.getConfig().getSlave(): |
655 for slave in self.Config.getConfig().getSlave(): |
536 slaves.append(slave.getInfo().getPhysAddr()) |
656 slaves.append(slave.getInfo().getPhysAddr()) |
537 slaves.sort() |
657 slaves.sort() |
542 slave_info = slave.getInfo() |
662 slave_info = slave.getInfo() |
543 if slave_info.getPhysAddr() == slave_pos: |
663 if slave_info.getPhysAddr() == slave_pos: |
544 return slave |
664 return slave |
545 return None |
665 return None |
546 |
666 |
|
667 def FilterSlave(self, slave, vendor=None, slave_pos=None, slave_profile=None): |
|
668 if slave_pos is not None and slave.getInfo().getPhysAddr() != slave_pos: |
|
669 return False |
|
670 type_infos = slave.getType() |
|
671 if vendor is not None and ExtractHexDecValue(type_infos["vendor"]) != vendor: |
|
672 return False |
|
673 device, alignment = self.GetModuleInfos(type_infos) |
|
674 if slave_profile is not None and slave_profile not in device.GetProfileNumbers(): |
|
675 return False |
|
676 return True |
|
677 |
|
678 def GetStartupCommands(self, vendor=None, slave_pos=None, slave_profile=None): |
|
679 commands = [] |
|
680 for slave in self.Config.getConfig().getSlave(): |
|
681 if self.FilterSlave(slave, vendor, slave_pos, slave_profile): |
|
682 commands.append((slave.getInfo().getPhysAddr(), slave.getStartupCommands())) |
|
683 commands.sort() |
|
684 return reduce(lambda x, y: x + y[1], commands, []) |
|
685 |
|
686 def AppendStartupCommand(self, command_infos): |
|
687 slave = self.GetSlave(command_infos["Position"]) |
|
688 if slave is not None: |
|
689 command_idx = slave.appendStartupCommand(command_infos) |
|
690 self.BufferModel() |
|
691 return command_idx |
|
692 return None |
|
693 |
|
694 def SetStartupCommandInfos(self, command_infos): |
|
695 slave = self.GetSlave(command_infos["Position"]) |
|
696 if slave is not None: |
|
697 slave.setStartupCommand(command_infos) |
|
698 self.BufferModel() |
|
699 |
|
700 def RemoveStartupCommand(self, slave_pos, command_idx): |
|
701 slave = self.GetSlave(slave_pos) |
|
702 if slave is not None: |
|
703 slave.removeStartupCommand(command_idx) |
|
704 self.BufferModel() |
|
705 |
|
706 def SetProcessVariables(self, variables): |
|
707 vars = [] |
|
708 for var in variables: |
|
709 variable = ProcessVariablesClasses["ProcessVariables_variable"]() |
|
710 variable.setName(var["Name"]) |
|
711 variable.setComment(var["Description"]) |
|
712 if var["ReadFrom"] != "": |
|
713 position, index, subindex = var["ReadFrom"] |
|
714 if variable.getReadFrom() is None: |
|
715 variable.addReadFrom() |
|
716 read_from = variable.getReadFrom() |
|
717 read_from.setPosition(position) |
|
718 read_from.setIndex(index) |
|
719 read_from.setSubIndex(subindex) |
|
720 elif variable.getReadFrom() is not None: |
|
721 variable.deleteReadFrom() |
|
722 if var["WriteTo"] != "": |
|
723 position, index, subindex = var["WriteTo"] |
|
724 if variable.getWriteTo() is None: |
|
725 variable.addWriteTo() |
|
726 write_to = variable.getWriteTo() |
|
727 write_to.setPosition(position) |
|
728 write_to.setIndex(index) |
|
729 write_to.setSubIndex(subindex) |
|
730 elif variable.getWriteTo() is not None: |
|
731 variable.deleteWriteTo() |
|
732 vars.append(variable) |
|
733 self.ProcessVariables.setvariable(vars) |
|
734 self.BufferModel() |
|
735 |
|
736 def GetProcessVariables(self): |
|
737 variables = [] |
|
738 for variable in self.ProcessVariables.getvariable(): |
|
739 var = {"Name": variable.getName(), |
|
740 "Description": variable.getComment()} |
|
741 read_from = variable.getReadFrom() |
|
742 if read_from is not None: |
|
743 var["ReadFrom"] = (read_from.getPosition(), |
|
744 read_from.getIndex(), |
|
745 read_from.getSubIndex()) |
|
746 else: |
|
747 var["ReadFrom"] = "" |
|
748 write_to = variable.getWriteTo() |
|
749 if write_to is not None: |
|
750 var["WriteTo"] = (write_to.getPosition(), |
|
751 write_to.getIndex(), |
|
752 write_to.getSubIndex()) |
|
753 else: |
|
754 var["WriteTo"] = "" |
|
755 variables.append(var) |
|
756 return variables |
|
757 |
547 def _ScanNetwork(self): |
758 def _ScanNetwork(self): |
548 app_frame = self.GetCTRoot().AppFrame |
759 app_frame = self.GetCTRoot().AppFrame |
549 |
760 |
550 execute = True |
761 execute = True |
551 if len(self.Children) > 0: |
762 if len(self.Children) > 0: |
609 config = self.Config.getConfig() |
820 config = self.Config.getConfig() |
610 for idx, slave in enumerate(config.getSlave()): |
821 for idx, slave in enumerate(config.getSlave()): |
611 slave_infos = slave.getInfo() |
822 slave_infos = slave.getInfo() |
612 if slave_infos.getPhysAddr() == slave_pos: |
823 if slave_infos.getPhysAddr() == slave_pos: |
613 config.removeSlave(idx) |
824 config.removeSlave(idx) |
614 self.BufferConfig() |
825 self.BufferModel() |
615 self.OnCTNSave() |
826 self.OnCTNSave() |
616 ConfigTreeNode._doRemoveChild(self, CTNInstance) |
827 ConfigTreeNode._doRemoveChild(self, CTNInstance) |
617 |
828 |
618 def SetSlavePosition(self, slave_pos, new_pos): |
829 def SetSlavePosition(self, slave_pos, new_pos): |
619 slave = self.GetSlave(slave_pos) |
830 slave = self.GetSlave(slave_pos) |
620 if slave is not None: |
831 if slave is not None: |
621 slave_info = slave.getInfo() |
832 slave_info = slave.getInfo() |
622 slave_info.setPhysAddr(new_pos) |
833 slave_info.setPhysAddr(new_pos) |
623 self.BufferConfig() |
834 self.BufferModel() |
624 |
835 |
625 def GetSlaveAlias(self, slave_pos): |
836 def GetSlaveAlias(self, slave_pos): |
626 slave = self.GetSlave(slave_pos) |
837 slave = self.GetSlave(slave_pos) |
627 if slave is not None: |
838 if slave is not None: |
628 slave_info = slave.getInfo() |
839 slave_info = slave.getInfo() |
644 |
855 |
645 def SetSlaveType(self, slave_pos, type_infos): |
856 def SetSlaveType(self, slave_pos, type_infos): |
646 slave = self.GetSlave(slave_pos) |
857 slave = self.GetSlave(slave_pos) |
647 if slave is not None: |
858 if slave is not None: |
648 slave.setType(type_infos) |
859 slave.setType(type_infos) |
649 self.BufferConfig() |
860 self.BufferModel() |
650 |
861 |
651 def GetSlaveInfos(self, slave_pos): |
862 def GetSlaveInfos(self, slave_pos): |
652 slave = self.GetSlave(slave_pos) |
863 slave = self.GetSlave(slave_pos) |
653 if slave is not None: |
864 if slave is not None: |
654 type_infos = slave.getType() |
865 type_infos = slave.getType() |
655 device, alignement = self.GetModuleInfos(type_infos) |
866 device, alignment = self.GetModuleInfos(type_infos) |
656 if device is not None: |
867 if device is not None: |
657 infos = type_infos.copy() |
868 infos = type_infos.copy() |
658 entries = device.GetEntriesList() |
|
659 entries_list = entries.items() |
|
660 entries_list.sort() |
|
661 entries = [] |
|
662 current_index = None |
|
663 current_entry = None |
|
664 for (index, subindex), entry in entries_list: |
|
665 entry["children"] = [] |
|
666 if index != current_index: |
|
667 current_index = index |
|
668 current_entry = entry |
|
669 entries.append(entry) |
|
670 elif current_entry is not None: |
|
671 current_entry["children"].append(entry) |
|
672 else: |
|
673 entries.append(entry) |
|
674 infos.update({"physics": device.getPhysics(), |
869 infos.update({"physics": device.getPhysics(), |
675 "sync_managers": device.GetSyncManagers(), |
870 "sync_managers": device.GetSyncManagers(), |
676 "entries": entries}) |
871 "entries": self.GetSlaveVariables(device)}) |
677 return infos |
872 return infos |
678 return None |
873 return None |
679 |
874 |
|
875 def GetSlaveVariables(self, slave_pos=None, limits=None, device=None): |
|
876 if device is None and slave_pos is not None: |
|
877 slave = self.GetSlave(slave_pos) |
|
878 if slave is not None: |
|
879 type_infos = slave.getType() |
|
880 device, alignment = self.GetModuleInfos(type_infos) |
|
881 if device is not None: |
|
882 entries = device.GetEntriesList(limits) |
|
883 entries_list = entries.items() |
|
884 entries_list.sort() |
|
885 entries = [] |
|
886 current_index = None |
|
887 current_entry = None |
|
888 for (index, subindex), entry in entries_list: |
|
889 entry["children"] = [] |
|
890 if slave_pos is not None: |
|
891 entry["Position"] = str(slave_pos) |
|
892 entry |
|
893 if index != current_index: |
|
894 current_index = index |
|
895 current_entry = entry |
|
896 entries.append(entry) |
|
897 elif current_entry is not None: |
|
898 current_entry["children"].append(entry) |
|
899 else: |
|
900 entries.append(entry) |
|
901 return entries |
|
902 return [] |
|
903 |
|
904 def GetNodesVariables(self, vendor=None, slave_pos=None, slave_profile=None, limits=None): |
|
905 entries = [] |
|
906 for slave_position in self.GetSlaves(): |
|
907 if slave_pos is not None and slave_position != slave_pos: |
|
908 continue |
|
909 slave = self.GetSlave(slave_position) |
|
910 type_infos = slave.getType() |
|
911 if vendor is not None and ExtractHexDecValue(type_infos["vendor"]) != vendor: |
|
912 continue |
|
913 device, alignment = self.GetModuleInfos(type_infos) |
|
914 if slave_profile is not None and slave_profile not in device.GetProfileNumbers(): |
|
915 continue |
|
916 entries.extend(self.GetSlaveVariables(slave_position, limits, device)) |
|
917 return entries |
|
918 |
680 def GetModuleInfos(self, type_infos): |
919 def GetModuleInfos(self, type_infos): |
681 return self.CTNParent.GetModuleInfos(type_infos) |
920 return self.CTNParent.GetModuleInfos(type_infos) |
682 |
921 |
683 def GetSlaveTypesLibrary(self, profile_filter=None): |
922 def GetSlaveTypesLibrary(self, profile_filter=None): |
684 return self.CTNParent.GetModulesLibrary(profile_filter) |
923 return self.CTNParent.GetModulesLibrary(profile_filter) |
|
924 |
|
925 def GetLibraryVendors(self): |
|
926 return self.CTNParent.GetVendors() |
685 |
927 |
686 def GetDeviceLocationTree(self, slave_pos, current_location, device_name): |
928 def GetDeviceLocationTree(self, slave_pos, current_location, device_name): |
687 slave = self.GetSlave(slave_pos) |
929 slave = self.GetSlave(slave_pos) |
688 vars = [] |
930 vars = [] |
689 if slave is not None: |
931 if slave is not None: |
690 type_infos = slave.getType() |
932 type_infos = slave.getType() |
691 |
933 |
692 device, alignement = self.GetModuleInfos(type_infos) |
934 device, alignment = self.GetModuleInfos(type_infos) |
693 if device is not None: |
935 if device is not None: |
694 sync_managers = [] |
936 sync_managers = [] |
695 for sync_manager in device.getSm(): |
937 for sync_manager in device.getSm(): |
696 sync_manager_control_byte = ExtractHexDecValue(sync_manager.getControlByte()) |
938 sync_manager_control_byte = ExtractHexDecValue(sync_manager.getControlByte()) |
697 sync_manager_direction = sync_manager_control_byte & 0x0c |
939 sync_manager_direction = sync_manager_control_byte & 0x0c |
723 "children": []}) |
965 "children": []}) |
724 |
966 |
725 return vars |
967 return vars |
726 |
968 |
727 def CTNTestModified(self): |
969 def CTNTestModified(self): |
728 return self.ChangesToSave or not self.ConfigIsSaved() |
970 return self.ChangesToSave or not self.ModelIsSaved() |
729 |
971 |
730 def OnCTNSave(self): |
972 def OnCTNSave(self): |
731 filepath = self.ConfigFileName() |
973 config_filepath = self.ConfigFileName() |
732 |
974 |
733 text = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" |
975 config_text = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" |
734 extras = {"xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance", |
976 config_extras = {"xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance", |
735 "xsi:noNamespaceSchemaLocation" : "EtherCATInfo.xsd"} |
977 "xsi:noNamespaceSchemaLocation" : "EtherCATInfo.xsd"} |
736 text += self.Config.generateXMLText("EtherCATConfig", 0, extras) |
978 config_text += self.Config.generateXMLText("EtherCATConfig", 0, config_extras) |
737 |
979 |
738 xmlfile = open(filepath,"w") |
980 config_xmlfile = open(config_filepath,"w") |
739 xmlfile.write(text.encode("utf-8")) |
981 config_xmlfile.write(config_text.encode("utf-8")) |
740 xmlfile.close() |
982 config_xmlfile.close() |
741 |
983 |
742 self.ConfigBuffer.CurrentSaved() |
984 process_filepath = self.ProcessVariablesFileName() |
|
985 |
|
986 process_text = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" |
|
987 process_extras = {"xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance"} |
|
988 process_text += self.ProcessVariables.generateXMLText("ProcessVariables", 0, process_extras) |
|
989 |
|
990 process_xmlfile = open(process_filepath,"w") |
|
991 process_xmlfile.write(process_text.encode("utf-8")) |
|
992 process_xmlfile.close() |
|
993 |
|
994 self.Buffer.CurrentSaved() |
743 return True |
995 return True |
744 |
996 |
745 def _Generate_C(self, buildpath, locations): |
997 def _Generate_C(self, buildpath, locations): |
746 current_location = self.GetCurrentLocation() |
998 current_location = self.GetCurrentLocation() |
747 # define a unique name for the generated C file |
999 # define a unique name for the generated C file |
808 Return a copy of the config |
1060 Return a copy of the config |
809 """ |
1061 """ |
810 def Copy(self, model): |
1062 def Copy(self, model): |
811 return cPickle.loads(cPickle.dumps(model)) |
1063 return cPickle.loads(cPickle.dumps(model)) |
812 |
1064 |
813 def CreateConfigBuffer(self, saved): |
1065 def CreateBuffer(self, saved): |
814 self.ConfigBuffer = UndoBuffer(cPickle.dumps(self.Config), saved) |
1066 self.Buffer = UndoBuffer(cPickle.dumps((self.Config, self.ProcessVariables)), saved) |
815 |
1067 |
816 def BufferConfig(self): |
1068 def BufferModel(self): |
817 self.ConfigBuffer.Buffering(cPickle.dumps(self.Config)) |
1069 self.Buffer.Buffering(cPickle.dumps((self.Config, self.ProcessVariables))) |
818 |
1070 |
819 def ConfigIsSaved(self): |
1071 def ModelIsSaved(self): |
820 if self.ConfigBuffer is not None: |
1072 if self.Buffer is not None: |
821 return self.ConfigBuffer.IsCurrentSaved() |
1073 return self.Buffer.IsCurrentSaved() |
822 else: |
1074 else: |
823 return True |
1075 return True |
824 |
1076 |
825 def LoadPrevious(self): |
1077 def LoadPrevious(self): |
826 self.Config = cPickle.loads(self.ConfigBuffer.Previous()) |
1078 self.Config, self.ProcessVariables = cPickle.loads(self.Buffer.Previous()) |
827 |
1079 |
828 def LoadNext(self): |
1080 def LoadNext(self): |
829 self.Config = cPickle.loads(self.ConfigBuffer.Next()) |
1081 self.Config, self.ProcessVariables = cPickle.loads(self.Buffer.Next()) |
830 |
1082 |
831 def GetBufferState(self): |
1083 def GetBufferState(self): |
832 first = self.ConfigBuffer.IsFirst() |
1084 first = self.Buffer.IsFirst() |
833 last = self.ConfigBuffer.IsLast() |
1085 last = self.Buffer.IsLast() |
834 return not first, not last |
1086 return not first, not last |
835 |
1087 |
836 |
1088 |
837 SLAVE_PDOS_CONFIGURATION_DECLARATION = """ |
1089 SLAVE_PDOS_CONFIGURATION_DECLARATION = """ |
838 /* Slave %(slave)d, "%(device_type)s" |
1090 /* Slave %(slave)d, "%(device_type)s" |
1441 dictionary.load() |
1694 dictionary.load() |
1442 |
1695 |
1443 for object in dictionary.getObjects().getObject(): |
1696 for object in dictionary.getObjects().getObject(): |
1444 entry_index = object.getIndex().getcontent() |
1697 entry_index = object.getIndex().getcontent() |
1445 index = ExtractHexDecValue(entry_index) |
1698 index = ExtractHexDecValue(entry_index) |
1446 entry_type = object.getType() |
1699 if limits is None or limits[0] <= index <= limits[1]: |
1447 entry_name = ExtractName(object.getName()) |
1700 entry_type = object.getType() |
1448 |
1701 entry_name = ExtractName(object.getName()) |
1449 entry_type_infos = self.DataTypes.get(entry_type, None) |
1702 |
1450 if entry_type_infos is not None: |
1703 entry_type_infos = self.DataTypes.get(entry_type, None) |
1451 content = entry_type_infos.getcontent() |
1704 if entry_type_infos is not None: |
1452 for subitem in content["value"]: |
1705 content = entry_type_infos.getcontent() |
1453 entry_subidx = subitem.getSubIdx() |
1706 for subitem in content["value"]: |
1454 if entry_subidx is None: |
1707 entry_subidx = subitem.getSubIdx() |
1455 entry_subidx = "0" |
1708 if entry_subidx is None: |
1456 subidx = ExtractHexDecValue(entry_subidx) |
1709 entry_subidx = "0" |
1457 subitem_access = "" |
1710 subidx = ExtractHexDecValue(entry_subidx) |
1458 subitem_pdomapping = "" |
1711 subitem_access = "" |
1459 subitem_flags = subitem.getFlags() |
1712 subitem_pdomapping = "" |
1460 if subitem_flags is not None: |
1713 subitem_flags = subitem.getFlags() |
1461 access = subitem_flags.getAccess() |
1714 if subitem_flags is not None: |
|
1715 access = subitem_flags.getAccess() |
|
1716 if access is not None: |
|
1717 subitem_access = access.getcontent() |
|
1718 pdomapping = subitem_flags.getPdoMapping() |
|
1719 if pdomapping is not None: |
|
1720 subitem_pdomapping = pdomapping.upper() |
|
1721 entries[(index, subidx)] = { |
|
1722 "Index": entry_index, |
|
1723 "SubIndex": entry_subidx, |
|
1724 "Name": "%s - %s" % |
|
1725 (entry_name.decode("utf-8"), |
|
1726 ExtractName(subitem.getDisplayName(), |
|
1727 subitem.getName()).decode("utf-8")), |
|
1728 "Type": subitem.getType(), |
|
1729 "BitSize": subitem.getBitSize(), |
|
1730 "Access": subitem_access, |
|
1731 "PDOMapping": subitem_pdomapping} |
|
1732 else: |
|
1733 entry_access = "" |
|
1734 entry_pdomapping = "" |
|
1735 entry_flags = object.getFlags() |
|
1736 if entry_flags is not None: |
|
1737 access = entry_flags.getAccess() |
1462 if access is not None: |
1738 if access is not None: |
1463 subitem_access = access.getcontent() |
1739 entry_access = access.getcontent() |
1464 pdomapping = subitem_flags.getPdoMapping() |
1740 pdomapping = entry_flags.getPdoMapping() |
1465 if pdomapping is not None: |
1741 if pdomapping is not None: |
1466 subitem_pdomapping = pdomapping.upper() |
1742 entry_pdomapping = pdomapping.upper() |
1467 entries[(index, subidx)] = { |
1743 entries[(index, 0)] = { |
1468 "Index": entry_index, |
1744 "Index": entry_index, |
1469 "SubIndex": entry_subidx, |
1745 "SubIndex": "0", |
1470 "Name": "%s - %s" % |
1746 "Name": entry_name, |
1471 (entry_name.decode("utf-8"), |
1747 "Type": entry_type, |
1472 ExtractName(subitem.getDisplayName(), |
1748 "BitSize": object.getBitSize(), |
1473 subitem.getName()).decode("utf-8")), |
1749 "Access": entry_access, |
1474 "Type": subitem.getType(), |
1750 "PDOMapping": entry_pdomapping} |
1475 "BitSize": subitem.getBitSize(), |
|
1476 "Access": subitem_access, |
|
1477 "PDOMapping": subitem_pdomapping} |
|
1478 else: |
|
1479 entry_access = "" |
|
1480 entry_pdomapping = "" |
|
1481 entry_flags = object.getFlags() |
|
1482 if entry_flags is not None: |
|
1483 access = entry_flags.getAccess() |
|
1484 if access is not None: |
|
1485 entry_access = access.getcontent() |
|
1486 pdomapping = entry_flags.getPdoMapping() |
|
1487 if pdomapping is not None: |
|
1488 entry_pdomapping = pdomapping.upper() |
|
1489 entries[(index, 0)] = { |
|
1490 "Index": entry_index, |
|
1491 "SubIndex": "0", |
|
1492 "Name": entry_name, |
|
1493 "Type": entry_type, |
|
1494 "BitSize": object.getBitSize(), |
|
1495 "Access": entry_access, |
|
1496 "PDOMapping": entry_pdomapping} |
|
1497 |
1751 |
1498 for TxPdo in self.getTxPdo(): |
1752 for TxPdo in self.getTxPdo(): |
1499 ExtractPdoInfos(TxPdo, "Transmit", entries) |
1753 ExtractPdoInfos(TxPdo, "Transmit", entries, limits) |
1500 for RxPdo in self.getRxPdo(): |
1754 for RxPdo in self.getRxPdo(): |
1501 ExtractPdoInfos(RxPdo, "Receive", entries) |
1755 ExtractPdoInfos(RxPdo, "Receive", entries, limits) |
1502 |
1756 |
1503 return entries |
1757 return entries |
1504 setattr(cls, "GetEntriesList", GetEntriesList) |
1758 setattr(cls, "GetEntriesList", GetEntriesList) |
1505 |
1759 |
1506 def GetSyncManagers(self): |
1760 def GetSyncManagers(self): |
1542 for name in names: |
1796 for name in names: |
1543 if name.getLcId() == 1033: |
1797 if name.getLcId() == 1033: |
1544 return name.getcontent() |
1798 return name.getcontent() |
1545 return default |
1799 return default |
1546 |
1800 |
1547 def ExtractPdoInfos(pdo, pdo_type, entries): |
1801 def ExtractPdoInfos(pdo, pdo_type, entries, limits=None): |
1548 pdo_index = pdo.getIndex().getcontent() |
1802 pdo_index = pdo.getIndex().getcontent() |
1549 pdo_name = ExtractName(pdo.getName()) |
1803 pdo_name = ExtractName(pdo.getName()) |
1550 for pdo_entry in pdo.getEntry(): |
1804 for pdo_entry in pdo.getEntry(): |
1551 entry_index = pdo_entry.getIndex().getcontent() |
1805 entry_index = pdo_entry.getIndex().getcontent() |
1552 entry_subindex = pdo_entry.getSubIndex() |
1806 entry_subindex = pdo_entry.getSubIndex() |
1553 index = ExtractHexDecValue(entry_index) |
1807 index = ExtractHexDecValue(entry_index) |
1554 subindex = ExtractHexDecValue(entry_subindex) |
1808 subindex = ExtractHexDecValue(entry_subindex) |
1555 |
1809 |
1556 entry = entries.get((index, subindex), None) |
1810 if limits is None or limits[0] <= index <= limits[1]: |
1557 if entry is not None: |
1811 entry = entries.get((index, subindex), None) |
1558 entry["PDO index"] = pdo_index |
1812 if entry is not None: |
1559 entry["PDO name"] = pdo_name |
1813 entry["PDO index"] = pdo_index |
1560 entry["PDO type"] = pdo_type |
1814 entry["PDO name"] = pdo_name |
1561 else: |
1815 entry["PDO type"] = pdo_type |
1562 entry_type = pdo_entry.getDataType() |
1816 else: |
1563 if entry_type is not None: |
1817 entry_type = pdo_entry.getDataType() |
1564 if pdo_type == "Transmit": |
1818 if entry_type is not None: |
1565 access = "ro" |
1819 if pdo_type == "Transmit": |
1566 pdomapping = "T" |
1820 access = "ro" |
1567 else: |
1821 pdomapping = "T" |
1568 access = "wo" |
1822 else: |
1569 pdomapping = "R" |
1823 access = "wo" |
1570 entries[(index, subindex)] = { |
1824 pdomapping = "R" |
1571 "Index": entry_index, |
1825 entries[(index, subindex)] = { |
1572 "SubIndex": entry_subindex, |
1826 "Index": entry_index, |
1573 "Name": ExtractName(pdo_entry.getName()), |
1827 "SubIndex": entry_subindex, |
1574 "Type": entry_type.getcontent(), |
1828 "Name": ExtractName(pdo_entry.getName()), |
1575 "Access": access, |
1829 "Type": entry_type.getcontent(), |
1576 "PDOMapping": pdomapping} |
1830 "Access": access, |
|
1831 "PDOMapping": pdomapping} |
1577 |
1832 |
1578 DEFAULT_ALIGNMENT = 8 |
1833 DEFAULT_ALIGNMENT = 8 |
1579 |
1834 |
1580 class ModulesLibrary: |
1835 class ModulesLibrary: |
1581 |
1836 |