154 lines
7.1 KiB
Python
154 lines
7.1 KiB
Python
from BackendProvider.Helper.SimpleWebSocketServer import SimpleWebSocketServer, WebSocket
|
|
from threading import Thread
|
|
from functools import partial
|
|
|
|
class ThreadedWebSocketServer(Thread):
|
|
def __init__(self,effectController,rgbStripController):
|
|
Thread.__init__(self)
|
|
self.effectController = effectController
|
|
self.rgbStripController = rgbStripController
|
|
self.daemon = True
|
|
self.stopped = False
|
|
self.start()
|
|
|
|
def run(self):
|
|
server = SimpleWebSocketServer('', 8001, partial(HTTPWebSocketsHandler,self.effectController, self.rgbStripController))
|
|
while not self.stopped:
|
|
server.serveonce()
|
|
print("ThreadedWebSocketServer stopped")
|
|
|
|
def stop(self):
|
|
self.stopped = True
|
|
|
|
import json
|
|
|
|
from rgbUtils import effectControllerJsonHelper
|
|
from rgbUtils import rgbStripControllerJsonHelper
|
|
|
|
import traceback
|
|
import logging
|
|
|
|
|
|
CLIENT_TYPE_CONTROLLER = 0
|
|
CLIENT_TYPE_STRIPE = 1
|
|
CLIENT_TYPE_RECORDER = 2
|
|
|
|
class HTTPWebSocketsHandler(WebSocket):
|
|
|
|
def __init__(self, effectController, rgbStripController, *args, **kwargs):
|
|
self.effectController = effectController
|
|
self.rgbStripController = rgbStripController
|
|
self.client_type = CLIENT_TYPE_CONTROLLER
|
|
self.rgbStrip = None
|
|
super().__init__(*args, **kwargs)
|
|
|
|
def handleMessage(self):
|
|
try:
|
|
print(self.address, self.data)
|
|
data = json.loads(self.data)
|
|
# Client Registration on the Websocket Server
|
|
# maybe it would be better to use a websocket server thread for each client type,
|
|
# can be done in future if there is too much latency
|
|
if "register_client_type" in self.data:
|
|
# the controler type, add handler on RGBStripContoller and send the current state of the controller
|
|
if int(data['register_client_type']) is CLIENT_TYPE_CONTROLLER:
|
|
self.client_type = CLIENT_TYPE_CONTROLLER
|
|
# add effectController onControllerChangeHandler to get changes in the effectController eg start/stop effects, parameter updates, moved strips
|
|
# register rgbStripController onRGBStripRegistered/UnRegistered handler to get noticed about new rgbStrips is not necessary
|
|
# since we will get noticed from the effectController when it added the rgbStrip to the offEffect
|
|
self.effectController.addOnControllerChangeHandler(self.onChange)
|
|
# register new Stripes
|
|
elif int(data['register_client_type']) is CLIENT_TYPE_STRIPE and "client_name" in data:
|
|
self.client_type = CLIENT_TYPE_STRIPE
|
|
ledcount=1
|
|
if "led_count" in data:
|
|
ledcount = int(data["led_count"])
|
|
self.nojson=0
|
|
if "nojson" in data:
|
|
self.nojson = int(data["nojson"])
|
|
self.nosend=0
|
|
if "nosend" in data:
|
|
self.nosend = int(data["nosend"])
|
|
|
|
# registers the strip with websocket object and name. the onRGBStripValueUpdate(rgbStrip) is called by
|
|
# by the rgbStrip when an effectThread updates it
|
|
# the self.rgbStrip variable is used to unregister the strip only
|
|
self.rgbStrip = self.rgbStripController.registerRGBStrip(data["client_name"],self.onRGBStripValueUpdate,ledcount)
|
|
# register new Audio Recorders
|
|
elif int(data['register_client_type']) is CLIENT_TYPE_RECORDER:
|
|
self.client_type = CLIENT_TYPE_RECORDER
|
|
|
|
# controller responses are handled by the effectControllerJsonHelper
|
|
if self.client_type is CLIENT_TYPE_CONTROLLER:
|
|
response = effectControllerJsonHelper.responseHandler(self.effectController, self.rgbStripController, data)
|
|
self.sendMessage(
|
|
json.dumps({
|
|
'response': response
|
|
})
|
|
)
|
|
return
|
|
# the stripe should usualy not send any data, i do not know why it should...
|
|
elif self.client_type is CLIENT_TYPE_STRIPE:
|
|
if self.nosend == 1:
|
|
respdata = "d"
|
|
for i in range(self.rgbStrip.STRIP_LENGHT):
|
|
respdata += ":" + str(i) + ":"+str(self.rgbStrip.red[i])+":"+str(self.rgbStrip.green[i])+":"+str(self.rgbStrip.blue[i])
|
|
self.sendMessage(respdata)
|
|
return
|
|
# audio recorder responses are handled by the effectControllerJsonHandler
|
|
elif self.client_type is CLIENT_TYPE_RECORDER:
|
|
return
|
|
except Exception as e:
|
|
print(e, traceback.format_exc())
|
|
|
|
# notice about connects in terminal, the client has to register itself, see handleMessage
|
|
def handleConnected(self):
|
|
print(self.address, 'connected')
|
|
|
|
# unregister the onChangeHandler
|
|
# for now this function is not called when a client times out,
|
|
# so they don't get unregistered. i mean there is no function that
|
|
# is called when a client times out.
|
|
def handleClose(self):
|
|
if self.client_type is CLIENT_TYPE_CONTROLLER:
|
|
self.effectController.removeOnControllerChangeHandler(self.onChange)
|
|
elif self.client_type is CLIENT_TYPE_STRIPE:
|
|
self.rgbStripController.unregisterRGBStrip(self.rgbStrip)
|
|
elif self.client_type is CLIENT_TYPE_RECORDER:
|
|
pass
|
|
print(self.address, 'closed')
|
|
|
|
# called when there are changes that should be pushed to the client.
|
|
# - the effectController: start / stop effects, move strip to effect, changing effect params
|
|
# - the rgbStripController: add/removing strips
|
|
# -> CLIENT_TYPE_CONTROLLER
|
|
def onChange(self):
|
|
if self.client_type is CLIENT_TYPE_CONTROLLER:
|
|
self.sendMessage(
|
|
json.dumps({
|
|
'effects': effectControllerJsonHelper.getEffects(self.effectController),
|
|
'rgbStrips': rgbStripControllerJsonHelper.getRGBStrips(self.rgbStripController),
|
|
'effectThreads': effectControllerJsonHelper.getEffectThreads(self.effectController)
|
|
})
|
|
)
|
|
return
|
|
elif self.client_type is CLIENT_TYPE_STRIPE:
|
|
return
|
|
elif self.client_type is CLIENT_TYPE_RECORDER:
|
|
return
|
|
|
|
# when a rgbStrip value is changed, send json data to client
|
|
def onRGBStripValueUpdate(self,rgbStrip):
|
|
if self.nosend == 0:
|
|
if self.nojson == 0:
|
|
self.sendMessage(
|
|
json.dumps({
|
|
'data': rgbStripControllerJsonHelper.getRGBData(rgbStrip)
|
|
})
|
|
)
|
|
if self.nojson == 1:
|
|
respdata = "d"
|
|
for i in range(rgbStrip.STRIP_LENGHT):
|
|
respdata += ":" + str(i) + ":"+str(rgbStrip.red[i])+":"+str(rgbStrip.green[i])+":"+str(rgbStrip.blue[i])
|
|
self.sendMessage(respdata)
|