SVGHMI: fixed HMI->PLC dataflow : not updates as expected, and not initialized properly after subscribe.
--- 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>
--- 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"