svghmi/svghmi.py
branchsvghmi
changeset 2965 8f928cee01e5
parent 2945 69f395c01c09
child 2984 8c42504b6384
equal deleted inserted replaced
2964:a7b11c9f468e 2965:8f928cee01e5
    68         return res
    68         return res
    69 
    69 
    70     def place_node(self, node):
    70     def place_node(self, node):
    71         best_child = None
    71         best_child = None
    72         known_best_match = 0
    72         known_best_match = 0
       
    73         potential_siblings = {}
    73         for child in self.children:
    74         for child in self.children:
    74             if child.path is not None:
    75             if child.path is not None:
    75                 in_common = 0
    76                 in_common = 0
    76                 for child_path_item, node_path_item in izip(child.path, node.path):
    77                 for child_path_item, node_path_item in izip(child.path, node.path):
    77                     if child_path_item == node_path_item:
    78                     if child_path_item == node_path_item:
    84                 if in_common > known_best_match and \
    85                 if in_common > known_best_match and \
    85                    child.nodetype == "HMI_NODE" and \
    86                    child.nodetype == "HMI_NODE" and \
    86                    in_common == len(child.path) - 1:
    87                    in_common == len(child.path) - 1:
    87                     known_best_match = in_common
    88                     known_best_match = in_common
    88                     best_child = child
    89                     best_child = child
       
    90                 else:
       
    91                     potential_siblings[child.path[
       
    92                         -2 if child.nodetype == "HMI_NODE" else -1]] = child
    89         if best_child is not None:
    93         if best_child is not None:
    90             best_child.place_node(node)
    94             if node.nodetype == "HMI_NODE" and best_child.path[:-1] == node.path[:-1]:
       
    95                 return "Duplicate_HMI_NODE", best_child
       
    96             return best_child.place_node(node)
    91         else:
    97         else:
       
    98             candidate_name = node.path[-2 if node.nodetype == "HMI_NODE" else -1]
       
    99             if candidate_name in potential_siblings:
       
   100                 return "Non_Unique", potential_siblings[candidate_name]
       
   101 
       
   102             if node.nodetype == "HMI_NODE" and len(self.children) > 0:
       
   103                 prev = self.children[-1]
       
   104                 if prev.path[:-1] == node.path[:-1]:
       
   105                     return "Late_HMI_NODE",prev
       
   106 
    92             self.children.append(node)
   107             self.children.append(node)
       
   108             return None
    93 
   109 
    94     def etree(self, add_hash=False):
   110     def etree(self, add_hash=False):
    95 
   111 
    96         attribs = dict(name=self.name)
   112         attribs = dict(name=self.name)
    97         if self.path is not None:
   113         if self.path is not None:
   193 
   209 
   194         # take first HMI_NODE (placed as special node), make it root
   210         # take first HMI_NODE (placed as special node), make it root
   195         for i,v in enumerate(hmi_types_instances):
   211         for i,v in enumerate(hmi_types_instances):
   196             path = v["IEC_path"].split(".")
   212             path = v["IEC_path"].split(".")
   197             derived = v["derived"]
   213             derived = v["derived"]
   198             if derived == "HMI_NODE" and ['CONFIG', 'HEARTBEAT'] :
   214             if derived == "HMI_NODE":
   199                 hmi_tree_root = HMITreeNode(path, "", derived, v["type"], v["vartype"], v["C_path"])
   215                 hmi_tree_root = HMITreeNode(path, "", derived, v["type"], v["vartype"], v["C_path"])
   200                 hmi_types_instances.pop(i)
   216                 hmi_types_instances.pop(i)
   201                 break
   217                 break
   202 
   218 
   203         assert(hmi_tree_root is not None)
   219         assert(hmi_tree_root is not None)
   215                 name = path[-2]
   231                 name = path[-2]
   216                 kwargs['hmiclass'] = path[-1]
   232                 kwargs['hmiclass'] = path[-1]
   217             else:
   233             else:
   218                 name = path[-1]
   234                 name = path[-1]
   219             new_node = HMITreeNode(path, name, derived, v["type"], v["vartype"], v["C_path"], **kwargs)
   235             new_node = HMITreeNode(path, name, derived, v["type"], v["vartype"], v["C_path"], **kwargs)
   220             hmi_tree_root.place_node(new_node)
   236             placement_result = hmi_tree_root.place_node(new_node)
       
   237             if placement_result is not None:
       
   238                 cause, problematic_node = placement_result
       
   239                 if cause == "Non_Unique":
       
   240                     message = _("HMI tree nodes paths are not unique.\nConflicting variable: {} {}").format(
       
   241                         ".".join(problematic_node.path),
       
   242                         ".".join(new_node.path))
       
   243 
       
   244                     last_FB = None 
       
   245                     for v in varlist:
       
   246                         if v["vartype"] == "FB":
       
   247                             last_FB = v 
       
   248                         if v["C_path"] == problematic_node:
       
   249                             break
       
   250                     if last_FB is not None:
       
   251                         failing_parent = last_FB["type"]
       
   252                         message += "\n"
       
   253                         message += _("Solution: Add HMI_NODE at beginning of {}").format(failing_parent)
       
   254 
       
   255                 elif cause in ["Late_HMI_NODE", "Duplicate_HMI_NODE"]:
       
   256                     cause, problematic_node = placement_result
       
   257                     message = _("There must be only one occurrence of HMI_NODE before any HMI_* variable in POU.\nConflicting variable: {} {}").format(
       
   258                         ".".join(problematic_node.path),
       
   259                         ".".join(new_node.path))
       
   260 
       
   261                 self.FatalError("SVGHMI : " + message)
   221 
   262 
   222         if on_hmitree_update is not None:
   263         if on_hmitree_update is not None:
   223             on_hmitree_update()
   264             on_hmitree_update()
   224 
   265 
   225         variable_decl_array = []
   266         variable_decl_array = []