--- 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>const dvgetters = {
- <xsl:text> INT: [DataView.prototype.getInt16, 2],
+ <xsl:text> INT: (dv,offset) => [dv.getInt16(offset, true), 2], + <xsl:text> BOOL: (dv,offset) => [dv.getInt8(offset, true), 1], + <xsl:text> STRING: (dv, offset) => { + <xsl:text> size = dv.getInt8(offset); - <xsl:text> BOOL: [DataView.prototype.getInt8, 1]
+ <xsl:text> String.fromCharCode.apply(null, new Uint8Array( + <xsl:text> dv.buffer, /* original buffer */ + <xsl:text> offset + 1, /* string starts after size*/
+ <xsl:text> size /* size of string */ + <xsl:text> )), size + 1]; /* total increment */ @@ -492,9 +508,9 @@
<xsl:text> if(iectype != undefined){
- <xsl:text> let [dvgetter, bytesize] = dvgetters[iectype];
+ <xsl:text> let dvgetter = dvgetters[iectype]; - <xsl:text> let value = dvgetter.call(dv,i,true);
+ <xsl:text> let [value, bytesize] = dvgetter(dv,i); <xsl:text> dispatch_value(index, value);
--- 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';
- INT: [DataView.prototype.getInt16, 2],
- BOOL: [DataView.prototype.getInt8, 1]
+ INT: (dv,offset) => [dv.getInt16(offset, true), 2], + BOOL: (dv,offset) => [dv.getInt8(offset, true), 1], + STRING: (dv, offset) => { + size = dv.getInt8(offset); + 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 @@
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);
--- 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_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"> @@ -87,6 +87,32 @@
<derived name="HMI_INT"/>
+ <variable name="boolout"> + <derived name="HMI_BOOL"/> + <variable name="boolin"> + <derived name="HMI_BOOL"/> + <simpleValue value="True"/> + <variable name="strout"> + <derived name="HMI_STRING"/> + <variable name="strin"> + <derived name="HMI_STRING"/> + <simpleValue value=""blup""/> @@ -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"/> @@ -239,12 +265,234 @@
<inVariable localId="9" executionOrderId="0" height="30" width="60" negated="false">
- <position x="245" y="225"/>
+ <position x="240" y="225"/> <relPosition x="60" y="15"/>
<expression>100</expression>
+ <block localId="10" typeName="CONCAT" executionOrderId="0" height="60" width="65"> + <position x="360" y="345"/> + <variable formalParameter="IN1"> + <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"/> + <variable formalParameter="IN2"> + <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"/> + <variable formalParameter="OUT"> + <relPosition x="65" y="30"/> + <outVariable localId="11" executionOrderId="0" height="30" width="58" negated="false"> + <position x="495" y="355"/> + <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"/> + <expression>strout</expression> + <inVariable localId="12" executionOrderId="0" height="30" width="125" negated="false"> + <position x="145" y="285"/> + <relPosition x="125" y="15"/> + <expression>TargetPressure</expression> + <block localId="13" typeName="INT_TO_STRING" executionOrderId="0" height="40" width="115"> + <position x="315" y="270"/> + <variable formalParameter="IN"> + <relPosition x="0" y="30"/> + <connection refLocalId="12"> + <position x="315" y="300"/> + <position x="270" y="300"/> + <variable formalParameter="OUT"> + <relPosition x="115" y="30"/> + <inVariable localId="14" executionOrderId="0" height="30" width="50" negated="false"> + <position x="235" y="385"/> + <relPosition x="50" y="15"/> + <expression>strin</expression> + <inVariable localId="15" executionOrderId="0" height="30" width="60" negated="false"> + <position x="690" y="210"/> + <relPosition x="60" y="15"/> + <expression>boolin</expression> + <outVariable localId="16" executionOrderId="0" height="30" width="70" negated="false"> + <position x="915" y="240"/> + <relPosition x="0" y="15"/> + <connection refLocalId="17" formalParameter="OUT"> + <position x="915" y="255"/> + <position x="880" y="255"/> + <expression>boolout</expression> + <block localId="17" typeName="AND" executionOrderId="0" height="60" width="65"> + <position x="815" y="225"/> + <variable formalParameter="IN1"> + <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"/> + <variable formalParameter="IN2"> + <relPosition x="0" y="50"/> + <connection refLocalId="21" formalParameter="OUT"> + <position x="815" y="275"/> + <position x="750" y="275"/> + <variable formalParameter="OUT"> + <relPosition x="65" y="30"/> + <inVariable localId="18" executionOrderId="0" height="30" width="75" negated="false"> + <position x="455" y="260"/> + <relPosition x="75" y="15"/> + <expression>Pressure</expression> + <block localId="19" typeName="MOD" executionOrderId="0" height="60" width="65"> + <position x="585" y="245"/> + <variable formalParameter="IN1"> + <relPosition x="0" y="30"/> + <connection refLocalId="18"> + <position x="585" y="275"/> + <position x="530" y="275"/> + <variable formalParameter="IN2"> + <relPosition x="0" y="50"/> + <connection refLocalId="20"> + <position x="585" y="295"/> + <position x="555" y="295"/> + <variable formalParameter="OUT"> + <relPosition x="65" y="30"/> + <inVariable localId="20" executionOrderId="0" height="30" width="20" negated="false"> + <position x="535" y="280"/> + <relPosition x="20" y="15"/> + <expression>2</expression> + <block localId="21" typeName="EQ" executionOrderId="0" height="60" width="65"> + <position x="685" y="245"/> + <variable formalParameter="IN1"> + <relPosition x="0" y="30"/> + <connection refLocalId="19" formalParameter="OUT"> + <position x="685" y="275"/> + <position x="650" y="275"/> + <variable formalParameter="IN2"> + <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"/> + <variable formalParameter="OUT"> + <relPosition x="65" y="30"/> + <inVariable localId="22" executionOrderId="0" height="30" width="20" negated="false"> + <position x="630" y="315"/> + <relPosition x="20" y="15"/> + <expression>0</expression> --- 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"
- inkscape:zoom="0.8046875"
- inkscape:cx="959.69683"
- 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-maximized="1"
+ inkscape:window-maximized="0" inkscape:guide-bbox="true" />
@@ -898,4 +898,28 @@
style="fill:#82ff77;fill-opacity:1;stroke-width:1px;">8888</tspan></text>
+ 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" + inkscape:label="HMI:Display@/PUMP0/STROUT"><tspan + style="fill:#ffffff;fill-opacity:1;stroke-width:0.5px">8888</tspan></text> + inkscape:label="HMI:Display@/PUMP0/BOOLOUT" + 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" + sodipodi:role="line">8888</tspan></text>