author | Edouard Tisserant |
Tue, 13 Jul 2021 16:13:21 +0200 | |
branch | svghmi |
changeset 3277 | 8e81e4ce9bc6 |
parent 3273 | 08a5a019bed2 |
child 3278 | 2bcfbea6a2a8 |
permissions | -rw-r--r-- |
2771
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
1 |
#!/usr/bin/env python |
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
2 |
# -*- coding: utf-8 -*- |
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
3 |
|
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
4 |
# This file is part of Beremiz |
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
5 |
# Copyright (C) 2019: Edouard TISSERANT |
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
6 |
# See COPYING file for copyrights details. |
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
7 |
|
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
8 |
from __future__ import absolute_import |
2799
f5da343b9b63
SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents:
2798
diff
changeset
|
9 |
import errno |
2822
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
10 |
from threading import RLock, Timer |
2771
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
11 |
|
2823
d631f8671c75
SVGHMI : add on Start, Stop and Watchdog command fields to configuration
Edouard Tisserant
parents:
2822
diff
changeset
|
12 |
try: |
d631f8671c75
SVGHMI : add on Start, Stop and Watchdog command fields to configuration
Edouard Tisserant
parents:
2822
diff
changeset
|
13 |
from runtime.spawn_subprocess import Popen |
d631f8671c75
SVGHMI : add on Start, Stop and Watchdog command fields to configuration
Edouard Tisserant
parents:
2822
diff
changeset
|
14 |
except ImportError: |
d631f8671c75
SVGHMI : add on Start, Stop and Watchdog command fields to configuration
Edouard Tisserant
parents:
2822
diff
changeset
|
15 |
from subprocess import Popen |
d631f8671c75
SVGHMI : add on Start, Stop and Watchdog command fields to configuration
Edouard Tisserant
parents:
2822
diff
changeset
|
16 |
|
2771
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
17 |
from twisted.web.server import Site |
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
18 |
from twisted.web.resource import Resource |
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
19 |
from twisted.internet import reactor |
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
20 |
from twisted.web.static import File |
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
21 |
|
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
22 |
from autobahn.twisted.websocket import WebSocketServerFactory, WebSocketServerProtocol |
2799
f5da343b9b63
SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents:
2798
diff
changeset
|
23 |
from autobahn.websocket.protocol import WebSocketProtocol |
2771
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
24 |
from autobahn.twisted.resource import WebSocketResource |
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
25 |
|
3270
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
26 |
max_svghmi_sessions = None |
2822
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
27 |
svghmi_watchdog = None |
2771
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
28 |
|
3271
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
29 |
|
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
30 |
svghmi_wait = PLCBinary.svghmi_wait |
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
31 |
svghmi_wait.restype = ctypes.c_int # error or 0 |
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
32 |
svghmi_wait.argtypes = [] |
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
33 |
|
2774
9857b4b0d979
SVGHMI: WIP for python<->C data exchange
Edouard Tisserant
parents:
2773
diff
changeset
|
34 |
svghmi_send_collect = PLCBinary.svghmi_send_collect |
9857b4b0d979
SVGHMI: WIP for python<->C data exchange
Edouard Tisserant
parents:
2773
diff
changeset
|
35 |
svghmi_send_collect.restype = ctypes.c_int # error or 0 |
9857b4b0d979
SVGHMI: WIP for python<->C data exchange
Edouard Tisserant
parents:
2773
diff
changeset
|
36 |
svghmi_send_collect.argtypes = [ |
3270
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
37 |
ctypes.c_uint32, # index |
2774
9857b4b0d979
SVGHMI: WIP for python<->C data exchange
Edouard Tisserant
parents:
2773
diff
changeset
|
38 |
ctypes.POINTER(ctypes.c_uint32), # size |
2799
f5da343b9b63
SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents:
2798
diff
changeset
|
39 |
ctypes.POINTER(ctypes.c_void_p)] # data ptr |
2774
9857b4b0d979
SVGHMI: WIP for python<->C data exchange
Edouard Tisserant
parents:
2773
diff
changeset
|
40 |
|
3271
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
41 |
svghmi_reset = PLCBinary.svghmi_reset |
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
42 |
svghmi_reset.restype = ctypes.c_int # error or 0 |
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
43 |
svghmi_reset.argtypes = [ |
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
44 |
ctypes.c_uint32] # index |
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
45 |
|
2774
9857b4b0d979
SVGHMI: WIP for python<->C data exchange
Edouard Tisserant
parents:
2773
diff
changeset
|
46 |
svghmi_recv_dispatch = PLCBinary.svghmi_recv_dispatch |
9857b4b0d979
SVGHMI: WIP for python<->C data exchange
Edouard Tisserant
parents:
2773
diff
changeset
|
47 |
svghmi_recv_dispatch.restype = ctypes.c_int # error or 0 |
9857b4b0d979
SVGHMI: WIP for python<->C data exchange
Edouard Tisserant
parents:
2773
diff
changeset
|
48 |
svghmi_recv_dispatch.argtypes = [ |
3270
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
49 |
ctypes.c_uint32, # index |
2788
2ed9ff826d03
SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents:
2779
diff
changeset
|
50 |
ctypes.c_uint32, # size |
2779
75c6a31caca6
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.
Edouard Tisserant
parents:
2777
diff
changeset
|
51 |
ctypes.c_char_p] # data ptr |
3270
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
52 |
|
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
53 |
class HMISessionMgr(object): |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
54 |
def __init__(self): |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
55 |
self.multiclient_sessions = set() |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
56 |
self.watchdog_session = None |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
57 |
self.session_count = 0 |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
58 |
self.lock = RLock() |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
59 |
self.indexes = set() |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
60 |
|
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
61 |
def next_index(self): |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
62 |
if self.indexes: |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
63 |
greatest = max(self.indexes) |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
64 |
holes = set(range(greatest)) - self.indexes |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
65 |
index = min(holes) if holes else greatest+1 |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
66 |
else: |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
67 |
index = 0 |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
68 |
self.indexes.add(index) |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
69 |
return index |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
70 |
|
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
71 |
def free_index(self, index): |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
72 |
self.indexes.remove(index) |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
73 |
|
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
74 |
def register(self, session): |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
75 |
global max_svghmi_sessions |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
76 |
with self.lock: |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
77 |
if session.is_watchdog_session: |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
78 |
# Creating a new watchdog session closes pre-existing one |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
79 |
if self.watchdog_session is not None: |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
80 |
self.unregister(self.watchdog_session) |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
81 |
else: |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
82 |
assert(self.session_count < max_svghmi_sessions) |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
83 |
self.session_count += 1 |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
84 |
|
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
85 |
self.watchdog_session = session |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
86 |
else: |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
87 |
assert(self.session_count < max_svghmi_sessions) |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
88 |
self.multiclient_sessions.add(session) |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
89 |
self.session_count += 1 |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
90 |
session.session_index = self.next_index() |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
91 |
|
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
92 |
def unregister(self, session): |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
93 |
with self.lock: |
3271
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
94 |
if session.is_watchdog_session : |
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
95 |
if self.watchdog_session != session: |
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
96 |
return |
3270
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
97 |
self.watchdog_session = None |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
98 |
else: |
3271
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
99 |
try: |
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
100 |
self.multiclient_sessions.remove(self) |
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
101 |
except KeyError: |
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
102 |
return |
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
103 |
self.free_index(session.session_index) |
3270
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
104 |
self.session_count -= 1 |
3271
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
105 |
session.kill() |
3273
08a5a019bed2
SVGHMI: finished multiclient support. Still needs more testing.
Edouard Tisserant
parents:
3272
diff
changeset
|
106 |
|
3270
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
107 |
def close_all(self): |
3272
c8182e066545
SVGHMI: Fixed iterator in session manager. Getting closer to working multiclient, to be continued.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3271
diff
changeset
|
108 |
for session in self.iter_sessions(): |
c8182e066545
SVGHMI: Fixed iterator in session manager. Getting closer to working multiclient, to be continued.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3271
diff
changeset
|
109 |
self.unregister(session) |
3273
08a5a019bed2
SVGHMI: finished multiclient support. Still needs more testing.
Edouard Tisserant
parents:
3272
diff
changeset
|
110 |
|
3270
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
111 |
def iter_sessions(self): |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
112 |
with self.lock: |
3272
c8182e066545
SVGHMI: Fixed iterator in session manager. Getting closer to working multiclient, to be continued.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3271
diff
changeset
|
113 |
lst = list(self.multiclient_sessions) |
c8182e066545
SVGHMI: Fixed iterator in session manager. Getting closer to working multiclient, to be continued.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3271
diff
changeset
|
114 |
if self.watchdog_session is not None: |
c8182e066545
SVGHMI: Fixed iterator in session manager. Getting closer to working multiclient, to be continued.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3271
diff
changeset
|
115 |
lst = [self.watchdog_session]+lst |
c8182e066545
SVGHMI: Fixed iterator in session manager. Getting closer to working multiclient, to be continued.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3271
diff
changeset
|
116 |
for nxt_session in lst: |
c8182e066545
SVGHMI: Fixed iterator in session manager. Getting closer to working multiclient, to be continued.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3271
diff
changeset
|
117 |
yield nxt_session |
3270
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
118 |
|
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
119 |
|
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
120 |
svghmi_session_manager = HMISessionMgr() |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
121 |
|
2774
9857b4b0d979
SVGHMI: WIP for python<->C data exchange
Edouard Tisserant
parents:
2773
diff
changeset
|
122 |
|
2771
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
123 |
class HMISession(object): |
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
124 |
def __init__(self, protocol_instance): |
2773 | 125 |
self.protocol_instance = protocol_instance |
3270
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
126 |
self._session_index = None |
3271
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
127 |
self.closed = False |
3270
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
128 |
|
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
129 |
@property |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
130 |
def is_watchdog_session(self): |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
131 |
return self.protocol_instance.has_watchdog |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
132 |
|
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
133 |
@property |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
134 |
def session_index(self): |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
135 |
return self._session_index |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
136 |
|
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
137 |
@session_index.setter |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
138 |
def session_index(self, value): |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
139 |
self._session_index = value |
2775
3b93409ba22c
SVGHMI: WIP for python<->C data exchange
Edouard Tisserant
parents:
2774
diff
changeset
|
140 |
|
3271
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
141 |
def reset(self): |
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
142 |
return svghmi_reset(self.session_index) |
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
143 |
|
2799
f5da343b9b63
SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents:
2798
diff
changeset
|
144 |
def close(self): |
3271
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
145 |
if self.closed: return |
2799
f5da343b9b63
SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents:
2798
diff
changeset
|
146 |
self.protocol_instance.sendClose(WebSocketProtocol.CLOSE_STATUS_CODE_NORMAL) |
2771
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
147 |
|
3271
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
148 |
def notify_closed(self): |
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
149 |
self.closed = True |
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
150 |
|
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
151 |
def kill(self): |
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
152 |
self.close() |
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
153 |
self.reset() |
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
154 |
|
2772 | 155 |
def onMessage(self, msg): |
2779
75c6a31caca6
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.
Edouard Tisserant
parents:
2777
diff
changeset
|
156 |
# pass message to the C side recieve_message() |
3271
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
157 |
if self.closed: return |
3270
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
158 |
return svghmi_recv_dispatch(self.session_index, len(msg), msg) |
2777
cdf6584953a0
SVGHMI: WIP for python<->C data exchange : message from browser hit the C side.
Edouard Tisserant
parents:
2776
diff
changeset
|
159 |
|
2774
9857b4b0d979
SVGHMI: WIP for python<->C data exchange
Edouard Tisserant
parents:
2773
diff
changeset
|
160 |
def sendMessage(self, msg): |
3271
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
161 |
if self.closed: return |
2799
f5da343b9b63
SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents:
2798
diff
changeset
|
162 |
self.protocol_instance.sendMessage(msg, True) |
f5da343b9b63
SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents:
2798
diff
changeset
|
163 |
return 0 |
2771
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
164 |
|
2822
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
165 |
class Watchdog(object): |
2831
6c9cfdbe94dc
SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents:
2830
diff
changeset
|
166 |
def __init__(self, initial_timeout, interval, callback): |
2822
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
167 |
self._callback = callback |
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
168 |
self.lock = RLock() |
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
169 |
self.initial_timeout = initial_timeout |
2831
6c9cfdbe94dc
SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents:
2830
diff
changeset
|
170 |
self.interval = interval |
2822
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
171 |
self.callback = callback |
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
172 |
with self.lock: |
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
173 |
self._start() |
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
174 |
|
2831
6c9cfdbe94dc
SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents:
2830
diff
changeset
|
175 |
def _start(self, rearm=False): |
6c9cfdbe94dc
SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents:
2830
diff
changeset
|
176 |
duration = self.interval if rearm else self.initial_timeout |
6c9cfdbe94dc
SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents:
2830
diff
changeset
|
177 |
if duration: |
6c9cfdbe94dc
SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents:
2830
diff
changeset
|
178 |
self.timer = Timer(duration, self.trigger) |
6c9cfdbe94dc
SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents:
2830
diff
changeset
|
179 |
self.timer.start() |
2835
bc666f020ab3
SVGHMI : fix watchdog exception when timeout null
Edouard Tisserant
parents:
2832
diff
changeset
|
180 |
else: |
bc666f020ab3
SVGHMI : fix watchdog exception when timeout null
Edouard Tisserant
parents:
2832
diff
changeset
|
181 |
self.timer = None |
2822
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
182 |
|
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
183 |
def _stop(self): |
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
184 |
if self.timer is not None: |
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
185 |
self.timer.cancel() |
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
186 |
self.timer = None |
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
187 |
|
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
188 |
def cancel(self): |
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
189 |
with self.lock: |
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
190 |
self._stop() |
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
191 |
|
2832
e9ba4dee6ffb
SVGHMI : wait for initial timeout after watchdog is triggered, since it generaly induces HMI restart
Edouard Tisserant
parents:
2831
diff
changeset
|
192 |
def feed(self, rearm=True): |
2822
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
193 |
with self.lock: |
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
194 |
self._stop() |
2832
e9ba4dee6ffb
SVGHMI : wait for initial timeout after watchdog is triggered, since it generaly induces HMI restart
Edouard Tisserant
parents:
2831
diff
changeset
|
195 |
self._start(rearm) |
2822
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
196 |
|
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
197 |
def trigger(self): |
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
198 |
self._callback() |
3270
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
199 |
# Don't repeat trigger periodically |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
200 |
# # wait for initial timeout on re-start |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
201 |
# self.feed(rearm=False) |
2822
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
202 |
|
2771
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
203 |
class HMIProtocol(WebSocketServerProtocol): |
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
204 |
|
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
205 |
def __init__(self, *args, **kwargs): |
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
206 |
self._hmi_session = None |
3270
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
207 |
self.has_watchdog = False |
2771
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
208 |
WebSocketServerProtocol.__init__(self, *args, **kwargs) |
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
209 |
|
3268
d22782b9591f
SVGHMI: Added a way to distinguish watchdog-enabled HMI from multi-client HMI in URL.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3200
diff
changeset
|
210 |
def onConnect(self, request): |
d22782b9591f
SVGHMI: Added a way to distinguish watchdog-enabled HMI from multi-client HMI in URL.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3200
diff
changeset
|
211 |
self.has_watchdog = request.params.get("mode", [None])[0] == "watchdog" |
d22782b9591f
SVGHMI: Added a way to distinguish watchdog-enabled HMI from multi-client HMI in URL.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3200
diff
changeset
|
212 |
return WebSocketServerProtocol.onConnect(self, request) |
d22782b9591f
SVGHMI: Added a way to distinguish watchdog-enabled HMI from multi-client HMI in URL.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3200
diff
changeset
|
213 |
|
2771
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
214 |
def onOpen(self): |
3270
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
215 |
global svghmi_session_manager |
2799
f5da343b9b63
SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents:
2798
diff
changeset
|
216 |
assert(self._hmi_session is None) |
2771
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
217 |
self._hmi_session = HMISession(self) |
3271
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
218 |
registered = svghmi_session_manager.register(self._hmi_session) |
2771
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
219 |
|
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
220 |
def onClose(self, wasClean, code, reason): |
3270
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
221 |
global svghmi_session_manager |
3271
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
222 |
self._hmi_session.notify_closed() |
3270
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
223 |
svghmi_session_manager.unregister(self._hmi_session) |
2771
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
224 |
self._hmi_session = None |
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
225 |
|
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
226 |
def onMessage(self, msg, isBinary): |
3270
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
227 |
global svghmi_watchdog |
2799
f5da343b9b63
SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents:
2798
diff
changeset
|
228 |
assert(self._hmi_session is not None) |
2822
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
229 |
|
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
230 |
result = self._hmi_session.onMessage(msg) |
3270
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
231 |
if result == 1 and self.has_watchdog: # was heartbeat |
2822
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
232 |
if svghmi_watchdog is not None: |
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
233 |
svghmi_watchdog.feed() |
2775
3b93409ba22c
SVGHMI: WIP for python<->C data exchange
Edouard Tisserant
parents:
2774
diff
changeset
|
234 |
|
2779
75c6a31caca6
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.
Edouard Tisserant
parents:
2777
diff
changeset
|
235 |
class HMIWebSocketServerFactory(WebSocketServerFactory): |
75c6a31caca6
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.
Edouard Tisserant
parents:
2777
diff
changeset
|
236 |
protocol = HMIProtocol |
75c6a31caca6
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.
Edouard Tisserant
parents:
2777
diff
changeset
|
237 |
|
3269
5d174cdf4d98
SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3268
diff
changeset
|
238 |
svghmi_servers = {} |
2775
3b93409ba22c
SVGHMI: WIP for python<->C data exchange
Edouard Tisserant
parents:
2774
diff
changeset
|
239 |
svghmi_send_thread = None |
3b93409ba22c
SVGHMI: WIP for python<->C data exchange
Edouard Tisserant
parents:
2774
diff
changeset
|
240 |
|
2776
246ae685ab65
SVGHMI: WIP for python<->C data exchange
Edouard Tisserant
parents:
2775
diff
changeset
|
241 |
def SendThreadProc(): |
3270
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
242 |
global svghmi_session_manager |
2819
3b99c908f43b
SVGHMI: change collect/send thread looping condition to fix infinite loop in some cases
Edouard Tisserant
parents:
2799
diff
changeset
|
243 |
size = ctypes.c_uint32() |
3b99c908f43b
SVGHMI: change collect/send thread looping condition to fix infinite loop in some cases
Edouard Tisserant
parents:
2799
diff
changeset
|
244 |
ptr = ctypes.c_void_p() |
3b99c908f43b
SVGHMI: change collect/send thread looping condition to fix infinite loop in some cases
Edouard Tisserant
parents:
2799
diff
changeset
|
245 |
res = 0 |
3270
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
246 |
finished = False |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
247 |
while not(finished): |
3271
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
248 |
svghmi_wait() |
3270
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
249 |
for svghmi_session in svghmi_session_manager.iter_sessions(): |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
250 |
res = svghmi_send_collect( |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
251 |
svghmi_session.session_index, |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
252 |
ctypes.byref(size), ctypes.byref(ptr)) |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
253 |
if res == 0: |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
254 |
svghmi_session.sendMessage( |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
255 |
ctypes.string_at(ptr.value,size.value)) |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
256 |
elif res == errno.ENODATA: |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
257 |
# this happens when there is no data after wakeup |
3271
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
258 |
# because of hmi data refresh period longer than |
3270
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
259 |
# PLC common ticktime |
3271
561dbd1e3e04
SVGHMI: Fixing last commit's multiclient implementation, in case of watchdog. To be continued, since multiclient still fail...
Edouard Tisserant
parents:
3270
diff
changeset
|
260 |
pass |
3270
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
261 |
else: |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
262 |
# this happens when finishing |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
263 |
finished = True |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
264 |
break |
2776
246ae685ab65
SVGHMI: WIP for python<->C data exchange
Edouard Tisserant
parents:
2775
diff
changeset
|
265 |
|
3269
5d174cdf4d98
SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3268
diff
changeset
|
266 |
def AddPathToSVGHMIServers(path, factory): |
5d174cdf4d98
SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3268
diff
changeset
|
267 |
for k,v in svghmi_servers.iteritems(): |
5d174cdf4d98
SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3268
diff
changeset
|
268 |
svghmi_root, svghmi_listener, path_list = v |
5d174cdf4d98
SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3268
diff
changeset
|
269 |
svghmi_root.putChild(path, factory()) |
2779
75c6a31caca6
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.
Edouard Tisserant
parents:
2777
diff
changeset
|
270 |
|
2771
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
271 |
# Called by PLCObject at start |
2993
b76f303ffce6
Python Runtime: order of execution of extension's init() and cleanup() now reflects order of appearance of extensions in configuration tree.
Edouard Tisserant
parents:
2835
diff
changeset
|
272 |
def _runtime_00_svghmi_start(): |
3269
5d174cdf4d98
SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3268
diff
changeset
|
273 |
global svghmi_send_thread |
2771
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
274 |
|
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
275 |
# start a thread that call the C part of SVGHMI |
2775
3b93409ba22c
SVGHMI: WIP for python<->C data exchange
Edouard Tisserant
parents:
2774
diff
changeset
|
276 |
svghmi_send_thread = Thread(target=SendThreadProc, name="SVGHMI Send") |
3b93409ba22c
SVGHMI: WIP for python<->C data exchange
Edouard Tisserant
parents:
2774
diff
changeset
|
277 |
svghmi_send_thread.start() |
2771
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
278 |
|
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
279 |
|
361366b891ca
WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents:
diff
changeset
|
280 |
# Called by PLCObject at stop |
2993
b76f303ffce6
Python Runtime: order of execution of extension's init() and cleanup() now reflects order of appearance of extensions in configuration tree.
Edouard Tisserant
parents:
2835
diff
changeset
|
281 |
def _runtime_00_svghmi_stop(): |
3269
5d174cdf4d98
SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
3268
diff
changeset
|
282 |
global svghmi_send_thread, svghmi_session |
2822
9101a72a1da0
SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents:
2819
diff
changeset
|
283 |
|
3270
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
284 |
svghmi_session_manager.close_all() |
38f7122ccbf9
SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents:
3269
diff
changeset
|
285 |
|
2775
3b93409ba22c
SVGHMI: WIP for python<->C data exchange
Edouard Tisserant
parents:
2774
diff
changeset
|
286 |
# plc cleanup calls svghmi_(locstring)_cleanup and unlocks send thread |
3b93409ba22c
SVGHMI: WIP for python<->C data exchange
Edouard Tisserant
parents:
2774
diff
changeset
|
287 |
svghmi_send_thread.join() |
3b93409ba22c
SVGHMI: WIP for python<->C data exchange
Edouard Tisserant
parents:
2774
diff
changeset
|
288 |
svghmi_send_thread = None |
3b93409ba22c
SVGHMI: WIP for python<->C data exchange
Edouard Tisserant
parents:
2774
diff
changeset
|
289 |
|
2830
15d7bd79d9e8
SVGHMI : avoid caching of xhtml file by forcing cache-control header in http response.
Edouard Tisserant
parents:
2823
diff
changeset
|
290 |
|
15d7bd79d9e8
SVGHMI : avoid caching of xhtml file by forcing cache-control header in http response.
Edouard Tisserant
parents:
2823
diff
changeset
|
291 |
class NoCacheFile(File): |
15d7bd79d9e8
SVGHMI : avoid caching of xhtml file by forcing cache-control header in http response.
Edouard Tisserant
parents:
2823
diff
changeset
|
292 |
def render_GET(self, request): |
15d7bd79d9e8
SVGHMI : avoid caching of xhtml file by forcing cache-control header in http response.
Edouard Tisserant
parents:
2823
diff
changeset
|
293 |
request.setHeader(b"Cache-Control", b"no-cache, no-store") |
15d7bd79d9e8
SVGHMI : avoid caching of xhtml file by forcing cache-control header in http response.
Edouard Tisserant
parents:
2823
diff
changeset
|
294 |
return File.render_GET(self, request) |
15d7bd79d9e8
SVGHMI : avoid caching of xhtml file by forcing cache-control header in http response.
Edouard Tisserant
parents:
2823
diff
changeset
|
295 |
render_HEAD = render_GET |
15d7bd79d9e8
SVGHMI : avoid caching of xhtml file by forcing cache-control header in http response.
Edouard Tisserant
parents:
2823
diff
changeset
|
296 |
|
15d7bd79d9e8
SVGHMI : avoid caching of xhtml file by forcing cache-control header in http response.
Edouard Tisserant
parents:
2823
diff
changeset
|
297 |