# Getting Started This guide explains how to use `pymirokai` with the current **v2 API model**. ## Table of Contents ```{contents} :local: :depth: 2 ``` ## 1. Connection Model `pymirokai` exposes a single entry point: `connect(...)`. - The default API version is `v2`. - Authentication is handled with the API key you pass to `connect`. - `Robot` automatically keeps the shared JWT fresh for REST, WebSocket, and video usage. ```python from pymirokai.robot import connect async with connect(ip="192.168.0.10", api_key="YOUR_API_KEY") as robot: # Robot is connected to REST + WebSocket + Video endpoints ... ``` ### Local vs Remote Endpoints `connect(...)` resolves endpoints automatically: - `ip is None`: local UDS mode (`/tmp/rest_api.sock`) + local WS/RTSPS. - `ip in {"localhost", "127.0.0.1"}`: local TCP mode. - other IP/hostname: remote mode using: - `https:///rest` for REST, - `wss:///wss` for WebSocket, - `rtsps://:8555` for video. ### JWT Lifetime and Long-Running Connections Wizard JWTs are short-lived. `pymirokai` handles this for normal users: - REST responses can return a replacement token, which `pymirokai` stores automatically. - When the connection is idle, `pymirokai` refreshes the token through the authenticated `/auth/refresh/` route before it expires. - The refresh delay is computed from the JWT `exp` claim, not from a hard-coded token lifetime. If the token cannot be decoded, `pymirokai` falls back to a short retry delay instead of looping continuously. - After a successful background refresh, the WebSocket reconnects with the new token and re-subscribes to existing topics. - Video streams use the current shared JWT when they open or reconnect, so they do not need a separate refresh loop. Applications using `connect(...)` do not need to schedule their own JWT refresh. ## 2. Two Execution Styles `Robot` methods fall into two categories. ### Skills (Mission-based) Skill calls return a `Mission` object. ```python mission = robot.say("Hello!") await mission.started() await mission.completed() ``` ### Abilities / Commands (Immediate response) Ability calls return direct REST responses. ```python sound = await robot.set_sound_level(50) runes = await robot.get_detected_runes() ``` ## 3. Mission Lifecycle Mission helpers are available both on `Mission` and `Robot`. - Wait start: `await mission.started()` - Wait completion: `await mission.completed()` - Cancel: `await mission.cancel()` - Cancel and wait: `await mission.cancel_and_complete()` - Ignore completion exceptions: `await mission.completed(ignore_exceptions=True)` Robot-level helpers: - `await robot.wait_for_mission(mission_id)` - `await robot.cancel_mission(mission_id)` - `await robot.wait_for_mission_started(mission_id)` - `await robot.cancel_and_wait_for_mission(mission_id)` ## 4. v2 Command Transport Internally, all command-like abilities use explicit v2 REST routes under `/api/v2/commands/...`. - `Robot.send_get_command(route)` - `Robot.send_post_command(route, value)` - `Robot.send_command(method, route, value)` (low-level fallback) For most client code, prefer high-level ability methods (`set_sound_level`, `is_seeing_human`, etc.) instead of direct route calls. ## 5. WebSocket Topics ```python def on_navigation(message: dict) -> None: print(message) robot.subscribe("navigation_state") robot.register_callback("navigation_state", on_navigation) robot.publish("custom_topic", '{"name":"demo","type":"str","data":"hello"}') robot.unsubscribe("navigation_state") ``` ## 6. Video Streams Access the shared `VideoStreamManager` through `robot.connection.video_stream_manager`. The manager uses the current robot JWT automatically when opening streams. Relative stream names resolve against the connection video endpoint, for example `rtsps://:8555/head_color`. When a stream is opened or reconnected, the manager appends the current JWT as the `jwt` query parameter required by MediaMTX. ```python manager = robot.connection.video_stream_manager manager.add_stream("head_color", "head_color", display=True) manager.set_display("head_color", False) manager.remove_stream("head_color") ``` Absolute RTSP URLs are also accepted. If a URL already contains a `jwt` parameter, pymirokai replaces it with the current connection token and preserves any other query parameters. If OpenCV is unavailable, capture/display features are skipped safely. ## 7. Skill File Management Use these methods to manage uploaded custom skills: - `upload_skill_file(skill_path)` - `remove_skill_file(skill_name)` - `list_skill_files()` - `enable_skill_file(skill_name, enable)` ## 8. Error Handling Notes - Connection/auth failures raise from underlying `aiohttp` calls. - Command responses are validated server-side; invalid payloads return HTTP errors. - `Mission` methods raise `MissionError` on cancellation/failure unless ignored. Use regular `try/except` around mission and command calls in production clients.