# HG changeset patch # User Edouard Tisserant # Date 1568797775 -7200 # Node ID 75c6a31caca657edd1ba9bcd1e321e91b8f1265f # Parent cdf23b10b8f724751e1e2cd74d3c9d8eb5717098 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. diff -r cdf23b10b8f7 -r 75c6a31caca6 svghmi/gen_index_xhtml.xslt --- 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 @@ - - + + @@ -9,17 +9,44 @@ - - - - - - blah + + + + + + + + + + + + + + + ID: diff -r cdf23b10b8f7 -r 75c6a31caca6 svghmi/gen_index_xhtml.ysl2 --- 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"{ diff -r cdf23b10b8f7 -r 75c6a31caca6 svghmi/svghmi.c --- 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 diff -r cdf23b10b8f7 -r 75c6a31caca6 svghmi/svghmi.py --- 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}) diff -r cdf23b10b8f7 -r 75c6a31caca6 svghmi/svghmi_server.py --- 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")