SVGHMI: fixed HMI->PLC dataflow : not updates as expected, and not initialized properly after subscribe. svghmi
authorEdouard Tisserant
Sun, 27 Oct 2019 21:38:10 +0100
branchsvghmi
changeset 2805 e521e0d133d5
parent 2804 a6be58a1a8b7
child 2806 7d0e81cdedb0
SVGHMI: fixed HMI->PLC dataflow : not updates as expected, and not initialized properly after subscribe.
svghmi/gen_index_xhtml.xslt
svghmi/svghmi.c
svghmi/svghmi.js
tests/svghmi/plc.xml
tests/svghmi/svghmi_0@svghmi/svghmi.svg
--- 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 &gt; 0) {
 </xsl:text>
     <xsl:text>        for(let widget of widgets){
@@ -346,11 +352,11 @@
 </xsl:text>
     <xsl:text>            if(typeof(d) == "function" &amp;&amp; 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" &amp;&amp; d.length &gt;= 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>
--- 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);
 }
 
--- 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() {
--- 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>
--- 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"