# Dora IOBridge Node A WebSocket server that bridges web clients with the Dora dataflow for real-time voice commands and scene updates. ## Inputs/Outputs | Input | Type | Description | |----------------|--------|---------------------------------------| | `voice_out` | JSON | Response from voice control node | | `scene_update` | JSON | Scene objects from voice control | | Output | Type | Description | |----------------|--------|---------------------------------------| | `voice_in` | string | Voice commands forwarded to Dora | ## Environment Variables ```bash VOICE_HOST=0.0.0.0 # Bind address VOICE_PORT=8765 # Listen port ``` ## Installation ```bash cd dora_iobridge pip install -e . ``` ## Testing ### Test with WebSocket (wscat) ```bash # Install wscat npm install -g wscat # Connect to the server wscat -c ws://localhost:8765 ``` ### Test with curl (websocat) ```bash # Install websocat # Ubuntu: sudo apt install websocat # macOS: brew install websocat # Send a ping echo '{"type": "ping"}' | websocat ws://localhost:8765 # Response: {"type": "pong"} # Send a voice command echo '{"type": "command", "text": "sube"}' | websocat ws://localhost:8765 # Request scene refresh echo '{"type": "scene_refresh"}' | websocat ws://localhost:8765 ``` ### Test with Python ```python import asyncio import websockets import json async def test_iobridge(): uri = "ws://localhost:8765" async with websockets.connect(uri) as ws: # Test ping await ws.send(json.dumps({"type": "ping"})) response = await ws.recv() print(f"Ping response: {response}") # Send command await ws.send(json.dumps({ "type": "command", "text": "agarra el cubo rojo" })) # Listen for responses async for message in ws: data = json.loads(message) print(f"Received: {data}") asyncio.run(test_iobridge()) ``` ### Test with curl (HTTP upgrade not supported directly) Since WebSocket requires an upgrade handshake, use this shell script: ```bash #!/bin/bash # test_iobridge.sh # Using websocat for interactive testing websocat ws://localhost:8765 < Server **Command (voice input)** ```json {"type": "command", "text": "agarra el cubo rojo"} ``` **Ping (health check)** ```json {"type": "ping"} ``` Response: `{"type": "pong"}` **Scene Refresh** ```json {"type": "scene_refresh"} ``` ### Server -> Client (Broadcasts) **Command Response** ```json { "type": "response", "text": "Ok, voy a tomar", "status": "ok" } ``` **Scene Update** ```json { "type": "scene_updated", "objects": [ { "object_type": "cubo", "color": "rojo", "size": "big", "position_mm": [150.0, 200.0, 280.0], "source": "detection" } ] } ``` ## Dora Dataflow Configuration ```yaml nodes: - id: iobridge build: pip install -e ./dora_iobridge path: dora_iobridge inputs: voice_out: voice_control/voice_out scene_update: voice_control/scene_update outputs: - voice_in env: VOICE_HOST: "0.0.0.0" VOICE_PORT: "8765" ``` ```bash dora up dora start dataflow.yml ``` ## Dependencies - dora-rs >= 0.3.9 - pyarrow >= 12.0.0 - websockets >= 12.0