Edouard@2771: #!/usr/bin/env python Edouard@2771: # -*- coding: utf-8 -*- Edouard@2771: Edouard@2771: # This file is part of Beremiz Edouard@2771: # Copyright (C) 2019: Edouard TISSERANT Edouard@2771: # See COPYING file for copyrights details. Edouard@2771: Edouard@2771: from __future__ import absolute_import Edouard@2771: Edouard@2771: from twisted.web.server import Site Edouard@2771: from twisted.web.resource import Resource Edouard@2771: from twisted.internet import reactor Edouard@2771: from twisted.web.static import File Edouard@2771: Edouard@2771: from autobahn.twisted.websocket import WebSocketServerFactory, WebSocketServerProtocol Edouard@2771: from autobahn.twisted.resource import WebSocketResource Edouard@2771: Edouard@2773: # TODO multiclient : Edouard@2773: # session list lock Edouard@2773: # svghmi_sessions = [] Edouard@2773: Edouard@2773: svghmi_session = None Edouard@2771: Edouard@2771: class HMISession(object): Edouard@2771: def __init__(self, protocol_instance): Edouard@2773: global svghmi_session Edouard@2773: Edouard@2773: # TODO: kill existing session for robustness Edouard@2773: assert(svghmi_session is None) Edouard@2773: Edouard@2773: svghmi_session = self Edouard@2773: self.protocol_instance = protocol_instance Edouard@2771: Edouard@2771: # TODO multiclient : Edouard@2773: # svghmi_sessions.append(self) Edouard@2771: # get a unique bit index amont other svghmi_sessions, Edouard@2771: # so that we can match flags passed by C->python callback Edouard@2771: Edouard@2771: def __del__(self): Edouard@2773: global svghmi_session Edouard@2773: assert(svghmi_session) Edouard@2773: svghmi_session = None Edouard@2773: Edouard@2773: # TODO multiclient : Edouard@2773: # svghmi_sessions.remove(self) Edouard@2771: Edouard@2772: def onMessage(self, msg): Edouard@2771: # TODO : pass it to the C side recieve_message() Edouard@2771: # update HMITree Edouard@2771: # - values Edouard@2771: # - refresh rates / subsriptions Edouard@2771: Edouard@2771: # TODO multiclient : pass client index as well Edouard@2771: pass Edouard@2771: Edouard@2771: Edouard@2771: class HMIProtocol(WebSocketServerProtocol): Edouard@2771: Edouard@2771: def __init__(self, *args, **kwargs): Edouard@2771: self._hmi_session = None Edouard@2771: WebSocketServerProtocol.__init__(self, *args, **kwargs) Edouard@2771: Edouard@2771: def onOpen(self): Edouard@2771: self._hmi_session = HMISession(self) Edouard@2771: print "open" Edouard@2771: Edouard@2771: def onClose(self, wasClean, code, reason): Edouard@2771: del self._hmi_session Edouard@2771: self._hmi_session = None Edouard@2771: print "close" Edouard@2771: Edouard@2771: def onMessage(self, msg, isBinary): Edouard@2771: self._hmi_session.onMessage(msg) Edouard@2771: print msg Edouard@2771: #self.sendMessage(msg, binary) Edouard@2771: Edouard@2771: svghmi_root = None Edouard@2771: svghmi_listener = None Edouard@2771: Edouard@2771: # Called by PLCObject at start Edouard@2771: def _runtime_svghmi0_start(): Edouard@2771: global svghmi_listener, svghmi_root Edouard@2771: Edouard@2771: svghmi_root = Resource() Edouard@2771: Edouard@2771: wsfactory = WebSocketServerFactory() Edouard@2771: wsfactory.protocol = HMIProtocol Edouard@2771: Edouard@2771: # svghmi_root.putChild("",File(".svg")) Edouard@2771: svghmi_root.putChild("ws",WebSocketResource(wsfactory)) Edouard@2771: Edouard@2771: sitefactory = Site(svghmi_root) Edouard@2771: Edouard@2771: svghmi_listener = reactor.listenTCP(8008, sitefactory) Edouard@2771: Edouard@2771: # TODO Edouard@2771: # start a thread that call the C part of SVGHMI Edouard@2771: Edouard@2771: Edouard@2771: # Called by PLCObject at stop Edouard@2771: def _runtime_svghmi0_stop(): Edouard@2771: global svghmi_listener Edouard@2772: svghmi_listener.stopListening()