SVGHMI: Work In Progress : fixed pointer types in ctypes interface, cleaned up server startup and cleanup code, changed document type to XHTML, cleaner JS script : encapsulated in a function and in CDATA.
--- a/svghmi/gen_index_xhtml.xslt Wed Sep 18 11:03:56 2019 +0200
+++ b/svghmi/gen_index_xhtml.xslt Wed Sep 18 11:09:35 2019 +0200
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
-<xsl:stylesheet xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns:exsl="http://exslt.org/common" xmlns:ns="beremiz" xmlns:cc="http://creativecommons.org/ns#" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dc="http://purl.org/dc/elements/1.1/" extension-element-prefixes="ns" version="1.0" exclude-result-prefixes="ns">
- <xsl:output method="xml"/>
+<xsl:stylesheet xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/1999/xhtml" xmlns:exsl="http://exslt.org/common" xmlns:ns="beremiz" xmlns:cc="http://creativecommons.org/ns#" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dc="http://purl.org/dc/elements/1.1/" extension-element-prefixes="ns" version="1.0" exclude-result-prefixes="ns">
+ <xsl:output method="xml" cdata-section-elements="script"/>
<xsl:variable name="geometry" select="ns:GetSVGGeometry()"/>
<xsl:variable name="hmitree" select="ns:GetHMITree()"/>
<xsl:template match="@* | node()">
@@ -9,17 +9,44 @@
</xsl:copy>
</xsl:template>
<xsl:template match="/">
- <xsl:copy>
- <xsl:comment>
- <xsl:apply-templates mode="testgeo" select="$geometry"/>
- </xsl:comment>
- <xsl:comment>
- <xsl:text>blah
+ <html xmlns="http://www.w3.org/1999/xhtml">
+ <head/>
+ <body style="margin:0;">
+ <xsl:copy>
+ <xsl:comment>
+ <xsl:apply-templates mode="testgeo" select="$geometry"/>
+ </xsl:comment>
+ <xsl:comment>
+ <xsl:apply-templates mode="testtree" select="$hmitree"/>
+ </xsl:comment>
+ <xsl:apply-templates select="@* | node()"/>
+ </xsl:copy>
+ <script>
+ <xsl:text>(function(){
</xsl:text>
- <xsl:apply-templates mode="testtree" select="$hmitree"/>
- </xsl:comment>
- <xsl:apply-templates select="@* | node()"/>
- </xsl:copy>
+ <xsl:text> var relative_URI = window.location.href.replace(/^http(s?:\/\/[^\/]*)\/.*$/, 'ws$1/ws');
+</xsl:text>
+ <xsl:text> var ws = new WebSocket(relative_URI);
+</xsl:text>
+ <xsl:text> ws.onmessage = function (evt) {
+</xsl:text>
+ <xsl:text> var received_msg = evt.data;
+</xsl:text>
+ <xsl:text> alert("Message is received..."+received_msg);
+</xsl:text>
+ <xsl:text> };
+</xsl:text>
+ <xsl:text> ws.onopen = function (evt) {
+</xsl:text>
+ <xsl:text> ws.send("test");
+</xsl:text>
+ <xsl:text> };
+</xsl:text>
+ <xsl:text>})();
+</xsl:text>
+ </script>
+ </body>
+ </html>
</xsl:template>
<xsl:template mode="testgeo" match="bbox">
<xsl:text>ID: </xsl:text>
--- a/svghmi/gen_index_xhtml.ysl2 Wed Sep 18 11:03:56 2019 +0200
+++ b/svghmi/gen_index_xhtml.ysl2 Wed Sep 18 11:09:35 2019 +0200
@@ -1,4 +1,7 @@
include yslt_noindent.yml2
+
+// overrides yslt's output function to set CDATA
+decl output(method, cdata-section-elements="script");
istylesheet
/* From Inkscape */
xmlns:dc="http://purl.org/dc/elements/1.1/"
@@ -7,6 +10,7 @@
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns="http://www.w3.org/1999/xhtml"
/* Our namespace to invoke python code */
xmlns:ns="beremiz"
@@ -30,17 +34,34 @@
}
/* copy root node and add geometry as comment for a test */
- template "/" {
- xsl:copy {
- comment {
- apply "$geometry", mode="testgeo";
+ template "/"
+ html xmlns="http://www.w3.org/1999/xhtml" {
+ head;
+ body style="margin:0;" {
+ xsl:copy {
+ comment {
+ apply "$geometry", mode="testgeo";
+ }
+ comment {
+ apply "$hmitree", mode="testtree";
+ }
+ apply "@* | node()";
+ }
+ script
+ ||
+ (function(){
+ var relative_URI = window.location.href.replace(/^http(s?:\/\/[^\/]*)\/.*$/, 'ws$1/ws');
+ var ws = new WebSocket(relative_URI);
+ ws.onmessage = function (evt) {
+ var received_msg = evt.data;
+ alert("Message is received..."+received_msg);
+ };
+ ws.onopen = function (evt) {
+ ws.send("test");
+ };
+ })();
+ ||
}
- comment {
- | blah
- apply "$hmitree", mode="testtree";
- }
- apply "@* | node()";
- }
}
template "bbox", mode="testgeo"{
--- a/svghmi/svghmi.c Wed Sep 18 11:03:56 2019 +0200
+++ b/svghmi/svghmi.c Wed Sep 18 11:09:35 2019 +0200
@@ -179,7 +179,7 @@
}
/* PYTHON CALLS */
-int svghmi_send_collect(uint32_t *size, void *ptr){
+int svghmi_send_collect(uint32_t *size, char **ptr){
int do_collect;
pthread_mutex_lock(&svghmi_send_WakeCondLock);
@@ -202,7 +202,7 @@
}
}
-int svghmi_recv_dispatch(uint32_t size, void* ptr){
+int svghmi_recv_dispatch(uint32_t size, char *ptr){
printf("%%*s",size,ptr);
/* TODO something with ptr and size
- subscribe
--- a/svghmi/svghmi.py Wed Sep 18 11:03:56 2019 +0200
+++ b/svghmi/svghmi.py Wed Sep 18 11:09:35 2019 +0200
@@ -165,8 +165,6 @@
new_node = HMITreeNode(path, path[-1], v["derived"], v["type"], v["vartype"])
hmi_tree_root.place_node(new_node)
- print(hmi_tree_root.pprint())
-
variable_decl_array = []
extern_variables_declarations = []
buf_index = 0
@@ -366,6 +364,9 @@
def _runtime_svghmi1_%(location)s_start():
svghmi_root.putChild('%(view_name)s',File('%(xhtml)s'))
+def _runtime_svghmi1_%(location)s_stop():
+ svghmi_root.delEntity('%(view_name)s')
+
""" % {"location": location_str,
"xhtml": target_fname,
"view_name": view_name})
--- a/svghmi/svghmi_server.py Wed Sep 18 11:03:56 2019 +0200
+++ b/svghmi/svghmi_server.py Wed Sep 18 11:09:35 2019 +0200
@@ -25,14 +25,14 @@
svghmi_send_collect.restype = ctypes.c_int # error or 0
svghmi_send_collect.argtypes = [
ctypes.POINTER(ctypes.c_uint32), # size
- ctypes.POINTER(ctypes.c_void_p)] # data ptr
+ ctypes.POINTER(ctypes.c_char_p)] # data ptr
# TODO multiclient : switch to arrays
svghmi_recv_dispatch = PLCBinary.svghmi_recv_dispatch
svghmi_recv_dispatch.restype = ctypes.c_int # error or 0
svghmi_recv_dispatch.argtypes = [
- ctypes.c_uint32, # size
- ctypes.POINTER(ctypes.c_void_p)] # data ptr
+ ctypes.c_uint32, # size
+ ctypes.c_char_p] # data ptr
# TODO multiclient : switch to arrays
class HMISession(object):
@@ -59,15 +59,13 @@
# svghmi_sessions.remove(self)
def onMessage(self, msg):
- # TODO : pass it to the C side recieve_message()
- # update HMITree
- # - values
- # - refresh rates / subsriptions
+ # pass message to the C side recieve_message()
+ c_string = ctypes.c_char_p(msg)
+ c_string_pointer = ctypes.c_void_p(ctypes.addressof(c_string))
+ svghmi_recv_dispatch(len(msg), msg)
# TODO multiclient : pass client index as well
- #
- svghmi_recv_dispatch(len(msg), ctypes.c_void_p.from_buffer_copy(msg))
def sendMessage(self, msg):
self.sendMessage(msg, True)
@@ -92,6 +90,9 @@
print msg
#self.sendMessage(msg, binary)
+class HMIWebSocketServerFactory(WebSocketServerFactory):
+ protocol = HMIProtocol
+
svghmi_root = None
svghmi_listener = None
svghmi_send_thread = None
@@ -99,7 +100,7 @@
def SendThreadProc():
global svghmi_session
size = ctypes.c_uint32()
- ptr = ctypes.c_void_p()
+ ptr = ctypes.c_char_p()
res = 0
while svghmi_send_collect(ctypes.byref(size), ctypes.byref(ptr)) == 0 and \
svghmi_session is not None and \
@@ -109,20 +110,15 @@
# TODO multiclient : dispatch to sessions
+
# Called by PLCObject at start
def _runtime_svghmi0_start():
global svghmi_listener, svghmi_root, svghmi_send_thread
svghmi_root = Resource()
+ svghmi_root.putChild("ws", WebSocketResource(HMIWebSocketServerFactory()))
- wsfactory = WebSocketServerFactory()
- wsfactory.protocol = HMIProtocol
-
- svghmi_root.putChild("ws", WebSocketResource(wsfactory))
-
- sitefactory = Site(svghmi_root)
-
- svghmi_listener = reactor.listenTCP(8008, sitefactory)
+ svghmi_listener = reactor.listenTCP(8008, Site(svghmi_root))
# start a thread that call the C part of SVGHMI
svghmi_send_thread = Thread(target=SendThreadProc, name="SVGHMI Send")