# HG changeset patch # User Edouard Tisserant <edouard.tisserant@gmail.com> # Date 1578996566 -3600 # Node ID 1e5abecc3cdef481a43c47d5de180e34c27ecf05 # Parent b4b69e85ed530a6668c5eb236caac6c9d9f113e6 SVGHMI : support for HMI_STRING and HMI_BOOL diff -r b4b69e85ed53 -r 1e5abecc3cde svghmi/gen_index_xhtml.xslt --- 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) => [dv.getInt16(offset, true), 2], +</xsl:text> + <xsl:text> BOOL: (dv,offset) => [dv.getInt8(offset, true), 1], +</xsl:text> + <xsl:text> STRING: (dv, offset) => { +</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> diff -r b4b69e85ed53 -r 1e5abecc3cde svghmi/svghmi.c --- 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); diff -r b4b69e85ed53 -r 1e5abecc3cde svghmi/svghmi.js --- 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 { diff -r b4b69e85ed53 -r 1e5abecc3cde svghmi/svghmi.py --- 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() diff -r b4b69e85ed53 -r 1e5abecc3cde tests/svghmi/plc.xml --- 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=""blup""/> + </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> diff -r b4b69e85ed53 -r 1e5abecc3cde tests/svghmi/svghmi_0@svghmi/svghmi.svg --- 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>