# HG changeset patch # User Edouard Tisserant # Date 1572208690 -3600 # Node ID e521e0d133d5032d8e1d998245434abfcc49f4aa # Parent a6be58a1a8b7540f46c8851cc27997fa2e854bc9 SVGHMI: fixed HMI->PLC dataflow : not updates as expected, and not initialized properly after subscribe. diff -r a6be58a1a8b7 -r e521e0d133d5 svghmi/gen_index_xhtml.xslt --- a/svghmi/gen_index_xhtml.xslt Thu Oct 24 11:20:04 2019 +0200 +++ b/svghmi/gen_index_xhtml.xslt Sun Oct 27 21:38:10 2019 +0100 @@ -330,6 +330,12 @@ </xsl:text> <xsl:text> </xsl:text> + <xsl:text> let oldval = cache[index]; +</xsl:text> + <xsl:text> cache[index] = value; +</xsl:text> + <xsl:text> +</xsl:text> <xsl:text> if(widgets.size > 0) { </xsl:text> <xsl:text> for(let widget of widgets){ @@ -346,11 +352,11 @@ </xsl:text> <xsl:text> if(typeof(d) == "function" && idxidx == 0){ </xsl:text> - <xsl:text> return d.call(widget,value); + <xsl:text> return 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); + <xsl:text> return d[idxidx].call(widget, value, oldval); </xsl:text> <xsl:text> }/* else dispatch_0, ..., dispatch_n ? */ </xsl:text> @@ -364,12 +370,6 @@ </xsl:text> <xsl:text> } </xsl:text> - <xsl:text> -</xsl:text> - <xsl:text> cache[index] = value; -</xsl:text> - <xsl:text> -</xsl:text> <xsl:text>}; </xsl:text> <xsl:text> diff -r a6be58a1a8b7 -r e521e0d133d5 svghmi/svghmi.c --- a/svghmi/svghmi.c Thu Oct 24 11:20:04 2019 +0200 +++ b/svghmi/svghmi.c Sun Oct 27 21:38:10 2019 +0100 @@ -31,6 +31,7 @@ typedef enum { buf_free = 0, + buf_new, buf_set, buf_tosend } buf_state_t; @@ -89,6 +90,7 @@ dsc->age_ms += ticktime_ms; }else{ dsc->wstate = buf_tosend; + global_write_dirty = 1; } } } @@ -100,14 +102,18 @@ /* if new value differs from previous one */ USINT sz = __get_type_enum_size(dsc->type); - if(memcmp(dest_p, visible_value_p, sz) != 0){ + if(dsc->wstate == buf_new || memcmp(dest_p, visible_value_p, sz) != 0){ /* copy and flag as set */ memcpy(dest_p, visible_value_p, sz); - if(dsc->wstate == buf_free) { - dsc->wstate = buf_set; + if(dsc->wstate == buf_new || dsc->wstate == buf_free) { + if(dsc->wstate == buf_new || ticktime_ms > dsc->refresh_period_ms){ + dsc->wstate = buf_tosend; + global_write_dirty = 1; + } else { + dsc->wstate = buf_set; + } dsc->age_ms = 0; } - global_write_dirty = 1; } AtomicCompareExchange(&dsc->wlock, 1, 0); @@ -168,6 +174,11 @@ { while(AtomicCompareExchange(&dsc->wlock, 0, 1)) sched_yield(); dsc->refresh_period_ms = refresh_period_ms; + if(refresh_period_ms) { + dsc->wstate = buf_new; + } else { + dsc->wstate = buf_free; + } AtomicCompareExchange(&dsc->wlock, 1, 0); } diff -r a6be58a1a8b7 -r e521e0d133d5 svghmi/svghmi.js --- a/svghmi/svghmi.js Thu Oct 24 11:20:04 2019 +0200 +++ b/svghmi/svghmi.js Sun Oct 27 21:38:10 2019 +0100 @@ -5,6 +5,9 @@ function dispatch_value(index, value) { let widgets = subscribers[index]; + let oldval = cache[index]; + cache[index] = value; + if(widgets.size > 0) { for(let widget of widgets){ let idxidx = widget.indexes.indexOf(index); @@ -13,18 +16,15 @@ } let d = widget.dispatch; if(typeof(d) == "function" && idxidx == 0){ - return d.call(widget,value); + return d.call(widget, value, oldval); }else if(typeof(d) == "object" && d.length >= idxidx){ - d[idxidx].call(widget,value); + 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); }*/ } } - - cache[index] = value; - }; function init_widgets() { diff -r a6be58a1a8b7 -r e521e0d133d5 tests/svghmi/plc.xml --- a/tests/svghmi/plc.xml Thu Oct 24 11:20:04 2019 +0200 +++ b/tests/svghmi/plc.xml Sun Oct 27 21:38:10 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-09-11T11:54:14"> + <contentHeader name="Unnamed" modificationDateTime="2019-10-23T11:12:09"> <coordinateInfo> <fbd> <scaling x="5" y="5"/> @@ -34,64 +34,6 @@ </interface> <body> <FBD> - <block localId="2" typeName="ADD" executionOrderId="0" height="60" width="63"> - <position x="255" y="175"/> - <inputVariables> - <variable formalParameter="IN1"> - <connectionPointIn> - <relPosition x="0" y="30"/> - <connection refLocalId="1"> - <position x="255" y="205"/> - <position x="202" y="205"/> - </connection> - </connectionPointIn> - </variable> - <variable formalParameter="IN2"> - <connectionPointIn> - <relPosition x="0" y="50"/> - <connection refLocalId="3"> - <position x="255" y="225"/> - <position x="235" y="225"/> - <position x="235" y="235"/> - <position x="190" y="235"/> - </connection> - </connectionPointIn> - </variable> - </inputVariables> - <inOutVariables/> - <outputVariables> - <variable formalParameter="OUT"> - <connectionPointOut> - <relPosition x="63" y="30"/> - </connectionPointOut> - </variable> - </outputVariables> - </block> - <inOutVariable localId="1" executionOrderId="0" height="26" width="122" negatedOut="false" negatedIn="false"> - <position x="120" y="190"/> - <connectionPointIn> - <relPosition x="0" y="15"/> - <connection refLocalId="2" formalParameter="OUT"> - <position x="120" y="205"/> - <position x="100" y="205"/> - <position x="100" y="140"/> - <position x="328" y="140"/> - <position x="328" y="205"/> - <position x="318" y="205"/> - </connection> - </connectionPointIn> - <connectionPointOut> - <relPosition x="122" y="15"/> - </connectionPointOut> - <expression>TargetPressure</expression> - </inOutVariable> - <inVariable localId="3" executionOrderId="0" height="25" width="60" negated="false"> - <position x="130" y="225"/> - <connectionPointOut> - <relPosition x="60" y="10"/> - </connectionPointOut> - <expression>1</expression> - </inVariable> <block localId="4" typeName="PumpControl" instanceName="Pump0" executionOrderId="0" height="40" width="127"> <position x="595" y="50"/> <inputVariables> @@ -140,7 +82,7 @@ </variable> </inputVars> <localVars> - <variable name="AddOut"> + <variable name="Sloth"> <type> <derived name="HMI_INT"/> </type> @@ -149,59 +91,6 @@ </interface> <body> <FBD> - <inOutVariable localId="1" executionOrderId="0" height="30" width="75" negatedOut="false" negatedIn="false"> - <position x="285" y="105"/> - <connectionPointIn> - <relPosition x="0" y="15"/> - <connection refLocalId="2" formalParameter="OUT"> - <position x="285" y="120"/> - <position x="275" y="120"/> - <position x="275" y="95"/> - <position x="550" y="95"/> - <position x="550" y="135"/> - <position x="540" y="135"/> - </connection> - </connectionPointIn> - <connectionPointOut> - <relPosition x="75" y="15"/> - </connectionPointOut> - <expression>Pressure</expression> - </inOutVariable> - <block localId="2" typeName="ADD" executionOrderId="0" height="60" width="65"> - <position x="475" y="105"/> - <inputVariables> - <variable formalParameter="IN1"> - <connectionPointIn> - <relPosition x="0" y="30"/> - <connection refLocalId="1"> - <position x="475" y="135"/> - <position x="417" y="135"/> - <position x="417" y="120"/> - <position x="360" y="120"/> - </connection> - </connectionPointIn> - </variable> - <variable formalParameter="IN2"> - <connectionPointIn> - <relPosition x="0" y="50"/> - <connection refLocalId="3"> - <position x="475" y="155"/> - <position x="432" y="155"/> - <position x="432" y="150"/> - <position x="410" y="150"/> - </connection> - </connectionPointIn> - </variable> - </inputVariables> - <inOutVariables/> - <outputVariables> - <variable formalParameter="OUT"> - <connectionPointOut> - <relPosition x="65" y="30"/> - </connectionPointOut> - </variable> - </outputVariables> - </block> <inVariable localId="3" executionOrderId="0" height="25" width="30" negated="false"> <position x="380" y="140"/> <connectionPointOut> @@ -213,15 +102,33 @@ <position x="640" y="135"/> <connectionPointIn> <relPosition x="0" y="15"/> - <connection refLocalId="2" formalParameter="OUT"> + <connection refLocalId="3"> <position x="640" y="150"/> - <position x="590" y="150"/> - <position x="590" y="135"/> - <position x="540" y="135"/> + <position x="410" y="150"/> </connection> </connectionPointIn> - <expression>AddOut</expression> + <expression>Sloth</expression> </outVariable> + <outVariable localId="1" executionOrderId="0" height="30" width="75" negated="false"> + <position x="285" y="105"/> + <connectionPointIn> + <relPosition x="0" y="15"/> + <connection refLocalId="5"> + <position x="285" y="120"/> + <position x="240" y="120"/> + <position x="240" y="115"/> + <position x="195" y="115"/> + </connection> + </connectionPointIn> + <expression>Pressure</expression> + </outVariable> + <inVariable localId="5" executionOrderId="0" height="30" width="125" negated="false"> + <position x="70" y="100"/> + <connectionPointOut> + <relPosition x="125" y="15"/> + </connectionPointOut> + <expression>TargetPressure</expression> + </inVariable> </FBD> </body> </pou> diff -r a6be58a1a8b7 -r e521e0d133d5 tests/svghmi/svghmi_0@svghmi/svghmi.svg --- a/tests/svghmi/svghmi_0@svghmi/svghmi.svg Thu Oct 24 11:20:04 2019 +0200 +++ b/tests/svghmi/svghmi_0@svghmi/svghmi.svg Sun Oct 27 21:38:10 2019 +0100 @@ -76,12 +76,12 @@ inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:document-units="px" - inkscape:current-layer="g84" + inkscape:current-layer="hmi0" showgrid="false" units="px" inkscape:zoom="0.84375" - inkscape:cx="-12.406671" - inkscape:cy="380.60108" + inkscape:cx="-391.07334" + inkscape:cy="346.23071" inkscape:window-width="1600" inkscape:window-height="886" inkscape:window-x="0" @@ -195,8 +195,8 @@ 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;vector-effect:none;fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:#ff6600;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" id="path89" sodipodi:sides="3" - sodipodi:cx="580.74072" - sodipodi:cy="-236.2599" + sodipodi:cx="596.74072" + sodipodi:cy="-216.2599" sodipodi:r1="59.825443" sodipodi:r2="29.912722" sodipodi:arg1="0.52359878" @@ -204,13 +204,13 @@ inkscape:flatsided="true" inkscape:rounded="0" inkscape:randomized="0" - d="m 632.55108,-206.34718 -103.62071,0 51.81035,-89.73817 z" + d="m 648.55108,-186.34718 -103.62071,0 51.81035,-89.73817 z" inkscape:transform-center-y="14.956363" inkscape:label="-100" /> <path inkscape:label="-10" inkscape:transform-center-y="7.4781812" - d="m 606.6459,-170.03172 -51.81035,0 25.90517,-44.86908 z" + d="m 622.6459,-170.03172 -51.81035,0 25.90517,-44.86908 z" inkscape:randomized="0" inkscape:rounded="0" inkscape:flatsided="true" @@ -219,7 +219,7 @@ sodipodi:r2="14.956361" sodipodi:r1="29.912722" sodipodi:cy="-184.98808" - sodipodi:cx="580.74072" + sodipodi:cx="596.74072" sodipodi:sides="3" id="path88" 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;vector-effect:none;fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:#ff6600;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" @@ -237,7 +237,7 @@ <path inkscape:label="+100" inkscape:transform-center-y="-14.956361" - d="m 632.55108,115.08534 -103.62071,0 51.81035,-89.738161 z" + d="m 648.55108,135.08534 -103.62071,0 51.81035,-89.738161 z" inkscape:randomized="0" inkscape:rounded="0" inkscape:flatsided="true" @@ -245,8 +245,8 @@ sodipodi:arg1="0.52359878" sodipodi:r2="29.912722" sodipodi:r1="59.825443" - sodipodi:cy="85.172623" - sodipodi:cx="580.74072" + sodipodi:cy="105.17262" + sodipodi:cx="596.74072" sodipodi:sides="3" id="path87" 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;vector-effect:none;fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:#ff6600;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" @@ -256,7 +256,7 @@ 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;vector-effect:none;fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:#ff6600;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" id="path86" sodipodi:sides="3" - sodipodi:cx="580.74072" + sodipodi:cx="596.74072" sodipodi:cy="136.44444" sodipodi:r1="29.912722" sodipodi:r2="14.956361" @@ -265,7 +265,7 @@ inkscape:flatsided="true" inkscape:rounded="0" inkscape:randomized="0" - d="m 606.6459,151.4008 -51.81035,0 25.90517,-44.86908 z" + d="m 622.6459,151.4008 -51.81035,0 25.90517,-44.86908 z" inkscape:transform-center-y="-7.4781804" inkscape:label="+10" /> <path @@ -301,7 +301,7 @@ <g id="g4523" transform="matrix(3.7795276,0,0,3.7795276,308.51002,630.30393)" - inkscape:label="HMI:Meter@/PUMP/ADDOUT"> + inkscape:label="HMI:Meter@/PUMP/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"