Merge + fix side effects of making warning instead of errors in case of missing HMI variable
--- a/docutil/docsvg.py Wed Sep 16 09:42:26 2020 +0200
+++ b/docutil/docsvg.py Thu Sep 17 11:30:22 2020 +0200
@@ -34,16 +34,23 @@
if wx.Platform == '__WXMSW__':
from six.moves import winreg
try:
- svgexepath = winreg.QueryValue(winreg.HKEY_LOCAL_MACHINE,
- 'Software\\Classes\\svgfile\\shell\\Inkscape\\command')
+ svgexepath = winreg.QueryValue(winreg.HKEY_LOCAL_MACHINE,
+ 'Software\\Classes\\svgfile\\shell\\Inkscape\\command')
except OSError:
- svgexepath = winreg.QueryValue(winreg.HKEY_LOCAL_MACHINE,
- 'Software\\Classes\\inkscape.svg\\shell\\open\\command')
+ try:
+ svgexepath = winreg.QueryValue(winreg.HKEY_LOCAL_MACHINE,
+ 'Software\\Classes\\inkscape.svg\\shell\\open\\command')
+ except Exception:
+ return None
+
svgexepath = svgexepath.replace('"%1"', '').strip()
return svgexepath.replace('"', '')
else:
- # TODO: search path
- return os.path.join("/usr/bin", "inkscape")
+ # TODO: search for inkscape in $PATH
+ svgexepath = os.path.join("/usr/bin", "inkscape")
+ if os.path.exists(svgexepath):
+ return svgexepath
+ return None
def open_win_svg(svgexepath, svgfile):
--- a/modbus/mb_runtime.c Wed Sep 16 09:42:26 2020 +0200
+++ b/modbus/mb_runtime.c Thu Sep 17 11:30:22 2020 +0200
@@ -28,6 +28,7 @@
#include <errno.h>
#include <time.h>
#include <signal.h>
+#include <unistd.h> /* required for pause() */
#include "mb_slave_and_master.h"
#include "MB_%(locstr)s.h"
@@ -328,7 +329,7 @@
/*
struct timespec cur_time;
clock_gettime(CLOCK_MONOTONIC, &cur_time);
- fprintf(stderr, "Modbus client thread - new cycle (%%ld:%%ld)!\n", cur_time.tv_sec, cur_time.tv_nsec);
+ fprintf(stderr, "Modbus client thread (%%d) - new cycle (%%ld:%%ld)!\n", client_node_id, cur_time.tv_sec, cur_time.tv_nsec);
*/
int req;
for (req=0; req < NUMBER_OF_CLIENT_REQTS; req ++){
@@ -345,8 +346,10 @@
if ((client_requests[req].flag_exec_req == 0) && (client_nodes[client_requests[req].client_node_id].periodic_act == 0))
continue;
- //fprintf(stderr, "Modbus plugin: RUNNING<###> of Modbus request %%d (periodic = %%d flag_exec_req = %%d)\n",
- // req, client_nodes[client_requests[req].client_node_id].periodic_act, client_requests[req].flag_exec_req );
+ /*
+ fprintf(stderr, "Modbus client thread (%%d): RUNNING Modbus request %%d (periodic = %%d flag_exec_req = %%d)\n",
+ client_node_id, req, client_nodes[client_requests[req].client_node_id].periodic_act, client_requests[req].flag_exec_req );
+ */
int res_tmp = __execute_mb_request(req);
switch (res_tmp) {
@@ -433,102 +436,76 @@
-/* Function to activate a client node's thread */
-/* returns -1 if it could not send the signal */
-static int __signal_client_thread(int client_node_id) {
- /* We TRY to signal the client thread.
- * We do this because this function can be called at the end of the PLC scan cycle
- * and we don't want it to block at that time.
- */
- if (pthread_mutex_trylock(&(client_nodes[client_node_id].mutex)) != 0)
- return -1;
- client_nodes[client_node_id].execute_req = 1; // tell the thread to execute
- pthread_cond_signal (&(client_nodes[client_node_id].condv));
- pthread_mutex_unlock(&(client_nodes[client_node_id].mutex));
- return 0;
-}
-
-
-
-/* Function that will be called whenever a client node's periodic timer expires. */
-/* The client node's thread will be waiting on a condition variable, so this function simply signals that
- * condition variable.
+
+
+/* Thread that simply implements a periodic 'timer',
+ * i.e. periodically sends signal to the thread running __mb_client_thread()
*
- * The same callback function is called by the timers of all client nodes. The id of the client node
- * in question will be passed as a parameter to the call back function.
+ * Note that we do not use a posix timer (timer_create() ) because there doesn't seem to be a way
+ * of having the timer notify the thread that is portable across Xenomai and POSIX.
+ * - SIGEV_THREAD : not supported by Xenomai
+ * - SIGEV_THREAD_ID : Linux specific (i.e. non POSIX)
+ * Even so, I did not get it to work under Linux (issues with the header files)
+ * - SIGEV_SIGNAL : Will not work, as signal is sent to random thread in process!
*/
-void __client_node_timer_callback_function(int client_node_id) {
- /* signal the client node's condition variable on which the client node's thread should be waiting... */
- /* Since the communication cycle is run with the mutex locked, we use trylock() instead of lock() */
- if (pthread_mutex_trylock (&(client_nodes[client_node_id].mutex)) != 0)
- /* we never get to signal the thread for activation. But that is OK.
- * If it still in the communication cycle (during which the mutex is kept locked)
- * then that means that the communication cycle is falling behing in the periodic
- * communication cycle, and we therefore need to skip a period.
+static void *__mb_client_timer_thread(void *_index) {
+ int client_node_id = (char *)_index - (char *)NULL; // Use pointer arithmetic (more portable than cast)
+ struct timespec next_cycle;
+
+ int period_sec = client_nodes[client_node_id].comm_period / 1000; /* comm_period is in ms */
+ int period_nsec = (client_nodes[client_node_id].comm_period %%1000)*1000000; /* comm_period is in ms */
+
+ // Enable thread cancelation. Enabled is default, but set it anyway to be safe.
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+
+ if (client_nodes[client_node_id].comm_period <= 0) {
+ // No periodic activation required => nothing to do!
+ while (1) pause(); // wait to be canceled when program terminates (shutdown() is called)
+ return NULL; // not really necessary, just makes it easier to understand the code.
+ }
+
+ // get the current time
+ clock_gettime(CLOCK_MONOTONIC, &next_cycle);
+
+ while(1) {
+ // Determine absolute time instant for starting the next cycle
+ struct timespec prev_cycle, now;
+ prev_cycle = next_cycle;
+ timespec_add(next_cycle, period_sec, period_nsec);
+
+ /* NOTE:
+ * It is probably un-necessary to check for overflow of timer!
+ * Even in 32 bit systems this will take at least 68 years since the computer booted
+ * (remember, we are using CLOCK_MONOTONIC, which should start counting from 0
+ * every time the system boots). On 64 bit systems, it will take over
+ * 10^11 years to overflow.
*/
- return;
- client_nodes[client_node_id].execute_req = 1; // tell the thread to execute
- client_nodes[client_node_id].periodic_act = 1; // tell the thread the activation was done by periodic timer
- pthread_cond_signal (&(client_nodes[client_node_id].condv));
- pthread_mutex_unlock(&(client_nodes[client_node_id].mutex));
-}
-
-
-
-static int stop_mb_client_timer_thread;
-static void *__mb_client_timer_thread(void *_index) {
- sigset_t set;
- int signum;
- sigemptyset(&set);
- sigaddset(&set, SIGALRM);
-
- int client_node_id = (char *)_index - (char *)NULL; // Use pointer arithmetic (more portable than cast)
- /* initialize the timer that will be used to periodically activate the client node */
- {
- // start off by reseting the flag that will be set whenever the timer expires
- client_nodes[client_node_id].periodic_act = 0;
-
- if (timer_create(CLOCK_REALTIME, NULL, &(client_nodes[client_node_id].timer_id)) < 0) {
- fprintf(stderr, "Modbus plugin: Error (%%s) creating timer for modbus client node %%s\n", strerror(errno), client_nodes[client_node_id].location);
- return NULL;
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ if (next_cycle.tv_sec < prev_cycle.tv_sec) {
+ /* Timer overflow. See NOTE B above */
+ next_cycle = now;
+ timespec_add(next_cycle, period_sec, period_nsec);
+ }
+
+ while (0 != clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next_cycle, NULL));
+
+ /* signal the client node's condition variable on which the client node's thread should be waiting... */
+ /* Since the communication cycle is run with the mutex locked, we use trylock() instead of lock() */
+ if (pthread_mutex_trylock (&(client_nodes[client_node_id].mutex)) == 0) {
+ client_nodes[client_node_id].execute_req = 1; // tell the thread to execute
+ client_nodes[client_node_id].periodic_act = 1; // tell the thread the activation was done by periodic timer
+ pthread_cond_signal (&(client_nodes[client_node_id].condv));
+ pthread_mutex_unlock(&(client_nodes[client_node_id].mutex));
+ } else {
+ /* We never get to signal the thread for activation. But that is OK.
+ * If it still in the communication cycle (during which the mutex is kept locked)
+ * then that means that the communication cycle is falling behing in the periodic
+ * communication cycle, and we therefore need to skip a period.
+ */
}
}
- int period_sec = client_nodes[client_node_id].comm_period / 1000; /* comm_period is in ms */
- int period_nsec = (client_nodes[client_node_id].comm_period %%1000)*1000000; /* comm_period is in ms */
-
- // configure the timer for periodic activation
- {
- struct itimerspec timerspec;
- timerspec.it_interval.tv_sec = period_sec;
- timerspec.it_interval.tv_nsec = period_nsec;
- timerspec.it_value = timerspec.it_interval;
-
- if (timer_settime(client_nodes[client_node_id].timer_id, 0 /* flags */, &timerspec, NULL) < 0)
- fprintf(stderr, "Modbus plugin: Error configuring periodic activation timer for Modbus client %%s.\n", client_nodes[client_node_id].location);
- }
-
- stop_mb_client_timer_thread = 0;
- while(!stop_mb_client_timer_thread) {
- if(sigwait (&set, &signum) == -1)
- perror ("sigwait");
-
- if(stop_mb_client_timer_thread)
- break;
-
- if(signum == SIGALRM)
- __client_node_timer_callback_function(client_node_id);
- else
- fprintf(stderr, "Modbus plugin: spurious wakeup of timer thread for Modbus client %%s.\n", client_nodes[client_node_id].location);
-
- }
-
- // timer was created, so we try to destroy it!
- int res = timer_delete(client_nodes[client_node_id].timer_id);
- if (res < 0)
- fprintf(stderr, "Modbus plugin: Error destroying timer for modbus client node %%s\n", client_nodes[client_node_id].location);
-
- return NULL;
+ return NULL; // humour the compiler -> will never be executed!
}
@@ -740,13 +717,26 @@
*/
if ((client_requests[index].flag_exec_req != 0) && (0 == client_requests[index].flag_exec_started)) {
int client_node_id = client_requests[index].client_node_id;
- if (__signal_client_thread(client_node_id) >= 0) {
- /* - upon success, set flag_exec_started
- * - both flags (flag_exec_req and flag_exec_started) will be reset
- * once the transaction has completed.
- */
- client_requests[index].flag_exec_started = 1;
- }
+
+ /* We TRY to signal the client thread.
+ * We do this because this function can be called at the end of the PLC scan cycle
+ * and we don't want it to block at that time.
+ */
+ if (pthread_mutex_trylock(&(client_nodes[client_node_id].mutex)) == 0) {
+ client_nodes[client_node_id].execute_req = 1; // tell the thread to execute
+ pthread_cond_signal (&(client_nodes[client_node_id].condv));
+ pthread_mutex_unlock(&(client_nodes[client_node_id].mutex));
+ /* - upon success, set flag_exec_started
+ * - both flags (flag_exec_req and flag_exec_started) will be reset
+ * once the transaction has completed.
+ */
+ client_requests[index].flag_exec_started = 1;
+ } else {
+ /* The mutex is locked => the client thread is currently executing MB transactions.
+ * We will try to activate it in the next PLC cycle...
+ * For now, do nothing.
+ */
+ }
}
}
}
@@ -794,8 +784,8 @@
close = 0;
if (client_nodes[index].init_state >= 4) {
- stop_mb_client_timer_thread = 1;
- pthread_kill(client_nodes[index].timer_thread_id, SIGALRM);
+ // timer thread was launched, so we try to cancel it!
+ close = pthread_cancel(client_nodes[index].timer_thread_id);
close |= pthread_join (client_nodes[index].timer_thread_id, NULL);
if (close < 0)
fprintf(stderr, "Modbus plugin: Error closing timer thread for modbus client node %%s\n", client_nodes[index].location);
@@ -835,6 +825,7 @@
client_nodes[index].init_state = 0;
}
+//fprintf(stderr, "Modbus plugin: __cleanup_%%s() 5 close=%%d res=%%d\n", client_nodes[index].location, close, res);
/* kill thread and close connections of each modbus server node */
for (index=0; index < NUMBER_OF_SERVER_NODES; index++) {
close = 0;
--- a/modbus/mb_runtime.h Wed Sep 16 09:42:26 2020 +0200
+++ b/modbus/mb_runtime.h Thu Sep 17 11:30:22 2020 +0200
@@ -107,7 +107,6 @@
int prev_error; // error code of the last printed error message (0 when no error)
pthread_t thread_id; // thread handling all communication for this client node
pthread_t timer_thread_id; // thread handling periodical timer for this client node
- timer_t timer_id; // timer used to periodically activate this client node's thread
pthread_mutex_t mutex; // mutex to be used with the following condition variable
pthread_cond_t condv; // used to signal the client thread when to start new modbus transactions
int execute_req; /* used, in association with condition variable,
--- a/modbus/web_settings.py Wed Sep 16 09:42:26 2020 +0200
+++ b/modbus/web_settings.py Thu Sep 17 11:30:22 2020 +0200
@@ -183,7 +183,7 @@
("baud" , _("Baud Rate") , ctypes.c_int, MB_Baud ),
("parity" , _("Parity") , ctypes.c_int, MB_Parity ),
("stop_bits" , _("Stop Bits") , ctypes.c_int, MB_StopBits ),
- ("slave_id" , _("Slave ID") , ctypes.c_ulonglong, annotate.Integer)
+ ("slave_id" , _("Slave ID") , ctypes.c_ubyte, annotate.Integer)
]
@@ -228,7 +228,7 @@
# This allows us to confirm the saved data contains the correct addr_type
# when loading from file
save_info = {}
- save_info["addr_type"] = ["addr_type"]
+ save_info["addr_type"] = WebNode_entry["addr_type"]
save_info["node_type"] = WebNode_entry["node_type"]
save_info["config" ] = newConfig
@@ -262,7 +262,7 @@
filename = _WebNodeList[WebNode_id]["filename"]
try:
#if os.path.isfile(filename):
- save_info = json.load(open(filename))
+ save_info = json.load(open(os.path.realpath(filename)))
except Exception:
return None
--- a/plcopen/plcopen.py Wed Sep 16 09:42:26 2020 +0200
+++ b/plcopen/plcopen.py Thu Sep 17 11:30:22 2020 +0200
@@ -331,12 +331,16 @@
def SaveProject(project, filepath):
- project_file = open(filepath, 'w')
- project_file.write(etree.tostring(
+ content = etree.tostring(
project,
pretty_print=True,
xml_declaration=True,
- encoding='utf-8'))
+ encoding='utf-8')
+
+ assert len(content) != 0
+
+ project_file = open(filepath, 'w')
+ project_file.write(content)
project_file.close()
--- a/runtime/PLCObject.py Wed Sep 16 09:42:26 2020 +0200
+++ b/runtime/PLCObject.py Thu Sep 17 11:30:22 2020 +0200
@@ -440,6 +440,7 @@
if cmd == "Activate":
self.PythonRuntimeCall("start")
+ self.PreStartPLC()
self.PythonThreadLoop()
self.PythonRuntimeCall("stop", reverse_order=True)
else: # "Finish"
@@ -471,8 +472,6 @@
if not self.LoadPLC():
self._fail(_("Problem starting PLC : can't load PLC"))
- self.PreStartPLC()
-
if self.CurrentPLCFilename is not None and self.PLCStatus == PlcStatus.Stopped:
c_argv = ctypes.c_char_p * len(self.argv)
res = self._startPLC(len(self.argv), c_argv(*self.argv))
--- a/svghmi/gen_index_xhtml.xslt Wed Sep 16 09:42:26 2020 +0200
+++ b/svghmi/gen_index_xhtml.xslt Thu Sep 17 11:30:22 2020 +0200
@@ -1,9 +1,9 @@
<?xml version="1.0"?>
-<xsl:stylesheet xmlns:ns="beremiz" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:exsl="http://exslt.org/common" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:preamble="preamble" xmlns:regexp="http://exslt.org/regular-expressions" xmlns:svg="http://www.w3.org/2000/svg" xmlns:debug="debug" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:definitions="definitions" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:cc="http://creativecommons.org/ns#" xmlns:declarations="declarations" xmlns:func="http://exslt.org/functions" xmlns:str="http://exslt.org/strings" xmlns:epilogue="epilogue" extension-element-prefixes="ns func exsl regexp str dyn" version="1.0" exclude-result-prefixes="ns func exsl regexp str dyn debug preamble epilogue declarations definitions">
- <xsl:output cdata-section-elements="xhtml:script" method="xml"/>
- <xsl:variable select="/svg:svg" name="svg"/>
- <xsl:variable select="//svg:*[starts-with(@inkscape:label, 'HMI:')]" name="hmi_elements"/>
- <xsl:variable select="ns:GetHMITree()" name="hmitree"/>
+<xsl:stylesheet xmlns:ns="beremiz" xmlns:definitions="definitions" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:func="http://exslt.org/functions" xmlns:epilogue="epilogue" xmlns:preamble="preamble" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:svg="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:str="http://exslt.org/strings" xmlns:regexp="http://exslt.org/regular-expressions" xmlns:exsl="http://exslt.org/common" xmlns:declarations="declarations" xmlns:debug="debug" exclude-result-prefixes="ns func exsl regexp str dyn debug preamble epilogue declarations definitions" extension-element-prefixes="ns func exsl regexp str dyn" version="1.0">
+ <xsl:output method="xml" cdata-section-elements="xhtml:script"/>
+ <xsl:variable name="svg" select="/svg:svg"/>
+ <xsl:variable name="hmi_elements" select="//svg:*[starts-with(@inkscape:label, 'HMI:')]"/>
+ <xsl:variable name="hmitree" select="ns:GetHMITree()"/>
<xsl:variable name="_categories">
<noindex>
<xsl:text>HMI_PLC_STATUS</xsl:text>
@@ -12,11 +12,11 @@
<xsl:text>HMI_CURRENT_PAGE</xsl:text>
</noindex>
</xsl:variable>
- <xsl:variable select="exsl:node-set($_categories)" name="categories"/>
+ <xsl:variable name="categories" select="exsl:node-set($_categories)"/>
<xsl:variable name="_indexed_hmitree">
<xsl:apply-templates mode="index" select="$hmitree"/>
</xsl:variable>
- <xsl:variable select="exsl:node-set($_indexed_hmitree)" name="indexed_hmitree"/>
+ <xsl:variable name="indexed_hmitree" select="exsl:node-set($_indexed_hmitree)"/>
<preamble:hmi-tree/>
<xsl:template match="preamble:hmi-tree">
<xsl:text>
@@ -63,8 +63,8 @@
</xsl:text>
</xsl:template>
<xsl:template mode="index" match="*">
- <xsl:param select="0" name="index"/>
- <xsl:param select="''" name="parentpath"/>
+ <xsl:param name="index" select="0"/>
+ <xsl:param name="parentpath" select="''"/>
<xsl:variable name="content">
<xsl:variable name="path">
<xsl:choose>
@@ -96,7 +96,7 @@
</xsl:for-each>
</xsl:copy>
<xsl:apply-templates mode="index" select="*[1]">
- <xsl:with-param select="$index + 1" name="index"/>
+ <xsl:with-param name="index" select="$index + 1"/>
<xsl:with-param name="parentpath">
<xsl:value-of select="$path"/>
</xsl:with-param>
@@ -104,7 +104,7 @@
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates mode="index" select="*[1]">
- <xsl:with-param select="$index" name="index"/>
+ <xsl:with-param name="index" select="$index"/>
<xsl:with-param name="parentpath">
<xsl:value-of select="$path"/>
</xsl:with-param>
@@ -114,16 +114,16 @@
</xsl:variable>
<xsl:copy-of select="$content"/>
<xsl:apply-templates mode="index" select="following-sibling::*[1]">
- <xsl:with-param select="$index + count(exsl:node-set($content)/*)" name="index"/>
+ <xsl:with-param name="index" select="$index + count(exsl:node-set($content)/*)"/>
<xsl:with-param name="parentpath">
<xsl:value-of select="$parentpath"/>
</xsl:with-param>
</xsl:apply-templates>
</xsl:template>
<xsl:template mode="parselabel" match="*">
- <xsl:variable select="@inkscape:label" name="label"/>
- <xsl:variable select="substring-after($label,'HMI:')" name="description"/>
- <xsl:variable select="substring-before($description,'@')" name="_args"/>
+ <xsl:variable name="label" select="@inkscape:label"/>
+ <xsl:variable name="description" select="substring-after($label,'HMI:')"/>
+ <xsl:variable name="_args" select="substring-before($description,'@')"/>
<xsl:variable name="args">
<xsl:choose>
<xsl:when test="$_args">
@@ -134,7 +134,7 @@
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
- <xsl:variable select="substring-before($args,':')" name="_type"/>
+ <xsl:variable name="_type" select="substring-before($args,':')"/>
<xsl:variable name="type">
<xsl:choose>
<xsl:when test="$_type">
@@ -160,15 +160,15 @@
</xsl:attribute>
</arg>
</xsl:for-each>
- <xsl:variable select="substring-after($description,'@')" name="paths"/>
+ <xsl:variable name="paths" select="substring-after($description,'@')"/>
<xsl:for-each select="str:split($paths, '@')">
<xsl:if test="string-length(.) > 0">
<path>
<xsl:attribute name="value">
<xsl:value-of select="."/>
</xsl:attribute>
- <xsl:variable select="." name="path"/>
- <xsl:variable select="$indexed_hmitree/*[@hmipath = $path]" name="item"/>
+ <xsl:variable name="path" select="."/>
+ <xsl:variable name="item" select="$indexed_hmitree/*[@hmipath = $path]"/>
<xsl:choose>
<xsl:when test="count($item) = 1">
<xsl:attribute name="index">
@@ -202,7 +202,7 @@
<xsl:variable name="_parsed_widgets">
<xsl:apply-templates mode="parselabel" select="$hmi_elements"/>
</xsl:variable>
- <xsl:variable select="exsl:node-set($_parsed_widgets)" name="parsed_widgets"/>
+ <xsl:variable name="parsed_widgets" select="exsl:node-set($_parsed_widgets)"/>
<func:function name="func:widget">
<xsl:param name="id"/>
<func:result select="$parsed_widgets/widget[@id = $id]"/>
@@ -215,12 +215,12 @@
<func:function name="func:same_class_paths">
<xsl:param name="a"/>
<xsl:param name="b"/>
- <xsl:variable select="$indexed_hmitree/*[@hmipath = $a]/@class" name="class_a"/>
- <xsl:variable select="$indexed_hmitree/*[@hmipath = $b]/@class" name="class_b"/>
+ <xsl:variable name="class_a" select="$indexed_hmitree/*[@hmipath = $a]/@class"/>
+ <xsl:variable name="class_b" select="$indexed_hmitree/*[@hmipath = $b]/@class"/>
<func:result select="$class_a and $class_b and $class_a = $class_b"/>
</func:function>
<xsl:template mode="testtree" match="*">
- <xsl:param select="''" name="indent"/>
+ <xsl:param name="indent" select="''"/>
<xsl:value-of select="$indent"/>
<xsl:text> </xsl:text>
<xsl:value-of select="local-name()"/>
@@ -266,7 +266,7 @@
<xsl:text>
</xsl:text>
</xsl:template>
- <xsl:variable select="ns:GetSVGGeometry()" name="geometry"/>
+ <xsl:variable name="geometry" select="ns:GetSVGGeometry()"/>
<debug:geometry/>
<xsl:template match="debug:geometry">
<xsl:text>
@@ -301,8 +301,8 @@
<xsl:param name="a1"/>
<xsl:param name="b0"/>
<xsl:param name="b1"/>
- <xsl:variable select="$a0 >= $b0" name="d0"/>
- <xsl:variable select="$a1 >= $b1" name="d1"/>
+ <xsl:variable name="d0" select="$a0 >= $b0"/>
+ <xsl:variable name="d1" select="$a1 >= $b1"/>
<xsl:choose>
<xsl:when test="not($d0) and $d1">
<func:result select="3"/>
@@ -324,10 +324,10 @@
<func:function name="func:intersect">
<xsl:param name="a"/>
<xsl:param name="b"/>
- <xsl:variable select="func:intersect_1d($a/@x, $a/@x+$a/@w, $b/@x, $b/@x+$b/@w)" name="x_intersect"/>
+ <xsl:variable name="x_intersect" select="func:intersect_1d($a/@x, $a/@x+$a/@w, $b/@x, $b/@x+$b/@w)"/>
<xsl:choose>
<xsl:when test="$x_intersect != 0">
- <xsl:variable select="func:intersect_1d($a/@y, $a/@y+$a/@h, $b/@y, $b/@y+$b/@h)" name="y_intersect"/>
+ <xsl:variable name="y_intersect" select="func:intersect_1d($a/@y, $a/@y+$a/@h, $b/@y, $b/@y+$b/@h)"/>
<func:result select="$x_intersect * $y_intersect"/>
</xsl:when>
<xsl:otherwise>
@@ -337,13 +337,13 @@
</func:function>
<func:function name="func:overlapping_geometry">
<xsl:param name="elt"/>
- <xsl:variable select="/svg:svg | //svg:g" name="groups"/>
- <xsl:variable select="$geometry[@Id = $elt/@id]" name="g"/>
- <xsl:variable select="$geometry[@Id != $elt/@id]" name="candidates"/>
+ <xsl:variable name="groups" select="/svg:svg | //svg:g"/>
+ <xsl:variable name="g" select="$geometry[@Id = $elt/@id]"/>
+ <xsl:variable name="candidates" select="$geometry[@Id != $elt/@id]"/>
<func:result select="$candidates[(@Id = $groups/@id and (func:intersect($g, .) = 9)) or (not(@Id = $groups/@id) and (func:intersect($g, .) > 0 ))]"/>
</func:function>
- <xsl:variable select="$parsed_widgets/widget[@type = 'Page']" name="hmi_pages_descs"/>
- <xsl:variable select="$hmi_elements[@id = $hmi_pages_descs/@id]" name="hmi_pages"/>
+ <xsl:variable name="hmi_pages_descs" select="$parsed_widgets/widget[@type = 'Page']"/>
+ <xsl:variable name="hmi_pages" select="$hmi_elements[@id = $hmi_pages_descs/@id]"/>
<xsl:variable name="default_page">
<xsl:choose>
<xsl:when test="count($hmi_pages) > 1">
@@ -383,13 +383,13 @@
<xsl:text>
</xsl:text>
</xsl:template>
- <xsl:variable select="$parsed_widgets/widget[@type = 'Keypad']" name="keypads_descs"/>
- <xsl:variable select="$hmi_elements[@id = $keypads_descs/@id]" name="keypads"/>
+ <xsl:variable name="keypads_descs" select="$parsed_widgets/widget[@type = 'Keypad']"/>
+ <xsl:variable name="keypads" select="$hmi_elements[@id = $keypads_descs/@id]"/>
<func:function name="func:refered_elements">
<xsl:param name="elems"/>
- <xsl:variable select="$elems/descendant-or-self::svg:*" name="descend"/>
- <xsl:variable select="$descend[self::svg:use]" name="clones"/>
- <xsl:variable select="//svg:*[concat('#',@id) = $clones/@xlink:href]" name="originals"/>
+ <xsl:variable name="descend" select="$elems/descendant-or-self::svg:*"/>
+ <xsl:variable name="clones" select="$descend[self::svg:use]"/>
+ <xsl:variable name="originals" select="//svg:*[concat('#',@id) = $clones/@xlink:href]"/>
<xsl:choose>
<xsl:when test="$originals">
<func:result select="$descend | func:refered_elements($originals)"/>
@@ -401,9 +401,9 @@
</func:function>
<func:function name="func:all_related_elements">
<xsl:param name="page"/>
- <xsl:variable select="func:overlapping_geometry($page)" name="page_overlapping_geometry"/>
- <xsl:variable select="//svg:*[@id = $page_overlapping_geometry/@Id]" name="page_overlapping_elements"/>
- <xsl:variable select="func:refered_elements($page | $page_overlapping_elements)" name="page_sub_elements"/>
+ <xsl:variable name="page_overlapping_geometry" select="func:overlapping_geometry($page)"/>
+ <xsl:variable name="page_overlapping_elements" select="//svg:*[@id = $page_overlapping_geometry/@Id]"/>
+ <xsl:variable name="page_sub_elements" select="func:refered_elements($page | $page_overlapping_elements)"/>
<func:result select="$page_sub_elements"/>
</func:function>
<func:function name="func:required_elements">
@@ -417,13 +417,13 @@
</xsl:otherwise>
</xsl:choose>
</func:function>
- <xsl:variable select="//svg:defs/descendant-or-self::svg:* | func:required_elements($hmi_pages | $keypads)/ancestor-or-self::svg:*" name="required_elements"/>
- <xsl:variable select="//svg:*[not(@id = $required_elements/@id)]" name="discardable_elements"/>
+ <xsl:variable name="required_elements" select="//svg:defs/descendant-or-self::svg:* | func:required_elements($hmi_pages | $keypads)/ancestor-or-self::svg:*"/>
+ <xsl:variable name="discardable_elements" select="//svg:*[not(@id = $required_elements/@id)]"/>
<func:function name="func:sumarized_elements">
<xsl:param name="elements"/>
- <xsl:variable select="$elements[not(ancestor::*/@id = $elements/@id)]" name="short_list"/>
- <xsl:variable select="$short_list/parent::svg:*[ not(descendant::*[ not(self::svg:g) and not(@id = $discardable_elements/@id) and not(@id = $short_list/descendant-or-self::*[not(self::svg:g)]/@id) ])]" name="filled_groups"/>
- <xsl:variable select="$filled_groups[not(ancestor::*/@id = $filled_groups/@id)]" name="groups_to_add"/>
+ <xsl:variable name="short_list" select="$elements[not(ancestor::*/@id = $elements/@id)]"/>
+ <xsl:variable name="filled_groups" select="$short_list/parent::svg:*[ not(descendant::*[ not(self::svg:g) and not(@id = $discardable_elements/@id) and not(@id = $short_list/descendant-or-self::*[not(self::svg:g)]/@id) ])]"/>
+ <xsl:variable name="groups_to_add" select="$filled_groups[not(ancestor::*/@id = $filled_groups/@id)]"/>
<func:result select="$groups_to_add | $short_list[not(ancestor::svg:g/@id = $filled_groups/@id)]"/>
</func:function>
<func:function name="func:detachable_elements">
@@ -437,8 +437,8 @@
</xsl:otherwise>
</xsl:choose>
</func:function>
- <xsl:variable select="func:detachable_elements($hmi_pages | $keypads)" name="_detachable_elements"/>
- <xsl:variable select="$_detachable_elements[not(ancestor::*/@id = $_detachable_elements/@id)]" name="detachable_elements"/>
+ <xsl:variable name="_detachable_elements" select="func:detachable_elements($hmi_pages | $keypads)"/>
+ <xsl:variable name="detachable_elements" select="$_detachable_elements[not(ancestor::*/@id = $_detachable_elements/@id)]"/>
<declarations:detachable-elements/>
<xsl:template match="declarations:detachable-elements">
<xsl:text>
@@ -472,18 +472,18 @@
<xsl:text>
</xsl:text>
</xsl:template>
- <xsl:variable select="$parsed_widgets/widget[@type = 'ForEach']/@id" name="forEach_widgets_ids"/>
- <xsl:variable select="$hmi_elements[@id = $forEach_widgets_ids]" name="forEach_widgets"/>
- <xsl:variable select="func:refered_elements($forEach_widgets)[not(@id = $forEach_widgets_ids)]/@id" name="in_forEach_widget_ids"/>
+ <xsl:variable name="forEach_widgets_ids" select="$parsed_widgets/widget[@type = 'ForEach']/@id"/>
+ <xsl:variable name="forEach_widgets" select="$hmi_elements[@id = $forEach_widgets_ids]"/>
+ <xsl:variable name="in_forEach_widget_ids" select="func:refered_elements($forEach_widgets)[not(@id = $forEach_widgets_ids)]/@id"/>
<xsl:template mode="page_desc" match="svg:*">
- <xsl:variable select="func:widget(@id)" name="desc"/>
- <xsl:variable select="." name="page"/>
- <xsl:variable select="$geometry[@Id = $page/@id]" name="p"/>
- <xsl:variable select="func:all_related_elements($page)" name="page_all_elements"/>
- <xsl:variable select="$hmi_elements[@id = $page_all_elements/@id and @id != $page/@id]" name="all_page_widgets"/>
- <xsl:variable select="$all_page_widgets[not(@id=$in_forEach_widget_ids)]" name="page_managed_widgets"/>
- <xsl:variable select="$page_managed_widgets[func:is_descendant_path(func:widget(@id)/path/@value, $desc/path/@value)]" name="page_relative_widgets"/>
- <xsl:variable select="func:sumarized_elements($page_all_elements)/ ancestor-or-self::*[@id = $detachable_elements/@id]" name="required_detachables"/>
+ <xsl:variable name="desc" select="func:widget(@id)"/>
+ <xsl:variable name="page" select="."/>
+ <xsl:variable name="p" select="$geometry[@Id = $page/@id]"/>
+ <xsl:variable name="page_all_elements" select="func:all_related_elements($page)"/>
+ <xsl:variable name="all_page_widgets" select="$hmi_elements[@id = $page_all_elements/@id and @id != $page/@id]"/>
+ <xsl:variable name="page_managed_widgets" select="$all_page_widgets[not(@id=$in_forEach_widget_ids)]"/>
+ <xsl:variable name="page_relative_widgets" select="$page_managed_widgets[func:is_descendant_path(func:widget(@id)/path/@value, $desc/path/@value)]"/>
+ <xsl:variable name="required_detachables" select="func:sumarized_elements($page_all_elements)/ ancestor-or-self::*[@id = $detachable_elements/@id]"/>
<xsl:text> "</xsl:text>
<xsl:value-of select="$desc/arg[1]/@value"/>
<xsl:text>": {
@@ -540,10 +540,10 @@
<xsl:text> jumps: [
</xsl:text>
<xsl:for-each select="$parsed_widgets/widget[@id = $all_page_widgets/@id and @type='Jump']">
- <xsl:variable select="@id" name="_id"/>
+ <xsl:variable name="_id" select="@id"/>
<xsl:variable name="opts">
<xsl:call-template name="jump_widget_activity">
- <xsl:with-param select="$hmi_elements[@id=$_id]" name="hmi_element"/>
+ <xsl:with-param name="hmi_element" select="$hmi_elements[@id=$_id]"/>
</xsl:call-template>
</xsl:variable>
<xsl:if test="string-length($opts)>0">
@@ -576,7 +576,7 @@
<xsl:text> }
</xsl:text>
<xsl:apply-templates mode="per_page_widget_template" select="$parsed_widgets/widget[@id = $all_page_widgets/@id]">
- <xsl:with-param select="$desc" name="page_desc"/>
+ <xsl:with-param name="page_desc" select="$desc"/>
</xsl:apply-templates>
<xsl:text> }</xsl:text>
<xsl:if test="position()!=last()">
@@ -637,7 +637,10 @@
<xsl:text>
</xsl:text>
</xsl:template>
- <xsl:template mode="inline_svg" match="@* | node()">
+ <xsl:template xmlns="http://www.w3.org/2000/svg" mode="inline_svg" match="@*">
+ <xsl:copy/>
+ </xsl:template>
+ <xsl:template mode="inline_svg" match="node()">
<xsl:if test="not(@id = $discardable_elements/@id)">
<xsl:copy>
<xsl:apply-templates mode="inline_svg" select="@* | node()"/>
@@ -670,23 +673,26 @@
<xsl:text>All units must be set to "px" in Inkscape's document properties</xsl:text>
</xsl:message>
</xsl:template>
- <xsl:variable select="$parsed_widgets/widget[@type = 'List']" name="hmi_lists_descs"/>
- <xsl:variable select="$hmi_elements[@id = $hmi_lists_descs/@id]" name="hmi_lists"/>
- <xsl:variable select="$hmi_lists/descendant-or-self::svg:*" name="targets_not_to_unlink"/>
- <xsl:variable select="$hmi_elements[not(@id = $hmi_pages/@id)]/descendant-or-self::svg:use" name="to_unlink"/>
+ <xsl:variable name="hmi_lists_descs" select="$parsed_widgets/widget[@type = 'List']"/>
+ <xsl:variable name="hmi_lists" select="$hmi_elements[@id = $hmi_lists_descs/@id]"/>
+ <xsl:variable name="targets_not_to_unlink" select="$hmi_lists/descendant-or-self::svg:*"/>
+ <xsl:variable name="to_unlink" select="$hmi_elements[not(@id = $hmi_pages/@id)]/descendant-or-self::svg:use"/>
+ <func:function name="func:is_unlinkable">
+ <xsl:param name="targetid"/>
+ <xsl:param name="eltid"/>
+ <func:result select="$eltid = $to_unlink/@id and not($targetid = $targets_not_to_unlink/@id)"/>
+ </func:function>
<xsl:template xmlns="http://www.w3.org/2000/svg" mode="inline_svg" match="svg:use">
- <xsl:param name="seed"/>
- <xsl:variable select="substring-after(@xlink:href,'#')" name="targetid"/>
+ <xsl:variable name="targetid" select="substring-after(@xlink:href,'#')"/>
<xsl:choose>
- <xsl:when test="@id = $to_unlink/@id and not($targetid = $targets_not_to_unlink/@id)">
+ <xsl:when test="func:is_unlinkable($targetid, @id)">
<xsl:call-template name="unlink_clone">
- <xsl:with-param select="$targetid" name="targetid"/>
- <xsl:with-param select="$seed" name="seed"/>
+ <xsl:with-param name="targetid" select="$targetid"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
- <xsl:apply-templates mode="inline_svg" select="@* | node()"/>
+ <xsl:apply-templates mode="inline_svg" select="@*"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
@@ -711,7 +717,7 @@
<xsl:text>id</xsl:text>
</name>
</xsl:variable>
- <xsl:variable select="exsl:node-set($_excluded_use_attrs)" name="excluded_use_attrs"/>
+ <xsl:variable name="excluded_use_attrs" select="exsl:node-set($_excluded_use_attrs)"/>
<xsl:variable name="_merge_use_attrs">
<name>
<xsl:text>transform</xsl:text>
@@ -720,16 +726,30 @@
<xsl:text>style</xsl:text>
</name>
</xsl:variable>
- <xsl:variable select="exsl:node-set($_merge_use_attrs)" name="merge_use_attrs"/>
+ <xsl:variable name="merge_use_attrs" select="exsl:node-set($_merge_use_attrs)"/>
<xsl:template xmlns="http://www.w3.org/2000/svg" name="unlink_clone">
<xsl:param name="targetid"/>
- <xsl:param name="seed"/>
- <xsl:variable select="//svg:*[@id = $targetid]" name="target"/>
- <xsl:variable select="concat($seed, @id)" name="seeded_id"/>
+ <xsl:param name="seed" select="''"/>
+ <xsl:variable name="target" select="//svg:*[@id = $targetid]"/>
+ <xsl:variable name="seeded_id">
+ <xsl:choose>
+ <xsl:when test="string-length($seed) > 0">
+ <xsl:value-of select="$seed"/>
+ <xsl:text>_</xsl:text>
+ <xsl:value-of select="@id"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@id"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
<g>
<xsl:attribute name="id">
<xsl:value-of select="$seeded_id"/>
</xsl:attribute>
+ <xsl:attribute name="original">
+ <xsl:value-of select="@id"/>
+ </xsl:attribute>
<xsl:choose>
<xsl:when test="$target[self::svg:g]">
<xsl:for-each select="@*[not(local-name() = $excluded_use_attrs/name | $merge_use_attrs)]">
@@ -756,7 +776,7 @@
</xsl:attribute>
</xsl:if>
<xsl:apply-templates mode="unlink_clone" select="$target/*">
- <xsl:with-param select="concat($seed, @id)" name="seed"/>
+ <xsl:with-param name="seed" select="$seeded_id"/>
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
@@ -766,7 +786,7 @@
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates mode="unlink_clone" select="$target">
- <xsl:with-param select="concat($seed, @id)" name="seed"/>
+ <xsl:with-param name="seed" select="$seeded_id"/>
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
@@ -779,15 +799,31 @@
<xsl:text>_</xsl:text>
<xsl:value-of select="."/>
</xsl:attribute>
+ <xsl:attribute name="original">
+ <xsl:value-of select="."/>
+ </xsl:attribute>
</xsl:template>
<xsl:template xmlns="http://www.w3.org/2000/svg" mode="unlink_clone" match="@*">
<xsl:copy/>
</xsl:template>
<xsl:template xmlns="http://www.w3.org/2000/svg" mode="unlink_clone" match="svg:use">
<xsl:param name="seed"/>
- <xsl:apply-templates mode="inline_svg" select=".">
- <xsl:with-param select="concat($seed, '_')" name="seed"/>
- </xsl:apply-templates>
+ <xsl:variable name="targetid" select="substring-after(@xlink:href,'#')"/>
+ <xsl:choose>
+ <xsl:when test="func:is_unlinkable($targetid, @id)">
+ <xsl:call-template name="unlink_clone">
+ <xsl:with-param name="targetid" select="$targetid"/>
+ <xsl:with-param name="seed" select="$seed"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy>
+ <xsl:apply-templates mode="unlink_clone" select="@*">
+ <xsl:with-param name="seed" select="$seed"/>
+ </xsl:apply-templates>
+ </xsl:copy>
+ </xsl:otherwise>
+ </xsl:choose>
</xsl:template>
<xsl:template xmlns="http://www.w3.org/2000/svg" mode="unlink_clone" match="svg:*">
<xsl:param name="seed"/>
@@ -802,7 +838,7 @@
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates mode="unlink_clone" select="@* | node()">
- <xsl:with-param select="$seed" name="seed"/>
+ <xsl:with-param name="seed" select="$seed"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:otherwise>
@@ -811,7 +847,7 @@
<xsl:variable name="result_svg">
<xsl:apply-templates mode="inline_svg" select="/"/>
</xsl:variable>
- <xsl:variable select="exsl:node-set($result_svg)" name="result_svg_ns"/>
+ <xsl:variable name="result_svg_ns" select="exsl:node-set($result_svg)"/>
<preamble:inline-svg/>
<xsl:template match="preamble:inline-svg">
<xsl:text>
@@ -861,8 +897,8 @@
</xsl:text>
</xsl:template>
<xsl:template mode="hmi_widgets" match="svg:*">
- <xsl:variable select="func:widget(@id)" name="widget"/>
- <xsl:variable select="@id" name="eltid"/>
+ <xsl:variable name="widget" select="func:widget(@id)"/>
+ <xsl:variable name="eltid" select="@id"/>
<xsl:variable name="args">
<xsl:for-each select="$widget/arg">
<xsl:text>"</xsl:text>
@@ -879,7 +915,7 @@
<xsl:when test="not(@index)">
<xsl:choose>
<xsl:when test="not(@type)">
- <xsl:message terminate="yes">
+ <xsl:message terminate="no">
<xsl:text>Widget </xsl:text>
<xsl:value-of select="$widget/@type"/>
<xsl:text> id="</xsl:text>
@@ -888,6 +924,10 @@
<xsl:value-of select="@value"/>
<xsl:text>" in HMI tree</xsl:text>
</xsl:message>
+ <xsl:text>undefined</xsl:text>
+ <xsl:if test="position()!=last()">
+ <xsl:text>,</xsl:text>
+ </xsl:if>
</xsl:when>
<xsl:when test="@type = 'PAGE_LOCAL'">
<xsl:text>"</xsl:text>
@@ -929,7 +969,7 @@
<xsl:text>],{
</xsl:text>
<xsl:apply-templates mode="widget_defs" select="$widget">
- <xsl:with-param select="." name="hmi_element"/>
+ <xsl:with-param name="hmi_element" select="."/>
</xsl:apply-templates>
<xsl:text> })</xsl:text>
<xsl:if test="position()!=last()">
@@ -942,7 +982,7 @@
<xsl:param name="elts_with_type"/>
<xsl:choose>
<xsl:when test="count($elts_with_type) > 1">
- <xsl:variable select="func:unique_types($elts_with_type[position()!=last()])" name="prior_results"/>
+ <xsl:variable name="prior_results" select="func:unique_types($elts_with_type[position()!=last()])"/>
<xsl:choose>
<xsl:when test="$elts_with_type[last()][@type = $prior_results/@type]">
<func:result select="$prior_results"/>
@@ -1143,6 +1183,8 @@
</xsl:text>
<xsl:text> let index = this.get_variable_index(i);
</xsl:text>
+ <xsl:text> if(index == undefined) continue;
+</xsl:text>
<xsl:text> subscribers(index).add(this);
</xsl:text>
<xsl:text> }
@@ -1161,6 +1203,8 @@
</xsl:text>
<xsl:text> let realindex = this.get_variable_index(index);
</xsl:text>
+ <xsl:text> if(realindex == undefined) continue;
+</xsl:text>
<xsl:text> let cached_val = cache[realindex];
</xsl:text>
<xsl:text> if(cached_val != undefined)
@@ -1195,9 +1239,13 @@
</xsl:text>
<xsl:text> }
</xsl:text>
- <xsl:text> change_hmi_value(index,opstr) {
-</xsl:text>
- <xsl:text> return change_hmi_value(this.get_variable_index(index), opstr);
+ <xsl:text> change_hmi_value(index, opstr) {
+</xsl:text>
+ <xsl:text> let realindex = this.get_variable_index(index);
+</xsl:text>
+ <xsl:text> if(realindex == undefined) return undefined;
+</xsl:text>
+ <xsl:text> return change_hmi_value(realindex, opstr);
</xsl:text>
<xsl:text> }
</xsl:text>
@@ -1205,7 +1253,11 @@
</xsl:text>
<xsl:text> apply_hmi_value(index, new_val) {
</xsl:text>
- <xsl:text> return apply_hmi_value(this.get_variable_index(0), new_val);
+ <xsl:text> let realindex = this.get_variable_index(index);
+</xsl:text>
+ <xsl:text> if(realindex == undefined) return undefined;
+</xsl:text>
+ <xsl:text> return apply_hmi_value(realindex, new_val);
</xsl:text>
<xsl:text> }
</xsl:text>
@@ -1219,6 +1271,8 @@
</xsl:text>
<xsl:text> let refindex = this.get_variable_index(i);
</xsl:text>
+ <xsl:text> if(refindex == undefined) continue;
+</xsl:text>
<xsl:text>
</xsl:text>
<xsl:text> if(index == refindex) {
@@ -1298,7 +1352,7 @@
</xsl:text>
<xsl:text>
</xsl:text>
- <xsl:variable select="func:unique_types($parsed_widgets/widget)" name="used_widget_types"/>
+ <xsl:variable name="used_widget_types" select="func:unique_types($parsed_widgets/widget)"/>
<xsl:apply-templates mode="widget_class" select="$used_widget_types"/>
<xsl:text>
</xsl:text>
@@ -1315,8 +1369,8 @@
<xsl:text>}
</xsl:text>
</xsl:template>
- <xsl:variable select="str:split('Page Lang VarInit')" name="excluded_types"/>
- <xsl:variable select="$parsed_widgets/widget[not(@type = $excluded_types)]/@id" name="included_ids"/>
+ <xsl:variable name="excluded_types" select="str:split('Page Lang VarInit')"/>
+ <xsl:variable name="included_ids" select="$parsed_widgets/widget[not(@type = $excluded_types)]/@id"/>
<declarations:hmi-elements/>
<xsl:template match="declarations:hmi-elements">
<xsl:text>
@@ -1336,14 +1390,14 @@
</xsl:text>
</xsl:template>
<xsl:template name="defs_by_labels">
- <xsl:param select="''" name="labels"/>
- <xsl:param select="'yes'" name="mandatory"/>
- <xsl:param select="/.." name="subelements"/>
+ <xsl:param name="labels" select="''"/>
+ <xsl:param name="mandatory" select="'yes'"/>
+ <xsl:param name="subelements" select="/.."/>
<xsl:param name="hmi_element"/>
- <xsl:variable select="@type" name="widget_type"/>
+ <xsl:variable name="widget_type" select="@type"/>
<xsl:for-each select="str:split($labels)">
- <xsl:variable select="." name="name"/>
- <xsl:variable select="$result_svg_ns//*[@id = $hmi_element/@id]//*[@inkscape:label=$name][1]" name="elt"/>
+ <xsl:variable name="name" select="."/>
+ <xsl:variable name="elt" select="$result_svg_ns//*[@id = $hmi_element/@id]//*[@inkscape:label=$name][1]"/>
<xsl:choose>
<xsl:when test="not($elt/@id)">
<xsl:if test="$mandatory='yes'">
@@ -1368,8 +1422,8 @@
<xsl:text>_sub: {
</xsl:text>
<xsl:for-each select="str:split($subelements)">
- <xsl:variable select="." name="subname"/>
- <xsl:variable select="$elt/*[@inkscape:label=$subname][1]" name="subelt"/>
+ <xsl:variable name="subname" select="."/>
+ <xsl:variable name="subelt" select="$elt/*[@inkscape:label=$subname][1]"/>
<xsl:choose>
<xsl:when test="not($subelt/@id)">
<xsl:if test="$mandatory='yes'">
@@ -1454,12 +1508,26 @@
</xsl:text>
<xsl:text> state = 0;
</xsl:text>
+ <xsl:text> plc_lock = false;
+</xsl:text>
<xsl:text> active_style = undefined;
</xsl:text>
<xsl:text> inactive_style = undefined;
</xsl:text>
<xsl:text>
</xsl:text>
+ <xsl:text> dispatch(value) {
+</xsl:text>
+ <xsl:text> if(value){
+</xsl:text>
+ <xsl:text> this.button_release();
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text>
+</xsl:text>
<xsl:text> on_mouse_down(evt) {
</xsl:text>
<xsl:text> if (this.active_style && this.inactive_style) {
@@ -1472,21 +1540,41 @@
</xsl:text>
<xsl:text> this.apply_hmi_value(0, 1);
</xsl:text>
+ <xsl:text> this.plc_lock = false;
+</xsl:text>
<xsl:text> }
</xsl:text>
<xsl:text>
</xsl:text>
<xsl:text> on_mouse_up(evt) {
</xsl:text>
- <xsl:text> if (this.active_style && this.inactive_style) {
-</xsl:text>
- <xsl:text> this.active_elt.setAttribute("style", "display:none");
-</xsl:text>
- <xsl:text> this.inactive_elt.setAttribute("style", this.inactive_style);
-</xsl:text>
- <xsl:text> }
-</xsl:text>
- <xsl:text> this.apply_hmi_value(0, 0);
+ <xsl:text> this.button_release();
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> button_release(){
+</xsl:text>
+ <xsl:text> if(!this.plc_lock){
+</xsl:text>
+ <xsl:text> this.plc_lock = true;
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text> else{
+</xsl:text>
+ <xsl:text> if (this.active_style && this.inactive_style) {
+</xsl:text>
+ <xsl:text> this.active_elt.setAttribute("style", "display:none");
+</xsl:text>
+ <xsl:text> this.inactive_elt.setAttribute("style", this.inactive_style);
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text> this.apply_hmi_value(0, 0);
+</xsl:text>
+ <xsl:text> }
</xsl:text>
<xsl:text> }
</xsl:text>
@@ -1522,11 +1610,11 @@
<xsl:template mode="widget_defs" match="widget[@type='Button']">
<xsl:param name="hmi_element"/>
<xsl:call-template name="defs_by_labels">
- <xsl:with-param select="$hmi_element" name="hmi_element"/>
+ <xsl:with-param name="hmi_element" select="$hmi_element"/>
<xsl:with-param name="labels">
<xsl:text>active inactive</xsl:text>
</xsl:with-param>
- <xsl:with-param select="'no'" name="mandatory"/>
+ <xsl:with-param name="mandatory" select="'no'"/>
</xsl:call-template>
<xsl:text>
</xsl:text>
@@ -1624,17 +1712,17 @@
<xsl:template mode="widget_defs" match="widget[@type='CircularBar']">
<xsl:param name="hmi_element"/>
<xsl:call-template name="defs_by_labels">
- <xsl:with-param select="$hmi_element" name="hmi_element"/>
+ <xsl:with-param name="hmi_element" select="$hmi_element"/>
<xsl:with-param name="labels">
<xsl:text>path</xsl:text>
</xsl:with-param>
</xsl:call-template>
<xsl:call-template name="defs_by_labels">
- <xsl:with-param select="$hmi_element" name="hmi_element"/>
+ <xsl:with-param name="hmi_element" select="$hmi_element"/>
<xsl:with-param name="labels">
<xsl:text>value min max</xsl:text>
</xsl:with-param>
- <xsl:with-param select="'no'" name="mandatory"/>
+ <xsl:with-param name="mandatory" select="'no'"/>
</xsl:call-template>
<xsl:text>
</xsl:text>
@@ -2028,17 +2116,17 @@
<xsl:template mode="widget_defs" match="widget[@type='CircularSlider']">
<xsl:param name="hmi_element"/>
<xsl:call-template name="defs_by_labels">
- <xsl:with-param select="$hmi_element" name="hmi_element"/>
+ <xsl:with-param name="hmi_element" select="$hmi_element"/>
<xsl:with-param name="labels">
<xsl:text>handle range</xsl:text>
</xsl:with-param>
</xsl:call-template>
<xsl:call-template name="defs_by_labels">
- <xsl:with-param select="$hmi_element" name="hmi_element"/>
+ <xsl:with-param name="hmi_element" select="$hmi_element"/>
<xsl:with-param name="labels">
<xsl:text>value min max</xsl:text>
</xsl:with-param>
- <xsl:with-param select="'no'" name="mandatory"/>
+ <xsl:with-param name="mandatory" select="'no'"/>
</xsl:call-template>
<xsl:text>
</xsl:text>
@@ -2052,8 +2140,6 @@
</xsl:text>
<xsl:text> this.fields[index] = value;
</xsl:text>
- <xsl:text> console.log(value, index);
-</xsl:text>
<xsl:text> this.element.textContent = this.args.length == 1 ? vsprintf(this.args[0],this.fields) : this.fields.join(' ');
</xsl:text>
<xsl:text> }
@@ -2570,7 +2656,7 @@
<xsl:template mode="widget_defs" match="widget[@type='DropDown']">
<xsl:param name="hmi_element"/>
<xsl:call-template name="defs_by_labels">
- <xsl:with-param select="$hmi_element" name="hmi_element"/>
+ <xsl:with-param name="hmi_element" select="$hmi_element"/>
<xsl:with-param name="labels">
<xsl:text>text box button</xsl:text>
</xsl:with-param>
@@ -2891,8 +2977,6 @@
</xsl:text>
<xsl:text> }
</xsl:text>
- <xsl:text> console.log(this.menu_offset);
-</xsl:text>
<xsl:text> this.set_partial_text();
</xsl:text>
<xsl:text> },
@@ -3096,13 +3180,13 @@
<xsl:text> must have one argument given : a class name.</xsl:text>
</xsl:message>
</xsl:if>
- <xsl:variable select="arg[1]/@value" name="class"/>
- <xsl:variable select="path/@value" name="base_path"/>
- <xsl:variable select="$indexed_hmitree/*[@hmipath = $base_path]" name="hmi_index_base"/>
- <xsl:variable select="$hmitree/descendant-or-self::*[@path = $hmi_index_base/@path]" name="hmi_tree_base"/>
- <xsl:variable select="$hmi_tree_base/*[@class = $class]" name="hmi_tree_items"/>
- <xsl:variable select="$indexed_hmitree/*[@path = $hmi_tree_items/@path]" name="hmi_index_items"/>
- <xsl:variable select="$hmi_index_items/@hmipath" name="items_paths"/>
+ <xsl:variable name="class" select="arg[1]/@value"/>
+ <xsl:variable name="base_path" select="path/@value"/>
+ <xsl:variable name="hmi_index_base" select="$indexed_hmitree/*[@hmipath = $base_path]"/>
+ <xsl:variable name="hmi_tree_base" select="$hmitree/descendant-or-self::*[@path = $hmi_index_base/@path]"/>
+ <xsl:variable name="hmi_tree_items" select="$hmi_tree_base/*[@class = $class]"/>
+ <xsl:variable name="hmi_index_items" select="$indexed_hmitree/*[@path = $hmi_tree_items/@path]"/>
+ <xsl:variable name="items_paths" select="$hmi_index_items/@hmipath"/>
<xsl:text> index_pool: [
</xsl:text>
<xsl:for-each select="$hmi_index_items">
@@ -3118,11 +3202,11 @@
</xsl:text>
<xsl:text> init: function() {
</xsl:text>
- <xsl:variable select="concat($class,':')" name="prefix"/>
- <xsl:variable select="concat('^',$prefix,'[+\-][0-9]+')" name="buttons_regex"/>
- <xsl:variable select="$hmi_element/*[regexp:test(@inkscape:label, $buttons_regex)]" name="buttons"/>
+ <xsl:variable name="prefix" select="concat($class,':')"/>
+ <xsl:variable name="buttons_regex" select="concat('^',$prefix,'[+\-][0-9]+')"/>
+ <xsl:variable name="buttons" select="$hmi_element/*[regexp:test(@inkscape:label, $buttons_regex)]"/>
<xsl:for-each select="$buttons">
- <xsl:variable select="substring-after(@inkscape:label, $prefix)" name="op"/>
+ <xsl:variable name="op" select="substring-after(@inkscape:label, $prefix)"/>
<xsl:text> id("</xsl:text>
<xsl:value-of select="@id"/>
<xsl:text>").setAttribute("onclick", "hmi_widgets['</xsl:text>
@@ -3136,13 +3220,13 @@
</xsl:text>
<xsl:text> this.items = [
</xsl:text>
- <xsl:variable select="concat('^',$prefix,'[0-9]+')" name="items_regex"/>
- <xsl:variable select="$hmi_element//*[regexp:test(@inkscape:label, $items_regex)]" name="unordered_items"/>
+ <xsl:variable name="items_regex" select="concat('^',$prefix,'[0-9]+')"/>
+ <xsl:variable name="unordered_items" select="$hmi_element//*[regexp:test(@inkscape:label, $items_regex)]"/>
<xsl:for-each select="$unordered_items">
- <xsl:variable select="concat($prefix, string(position()))" name="elt_label"/>
- <xsl:variable select="$unordered_items[@inkscape:label = $elt_label]" name="elt"/>
- <xsl:variable select="position()" name="pos"/>
- <xsl:variable select="$items_paths[$pos]" name="item_path"/>
+ <xsl:variable name="elt_label" select="concat($prefix, string(position()))"/>
+ <xsl:variable name="elt" select="$unordered_items[@inkscape:label = $elt_label]"/>
+ <xsl:variable name="pos" select="position()"/>
+ <xsl:variable name="item_path" select="$items_paths[$pos]"/>
<xsl:text> [ /* item="</xsl:text>
<xsl:value-of select="$elt_label"/>
<xsl:text>" path="</xsl:text>
@@ -3333,22 +3417,22 @@
<xsl:template mode="widget_defs" match="widget[@type='Input']">
<xsl:param name="hmi_element"/>
<xsl:call-template name="defs_by_labels">
- <xsl:with-param select="$hmi_element" name="hmi_element"/>
+ <xsl:with-param name="hmi_element" select="$hmi_element"/>
<xsl:with-param name="labels">
<xsl:text>key_pos</xsl:text>
</xsl:with-param>
- <xsl:with-param select="'no'" name="mandatory"/>
+ <xsl:with-param name="mandatory" select="'no'"/>
</xsl:call-template>
<xsl:variable name="value_elt">
<xsl:call-template name="defs_by_labels">
- <xsl:with-param select="$hmi_element" name="hmi_element"/>
+ <xsl:with-param name="hmi_element" select="$hmi_element"/>
<xsl:with-param name="labels">
<xsl:text>value</xsl:text>
</xsl:with-param>
- <xsl:with-param select="'no'" name="mandatory"/>
+ <xsl:with-param name="mandatory" select="'no'"/>
</xsl:call-template>
</xsl:variable>
- <xsl:variable select="string-length($value_elt)>0" name="have_value"/>
+ <xsl:variable name="have_value" select="string-length($value_elt)>0"/>
<xsl:value-of select="$value_elt"/>
<xsl:if test="$have_value">
<xsl:text> frequency: 5,
@@ -3366,7 +3450,7 @@
</xsl:if>
<xsl:text> },
</xsl:text>
- <xsl:variable select="$hmi_element/*[@inkscape:label='edit'][1]/@id" name="edit_elt_id"/>
+ <xsl:variable name="edit_elt_id" select="$hmi_element/*[@inkscape:label='edit'][1]/@id"/>
<xsl:text> init: function() {
</xsl:text>
<xsl:if test="$edit_elt_id">
@@ -3403,7 +3487,7 @@
<xsl:value-of select="path/@value"/>
<xsl:text>", "</xsl:text>
<xsl:value-of select="path/@type"/>
- <xsl:text>", this, this.last_val,size);
+ <xsl:text>", this, this.last_val, size);
</xsl:text>
<xsl:text> },
</xsl:text>
@@ -3417,15 +3501,19 @@
<xsl:template mode="widget_class" match="widget[@type='JsonTable']">
<xsl:text>class JsonTableWidget extends Widget{
</xsl:text>
- <xsl:text> do_http_request() {
+ <xsl:text> cache = [];
+</xsl:text>
+ <xsl:text> do_http_request(...opt) {
</xsl:text>
<xsl:text> const query = {
</xsl:text>
- <xsl:text> offset: '42',
-</xsl:text>
- <xsl:text> filter: '*powerloss*',
-</xsl:text>
- <xsl:text> args: this.args
+ <xsl:text> args: this.args,
+</xsl:text>
+ <xsl:text> vars: this.cache,
+</xsl:text>
+ <xsl:text> visible: this.visible,
+</xsl:text>
+ <xsl:text> options: opt
</xsl:text>
<xsl:text> };
</xsl:text>
@@ -3439,7 +3527,7 @@
</xsl:text>
<xsl:text> headers: {'Content-Type': 'application/json'}
</xsl:text>
- <xsl:text> }
+ <xsl:text> };
</xsl:text>
<xsl:text>
</xsl:text>
@@ -3447,27 +3535,23 @@
</xsl:text>
<xsl:text> .then(res => res.json())
</xsl:text>
- <xsl:text> .then(this.spread_json_data);
+ <xsl:text> .then(this.spread_json_data.bind(this));
</xsl:text>
<xsl:text>
</xsl:text>
<xsl:text> }
</xsl:text>
- <xsl:text> dispatch(value) {
+ <xsl:text> dispatch(value, oldval, index) {
+</xsl:text>
+ <xsl:text> this.cache[index] = value;
</xsl:text>
<xsl:text> this.do_http_request();
</xsl:text>
<xsl:text> }
</xsl:text>
- <xsl:text> on_click(evt) {
-</xsl:text>
- <xsl:text> this.do_http_request();
-</xsl:text>
- <xsl:text> }
-</xsl:text>
- <xsl:text> init() {
-</xsl:text>
- <xsl:text> this.element.setAttribute("onclick", "hmi_widgets['"+this.element_id+"'].on_click(evt)");
+ <xsl:text> on_click(evt, ...options) {
+</xsl:text>
+ <xsl:text> this.do_http_request(...options);
</xsl:text>
<xsl:text> }
</xsl:text>
@@ -3481,13 +3565,83 @@
<xsl:text>.</xsl:text>
</xsl:message>
</xsl:template>
- <xsl:variable select="$parsed_widgets/widget[@type = 'TextStyleList']" name="hmi_textstylelists_descs"/>
- <xsl:variable select="$hmi_elements[@id = $hmi_textstylelists_descs/@id]" name="hmi_textstylelists"/>
+ <xsl:variable name="hmi_textstylelists_descs" select="$parsed_widgets/widget[@type = 'TextStyleList']"/>
+ <xsl:variable name="hmi_textstylelists" select="$hmi_elements[@id = $hmi_textstylelists_descs/@id]"/>
+ <xsl:variable name="textstylelist_related">
+ <xsl:for-each select="$hmi_textstylelists">
+ <list>
+ <xsl:attribute name="listid">
+ <xsl:value-of select="@id"/>
+ </xsl:attribute>
+ <xsl:for-each select="func:refered_elements(.)">
+ <elt>
+ <xsl:attribute name="eltid">
+ <xsl:value-of select="@id"/>
+ </xsl:attribute>
+ </elt>
+ </xsl:for-each>
+ </list>
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:variable name="textstylelist_related_ns" select="exsl:node-set($textstylelist_related)"/>
+ <func:function name="func:json_expressions">
+ <xsl:param name="expressions"/>
+ <xsl:param name="label"/>
+ <xsl:choose>
+ <xsl:when test="$label">
+ <xsl:variable name="suffixes" select="str:split($label)"/>
+ <xsl:variable name="res">
+ <xsl:for-each select="$suffixes">
+ <expression>
+ <xsl:variable name="suffix" select="."/>
+ <xsl:variable name="pos" select="position()"/>
+ <xsl:variable name="expr" select="$expressions[position() <= $pos][last()]/expression"/>
+ <xsl:choose>
+ <xsl:when test="contains($suffix,'=')">
+ <xsl:variable name="name" select="substring-before($suffix,'=')"/>
+ <xsl:if test="$expr/@name[. != $name]">
+ <xsl:message terminate="yes">
+ <xsl:text>JsonTable : missplaced '=' or inconsistent names in Json data expressions.</xsl:text>
+ </xsl:message>
+ </xsl:if>
+ <xsl:attribute name="name">
+ <xsl:value-of select="$name"/>
+ </xsl:attribute>
+ <xsl:attribute name="content">
+ <xsl:value-of select="$expr/@content"/>
+ <xsl:value-of select="substring-after($suffix,'=')"/>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy-of select="$expr/@name"/>
+ <xsl:attribute name="content">
+ <xsl:value-of select="$expr/@content"/>
+ <xsl:value-of select="$suffix"/>
+ </xsl:attribute>
+ </xsl:otherwise>
+ </xsl:choose>
+ </expression>
+ </xsl:for-each>
+ </xsl:variable>
+ <func:result select="exsl:node-set($res)"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <func:result select="$expressions"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </func:function>
+ <xsl:variable name="initexpr">
+ <expression>
+ <xsl:attribute name="content">
+ <xsl:text>jdata</xsl:text>
+ </xsl:attribute>
+ </expression>
+ </xsl:variable>
+ <xsl:variable name="initexpr_ns" select="exsl:node-set($initexpr)"/>
<xsl:template mode="json_table_elt_render" match="svg:use">
- <xsl:param name="value_expr"/>
- <xsl:variable select="substring-after(@xlink:href,'#')" name="targetid"/>
- <xsl:variable select="$hmi_lists[(@id | */@id) = $targetid]" name="from_list"/>
- <xsl:variable select="$hmi_textstylelists[(@id | */@id) = $targetid]" name="from_textstylelist"/>
+ <xsl:param name="expressions"/>
+ <xsl:variable name="targetid" select="substring-after(@xlink:href,'#')"/>
+ <xsl:variable name="from_list" select="$hmi_lists[(@id | */@id) = $targetid]"/>
<xsl:choose>
<xsl:when test="count($from_list) > 0">
<xsl:text> id("</xsl:text>
@@ -3497,29 +3651,13 @@
<xsl:text> "#"+hmi_widgets["</xsl:text>
<xsl:value-of select="$from_list/@id"/>
<xsl:text>"].items[</xsl:text>
- <xsl:value-of select="$value_expr"/>
- <xsl:text>]);
-</xsl:text>
- </xsl:when>
- <xsl:when test="count($from_textstylelist) > 0">
- <xsl:text> console.log("from_textsylelist","</xsl:text>
- <xsl:value-of select="@id"/>
- <xsl:text>", "</xsl:text>
- <xsl:value-of select="$value_expr"/>
- <xsl:text>", </xsl:text>
- <xsl:value-of select="$value_expr"/>
- <xsl:text>,
-</xsl:text>
- <xsl:text> hmi_widgets["</xsl:text>
- <xsl:value-of select="$from_textstylelist/@id"/>
- <xsl:text>"].items[</xsl:text>
- <xsl:value-of select="$value_expr"/>
+ <xsl:value-of select="$expressions/expression[1]/@content"/>
<xsl:text>]);
</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:message terminate="no">
- <xsl:text>Clones (svg:use) in JsonTable Widget must point to a valid HMI:List or HMI:TextStyleList widget or item. Reference "</xsl:text>
+ <xsl:text>Clones (svg:use) in JsonTable Widget must point to a valid HMI:List widget or item. Reference "</xsl:text>
<xsl:value-of select="@xlink:href"/>
<xsl:text>" is not valid and will not be updated.</xsl:text>
</xsl:message>
@@ -3527,59 +3665,194 @@
</xsl:choose>
</xsl:template>
<xsl:template mode="json_table_elt_render" match="svg:text">
- <xsl:param name="value_expr"/>
- <xsl:text> id("</xsl:text>
+ <xsl:param name="expressions"/>
+ <xsl:variable name="value_expr" select="$expressions/expression[1]/@content"/>
+ <xsl:variable name="original" select="@original"/>
+ <xsl:variable name="from_textstylelist" select="$textstylelist_related_ns/list[elt/@eltid = $original]"/>
+ <xsl:choose>
+ <xsl:when test="count($from_textstylelist) > 0">
+ <xsl:variable name="content_expr" select="$expressions/expression[2]/@content"/>
+ <xsl:if test="string-length($content_expr) = 0 or $expressions/expression[2]/@name != 'textContent'">
+ <xsl:message terminate="yes">
+ <xsl:text>Clones (svg:use) in JsonTable Widget pointing to a HMI:TextStyleList widget or item must have a "textContent=.someVal" assignement following value expression in label.</xsl:text>
+ </xsl:message>
+ </xsl:if>
+ <xsl:text> {
+</xsl:text>
+ <xsl:text> let elt = id("</xsl:text>
+ <xsl:value-of select="@id"/>
+ <xsl:text>");
+</xsl:text>
+ <xsl:text> elt.textContent = String(</xsl:text>
+ <xsl:value-of select="$content_expr"/>
+ <xsl:text>);
+</xsl:text>
+ <xsl:text> elt.style = hmi_widgets["</xsl:text>
+ <xsl:value-of select="$from_textstylelist/@listid"/>
+ <xsl:text>"].styles[</xsl:text>
+ <xsl:value-of select="$value_expr"/>
+ <xsl:text>];
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text> id("</xsl:text>
+ <xsl:value-of select="@id"/>
+ <xsl:text>").textContent = String(</xsl:text>
+ <xsl:value-of select="$value_expr"/>
+ <xsl:text>);
+</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+ <func:function name="func:filter_non_widget_label">
+ <xsl:param name="elt"/>
+ <xsl:param name="widget_elts"/>
+ <xsl:variable name="eltid">
+ <xsl:choose>
+ <xsl:when test="$elt/@original">
+ <xsl:value-of select="$elt/@original"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$elt/@id"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <func:result select="$widget_elts[@id=$eltid]/@inkscape:label"/>
+ </func:function>
+ <xsl:template mode="json_table_render_except_comments" match="svg:*">
+ <xsl:param name="expressions"/>
+ <xsl:param name="widget_elts"/>
+ <xsl:variable name="label" select="func:filter_non_widget_label(., $widget_elts)"/>
+ <xsl:if test="not(starts-with($label,'#'))">
+ <xsl:apply-templates mode="json_table_render" select=".">
+ <xsl:with-param name="expressions" select="$expressions"/>
+ <xsl:with-param name="widget_elts" select="$widget_elts"/>
+ <xsl:with-param name="label" select="$label"/>
+ </xsl:apply-templates>
+ </xsl:if>
+ </xsl:template>
+ <xsl:template mode="json_table_render" match="svg:*">
+ <xsl:param name="expressions"/>
+ <xsl:param name="widget_elts"/>
+ <xsl:param name="label"/>
+ <xsl:variable name="new_expressions" select="func:json_expressions($expressions, $label)"/>
+ <xsl:variable name="elt" select="."/>
+ <xsl:for-each select="$new_expressions/expression[position() > 1][starts-with(@name,'onClick')]">
+ <xsl:text> id("</xsl:text>
+ <xsl:value-of select="$elt/@id"/>
+ <xsl:text>").setAttribute("onclick", "hmi_widgets['"+this.element_id+"'].on_click(evt, '</xsl:text>
+ <xsl:value-of select="@name"/>
+ <xsl:text>', '"+</xsl:text>
+ <xsl:value-of select="@content"/>
+ <xsl:text>+"')");
+</xsl:text>
+ </xsl:for-each>
+ <xsl:apply-templates mode="json_table_elt_render" select=".">
+ <xsl:with-param name="expressions" select="$new_expressions"/>
+ </xsl:apply-templates>
+ </xsl:template>
+ <xsl:template mode="json_table_render" match="svg:g">
+ <xsl:param name="expressions"/>
+ <xsl:param name="widget_elts"/>
+ <xsl:param name="label"/>
+ <xsl:variable name="gid" select="@id"/>
+ <xsl:variable name="varprefix">
+ <xsl:text>obj_</xsl:text>
+ <xsl:value-of select="$gid"/>
+ <xsl:text>_</xsl:text>
+ </xsl:variable>
+ <xsl:text> try {
+</xsl:text>
+ <xsl:for-each select="$expressions/expression">
+ <xsl:text> let </xsl:text>
+ <xsl:value-of select="$varprefix"/>
+ <xsl:value-of select="position()"/>
+ <xsl:text> = </xsl:text>
+ <xsl:value-of select="@content"/>
+ <xsl:text>;
+</xsl:text>
+ <xsl:text> if(</xsl:text>
+ <xsl:value-of select="$varprefix"/>
+ <xsl:value-of select="position()"/>
+ <xsl:text> == undefined) {
+</xsl:text>
+ <xsl:text> console.log("</xsl:text>
+ <xsl:value-of select="$varprefix"/>
+ <xsl:value-of select="position()"/>
+ <xsl:text> = </xsl:text>
+ <xsl:value-of select="@content"/>
+ <xsl:text>");
+</xsl:text>
+ <xsl:text> throw null;
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ </xsl:for-each>
+ <xsl:variable name="new_expressions">
+ <xsl:for-each select="$expressions/expression">
+ <xsl:copy>
+ <xsl:copy-of select="@name"/>
+ <xsl:attribute name="content">
+ <xsl:value-of select="$varprefix"/>
+ <xsl:value-of select="position()"/>
+ </xsl:attribute>
+ </xsl:copy>
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:text> id("</xsl:text>
<xsl:value-of select="@id"/>
- <xsl:text>").textContent = String(</xsl:text>
- <xsl:value-of select="$value_expr"/>
- <xsl:text>);
-</xsl:text>
- </xsl:template>
- <xsl:template mode="json_table_render" match="svg:*">
- <xsl:param name="objname"/>
- <xsl:apply-templates mode="json_table_elt_render" select=".">
- <xsl:with-param name="value_expr">
- <xsl:value-of select="$objname"/>
- <xsl:value-of select="substring-before(@inkscape:label, ' ')"/>
- </xsl:with-param>
+ <xsl:text>").setAttribute("style", "</xsl:text>
+ <xsl:value-of select="@style"/>
+ <xsl:text>");
+</xsl:text>
+ <xsl:apply-templates mode="json_table_render_except_comments" select="*">
+ <xsl:with-param name="expressions" select="func:json_expressions(exsl:node-set($new_expressions), $label)"/>
+ <xsl:with-param name="widget_elts" select="$widget_elts"/>
</xsl:apply-templates>
- </xsl:template>
- <xsl:template mode="json_table_render" match="svg:g">
- <xsl:param name="objname"/>
- <xsl:text> let obj_</xsl:text>
- <xsl:value-of select="@id"/>
- <xsl:text> = </xsl:text>
- <xsl:value-of select="$objname"/>
- <xsl:value-of select="substring-before(@inkscape:label, ' ')"/>
- <xsl:text>;
-</xsl:text>
- <xsl:apply-templates mode="json_table_render" select="*[@inkscape:label]">
- <xsl:with-param name="objname">
- <xsl:text>obj_</xsl:text>
- <xsl:value-of select="@id"/>
- </xsl:with-param>
- </xsl:apply-templates>
+ <xsl:text> } catch(err) {
+</xsl:text>
+ <xsl:text> id("</xsl:text>
+ <xsl:value-of select="$gid"/>
+ <xsl:text>").setAttribute("style", "display:none");
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
</xsl:template>
<xsl:template mode="widget_defs" match="widget[@type='JsonTable']">
<xsl:param name="hmi_element"/>
<xsl:call-template name="defs_by_labels">
- <xsl:with-param select="$hmi_element" name="hmi_element"/>
+ <xsl:with-param name="hmi_element" select="$hmi_element"/>
<xsl:with-param name="labels">
<xsl:text>data</xsl:text>
</xsl:with-param>
</xsl:call-template>
<xsl:call-template name="defs_by_labels">
- <xsl:with-param select="$hmi_element" name="hmi_element"/>
+ <xsl:with-param name="hmi_element" select="$hmi_element"/>
<xsl:with-param name="labels">
<xsl:text>forward backward cursor</xsl:text>
</xsl:with-param>
- <xsl:with-param select="'no'" name="mandatory"/>
+ <xsl:with-param name="mandatory" select="'no'"/>
</xsl:call-template>
- <xsl:variable select="$result_svg_ns//*[@id = $hmi_element/@id]/*[@inkscape:label = 'data']" name="data_elt"/>
- <xsl:text> spread_json_data: function(jdata) {
-</xsl:text>
- <xsl:apply-templates mode="json_table_render" select="$data_elt/*">
- <xsl:with-param select="'jdata'" name="objname"/>
+ <xsl:variable name="data_elt" select="$result_svg_ns//*[@id = $hmi_element/@id]/*[@inkscape:label = 'data']"/>
+ <xsl:text> visible: </xsl:text>
+ <xsl:value-of select="count($data_elt/*[@inkscape:label])"/>
+ <xsl:text>,
+</xsl:text>
+ <xsl:text> spread_json_data: function(janswer) {
+</xsl:text>
+ <xsl:text> let [range,position,jdata] = janswer;
+</xsl:text>
+ <xsl:text> this.apply_hmi_value(1, range);
+</xsl:text>
+ <xsl:text> this.apply_hmi_value(2, position);
+</xsl:text>
+ <xsl:text> console.log(range,position,jdata);
+</xsl:text>
+ <xsl:apply-templates mode="json_table_render_except_comments" select="$data_elt">
+ <xsl:with-param name="expressions" select="$initexpr_ns"/>
+ <xsl:with-param name="widget_elts" select="$hmi_element/*[@inkscape:label = 'data']/descendant::svg:*"/>
</xsl:apply-templates>
<xsl:text> }
</xsl:text>
@@ -3587,38 +3860,38 @@
<xsl:template name="jump_widget_activity">
<xsl:param name="hmi_element"/>
<xsl:call-template name="defs_by_labels">
- <xsl:with-param select="$hmi_element" name="hmi_element"/>
+ <xsl:with-param name="hmi_element" select="$hmi_element"/>
<xsl:with-param name="labels">
<xsl:text>active inactive</xsl:text>
</xsl:with-param>
- <xsl:with-param select="'no'" name="mandatory"/>
+ <xsl:with-param name="mandatory" select="'no'"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="jump_widget_disability">
<xsl:param name="hmi_element"/>
<xsl:call-template name="defs_by_labels">
- <xsl:with-param select="$hmi_element" name="hmi_element"/>
+ <xsl:with-param name="hmi_element" select="$hmi_element"/>
<xsl:with-param name="labels">
<xsl:text>disabled</xsl:text>
</xsl:with-param>
- <xsl:with-param select="'no'" name="mandatory"/>
+ <xsl:with-param name="mandatory" select="'no'"/>
</xsl:call-template>
</xsl:template>
<xsl:template mode="widget_defs" match="widget[@type='Jump']">
<xsl:param name="hmi_element"/>
<xsl:variable name="activity">
<xsl:call-template name="jump_widget_activity">
- <xsl:with-param select="$hmi_element" name="hmi_element"/>
+ <xsl:with-param name="hmi_element" select="$hmi_element"/>
</xsl:call-template>
</xsl:variable>
- <xsl:variable select="string-length($activity)>0" name="have_activity"/>
+ <xsl:variable name="have_activity" select="string-length($activity)>0"/>
<xsl:value-of select="$activity"/>
<xsl:variable name="disability">
<xsl:call-template name="jump_widget_disability">
- <xsl:with-param select="$hmi_element" name="hmi_element"/>
+ <xsl:with-param name="hmi_element" select="$hmi_element"/>
</xsl:call-template>
</xsl:variable>
- <xsl:variable select="$have_activity and string-length($disability)>0" name="have_disability"/>
+ <xsl:variable name="have_disability" select="$have_activity and string-length($disability)>0"/>
<xsl:value-of select="$disability"/>
<xsl:if test="$have_activity">
<xsl:text> active: false,
@@ -3821,9 +4094,9 @@
<xsl:text>var keypads = {
</xsl:text>
<xsl:for-each select="$keypads_descs">
- <xsl:variable select="@id" name="keypad_id"/>
+ <xsl:variable name="keypad_id" select="@id"/>
<xsl:for-each select="arg">
- <xsl:variable select="$geometry[@Id = $keypad_id]" name="g"/>
+ <xsl:variable name="g" select="$geometry[@Id = $keypad_id]"/>
<xsl:text> "</xsl:text>
<xsl:value-of select="@value"/>
<xsl:text>":["</xsl:text>
@@ -4020,11 +4293,25 @@
</xsl:text>
<xsl:text> on_Enter_click() {
</xsl:text>
- <xsl:text> end_modal.call(this);
-</xsl:text>
- <xsl:text> let callback_obj = this.result_callback_obj;
-</xsl:text>
- <xsl:text> callback_obj.edit_callback(this.editstr);
+ <xsl:text> let coercedval = (typeof this.initial) == "number" ? Number(this.editstr) : this.editstr;
+</xsl:text>
+ <xsl:text> if(typeof coercedval == 'number' && isNaN(coercedval)){
+</xsl:text>
+ <xsl:text> // revert to initial so it explicitely shows input was ignored
+</xsl:text>
+ <xsl:text> this.editstr = String(this.initial);
+</xsl:text>
+ <xsl:text> this.update();
+</xsl:text>
+ <xsl:text> } else {
+</xsl:text>
+ <xsl:text> let callback_obj = this.result_callback_obj;
+</xsl:text>
+ <xsl:text> end_modal.call(this);
+</xsl:text>
+ <xsl:text> callback_obj.edit_callback(coercedval);
+</xsl:text>
+ <xsl:text> }
</xsl:text>
<xsl:text> }
</xsl:text>
@@ -4118,7 +4405,7 @@
</xsl:text>
<xsl:text> show_modal.call(this,size);
</xsl:text>
- <xsl:text> this.editstr = initial;
+ <xsl:text> this.editstr = String(initial);
</xsl:text>
<xsl:text> this.result_callback_obj = callback_obj;
</xsl:text>
@@ -4128,6 +4415,10 @@
</xsl:text>
<xsl:text> this.caps = false;
</xsl:text>
+ <xsl:text> this.initial = initial;
+</xsl:text>
+ <xsl:text>
+</xsl:text>
<xsl:text> this.update();
</xsl:text>
<xsl:text> }
@@ -4168,25 +4459,25 @@
<xsl:template mode="widget_defs" match="widget[@type='Keypad']">
<xsl:param name="hmi_element"/>
<xsl:call-template name="defs_by_labels">
- <xsl:with-param select="$hmi_element" name="hmi_element"/>
+ <xsl:with-param name="hmi_element" select="$hmi_element"/>
<xsl:with-param name="labels">
<xsl:text>Esc Enter BackSpace Keys Info Value</xsl:text>
</xsl:with-param>
</xsl:call-template>
<xsl:call-template name="defs_by_labels">
- <xsl:with-param select="$hmi_element" name="hmi_element"/>
+ <xsl:with-param name="hmi_element" select="$hmi_element"/>
<xsl:with-param name="labels">
<xsl:text>Sign Space NumDot position</xsl:text>
</xsl:with-param>
- <xsl:with-param select="'no'" name="mandatory"/>
+ <xsl:with-param name="mandatory" select="'no'"/>
</xsl:call-template>
<xsl:call-template name="defs_by_labels">
- <xsl:with-param select="$hmi_element" name="hmi_element"/>
+ <xsl:with-param name="hmi_element" select="$hmi_element"/>
<xsl:with-param name="labels">
<xsl:text>CapsLock Shift</xsl:text>
</xsl:with-param>
- <xsl:with-param select="'no'" name="mandatory"/>
- <xsl:with-param select="'active inactive'" name="subelements"/>
+ <xsl:with-param name="mandatory" select="'no'"/>
+ <xsl:with-param name="subelements" select="'active inactive'"/>
</xsl:call-template>
<xsl:text> init: function() {
</xsl:text>
@@ -4232,7 +4523,7 @@
</xsl:text>
<xsl:text>
</xsl:text>
- <xsl:variable select="$geometry[@Id = $hmi_element/@id]" name="g"/>
+ <xsl:variable name="g" select="$geometry[@Id = $hmi_element/@id]"/>
<xsl:text> coordinates: [</xsl:text>
<xsl:value-of select="$g/@x"/>
<xsl:text>, </xsl:text>
@@ -4240,13 +4531,13 @@
<xsl:text>],
</xsl:text>
</xsl:template>
- <xsl:template mode="widget_defs" match="widget[@type='List' or @type='TextStyleList']">
+ <xsl:template mode="widget_defs" match="widget[@type='List']">
<xsl:param name="hmi_element"/>
<xsl:text> items: {
</xsl:text>
<xsl:for-each select="$hmi_element/*[@inkscape:label]">
<xsl:text> </xsl:text>
- <xsl:value-of select="func:escape_quotes(@inkscape:label)"/>
+ <xsl:value-of select="@inkscape:label"/>
<xsl:text>: "</xsl:text>
<xsl:value-of select="@id"/>
<xsl:text>",
@@ -4255,6 +4546,22 @@
<xsl:text> },
</xsl:text>
</xsl:template>
+ <xsl:template mode="widget_defs" match="widget[@type='TextStyleList']">
+ <xsl:param name="hmi_element"/>
+ <xsl:text> styles: {
+</xsl:text>
+ <xsl:for-each select="$hmi_element/*[@inkscape:label]">
+ <xsl:variable name="style" select="func:refered_elements(.)[self::svg:text]/@style"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="@inkscape:label"/>
+ <xsl:text>: "</xsl:text>
+ <xsl:value-of select="$style"/>
+ <xsl:text>",
+</xsl:text>
+ </xsl:for-each>
+ <xsl:text> },
+</xsl:text>
+ </xsl:template>
<xsl:template mode="widget_class" match="widget[@type='Meter']">
<xsl:text>class MeterWidget extends Widget{
</xsl:text>
@@ -4312,17 +4619,17 @@
<xsl:template mode="widget_defs" match="widget[@type='Meter']">
<xsl:param name="hmi_element"/>
<xsl:call-template name="defs_by_labels">
- <xsl:with-param select="$hmi_element" name="hmi_element"/>
+ <xsl:with-param name="hmi_element" select="$hmi_element"/>
<xsl:with-param name="labels">
<xsl:text>needle range</xsl:text>
</xsl:with-param>
</xsl:call-template>
<xsl:call-template name="defs_by_labels">
- <xsl:with-param select="$hmi_element" name="hmi_element"/>
+ <xsl:with-param name="hmi_element" select="$hmi_element"/>
<xsl:with-param name="labels">
<xsl:text>value min max</xsl:text>
</xsl:with-param>
- <xsl:with-param select="'no'" name="mandatory"/>
+ <xsl:with-param name="mandatory" select="'no'"/>
</xsl:call-template>
<xsl:text>
</xsl:text>
@@ -4413,9 +4720,9 @@
<xsl:param name="hmi_element"/>
<xsl:text> choices: [
</xsl:text>
- <xsl:variable select="'^("[^"].*"|\-?[0-9]+|false|true)(#.*)?$'" name="regex"/>
+ <xsl:variable name="regex" select="'^("[^"].*"|\-?[0-9]+|false|true)(#.*)?$'"/>
<xsl:for-each select="$result_svg_ns//*[@id = $hmi_element/@id]//*[regexp:test(@inkscape:label,$regex)]">
- <xsl:variable select="regexp:match(@inkscape:label,$regex)[2]" name="literal"/>
+ <xsl:variable name="literal" select="regexp:match(@inkscape:label,$regex)[2]"/>
<xsl:text> {
</xsl:text>
<xsl:text> elt:id("</xsl:text>
@@ -4447,47 +4754,163 @@
</xsl:text>
<xsl:text> range = undefined;
</xsl:text>
+ <xsl:text> handle_orig = undefined;
+</xsl:text>
+ <xsl:text> scroll_size = 10;
+</xsl:text>
+ <xsl:text> min_size = 0.07;
+</xsl:text>
<xsl:text> fi = undefined;
</xsl:text>
- <xsl:text> svg_dist = undefined;
+ <xsl:text> curr_value = 0;
</xsl:text>
<xsl:text> drag = false;
</xsl:text>
<xsl:text> enTimer = false;
</xsl:text>
+ <xsl:text> handle_click = undefined;
+</xsl:text>
+ <xsl:text> last_drag = false;
+</xsl:text>
<xsl:text>
</xsl:text>
<xsl:text> dispatch(value) {
</xsl:text>
+ <xsl:text> //save current value inside widget
+</xsl:text>
+ <xsl:text> this.curr_value = value;
+</xsl:text>
+ <xsl:text>
+</xsl:text>
<xsl:text> if(this.value_elt)
</xsl:text>
<xsl:text> this.value_elt.textContent = String(value);
</xsl:text>
<xsl:text>
</xsl:text>
- <xsl:text> this.update_DOM(value, this.handle_elt);
-</xsl:text>
- <xsl:text>
+ <xsl:text> //don't update if draging and setpoint ghost doesn't exist
+</xsl:text>
+ <xsl:text> if(!this.drag || (this.setpoint_elt != undefined)){
+</xsl:text>
+ <xsl:text> this.update_DOM(value, this.handle_elt);
+</xsl:text>
+ <xsl:text> }
</xsl:text>
<xsl:text> }
</xsl:text>
<xsl:text>
</xsl:text>
- <xsl:text> last_drag = false;
-</xsl:text>
- <xsl:text>
-</xsl:text>
<xsl:text> update_DOM(value, elt){
</xsl:text>
<xsl:text> let [min,max,start,totallength] = this.range;
</xsl:text>
- <xsl:text> let length = Math.max(0,Math.min(totallength,(Number(value)-min)*totallength/(max-min)));
-</xsl:text>
- <xsl:text> let tip = this.range_elt.getPointAtLength(length);
-</xsl:text>
- <xsl:text> elt.setAttribute('transform',"translate("+(tip.x-start.x)+","+(tip.y-start.y)+")");
-</xsl:text>
- <xsl:text>
+ <xsl:text> // check if handle is resizeable
+</xsl:text>
+ <xsl:text> if (this.scroll_size != undefined){ //size changes
+</xsl:text>
+ <xsl:text> //get parameters
+</xsl:text>
+ <xsl:text> let length = Math.max(min,Math.min(max,(Number(value)-min)*max/(max-min)));
+</xsl:text>
+ <xsl:text> let tip = this.range_elt.getPointAtLength(length);
+</xsl:text>
+ <xsl:text> let handle_min = totallength*this.min_size;
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> let step = 1;
+</xsl:text>
+ <xsl:text> //check if range is bigger than max displayed and recalculate step
+</xsl:text>
+ <xsl:text> if ((totallength/handle_min) < (max-min+1)){
+</xsl:text>
+ <xsl:text> step = (max-min+1)/(totallength/handle_min-1);
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> let kx,ky,offseY,offseX = undefined;
+</xsl:text>
+ <xsl:text> //scale on x or y axes
+</xsl:text>
+ <xsl:text> if (this.fi > 0.75){
+</xsl:text>
+ <xsl:text> //get scale factor
+</xsl:text>
+ <xsl:text> if(step > 1){
+</xsl:text>
+ <xsl:text> ky = handle_min/this.handle_orig.height;
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text> else{
+</xsl:text>
+ <xsl:text> ky = (totallength-handle_min*(max-min))/this.handle_orig.height;
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text> kx = 1;
+</xsl:text>
+ <xsl:text> //get 0 offset to stay inside range
+</xsl:text>
+ <xsl:text> offseY = start.y - (this.handle_orig.height + this.handle_orig.y) * ky;
+</xsl:text>
+ <xsl:text> offseX = 0;
+</xsl:text>
+ <xsl:text> //get distance from value
+</xsl:text>
+ <xsl:text> tip.y =this.range_elt.getPointAtLength(0).y - length/step *handle_min;
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text> else{
+</xsl:text>
+ <xsl:text> //get scale factor
+</xsl:text>
+ <xsl:text> if(step > 1){
+</xsl:text>
+ <xsl:text> kx = handle_min/this.handle_orig.width;
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text> else{
+</xsl:text>
+ <xsl:text> kx = (totallength-handle_min*(max-min))/this.handle_orig.width;
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text> ky = 1;
+</xsl:text>
+ <xsl:text> //get 0 offset to stay inside range
+</xsl:text>
+ <xsl:text> offseX = start.x - (this.handle_orig.x * kx);
+</xsl:text>
+ <xsl:text> offseY = 0;
+</xsl:text>
+ <xsl:text> //get distance from value
+</xsl:text>
+ <xsl:text> tip.x =this.range_elt.getPointAtLength(0).x + length/step *handle_min;
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text> elt.setAttribute('transform',"matrix("+(kx)+" 0 0 "+(ky)+" "+(tip.x-start.x+offseX)+" "+(tip.y-start.y+offseY)+")");
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text> else{ //size stays the same
+</xsl:text>
+ <xsl:text> let length = Math.max(0,Math.min(totallength,(Number(value)-min)*totallength/(max-min)));
+</xsl:text>
+ <xsl:text> let tip = this.range_elt.getPointAtLength(length);
+</xsl:text>
+ <xsl:text> elt.setAttribute('transform',"translate("+(tip.x-start.x)+","+(tip.y-start.y)+")");
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> // show or hide ghost if exists
</xsl:text>
<xsl:text> if(this.setpoint_elt != undefined){
</xsl:text>
@@ -4515,6 +4938,8 @@
</xsl:text>
<xsl:text> on_release(evt) {
</xsl:text>
+ <xsl:text> //unbind events
+</xsl:text>
<xsl:text> window.removeEventListener("touchmove", this.on_bound_drag, true);
</xsl:text>
<xsl:text> window.removeEventListener("mousemove", this.on_bound_drag, true);
@@ -4527,26 +4952,38 @@
</xsl:text>
<xsl:text> window.removeEventListener("touchcancel", this.bound_on_release, true);
</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> //reset drag flag
+</xsl:text>
<xsl:text> if(this.drag){
</xsl:text>
<xsl:text> this.drag = false;
</xsl:text>
<xsl:text> }
</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> // get final position
+</xsl:text>
<xsl:text> this.update_position(evt);
</xsl:text>
+ <xsl:text>
+</xsl:text>
<xsl:text> }
</xsl:text>
<xsl:text>
</xsl:text>
- <xsl:text>
-</xsl:text>
<xsl:text> on_drag(evt){
</xsl:text>
+ <xsl:text> //ignore drag event for X amount of time and if not selected
+</xsl:text>
<xsl:text> if(this.enTimer && this.drag){
</xsl:text>
<xsl:text> this.update_position(evt);
</xsl:text>
+ <xsl:text>
+</xsl:text>
<xsl:text> //reset timer
</xsl:text>
<xsl:text> this.enTimer = false;
@@ -4563,16 +5000,18 @@
</xsl:text>
<xsl:text> var html_dist = 0;
</xsl:text>
+ <xsl:text> let [min,max,start,totallength] = this.range;
+</xsl:text>
<xsl:text>
</xsl:text>
<xsl:text> //calculate size of widget in html
</xsl:text>
<xsl:text> var range_borders = this.range_elt.getBoundingClientRect();
</xsl:text>
+ <xsl:text> var [minX,minY,maxX,maxY] = [range_borders.left,range_borders.bottom,range_borders.right,range_borders.top];
+</xsl:text>
<xsl:text> var range_length = Math.sqrt( range_borders.height*range_borders.height + range_borders.width*range_borders.width );
</xsl:text>
- <xsl:text> var [minX,minY,maxX,maxY] = [range_borders.left,range_borders.bottom,range_borders.right,range_borders.top];
-</xsl:text>
<xsl:text>
</xsl:text>
<xsl:text> //get range and mouse coordinates
@@ -4599,112 +5038,240 @@
</xsl:text>
<xsl:text>
</xsl:text>
- <xsl:text> //get handle distance from mouse position
-</xsl:text>
- <xsl:text> if (minX > mouseX && minY < mouseY){
-</xsl:text>
- <xsl:text> html_dist = 0;
+ <xsl:text> // calculate position
+</xsl:text>
+ <xsl:text> if (this.handle_click){ //if clicked on handle
+</xsl:text>
+ <xsl:text> let moveDist = 0, resizeAdd = 0;
+</xsl:text>
+ <xsl:text> let range_percent = 1;
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> //set paramters for resizeable handle
+</xsl:text>
+ <xsl:text> if (this.scroll_size != undefined){
+</xsl:text>
+ <xsl:text> // add one more object to stay inside range
+</xsl:text>
+ <xsl:text> resizeAdd = 1;
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> //chack if range is bigger than display option and
+</xsl:text>
+ <xsl:text> // calculate percent of range with out handle
+</xsl:text>
+ <xsl:text> if(((max/(max*this.min_size)) < (max-min+1))){
+</xsl:text>
+ <xsl:text> range_percent = 1-this.min_size;
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text> else{
+</xsl:text>
+ <xsl:text> range_percent = 1-(max-max*this.min_size*(max-min))/max;
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> //calculate value difference on x or y axis
+</xsl:text>
+ <xsl:text> if(this.fi > 0.7){
+</xsl:text>
+ <xsl:text> moveDist = ((max-min+resizeAdd)/(range_length*range_percent))*((this.handle_click[1]-mouseY)/Math.sin(this.fi));
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text> else{
+</xsl:text>
+ <xsl:text> moveDist = ((max-min+resizeAdd)/(range_length*range_percent))*((mouseX-this.handle_click[0])/Math.cos(this.fi));
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> this.curr_value = Math.ceil(this.handle_click[2] + moveDist);
</xsl:text>
<xsl:text> }
</xsl:text>
- <xsl:text> else if (maxX < mouseX && maxY > mouseY){
-</xsl:text>
- <xsl:text> html_dist = range_length;
+ <xsl:text> else{ //if clicked on widget
+</xsl:text>
+ <xsl:text> //get handle distance from mouse position
+</xsl:text>
+ <xsl:text> if (minX > mouseX && minY < mouseY){
+</xsl:text>
+ <xsl:text> html_dist = 0;
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text> else if (maxX < mouseX && maxY > mouseY){
+</xsl:text>
+ <xsl:text> html_dist = range_length;
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text> else{
+</xsl:text>
+ <xsl:text> if(this.fi > 0.7){
+</xsl:text>
+ <xsl:text> html_dist = (minY - mouseY)/Math.sin(this.fi);
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text> else{
+</xsl:text>
+ <xsl:text> html_dist = (mouseX - minX)/Math.cos(this.fi);
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text> //calculate distance
+</xsl:text>
+ <xsl:text> this.curr_value=Math.ceil((html_dist/range_length)*(this.range[1]-this.range[0])+this.range[0]);
</xsl:text>
<xsl:text> }
</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> //check if in range
+</xsl:text>
+ <xsl:text> if (this.curr_value > max){
+</xsl:text>
+ <xsl:text> this.curr_value = max;
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text> else if (this.curr_value < min){
+</xsl:text>
+ <xsl:text> this.curr_value = min;
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> this.apply_hmi_value(0, this.curr_value);
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> //redraw handle
+</xsl:text>
+ <xsl:text> this.request_animate();
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> animate(){
+</xsl:text>
+ <xsl:text> // redraw handle on screen refresh
+</xsl:text>
+ <xsl:text> // check if setpoint(ghost) handle exsist otherwise update main handle
+</xsl:text>
+ <xsl:text> if(this.setpoint_elt != undefined){
+</xsl:text>
+ <xsl:text> this.update_DOM(this.curr_value, this.setpoint_elt);
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
<xsl:text> else{
</xsl:text>
- <xsl:text> // calculate distace
-</xsl:text>
- <xsl:text> if(this.fi > 0.7){
-</xsl:text>
- <xsl:text> html_dist = (minY - mouseY)/Math.sin(this.fi);
+ <xsl:text> this.update_DOM(this.curr_value, this.handle_elt);
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> on_select(evt){
+</xsl:text>
+ <xsl:text> //enable drag flag and timer
+</xsl:text>
+ <xsl:text> this.drag = true;
+</xsl:text>
+ <xsl:text> this.enTimer = true;
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> //bind events
+</xsl:text>
+ <xsl:text> window.addEventListener("touchmove", this.on_bound_drag, true);
+</xsl:text>
+ <xsl:text> window.addEventListener("mousemove", this.on_bound_drag, true);
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> window.addEventListener("mouseup", this.bound_on_release, true)
+</xsl:text>
+ <xsl:text> window.addEventListener("touchend", this.bound_on_release, true);
+</xsl:text>
+ <xsl:text> window.addEventListener("touchcancel", this.bound_on_release, true);
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> // check if handle was pressed
+</xsl:text>
+ <xsl:text> if (evt.currentTarget == this.handle_elt){
+</xsl:text>
+ <xsl:text> //get mouse position on the handle
+</xsl:text>
+ <xsl:text> let mouseX = undefined;
+</xsl:text>
+ <xsl:text> let mouseY = undefined;
+</xsl:text>
+ <xsl:text> if (evt.type.startsWith("touch")){
+</xsl:text>
+ <xsl:text> mouseX = Math.ceil(evt.touches[0].clientX);
+</xsl:text>
+ <xsl:text> mouseY = Math.ceil(evt.touches[0].clientY);
</xsl:text>
<xsl:text> }
</xsl:text>
<xsl:text> else{
</xsl:text>
- <xsl:text> html_dist = (mouseX - minX)/Math.cos(this.fi);
+ <xsl:text> mouseX = evt.pageX;
+</xsl:text>
+ <xsl:text> mouseY = evt.pageY;
</xsl:text>
<xsl:text> }
</xsl:text>
- <xsl:text>
-</xsl:text>
- <xsl:text> //check if in range
-</xsl:text>
- <xsl:text> if (html_dist > range_length){
-</xsl:text>
- <xsl:text> html_dist = range_length;
-</xsl:text>
- <xsl:text> }
-</xsl:text>
- <xsl:text> else if (html_dist < 0){
-</xsl:text>
- <xsl:text> html_dist = 0;
-</xsl:text>
- <xsl:text> }
-</xsl:text>
- <xsl:text>
+ <xsl:text> //save coordinates and orig value
+</xsl:text>
+ <xsl:text> this.handle_click = [mouseX,mouseY,this.curr_value];
</xsl:text>
<xsl:text> }
</xsl:text>
- <xsl:text>
-</xsl:text>
- <xsl:text> this.svg_dist=Math.ceil((html_dist/range_length)*this.range[1]);
-</xsl:text>
- <xsl:text>
-</xsl:text>
- <xsl:text> this.apply_hmi_value(0, this.svg_dist);
-</xsl:text>
- <xsl:text>
-</xsl:text>
- <xsl:text> // update ghost cursor
-</xsl:text>
- <xsl:text> if(this.setpoint_elt != undefined){
-</xsl:text>
- <xsl:text> this.request_animate();
+ <xsl:text> else{
+</xsl:text>
+ <xsl:text> // get new handle position and reset if handle was not pressed
+</xsl:text>
+ <xsl:text> this.handle_click = undefined;
+</xsl:text>
+ <xsl:text> this.update_position(evt);
</xsl:text>
<xsl:text> }
</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> //prevent next events
+</xsl:text>
+ <xsl:text> evt.stopPropagation();
+</xsl:text>
<xsl:text> }
</xsl:text>
<xsl:text>
</xsl:text>
- <xsl:text> animate(){
-</xsl:text>
- <xsl:text> this.update_DOM(this.svg_dist, this.setpoint_elt);
-</xsl:text>
- <xsl:text> }
-</xsl:text>
- <xsl:text>
-</xsl:text>
- <xsl:text> on_select(evt){
-</xsl:text>
- <xsl:text> this.drag = true;
-</xsl:text>
- <xsl:text> this.enTimer = true;
-</xsl:text>
- <xsl:text> window.addEventListener("touchmove", this.on_bound_drag, true);
-</xsl:text>
- <xsl:text> window.addEventListener("mousemove", this.on_bound_drag, true);
-</xsl:text>
- <xsl:text>
-</xsl:text>
- <xsl:text> window.addEventListener("mouseup", this.bound_on_release, true)
-</xsl:text>
- <xsl:text> window.addEventListener("touchend", this.bound_on_release, true);
-</xsl:text>
- <xsl:text> window.addEventListener("touchcancel", this.bound_on_release, true);
-</xsl:text>
- <xsl:text> this.update_position(evt);
-</xsl:text>
- <xsl:text> }
-</xsl:text>
- <xsl:text>
-</xsl:text>
<xsl:text> init() {
</xsl:text>
+ <xsl:text> //set min max value if not defined
+</xsl:text>
<xsl:text> let min = this.min_elt ?
</xsl:text>
<xsl:text> Number(this.min_elt.textContent) :
@@ -4719,6 +5286,10 @@
</xsl:text>
<xsl:text>
</xsl:text>
+ <xsl:text> // save initial parameters
+</xsl:text>
+ <xsl:text> this.range_elt.style.strokeMiterlimit="0";
+</xsl:text>
<xsl:text> this.range = [min, max, this.range_elt.getPointAtLength(0),this.range_elt.getTotalLength()];
</xsl:text>
<xsl:text> let start = this.range_elt.getPointAtLength(0);
@@ -4727,7 +5298,11 @@
</xsl:text>
<xsl:text> this.fi = Math.atan2(start.y-end.y, end.x-start.x);
</xsl:text>
- <xsl:text>
+ <xsl:text> this.handle_orig = this.handle_elt.getBBox();
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> //bind functions
</xsl:text>
<xsl:text> this.bound_on_select = this.on_select.bind(this);
</xsl:text>
@@ -4737,6 +5312,8 @@
</xsl:text>
<xsl:text>
</xsl:text>
+ <xsl:text> this.handle_elt.addEventListener("mousedown", this.bound_on_select);
+</xsl:text>
<xsl:text> this.element.addEventListener("mousedown", this.bound_on_select);
</xsl:text>
<xsl:text> this.element.addEventListener("touchstart", this.bound_on_select);
@@ -4761,17 +5338,17 @@
<xsl:template mode="widget_defs" match="widget[@type='Slider']">
<xsl:param name="hmi_element"/>
<xsl:call-template name="defs_by_labels">
- <xsl:with-param select="$hmi_element" name="hmi_element"/>
+ <xsl:with-param name="hmi_element" select="$hmi_element"/>
<xsl:with-param name="labels">
<xsl:text>handle range</xsl:text>
</xsl:with-param>
</xsl:call-template>
<xsl:call-template name="defs_by_labels">
- <xsl:with-param select="$hmi_element" name="hmi_element"/>
+ <xsl:with-param name="hmi_element" select="$hmi_element"/>
<xsl:with-param name="labels">
<xsl:text>value min max setpoint</xsl:text>
</xsl:with-param>
- <xsl:with-param select="'no'" name="mandatory"/>
+ <xsl:with-param name="mandatory" select="'no'"/>
</xsl:call-template>
<xsl:text>
</xsl:text>
@@ -4806,9 +5383,9 @@
<xsl:param name="hmi_element"/>
<xsl:text> choices: [
</xsl:text>
- <xsl:variable select="'^("[^"].*"|\-?[0-9]+|false|true)(#.*)?$'" name="regex"/>
+ <xsl:variable name="regex" select="'^("[^"].*"|\-?[0-9]+|false|true)(#.*)?$'"/>
<xsl:for-each select="$result_svg_ns//*[@id = $hmi_element/@id]//*[regexp:test(@inkscape:label,$regex)]">
- <xsl:variable select="regexp:match(@inkscape:label,$regex)[2]" name="literal"/>
+ <xsl:variable name="literal" select="regexp:match(@inkscape:label,$regex)[2]"/>
<xsl:text> {
</xsl:text>
<xsl:text> elt:id("</xsl:text>
@@ -4848,38 +5425,56 @@
</xsl:text>
<xsl:text> dispatch(value) {
</xsl:text>
- <xsl:text> this.state = value;
+ <xsl:text> if(this.state != value){
+</xsl:text>
+ <xsl:text> this.state = value;
+</xsl:text>
+ <xsl:text> if (this.state) {
+</xsl:text>
+ <xsl:text> this.active_elt.setAttribute("style", this.active_style);
+</xsl:text>
+ <xsl:text> this.inactive_elt.setAttribute("style", "display:none");
+</xsl:text>
+ <xsl:text> } else {
+</xsl:text>
+ <xsl:text> this.inactive_elt.setAttribute("style", this.inactive_style);
+</xsl:text>
+ <xsl:text> this.active_elt.setAttribute("style", "display:none");
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> on_click(evt) {
</xsl:text>
<xsl:text> if (this.state) {
</xsl:text>
+ <xsl:text> this.inactive_elt.setAttribute("style", this.inactive_style);
+</xsl:text>
+ <xsl:text> this.active_elt.setAttribute("style", "display:none");
+</xsl:text>
+ <xsl:text> this.state = 0;
+</xsl:text>
+ <xsl:text> } else {
+</xsl:text>
<xsl:text> this.active_elt.setAttribute("style", this.active_style);
</xsl:text>
<xsl:text> this.inactive_elt.setAttribute("style", "display:none");
</xsl:text>
- <xsl:text> this.state = 0;
-</xsl:text>
- <xsl:text> } else {
-</xsl:text>
- <xsl:text> this.inactive_elt.setAttribute("style", this.inactive_style);
-</xsl:text>
- <xsl:text> this.active_elt.setAttribute("style", "display:none");
-</xsl:text>
<xsl:text> this.state = 1;
</xsl:text>
<xsl:text> }
</xsl:text>
+ <xsl:text> this.apply_hmi_value(0, this.state);
+</xsl:text>
<xsl:text> }
</xsl:text>
<xsl:text>
</xsl:text>
- <xsl:text> on_click(evt) {
-</xsl:text>
- <xsl:text> this.apply_hmi_value(0, this.state);
-</xsl:text>
- <xsl:text> }
-</xsl:text>
- <xsl:text>
-</xsl:text>
<xsl:text> init() {
</xsl:text>
<xsl:text> this.active_style = this.active_elt.style.cssText;
@@ -4888,6 +5483,10 @@
</xsl:text>
<xsl:text> this.element.setAttribute("onclick", "hmi_widgets['"+this.element_id+"'].on_click(evt)");
</xsl:text>
+ <xsl:text> this.inactive_elt.setAttribute("style", this.inactive_style);
+</xsl:text>
+ <xsl:text> this.active_elt.setAttribute("style", "display:none");
+</xsl:text>
<xsl:text> }
</xsl:text>
<xsl:text>}
@@ -4896,7 +5495,7 @@
<xsl:template mode="widget_defs" match="widget[@type='ToggleButton']">
<xsl:param name="hmi_element"/>
<xsl:call-template name="defs_by_labels">
- <xsl:with-param select="$hmi_element" name="hmi_element"/>
+ <xsl:with-param name="hmi_element" select="$hmi_element"/>
<xsl:with-param name="labels">
<xsl:text>active inactive</xsl:text>
</xsl:with-param>
@@ -5432,8 +6031,6 @@
</xsl:text>
<xsl:text> if(index > last_remote_index){
</xsl:text>
- <xsl:text> console.log("updated local variable ",index,value);
-</xsl:text>
<xsl:text> updates[index] = value;
</xsl:text>
<xsl:text> requestHMIAnimation();
@@ -5784,8 +6381,6 @@
</xsl:text>
<xsl:text> let [keypadid, xcoord, ycoord] = keypads[valuetype];
</xsl:text>
- <xsl:text> console.log('XXX TODO : Edit value', path, valuetype, callback, initial, keypadid);
-</xsl:text>
<xsl:text> edit_callback = callback;
</xsl:text>
<xsl:text> let widget = hmi_widgets[keypadid];
@@ -5874,8 +6469,6 @@
</xsl:text>
<xsl:text> eltsub.active.setAttribute("style", eltsub.active_style);
</xsl:text>
- <xsl:text> console.log("active", eltsub);
-</xsl:text>
<xsl:text>};
</xsl:text>
<xsl:text>function widget_inactive_activable(eltsub) {
@@ -5890,8 +6483,6 @@
</xsl:text>
<xsl:text> eltsub.inactive.setAttribute("style", eltsub.inactive_style);
</xsl:text>
- <xsl:text> console.log("inactive", eltsub);
-</xsl:text>
<xsl:text>};
</xsl:text>
</script>
--- a/svghmi/inline_svg.ysl2 Wed Sep 16 09:42:26 2020 +0200
+++ b/svghmi/inline_svg.ysl2 Thu Sep 17 11:30:22 2020 +0200
@@ -10,7 +10,10 @@
// Identity template :
// - copy every attributes
// - copy every sub-elements
-template "@* | node()", mode="inline_svg" {
+
+svgtmpl "@*", mode="inline_svg" xsl:copy;
+
+template "node()", mode="inline_svg" {
// use real xsl:copy instead copy-of alias from yslt.yml2
if "not(@id = $discardable_elements/@id)"
xsl:copy apply "@* | node()", mode="inline_svg";
@@ -51,19 +54,22 @@
const "hmi_lists", "$hmi_elements[@id = $hmi_lists_descs/@id]";
const "targets_not_to_unlink", "$hmi_lists/descendant-or-self::svg:*";
const "to_unlink", "$hmi_elements[not(@id = $hmi_pages/@id)]/descendant-or-self::svg:use";
-svgtmpl "svg:use", mode="inline_svg"
-{
- param "seed";
+
+def "func:is_unlinkable" {
+ param "targetid";
+ param "eltid";
+ result "$eltid = $to_unlink/@id and not($targetid = $targets_not_to_unlink/@id)";
+}
+
+svgtmpl "svg:use", mode="inline_svg"{
const "targetid","substring-after(@xlink:href,'#')";
choose {
- when "@id = $to_unlink/@id and not($targetid = $targets_not_to_unlink/@id)" {
+ when "func:is_unlinkable($targetid, @id)" {
call "unlink_clone" {
with "targetid", "$targetid";
- with "seed","$seed";
- }
- }
- otherwise
- xsl:copy apply "@* | node()", mode="inline_svg";
+ }
+ }
+ otherwise xsl:copy apply "@*", mode="inline_svg";
}
}
@@ -87,11 +93,16 @@
svgfunc "unlink_clone"{
param "targetid";
- param "seed";
+ param "seed","''";
const "target", "//svg:*[@id = $targetid]";
- const "seeded_id","concat($seed, @id)";
+ const "seeded_id" choose {
+ when "string-length($seed) > 0" > «$seed»_«@id»
+ otherwise value "@id";
+ }
g{
attrib "id" value "$seeded_id";
+ attrib "original" value "@id";
+
choose {
when "$target[self::svg:g]" {
foreach "@*[not(local-name() = $excluded_use_attrs/name | $merge_use_attrs)]"
@@ -112,7 +123,7 @@
}
apply "$target/*", mode="unlink_clone"{
- with "seed","concat($seed, @id)";
+ with "seed","$seeded_id";
}
}
otherwise {
@@ -121,7 +132,7 @@
attrib "{name()}" > «.»
apply "$target", mode="unlink_clone"{
- with "seed","concat($seed, @id)";
+ with "seed","$seeded_id";
}
}
}
@@ -133,13 +144,25 @@
svgtmpl "@id", mode="unlink_clone" {
param "seed";
attrib "id" > «$seed»_«.»
+ attrib "original" > «.»
}
svgtmpl "@*", mode="unlink_clone" xsl:copy;
svgtmpl "svg:use", mode="unlink_clone" {
param "seed";
- apply "." mode="inline_svg" with "seed","concat($seed, '_')";
+ const "targetid","substring-after(@xlink:href,'#')";
+ choose {
+ when "func:is_unlinkable($targetid, @id)" {
+ call "unlink_clone" {
+ with "targetid", "$targetid";
+ with "seed","$seed";
+ }
+ }
+ otherwise xsl:copy apply "@*", mode="unlink_clone" {
+ with "seed","$seed";
+ }
+ }
}
// copying widgets would have unwanted effect
--- a/svghmi/svghmi.js Wed Sep 16 09:42:26 2020 +0200
+++ b/svghmi/svghmi.js Thu Sep 17 11:30:22 2020 +0200
@@ -240,7 +240,6 @@
function send_hmi_value(index, value) {
if(index > last_remote_index){
- console.log("updated local variable ",index,value);
updates[index] = value;
requestHMIAnimation();
return;
@@ -416,7 +415,6 @@
function edit_value(path, valuetype, callback, initial, size) {
let [keypadid, xcoord, ycoord] = keypads[valuetype];
- console.log('XXX TODO : Edit value', path, valuetype, callback, initial, keypadid);
edit_callback = callback;
let widget = hmi_widgets[keypadid];
widget.start_edit(path, valuetype, callback, initial, size);
@@ -461,7 +459,6 @@
eltsub.inactive.setAttribute("style", "display:none");
if(eltsub.active_style !== undefined)
eltsub.active.setAttribute("style", eltsub.active_style);
- console.log("active", eltsub);
};
function widget_inactive_activable(eltsub) {
if(eltsub.active_style === undefined)
@@ -469,5 +466,4 @@
eltsub.active.setAttribute("style", "display:none");
if(eltsub.inactive_style !== undefined)
eltsub.inactive.setAttribute("style", eltsub.inactive_style);
- console.log("inactive", eltsub);
-};
+};
--- a/svghmi/svghmi.py Wed Sep 16 09:42:26 2020 +0200
+++ b/svghmi/svghmi.py Thu Sep 17 11:30:22 2020 +0200
@@ -216,7 +216,8 @@
hmi_types_instances.pop(i)
break
- assert(hmi_tree_root is not None)
+ if hmi_tree_root is None:
+ self.FatalError("SVGHMI : Library is selected but not used. Please either deselect it in project config or add a SVGHMI node to project.")
# deduce HMI tree from PLC HMI_* instances
for v in hmi_types_instances:
@@ -484,11 +485,18 @@
InkscapeGeomColumns = ["Id", "x", "y", "w", "h"]
inkpath = get_inkscape_path()
+
+ if inkpath is None:
+ self.FatalError("SVGHMI: inkscape is not installed.")
+
svgpath = self._getSVGpath()
- _status, result, _err_result = ProcessLogger(self.GetCTRoot().logger,
- inkpath + " -S " + svgpath,
+ status, result, _err_result = ProcessLogger(self.GetCTRoot().logger,
+ '"' + inkpath + '" -S "' + svgpath + '"',
no_stdout=True,
no_stderr=True).spin()
+ if status != 0:
+ self.FatalError("SVGHMI: inkscape couldn't extract geometry from given SVG.")
+
res = []
for line in result.split():
strippedline = line.strip()
--- a/svghmi/widget_display.ysl2 Wed Sep 16 09:42:26 2020 +0200
+++ b/svghmi/widget_display.ysl2 Thu Sep 17 11:30:22 2020 +0200
@@ -7,7 +7,6 @@
frequency = 5;
dispatch(value, oldval, index) {
this.fields[index] = value;
- console.log(value, index);
this.element.textContent = this.args.length == 1 ? vsprintf(this.args[0],this.fields) : this.fields.join(' ');
}
}
--- a/svghmi/widget_dropdown.ysl2 Wed Sep 16 09:42:26 2020 +0200
+++ b/svghmi/widget_dropdown.ysl2 Thu Sep 17 11:30:22 2020 +0200
@@ -158,7 +158,6 @@
0,
this.menu_offset - spanslength);
}
- console.log(this.menu_offset);
this.set_partial_text();
},
// Setup partial view text content
--- a/svghmi/widget_input.ysl2 Wed Sep 16 09:42:26 2020 +0200
+++ b/svghmi/widget_input.ysl2 Thu Sep 17 11:30:22 2020 +0200
@@ -35,7 +35,7 @@
| },
| on_edit_click: function(opstr) {
| var size = (typeof this.key_pos_elt !== 'undefined') ? this.key_pos_elt.getBBox() : undefined
- | edit_value("«path/@value»", "«path/@type»", this, this.last_val,size);
+ | edit_value("«path/@value»", "«path/@type»", this, this.last_val, size);
| },
| edit_callback: function(new_val) {
--- a/svghmi/widget_jsontable.ysl2 Wed Sep 16 09:42:26 2020 +0200
+++ b/svghmi/widget_jsontable.ysl2 Thu Sep 17 11:30:22 2020 +0200
@@ -3,32 +3,32 @@
template "widget[@type='JsonTable']", mode="widget_class"
||
class JsonTableWidget extends Widget{
- do_http_request() {
+ cache = [];
+ do_http_request(...opt) {
const query = {
- offset: '42',
- filter: '*powerloss*',
- args: this.args
+ args: this.args,
+ vars: this.cache,
+ visible: this.visible,
+ options: opt
};
const options = {
method: 'POST',
body: JSON.stringify(query),
headers: {'Content-Type': 'application/json'}
- }
+ };
fetch(this.args[0], options)
.then(res => res.json())
- .then(this.spread_json_data);
-
- }
- dispatch(value) {
+ .then(this.spread_json_data.bind(this));
+
+ }
+ dispatch(value, oldval, index) {
+ this.cache[index] = value;
this.do_http_request();
}
- on_click(evt) {
- this.do_http_request();
- }
- init() {
- this.element.setAttribute("onclick", "hmi_widgets['"+this.element_id+"'].on_click(evt)");
+ on_click(evt, ...options) {
+ this.do_http_request(...options);
}
}
||
@@ -41,44 +41,171 @@
const "hmi_textstylelists_descs", "$parsed_widgets/widget[@type = 'TextStyleList']";
const "hmi_textstylelists", "$hmi_elements[@id = $hmi_textstylelists_descs/@id]";
+const "textstylelist_related" foreach "$hmi_textstylelists" list {
+ attrib "listid" value "@id";
+ foreach "func:refered_elements(.)" elt {
+ attrib "eltid" value "@id";
+ }
+}
+const "textstylelist_related_ns", "exsl:node-set($textstylelist_related)";
+
+def "func:json_expressions" {
+ param "expressions";
+ param "label";
+
+ // compute javascript expressions to access JSON data
+ // desscribed in given svg element's "label"
+ // knowing that parent element already has given "expressions".
+
+ choose {
+ when "$label" {
+ const "suffixes", "str:split($label)";
+ const "res" foreach "$suffixes" expression {
+ const "suffix",".";
+ const "pos","position()";
+ // take last available expression (i.e can have more suffixes than expressions)
+ const "expr","$expressions[position() <= $pos][last()]/expression";
+ choose {
+ when "contains($suffix,'=')" {
+ const "name", "substring-before($suffix,'=')";
+ if "$expr/@name[. != $name]"
+ error > JsonTable : missplaced '=' or inconsistent names in Json data expressions.
+ attrib "name" value "$name";
+ attrib "content" > «$expr/@content»«substring-after($suffix,'=')»
+ }
+ otherwise {
+ copy "$expr/@name";
+ attrib "content" > «$expr/@content»«$suffix»
+ }
+ }
+ }
+ result "exsl:node-set($res)";
+ }
+ // Empty labels are ignored, expressions are then passed as-is.
+ otherwise result "$expressions";
+ }
+
+}
+
+const "initexpr" expression attrib "content" > jdata
+const "initexpr_ns", "exsl:node-set($initexpr)";
+
template "svg:use", mode="json_table_elt_render" {
- param "value_expr";
+ param "expressions";
// cloned element must be part of a HMI:List
const "targetid", "substring-after(@xlink:href,'#')";
const "from_list", "$hmi_lists[(@id | */@id) = $targetid]";
- const "from_textstylelist", "$hmi_textstylelists[(@id | */@id) = $targetid]";
choose {
when "count($from_list) > 0" {
| id("«@id»").setAttribute("xlink:href",
// obtain new target id from HMI:List widget
- | "#"+hmi_widgets["«$from_list/@id»"].items[«$value_expr»]);
- }
+ | "#"+hmi_widgets["«$from_list/@id»"].items[«$expressions/expression[1]/@content»]);
+ }
+ otherwise
+ warning > Clones (svg:use) in JsonTable Widget must point to a valid HMI:List widget or item. Reference "«@xlink:href»" is not valid and will not be updated.
+ }
+}
+
+template "svg:text", mode="json_table_elt_render" {
+ param "expressions";
+ const "value_expr", "$expressions/expression[1]/@content";
+ const "original", "@original";
+ const "from_textstylelist", "$textstylelist_related_ns/list[elt/@eltid = $original]";
+ choose {
+
when "count($from_textstylelist) > 0" {
- | console.log("from_textsylelist","«@id»", "«$value_expr»", «$value_expr»,
- // obtain new style from HMI:TextStyleList widget
- | hmi_widgets["«$from_textstylelist/@id»"].items[«$value_expr»]);
- }
- otherwise
- warning > Clones (svg:use) in JsonTable Widget must point to a valid HMI:List or HMI:TextStyleList widget or item. Reference "«@xlink:href»" is not valid and will not be updated.
- }
-}
-
-template "svg:text", mode="json_table_elt_render" {
- param "value_expr";
- | id("«@id»").textContent = String(«$value_expr»);
-}
+ const "content_expr", "$expressions/expression[2]/@content";
+ if "string-length($content_expr) = 0 or $expressions/expression[2]/@name != 'textContent'"
+ error > Clones (svg:use) in JsonTable Widget pointing to a HMI:TextStyleList widget or item must have a "textContent=.someVal" assignement following value expression in label.
+ | {
+ | let elt = id("«@id»");
+ | elt.textContent = String(«$content_expr»);
+ | elt.style = hmi_widgets["«$from_textstylelist/@listid»"].styles[«$value_expr»];
+ | }
+ }
+ otherwise {
+ | id("«@id»").textContent = String(«$value_expr»);
+ }
+ }
+}
+
+
+// only labels comming from Json widget are counted in
+def "func:filter_non_widget_label" {
+ param "elt";
+ param "widget_elts";
+ const "eltid" choose {
+ when "$elt/@original" value "$elt/@original";
+ otherwise value "$elt/@id";
+ }
+ result "$widget_elts[@id=$eltid]/@inkscape:label";
+}
+
+template "svg:*", mode="json_table_render_except_comments"{
+ param "expressions";
+ param "widget_elts";
+
+ const "label", "func:filter_non_widget_label(., $widget_elts)";
+ // filter out "# commented" elements
+ if "not(starts-with($label,'#'))"
+ apply ".", mode="json_table_render"{
+ with "expressions", "$expressions";
+ with "widget_elts", "$widget_elts";
+ with "label", "$label";
+ }
+}
+
template "svg:*", mode="json_table_render" {
- param "objname";
- apply ".", mode="json_table_elt_render" with "value_expr" > «$objname»«substring-before(@inkscape:label, ' ')»
+ param "expressions";
+ param "widget_elts";
+ param "label";
+
+ const "new_expressions", "func:json_expressions($expressions, $label)";
+
+ const "elt",".";
+ foreach "$new_expressions/expression[position() > 1][starts-with(@name,'onClick')]"
+ | id("«$elt/@id»").setAttribute("onclick", "hmi_widgets['"+this.element_id+"'].on_click(evt, '«@name»', '"+«@content»+"')");
+
+ apply ".", mode="json_table_elt_render"
+ with "expressions", "$new_expressions";
}
template "svg:g", mode="json_table_render" {
- param "objname";
- | let obj_«@id» = «$objname»«substring-before(@inkscape:label, ' ')»;
- apply "*[@inkscape:label]", mode="json_table_render"
- with "objname" > obj_«@id»
+ param "expressions";
+ param "widget_elts";
+ param "label";
+ const "gid", "@id";
+
+ // use intermediate variables for optimization
+ const "varprefix" > obj_«$gid»_
+ | try {
+
+ foreach "$expressions/expression"{
+ | let «$varprefix»«position()» = «@content»;
+ | if(«$varprefix»«position()» == undefined) {
+ | console.log("«$varprefix»«position()» = «@content»");
+ | throw null;
+ | }
+ }
+
+ // because we put values in a variables, we can replace corresponding expression with variable name
+ const "new_expressions" foreach "$expressions/expression" xsl:copy {
+ copy "@name";
+ attrib "content" > «$varprefix»«position()»
+ }
+
+ // revert hiding in case it did happen before
+ | id("«@id»").setAttribute("style", "«@style»");
+
+ apply "*", mode="json_table_render_except_comments" {
+ with "expressions", "func:json_expressions(exsl:node-set($new_expressions), $label)";
+ with "widget_elts", "$widget_elts";
+ }
+ | } catch(err) {
+ | id("«$gid»").setAttribute("style", "display:none");
+ | }
}
template "widget[@type='JsonTable']", mode="widget_defs" {
@@ -86,7 +213,15 @@
labels("data");
optional_labels("forward backward cursor");
const "data_elt", "$result_svg_ns//*[@id = $hmi_element/@id]/*[@inkscape:label = 'data']";
- | spread_json_data: function(jdata) {
- apply "$data_elt/*", mode="json_table_render" with "objname","'jdata'";
+ | visible: «count($data_elt/*[@inkscape:label])»,
+ | spread_json_data: function(janswer) {
+ | let [range,position,jdata] = janswer;
+ | this.apply_hmi_value(1, range);
+ | this.apply_hmi_value(2, position);
+ | console.log(range,position,jdata);
+ apply "$data_elt", mode="json_table_render_except_comments" {
+ with "expressions","$initexpr_ns";
+ with "widget_elts","$hmi_element/*[@inkscape:label = 'data']/descendant::svg:*";
+ }
| }
}
--- a/svghmi/widget_keypad.ysl2 Wed Sep 16 09:42:26 2020 +0200
+++ b/svghmi/widget_keypad.ysl2 Thu Sep 17 11:30:22 2020 +0200
@@ -104,9 +104,16 @@
}
on_Enter_click() {
- end_modal.call(this);
- let callback_obj = this.result_callback_obj;
- callback_obj.edit_callback(this.editstr);
+ let coercedval = (typeof this.initial) == "number" ? Number(this.editstr) : this.editstr;
+ if(typeof coercedval == 'number' && isNaN(coercedval)){
+ // revert to initial so it explicitely shows input was ignored
+ this.editstr = String(this.initial);
+ this.update();
+ } else {
+ let callback_obj = this.result_callback_obj;
+ end_modal.call(this);
+ callback_obj.edit_callback(coercedval);
+ }
}
on_BackSpace_click() {
@@ -153,11 +160,13 @@
result_callback_obj = undefined;
start_edit(info, valuetype, callback_obj, initial,size) {
show_modal.call(this,size);
- this.editstr = initial;
+ this.editstr = String(initial);
this.result_callback_obj = callback_obj;
this.Info_elt.textContent = info;
this.shift = false;
this.caps = false;
+ this.initial = initial;
+
this.update();
}
--- a/svghmi/widget_list.ysl2 Wed Sep 16 09:42:26 2020 +0200
+++ b/svghmi/widget_list.ysl2 Thu Sep 17 11:30:22 2020 +0200
@@ -1,10 +1,20 @@
// widget_list.ysl2
-template "widget[@type='List' or @type='TextStyleList']", mode="widget_defs" {
+template "widget[@type='List']", mode="widget_defs" {
param "hmi_element";
| items: {
foreach "$hmi_element/*[@inkscape:label]" {
- | «func:escape_quotes(@inkscape:label)»: "«@id»",
+ | «@inkscape:label»: "«@id»",
}
| },
}
+
+template "widget[@type='TextStyleList']", mode="widget_defs" {
+ param "hmi_element";
+ | styles: {
+ foreach "$hmi_element/*[@inkscape:label]" {
+ const "style", "func:refered_elements(.)[self::svg:text]/@style";
+ | «@inkscape:label»: "«$style»",
+ }
+ | },
+}
--- a/svghmi/widgets_common.ysl2 Wed Sep 16 09:42:26 2020 +0200
+++ b/svghmi/widgets_common.ysl2 Thu Sep 17 11:30:22 2020 +0200
@@ -29,8 +29,10 @@
choose {
when "not(@index)" {
choose {
- when "not(@type)"
+ when "not(@type)" {
warning > Widget «$widget/@type» id="«$eltid»" : No match for path "«@value»" in HMI tree
+ > undefined`if "position()!=last()" > ,`
+ }
when "@type = 'PAGE_LOCAL'"
> "«@value»"`if "position()!=last()" > ,`
when "@type = 'HMI_LOCAL'"
@@ -152,6 +154,7 @@
if(!this.unsubscribable)
for(let i = 0; i < this.indexes.length; i++) {
let index = this.get_variable_index(i);
+ if(index == undefined) continue;
subscribers(index).add(this);
}
need_cache_apply.push(this);
@@ -161,6 +164,7 @@
if(!this.unsubscribable) for(let index in this.indexes){
/* dispatch current cache in newly opened page widgets */
let realindex = this.get_variable_index(index);
+ if(realindex == undefined) continue;
let cached_val = cache[realindex];
if(cached_val != undefined)
this._dispatch(cached_val, cached_val, index);
@@ -178,18 +182,23 @@
}
return index;
}
- change_hmi_value(index,opstr) {
- return change_hmi_value(this.get_variable_index(index), opstr);
+ change_hmi_value(index, opstr) {
+ let realindex = this.get_variable_index(index);
+ if(realindex == undefined) return undefined;
+ return change_hmi_value(realindex, opstr);
}
apply_hmi_value(index, new_val) {
- return apply_hmi_value(this.get_variable_index(0), new_val);
+ let realindex = this.get_variable_index(index);
+ if(realindex == undefined) return undefined;
+ return apply_hmi_value(realindex, new_val);
}
new_hmi_value(index, value, oldval) {
// TODO avoid searching, store index at sub()
for(let i = 0; i < this.indexes.length; i++) {
let refindex = this.get_variable_index(i);
+ if(refindex == undefined) continue;
if(index == refindex) {
this._dispatch(value, oldval, i);
--- a/tests/svghmi/py_ext_0@py_ext/pyfile.xml Wed Sep 16 09:42:26 2020 +0200
+++ b/tests/svghmi/py_ext_0@py_ext/pyfile.xml Thu Sep 17 11:30:22 2020 +0200
@@ -1,33 +1,69 @@
<?xml version='1.0' encoding='utf-8'?>
<PyFile xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<variables>
- <variable name="SomePLCglobal" type="HMI_STRING" onchange="MyOnChangeFunc"/>
- <variable name="AlarmCount" type="HMI_INT"/>
+ <variable name="AlarmNotify" type="HMI_INT"/>
+ <variable name="SendAlarm" type="HMI_INT" onchange="TriggerAlarm"/>
+ <variable name="AlarmText" type="HMI_STRING" initial="'POS'"/>
+ <variable name="AlarmStatus" type="HMI_STRING" initial="'alarm'"/>
</variables>
<globals>
<xhtml:p><![CDATA[
from twisted.web.resource import Resource
-import json
+import json, time, random, collections
+
+Alarms = []
+AlarmIndex = {}
+lastid = 0
+
+def TriggerAlarm(changed_var_name):
+ global Alarms, lastid
+ new_entry = [time.time(), PLCGlobals.AlarmText, PLCGlobals.AlarmStatus, lastid]
+ Alarms.append(new_entry)
+ AlarmIndex[lastid] = new_entry
+ lastid = lastid + 1
+ PLCGlobals.AlarmNotify = random.randint(0, 4294967296)
class AlarmJsonResource(Resource):
def render_GET(self, request):
return ''
def render_POST(self, request):
- print(request.__dict__)
- newdata = request.content.getvalue()
- print newdata
- selected_alarms = [
- {"name":"three", "sides":3},
- {"name":"four", "sides":4},
- {"name":"five", "sides":5},
- {"name":"six", "sides":6},
- ]
- return json.dumps(selected_alarms)
+ newstr = request.content.getvalue()
+ newdata = json.loads(newstr)
+ vars = newdata[u'vars']
+ args = newdata[u'args']
+ visible = newdata[u'visible']
+ options = newdata[u'options']
+ if len(options) == 2 :
+ action, alarmid = options
+ if action == "onClick[acknowledge]":
+ AlarmIndex[int(alarmid)][2] = "ack"
-def MyOnChangeFunc(changed_var_name):
- print changed_var_name + ": " + getattr(PLCGlobals, changed_var_name)
+ 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)
+ return janswer
+
+ 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
+
+ visible_alarms = []
+ for ts, text, status, alarmid in Alarms[new_position:new_position + new_visible]:
+ visible_alarms.append({
+ "time": time.ctime(ts),
+ "text": text, # TODO translate text
+ "status": status,
+ "alarmid": alarmid
+ })
+
+ return new_range, new_position, visible_alarms
+
]]></xhtml:p>
</globals>
--- a/tests/svghmi/svghmi_0@svghmi/svghmi.svg Wed Sep 16 09:42:26 2020 +0200
+++ b/tests/svghmi/svghmi_0@svghmi/svghmi.svg Thu Sep 17 11:30:22 2020 +0200
@@ -16,7 +16,7 @@
version="1.1"
id="hmi0"
sodipodi:docname="svghmi.svg"
- inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
+ inkscape:version="0.92.3 (2405546, 2018-03-11)">
<metadata
id="metadata4542">
<rdf:RDF>
@@ -34,6 +34,21 @@
<marker
inkscape:isstock="true"
style="overflow:visible"
+ id="marker1971"
+ refX="0"
+ refY="0"
+ orient="auto"
+ inkscape:stockid="Arrow2Lend">
+ <path
+ transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+ style="fill:#ff3000;fill-opacity:1;fill-rule:evenodd;stroke:#ff3000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+ id="path1969"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <marker
+ inkscape:isstock="true"
+ style="overflow:visible"
id="marker1536"
refX="0"
refY="0"
@@ -42,7 +57,7 @@
<path
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
- style="fill:#c130f7;fill-opacity:1;fill-rule:evenodd;stroke:#c130f7;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+ style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
id="path1534"
inkscape:connector-curvature="0" />
</marker>
@@ -182,17 +197,17 @@
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:document-units="px"
- inkscape:current-layer="g907"
+ inkscape:current-layer="g1384"
showgrid="false"
units="px"
- inkscape:zoom="0.50000001"
- inkscape:cx="632.83299"
- inkscape:cy="-317.59408"
- inkscape:window-width="2443"
- inkscape:window-height="1567"
- inkscape:window-x="816"
- inkscape:window-y="103"
- inkscape:window-maximized="0"
+ inkscape:zoom="1.0913159"
+ inkscape:cx="-911.00114"
+ inkscape:cy="181.96708"
+ inkscape:window-width="1800"
+ inkscape:window-height="836"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
showguides="true"
inkscape:guide-bbox="true" />
<rect
@@ -1492,7 +1507,7 @@
transform="matrix(3.3549332,0,0,3.14525,-181.87457,1556.0198)"
style="fill-rule:evenodd;stroke-width:0.47631353"
id="g4278"
- inkscape:label="HMI:Keypad:HMI_STRING">
+ inkscape:label="HMI:Keypad:HMI_STRING:HMI_LOCAL:PAGE_LOCAL">
<path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.6;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.16776976;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"
d="M 54.211084,1.2654702 H 435.7388 V 230.18209 H 54.211084 Z"
@@ -2639,443 +2654,6 @@
</g>
</g>
<g
- transform="matrix(0.28590269,0,0,0.28590269,-13.279646,425.80032)"
- id="g208-1-3"
- inkscape:label="HMI:Input@/SOMEPLCGLOBAL"
- style="stroke-width:2">
- <text
- inkscape:label="value"
- id="text164-6"
- y="218.24219"
- x="136.32812"
- 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"
- y="218.24219"
- x="136.32812"
- id="tspan162-7"
- sodipodi:role="line">8888</tspan></text>
- <rect
- 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"
- id="rect166-5"
- width="407.7037"
- height="128"
- x="139.85185"
- y="95.40741"
- onclick=""
- inkscape:label="edit" />
- <g
- transform="translate(-416.52022,170.47452)"
- inkscape:label="+"dhu""
- id="g174-3"
- style="stroke-width:2">
- <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;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"
- id="path168-5"
- inkscape:connector-curvature="0" />
- <text
- xml:space="preserve"
- 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"
- x="733.58197"
- y="111.05016"
- id="text172-6"><tspan
- sodipodi:role="line"
- id="tspan170-2"
- x="733.58197"
- y="111.05016"
- style="stroke-width:1px">dhu</tspan></text>
- </g>
- <g
- transform="translate(-416.52022,170.47452)"
- inkscape:label="="plop""
- id="g182-9"
- style="stroke-width:2">
- <path
- transform="matrix(0,-2.0000001,1.9999999,0,1034.195,1298.6541)"
- sodipodi:type="star"
- 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"
- id="path176-1"
- sodipodi:sides="3"
- 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:rounded="0"
- 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" />
- <text
- id="text180-2"
- y="111.05016"
- x="633.09552"
- 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"
- y="111.05016"
- x="633.09552"
- id="tspan178-7"
- sodipodi:role="line">plop</tspan></text>
- </g>
- <g
- transform="translate(-416.52022,170.47452)"
- inkscape:label="="mhoo""
- id="g190-0"
- style="stroke-width:2">
- <path
- 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:rounded="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"
- sodipodi:sides="3"
- id="path184-9"
- 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:type="star"
- transform="rotate(-90,746.45698,-44.543641)"
- inkscape:transform-center-x="14.956364" />
- <text
- xml:space="preserve"
- 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"
- x="537.25018"
- y="111.05016"
- id="text188-3"><tspan
- sodipodi:role="line"
- id="tspan186-6"
- x="537.25018"
- y="111.05016"
- style="stroke-width:1px">mhoo</tspan></text>
- </g>
- <g
- transform="translate(-416.52022,170.47452)"
- inkscape:label="="yodl""
- id="g198-0"
- style="stroke-width:2">
- <path
- sodipodi:type="star"
- 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"
- id="path192-6"
- sodipodi:sides="3"
- 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:rounded="0"
- 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" />
- <text
- xml:space="preserve"
- 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"
- x="925.82605"
- y="111.05016"
- id="text196-2"><tspan
- sodipodi:role="line"
- id="tspan194-6"
- x="925.82605"
- y="111.05016"
- style="stroke-width:1px">yodl</tspan></text>
- </g>
- <g
- transform="translate(-416.52022,170.47452)"
- inkscape:label="="mhe""
- id="g206-1-1"
- style="stroke-width:2">
- <path
- 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:rounded="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"
- sodipodi:sides="3"
- id="path200-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: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:type="star"
- transform="matrix(0,-2.0000001,-1.9999999,0,1122.1514,1298.6541)"
- inkscape:transform-center-x="-14.956349" />
- <text
- id="text204-7"
- y="111.05016"
- x="842.71497"
- 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"
- y="111.05016"
- x="842.71497"
- id="tspan202-9"
- sodipodi:role="line">mhe</tspan></text>
- </g>
- </g>
- <g
- id="g1289"
- inkscape:label="HMI:JsonTable:/alarms@/ALARMCOUNT"
- transform="matrix(0.5,0,0,0.5,635.30409,71.500438)">
- <g
- id="g5231"
- inkscape:label="data">
- <g
- id="g1384"
- inkscape:label="[0]"
- transform="translate(52.325902,207.55635)">
- <use
- x="0"
- y="0"
- xlink:href="#use1297"
- inkscape:transform-center-x="0.11123312"
- inkscape:transform-center-y="2.2824109"
- id="use1378"
- width="100%"
- height="100%"
- transform="matrix(0.7609336,0,0,0.7609336,199.15217,164.3798)"
- inkscape:label=".sides" />
- <use
- transform="matrix(2,0,0,2,-474.04606,349.02524)"
- x="0"
- y="0"
- xlink:href="#use913"
- id="use966"
- width="100%"
- height="100%"
- inkscape:label=".textstyle textContent=.name" />
- </g>
- <use
- inkscape:label="[1]"
- transform="translate(0,-64)"
- height="100%"
- width="100%"
- id="use5200"
- xlink:href="#g1384"
- y="0"
- x="0" />
- <use
- inkscape:label="[2]"
- x="0"
- y="0"
- xlink:href="#g1384"
- id="use5202"
- width="100%"
- height="100%"
- transform="translate(0,-128)" />
- <use
- inkscape:label="[3]"
- transform="translate(0,-192)"
- height="100%"
- width="100%"
- id="use5204"
- xlink:href="#g1384"
- y="0"
- x="0" />
- </g>
- </g>
- <g
- id="g1332"
- inkscape:label="polygons"
- transform="translate(-126,32)">
- <path
- inkscape:transform-center-y="2.9995242"
- inkscape:transform-center-x="0.14620371"
- d="m 861.96316,-226.81598 -27.92731,5.51725 -27.92732,5.51724 9.18558,-26.94439 9.18559,-26.94439 18.74173,21.42715 z"
- inkscape:randomized="0"
- inkscape:rounded="0"
- inkscape:flatsided="false"
- sodipodi:arg2="1.3757507"
- sodipodi:arg1="0.32855317"
- sodipodi:r2="16.43548"
- sodipodi:r1="32.87096"
- sodipodi:cy="-237.42258"
- sodipodi:cx="830.85046"
- sodipodi:sides="3"
- id="path1298"
- style="fill:#8fbc8f;fill-opacity:1;stroke:#ff0000"
- sodipodi:type="star"
- inkscape:label="three" />
- <path
- sodipodi:type="star"
- style="fill:#ff8c00;fill-opacity:1;stroke:#ff0000"
- id="path1308"
- sodipodi:sides="4"
- sodipodi:cx="890.85046"
- sodipodi:cy="-237.42258"
- sodipodi:r1="32.87096"
- sodipodi:r2="16.43548"
- sodipodi:arg1="0.32855317"
- sodipodi:arg2="1.1139513"
- inkscape:flatsided="false"
- inkscape:rounded="0"
- inkscape:randomized="0"
- d="m 921.96316,-226.81598 -23.8627,4.1434 -17.8566,16.3627 -4.1434,-23.8627 -16.36269,-17.8566 23.86269,-4.1434 17.85661,-16.3627 4.14339,23.8627 z"
- inkscape:transform-center-x="0.14620371"
- inkscape:transform-center-y="2.9995242"
- inkscape:label="four" />
- <path
- inkscape:transform-center-y="2.9995242"
- inkscape:transform-center-x="0.14620371"
- d="m 981.96316,-226.81598 -21.64455,2.82766 -9.94127,19.4333 -9.37779,-19.7114 -21.55419,-3.44949 15.84875,-15.00997 -3.37994,-21.5652 19.17286,10.43473 19.46526,-9.87854 -3.99927,21.45898 z"
- inkscape:randomized="0"
- inkscape:rounded="0"
- inkscape:flatsided="false"
- sodipodi:arg2="0.9568717"
- sodipodi:arg1="0.32855317"
- sodipodi:r2="16.43548"
- sodipodi:r1="32.87096"
- sodipodi:cy="-237.42258"
- sodipodi:cx="950.85046"
- sodipodi:sides="5"
- id="path1310"
- style="fill:#bc8f8f;fill-opacity:1;stroke:#ff0000"
- sodipodi:type="star"
- inkscape:label="five" />
- <path
- sodipodi:type="star"
- style="fill:#f0f8ff;fill-opacity:1;stroke:#ff0000"
- id="path1312"
- sodipodi:sides="6"
- sodipodi:cx="1010.8505"
- sodipodi:cy="-237.42258"
- sodipodi:r1="32.87096"
- sodipodi:r2="16.43548"
- sodipodi:arg1="0.32855317"
- sodipodi:arg2="0.85215195"
- inkscape:flatsided="false"
- inkscape:rounded="0"
- inkscape:randomized="0"
- d="m 1041.9632,-226.81598 -20.2921,1.76437 -4.4498,19.87672 -11.6741,-16.69134 -19.43861,6.08474 8.61809,-18.45571 -14.98885,-13.79198 20.29217,-1.76436 4.4498,-19.87673 11.674,16.69134 19.4387,-6.08473 -8.6181,18.4557 z"
- inkscape:transform-center-x="0.14620371"
- inkscape:transform-center-y="2.9995242"
- inkscape:label="six" />
- <path
- 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:rounded="0"
- inkscape:flatsided="false"
- sodipodi:arg2="0.77735212"
- sodipodi:arg1="0.32855317"
- sodipodi:r2="16.43548"
- sodipodi:r1="32.87096"
- sodipodi:cy="-237.42258"
- sodipodi:cx="1070.8505"
- sodipodi:sides="7"
- id="path1314"
- style="fill:#ba55d3;fill-opacity:1;stroke:#ff0000"
- sodipodi:type="star"
- inkscape:label="seven" />
- <path
- sodipodi:type="star"
- style="fill:#ffff00;fill-opacity:1;stroke:#ff0000"
- id="path1316"
- sodipodi:sides="8"
- sodipodi:cx="1130.8505"
- sodipodi:cy="-237.42258"
- sodipodi:r1="32.87096"
- sodipodi:r2="16.43548"
- sodipodi:arg1="0.32855317"
- sodipodi:arg2="0.72125225"
- inkscape:flatsided="false"
- inkscape:rounded="0"
- 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" />
- </g>
- <g
- inkscape:label="HMI:List"
- id="g1311"
- transform="translate(-126,32)">
- <use
- x="0"
- y="0"
- xlink:href="#path1298"
- inkscape:transform-center-x="0.14620371"
- inkscape:transform-center-y="2.9995242"
- id="use1293"
- width="100%"
- height="100%"
- transform="translate(150.23297,80)"
- style="display:inline"
- inkscape:label="3" />
- <use
- x="0"
- y="0"
- xlink:href="#path1308"
- inkscape:transform-center-x="0.14620371"
- inkscape:transform-center-y="2.9995242"
- id="use1295"
- width="100%"
- height="100%"
- transform="translate(93.515259,80)"
- inkscape:label="4" />
- <use
- x="0"
- y="0"
- xlink:href="#path1310"
- inkscape:transform-center-x="0.14620371"
- inkscape:transform-center-y="2.9995242"
- id="use1297"
- width="100%"
- height="100%"
- transform="translate(33.666488,80)"
- inkscape:label="5" />
- <use
- x="0"
- y="0"
- xlink:href="#path1312"
- inkscape:transform-center-x="0.14620371"
- inkscape:transform-center-y="2.9995242"
- id="use1299"
- width="100%"
- height="100%"
- transform="translate(-26.484802,80)"
- inkscape:label="6" />
- <use
- x="0"
- y="0"
- xlink:href="#path1314"
- inkscape:transform-center-x="0.14620371"
- inkscape:transform-center-y="2.9995242"
- id="use1301"
- width="100%"
- height="100%"
- transform="translate(-85.692787,80)"
- inkscape:label="7" />
- <use
- x="0"
- y="0"
- xlink:href="#path1316"
- inkscape:transform-center-x="0.14620371"
- inkscape:transform-center-y="2.9995242"
- id="use1303"
- width="100%"
- height="100%"
- transform="translate(-146.48474,80)"
- style="display:inline"
- inkscape:label="8" />
- </g>
- <g
transform="matrix(3.3549332,0,0,3.14525,-181.87457,3116.0198)"
style="fill-rule:evenodd;stroke-width:0.47631353"
id="g1490"
@@ -3144,67 +2722,6 @@
id="tspan1480"
sodipodi:role="line">information</tspan></text>
</g>
- <g
- transform="matrix(0.2527605,0,0,0.2527605,1089.2831,6.7725187)"
- inkscape:label="HMI:Input@/ALARMCOUNT"
- id="g5222">
- <text
- xml:space="preserve"
- 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:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- x="136.32812"
- y="218.24219"
- id="text5208"
- inkscape:label="value"><tspan
- sodipodi:role="line"
- id="tspan5206"
- x="136.32812"
- y="218.24219"
- style="stroke-width:1px">8888</tspan></text>
- <path
- transform="scale(1,-1)"
- sodipodi:type="star"
- 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="path5212"
- sodipodi:sides="3"
- 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:rounded="0"
- inkscape:randomized="0"
- d="m 622.6459,-170.03172 -51.81035,0 25.90517,-44.86908 z"
- inkscape:transform-center-y="7.4781812"
- inkscape:label="-1" />
- <rect
- inkscape:label="edit"
- onclick=""
- y="95.40741"
- x="139.85185"
- height="128"
- width="407.7037"
- id="rect5214"
- 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: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" />
- <path
- inkscape:label="+1"
- inkscape:transform-center-y="-7.4781804"
- d="m 622.6459,151.4008 -51.81035,0 25.90517,-44.86908 z"
- inkscape:randomized="0"
- inkscape:rounded="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"
- sodipodi:sides="3"
- id="path5218"
- 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"
- sodipodi:type="star" />
- </g>
<rect
inkscape:label="HMI:Page:RelativePageTest@/PUMP0"
y="0"
@@ -3236,7 +2753,7 @@
inkscape:connector-curvature="0"
id="path1320"
d="M 130.96206,4.0725977 79.111776,-41.363223"
- style="fill:none;fill-rule:evenodd;stroke:#ff3000;stroke-width:2.96333337;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:0, 32.59666667;stroke-dashoffset:29.63333321;stroke-opacity:1;marker-end:url(#marker1656)" />
+ style="fill:none;fill-rule:evenodd;stroke:#ff3000;stroke-width:2.9633333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:29.63333301;stroke-opacity:1;marker-end:url(#marker1656)" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:125%;font-family:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;fill:#ff6600;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
@@ -4224,23 +3741,23 @@
<text
inkscape:label="HMI:Display@paff"
id="text1457"
- y="108.60184"
- x="902.83728"
- style="font-style:normal;font-weight:normal;font-size:45.74443054px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.28590268px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ y="68.844757"
+ x="590.28473"
+ style="font-style:normal;font-weight:normal;font-size:22.87221527px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.28590268px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="fill:#ffffff;fill-opacity:1;stroke-width:0.28590268px"
- y="108.60184"
- x="902.83728"
+ y="68.844757"
+ x="590.28473"
id="tspan1455"
sodipodi:role="line">8888</tspan></text>
<g
- style="stroke-width:2"
+ style="stroke-width:4"
inkscape:label="HMI:Input@paff"
id="g1505"
- transform="matrix(0.28590269,0,0,0.28590269,700.70444,46.1427)">
+ transform="matrix(0.14295135,0,0,0.14295135,489.21833,37.615184)">
<text
xml:space="preserve"
- 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"
+ 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:4px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="136.32812"
y="218.24219"
id="text1461"
@@ -4249,7 +3766,7 @@
id="tspan1459"
x="136.32812"
y="218.24219"
- style="stroke-width:2px">8888</tspan></text>
+ style="stroke-width:4px">8888</tspan></text>
<rect
inkscape:label="edit"
onclick=""
@@ -4258,9 +3775,9 @@
height="128"
width="407.7037"
id="rect1463"
- 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" />
- <g
- style="stroke-width:2"
+ 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:20;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" />
+ <g
+ style="stroke-width:4"
id="g1471"
inkscape:label="+"dhu""
transform="translate(-416.52022,170.47452)">
@@ -4269,21 +3786,21 @@
id="path1465"
d="m 797.19546,145.18619 -80.62929,0.60214 -0.60215,-80.629288 80.6293,-0.60214 z"
inkscape:transform-center-y="-14.956361"
- 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" />
+ 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:20;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" />
<text
id="text1469"
y="111.05016"
x="733.58197"
- 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="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:2px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
- style="stroke-width:1px"
+ style="stroke-width:2px"
y="111.05016"
x="733.58197"
id="tspan1467"
sodipodi:role="line">dhu</tspan></text>
</g>
<g
- style="stroke-width:2"
+ style="stroke-width:4"
id="g1479"
inkscape:label="="plop""
transform="translate(-416.52022,170.47452)">
@@ -4302,12 +3819,12 @@
sodipodi:cx="596.74072"
sodipodi:sides="3"
id="path1473"
- 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"
+ 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:20;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:type="star"
transform="matrix(0,-2.0000001,1.9999999,0,1034.195,1298.6541)" />
<text
xml:space="preserve"
- 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="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:2px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="633.09552"
y="111.05016"
id="text1477"><tspan
@@ -4315,10 +3832,10 @@
id="tspan1475"
x="633.09552"
y="111.05016"
- style="stroke-width:1px">plop</tspan></text>
- </g>
- <g
- style="stroke-width:2"
+ style="stroke-width:2px">plop</tspan></text>
+ </g>
+ <g
+ style="stroke-width:4"
id="g1487"
inkscape:label="="mhoo""
transform="translate(-416.52022,170.47452)">
@@ -4326,7 +3843,7 @@
inkscape:transform-center-x="14.956364"
transform="rotate(-90,746.45698,-44.543641)"
sodipodi:type="star"
- 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"
+ 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:20;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="path1481"
sodipodi:sides="3"
sodipodi:cx="596.74072"
@@ -4344,16 +3861,16 @@
id="text1485"
y="111.05016"
x="537.25018"
- 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="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:2px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
- style="stroke-width:1px"
+ style="stroke-width:2px"
y="111.05016"
x="537.25018"
id="tspan1483"
sodipodi:role="line">mhoo</tspan></text>
</g>
<g
- style="stroke-width:2"
+ style="stroke-width:4"
id="g1495"
inkscape:label="="yodl""
transform="translate(-416.52022,170.47452)">
@@ -4373,22 +3890,22 @@
sodipodi:cx="596.74072"
sodipodi:sides="3"
id="path1489"
- 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"
+ 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:20;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:type="star" />
<text
id="text1493"
y="111.05016"
x="925.82605"
- 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="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:2px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
- style="stroke-width:1px"
+ style="stroke-width:2px"
y="111.05016"
x="925.82605"
id="tspan1491"
sodipodi:role="line">yodl</tspan></text>
</g>
<g
- style="stroke-width:2"
+ style="stroke-width:4"
id="g1503"
inkscape:label="="mhe""
transform="translate(-416.52022,170.47452)">
@@ -4396,7 +3913,7 @@
inkscape:transform-center-x="-14.956349"
transform="matrix(0,-2.0000001,-1.9999999,0,1122.1514,1298.6541)"
sodipodi:type="star"
- 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"
+ 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:20;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="path1497"
sodipodi:sides="3"
sodipodi:cx="596.74072"
@@ -4412,7 +3929,7 @@
inkscape:transform-center-y="-3.3040441e-05" />
<text
xml:space="preserve"
- 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="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:2px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="842.71497"
y="111.05016"
id="text1501"><tspan
@@ -4420,80 +3937,52 @@
id="tspan1499"
x="842.71497"
y="111.05016"
- style="stroke-width:1px">mhe</tspan></text>
+ style="stroke-width:2px">mhe</tspan></text>
</g>
</g>
<text
inkscape:label="actual_label"
xml:space="preserve"
- style="font-style:normal;font-weight:normal;font-size:25.4761734px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;display:inline;fill:#008000;fill-opacity:1;stroke:none;stroke-width:0.63690436px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- x="741.62634"
- y="57.767578"
+ style="font-style:normal;font-weight:normal;font-size:12.7380867px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;display:inline;fill:#008000;fill-opacity:1;stroke:none;stroke-width:0.63690436px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="509.67926"
+ y="43.42762"
id="text1527"><tspan
style="stroke-width:0.63690436px"
sodipodi:role="line"
id="tspan1525"
- x="741.62634"
- y="57.767578">HMI_LOCAL variables</tspan></text>
- <g
- id="g1553"
- transform="matrix(0.5,0,0,0.5,645.20358,-103.15494)">
- <rect
- 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:#bc8f8f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2px;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="rect1264"
- width="68.255615"
- height="165.68298"
- x="1141.0836"
- y="420.78394"
- rx="12.247418"
- ry="14"
- inkscape:label="cursor" />
- <path
- sodipodi:nodetypes="cccc"
- inkscape:connector-curvature="0"
- id="path1266"
- d="m 1175.2115,371.25263 34.1278,34.74552 h -68.2556 z"
- 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:#bc8f8f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2px;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="backward" />
- <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;vector-effect:none;fill:#bc8f8f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2px;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"
- d="m 1175.2115,635.99803 34.1278,-34.7453 h -68.2556 z"
- id="path1268"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccc"
- inkscape:label="forward" />
- </g>
+ x="509.67926"
+ y="43.42762">HMI_LOCAL variables</tspan></text>
<text
xml:space="preserve"
- style="font-style:normal;font-weight:normal;font-size:45.74443054px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.28590268px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- x="902.83728"
- y="228.60184"
+ style="font-style:normal;font-weight:normal;font-size:22.87221527px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.28590268px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="590.28473"
+ y="128.84476"
id="text1557"
inkscape:label="HMI:Display@.piff"><tspan
sodipodi:role="line"
id="tspan1555"
- x="902.83728"
- y="228.60184"
+ x="590.28473"
+ y="128.84476"
style="fill:#ffffff;fill-opacity:1;stroke-width:0.28590268px">8888</tspan></text>
<g
- transform="matrix(0.28590269,0,0,0.28590269,700.70444,166.1427)"
+ transform="matrix(0.14295135,0,0,0.14295135,489.21833,97.61518)"
id="g1605"
inkscape:label="HMI:Input@.piff"
- style="stroke-width:2">
+ style="stroke-width:4">
<text
inkscape:label="value"
id="text1561"
y="218.24219"
x="136.32812"
- 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"
+ 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:4px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
- style="stroke-width:2px"
+ style="stroke-width:4px"
y="218.24219"
x="136.32812"
id="tspan1559"
sodipodi:role="line">8888</tspan></text>
<rect
- 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="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:20;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="rect1563"
width="407.7037"
height="128"
@@ -4505,16 +3994,16 @@
transform="translate(-416.52022,170.47452)"
inkscape:label="+"dhu""
id="g1571"
- style="stroke-width:2">
- <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;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"
+ style="stroke-width:4">
+ <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;vector-effect:none;fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:20;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"
id="path1565"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
- 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="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:2px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="733.58197"
y="111.05016"
id="text1569"><tspan
@@ -4522,17 +4011,17 @@
id="tspan1567"
x="733.58197"
y="111.05016"
- style="stroke-width:1px">dhu</tspan></text>
+ style="stroke-width:2px">dhu</tspan></text>
</g>
<g
transform="translate(-416.52022,170.47452)"
inkscape:label="="plop""
id="g1579"
- style="stroke-width:2">
+ style="stroke-width:4">
<path
transform="matrix(0,-2.0000001,1.9999999,0,1034.195,1298.6541)"
sodipodi:type="star"
- 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"
+ 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:20;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="path1573"
sodipodi:sides="3"
sodipodi:cx="596.74072"
@@ -4551,9 +4040,9 @@
id="text1577"
y="111.05016"
x="633.09552"
- 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="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:2px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
- style="stroke-width:1px"
+ style="stroke-width:2px"
y="111.05016"
x="633.09552"
id="tspan1575"
@@ -4563,7 +4052,7 @@
transform="translate(-416.52022,170.47452)"
inkscape:label="="mhoo""
id="g1587"
- style="stroke-width:2">
+ style="stroke-width:4">
<path
inkscape:transform-center-y="-5.9989963e-06"
d="m 648.55108,-186.34718 -103.62071,0 51.81035,-89.73817 z"
@@ -4578,13 +4067,13 @@
sodipodi:cx="596.74072"
sodipodi:sides="3"
id="path1581"
- 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"
+ 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:20;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:type="star"
transform="rotate(-90,746.45698,-44.543641)"
inkscape:transform-center-x="14.956364" />
<text
xml:space="preserve"
- 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="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:2px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="537.25018"
y="111.05016"
id="text1585"><tspan
@@ -4592,16 +4081,16 @@
id="tspan1583"
x="537.25018"
y="111.05016"
- style="stroke-width:1px">mhoo</tspan></text>
+ style="stroke-width:2px">mhoo</tspan></text>
</g>
<g
transform="translate(-416.52022,170.47452)"
inkscape:label="="yodl""
id="g1595"
- style="stroke-width:2">
+ style="stroke-width:4">
<path
sodipodi:type="star"
- 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"
+ 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:20;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="path1589"
sodipodi:sides="3"
sodipodi:cx="596.74072"
@@ -4619,7 +4108,7 @@
inkscape:transform-center-x="-14.956365" />
<text
xml:space="preserve"
- 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="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:2px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="925.82605"
y="111.05016"
id="text1593"><tspan
@@ -4627,13 +4116,13 @@
id="tspan1591"
x="925.82605"
y="111.05016"
- style="stroke-width:1px">yodl</tspan></text>
+ style="stroke-width:2px">yodl</tspan></text>
</g>
<g
transform="translate(-416.52022,170.47452)"
inkscape:label="="mhe""
id="g1603"
- style="stroke-width:2">
+ style="stroke-width:4">
<path
inkscape:transform-center-y="-3.3040441e-05"
d="m 622.6459,151.4008 -51.81035,0 25.90517,-44.86908 z"
@@ -4648,7 +4137,7 @@
sodipodi:cx="596.74072"
sodipodi:sides="3"
id="path1597"
- 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"
+ 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:20;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:type="star"
transform="matrix(0,-2.0000001,-1.9999999,0,1122.1514,1298.6541)"
inkscape:transform-center-x="-14.956349" />
@@ -4656,9 +4145,9 @@
id="text1601"
y="111.05016"
x="842.71497"
- 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="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:2px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
- style="stroke-width:1px"
+ style="stroke-width:2px"
y="111.05016"
x="842.71497"
id="tspan1599"
@@ -4667,13 +4156,13 @@
</g>
<text
id="text1609"
- y="177.76758"
- x="741.62634"
- style="font-style:normal;font-weight:normal;font-size:25.4761734px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;display:inline;fill:#008000;fill-opacity:1;stroke:none;stroke-width:0.63690436px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ y="103.42763"
+ x="509.67926"
+ style="font-style:normal;font-weight:normal;font-size:12.7380867px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;display:inline;fill:#008000;fill-opacity:1;stroke:none;stroke-width:0.63690436px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"
inkscape:label="actual_label"><tspan
- y="177.76758"
- x="741.62634"
+ y="103.42763"
+ x="509.67926"
sodipodi:role="line"
style="stroke-width:0.63690436px"
id="tspan1611">PAGE_LOCAL variables</tspan></text>
@@ -4700,7 +4189,7 @@
inkscape:connector-curvature="0"
id="path691"
d="M 130.96206,4.0725977 79.111776,-41.363223"
- style="fill:none;fill-rule:evenodd;stroke:#c130f7;stroke-width:2.96323133;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:0, 32.59554547;stroke-dashoffset:29.63231468;stroke-opacity:1;marker-end:url(#marker1536)" />
+ style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ff3000;stroke-width:2.96333337;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:0, 32.59666667;stroke-dashoffset:29.63333321;stroke-opacity:1;marker-end:url(#marker1971)" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:125%;font-family:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;fill:#ff6600;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
@@ -5729,9 +5218,368 @@
id="g825"
inkscape:label="HMI:VarInit:"a page string"@.piff" />
<g
+ inkscape:label="HMI:VarInit:50@.position"
+ id="g906" />
+ <g
+ id="g908"
+ inkscape:label="HMI:VarInit:100@.range" />
+ <rect
+ style="color:#000000;fill:#4d4d4d"
+ id="rect2015"
+ width="1280"
+ height="720"
+ x="-1380"
+ y="0"
+ inkscape:label="HMI:Page:AlarmPage"
+ sodipodi:insensitive="true" />
+ <text
+ xml:space="preserve"
+ 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:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="-738.18359"
+ y="86.260696"
+ id="text2019"><tspan
+ sodipodi:role="line"
+ id="tspan2017"
+ x="-738.18359"
+ y="86.260696"
+ style="fill:#ffffff;stroke-width:1px">Alarm Page</tspan></text>
+ <g
+ id="g1289"
+ inkscape:label="HMI:JsonTable:/alarms@/ALARMNOTIFY@.range@.position"
+ transform="matrix(0.5,0,0,0.5,-1757.3465,454.4367)">
+ <g
+ id="g5231"
+ inkscape:label="data">
+ <g
+ id="g1384"
+ inkscape:label="[0]"
+ transform="translate(52.326002,240.30067)">
+ <g
+ id="g901"
+ inkscape:label="# commented group"
+ transform="translate(419.716,-441.73566)">
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 528.62458,486.07049 23.69122,21.00809"
+ id="path903"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ </g>
+ <use
+ x="0"
+ y="0"
+ xlink:href="#use1297"
+ inkscape:transform-center-x="0.11123312"
+ inkscape:transform-center-y="2.2824109"
+ id="use1378"
+ width="100%"
+ height="100%"
+ transform="matrix(0.7609336,0,0,0.7609336,199.15217,164.3798)"
+ inkscape:label=".status onClick[acknowledge]=.alarmid" />
+ <use
+ transform="matrix(1.3019536,0,0,1.3019536,39.582906,238.73392)"
+ x="0"
+ y="0"
+ xlink:href="#use913"
+ id="use966"
+ width="100%"
+ height="100%"
+ inkscape:label=".status textContent=.time"
+ style="stroke-width:1.53615308" />
+ <use
+ inkscape:label=".status textContent=.text"
+ height="100%"
+ width="100%"
+ id="use1832"
+ xlink:href="#use913"
+ y="0"
+ x="0"
+ transform="matrix(2,0,0,2,85.95394,349.02524)" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 972.0318,65.34292 H 2780.6604"
+ id="path2238"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ inkscape:label="# separation line" />
+ </g>
+ <use
+ inkscape:label="[1]"
+ transform="translate(0,-62.914773)"
+ height="100%"
+ width="100%"
+ id="use5200"
+ xlink:href="#g1384"
+ y="0"
+ x="0" />
+ <use
+ inkscape:label="[2]"
+ x="0"
+ y="0"
+ xlink:href="#g1384"
+ id="use5202"
+ width="100%"
+ height="100%"
+ transform="translate(0,-125.82955)" />
+ <use
+ inkscape:label="[3]"
+ transform="translate(0,-188.74432)"
+ height="100%"
+ width="100%"
+ id="use5204"
+ xlink:href="#g1384"
+ y="0"
+ x="0" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#g1384"
+ id="use2176"
+ width="100%"
+ height="100%"
+ transform="translate(0,-251.65909)"
+ inkscape:label="[4]" />
+ <use
+ inkscape:label="[5]"
+ transform="translate(0,-314.57387)"
+ height="100%"
+ width="100%"
+ id="use2178"
+ xlink:href="#g1384"
+ y="0"
+ x="0" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#g1384"
+ id="use2180"
+ width="100%"
+ height="100%"
+ transform="translate(0,-377.48864)"
+ inkscape:label="[6]" />
+ </g>
+ </g>
+ <g
+ id="g1332"
+ inkscape:label="polygons"
+ transform="translate(-1556.6506,114.93627)">
+ <path
+ inkscape:transform-center-y="2.9995242"
+ inkscape:transform-center-x="0.14620371"
+ d="m 1081.9632,-246.81598 -27.9274,5.51725 -27.9273,5.51724 9.1856,-26.94439 9.1856,-26.94439 18.7417,21.42715 z"
+ inkscape:randomized="0"
+ inkscape:rounded="0"
+ inkscape:flatsided="false"
+ sodipodi:arg2="1.3757507"
+ sodipodi:arg1="0.32855317"
+ sodipodi:r2="16.43548"
+ sodipodi:r1="32.87096"
+ sodipodi:cy="-257.42258"
+ sodipodi:cx="1050.8505"
+ sodipodi:sides="3"
+ id="path1298"
+ style="fill:#8fbc8f;fill-opacity:1;stroke:#ff0000"
+ sodipodi:type="star"
+ inkscape:label="three" />
+ <path
+ sodipodi:type="star"
+ style="fill:#ff8c00;fill-opacity:1;stroke:#ff0000"
+ id="path1308"
+ sodipodi:sides="4"
+ sodipodi:cx="1110.8505"
+ sodipodi:cy="-257.42258"
+ sodipodi:r1="32.87096"
+ sodipodi:r2="16.43548"
+ sodipodi:arg1="0.32855317"
+ sodipodi:arg2="1.1139513"
+ inkscape:flatsided="false"
+ inkscape:rounded="0"
+ inkscape:randomized="0"
+ d="m 1141.9632,-246.81598 -23.8627,4.1434 -17.8566,16.3627 -4.1434,-23.8627 -16.3627,-17.8566 23.8627,-4.1434 17.8566,-16.3627 4.1434,23.8627 z"
+ inkscape:transform-center-x="0.14620371"
+ inkscape:transform-center-y="2.9995242"
+ inkscape:label="four" />
+ <path
+ inkscape:transform-center-y="2.9995242"
+ inkscape:transform-center-x="0.14620371"
+ d="m 1201.9632,-246.81598 -21.6446,2.82766 -9.9413,19.4333 -9.3778,-19.7114 -21.5541,-3.44949 15.8487,-15.00997 -3.3799,-21.5652 19.1728,10.43473 19.4653,-9.87854 -3.9993,21.45898 z"
+ inkscape:randomized="0"
+ inkscape:rounded="0"
+ inkscape:flatsided="false"
+ sodipodi:arg2="0.9568717"
+ sodipodi:arg1="0.32855317"
+ sodipodi:r2="16.43548"
+ sodipodi:r1="32.87096"
+ sodipodi:cy="-257.42258"
+ sodipodi:cx="1170.8505"
+ sodipodi:sides="5"
+ id="path1310"
+ style="fill:#bc8f8f;fill-opacity:1;stroke:#ff0000"
+ sodipodi:type="star"
+ inkscape:label="five" />
+ <path
+ sodipodi:type="star"
+ style="fill:#f0f8ff;fill-opacity:1;stroke:#ff0000"
+ id="path1312"
+ sodipodi:sides="6"
+ sodipodi:cx="1230.8505"
+ sodipodi:cy="-257.42258"
+ sodipodi:r1="32.87096"
+ sodipodi:r2="16.43548"
+ sodipodi:arg1="0.32855317"
+ sodipodi:arg2="0.85215195"
+ inkscape:flatsided="false"
+ inkscape:rounded="0"
+ inkscape:randomized="0"
+ d="m 1261.9632,-246.81598 -20.2922,1.76437 -4.4498,19.87672 -11.674,-16.69134 -19.4387,6.08474 8.6181,-18.45571 -14.9888,-13.79198 20.2921,-1.76436 4.4498,-19.87673 11.6741,16.69134 19.4386,-6.08473 -8.6181,18.4557 z"
+ inkscape:transform-center-x="0.14620371"
+ inkscape:transform-center-y="2.9995242"
+ inkscape:label="six" />
+ </g>
+ <g
+ inkscape:label="HMI:List"
+ id="g1311"
+ transform="translate(-1396.6506,94.93627)">
+ <use
+ x="0"
+ y="0"
+ xlink:href="#path1298"
+ inkscape:transform-center-x="0.14620371"
+ inkscape:transform-center-y="2.9995242"
+ id="use1293"
+ width="100%"
+ height="100%"
+ transform="translate(-69.76703,100)"
+ style="display:inline"
+ inkscape:label="ack" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#path1308"
+ inkscape:transform-center-x="0.14620371"
+ inkscape:transform-center-y="2.9995242"
+ id="use1295"
+ width="100%"
+ height="100%"
+ transform="translate(-126.48474,100)"
+ inkscape:label="alarm" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#path1310"
+ inkscape:transform-center-x="0.14620371"
+ inkscape:transform-center-y="2.9995242"
+ id="use1297"
+ width="100%"
+ height="100%"
+ transform="translate(-186.33351,100)"
+ inkscape:label="active" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#path1312"
+ inkscape:transform-center-x="0.14620371"
+ inkscape:transform-center-y="2.9995242"
+ id="use1299"
+ width="100%"
+ height="100%"
+ transform="translate(-246.4848,100)"
+ inkscape:label="disabled" />
+ </g>
+ <g
+ transform="matrix(0.33436432,0,0,0.33436432,-664.21063,278.8185)"
+ inkscape:label="HMI:Input@/ALARMNOTIFY"
+ id="g5222"
+ style="stroke-width:0.75594342">
+ <text
+ xml:space="preserve"
+ 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:0.75594342px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="136.32812"
+ y="218.24219"
+ id="text5208"
+ inkscape:label="value"><tspan
+ sodipodi:role="line"
+ id="tspan5206"
+ x="136.32812"
+ y="218.24219"
+ style="stroke-width:0.75594342px">8888</tspan></text>
+ <path
+ transform="scale(1,-1)"
+ sodipodi:type="star"
+ 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:3.77971721;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="path5212"
+ sodipodi:sides="3"
+ sodipodi:cx="608.70374"
+ sodipodi:cy="-209.2599"
+ sodipodi:r1="59.825443"
+ sodipodi:r2="29.912722"
+ sodipodi:arg1="0.52359878"
+ sodipodi:arg2="1.5707963"
+ inkscape:flatsided="true"
+ inkscape:rounded="0"
+ inkscape:randomized="0"
+ d="m 660.51409,-179.34718 -103.62071,0 51.81036,-89.73817 z"
+ inkscape:transform-center-y="14.956362"
+ inkscape:label="-1" />
+ <rect
+ inkscape:label="edit"
+ onclick=""
+ y="95.40741"
+ x="139.85185"
+ height="128"
+ width="407.7037"
+ id="rect5214"
+ 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:3.77971721;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" />
+ <path
+ inkscape:label="+1"
+ inkscape:transform-center-y="-14.95636"
+ d="m 660.51409,142.08535 -103.62071,0 51.81036,-89.738163 z"
+ inkscape:randomized="0"
+ inkscape:rounded="0"
+ inkscape:flatsided="true"
+ sodipodi:arg2="1.5707963"
+ sodipodi:arg1="0.52359878"
+ sodipodi:r2="29.912722"
+ sodipodi:r1="59.825443"
+ sodipodi:cy="112.17263"
+ sodipodi:cx="608.70374"
+ sodipodi:sides="3"
+ id="path5218"
+ 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:3.77971721;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:type="star" />
+ </g>
+ <g
+ id="g1553"
+ transform="matrix(0.5,0,0,0.5,-774.48108,252.30551)">
+ <rect
+ 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:#bc8f8f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2px;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="rect1264"
+ width="68.255615"
+ height="165.68298"
+ x="1141.0836"
+ y="420.78394"
+ rx="12.247418"
+ ry="14"
+ inkscape:label="cursor" />
+ <path
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0"
+ id="path1266"
+ d="m 1175.2115,371.25263 34.1278,34.74552 h -68.2556 z"
+ 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:#bc8f8f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2px;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="backward" />
+ <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;vector-effect:none;fill:#bc8f8f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2px;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"
+ d="m 1175.2115,635.99803 34.1278,-34.7453 h -68.2556 z"
+ id="path1268"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ inkscape:label="forward" />
+ </g>
+ <g
id="g893"
inkscape:label="textstyles"
- transform="translate(-136,-6.0000001)">
+ transform="translate(-1566.6506,56.936266)">
<text
inkscape:label="red"
id="text1382-7"
@@ -5784,7 +5632,7 @@
<g
id="g907"
inkscape:label="HMI:TextStyleList"
- transform="translate(440,40)">
+ transform="translate(-990.65059,102.93627)">
<use
x="0"
y="0"
@@ -5822,4 +5670,408 @@
transform="translate(-573,80.999998)"
inkscape:label="disabled" />
</g>
+ <g
+ transform="matrix(0.33436432,0,0,0.33436432,-1128.7703,278.8185)"
+ inkscape:label="HMI:Input@.range"
+ id="g5222-3"
+ style="stroke-width:0.75594342">
+ <text
+ xml:space="preserve"
+ 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:0.75594342px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="136.32812"
+ y="218.24219"
+ id="text5208-6"
+ inkscape:label="value"><tspan
+ sodipodi:role="line"
+ id="tspan5206-7"
+ x="136.32812"
+ y="218.24219"
+ style="stroke-width:0.75594342px">8888</tspan></text>
+ <path
+ transform="scale(1,-1)"
+ sodipodi:type="star"
+ 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:3.77971721;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="path5212-5"
+ sodipodi:sides="3"
+ sodipodi:cx="620.66675"
+ sodipodi:cy="-209.2599"
+ sodipodi:r1="59.825443"
+ sodipodi:r2="29.912722"
+ sodipodi:arg1="0.52359878"
+ sodipodi:arg2="1.5707963"
+ inkscape:flatsided="true"
+ inkscape:rounded="0"
+ inkscape:randomized="0"
+ d="m 672.4771,-179.34718 -103.62071,0 51.81036,-89.73817 z"
+ inkscape:transform-center-y="14.956362"
+ inkscape:label="-1" />
+ <rect
+ inkscape:label="edit"
+ onclick=""
+ y="95.40741"
+ x="139.85185"
+ height="128"
+ width="407.7037"
+ id="rect5214-3"
+ 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:3.77971721;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" />
+ <path
+ inkscape:label="+1"
+ inkscape:transform-center-y="-14.95636"
+ d="m 672.4771,142.08535 -103.62071,0 51.81036,-89.738163 z"
+ inkscape:randomized="0"
+ inkscape:rounded="0"
+ inkscape:flatsided="true"
+ sodipodi:arg2="1.5707963"
+ sodipodi:arg1="0.52359878"
+ sodipodi:r2="29.912722"
+ sodipodi:r1="59.825443"
+ sodipodi:cy="112.17263"
+ sodipodi:cx="620.66675"
+ sodipodi:sides="3"
+ id="path5218-5"
+ 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:3.77971721;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:type="star" />
+ </g>
+ <g
+ transform="matrix(0.33436432,0,0,0.33436432,-896.49047,278.8185)"
+ inkscape:label="HMI:Input@.position"
+ id="g5222-6"
+ style="stroke-width:0.75594342">
+ <text
+ xml:space="preserve"
+ 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:0.75594342px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="136.32812"
+ y="218.24219"
+ id="text5208-2"
+ inkscape:label="value"><tspan
+ sodipodi:role="line"
+ id="tspan5206-9"
+ x="136.32812"
+ y="218.24219"
+ style="stroke-width:0.75594342px">8888</tspan></text>
+ <path
+ transform="scale(1,-1)"
+ sodipodi:type="star"
+ 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:3.77971721;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="path5212-1"
+ sodipodi:sides="3"
+ sodipodi:cx="608.70374"
+ sodipodi:cy="-209.2599"
+ sodipodi:r1="59.825443"
+ sodipodi:r2="29.912722"
+ sodipodi:arg1="0.52359878"
+ sodipodi:arg2="1.5707963"
+ inkscape:flatsided="true"
+ inkscape:rounded="0"
+ inkscape:randomized="0"
+ d="m 660.51409,-179.34718 -103.62071,0 51.81036,-89.73817 z"
+ inkscape:transform-center-y="14.956362"
+ inkscape:label="-1" />
+ <rect
+ inkscape:label="edit"
+ onclick=""
+ y="95.40741"
+ x="139.85185"
+ height="128"
+ width="407.7037"
+ id="rect5214-2"
+ 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:3.77971721;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" />
+ <path
+ inkscape:label="+1"
+ inkscape:transform-center-y="-14.95636"
+ d="m 660.51409,142.08535 -103.62071,0 51.81036,-89.738163 z"
+ inkscape:randomized="0"
+ inkscape:rounded="0"
+ inkscape:flatsided="true"
+ sodipodi:arg2="1.5707963"
+ sodipodi:arg1="0.52359878"
+ sodipodi:r2="29.912722"
+ sodipodi:r1="59.825443"
+ sodipodi:cy="112.17263"
+ sodipodi:cx="608.70374"
+ sodipodi:sides="3"
+ id="path5218-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:3.77971721;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:type="star" />
+ </g>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:26.45700645px;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:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="-1015.5838"
+ y="291.8042"
+ id="text887"><tspan
+ sodipodi:role="line"
+ id="tspan885"
+ x="-1015.5838"
+ y="291.8042"
+ style="fill:#ffffff;stroke-width:1px">range</tspan></text>
+ <text
+ id="text891"
+ y="291.8042"
+ x="-782.87115"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:26.45700645px;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:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ style="fill:#ffffff;stroke-width:1px"
+ y="291.8042"
+ x="-782.87115"
+ id="tspan889"
+ sodipodi:role="line">position</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:26.45700645px;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:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="-551.33417"
+ y="291.8042"
+ id="text895"><tspan
+ sodipodi:role="line"
+ id="tspan893"
+ x="-551.33417"
+ y="291.8042"
+ style="fill:#ffffff;stroke-width:1px">notify</tspan></text>
+ <g
+ style="stroke-width:2"
+ inkscape:label="HMI:Input@/ALARMTEXT"
+ id="g1442-3"
+ transform="matrix(0.5,0,0,0.5,-915.0529,113.05833)">
+ <rect
+ inkscape:label="edit"
+ onclick=""
+ y="77.265099"
+ x="-648.04266"
+ height="179.83517"
+ width="1195.5988"
+ id="rect1400-5"
+ 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:#cacaca;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"
+ ry="36.786537" />
+ <text
+ xml:space="preserve"
+ 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:#0e0e0e;fill-opacity:1;stroke:none;stroke-width:2px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="545.95312"
+ y="218.24219"
+ id="text1398-6"
+ inkscape:label="value"><tspan
+ sodipodi:role="line"
+ id="tspan1396-7"
+ x="545.95312"
+ y="218.24219"
+ style="text-align:end;text-anchor:end;fill:#0e0e0e;fill-opacity:1;stroke-width:2px">8888</tspan></text>
+ </g>
+ <g
+ style="stroke-width:1.04184687"
+ inkscape:label="HMI:Input@/SENDALARM"
+ id="g953"
+ transform="translate(-1386.3329,-450.57041)">
+ <g
+ id="g1839"
+ inkscape:label="+1">
+ <g
+ id="g945"
+ inkscape:label="bg"
+ style="stroke-width:1.04184687">
+ <rect
+ 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"
+ id="rect943"
+ width="245.44583"
+ height="95.723877"
+ x="971.96545"
+ y="594.82263"
+ ry="23.177595"
+ inkscape:label="button"
+ rx="26.820074" />
+ </g>
+ <g
+ id="g951"
+ inkscape:label="text"
+ style="stroke-width:1.04184687">
+ <text
+ inkscape:label="setting_jmp"
+ id="text949"
+ y="656.98151"
+ x="1090.7626"
+ 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"
+ xml:space="preserve"><tspan
+ style="text-align:center;text-anchor:middle;fill:#ff6600;stroke-width:1.04184675px"
+ y="656.98151"
+ x="1090.7626"
+ id="tspan947"
+ sodipodi:role="line">trigger</tspan></text>
+ </g>
+ </g>
+ </g>
+ <g
+ style="stroke-width:2"
+ inkscape:label="HMI:Input@/ALARMSTATUS"
+ id="g1887"
+ transform="matrix(0.28590269,0,0,0.28590269,-631.94615,129.07897)">
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-weight:normal;font-size:148.39013672px;line-height:125%;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.99999988px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="329.13501"
+ y="214.01605"
+ id="text1843"
+ inkscape:label="value"><tspan
+ sodipodi:role="line"
+ id="tspan1841"
+ x="329.13501"
+ y="214.01605"
+ style="text-align:center;text-anchor:middle;stroke-width:1.99999988px">8888</tspan></text>
+ <g
+ style="stroke-width:1.09375393"
+ id="g1853"
+ inkscape:label="="ack""
+ transform="matrix(1.8285648,0,0,1.8285648,-936.17681,115.40643)">
+ <path
+ inkscape:connector-curvature="0"
+ id="path1847"
+ d="m 797.19546,145.18619 -80.62929,0.60214 -0.60215,-80.629288 80.6293,-0.60214 z"
+ inkscape:transform-center-y="-14.956361"
+ 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:5.46877003;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" />
+ <text
+ id="text1851"
+ y="112.62867"
+ x="738.57678"
+ 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:0.54687697px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ style="stroke-width:0.54687697px"
+ y="112.62867"
+ x="738.57678"
+ id="tspan1849"
+ sodipodi:role="line">ack</tspan></text>
+ </g>
+ <g
+ style="stroke-width:1.09375393"
+ id="g1861"
+ inkscape:label="="disabled""
+ transform="matrix(1.8285648,0,0,1.8285648,-1012.4359,109.57379)">
+ <path
+ inkscape:connector-curvature="0"
+ id="path1847-7"
+ d="m 738.52607,148.37593 -80.6293,0.60214 -0.6021,-80.629288 80.6293,-0.60214 z"
+ inkscape:transform-center-y="-14.956361"
+ 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:5.46877003;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" />
+ <text
+ xml:space="preserve"
+ 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:0.54687697px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="656.177"
+ y="115.81841"
+ id="text1859"><tspan
+ sodipodi:role="line"
+ id="tspan1857"
+ x="656.177"
+ y="115.81841"
+ style="stroke-width:0.54687697px">disabled</tspan></text>
+ </g>
+ <g
+ style="stroke-width:1.09375393"
+ id="g1869"
+ inkscape:label="="active""
+ transform="matrix(1.8285648,0,0,1.8285648,-998.18055,84.666267)">
+ <path
+ inkscape:connector-curvature="0"
+ id="path1847-5"
+ d="m 630.35651,161.99728 -80.6293,0.60214 -0.6021,-80.629287 80.6293,-0.60214 z"
+ inkscape:transform-center-y="-14.956361"
+ 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:5.46877003;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" />
+ <text
+ id="text1867"
+ y="129.43976"
+ x="559.26227"
+ 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:0.54687697px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ style="stroke-width:0.54687697px"
+ y="129.43976"
+ x="559.26227"
+ id="tspan1865"
+ sodipodi:role="line">active</tspan></text>
+ </g>
+ <g
+ style="stroke-width:1.09375393"
+ id="g1877"
+ inkscape:label="="alarm""
+ transform="matrix(1.8285648,0,0,1.8285648,-1114.212,118.29284)">
+ <path
+ inkscape:connector-curvature="0"
+ id="path1847-3"
+ d="m 994.91832,143.60768 -80.62931,0.60214 -0.6021,-80.629285 80.62931,-0.60214 z"
+ inkscape:transform-center-y="-14.956361"
+ 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:5.46877003;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" />
+ <text
+ id="text1875"
+ y="111.05016"
+ x="925.82605"
+ 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:0.54687697px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ style="stroke-width:0.54687697px"
+ y="111.05016"
+ x="925.82605"
+ id="tspan1873"
+ sodipodi:role="line">alarm</tspan></text>
+ </g>
+ </g>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:20px;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:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="-926.47461"
+ y="134.36742"
+ id="text2019-9"><tspan
+ sodipodi:role="line"
+ id="tspan2017-2"
+ x="-926.47461"
+ y="134.36742"
+ style="fill:#ffffff;stroke-width:1px">Alarm Text</tspan></text>
+ <text
+ id="text2174"
+ y="134.36742"
+ x="-546.47461"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:20px;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:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ style="fill:#ffffff;stroke-width:1px"
+ y="134.36742"
+ x="-546.47461"
+ id="tspan2172"
+ sodipodi:role="line">Status</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;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:#ff0000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="-241.25107"
+ y="513.61072"
+ id="text2184"><tspan
+ sodipodi:role="line"
+ id="tspan2182"
+ x="-241.25107"
+ y="513.61072">TODO</tspan></text>
+ <g
+ transform="matrix(0.57180538,0,0,0.57180538,226.35945,-231.48695)"
+ inkscape:label="HMI:Jump:AlarmPage"
+ id="g2198">
+ <g
+ inkscape:label="button"
+ id="g2190">
+ <rect
+ inkscape:label="button"
+ ry="35.579063"
+ y="594.82263"
+ x="971.96545"
+ height="95.723877"
+ width="245.44583"
+ id="rect2188"
+ 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"
+ rx="35.579063" />
+ </g>
+ <g
+ inkscape:label="text"
+ id="g2196">
+ <text
+ xml:space="preserve"
+ 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:0.99999994px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="1090.7626"
+ y="656.98151"
+ id="text2194"
+ inkscape:label="setting_jmp"><tspan
+ sodipodi:role="line"
+ id="tspan2192"
+ x="1090.7626"
+ y="656.98151"
+ style="text-align:center;text-anchor:middle;fill:#ff6600;stroke-width:0.99999994px">Alarms</tspan></text>
+ </g>
+ </g>
</svg>
--- a/tests/svghmi_v2/svghmi_0@svghmi/svghmi.svg Wed Sep 16 09:42:26 2020 +0200
+++ b/tests/svghmi_v2/svghmi_0@svghmi/svghmi.svg Thu Sep 17 11:30:22 2020 +0200
@@ -53,17 +53,6 @@
inkscape:vp_z="1272 : 385 : 1"
inkscape:persp3d-origin="536 : 237 : 1"
id="perspective445" />
- <inkscape:tag
- id="Set 1"
- inkscape:label="HMI:AccessList@Admin"
- inkscape:expanded="true">
- <inkscape:tagref
- xlink:href="#text995"
- id="tagref192" />
- <inkscape:tagref
- xlink:href="#g991"
- id="tagref194" />
- </inkscape:tag>
<linearGradient
inkscape:collect="always"
id="linearGradient962">
@@ -91,26 +80,6 @@
id="path924"
inkscape:connector-curvature="0" />
</marker>
- <inkscape:tag
- id="Set 3"
- inkscape:expanded="true"
- inkscape:label="HMI:Translate">
- <inkscape:tagref
- xlink:href="#text831"
- id="tagref1085" />
- <inkscape:tagref
- xlink:href="#text827"
- id="tagref1087" />
- <inkscape:tagref
- xlink:href="#text4497"
- id="tagref1089" />
- <inkscape:tagref
- xlink:href="#home_jmp"
- id="tagref1091" />
- <inkscape:tagref
- xlink:href="#setting_jmp"
- id="tagref1093" />
- </inkscape:tag>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient962"