34 tools (connection, movement, signal, system, satellite, console), 5 resources, 3 prompts. Backed by DemoDevice for offline testing. 46 tests passing against the demo backend via run_server_async.
79 lines
3.6 KiB
Python
79 lines
3.6 KiB
Python
"""MCP prompts — guided workflows for common dish operations."""
|
|
|
|
|
|
def register(mcp):
|
|
"""Register MCP prompts on the FastMCP instance."""
|
|
|
|
@mcp.prompt()
|
|
async def setup_wizard() -> str:
|
|
"""Step-by-step guide to connect and initialize the satellite dish.
|
|
|
|
Walks through: check status -> connect to serial port -> verify
|
|
firmware -> home motors -> confirm position.
|
|
"""
|
|
return (
|
|
"Follow these steps to set up the satellite dish:\n\n"
|
|
"1. Call `status` to check the current connection state.\n"
|
|
"2. If not connected, call `connect` with the correct port "
|
|
"and firmware variant.\n"
|
|
"3. Call `get_firmware_id` to verify the firmware version.\n"
|
|
"4. Call `home_motor` with motor_id=0 (AZ) then motor_id=1 (EL) "
|
|
"to establish reference positions.\n"
|
|
"5. Call `get_position` to verify the dish is at the expected "
|
|
"home coordinates.\n"
|
|
"6. Call `get_el_limits` to confirm the elevation operating range.\n\n"
|
|
"The dish is now ready for tracking or manual positioning."
|
|
)
|
|
|
|
@mcp.prompt()
|
|
async def satellite_tracking_guide() -> str:
|
|
"""Guide for tracking a satellite pass with the dish.
|
|
|
|
Walks through: search -> get passes -> wait for AOS -> poll
|
|
position at 1 Hz -> move dish -> detect LOS.
|
|
"""
|
|
return (
|
|
"Follow these steps to track a satellite:\n\n"
|
|
"1. Call `search_satellites` with the satellite name "
|
|
"(e.g. 'ISS', 'NOAA 19').\n"
|
|
"2. Note the NORAD ID from the search results.\n"
|
|
"3. Call `get_passes` with the NORAD ID to see upcoming passes.\n"
|
|
"4. Choose a pass with good max elevation (>30 deg is ideal).\n"
|
|
"5. When the pass is about to start (AOS time), begin a tracking "
|
|
"loop:\n"
|
|
" a. Call `get_visible_targets` to get the satellite's current "
|
|
"AZ/EL.\n"
|
|
" b. Call `move_to` with those coordinates.\n"
|
|
" c. Wait ~1 second, then repeat from (a).\n"
|
|
"6. Stop tracking when the satellite drops below your minimum "
|
|
"elevation.\n\n"
|
|
"TIP: Enable the LNA first with `enable_lna` if you want to "
|
|
"measure signal strength during the pass."
|
|
)
|
|
|
|
@mcp.prompt()
|
|
async def rf_sweep_guide() -> str:
|
|
"""Guide for performing an RF sky sweep with the dish.
|
|
|
|
Walks through: enable LNA -> baseline RSSI -> configure sweep
|
|
-> run az_sweep -> analyze results.
|
|
"""
|
|
return (
|
|
"Follow these steps for an RF sky sweep:\n\n"
|
|
"1. Call `enable_lna` to power the low-noise amplifier.\n"
|
|
"2. Call `get_rssi` to establish a baseline noise floor.\n"
|
|
"3. Decide your sweep parameters:\n"
|
|
" - start_az: Starting azimuth\n"
|
|
" - span: How many degrees to sweep\n"
|
|
" - step_cdeg: Resolution in centidegrees (100 = 1 deg)\n"
|
|
" - num_xponders: Transponders per position (1 for basic)\n"
|
|
"4. Call `az_sweep` with those parameters.\n"
|
|
"5. Analyze the returned points:\n"
|
|
" - Look for RSSI peaks above the noise floor (~500)\n"
|
|
" - Check lock=1 points for strong signals\n"
|
|
" - SNR values indicate signal quality\n\n"
|
|
"For a 2D sky map, repeat the sweep at different elevations "
|
|
"(e.g. EL 20 to 60 in 5 deg steps) using `move_motor` to "
|
|
"set each elevation before sweeping."
|
|
)
|