29 # TODO multiclient : switch to arrays |
29 # TODO multiclient : switch to arrays |
30 |
30 |
31 svghmi_recv_dispatch = PLCBinary.svghmi_recv_dispatch |
31 svghmi_recv_dispatch = PLCBinary.svghmi_recv_dispatch |
32 svghmi_recv_dispatch.restype = ctypes.c_int # error or 0 |
32 svghmi_recv_dispatch.restype = ctypes.c_int # error or 0 |
33 svghmi_recv_dispatch.argtypes = [ |
33 svghmi_recv_dispatch.argtypes = [ |
34 ctypes.POINTER(ctypes.c_uint32), # size |
34 ctypes.c_uint32, # size |
35 ctypes.POINTER(ctypes.c_void_p)] # data ptr |
35 ctypes.POINTER(ctypes.c_void_p)] # data ptr |
36 # TODO multiclient : switch to arrays |
36 # TODO multiclient : switch to arrays |
37 |
37 |
38 def SendThreadProc(): |
38 def SendThreadProc(): |
39 assert(svghmi_session) |
39 assert(svghmi_session) |
40 size = ctypes.c_uint32() |
40 size = ctypes.c_uint32() |
41 ptr = ctypes.c_void_p() |
41 ptr = ctypes.c_void_p() |
42 while res == 0: |
42 res = 0 |
43 res = svghmi_send_collect(ctypes.byref(size), ctypes.byref(ptr)) |
43 while svghmi_send_collect(ctypes.byref(size), ctypes.byref(ptr)) == 0 and \ |
|
44 svghmi_session is not None and \ |
|
45 svghmi_session.sendMessage(ctypes.string_at(ptr,size)) == 0: |
|
46 pass |
44 |
47 |
45 # TODO multiclient : dispatch to sessions |
48 # TODO multiclient : dispatch to sessions |
46 svghmi_session.sendMessage(ctypes.string_at(ptr,size)) |
|
47 |
49 |
48 class HMISession(object): |
50 class HMISession(object): |
49 def __init__(self, protocol_instance): |
51 def __init__(self, protocol_instance): |
50 global svghmi_session |
52 global svghmi_session |
51 |
53 |
52 # TODO: kill existing session for robustness |
54 # TODO: kill existing session for robustness |
53 assert(svghmi_session is None) |
55 assert(svghmi_session is None) |
54 |
56 |
55 svghmi_session = self |
57 svghmi_session = self |
56 self.protocol_instance = protocol_instance |
58 self.protocol_instance = protocol_instance |
57 |
59 |
58 # TODO multiclient : |
60 # TODO multiclient : |
59 # svghmi_sessions.append(self) |
61 # svghmi_sessions.append(self) |
60 # get a unique bit index amont other svghmi_sessions, |
62 # get a unique bit index amont other svghmi_sessions, |
61 # so that we can match flags passed by C->python callback |
63 # so that we can match flags passed by C->python callback |
62 |
64 |
63 def __del__(self): |
65 def __del__(self): |
64 global svghmi_session |
66 global svghmi_session |
65 assert(svghmi_session) |
67 assert(svghmi_session) |
66 svghmi_session = None |
68 svghmi_session = None |
67 |
69 |
74 # - values |
76 # - values |
75 # - refresh rates / subsriptions |
77 # - refresh rates / subsriptions |
76 |
78 |
77 # TODO multiclient : pass client index as well |
79 # TODO multiclient : pass client index as well |
78 pass |
80 pass |
79 |
81 |
80 def sendMessage(self, msg): |
82 def sendMessage(self, msg): |
81 self.sendMessage(msg, True) |
83 self.sendMessage(msg, True) |
82 |
84 |
83 class HMIProtocol(WebSocketServerProtocol): |
85 class HMIProtocol(WebSocketServerProtocol): |
84 |
86 |
97 |
99 |
98 def onMessage(self, msg, isBinary): |
100 def onMessage(self, msg, isBinary): |
99 self._hmi_session.onMessage(msg) |
101 self._hmi_session.onMessage(msg) |
100 print msg |
102 print msg |
101 #self.sendMessage(msg, binary) |
103 #self.sendMessage(msg, binary) |
102 |
104 |
103 svghmi_root = None |
105 svghmi_root = None |
104 svghmi_listener = None |
106 svghmi_listener = None |
|
107 svghmi_send_thread = None |
|
108 |
105 |
109 |
106 # Called by PLCObject at start |
110 # Called by PLCObject at start |
107 def _runtime_svghmi0_start(): |
111 def _runtime_svghmi0_start(): |
108 global svghmi_listener, svghmi_root |
112 global svghmi_listener, svghmi_root, svghmi_send_thread |
109 |
113 |
110 svghmi_root = Resource() |
114 svghmi_root = Resource() |
111 |
115 |
112 wsfactory = WebSocketServerFactory() |
116 wsfactory = WebSocketServerFactory() |
113 wsfactory.protocol = HMIProtocol |
117 wsfactory.protocol = HMIProtocol |
114 |
118 |
115 # svghmi_root.putChild("",File(".svg")) |
119 svghmi_root.putChild("ws", WebSocketResource(wsfactory)) |
116 svghmi_root.putChild("ws",WebSocketResource(wsfactory)) |
|
117 |
120 |
118 sitefactory = Site(svghmi_root) |
121 sitefactory = Site(svghmi_root) |
119 |
122 |
120 svghmi_listener = reactor.listenTCP(8008, sitefactory) |
123 svghmi_listener = reactor.listenTCP(8008, sitefactory) |
121 |
124 |
122 # TODO |
|
123 # start a thread that call the C part of SVGHMI |
125 # start a thread that call the C part of SVGHMI |
|
126 svghmi_send_thread = Thread(target=SendThreadProc, name="SVGHMI Send") |
|
127 svghmi_send_thread.start() |
124 |
128 |
125 |
129 |
126 # Called by PLCObject at stop |
130 # Called by PLCObject at stop |
127 def _runtime_svghmi0_stop(): |
131 def _runtime_svghmi0_stop(): |
128 global svghmi_listener |
132 global svghmi_listener, svghmi_root, svghmi_send_thread |
|
133 svghmi_root.delEntity("ws") |
|
134 svghmi_root = None |
129 svghmi_listener.stopListening() |
135 svghmi_listener.stopListening() |
|
136 svghmi_listener = None |
|
137 # plc cleanup calls svghmi_(locstring)_cleanup and unlocks send thread |
|
138 svghmi_send_thread.join() |
|
139 svghmi_send_thread = None |
|
140 |