PLCGenerator.py
changeset 242 5b3e1c4569e6
parent 232 cbdfef9b2020
child 244 05f6e0d7710c
equal deleted inserted replaced
241:64e584348a5b 242:5b3e1c4569e6
   712                     if connections and len(connections) == 1:
   712                     if connections and len(connections) == 1:
   713                         self.ComputedConnectors[connector] = self.ComputeFBDExpression(body, connections[0])
   713                         self.ComputedConnectors[connector] = self.ComputeFBDExpression(body, connections[0])
   714         elif body_type == "LD":
   714         elif body_type == "LD":
   715             for instance in body.getcontentInstances():
   715             for instance in body.getcontentInstances():
   716                 if isinstance(instance, plcopen.ldObjects_coil):
   716                 if isinstance(instance, plcopen.ldObjects_coil):
   717                     paths = self.GenerateLDPaths(instance.connectionPointIn.getconnections(), body)
   717                     expression = self.ComputeLDExpression(body, instance.connectionPointIn.getconnections())
   718                     if len(paths) > 0:
       
   719                         paths = tuple(paths)
       
   720                     else:
       
   721                         paths = paths[0]
       
   722                     coil_info = (self.TagName, "coil", instance.getlocalId())
   718                     coil_info = (self.TagName, "coil", instance.getlocalId())
   723                     variable = self.ExtractModifier(instance, [(instance.getvariable(), coil_info + ("reference",))], coil_info)
   719                     variable = self.ExtractModifier(instance, [(instance.getvariable(), coil_info + ("reference",))], coil_info)
   724                     expression = self.ComputeLDExpression(paths, True)
       
   725                     self.Program += [(self.CurrentIndent, ())] + variable
   720                     self.Program += [(self.CurrentIndent, ())] + variable
   726                     self.Program += [(" := ", ())] + expression + [(";\n", ())]
   721                     self.Program += [(" := ", ())] + expression + [(";\n", ())]
   727         elif body_type == "SFC":
   722         elif body_type == "SFC":
   728             self.IndentRight()
   723             self.IndentRight()
   729             for instance in body.getcontentInstances():
   724             for instance in body.getcontentInstances():
   768                             expression = self.ComputeFBDExpression(body, connections[0], order)
   763                             expression = self.ComputeFBDExpression(body, connections[0], order)
   769                             self.ComputedConnectors[name] = expression
   764                             self.ComputedConnectors[name] = expression
   770                             return expression
   765                             return expression
   771             raise PLCGenException, "No connector found corresponding to \"%s\" continuation in \"%s\" POU"%(name, self.Name)
   766             raise PLCGenException, "No connector found corresponding to \"%s\" continuation in \"%s\" POU"%(name, self.Name)
   772 
   767 
       
   768     def FactorizeLDPaths(self, paths):
       
   769         same_paths = {}
       
   770         uncomputed_index = range(len(paths))
       
   771         factorized_paths = []
       
   772         for num, path in enumerate(paths):
       
   773             if type(path) == ListType:
       
   774                 for i in xrange(1, len(path)):
       
   775                     str_path = str(path[i:])
       
   776                     same_paths.setdefault(str_path, [])
       
   777                     same_paths[str_path].append((path[:i], num))
       
   778             else:
       
   779                 factorized_paths.append(path)
       
   780                 uncomputed_index.remove(num)
       
   781         for same_path, elements in same_paths.items():
       
   782             if len(elements) > 1:
       
   783                 factorized_paths.append([tuple([path for path, num in elements])] + eval(same_path))        
       
   784                 for path, num in elements:
       
   785                     uncomputed_index.remove(num)
       
   786         for num in uncomputed_index:
       
   787             factorized_paths.append(paths[num])
       
   788         return factorized_paths
       
   789 
   773     def GenerateLDPaths(self, connections, body):
   790     def GenerateLDPaths(self, connections, body):
   774         paths = []
   791         paths = []
   775         for connection in connections:
   792         for connection in connections:
   776             localId = connection.getrefLocalId()
   793             localId = connection.getrefLocalId()
   777             next = body.getcontentInstance(localId)
   794             next = body.getcontentInstance(localId)
   785             else:
   802             else:
   786                 contact_info = (self.TagName, "contact", next.getlocalId())
   803                 contact_info = (self.TagName, "contact", next.getlocalId())
   787                 variable = str(self.ExtractModifier(next, [(next.getvariable(), contact_info + ("reference",))], contact_info))
   804                 variable = str(self.ExtractModifier(next, [(next.getvariable(), contact_info + ("reference",))], contact_info))
   788                 result = self.GenerateLDPaths(next.connectionPointIn.getconnections(), body)
   805                 result = self.GenerateLDPaths(next.connectionPointIn.getconnections(), body)
   789                 if len(result) > 1:
   806                 if len(result) > 1:
   790                     paths.append([variable, tuple(result)])
   807                     factorized_paths = self.FactorizeLDPaths(result)
       
   808                     if len(factorized_paths) > 1:
       
   809                         paths.append([variable, tuple(factorized_paths)])
       
   810                     else:
       
   811                         paths.append([variable] + factorized_paths)
   791                 elif type(result[0]) == ListType:
   812                 elif type(result[0]) == ListType:
   792                     paths.append([variable] + result[0])
   813                     paths.append([variable] + result[0])
   793                 elif result[0]:
   814                 elif result[0] is not None:
   794                     paths.append([variable, result[0]])
   815                     paths.append([variable, result[0]])
   795                 else:
   816                 else:
   796                     paths.append(variable)
   817                     paths.append(variable)
   797         return paths
   818         return paths
   798 
   819 
   799     def ComputeLDExpression(self, paths, first = False):
   820     def ComputeLDPaths(self, paths, first = False):
   800         if type(paths) == TupleType:
   821         if type(paths) == TupleType:
   801             if None in paths:
   822             if None in paths:
   802                 return [("TRUE", ())]
   823                 return [("TRUE", ())]
   803             else:
   824             else:
   804                 vars = [self.ComputeLDExpression(path) for path in paths]
   825                 vars = [self.ComputeLDPaths(path) for path in paths]
   805                 if first:
   826                 if first:
   806                     return JoinList([(" OR ", ())], vars)
   827                     return JoinList([(" OR ", ())], vars)
   807                 else:
   828                 else:
   808                     return [("(", ())] + JoinList([(" OR ", ())], vars) + [(")", ())]
   829                     return [("(", ())] + JoinList([(" OR ", ())], vars) + [(")", ())]
   809         elif type(paths) == ListType:
   830         elif type(paths) == ListType:
   810             vars = [self.ComputeLDExpression(path) for path in paths]
   831             vars = [self.ComputeLDPaths(path) for path in paths]
   811             return JoinList([(" AND ", ())], vars)
   832             return JoinList([(" AND ", ())], vars)
   812         else:
   833         else:
   813             return eval(paths)
   834             return eval(paths)
       
   835 
       
   836     def ComputeLDExpression(self, body, connections):
       
   837         paths = self.GenerateLDPaths(connections, body)
       
   838         if len(paths) > 1:
       
   839             factorized_paths = self.FactorizeLDPaths(paths)
       
   840             if len(factorized_paths) > 1:
       
   841                 paths = tuple(factorized_paths)
       
   842             else:
       
   843                 paths = factorized_paths[0]
       
   844         else:
       
   845             paths = paths[0]
       
   846         return self.ComputeLDPaths(paths, True)
   814 
   847 
   815     def ExtractModifier(self, variable, expression, var_info):
   848     def ExtractModifier(self, variable, expression, var_info):
   816         if variable.getnegated():
   849         if variable.getnegated():
   817             return [("NOT(", var_info + ("negated",))] + expression + [(")", ())]
   850             return [("NOT(", var_info + ("negated",))] + expression + [(")", ())]
   818         else:
   851         else:
  1001                                 self.SFCComputedBlocks += self.Program
  1034                                 self.SFCComputedBlocks += self.Program
  1002                                 self.Program = []
  1035                                 self.Program = []
  1003                 elif transitionType == "LD":
  1036                 elif transitionType == "LD":
  1004                     for instance in transitionBody.getcontentInstances():
  1037                     for instance in transitionBody.getcontentInstances():
  1005                         if isinstance(instance, plcopen.ldObjects_coil):
  1038                         if isinstance(instance, plcopen.ldObjects_coil):
  1006                             paths = self.GenerateLDPaths(instance.connectionPointIn.getconnections(), transitionBody)
  1039                             expression = self.ComputeLDExpression(transitionBody, instance.connectionPointIn.getconnections())
  1007                             expression = self.ComputeLDExpression(paths, True)
       
  1008                             transition_infos["content"] = [("\n%s:= "%self.CurrentIndent, ())] + expression + [(";\n", ())]
  1040                             transition_infos["content"] = [("\n%s:= "%self.CurrentIndent, ())] + expression + [(";\n", ())]
  1009                             self.SFCComputedBlocks += self.Program
  1041                             self.SFCComputedBlocks += self.Program
  1010                             self.Program = []
  1042                             self.Program = []
  1011                 self.TagName = previous_tagname
  1043                 self.TagName = previous_tagname
  1012             elif transitionValues["type"] == "connection":
  1044             elif transitionValues["type"] == "connection":
  1014                 connections = transition.getconnections()
  1046                 connections = transition.getconnections()
  1015                 network_type = self.GetNetworkType(connections, body)
  1047                 network_type = self.GetNetworkType(connections, body)
  1016                 if network_type == None:
  1048                 if network_type == None:
  1017                     raise PLCGenException, "Type of network connected to transition impossible to define in \"%s\" POU"%self.Name
  1049                     raise PLCGenException, "Type of network connected to transition impossible to define in \"%s\" POU"%self.Name
  1018                 if len(connections) > 1 or network_type == "LD":
  1050                 if len(connections) > 1 or network_type == "LD":
  1019                     paths = self.GenerateLDPaths(connections, body)
  1051                     expression = self.ComputeLDExpression(body, connections)
  1020                     expression = self.ComputeLDExpression(paths, True)
       
  1021                 else:
  1052                 else:
  1022                     expression = self.ComputeFBDExpression(body, connections[0])
  1053                     expression = self.ComputeFBDExpression(body, connections[0])
  1023                 transition_infos["content"] = [("\n%s:= "%self.CurrentIndent, ())] + expression + [(";\n", ())]
  1054                 transition_infos["content"] = [("\n%s:= "%self.CurrentIndent, ())] + expression + [(";\n", ())]
  1024                 self.SFCComputedBlocks += self.Program
  1055                 self.SFCComputedBlocks += self.Program
  1025                 self.Program = []
  1056                 self.Program = []