60 lines
2.1 KiB
Python
60 lines
2.1 KiB
Python
import asyncio
|
|
import json
|
|
import logging
|
|
import panel
|
|
|
|
from websockets import ConnectionClosed
|
|
from websockets.asyncio.client import connect
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
def attach_w42_state(rx_var: panel.rx, system_id: str, token: str):
|
|
|
|
WS_URL = "ws://localhost:8000/ws/systems" # TODO: make configurable
|
|
|
|
must_reconnect = True
|
|
|
|
async def subscribe_to_system():
|
|
|
|
logger.info(f"Starting connection to {WS_URL} for system_id {system_id}")
|
|
|
|
async for websocket in connect(WS_URL):
|
|
try:
|
|
logger.info(f"Connected to {WS_URL}")
|
|
send_response = await websocket.send(json.dumps({
|
|
"action": "subscribe",
|
|
"system_id": system_id,
|
|
"token": token
|
|
}))
|
|
logger.info(f"Subscribed to system {system_id}, waiting for messages..., send_response={send_response}")
|
|
async for message in websocket:
|
|
as_json = json.loads(message)
|
|
if as_json.get('error'):
|
|
logger.error(f"Error from websocket: {as_json['error']}")
|
|
rx_var.rx.value = as_json
|
|
else:
|
|
rx_var.rx.value = as_json['change']['state']
|
|
except ConnectionClosed:
|
|
if must_reconnect:
|
|
logger.info("connection closed, retrying...")
|
|
continue
|
|
else:
|
|
logger.info("Not retrying connection.")
|
|
return
|
|
except Exception as e:
|
|
logger.info(f"connection error, will retry: {e}")
|
|
await asyncio.sleep(2)
|
|
|
|
logger.info(f"Attaching W42 state for system_id {system_id}")
|
|
panel.state.execute(subscribe_to_system)
|
|
|
|
async def session_destroyed():
|
|
logger.info("Stop retrying connection (session destroyed)")
|
|
nonlocal must_reconnect
|
|
must_reconnect = False
|
|
|
|
def on_session_destroyed(session_id):
|
|
logger.info(f"Session {session_id} destroyed")
|
|
panel.state.execute(session_destroyed)
|
|
|
|
panel.state.on_session_destroyed(on_session_destroyed)
|