SVGHMI: HMI_LABEL and HMI_CLASS become HMI_NODE.
- Name of parent POU becomes HMI tree node name,
- Name of HMI_NODE variable becomes class of the node.
--- a/svghmi/gen_index_xhtml.xslt Wed Nov 13 11:21:04 2019 +0100
+++ b/svghmi/gen_index_xhtml.xslt Wed Nov 13 11:22:53 2019 +0100
@@ -33,10 +33,7 @@
<xsl:text>HMI_ROOT</xsl:text>
</noindex>
<noindex>
- <xsl:text>HMI_LABEL</xsl:text>
- </noindex>
- <noindex>
- <xsl:text>HMI_CLASS</xsl:text>
+ <xsl:text>HMI_NODE</xsl:text>
</noindex>
<noindex>
<xsl:text>HMI_PLC_STATUS</xsl:text>
@@ -123,6 +120,15 @@
<xsl:comment>
<xsl:text>Made with SVGHMI. https://beremiz.org</xsl:text>
</xsl:comment>
+ <xsl:comment>
+ <xsl:apply-templates mode="testgeo" select="$hmi_geometry"/>
+ </xsl:comment>
+ <xsl:comment>
+ <xsl:apply-templates mode="testtree" select="$hmitree"/>
+ </xsl:comment>
+ <xsl:comment>
+ <xsl:apply-templates mode="testtree" select="$indexed_hmitree"/>
+ </xsl:comment>
<html xmlns="http://www.w3.org/1999/xhtml">
<head/>
<body style="margin:0;overflow:hidden;">
@@ -225,9 +231,9 @@
<xsl:variable name="hmitree_match" select="$indexed_hmitree/*[@hmipath = $hmipath]"/>
<xsl:if test="count($hmitree_match) = 0">
<xsl:message terminate="yes">
- <xsl:text>No match for HMI </xsl:text>
+ <xsl:text>No match for path "</xsl:text>
<xsl:value-of select="$hmipath"/>
- <xsl:text>;</xsl:text>
+ <xsl:text>" in HMI tree</xsl:text>
</xsl:message>
</xsl:if>
<xsl:text> </xsl:text>
@@ -799,6 +805,40 @@
<xsl:text>//})();
</xsl:text>
</xsl:template>
+ <xsl:template mode="testgeo" match="bbox">
+ <xsl:text>ID: </xsl:text>
+ <xsl:value-of select="@Id"/>
+ <xsl:text> x: </xsl:text>
+ <xsl:value-of select="@x"/>
+ <xsl:text> y: </xsl:text>
+ <xsl:value-of select="@y"/>
+ <xsl:text> w: </xsl:text>
+ <xsl:value-of select="@w"/>
+ <xsl:text> h: </xsl:text>
+ <xsl:value-of select="@h"/>
+ <xsl:text>
+</xsl:text>
+ </xsl:template>
+ <xsl:template mode="testtree" match="*">
+ <xsl:param name="indent" select="''"/>
+ <xsl:value-of select="$indent"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="local-name()"/>
+ <xsl:text> </xsl:text>
+ <xsl:for-each select="@*">
+ <xsl:value-of select="local-name()"/>
+ <xsl:text>=</xsl:text>
+ <xsl:value-of select="."/>
+ <xsl:text> </xsl:text>
+ </xsl:for-each>
+ <xsl:text>
+</xsl:text>
+ <xsl:apply-templates mode="testtree" select="*">
+ <xsl:with-param name="indent">
+ <xsl:value-of select="concat($indent,'>')"/>
+ </xsl:with-param>
+ </xsl:apply-templates>
+ </xsl:template>
<xsl:template name="defs_by_labels">
<xsl:param name="labels" select="''"/>
<xsl:param name="mandatory" select="'yes'"/>
--- a/svghmi/gen_index_xhtml.ysl2 Wed Nov 13 11:21:04 2019 +0100
+++ b/svghmi/gen_index_xhtml.ysl2 Wed Nov 13 11:22:53 2019 +0100
@@ -55,8 +55,7 @@
const "_categories" {
noindex > HMI_ROOT
- noindex > HMI_LABEL
- noindex > HMI_CLASS
+ noindex > HMI_NODE
noindex > HMI_PLC_STATUS
noindex > HMI_CURRENT_PAGE
}
@@ -122,7 +121,7 @@
/* copy root node and add geometry as comment for a test */
template "/" {
comment > Made with SVGHMI. https://beremiz.org
- /* DEBUG DATA
+ /* DEBUG DATA */
comment {
apply "$hmi_geometry", mode="testgeo";
}
@@ -132,7 +131,7 @@
comment {
apply "$indexed_hmitree", mode="testtree";
}
- */
+ /**/
html xmlns="http://www.w3.org/1999/xhtml" {
head;
body style="margin:0;overflow:hidden;" {
@@ -229,7 +228,7 @@
const "hmipath","@value";
const "hmitree_match","$indexed_hmitree/*[@hmipath = $hmipath]";
if "count($hmitree_match) = 0"
- error > No match for HMI «$hmipath»;
+ error > No match for path "«$hmipath»" in HMI tree
| «$hmitree_match/@index»`if "position()!=last()" > ,`
}
| ],
@@ -307,7 +306,7 @@
// }
- /*
+ /**/
template "bbox", mode="testgeo"{
| ID: «@Id» x: «@x» y: «@y» w: «@w» h: «@h»
}
@@ -321,7 +320,7 @@
with "indent" value "concat($indent,'>')"
};
}
- */
+ /**/
function "defs_by_labels" {
param "labels","''";
--- a/svghmi/pous.xml Wed Nov 13 11:21:04 2019 +0100
+++ b/svghmi/pous.xml Wed Nov 13 11:22:53 2019 +0100
@@ -36,12 +36,7 @@
<BOOL/>
</baseType>
</dataType>
- <dataType name="HMI_CLASS">
- <baseType>
- <BOOL/>
- </baseType>
- </dataType>
- <dataType name="HMI_LABEL">
+ <dataType name="HMI_NODE">
<baseType>
<BOOL/>
</baseType>
--- a/svghmi/svghmi.py Wed Nov 13 11:21:04 2019 +0100
+++ b/svghmi/svghmi.py Wed Nov 13 11:22:53 2019 +0100
@@ -25,8 +25,7 @@
import targets
HMI_TYPES_DESC = {
- "HMI_CLASS":{},
- "HMI_LABEL":{},
+ "HMI_NODE":{},
"HMI_STRING":{},
"HMI_INT":{},
"HMI_REAL":{}
@@ -35,19 +34,21 @@
HMI_TYPES = HMI_TYPES_DESC.keys()
from XSLTransform import XSLTransform
+from lxml.etree import XSLTApplyError
ScriptDirectory = paths.AbsDir(__file__)
class HMITreeNode(object):
- def __init__(self, path, name, nodetype, iectype = None, vartype = None):
+ def __init__(self, path, name, nodetype, iectype = None, vartype = None, hmiclass = None):
self.path = path
self.name = name
self.nodetype = nodetype
+ self.hmiclass = hmiclass
if iectype is not None:
self.iectype = iectype
self.vartype = vartype
- if nodetype in ["HMI_LABEL", "HMI_ROOT"]:
+ if nodetype in ["HMI_NODE", "HMI_ROOT"]:
self.children = []
def pprint(self, indent = 0):
@@ -73,7 +74,7 @@
if in_common > known_best_match:
known_best_match = in_common
best_child = child
- if best_child is not None and best_child.nodetype == "HMI_LABEL":
+ if best_child is not None and best_child.nodetype == "HMI_NODE":
best_child.place_node(node)
else:
self.children.append(node)
@@ -136,12 +137,12 @@
+->v1 HMI_INT
+->v2 HMI_INT
+->fb0 (type mhoo)
- | +->va HMI_LABEL
+ | +->va HMI_NODE
| +->v3 HMI_INT
| +->v4 HMI_INT
|
+->fb1 (type mhoo)
- | +->va HMI_LABEL
+ | +->va HMI_NODE
| +->v3 HMI_INT
| +->v4 HMI_INT
|
@@ -152,11 +153,11 @@
hmi0
+->v1
+->v2
- +->fb0_va
+ +->fb0 class:va
| +-> v3
| +-> v4
|
- +->fb1_va
+ +->fb1 class:va
| +-> v3
| +-> v4
|
@@ -180,7 +181,14 @@
# ignores variables starting with _TMP_
if path[-1].startswith("_TMP_"):
continue
- new_node = HMITreeNode(path, path[-1], v["derived"], v["type"], v["vartype"])
+ derived = v["derived"]
+ kwargs={}
+ if derived == "HMI_NODE":
+ name = path[-2]
+ kwargs['hmiclass'] = path[-1]
+ else:
+ name = path[-1]
+ new_node = HMITreeNode(path, name, derived, v["type"], v["vartype"], **kwargs)
hmi_tree_root.place_node(new_node)
variable_decl_array = []
@@ -189,7 +197,7 @@
item_count = 0
for node in hmi_tree_root.traverse():
if hasattr(node, "iectype") and \
- node.nodetype not in ["HMI_CLASS", "HMI_LABEL"]:
+ node.nodetype not in ["HMI_NODE"]:
sz = DebugTypesSize.get(node.iectype, 0)
variable_decl_array += [
"{&(" + ".".join(node.path) + "), " + node.iectype + {
@@ -357,7 +365,10 @@
svgdom = etree.parse(svgfile)
# call xslt transform on Inkscape's SVG to generate XHTML
- result = transform.transform(svgdom)
+ try:
+ result = transform.transform(svgdom)
+ except XSLTApplyError as e:
+ self.FatalError("SVGHMI " + view_name + ": " + e.message)
result.write(target_file, encoding="utf-8")
# print(str(result))
--- a/tests/svghmi/plc.xml Wed Nov 13 11:21:04 2019 +0100
+++ b/tests/svghmi/plc.xml Wed Nov 13 11:22:53 2019 +0100
@@ -1,7 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<project xmlns:ns1="http://www.plcopen.org/xml/tc6_0201" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.plcopen.org/xml/tc6_0201">
<fileHeader companyName="Unknown" productName="Unnamed" productVersion="1" creationDateTime="2019-08-06T14:23:42"/>
- <contentHeader name="Unnamed" modificationDateTime="2019-10-27T21:48:33">
+ <contentHeader name="Unnamed" modificationDateTime="2019-11-12T13:19:15">
<coordinateInfo>
<fbd>
<scaling x="5" y="5"/>
@@ -30,6 +30,11 @@
<derived name="PumpControl"/>
</type>
</variable>
+ <variable name="Pump1">
+ <type>
+ <derived name="PumpControl"/>
+ </type>
+ </variable>
</localVars>
</interface>
<body>
@@ -57,6 +62,24 @@
</connectionPointOut>
<expression>TargetPressure</expression>
</inVariable>
+ <block localId="1" typeName="PumpControl" instanceName="Pump1" executionOrderId="0" height="40" width="127">
+ <position x="605" y="145"/>
+ <inputVariables>
+ <variable formalParameter="TargetPressure">
+ <connectionPointIn>
+ <relPosition x="0" y="30"/>
+ <connection refLocalId="5">
+ <position x="605" y="175"/>
+ <position x="587" y="175"/>
+ <position x="587" y="80"/>
+ <position x="570" y="80"/>
+ </connection>
+ </connectionPointIn>
+ </variable>
+ </inputVariables>
+ <inOutVariables/>
+ <outputVariables/>
+ </block>
</FBD>
</body>
</pou>
@@ -65,7 +88,7 @@
<localVars>
<variable name="Pump">
<type>
- <derived name="HMI_LABEL"/>
+ <derived name="HMI_NODE"/>
</type>
</variable>
<variable name="Pressure">
--- a/tests/svghmi/svghmi_0@svghmi/svghmi.svg Wed Nov 13 11:21:04 2019 +0100
+++ b/tests/svghmi/svghmi_0@svghmi/svghmi.svg Wed Nov 13 11:22:53 2019 +0100
@@ -113,12 +113,12 @@
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:document-units="px"
- inkscape:current-layer="g110"
+ inkscape:current-layer="hmi0"
showgrid="false"
units="px"
inkscape:zoom="0.8046875"
- inkscape:cx="478.76479"
- inkscape:cy="-403.42943"
+ inkscape:cx="959.69683"
+ inkscape:cy="656.6094"
inkscape:window-width="1600"
inkscape:window-height="886"
inkscape:window-x="0"
@@ -321,7 +321,7 @@
inkscape:label="=0" />
</g>
<text
- inkscape:label="HMI:Display@/PUMP/PRESSURE"
+ inkscape:label="HMI:Display@/PUMP0/PRESSURE"
id="text823"
y="218.24219"
x="756.32812"
@@ -335,7 +335,7 @@
<g
id="g4523"
transform="matrix(3.7795276,0,0,3.7795276,308.51002,630.30393)"
- inkscape:label="HMI:Meter@/PUMP/SLOTH">
+ inkscape:label="HMI:Meter@/PUMP0/SLOTH">
<path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#3ee800;stroke-width:26.45833397;stroke-miterlimit:4;stroke-dasharray:2.64583333, 2.64583333;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="path4499"
@@ -635,7 +635,7 @@
sodipodi:role="line">Home</tspan></text>
</g>
<g
- inkscape:label="HMI:Meter@/PUMP/SLOTH"
+ inkscape:label="HMI:Meter@/PUMP0/SLOTH"
transform="matrix(7.5590552,0,0,7.5590552,-244.3956,1321.2434)"
id="g110">
<path
@@ -892,7 +892,7 @@
x="736.32812"
y="1478.2422"
id="text995"
- inkscape:label="HMI:Display@/PUMP/PRESSURE"><tspan
+ inkscape:label="HMI:Display@/PUMP0/PRESSURE"><tspan
sodipodi:role="line"
id="tspan993"
x="736.32812"