670 body_content = body.getcontent() |
670 body_content = body.getcontent() |
671 body_type = body_content["name"] |
671 body_type = body_content["name"] |
672 if body_type in ["IL","ST"]: |
672 if body_type in ["IL","ST"]: |
673 self.Program = [(ReIndentText(body_content["value"].gettext(), len(self.CurrentIndent)), |
673 self.Program = [(ReIndentText(body_content["value"].gettext(), len(self.CurrentIndent)), |
674 (self.TagName, "body", len(self.CurrentIndent)))] |
674 (self.TagName, "body", len(self.CurrentIndent)))] |
675 elif body_type == "FBD": |
|
676 orderedInstances = [] |
|
677 otherInstances = {"outVariables" : [], "block" : [], "connector" : []} |
|
678 for instance in body.getcontentInstances(): |
|
679 if isinstance(instance, (plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable, plcopen.fbdObjects_block)): |
|
680 executionOrderId = instance.getexecutionOrderId() |
|
681 if executionOrderId > 0: |
|
682 orderedInstances.append((executionOrderId, instance)) |
|
683 elif isinstance(instance, (plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable)): |
|
684 otherInstances["outVariables"].append(instance) |
|
685 elif isinstance(instance, plcopen.fbdObjects_block): |
|
686 otherInstances["block"].append(instance) |
|
687 elif isinstance(instance, plcopen.commonObjects_connector): |
|
688 otherInstances["connector"].append(instance) |
|
689 orderedInstances.sort() |
|
690 instances = [instance for (executionOrderId, instance) in orderedInstances] |
|
691 instances.extend(otherInstances["connector"] + otherInstances["outVariables"] + otherInstances["block"]) |
|
692 for instance in instances: |
|
693 if isinstance(instance, (plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable)): |
|
694 connections = instance.connectionPointIn.getconnections() |
|
695 if connections and len(connections) == 1: |
|
696 expression = self.ComputeFBDExpression(body, connections[0]) |
|
697 self.Program += [(self.CurrentIndent, ()), |
|
698 (instance.getexpression(), (self.TagName, "io_variable", instance.getlocalId(), "expression")), |
|
699 (" := ", ())] |
|
700 self.Program += expression |
|
701 self.Program += [(";\n", ())] |
|
702 elif isinstance(instance, plcopen.fbdObjects_block): |
|
703 block_type = instance.gettypeName() |
|
704 self.ParentGenerator.GeneratePouProgram(block_type) |
|
705 block_infos = self.GetBlockType(block_type) |
|
706 block_infos["generate"](self, instance, body, None) |
|
707 elif isinstance(instance, plcopen.commonObjects_connector): |
|
708 connector = instance.getname() |
|
709 if self.ComputedConnectors.get(connector, None): |
|
710 continue |
|
711 connections = instance.connectionPointIn.getconnections() |
|
712 if connections and len(connections) == 1: |
|
713 self.ComputedConnectors[connector] = self.ComputeFBDExpression(body, connections[0]) |
|
714 elif body_type == "LD": |
|
715 for instance in body.getcontentInstances(): |
|
716 if isinstance(instance, plcopen.ldObjects_coil): |
|
717 expression = self.ComputeLDExpression(body, instance.connectionPointIn.getconnections()) |
|
718 coil_info = (self.TagName, "coil", instance.getlocalId()) |
|
719 variable = self.ExtractModifier(instance, [(instance.getvariable(), coil_info + ("reference",))], coil_info) |
|
720 self.Program += [(self.CurrentIndent, ())] + variable |
|
721 self.Program += [(" := ", ())] + expression + [(";\n", ())] |
|
722 elif body_type == "SFC": |
675 elif body_type == "SFC": |
723 self.IndentRight() |
676 self.IndentRight() |
724 for instance in body.getcontentInstances(): |
677 for instance in body.getcontentInstances(): |
725 if isinstance(instance, plcopen.sfcObjects_step): |
678 if isinstance(instance, plcopen.sfcObjects_step): |
726 self.GenerateSFCStep(instance, pou) |
679 self.GenerateSFCStep(instance, pou) |
737 self.SFCNetworks["Actions"][action_name] = (self.SFCComputedBlocks, ()) |
690 self.SFCNetworks["Actions"][action_name] = (self.SFCComputedBlocks, ()) |
738 self.Program = [] |
691 self.Program = [] |
739 self.IndentLeft() |
692 self.IndentLeft() |
740 for initialstep in self.InitialSteps: |
693 for initialstep in self.InitialSteps: |
741 self.ComputeSFCStep(initialstep) |
694 self.ComputeSFCStep(initialstep) |
|
695 else: |
|
696 orderedInstances = [] |
|
697 otherInstances = {"outVariables" : [], "block" : [], "connector" : [], "coil" : []} |
|
698 for instance in body.getcontentInstances(): |
|
699 if isinstance(instance, (plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable, plcopen.fbdObjects_block)): |
|
700 executionOrderId = instance.getexecutionOrderId() |
|
701 if executionOrderId > 0: |
|
702 orderedInstances.append((executionOrderId, instance)) |
|
703 elif isinstance(instance, (plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable)): |
|
704 otherInstances["outVariables"].append(instance) |
|
705 elif isinstance(instance, plcopen.fbdObjects_block): |
|
706 otherInstances["block"].append(instance) |
|
707 elif isinstance(instance, plcopen.commonObjects_connector): |
|
708 otherInstances["connector"].append(instance) |
|
709 elif isinstance(instance, plcopen.ldObjects_coil): |
|
710 otherInstances["coil"].append(instance) |
|
711 orderedInstances.sort() |
|
712 instances = [instance for (executionOrderId, instance) in orderedInstances] |
|
713 instances.extend(otherInstances["connector"] + otherInstances["outVariables"] + otherInstances["coil"] + otherInstances["block"]) |
|
714 for instance in instances: |
|
715 if isinstance(instance, (plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable)): |
|
716 connections = instance.connectionPointIn.getconnections() |
|
717 if connections is not None: |
|
718 expression = self.ComputeExpression(body, connections) |
|
719 self.Program += [(self.CurrentIndent, ()), |
|
720 (instance.getexpression(), (self.TagName, "io_variable", instance.getlocalId(), "expression")), |
|
721 (" := ", ())] |
|
722 self.Program += expression |
|
723 self.Program += [(";\n", ())] |
|
724 elif isinstance(instance, plcopen.fbdObjects_block): |
|
725 block_type = instance.gettypeName() |
|
726 self.ParentGenerator.GeneratePouProgram(block_type) |
|
727 block_infos = self.GetBlockType(block_type) |
|
728 block_infos["generate"](self, instance, body, None) |
|
729 elif isinstance(instance, plcopen.commonObjects_connector): |
|
730 connector = instance.getname() |
|
731 if self.ComputedConnectors.get(connector, None): |
|
732 continue |
|
733 self.ComputedConnectors[connector] = self.ComputeExpression(body, instance.connectionPointIn.getconnections()) |
|
734 elif isinstance(instance, plcopen.ldObjects_coil): |
|
735 connections = instance.connectionPointIn.getconnections() |
|
736 if connections is not None: |
|
737 expression = self.ComputeExpression(body, connections) |
|
738 coil_info = (self.TagName, "coil", instance.getlocalId()) |
|
739 variable = self.ExtractModifier(instance, [(instance.getvariable(), coil_info + ("reference",))], coil_info) |
|
740 self.Program += [(self.CurrentIndent, ())] + variable |
|
741 self.Program += [(" := ", ())] + expression + [(";\n", ())] |
742 |
742 |
743 def ComputeFBDExpression(self, body, link, order = False): |
743 def FactorizePaths(self, paths): |
744 localid = link.getrefLocalId() |
|
745 instance = body.getcontentInstance(localid) |
|
746 if isinstance(instance, (plcopen.fbdObjects_inVariable, plcopen.fbdObjects_inOutVariable)): |
|
747 return [(instance.getexpression(), (self.TagName, "io_variable", localid, "expression"))] |
|
748 elif isinstance(instance, plcopen.fbdObjects_block): |
|
749 block_type = instance.gettypeName() |
|
750 self.ParentGenerator.GeneratePouProgram(block_type) |
|
751 block_infos = self.GetBlockType(block_type) |
|
752 return block_infos["generate"](self, instance, body, link, order) |
|
753 elif isinstance(instance, plcopen.commonObjects_continuation): |
|
754 name = instance.getname() |
|
755 computed_value = self.ComputedConnectors.get(name, None) |
|
756 if computed_value != None: |
|
757 return computed_value |
|
758 for tmp_instance in body.getcontentInstances(): |
|
759 if isinstance(tmp_instance, plcopen.commonObjects_connector): |
|
760 if tmp_instance.getname() == name: |
|
761 connections = tmp_instance.connectionPointIn.getconnections() |
|
762 if connections and len(connections) == 1: |
|
763 expression = self.ComputeFBDExpression(body, connections[0], order) |
|
764 self.ComputedConnectors[name] = expression |
|
765 return expression |
|
766 raise PLCGenException, "No connector found corresponding to \"%s\" continuation in \"%s\" POU"%(name, self.Name) |
|
767 |
|
768 def FactorizeLDPaths(self, paths): |
|
769 same_paths = {} |
744 same_paths = {} |
770 uncomputed_index = range(len(paths)) |
745 uncomputed_index = range(len(paths)) |
771 factorized_paths = [] |
746 factorized_paths = [] |
772 for num, path in enumerate(paths): |
747 for num, path in enumerate(paths): |
773 if type(path) == ListType: |
748 if type(path) == ListType: |
786 for num in uncomputed_index: |
761 for num in uncomputed_index: |
787 factorized_paths.append(paths[num]) |
762 factorized_paths.append(paths[num]) |
788 factorized_paths.sort() |
763 factorized_paths.sort() |
789 return factorized_paths |
764 return factorized_paths |
790 |
765 |
791 def GenerateLDPaths(self, connections, body): |
766 def GeneratePaths(self, connections, body, order = False): |
792 paths = [] |
767 paths = [] |
793 for connection in connections: |
768 for connection in connections: |
794 localId = connection.getrefLocalId() |
769 localId = connection.getrefLocalId() |
795 next = body.getcontentInstance(localId) |
770 next = body.getcontentInstance(localId) |
796 if isinstance(next, plcopen.ldObjects_leftPowerRail): |
771 if isinstance(next, plcopen.ldObjects_leftPowerRail): |
797 paths.append(None) |
772 paths.append(None) |
|
773 elif isinstance(next, (plcopen.fbdObjects_inVariable, plcopen.fbdObjects_inOutVariable)): |
|
774 paths.append(str([(next.getexpression(), (self.TagName, "io_variable", localId, "expression"))])) |
798 elif isinstance(next, plcopen.fbdObjects_block): |
775 elif isinstance(next, plcopen.fbdObjects_block): |
799 block_type = next.gettypeName() |
776 block_type = next.gettypeName() |
800 self.ParentGenerator.GeneratePouProgram(block_type) |
777 self.ParentGenerator.GeneratePouProgram(block_type) |
801 block_infos = self.GetBlockType(block_type) |
778 block_infos = self.GetBlockType(block_type) |
802 paths.append(str(block_infos["generate"](self, next, body, connection))) |
779 paths.append(str(block_infos["generate"](self, next, body, connection, order))) |
|
780 elif isinstance(next, plcopen.commonObjects_continuation): |
|
781 name = next.getname() |
|
782 computed_value = self.ComputedConnectors.get(name, None) |
|
783 if computed_value != None: |
|
784 paths.append(computed_value) |
|
785 for tmp_instance in body.getcontentInstances(): |
|
786 if isinstance(tmp_instance, plcopen.commonObjects_connector): |
|
787 if tmp_instance.getname() == name: |
|
788 connections = tmp_instance.connectionPointIn.getconnections() |
|
789 if connections is not None: |
|
790 expression = str(self.ComputeExpression(body, connections, order)) |
|
791 self.ComputedConnectors[name] = expression |
|
792 paths.append(expression) |
|
793 raise PLCGenException, "No connector found corresponding to \"%s\" continuation in \"%s\" POU"%(name, self.Name) |
803 else: |
794 else: |
804 contact_info = (self.TagName, "contact", next.getlocalId()) |
795 contact_info = (self.TagName, "contact", next.getlocalId()) |
805 variable = str(self.ExtractModifier(next, [(next.getvariable(), contact_info + ("reference",))], contact_info)) |
796 variable = str(self.ExtractModifier(next, [(next.getvariable(), contact_info + ("reference",))], contact_info)) |
806 result = self.GenerateLDPaths(next.connectionPointIn.getconnections(), body) |
797 result = self.GeneratePaths(next.connectionPointIn.getconnections(), body, order) |
807 if len(result) > 1: |
798 if len(result) > 1: |
808 factorized_paths = self.FactorizeLDPaths(result) |
799 factorized_paths = self.FactorizePaths(result) |
809 if len(factorized_paths) > 1: |
800 if len(factorized_paths) > 1: |
810 paths.append([variable, tuple(factorized_paths)]) |
801 paths.append([variable, tuple(factorized_paths)]) |
811 else: |
802 else: |
812 paths.append([variable] + factorized_paths) |
803 paths.append([variable] + factorized_paths) |
813 elif type(result[0]) == ListType: |
804 elif type(result[0]) == ListType: |
816 paths.append([variable, result[0]]) |
807 paths.append([variable, result[0]]) |
817 else: |
808 else: |
818 paths.append(variable) |
809 paths.append(variable) |
819 return paths |
810 return paths |
820 |
811 |
821 def ComputeLDPaths(self, paths, first = False): |
812 def ComputePaths(self, paths, first = False): |
822 if type(paths) == TupleType: |
813 if type(paths) == TupleType: |
823 if None in paths: |
814 if None in paths: |
824 return [("TRUE", ())] |
815 return [("TRUE", ())] |
825 else: |
816 else: |
826 vars = [self.ComputeLDPaths(path) for path in paths] |
817 vars = [self.ComputePaths(path) for path in paths] |
827 if first: |
818 if first: |
828 return JoinList([(" OR ", ())], vars) |
819 return JoinList([(" OR ", ())], vars) |
829 else: |
820 else: |
830 return [("(", ())] + JoinList([(" OR ", ())], vars) + [(")", ())] |
821 return [("(", ())] + JoinList([(" OR ", ())], vars) + [(")", ())] |
831 elif type(paths) == ListType: |
822 elif type(paths) == ListType: |
832 vars = [self.ComputeLDPaths(path) for path in paths] |
823 vars = [self.ComputePaths(path) for path in paths] |
833 return JoinList([(" AND ", ())], vars) |
824 return JoinList([(" AND ", ())], vars) |
834 else: |
825 else: |
835 return eval(paths) |
826 return eval(paths) |
836 |
827 |
837 def ComputeLDExpression(self, body, connections): |
828 def ComputeExpression(self, body, connections, order = False): |
838 paths = self.GenerateLDPaths(connections, body) |
829 paths = self.GeneratePaths(connections, body, order) |
839 if len(paths) > 1: |
830 if len(paths) > 1: |
840 factorized_paths = self.FactorizeLDPaths(paths) |
831 factorized_paths = self.FactorizePaths(paths) |
841 if len(factorized_paths) > 1: |
832 if len(factorized_paths) > 1: |
842 paths = tuple(factorized_paths) |
833 paths = tuple(factorized_paths) |
843 else: |
834 else: |
844 paths = factorized_paths[0] |
835 paths = factorized_paths[0] |
845 else: |
836 else: |
846 paths = paths[0] |
837 paths = paths[0] |
847 return self.ComputeLDPaths(paths, True) |
838 return self.ComputePaths(paths, True) |
848 |
839 |
849 def ExtractModifier(self, variable, expression, var_info): |
840 def ExtractModifier(self, variable, expression, var_info): |
850 if variable.getnegated(): |
841 if variable.getnegated(): |
851 return [("NOT(", var_info + ("negated",))] + expression + [(")", ())] |
842 return [("NOT(", var_info + ("negated",))] + expression + [(")", ())] |
852 else: |
843 else: |
1023 transition_infos["content"] = [(":\n", ()), |
1014 transition_infos["content"] = [(":\n", ()), |
1024 (ReIndentText(transitionBody.gettext(), len(self.CurrentIndent)), (self.TagName, "body", len(self.CurrentIndent)))] |
1015 (ReIndentText(transitionBody.gettext(), len(self.CurrentIndent)), (self.TagName, "body", len(self.CurrentIndent)))] |
1025 elif transitionType == "ST": |
1016 elif transitionType == "ST": |
1026 transition_infos["content"] = [("\n", ()), |
1017 transition_infos["content"] = [("\n", ()), |
1027 (ReIndentText(transitionBody.gettext(), len(self.CurrentIndent)), (self.TagName, "body", len(self.CurrentIndent)))] |
1018 (ReIndentText(transitionBody.gettext(), len(self.CurrentIndent)), (self.TagName, "body", len(self.CurrentIndent)))] |
1028 elif transitionType == "FBD": |
1019 else: |
1029 for instance in transitionBody.getcontentInstances(): |
1020 for instance in transitionBody.getcontentInstances(): |
1030 if isinstance(instance, plcopen.fbdObjects_outVariable): |
1021 if isinstance(instance, plcopen.fbdObjects_outVariable) and instance.getexpression() == transitionValues["value"]\ |
|
1022 or isinstance(instance, plcopen.ldObjects_coil) and instance.getvariable() == transitionValues["value"]: |
1031 connections = instance.connectionPointIn.getconnections() |
1023 connections = instance.connectionPointIn.getconnections() |
1032 if connections and len(connections) == 1: |
1024 if connections is not None: |
1033 expression = self.ComputeFBDExpression(transitionBody, connections[0]) |
1025 expression = self.ComputeExpression(transitionBody, connections) |
1034 transition_infos["content"] = [("\n%s:= "%self.CurrentIndent, ())] + expression + [(";\n", ())] |
1026 transition_infos["content"] = [("\n%s:= "%self.CurrentIndent, ())] + expression + [(";\n", ())] |
1035 self.SFCComputedBlocks += self.Program |
1027 self.SFCComputedBlocks += self.Program |
1036 self.Program = [] |
1028 self.Program = [] |
1037 elif transitionType == "LD": |
|
1038 for instance in transitionBody.getcontentInstances(): |
|
1039 if isinstance(instance, plcopen.ldObjects_coil): |
|
1040 expression = self.ComputeLDExpression(transitionBody, instance.connectionPointIn.getconnections()) |
|
1041 transition_infos["content"] = [("\n%s:= "%self.CurrentIndent, ())] + expression + [(";\n", ())] |
|
1042 self.SFCComputedBlocks += self.Program |
|
1043 self.Program = [] |
|
1044 self.TagName = previous_tagname |
1029 self.TagName = previous_tagname |
1045 elif transitionValues["type"] == "connection": |
1030 elif transitionValues["type"] == "connection": |
1046 body = pou.getbody() |
1031 body = pou.getbody() |
1047 connections = transition.getconnections() |
1032 connections = transition.getconnections() |
1048 network_type = self.GetNetworkType(connections, body) |
1033 if connections is not None: |
1049 if network_type == None: |
1034 expression = self.ComputeExpression(body, connections) |
1050 raise PLCGenException, "Type of network connected to transition impossible to define in \"%s\" POU"%self.Name |
1035 transition_infos["content"] = [("\n%s:= "%self.CurrentIndent, ())] + expression + [(";\n", ())] |
1051 if len(connections) > 1 or network_type == "LD": |
1036 self.SFCComputedBlocks += self.Program |
1052 expression = self.ComputeLDExpression(body, connections) |
1037 self.Program = [] |
1053 else: |
|
1054 expression = self.ComputeFBDExpression(body, connections[0]) |
|
1055 transition_infos["content"] = [("\n%s:= "%self.CurrentIndent, ())] + expression + [(";\n", ())] |
|
1056 self.SFCComputedBlocks += self.Program |
|
1057 self.Program = [] |
|
1058 for step in steps: |
1038 for step in steps: |
1059 self.GenerateSFCStep(step, pou) |
1039 self.GenerateSFCStep(step, pou) |
1060 step_name = step.getname() |
1040 step_name = step.getname() |
1061 if step_name in self.SFCNetworks["Steps"].keys(): |
1041 if step_name in self.SFCNetworks["Steps"].keys(): |
1062 transition_infos["from"].append([(step_name, (self.TagName, "transition", transition.getlocalId(), "from", step.getlocalId()))]) |
1042 transition_infos["from"].append([(step_name, (self.TagName, "transition", transition.getlocalId(), "from", step.getlocalId()))]) |