Compare commits

..

2 commits

2 changed files with 70 additions and 3 deletions

17
sample.py Normal file
View file

@ -0,0 +1,17 @@
import json
import panel
from watt42_viewlib import attach_w42_state
w42_state = panel.rx(None)
attach_w42_state(rx_var=w42_state, system_id="fb2b91ce-383e-4356-96b3-b6405dacb353")
state_as_text = panel.bind(lambda s: f"W42 State:\n\n```\n{json.dumps(s, indent=2)}\n```\n\nReplace this with some awesome visuals", w42_state)
state_pane = panel.pane.Markdown(state_as_text, sizing_mode='stretch_width')
_ = panel.template.FastListTemplate(
title="Sample W42 View App",
sidebar=[panel.pane.Markdown("This is a sample sidebar.")],
main=[panel.pane.Markdown("# Welcome to the Main Content Area"), state_pane],
).servable()

View file

@ -1,5 +1,55 @@
import asyncio
import json
import logging
import panel
print(f"hello from viewlib")
from websockets import ConnectionClosed
from websockets.asyncio.client import connect
def greet(name: str) -> str:
return f"Hello, {name}!"
logger = logging.getLogger(__name__)
def attach_w42_state(rx_var: panel.rx, system_id: 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
}))
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)
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)