author | Edouard Tisserant |
Mon, 24 Jan 2022 11:14:56 +0100 | |
changeset 3421 | 70ef15fca028 |
parent 3381 | 3a0908b0319d |
child 3750 | f62625418bff |
child 3837 | efe0b5b21842 |
permissions | -rw-r--r-- |
2745 | 1 |
#!/usr/bin/env python |
2 |
# -*- coding: utf-8 -*- |
|
3 |
||
4 |
# This file is part of Beremiz |
|
3197
0f41c1e2c121
SVGHMI: split svghmi.py into hmi_tree.py + svghmi.py
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3193
diff
changeset
|
5 |
# Copyright (C) 2021: Edouard TISSERANT |
2745 | 6 |
# |
7 |
# See COPYING file for copyrights details. |
|
8 |
||
9 |
from __future__ import absolute_import |
|
2763
ce04d79b8e57
Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents:
2762
diff
changeset
|
10 |
from itertools import izip, imap |
2822
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2818
diff
changeset
|
11 |
from pprint import pformat |
3223
061796d9855e
SVGHMI: Widget transform before DnD now should have HMI path as a parameter, but this path isn't computed for some reason... WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3197
diff
changeset
|
12 |
import weakref |
2789 | 13 |
import hashlib |
2816 | 14 |
|
15 |
from lxml import etree |
|
2756
f94bc35a023e
SVGHMI: added extraction of SVG bounding boxes, obtained from "inkscape -S", and passed to XSLT transform as variable.
Edouard Tisserant
parents:
2753
diff
changeset
|
16 |
|
2749
2769b3aed34d
Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents:
2747
diff
changeset
|
17 |
HMI_TYPES_DESC = { |
2814
2cabc4773885
SVGHMI: HMI_LABEL and HMI_CLASS become HMI_NODE.
Edouard Tisserant
parents:
2812
diff
changeset
|
18 |
"HMI_NODE":{}, |
2749
2769b3aed34d
Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents:
2747
diff
changeset
|
19 |
"HMI_STRING":{}, |
2769b3aed34d
Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents:
2747
diff
changeset
|
20 |
"HMI_INT":{}, |
3068
81758c94f3df
SVGHMI: Fix HMI_REAL support, and add a HMI_REAL use case in tests/svghmi.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3052
diff
changeset
|
21 |
"HMI_BOOL":{}, |
81758c94f3df
SVGHMI: Fix HMI_REAL support, and add a HMI_REAL use case in tests/svghmi.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3052
diff
changeset
|
22 |
"HMI_REAL":{} |
2749
2769b3aed34d
Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents:
2747
diff
changeset
|
23 |
} |
2769b3aed34d
Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents:
2747
diff
changeset
|
24 |
|
2769b3aed34d
Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents:
2747
diff
changeset
|
25 |
HMI_TYPES = HMI_TYPES_DESC.keys() |
2745 | 26 |
|
2757
c901baa36bb3
SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents:
2756
diff
changeset
|
27 |
class HMITreeNode(object): |
2822
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2818
diff
changeset
|
28 |
def __init__(self, path, name, nodetype, iectype = None, vartype = None, cpath = None, hmiclass = None): |
2757
c901baa36bb3
SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents:
2756
diff
changeset
|
29 |
self.path = path |
c901baa36bb3
SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents:
2756
diff
changeset
|
30 |
self.name = name |
c901baa36bb3
SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents:
2756
diff
changeset
|
31 |
self.nodetype = nodetype |
2814
2cabc4773885
SVGHMI: HMI_LABEL and HMI_CLASS become HMI_NODE.
Edouard Tisserant
parents:
2812
diff
changeset
|
32 |
self.hmiclass = hmiclass |
3223
061796d9855e
SVGHMI: Widget transform before DnD now should have HMI path as a parameter, but this path isn't computed for some reason... WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3197
diff
changeset
|
33 |
self.parent = None |
2764
b75cc2cf4e50
SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents:
2763
diff
changeset
|
34 |
|
b75cc2cf4e50
SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents:
2763
diff
changeset
|
35 |
if iectype is not None: |
b75cc2cf4e50
SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents:
2763
diff
changeset
|
36 |
self.iectype = iectype |
b75cc2cf4e50
SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents:
2763
diff
changeset
|
37 |
self.vartype = vartype |
2822
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2818
diff
changeset
|
38 |
self.cpath = cpath |
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2818
diff
changeset
|
39 |
|
2890
ae8063127e95
SVGHMI: make root HMI tree node a HMI_NODE, droped HMI_ROOT node type
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
2866
diff
changeset
|
40 |
if nodetype in ["HMI_NODE"]: |
2757
c901baa36bb3
SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents:
2756
diff
changeset
|
41 |
self.children = [] |
c901baa36bb3
SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents:
2756
diff
changeset
|
42 |
|
c901baa36bb3
SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents:
2756
diff
changeset
|
43 |
def pprint(self, indent = 0): |
c901baa36bb3
SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents:
2756
diff
changeset
|
44 |
res = ">"*indent + pformat(self.__dict__, indent = indent, depth = 1) + "\n" |
2817
45bbfb2e120f
Non significant changes, whitespaces, etc.
Edouard Tisserant
parents:
2816
diff
changeset
|
45 |
if hasattr(self, "children"): |
2757
c901baa36bb3
SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents:
2756
diff
changeset
|
46 |
res += "\n".join([child.pprint(indent = indent + 1) |
c901baa36bb3
SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents:
2756
diff
changeset
|
47 |
for child in self.children]) |
c901baa36bb3
SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents:
2756
diff
changeset
|
48 |
res += "\n" |
2817
45bbfb2e120f
Non significant changes, whitespaces, etc.
Edouard Tisserant
parents:
2816
diff
changeset
|
49 |
|
2757
c901baa36bb3
SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents:
2756
diff
changeset
|
50 |
return res |
c901baa36bb3
SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents:
2756
diff
changeset
|
51 |
|
c901baa36bb3
SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents:
2756
diff
changeset
|
52 |
def place_node(self, node): |
c901baa36bb3
SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents:
2756
diff
changeset
|
53 |
best_child = None |
c901baa36bb3
SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents:
2756
diff
changeset
|
54 |
known_best_match = 0 |
2965
8f928cee01e5
SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents:
2945
diff
changeset
|
55 |
potential_siblings = {} |
2817
45bbfb2e120f
Non significant changes, whitespaces, etc.
Edouard Tisserant
parents:
2816
diff
changeset
|
56 |
for child in self.children: |
2762
282500e03dbc
Add special nodes at HMI Tree root, fix code to handle special node (no path).
Edouard Tisserant
parents:
2758
diff
changeset
|
57 |
if child.path is not None: |
282500e03dbc
Add special nodes at HMI Tree root, fix code to handle special node (no path).
Edouard Tisserant
parents:
2758
diff
changeset
|
58 |
in_common = 0 |
282500e03dbc
Add special nodes at HMI Tree root, fix code to handle special node (no path).
Edouard Tisserant
parents:
2758
diff
changeset
|
59 |
for child_path_item, node_path_item in izip(child.path, node.path): |
282500e03dbc
Add special nodes at HMI Tree root, fix code to handle special node (no path).
Edouard Tisserant
parents:
2758
diff
changeset
|
60 |
if child_path_item == node_path_item: |
282500e03dbc
Add special nodes at HMI Tree root, fix code to handle special node (no path).
Edouard Tisserant
parents:
2758
diff
changeset
|
61 |
in_common +=1 |
282500e03dbc
Add special nodes at HMI Tree root, fix code to handle special node (no path).
Edouard Tisserant
parents:
2758
diff
changeset
|
62 |
else: |
282500e03dbc
Add special nodes at HMI Tree root, fix code to handle special node (no path).
Edouard Tisserant
parents:
2758
diff
changeset
|
63 |
break |
2945
69f395c01c09
SVGHMI: Fix flawed logic to place nodes in the HMI tree, leading to wrecked tree in some cases.
Edouard Tisserant
parents:
2890
diff
changeset
|
64 |
# Match can only be HMI_NODE, and the whole path of node |
69f395c01c09
SVGHMI: Fix flawed logic to place nodes in the HMI tree, leading to wrecked tree in some cases.
Edouard Tisserant
parents:
2890
diff
changeset
|
65 |
# must match candidate node (except for name part) |
69f395c01c09
SVGHMI: Fix flawed logic to place nodes in the HMI tree, leading to wrecked tree in some cases.
Edouard Tisserant
parents:
2890
diff
changeset
|
66 |
# since candidate would become child of that node |
69f395c01c09
SVGHMI: Fix flawed logic to place nodes in the HMI tree, leading to wrecked tree in some cases.
Edouard Tisserant
parents:
2890
diff
changeset
|
67 |
if in_common > known_best_match and \ |
69f395c01c09
SVGHMI: Fix flawed logic to place nodes in the HMI tree, leading to wrecked tree in some cases.
Edouard Tisserant
parents:
2890
diff
changeset
|
68 |
child.nodetype == "HMI_NODE" and \ |
69f395c01c09
SVGHMI: Fix flawed logic to place nodes in the HMI tree, leading to wrecked tree in some cases.
Edouard Tisserant
parents:
2890
diff
changeset
|
69 |
in_common == len(child.path) - 1: |
2762
282500e03dbc
Add special nodes at HMI Tree root, fix code to handle special node (no path).
Edouard Tisserant
parents:
2758
diff
changeset
|
70 |
known_best_match = in_common |
282500e03dbc
Add special nodes at HMI Tree root, fix code to handle special node (no path).
Edouard Tisserant
parents:
2758
diff
changeset
|
71 |
best_child = child |
2965
8f928cee01e5
SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents:
2945
diff
changeset
|
72 |
else: |
8f928cee01e5
SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents:
2945
diff
changeset
|
73 |
potential_siblings[child.path[ |
8f928cee01e5
SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents:
2945
diff
changeset
|
74 |
-2 if child.nodetype == "HMI_NODE" else -1]] = child |
2945
69f395c01c09
SVGHMI: Fix flawed logic to place nodes in the HMI tree, leading to wrecked tree in some cases.
Edouard Tisserant
parents:
2890
diff
changeset
|
75 |
if best_child is not None: |
2965
8f928cee01e5
SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents:
2945
diff
changeset
|
76 |
if node.nodetype == "HMI_NODE" and best_child.path[:-1] == node.path[:-1]: |
8f928cee01e5
SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents:
2945
diff
changeset
|
77 |
return "Duplicate_HMI_NODE", best_child |
8f928cee01e5
SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents:
2945
diff
changeset
|
78 |
return best_child.place_node(node) |
2757
c901baa36bb3
SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents:
2756
diff
changeset
|
79 |
else: |
2965
8f928cee01e5
SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents:
2945
diff
changeset
|
80 |
candidate_name = node.path[-2 if node.nodetype == "HMI_NODE" else -1] |
8f928cee01e5
SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents:
2945
diff
changeset
|
81 |
if candidate_name in potential_siblings: |
8f928cee01e5
SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents:
2945
diff
changeset
|
82 |
return "Non_Unique", potential_siblings[candidate_name] |
8f928cee01e5
SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents:
2945
diff
changeset
|
83 |
|
8f928cee01e5
SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents:
2945
diff
changeset
|
84 |
if node.nodetype == "HMI_NODE" and len(self.children) > 0: |
8f928cee01e5
SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents:
2945
diff
changeset
|
85 |
prev = self.children[-1] |
8f928cee01e5
SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents:
2945
diff
changeset
|
86 |
if prev.path[:-1] == node.path[:-1]: |
8f928cee01e5
SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents:
2945
diff
changeset
|
87 |
return "Late_HMI_NODE",prev |
8f928cee01e5
SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents:
2945
diff
changeset
|
88 |
|
3223
061796d9855e
SVGHMI: Widget transform before DnD now should have HMI path as a parameter, but this path isn't computed for some reason... WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3197
diff
changeset
|
89 |
node.parent = weakref.ref(self) |
2757
c901baa36bb3
SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents:
2756
diff
changeset
|
90 |
self.children.append(node) |
2965
8f928cee01e5
SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents:
2945
diff
changeset
|
91 |
return None |
2817
45bbfb2e120f
Non significant changes, whitespaces, etc.
Edouard Tisserant
parents:
2816
diff
changeset
|
92 |
|
2788
2ed9ff826d03
SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents:
2781
diff
changeset
|
93 |
def etree(self, add_hash=False): |
2763
ce04d79b8e57
Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents:
2762
diff
changeset
|
94 |
|
ce04d79b8e57
Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents:
2762
diff
changeset
|
95 |
attribs = dict(name=self.name) |
ce04d79b8e57
Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents:
2762
diff
changeset
|
96 |
if self.path is not None: |
2788
2ed9ff826d03
SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents:
2781
diff
changeset
|
97 |
attribs["path"] = ".".join(self.path) |
2ed9ff826d03
SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents:
2781
diff
changeset
|
98 |
|
2815
77b2a3757e66
SVGHMI: add a class attribute to HMI Tree nodes, set when using HMI_NODE
Edouard Tisserant
parents:
2814
diff
changeset
|
99 |
if self.hmiclass is not None: |
77b2a3757e66
SVGHMI: add a class attribute to HMI Tree nodes, set when using HMI_NODE
Edouard Tisserant
parents:
2814
diff
changeset
|
100 |
attribs["class"] = self.hmiclass |
77b2a3757e66
SVGHMI: add a class attribute to HMI Tree nodes, set when using HMI_NODE
Edouard Tisserant
parents:
2814
diff
changeset
|
101 |
|
2788
2ed9ff826d03
SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents:
2781
diff
changeset
|
102 |
if add_hash: |
2ed9ff826d03
SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents:
2781
diff
changeset
|
103 |
attribs["hash"] = ",".join(map(str,self.hash())) |
2763
ce04d79b8e57
Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents:
2762
diff
changeset
|
104 |
|
ce04d79b8e57
Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents:
2762
diff
changeset
|
105 |
res = etree.Element(self.nodetype, **attribs) |
ce04d79b8e57
Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents:
2762
diff
changeset
|
106 |
|
2817
45bbfb2e120f
Non significant changes, whitespaces, etc.
Edouard Tisserant
parents:
2816
diff
changeset
|
107 |
if hasattr(self, "children"): |
2763
ce04d79b8e57
Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents:
2762
diff
changeset
|
108 |
for child_etree in imap(lambda c:c.etree(), self.children): |
ce04d79b8e57
Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents:
2762
diff
changeset
|
109 |
res.append(child_etree) |
ce04d79b8e57
Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents:
2762
diff
changeset
|
110 |
|
ce04d79b8e57
Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents:
2762
diff
changeset
|
111 |
return res |
ce04d79b8e57
Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents:
2762
diff
changeset
|
112 |
|
3176
81136a097012
SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3170
diff
changeset
|
113 |
@classmethod |
81136a097012
SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3170
diff
changeset
|
114 |
def from_etree(cls, enode): |
81136a097012
SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3170
diff
changeset
|
115 |
""" |
81136a097012
SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3170
diff
changeset
|
116 |
alternative constructor, restoring HMI Tree from XML backup |
81136a097012
SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3170
diff
changeset
|
117 |
note: all C-related information is gone, |
81136a097012
SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3170
diff
changeset
|
118 |
this restore is only for tree display and widget picking |
81136a097012
SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3170
diff
changeset
|
119 |
""" |
81136a097012
SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3170
diff
changeset
|
120 |
nodetype = enode.tag |
81136a097012
SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3170
diff
changeset
|
121 |
attributes = enode.attrib |
81136a097012
SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3170
diff
changeset
|
122 |
name = attributes["name"] |
81136a097012
SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3170
diff
changeset
|
123 |
path = attributes["path"].split('.') if "path" in attributes else None |
3177
5a8abd549aa8
SVGHMI: Lighter display of HMI Tree, no more icons and use buttons. Auto expand root. Fix loading of HMI tree XML backup (hmiclass attribute wasn't kept).
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3176
diff
changeset
|
124 |
hmiclass = attributes.get("class", None) |
3176
81136a097012
SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3170
diff
changeset
|
125 |
# hash is computed on demand |
81136a097012
SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3170
diff
changeset
|
126 |
node = cls(path, name, nodetype, hmiclass=hmiclass) |
81136a097012
SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3170
diff
changeset
|
127 |
for child in enode.iterchildren(): |
3224
507dd7bc8cb5
SVGHMI: Widget transform before DnD now have HMI path as a parameter
Edouard Tisserant
parents:
3223
diff
changeset
|
128 |
newnode = cls.from_etree(child) |
507dd7bc8cb5
SVGHMI: Widget transform before DnD now have HMI path as a parameter
Edouard Tisserant
parents:
3223
diff
changeset
|
129 |
newnode.parent = weakref.ref(node) |
507dd7bc8cb5
SVGHMI: Widget transform before DnD now have HMI path as a parameter
Edouard Tisserant
parents:
3223
diff
changeset
|
130 |
node.children.append(newnode) |
3176
81136a097012
SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3170
diff
changeset
|
131 |
return node |
81136a097012
SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3170
diff
changeset
|
132 |
|
2764
b75cc2cf4e50
SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents:
2763
diff
changeset
|
133 |
def traverse(self): |
b75cc2cf4e50
SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents:
2763
diff
changeset
|
134 |
yield self |
2817
45bbfb2e120f
Non significant changes, whitespaces, etc.
Edouard Tisserant
parents:
2816
diff
changeset
|
135 |
if hasattr(self, "children"): |
2764
b75cc2cf4e50
SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents:
2763
diff
changeset
|
136 |
for c in self.children: |
b75cc2cf4e50
SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents:
2763
diff
changeset
|
137 |
for yoodl in c.traverse(): |
b75cc2cf4e50
SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents:
2763
diff
changeset
|
138 |
yield yoodl |
b75cc2cf4e50
SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents:
2763
diff
changeset
|
139 |
|
3223
061796d9855e
SVGHMI: Widget transform before DnD now should have HMI path as a parameter, but this path isn't computed for some reason... WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3197
diff
changeset
|
140 |
def hmi_path(self): |
061796d9855e
SVGHMI: Widget transform before DnD now should have HMI path as a parameter, but this path isn't computed for some reason... WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3197
diff
changeset
|
141 |
if self.parent is None: |
061796d9855e
SVGHMI: Widget transform before DnD now should have HMI path as a parameter, but this path isn't computed for some reason... WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3197
diff
changeset
|
142 |
return "/" |
061796d9855e
SVGHMI: Widget transform before DnD now should have HMI path as a parameter, but this path isn't computed for some reason... WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3197
diff
changeset
|
143 |
p = self.parent() |
061796d9855e
SVGHMI: Widget transform before DnD now should have HMI path as a parameter, but this path isn't computed for some reason... WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3197
diff
changeset
|
144 |
if p.parent is None: |
061796d9855e
SVGHMI: Widget transform before DnD now should have HMI path as a parameter, but this path isn't computed for some reason... WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3197
diff
changeset
|
145 |
return "/" + self.name |
061796d9855e
SVGHMI: Widget transform before DnD now should have HMI path as a parameter, but this path isn't computed for some reason... WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3197
diff
changeset
|
146 |
return p.hmi_path() + "/" + self.name |
2788
2ed9ff826d03
SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents:
2781
diff
changeset
|
147 |
|
2ed9ff826d03
SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents:
2781
diff
changeset
|
148 |
def hash(self): |
2ed9ff826d03
SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents:
2781
diff
changeset
|
149 |
""" Produce a hash, any change in HMI tree structure change that hash """ |
2ed9ff826d03
SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents:
2781
diff
changeset
|
150 |
s = hashlib.new('md5') |
2ed9ff826d03
SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents:
2781
diff
changeset
|
151 |
self._hash(s) |
2ed9ff826d03
SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents:
2781
diff
changeset
|
152 |
# limit size to HMI_HASH_SIZE as in svghmi.c |
2817
45bbfb2e120f
Non significant changes, whitespaces, etc.
Edouard Tisserant
parents:
2816
diff
changeset
|
153 |
return map(ord,s.digest())[:8] |
2788
2ed9ff826d03
SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents:
2781
diff
changeset
|
154 |
|
2ed9ff826d03
SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents:
2781
diff
changeset
|
155 |
def _hash(self, s): |
2ed9ff826d03
SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents:
2781
diff
changeset
|
156 |
s.update(str((self.name,self.nodetype))) |
2817
45bbfb2e120f
Non significant changes, whitespaces, etc.
Edouard Tisserant
parents:
2816
diff
changeset
|
157 |
if hasattr(self, "children"): |
2788
2ed9ff826d03
SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents:
2781
diff
changeset
|
158 |
for c in self.children: |
2ed9ff826d03
SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents:
2781
diff
changeset
|
159 |
c._hash(s) |
2ed9ff826d03
SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents:
2781
diff
changeset
|
160 |
|
2890
ae8063127e95
SVGHMI: make root HMI tree node a HMI_NODE, droped HMI_ROOT node type
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
2866
diff
changeset
|
161 |
SPECIAL_NODES = [("HMI_ROOT", "HMI_NODE"), |
ae8063127e95
SVGHMI: make root HMI tree node a HMI_NODE, droped HMI_ROOT node type
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
2866
diff
changeset
|
162 |
("heartbeat", "HMI_INT")] |
2822
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2818
diff
changeset
|
163 |