#!/usr/bin/env python3 from typing import OrderedDict from dash_extensions.enrich import DashProxy from dash_extensions import WebSocket from dash_extensions.enrich import Input, Output, State, html, NoOutputTransform, MATCH import dash_mantine_components as dmc app = DashProxy(prevent_initial_callbacks=True, transforms=[NoOutputTransform()], title='Camera Server') port = 7000 def setup_dashboard(): print("Setting Up Dashboard") theme = { "colorScheme": "dark" } app.layout = dmc.MantineProvider( theme=theme, children=[ dmc.Paper( children=[ dmc.Header( p="md", children=[ dmc.Group( position="apart", children=[ dmc.Text("Websocket Client Connector", size="xl"), dmc.Group( position="right", children=[ video_selector(), ] ) ] ) ] ), dmc.Group( id="video_sockets_group", children=[] ) ], p="lg", radius=0, style={"height":"100%"} ), ] ) def video_selector(): return html.Div( dmc.MultiSelect( label="Subbed Web Sockets", placeholder="Select all you like!", id="socket_selector", data=[ "Test", "Test2" ], style={"width": 400}, ), ) def sort_dict(dict): return OrderedDict(sorted(dict.items())) def create_video_socket(id): print("Creating Socket: "+str(id)) un_ws_id = {"type":"ws", "id":str(id)} # Sort For JS Later on ws_id = sort_dict(un_ws_id) return html.Div( id=str(id), children=[ WebSocket(id=ws_id, url="ws://localhost:"+str(8000)), html.Div(id) ] ) def setup_video_socket_callbacks(): print("Set up Sockets") app.clientside_callback( """ function(state, wsId){ if(state && state.readyState === 1){ console.log('The Video connection has been established.'); let connect_data = {"reason": "connect", "type":"subscriber", "id":wsId.id}; console.log("Connect Data:", connect_data); return JSON.stringify(connect_data); } else { console.log("State Change Of Video Socket: ", wsId.id, state); return window.dash_clientside.no_update; } } """, Input({'type':'ws', "id": MATCH}, "state"), State({'type':'ws', "id": MATCH}, "id"), Output({'type':'ws', "id": MATCH}, "send") ) def callbacks(): @app.callback( Output('video_sockets_group', 'children'), Input('socket_selector', 'value'), State('video_sockets_group', 'children'), ) def update_output_sockets(ids, current_children): children = current_children addition = len(children) < len(ids) if(addition): current_ids = set() for child in children: current_ids.add(child["props"]["id"]) # Add Listeners for id in ids: if(id not in current_ids): children.append(create_video_socket(id)) else: # Subtract Listeners for child in children: if(child["props"]["id"] not in ids): print(" Remove") children.remove(child) return children setup_video_socket_callbacks() if __name__ == '__main__': setup_dashboard() callbacks() #spin the Dash server print("Starting Dashboard Server") app.run_server(host="0.0.0.0", port=port)