Starting the Node Agent for the first time is more than just launching software — it is the moment your telescope joins The Telescope Net. This page walks you through what happens during that first boot: how your activation code becomes a permanent node identity, how your Seestar is discovered on the local network, and how to confirm everything is working before you leave the setup unattended overnight.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/ManiFed/TTN/llms.txt
Use this file to discover all available pages before exploring further.
What Happens on First Boot
When the Node Agent starts with a validactivation_code in config.yaml and no existing credentials in data/cloud_state.json, it goes through a one-time registration sequence:
ALPACA Device Discovery
After registration, the Node Agent searches for your Seestar on the local network using the ALPACA discovery protocol:- Sends a UDP broadcast on port
32227(configurable viaalpaca.discovery_port) - Waits for Alpaca-compatible devices to respond — timeout: 5 seconds (configurable via
alpaca.discovery_timeout) - Any Seestar in Station Mode on the same subnet replies with its IP address and port
Your Seestar must be in Station Mode (connected to your home WiFi) for
discovery to work. In Access Point mode the ALPACA HTTP service is not
active, and the Node Agent will refuse the connection with:
Seestar is in Access Point (hotspot) mode — ALPACA is not active.- macOS:
mount_smbfs -N //guest:@<host>/seestar /Volumes/Seestar - Linux:
mount -t cifs //<host>/seestar /mnt/seestar -o guest,uid=0,gid=0
- Verify the Seestar is powered on and shows a local IP in the Seestar app
- Both the host machine and Seestar must be on the same subnet (no VLANs between them)
- Some routers block UDP broadcast — test with
tcpdump -i en0 udp port 32227 - macOS may require allowing Python in System Preferences → Privacy & Security
Dashboard Overview
The local dashboard runs at http://localhost:5173 and is served by the Flask app insrc/dashboard.py. It is the primary interface for monitoring and manually controlling your node.
The dashboard’s main sections:
| Section | What it shows |
|---|---|
| Status bar | Cloud registration state, last heartbeat timestamp, safety manager state, sun elevation |
| Telescope | Live RA/Dec, slew/park/unpark/tracking controls, arm state |
| Camera | Exposure controls, image preview, frame history with thumbnails |
| Schedule | Current plan from the cloud, per-target progress, start/cancel controls |
| Photometry | Last measurement (target, magnitude, uncertainty, SNR, quality flag), rolling session history |
| Config | In-browser YAML editor — edits write to config.yaml directly |
| Logs | Live log stream via Server-Sent Events, colour-coded by level |
Dev Mode vs. Production Mode
How you launch the Node Agent depends on your use case:- Dev Mode
- Production Mode
main.py is a watchdog process that monitors src/dashboard.py for file
changes and automatically restarts it. This is convenient when developing
or debugging — save a file and the server restarts within a second.Not recommended for unattended overnight runs — if the file watcher
itself crashes, the node stops until you restart it manually.Verifying Cloud Registration
After the first boot you should confirm that your node is registered and actively communicating with the cloud.In dev mode, watch the terminal. In production, follow the service logs
(see Installation for platform commands).
Cloud communicator started → https://api.thetelescope.net
Registered with cloud as node_a3f9b2c1
Activation code cleared from config after successful registration
Open http://localhost:5173 and navigate to the cloud
status panel. You should see:
node_a3f9b2c1curl https://api.thetelescope.net/api/v1/nodes/me \
-H "X-Node-Id: node_a3f9b2c1" \
-H "X-Api-Key: <your_api_key>"
A successful response returns your full node registry entry including
performance metrics, scheduler hints, and reliability score.
Heartbeat Loop
Everycloud.heartbeat_interval seconds (default: 60 seconds), the
CloudCommunicator sends a POST /api/v1/nodes/heartbeat with an optional
conditions snapshot:
- Mark the node online (visible in the member app and network status page)
- Record the latest conditions snapshot to
nodes.last_conditions - Update
utc_offset_hoursfor accurate twilight calculations
Plan Polling
Everycloud.plan_poll_interval seconds (default: 300 seconds), the plan
poller calls GET /api/v1/plan. If the cloud returns a plan with a new
plan_id, the node:
- Validates all observation items (RA/Dec bounds, exposure limits, etc.)
- If
auto_run_plansistrue— starts the schedule runner immediately in a background thread - If
auto_run_plansisfalse— stores the plan as pending and logs a warning; you must start it manually from the dashboard
ObservationPlan containing a list of PlanItem objects:
GET /api/v1/interrupts. Interrupts bypass the plan queue and, if
time_critical, immediately cancel any running schedule to observe the alert
target first.
SafetyManager Behaviour
TheSafetyManager runs as a daemon thread from the moment the Node Agent
starts. It operates independently of the Flask routes so it can park the
telescope even if the dashboard is unresponsive.
Key behaviours:
| Trigger | Action |
|---|---|
| ALPACA heartbeat fails | Attempt reconnect (reconnect_attempts × reconnect_delay) |
Reconnect fails; disconnect_timeout exceeded | Emergency park + disconnect |
Sun elevation > dawn_elevation | Emergency park (routine dawn stop) |
SIGTERM received (service stop) | Park telescope, then exit |
SIGINT received (Ctrl+C in dev mode) | Park telescope, then raise KeyboardInterrupt |
Cloud heartbeat fails > disconnect_park_timeout seconds | Emergency park via cloud disconnect monitor |
Activation Code Flow (Summary)
Verification Checklist
Use these steps to confirm your node is fully operational before your first unattended night:The line
Registered with cloud as node_XXXXXXXX confirms one-time
registration succeeded and credentials are persisted.Both devices show
Connected: ✓ in the dashboard status panel. You should
see live RA/Dec updating in the telescope section.The image watcher section shows
Enabled: ✓ with the correct watch_path
(your Seestar’s SMB share mount point). Take a manual exposure from the
Seestar app — within a few seconds the dashboard should show the FITS file
detected and a photometry result.If you have set
aavso.dry_run: true, check aavso_submissions/ for the
generated .txt file. Confirm the observer code, target name, and magnitude
format look correct. Then set dry_run: false for live submissions.