SVGHMI : support for HMI_STRING and HMI_BOOL svghmi
authorEdouard Tisserant <edouard.tisserant@gmail.com>
Tue, 14 Jan 2020 11:09:26 +0100
branchsvghmi
changeset 2826 1e5abecc3cde
parent 2825 b4b69e85ed53
child 2827 af32e80d108f
SVGHMI : support for HMI_STRING and HMI_BOOL
svghmi/gen_index_xhtml.xslt
svghmi/svghmi.c
svghmi/svghmi.js
svghmi/svghmi.py
tests/svghmi/plc.xml
tests/svghmi/svghmi_0@svghmi/svghmi.svg
--- a/svghmi/gen_index_xhtml.xslt	Tue Jan 14 11:04:18 2020 +0100
+++ b/svghmi/gen_index_xhtml.xslt	Tue Jan 14 11:09:26 2020 +0100
@@ -444,11 +444,27 @@
 </xsl:text>
     <xsl:text>const dvgetters = {
 </xsl:text>
-    <xsl:text>    INT: [DataView.prototype.getInt16, 2],
-</xsl:text>
-    <xsl:text>    BOOL: [DataView.prototype.getInt8, 1]
-</xsl:text>
-    <xsl:text>    /* TODO */
+    <xsl:text>    INT: (dv,offset) =&gt; [dv.getInt16(offset, true), 2],
+</xsl:text>
+    <xsl:text>    BOOL: (dv,offset) =&gt; [dv.getInt8(offset, true), 1],
+</xsl:text>
+    <xsl:text>    STRING: (dv, offset) =&gt; {
+</xsl:text>
+    <xsl:text>        size = dv.getInt8(offset);
+</xsl:text>
+    <xsl:text>        return [
+</xsl:text>
+    <xsl:text>            String.fromCharCode.apply(null, new Uint8Array(
+</xsl:text>
+    <xsl:text>                dv.buffer, /* original buffer */
+</xsl:text>
+    <xsl:text>                offset + 1, /* string starts after size*/
+</xsl:text>
+    <xsl:text>                size /* size of string */
+</xsl:text>
+    <xsl:text>            )), size + 1]; /* total increment */
+</xsl:text>
+    <xsl:text>    }
 </xsl:text>
     <xsl:text>};
 </xsl:text>
@@ -492,9 +508,9 @@
 </xsl:text>
     <xsl:text>            if(iectype != undefined){
 </xsl:text>
-    <xsl:text>                let [dvgetter, bytesize] = dvgetters[iectype];
-</xsl:text>
-    <xsl:text>                let value = dvgetter.call(dv,i,true);
+    <xsl:text>                let dvgetter = dvgetters[iectype];
+</xsl:text>
+    <xsl:text>                let [value, bytesize] = dvgetter(dv,i);
 </xsl:text>
     <xsl:text>                dispatch_value(index, value);
 </xsl:text>
--- a/svghmi/svghmi.c	Tue Jan 14 11:04:18 2020 +0100
+++ b/svghmi/svghmi.c	Tue Jan 14 11:09:26 2020 +0100
@@ -102,6 +102,9 @@
 
         /* if new value differs from previous one */
         USINT sz = __get_type_enum_size(dsc->type);
+        if(__Is_a_string(dsc)){
+            sz = ((STRING*)visible_value_p)->len + 1;
+        }
         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);
