# HG changeset patch # User Edouard Tisserant # Date 1581425808 -3600 # Node ID 6ac6a9dff594b9d866e626d7e212e6d19031de7d # Parent e74123b966ac1fd54f56e40c9fb99a385fbd89e3 SVGHMI: be a bit more tolerant with missing HMI paths or missing elements in widgets : continue build (with warning) and fail silently at runtime. diff -r e74123b966ac -r 6ac6a9dff594 XSLTransform.py --- a/XSLTransform.py Thu Jan 30 14:33:06 2020 +0100 +++ b/XSLTransform.py Tue Feb 11 13:56:48 2020 +0100 @@ -22,4 +22,7 @@ # print(self.xslt.error_log) return res + def get_error_log(self): + return self.xslt.error_log + diff -r e74123b966ac -r 6ac6a9dff594 svghmi/gen_index_xhtml.xslt --- a/svghmi/gen_index_xhtml.xslt Thu Jan 30 14:33:06 2020 +0100 +++ b/svghmi/gen_index_xhtml.xslt Tue Feb 11 13:56:48 2020 +0100 @@ -230,20 +230,24 @@ <xsl:for-each select="$widget/path"> <xsl:variable name="hmipath" select="@value"/> <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 path "</xsl:text> - <xsl:value-of select="$hmipath"/> - <xsl:text>" in HMI tree</xsl:text> - </xsl:message> - </xsl:if> - <xsl:text> </xsl:text> - <xsl:value-of select="$hmitree_match/@index"/> - <xsl:if test="position()!=last()"> - <xsl:text>,</xsl:text> - </xsl:if> - <xsl:text> -</xsl:text> + <xsl:choose> + <xsl:when test="count($hmitree_match) = 0"> + <xsl:message terminate="no"> + <xsl:text>No match for path "</xsl:text> + <xsl:value-of select="$hmipath"/> + <xsl:text>" in HMI tree</xsl:text> + </xsl:message> + </xsl:when> + <xsl:otherwise> + <xsl:text> </xsl:text> + <xsl:value-of select="$hmitree_match/@index"/> + <xsl:if test="position()!=last()"> + <xsl:text>,</xsl:text> + </xsl:if> + <xsl:text> +</xsl:text> + </xsl:otherwise> + </xsl:choose> </xsl:for-each> <xsl:text> ], </xsl:text> @@ -360,32 +364,30 @@ </xsl:text> <xsl:text>function dispatch_value_to_widget(widget, index, value, oldval) { </xsl:text> - <xsl:text> let idxidx = widget.indexes.indexOf(index); -</xsl:text> - <xsl:text> if(idxidx == -1){ -</xsl:text> - <xsl:text> throw new Error("Dispatching to widget not interested, should not happen."); + <xsl:text> try { +</xsl:text> + <xsl:text> let idxidx = widget.indexes.indexOf(index); +</xsl:text> + <xsl:text> let d = widget.dispatch; +</xsl:text> + <xsl:text> if(typeof(d) == "function" && idxidx == 0){ +</xsl:text> + <xsl:text> d.call(widget, value, oldval); +</xsl:text> + <xsl:text> }else if(typeof(d) == "object" && d.length >= idxidx){ +</xsl:text> + <xsl:text> d[idxidx].call(widget, value, oldval); +</xsl:text> + <xsl:text> }/* else dispatch_0, ..., dispatch_n ? */ +</xsl:text> + <xsl:text> /*else { +</xsl:text> + <xsl:text> throw new Error("Dunno how to dispatch to widget at index = " + index); +</xsl:text> + <xsl:text> }*/ </xsl:text> <xsl:text> } </xsl:text> - <xsl:text> let d = widget.dispatch; -</xsl:text> - <xsl:text> if(typeof(d) == "function" && idxidx == 0){ -</xsl:text> - <xsl:text> return d.call(widget, value, oldval); -</xsl:text> - <xsl:text> }else if(typeof(d) == "object" && d.length >= idxidx){ -</xsl:text> - <xsl:text> return d[idxidx].call(widget, value, oldval); -</xsl:text> - <xsl:text> }/* else dispatch_0, ..., dispatch_n ? */ -</xsl:text> - <xsl:text> /*else { -</xsl:text> - <xsl:text> throw new Error("Dunno how to dispatch to widget at index = " + index); -</xsl:text> - <xsl:text> }*/ -</xsl:text> <xsl:text>} </xsl:text> <xsl:text> @@ -426,7 +428,17 @@ </xsl:text> <xsl:text> if(typeof(init) == "function"){ </xsl:text> - <xsl:text> return init.call(widget); + <xsl:text> try { +</xsl:text> + <xsl:text> init.call(widget); +</xsl:text> + <xsl:text> } catch(err) { +</xsl:text> + <xsl:text> console.log("Widget initialization error : "+err.message); +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text> } </xsl:text> <xsl:text> } </xsl:text> @@ -913,12 +925,14 @@ <xsl:param name="labels" select="''"/> <xsl:param name="mandatory" select="'yes'"/> <xsl:param name="hmi_element"/> + <xsl:variable name="widget_type" select="@type"/> <xsl:for-each select="str:split($labels)"> <xsl:variable name="name" select="."/> <xsl:variable name="elt_id" select="$hmi_element//*[@inkscape:label=$name][1]/@id"/> <xsl:if test="$mandatory='yes' and not($elt_id)"> - <xsl:message terminate="yes"> - <xsl:text>Meter widget must have a </xsl:text> + <xsl:message terminate="no"> + <xsl:value-of select="$widget_type"/> + <xsl:text> widget must have a </xsl:text> <xsl:value-of select="$name"/> <xsl:text> element</xsl:text> </xsl:message> @@ -942,7 +956,7 @@ </xsl:text> </xsl:when> <xsl:otherwise> - <xsl:message terminate="yes"> + <xsl:message terminate="no"> <xsl:text>Display widget as a group not implemented</xsl:text> </xsl:message> </xsl:otherwise> diff -r e74123b966ac -r 6ac6a9dff594 svghmi/gen_index_xhtml.ysl2 --- a/svghmi/gen_index_xhtml.ysl2 Thu Jan 30 14:33:06 2020 +0100 +++ b/svghmi/gen_index_xhtml.ysl2 Tue Feb 11 13:56:48 2020 +0100 @@ -227,9 +227,14 @@ foreach "$widget/path" { const "hmipath","@value"; const "hmitree_match","$indexed_hmitree/*[@hmipath = $hmipath]"; - if "count($hmitree_match) = 0" - error > No match for path "«$hmipath»" in HMI tree + choose { + when "count($hmitree_match) = 0" { + warning > No match for path "«$hmipath»" in HMI tree + } + otherwise { | «$hmitree_match/@index»`if "position()!=last()" > ,` + } + } } | ], | element: document.getElementById("«@id»"), @@ -328,10 +333,12 @@ param "labels","''"; param "mandatory","'yes'"; param "hmi_element"; + const "widget_type","@type"; foreach "str:split($labels)" { const "name","."; const "elt_id","$hmi_element//*[@inkscape:label=$name][1]/@id"; - if "$mandatory='yes' and not($elt_id)" error > Meter widget must have a «$name» element + if "$mandatory='yes' and not($elt_id)" + warning > «$widget_type» widget must have a «$name» element | «$name»_elt: document.getElementById("«$elt_id»"), } } @@ -347,7 +354,7 @@ | this.element.textContent = String(value); } otherwise { - error > Display widget as a group not implemented + warning > Display widget as a group not implemented } } | }, diff -r e74123b966ac -r 6ac6a9dff594 svghmi/svghmi.js --- a/svghmi/svghmi.js Thu Jan 30 14:33:06 2020 +0100 +++ b/svghmi/svghmi.js Tue Feb 11 13:56:48 2020 +0100 @@ -3,19 +3,18 @@ var cache = hmitree_types.map(_ignored => undefined); function dispatch_value_to_widget(widget, index, value, oldval) { - let idxidx = widget.indexes.indexOf(index); - if(idxidx == -1){ - throw new Error("Dispatching to widget not interested, should not happen."); - } - let d = widget.dispatch; - if(typeof(d) == "function" && idxidx == 0){ - return d.call(widget, value, oldval); - }else if(typeof(d) == "object" && d.length >= idxidx){ - return d[idxidx].call(widget, value, oldval); - }/* else dispatch_0, ..., dispatch_n ? */ - /*else { - throw new Error("Dunno how to dispatch to widget at index = " + index); - }*/ + try { + let idxidx = widget.indexes.indexOf(index); + let d = widget.dispatch; + if(typeof(d) == "function" && idxidx == 0){ + d.call(widget, value, oldval); + }else if(typeof(d) == "object" && d.length >= idxidx){ + d[idxidx].call(widget, value, oldval); + }/* else dispatch_0, ..., dispatch_n ? */ + /*else { + throw new Error("Dunno how to dispatch to widget at index = " + index); + }*/ + } } function dispatch_value(index, value) { @@ -36,7 +35,12 @@ let widget = hmi_widgets[id]; let init = widget.init; if(typeof(init) == "function"){ - return init.call(widget); + try { + init.call(widget); + } catch(err) { + console.log("Widget initialization error : "+err.message); + + } } }); }; diff -r e74123b966ac -r 6ac6a9dff594 svghmi/svghmi.py --- a/svghmi/svghmi.py Thu Jan 30 14:33:06 2020 +0100 +++ b/svghmi/svghmi.py Tue Feb 11 13:56:48 2020 +0100 @@ -475,10 +475,14 @@ svgdom = etree.parse(svgfile) # call xslt transform on Inkscape's SVG to generate XHTML - try: + try: result = transform.transform(svgdom) except XSLTApplyError as e: self.FatalError("SVGHMI " + view_name + ": " + e.message) + finally: + for entry in transform.get_error_log(): + message = "SVGHMI: "+ entry.message + "\n" + self.GetCTRoot().logger.write_warning(message) result.write(target_file, encoding="utf-8") # print(str(result)) @@ -508,7 +512,7 @@ svghmi_cmds[thing] = ( "Popen(" + repr(shlex.split(given_command.format(port="8008", name=view_name))) + - ")") if given_command else "# no command given" + ")") if given_command else "pass # no command given" runtimefile_path = os.path.join(buildpath, "runtime_svghmi1_%s.py" % location_str) runtimefile = open(runtimefile_path, 'w')