--- a/svghmi/svghmi.py Wed May 13 14:47:17 2020 +0200
+++ b/svghmi/svghmi.py Wed May 13 14:48:52 2020 +0200
@@ -70,6 +70,7 @@
def place_node(self, node):
+ potential_siblings = {} for child in self.children:
if child.path is not None:
@@ -86,10 +87,25 @@
in_common == len(child.path) - 1:
known_best_match = in_common
+ potential_siblings[child.path[ + -2 if child.nodetype == "HMI_NODE" else -1]] = child if best_child is not None:
- best_child.place_node(node)
+ if node.nodetype == "HMI_NODE" and best_child.path[:-1] == node.path[:-1]: + return "Duplicate_HMI_NODE", best_child + return best_child.place_node(node) + candidate_name = node.path[-2 if node.nodetype == "HMI_NODE" else -1] + if candidate_name in potential_siblings: + return "Non_Unique", potential_siblings[candidate_name] + if node.nodetype == "HMI_NODE" and len(self.children) > 0: + prev = self.children[-1] + if prev.path[:-1] == node.path[:-1]: + return "Late_HMI_NODE",prev self.children.append(node)
def etree(self, add_hash=False):
@@ -195,7 +211,7 @@
for i,v in enumerate(hmi_types_instances):
path = v["IEC_path"].split(".")
- if derived == "HMI_NODE" and ['CONFIG', 'HEARTBEAT'] :
+ if derived == "HMI_NODE": hmi_tree_root = HMITreeNode(path, "", derived, v["type"], v["vartype"], v["C_path"])
hmi_types_instances.pop(i)
@@ -217,7 +233,32 @@
new_node = HMITreeNode(path, name, derived, v["type"], v["vartype"], v["C_path"], **kwargs)
- hmi_tree_root.place_node(new_node)
+ placement_result = hmi_tree_root.place_node(new_node) + if placement_result is not None: + cause, problematic_node = placement_result + if cause == "Non_Unique": + message = _("HMI tree nodes paths are not unique.\nConflicting variable: {} {}").format( + ".".join(problematic_node.path), + ".".join(new_node.path)) + if v["vartype"] == "FB": + if v["C_path"] == problematic_node: + if last_FB is not None: + failing_parent = last_FB["type"] + message += _("Solution: Add HMI_NODE at beginning of {}").format(failing_parent) + elif cause in ["Late_HMI_NODE", "Duplicate_HMI_NODE"]: + cause, problematic_node = placement_result + message = _("There must be only one occurrence of HMI_NODE before any HMI_* variable in POU.\nConflicting variable: {} {}").format( + ".".join(problematic_node.path), + ".".join(new_node.path)) + self.FatalError("SVGHMI : " + message) if on_hmitree_update is not None: