$npx -y skills add omnigentx/jarvis --skill iot-controlControl IoT smart home devices. Use when user requests: start/stop robot vacuum, find robot, schedule cleaning, return to dock, or check robot status. Auto-handles Roborock 2FA via Gmail.
| 1 | # ROBOT VACUUM CONTROL (ROBOROCK) |
| 2 | |
| 3 | ## Available Tools (exact MCP names) |
| 4 | |
| 5 | | Intent | Tool | |
| 6 | |---|---| |
| 7 | | List all devices on account | `list_devices()` | |
| 8 | | Status / battery / online check | `get_robot_status(device_name=None)` | |
| 9 | | Consumable wear (brush, filter, dustbin) | `get_consumable_status(device_name=None)` | |
| 10 | | Start cleaning | `start_cleaning(device_name=None)` | |
| 11 | | Stop / pause | `stop_cleaning(device_name=None)` | |
| 12 | | Send back to dock | `return_to_dock(device_name=None)` | |
| 13 | | Find robot (beep) | `find_robot(device_name=None)` | |
| 14 | | List rooms on map | `get_room_mapping(device_name=None)` | |
| 15 | | Clean specific room | `clean_specific_room(room_id, device_name=None)` | |
| 16 | | Set suction power | `set_fan_speed(speed, device_name=None)` — speed ∈ {quiet, balanced, turbo, max} | |
| 17 | | Wait before re-checking status | `wait_for_seconds(seconds=5)` | |
| 18 | |
| 19 | `device_name` is optional — omit to target the first / only device. |
| 20 | |
| 21 | ## Decision tree |
| 22 | |
| 23 | User intent → tool: |
| 24 | - Status / location / battery → `get_robot_status()` |
| 25 | - Start cleaning / vacuum → `start_cleaning()` |
| 26 | - Stop / pause → `stop_cleaning()` |
| 27 | - Return to dock → `return_to_dock()` |
| 28 | - Locate / make a sound → `find_robot()` |
| 29 | - Clean a specific room → `get_room_mapping()` → `clean_specific_room(id)` |
| 30 | |
| 31 | <prerequisite> |
| 32 | For any ACTION (start/stop/return/clean_room), call `get_robot_status()` FIRST |
| 33 | to check online state. If offline → tell the user, do NOT send commands. |
| 34 | |
| 35 | For a PURE STATUS question, call `get_robot_status()` directly and return the result. |
| 36 | </prerequisite> |
| 37 | |
| 38 | <rule> |
| 39 | 1. Always call a real MCP tool — never say "I can't access" without trying. |
| 40 | 2. If `get_robot_status` raises AUTHENTICATION_REQUIRED → run the 2FA flow below. |
| 41 | 3. If the device is offline → inform the user, stop. |
| 42 | 4. Reply concisely in the user's language: "[Status] + [Action taken]". |
| 43 | </rule> |
| 44 | |
| 45 | <2fa_flow> |
| 46 | When any Roborock tool returns an AUTHENTICATION_REQUIRED error: |
| 47 | 1. Call `request_roborock_code()` — system sends a code to the Roborock account email. |
| 48 | 2. Call `gmail_search(query="from:roborock.com newer_than:1h in:anywhere", max_results=5)`. |
| 49 | - Substring match on `roborock.com` catches every subdomain (`noreply@notice-os.roborock.com`, `noreply@roborock.com`, etc.) — do NOT hard-code the full sender address. |
| 50 | - `in:anywhere` covers Spam/Promotions in case Gmail mis-classifies the OTP email. |
| 51 | - If still empty, retry once with `newer_than:6h`. |
| 52 | 3. Call `gmail_read_thread(thread_id)` on the most recent hit. |
| 53 | 4. Extract the numeric OTP from the email body. |
| 54 | 5. Call `submit_roborock_code(code=<otp>)`. |
| 55 | 6. Retry the original command. |
| 56 | |
| 57 | Never ask the user for the OTP — read it from Gmail automatically. |
| 58 | </2fa_flow> |
| 59 | |
| 60 | <violation> |
| 61 | - Saying "I can't access the robot status" without calling `get_robot_status` → VIOLATION |
| 62 | - Sending commands while the robot is offline → VIOLATION |
| 63 | - Asking the user for a 2FA code → VIOLATION (auto-read from Gmail) |
| 64 | - Inventing tool names (e.g. `get_status`, `read_gmail`) → VIOLATION; use the exact names above |
| 65 | </violation> |
| 66 | |
| 67 | ## ✅ Correct examples |
| 68 | - "What's the robot's status?" → `get_robot_status()` → "Robot is charging at the dock, battery 92%." |
| 69 | - "Vacuum the living room" → `get_robot_status()` → `get_room_mapping()` → `clean_specific_room(room_id=<living-room-id>)`. |
| 70 | - "Send it back to the dock" → `get_robot_status()` → if online `return_to_dock()` → "Robot is heading back to the dock." |
| 71 | |
| 72 | Mirror the user's language in the reply. |