--- a/svghmi/widget_jsontable.ysl2 Mon Aug 24 09:48:35 2020 +0200
+++ b/svghmi/widget_jsontable.ysl2 Tue Aug 25 14:32:39 2020 +0200
@@ -7,7 +7,8 @@
@@ -155,15 +156,37 @@
template "svg:g", mode="json_table_render" {
- /* TODO : use intermediate variables for optimization
- foreach "$new_expressions"
- | let obj_«@id»_«position()» = «.»;
+ // use intermediate variables for optimization + const "varprefix" > obj_«$gid»_ + foreach "$expressions/expression"{ + | let «$varprefix»«position()» = «@content»; + | if(«$varprefix»«position()» == undefined) { + | console.log("«$varprefix»«position()» = «@content»"); + // because we put values in a variables, we can replace corresponding expression with variable name + const "new_expressions" foreach "$expressions/expression" xsl:copy { + attrib "content" > «$varprefix»«position()» + // revert hiding in case it did happen before + | id("«@id»").setAttribute("style", "«@style»"); const "label", "func:filter_non_widget_label(., $widget_elts)";
apply "*", mode="json_table_render" {
- with "expressions", "func:json_expressions($expressions, $label)";
+ with "expressions", "func:json_expressions(exsl:node-set($new_expressions), $label)"; with "widget_elts", "$widget_elts";
+ | id("«$gid»").setAttribute("style", "display:none"); template "widget[@type='JsonTable']", mode="widget_defs" {
@@ -171,7 +194,10 @@
optional_labels("forward backward cursor");
const "data_elt", "$result_svg_ns//*[@id = $hmi_element/@id]/*[@inkscape:label = 'data']";
- | spread_json_data: function(jdata) {
+ | visible: «count($data_elt/*[@inkscape:label])», + | spread_json_data: function(janswer) { + | let [range,position,jdata] = janswer; + | console.log(range,position,jdata); apply "$data_elt/*", mode="json_table_render" {
with "expressions","$initexpr_ns";
with "widget_elts","$hmi_element/*[@inkscape:label = 'data']/descendant::svg:*";
--- a/tests/svghmi/py_ext_0@py_ext/pyfile.xml Mon Aug 24 09:48:35 2020 +0200
+++ b/tests/svghmi/py_ext_0@py_ext/pyfile.xml Tue Aug 25 14:32:39 2020 +0200
@@ -1,33 +1,59 @@
<?xml version='1.0' encoding='utf-8'?>
<PyFile xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
- <variable name="SomePLCglobal" type="HMI_STRING" onchange="MyOnChangeFunc"/>
<variable name="AlarmNotify" type="HMI_INT"/>
+ <variable name="SendAlarm" type="HMI_BOOL" onchange="TriggerAlarm"/> + <variable name="AlarmText" type="HMI_STRING" initial="'POS'"/> + <variable name="AlarmStatus" type="HMI_STRING" initial="'alarm'"/> from twisted.web.resource import Resource
+import json, time, random +def TriggerAlarm(changed_var_name): + if(getattr(PLCGlobals, changed_var_name)): + Alarms.append((time.time(), PLCGlobals.AlarmText, PLCGlobals.AlarmStatus)) + PLCGlobals.AlarmNotify = random.randint(0, 4294967296) class AlarmJsonResource(Resource):
def render_GET(self, request):
def render_POST(self, request):
- newdata = request.content.getvalue()
+ newstr = request.content.getvalue() + newdata = json.loads(newstr) - print json.loads(newdata)
- {"name":"three", "sides":3, "textstyle":"alarm"},
- {"name":"four", "sides":4, "textstyle":"ack"},
- {"name":"five", "sides":5, "textstyle":"active"},
- {"name":"six", "sides":6, "textstyle":"disabled"},
- return json.dumps(selected_alarms)
+ vars = newdata[u'vars'] + args = newdata[u'args'] + visible = newdata[u'visible'] + svars = (vars + [0,0])[:3] + range_feedback = svars[1] + slider_position = svars[2] + answer = self.renderTable(range_feedback, slider_position, visible, *(args+svars[3:])) + janswer = json.dumps(answer) + def renderTable(self, old_range, old_position, visible, *options): + new_range = len(Alarms) + delta = new_range - visible + new_position = 0 if delta <= 0 else delta if old_position > delta else old_position + new_visible = new_range if delta <= 0 else visible + for ts, text, status in Alarms[new_position:new_position + new_visible]: + visible_alarms.append({ + "time": time.ctime(ts), + "text": text, # TODO translate text -def MyOnChangeFunc(changed_var_name):
- print changed_var_name + ": " + getattr(PLCGlobals, changed_var_name)
+ return new_range, new_position, visible_alarms --- a/tests/svghmi/svghmi_0@svghmi/svghmi.svg Mon Aug 24 09:48:35 2020 +0200
+++ b/tests/svghmi/svghmi_0@svghmi/svghmi.svg Tue Aug 25 14:32:39 2020 +0200
@@ -185,9 +185,9 @@
inkscape:current-layer="hmi0"
- inkscape:zoom="0.43668246"
- inkscape:cx="735.62981"
- inkscape:cy="-925.76586"
+ inkscape:zoom="0.61756226" + inkscape:cy="527.07406" inkscape:window-width="1800"
inkscape:window-height="836"
@@ -2639,196 +2639,6 @@
- transform="matrix(0.28590269,0,0,0.28590269,-13.279646,425.80032)"
- inkscape:label="HMI:Input@/SOMEPLCGLOBAL"
- style="stroke-width:2">
- style="font-style:normal;font-weight:normal;font-size:160px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- xml:space="preserve"><tspan
- style="stroke-width:2px"
- sodipodi:role="line">8888</tspan></text>
- style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ff00ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;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"
- inkscape:label="edit" />
- transform="translate(-416.52022,170.47452)"
- inkscape:label="+"dhu""
- style="stroke-width:2">
- 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:none;stroke-width:10;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"
- inkscape:transform-center-y="-14.956361"
- d="m 797.19546,145.18619 -80.62929,0.60214 -0.60215,-80.629288 80.6293,-0.60214 z"
- inkscape:connector-curvature="0" />
- style="font-style:normal;font-weight:normal;font-size:20px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- style="stroke-width:1px">dhu</tspan></text>
- transform="translate(-416.52022,170.47452)"
- inkscape:label="="plop""
- style="stroke-width:2">
- transform="matrix(0,-2.0000001,1.9999999,0,1034.195,1298.6541)"
- 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:none;stroke-width:10;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"
- sodipodi:cx="596.74072"
- sodipodi:cy="-184.98808"
- sodipodi:r1="29.912722"
- sodipodi:r2="14.956361"
- sodipodi:arg1="0.52359878"
- sodipodi:arg2="1.5707963"
- inkscape:flatsided="true"
- inkscape:randomized="0"
- d="m 622.6459,-170.03172 -51.81035,0 25.90517,-44.86908 z"
- inkscape:transform-center-y="-3.6154501e-05"
- inkscape:transform-center-x="14.956371" />
- style="font-style:normal;font-weight:normal;font-size:20px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- xml:space="preserve"><tspan
- style="stroke-width:1px"
- sodipodi:role="line">plop</tspan></text>
- transform="translate(-416.52022,170.47452)"
- inkscape:label="="mhoo""
- style="stroke-width:2">
- inkscape:transform-center-y="-5.9989963e-06"
- d="m 648.55108,-186.34718 -103.62071,0 51.81035,-89.73817 z"
- inkscape:randomized="0"
- inkscape:flatsided="true"
- sodipodi:arg2="1.5707963"
- sodipodi:arg1="0.52359878"
- sodipodi:r2="29.912722"
- sodipodi:r1="59.825443"
- sodipodi:cy="-216.2599"
- sodipodi:cx="596.74072"
- 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:none;stroke-width:10;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"
- transform="rotate(-90,746.45698,-44.543641)"
- inkscape:transform-center-x="14.956364" />
- style="font-style:normal;font-weight:normal;font-size:20px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- style="stroke-width:1px">mhoo</tspan></text>
- transform="translate(-416.52022,170.47452)"
- inkscape:label="="yodl""
- style="stroke-width:2">
- 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:none;stroke-width:10;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"
- sodipodi:cx="596.74072"
- sodipodi:cy="105.17262"
- sodipodi:r1="59.825443"
- sodipodi:r2="29.912722"
- sodipodi:arg1="0.52359878"
- sodipodi:arg2="1.5707963"
- inkscape:flatsided="true"
- inkscape:randomized="0"
- d="m 648.55108,135.08534 -103.62071,0 51.81035,-89.738161 z"
- inkscape:transform-center-y="-5.5023185e-06"
- transform="matrix(0,-1,-1,0,1043.9134,701.91334)"
- inkscape:transform-center-x="-14.956365" />
- style="font-style:normal;font-weight:normal;font-size:20px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- style="stroke-width:1px">yodl</tspan></text>
- transform="translate(-416.52022,170.47452)"
- inkscape:label="="mhe""
- style="stroke-width:2">
- inkscape:transform-center-y="-3.3040441e-05"
- d="m 622.6459,151.4008 -51.81035,0 25.90517,-44.86908 z"
- inkscape:randomized="0"
- inkscape:flatsided="true"
- sodipodi:arg2="1.5707963"
- sodipodi:arg1="0.52359878"
- sodipodi:r2="14.956361"
- sodipodi:r1="29.912722"
- sodipodi:cy="136.44444"
- sodipodi:cx="596.74072"
- 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:none;stroke-width:10;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"
- transform="matrix(0,-2.0000001,-1.9999999,0,1122.1514,1298.6541)"
- inkscape:transform-center-x="-14.956349" />
- style="font-style:normal;font-weight:normal;font-size:20px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- xml:space="preserve"><tspan
- style="stroke-width:1px"
- sodipodi:role="line">mhe</tspan></text>
inkscape:label="HMI:JsonTable:/alarms@/ALARMNOTIFY@.position@.range"
transform="matrix(0.5,0,0,0.5,515.30409,71.500438)">
@@ -2849,7 +2659,7 @@
transform="matrix(0.7609336,0,0,0.7609336,199.15217,164.3798)"
- inkscape:label=".sides" />
+ inkscape:label=".status" /> transform="matrix(2,0,0,2,-474.04606,349.02524)"
@@ -2858,7 +2668,16 @@
- inkscape:label=".textstyle textContent=.name" />
+ inkscape:label=".status textContent=.time" /> + inkscape:label=".status textContent=.text" + transform="matrix(2,0,0,2,-314.04606,349.02524)" /> @@ -2965,47 +2784,11 @@
inkscape:transform-center-x="0.14620371"
inkscape:transform-center-y="2.9995242"
- inkscape:transform-center-y="2.9995242"
- inkscape:transform-center-x="0.14620371"
- d="m 1101.9632,-226.81598 -19.398,0.92116 -0.6089,19.41024 -12.8146,-14.59158 -15.5551,11.62603 3.4184,-19.11656 -18.7881,-4.91281 17.0772,-9.24638 -7.8732,-17.75221 17.8766,7.58652 8.9704,-17.22384 5.2145,18.70661 19.0591,-3.72556 -11.3742,15.74025 z"
- inkscape:randomized="0"
- inkscape:flatsided="false"
- sodipodi:arg2="0.77735212"
- sodipodi:arg1="0.32855317"
- sodipodi:cy="-237.42258"
- sodipodi:cx="1070.8505"
- style="fill:#ba55d3;fill-opacity:1;stroke:#ff0000"
- inkscape:label="seven" />
- style="fill:#ffff00;fill-opacity:1;stroke:#ff0000"
- sodipodi:cx="1130.8505"
- sodipodi:cy="-237.42258"
- sodipodi:arg1="0.32855317"
- sodipodi:arg2="0.72125225"
- inkscape:flatsided="false"
- inkscape:randomized="0"
- d="m 1161.9632,-226.81598 -18.77,0.24617 2.1573,18.64723 -13.4465,-13.09832 -11.6601,14.71102 -0.2462,-18.76999 -18.6472,2.15729 13.0983,-13.44645 -14.711,-11.66015 18.77,-0.24617 -2.1573,-18.64723 13.4464,13.09832 11.6602,-14.71102 0.2461,18.77 18.6473,-2.1573 -13.0984,13.44646 z"
- inkscape:transform-center-x="0.14620371"
- inkscape:transform-center-y="2.9995242"
- inkscape:label="eight" />
inkscape:label="HMI:List"
- transform="translate(-126,32)">
+ transform="translate(-186,32)"> @@ -3017,7 +2800,7 @@
transform="translate(150.23297,80)"
+ inkscape:label="ack" /> @@ -3028,7 +2811,7 @@
transform="translate(93.515259,80)"
+ inkscape:label="alarm" /> @@ -3039,7 +2822,7 @@
transform="translate(33.666488,80)"
+ inkscape:label="active" /> @@ -3050,30 +2833,7 @@
transform="translate(-26.484802,80)"
- inkscape:transform-center-x="0.14620371"
- inkscape:transform-center-y="2.9995242"
- transform="translate(-85.692787,80)"
- inkscape:transform-center-x="0.14620371"
- inkscape:transform-center-y="2.9995242"
- transform="translate(-146.48474,80)"
+ inkscape:label="disabled" /> transform="matrix(3.3549332,0,0,3.14525,-181.87457,3116.0198)"
@@ -5986,4 +5746,113 @@
inkscape:label="HMI:VarInit:100@.range" />
+ inkscape:label="HMI:Input@/ALARMTEXT" + transform="matrix(0.5,0,0,0.5,377.5977,130.12206)"> + style="font-style:normal;font-weight:normal;font-size:160px;line-height:125%;font-family:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + inkscape:label="value"><tspan + style="text-align:end;text-anchor:end;stroke-width:2px">8888</tspan></text> + style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ff00ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;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" /> + style="stroke-width:1.04184687" + inkscape:label="HMI:Button@/SENDALARM" + transform="matrix(0.51020953,0,0,0.5903916,155.46943,-173.35252)"> + style="stroke-width:1.04184687" + inkscape:label="button" + 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.20923424;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" /> + style="stroke-width:1.04184687" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;display:inline;fill:#ff6600;fill-opacity:1;stroke:none;stroke-width:1.04184675px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + inkscape:label="setting_jmp"><tspan + style="text-align:center;text-anchor:middle;fill:#ff6600;stroke-width:1.04184675px">send</tspan></text> + transform="matrix(0.28590269,0,0,0.28590269,568.76957,-66.870442)" + inkscape:label="HMI:DropDown:active:warning:normal:ack@/ALARMSTATUS" + 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:#53676c;fill-opacity:1;fill-rule:nonzero;stroke:none;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" /> + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:80px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#d42aff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + style="text-align:start;text-anchor:start;fill:#d42aff;stroke-width:1px">sel_0</tspan></text> + inkscape:label="button" + inkscape:transform-center-y="10.92088" + d="m 1200.5,1018.6835 -18.9155,-32.76262 -18.9155,-32.76264 37.831,0 37.831,0 -18.9155,32.76264 z" + inkscape:randomized="0" + inkscape:flatsided="false" + sodipodi:arg2="2.6179939" + sodipodi:arg1="1.5707963" + sodipodi:r2="21.841761" + sodipodi:r1="43.683521" + style="opacity:1;vector-effect:none;fill:#a7a5a6;fill-opacity:1;stroke:none;stroke-width:0.35277769;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + sodipodi:type="star" />