@@ -133,6 +136,9 @@
         {
             void *src_p = &wbuf[dsc->buf_index];
             void *dst_p = &sbuf[sbufidx];
+            if(__Is_a_string(dsc)){
+                sz = ((STRING*)src_p)->len + 1;
+            }
             /* TODO : force into little endian */
             memcpy(dst_p, &index, sizeof(uint32_t));
             memcpy(dst_p + sizeof(uint32_t), src_p, sz);
--- a/svghmi/svghmi.js	Tue Jan 14 11:04:18 2020 +0100
+++ b/svghmi/svghmi.js	Tue Jan 14 11:09:26 2020 +0100
@@ -46,9 +46,17 @@
 ws.binaryType = 'arraybuffer';
 
 const dvgetters = {
-    INT: [DataView.prototype.getInt16, 2],
-    BOOL: [DataView.prototype.getInt8, 1]
-    /* TODO */
+    INT: (dv,offset) => [dv.getInt16(offset, true), 2],
+    BOOL: (dv,offset) => [dv.getInt8(offset, true), 1],
+    STRING: (dv, offset) => {
+        size = dv.getInt8(offset);
+        return [
+            String.fromCharCode.apply(null, new Uint8Array(
+                dv.buffer, /* original buffer */
+                offset + 1, /* string starts after size*/
+                size /* size of string */
+            )), size + 1]; /* total increment */
+    }
 };
 
 // Register message reception handler 
@@ -70,8 +78,8 @@
             i += 4;
             let iectype = hmitree_types[index];
             if(iectype != undefined){
-                let [dvgetter, bytesize] = dvgetters[iectype];
-                let value = dvgetter.call(dv,i,true);
+                let dvgetter = dvgetters[iectype];
+                let [value, bytesize] = dvgetter(dv,i);
                 dispatch_value(index, value);
                 i += bytesize;
             } else {
--- a/svghmi/svghmi.py	Tue Jan 14 11:04:18 2020 +0100
+++ b/svghmi/svghmi.py	Tue Jan 14 11:09:26 2020 +0100
@@ -35,7 +35,7 @@
     "HMI_NODE":{},
     "HMI_STRING":{},
     "HMI_INT":{},
-    "HMI_REAL":{}
+    "HMI_BOOL":{}
 }
 
 HMI_TYPES = HMI_TYPES_DESC.keys()
--- a/tests/svghmi/plc.xml	Tue Jan 14 11:04:18 2020 +0100
+++ b/tests/svghmi/plc.xml	Tue Jan 14 11:09:26 2020 +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="2020-01-13T15:12:19">
+  <contentHeader name="Unnamed" modificationDateTime="2020-01-14T10:15:29">
     <coordinateInfo>
       <fbd>
         <scaling x="5" y="5"/>
@@ -87,6 +87,32 @@
                 <derived name="HMI_INT"/>
               </type>
             </variable>
+            <variable name="boolout">
+              <type>
+                <derived name="HMI_BOOL"/>
+              </type>
+            </variable>
+            <variable name="boolin">
+              <type>
+                <derived name="HMI_BOOL"/>
+              </type>
+              <initialValue>
+                <simpleValue value="True"/>
+              </initialValue>
+            </variable>
+            <variable name="strout">
+              <type>
+                <derived name="HMI_STRING"/>
+              </type>
+            </variable>
+            <variable name="strin">
+              <type>
+                <derived name="HMI_STRING"/>
+              </type>
+              <initialValue>
+                <simpleValue value="&quot;blup&quot;"/>
+              </initialValue>
+            </variable>
           </localVars>
         </interface>
         <body>
@@ -224,7 +250,7 @@
                     <relPosition x="0" y="50"/>
                     <connection refLocalId="9">
                       <position x="345" y="240"/>
-                      <position x="305" y="240"/>
+                      <position x="300" y="240"/>
                     </connection>
                   </connectionPointIn>
                 </variable>
@@ -239,12 +265,234 @@
               </outputVariables>
             </block>
             <inVariable localId="9" executionOrderId="0" height="30" width="60" negated="false">
-              <position x="245" y="225"/>
+              <position x="240" y="225"/>
               <connectionPointOut>
                 <relPosition x="60" y="15"/>
               </connectionPointOut>
               <expression>100</expression>
             </inVariable>
+            <block localId="10" typeName="CONCAT" executionOrderId="0" height="60" width="65">
+              <position x="360" y="345"/>
+              <inputVariables>
+                <variable formalParameter="IN1">
+                  <connectionPointIn>
+                    <relPosition x="0" y="30"/>
+                    <connection refLocalId="13" formalParameter="OUT">
+                      <position x="360" y="375"/>
+                      <position x="330" y="375"/>
+                      <position x="330" y="332"/>
+                      <position x="440" y="332"/>
+                      <position x="440" y="300"/>
+                      <position x="430" y="300"/>
+                    </connection>
+                  </connectionPointIn>
+                </variable>
+                <variable formalParameter="IN2">
+                  <connectionPointIn>
+                    <relPosition x="0" y="50"/>
+                    <connection refLocalId="14">
+                      <position x="360" y="395"/>
+                      <position x="322" y="395"/>
+                      <position x="322" y="400"/>
+                      <position x="285" y="400"/>
+                    </connection>
+                  </connectionPointIn>
+                </variable>
+              </inputVariables>
+              <inOutVariables/>
+              <outputVariables>
+                <variable formalParameter="OUT">
+                  <connectionPointOut>
+                    <relPosition x="65" y="30"/>
+                  </connectionPointOut>
+                </variable>
+              </outputVariables>
+            </block>
+            <outVariable localId="11" executionOrderId="0" height="30" width="58" negated="false">
+              <position x="495" y="355"/>
+              <connectionPointIn>
+                <relPosition x="0" y="15"/>
+                <connection refLocalId="10" formalParameter="OUT">
+                  <position x="495" y="370"/>
+                  <position x="450" y="370"/>
+                  <position x="450" y="375"/>
+                  <position x="425" y="375"/>
+                </connection>
+              </connectionPointIn>
+              <expression>strout</expression>
+            </outVariable>
+            <inVariable localId="12" executionOrderId="0" height="30" width="125" negated="false">
+              <position x="145" y="285"/>
+              <connectionPointOut>
+                <relPosition x="125" y="15"/>
+              </connectionPointOut>
+              <expression>TargetPressure</expression>
+            </inVariable>
+            <block localId="13" typeName="INT_TO_STRING" executionOrderId="0" height="40" width="115">
+              <position x="315" y="270"/>
+              <inputVariables>
+                <variable formalParameter="IN">
+                  <connectionPointIn>
+                    <relPosition x="0" y="30"/>
+                    <connection refLocalId="12">
+                      <position x="315" y="300"/>
+                      <position x="270" y="300"/>
+                    </connection>
+                  </connectionPointIn>
+                </variable>
+              </inputVariables>
+              <inOutVariables/>
+              <outputVariables>
+                <variable formalParameter="OUT">
+                  <connectionPointOut>
+                    <relPosition x="115" y="30"/>
+                  </connectionPointOut>
+                </variable>
+              </outputVariables>
+            </block>
+            <inVariable localId="14" executionOrderId="0" height="30" width="50" negated="false">
+              <position x="235" y="385"/>
+              <connectionPointOut>
+                <relPosition x="50" y="15"/>
+              </connectionPointOut>
+              <expression>strin</expression>
+            </inVariable>
+            <inVariable localId="15" executionOrderId="0" height="30" width="60" negated="false">
+              <position x="690" y="210"/>
+              <connectionPointOut>
+                <relPosition x="60" y="15"/>
+              </connectionPointOut>
+              <expression>boolin</expression>
+            </inVariable>
+            <outVariable localId="16" executionOrderId="0" height="30" width="70" negated="false">
+              <position x="915" y="240"/>
+              <connectionPointIn>
+                <relPosition x="0" y="15"/>
+                <connection refLocalId="17" formalParameter="OUT">
+                  <position x="915" y="255"/>
+                  <position x="880" y="255"/>
+                </connection>
+              </connectionPointIn>
+              <expression>boolout</expression>
+            </outVariable>
+            <block localId="17" typeName="AND" executionOrderId="0" height="60" width="65">
+              <position x="815" y="225"/>
+              <inputVariables>
+                <variable formalParameter="IN1">
+                  <connectionPointIn>
+                    <relPosition x="0" y="30"/>
+                    <connection refLocalId="15">
+                      <position x="815" y="255"/>
+                      <position x="762" y="255"/>
+                      <position x="762" y="225"/>
+                      <position x="750" y="225"/>
+                    </connection>
+                  </connectionPointIn>
+                </variable>
+                <variable formalParameter="IN2">
+                  <connectionPointIn>
+                    <relPosition x="0" y="50"/>
+                    <connection refLocalId="21" formalParameter="OUT">
+                      <position x="815" y="275"/>
+                      <position x="750" y="275"/>
+                    </connection>
+                  </connectionPointIn>
+                </variable>
+              </inputVariables>
+              <inOutVariables/>
+              <outputVariables>
+                <variable formalParameter="OUT">
+                  <connectionPointOut>
+                    <relPosition x="65" y="30"/>
+                  </connectionPointOut>
+                </variable>
+              </outputVariables>
+            </block>
+            <inVariable localId="18" executionOrderId="0" height="30" width="75" negated="false">
+              <position x="455" y="260"/>
+              <connectionPointOut>
+                <relPosition x="75" y="15"/>
+              </connectionPointOut>
+              <expression>Pressure</expression>
+            </inVariable>
+            <block localId="19" typeName="MOD" executionOrderId="0" height="60" width="65">
+              <position x="585" y="245"/>
+              <inputVariables>
+                <variable formalParameter="IN1">
+                  <connectionPointIn>
+                    <relPosition x="0" y="30"/>
+                    <connection refLocalId="18">
+                      <position x="585" y="275"/>
+                      <position x="530" y="275"/>
+                    </connection>
+                  </connectionPointIn>
+                </variable>
+                <variable formalParameter="IN2">
+                  <connectionPointIn>
+                    <relPosition x="0" y="50"/>
+                    <connection refLocalId="20">
+                      <position x="585" y="295"/>
+                      <position x="555" y="295"/>
+                    </connection>
+                  </connectionPointIn>
+                </variable>
+              </inputVariables>
+              <inOutVariables/>
+              <outputVariables>
+                <variable formalParameter="OUT">
+                  <connectionPointOut>
+                    <relPosition x="65" y="30"/>
+                  </connectionPointOut>
+                </variable>
+              </outputVariables>
+            </block>
+            <inVariable localId="20" executionOrderId="0" height="30" width="20" negated="false">
+              <position x="535" y="280"/>
+              <connectionPointOut>
+                <relPosition x="20" y="15"/>
+              </connectionPointOut>
+              <expression>2</expression>
+            </inVariable>
+            <block localId="21" typeName="EQ" executionOrderId="0" height="60" width="65">
+              <position x="685" y="245"/>
+              <inputVariables>
+                <variable formalParameter="IN1">
+                  <connectionPointIn>
+                    <relPosition x="0" y="30"/>
+                    <connection refLocalId="19" formalParameter="OUT">
+                      <position x="685" y="275"/>
+                      <position x="650" y="275"/>
+                    </connection>
+                  </connectionPointIn>
+                </variable>
+                <variable formalParameter="IN2">
+                  <connectionPointIn>
+                    <relPosition x="0" y="50"/>
+                    <connection refLocalId="22">
+                      <position x="685" y="295"/>
+                      <position x="670" y="295"/>
+                      <position x="670" y="330"/>
+                      <position x="650" y="330"/>
+                    </connection>
+                  </connectionPointIn>
+                </variable>
+              </inputVariables>
+              <inOutVariables/>
+              <outputVariables>
+                <variable formalParameter="OUT">
+                  <connectionPointOut>
+                    <relPosition x="65" y="30"/>
+                  </connectionPointOut>
+                </variable>
+              </outputVariables>
+            </block>
+            <inVariable localId="22" executionOrderId="0" height="30" width="20" negated="false">
+              <position x="630" y="315"/>
+              <connectionPointOut>
+                <relPosition x="20" y="15"/>
+              </connectionPointOut>
+              <expression>0</expression>
+            </inVariable>
           </FBD>
         </body>
       </pou>
--- a/tests/svghmi/svghmi_0@svghmi/svghmi.svg	Tue Jan 14 11:04:18 2020 +0100
+++ b/tests/svghmi/svghmi_0@svghmi/svghmi.svg	Tue Jan 14 11:09:26 2020 +0100
@@ -116,14 +116,14 @@
      inkscape:current-layer="hmi0"
      showgrid="false"
      units="px"
-     inkscape:zoom="0.8046875"
-     inkscape:cx="959.69683"
-     inkscape:cy="656.6094"
-     inkscape:window-width="1600"
-     inkscape:window-height="886"
+     inkscape:zoom="1.2321777"
+     inkscape:cx="398.68209"
+     inkscape:cy="328.86048"
+     inkscape:window-width="1920"
+     inkscape:window-height="2105"
      inkscape:window-x="0"
      inkscape:window-y="27"
-     inkscape:window-maximized="1"
+     inkscape:window-maximized="0"
      showguides="true"
      inkscape:guide-bbox="true" />
   <rect
@@ -898,4 +898,28 @@
        x="736.32812"
        y="1478.2422"
        style="fill:#82ff77;fill-opacity:1;stroke-width:1px;">8888</tspan></text>
+  <text
+     xml:space="preserve"
+     style="font-style:normal;font-weight:normal;font-size:80px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+     x="98.164062"
+     y="489.12109"
+     id="text134"
+     inkscape:label="HMI:Display@/PUMP0/STROUT"><tspan
+       sodipodi:role="line"
+       id="tspan132"
+       x="98.164062"
+       y="489.12109"
+       style="fill:#ffffff;fill-opacity:1;stroke-width:0.5px">8888</tspan></text>
+  <text
+     inkscape:label="HMI:Display@/PUMP0/BOOLOUT"
+     id="text138"
+     y="569.12109"
+     x="98.164062"
+     style="font-style:normal;font-weight:normal;font-size:80px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+     xml:space="preserve"><tspan
+       style="fill:#ffffff;fill-opacity:1;stroke-width:0.5px"
+       y="569.12109"
+       x="98.164062"
+       id="tspan136"
+       sodipodi:role="line">8888</tspan></text>
 </svg>