Skip to main content

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.

Every aspect of the Node Agent’s behaviour is controlled by a single file: config.yaml in the project root. The file is read at startup and re-read on demand — the in-browser config editor in the dashboard writes changes directly to this file and they take effect without a restart. This page documents every section and every parameter.
Dry-run config — to test the dashboard without hardware or live cloud submissions, paste this minimal block into your config.yaml before first run. Everything in the UI works except hardware control and live data processing.
cloud:
  enabled: false

image_watcher:
  enabled: false

photometry:
  enabled: false

aavso:
  dry_run: true

cloud — Cloud Connection

The cloud section controls how the Node Agent connects to The Telescope Net cloud API, registers itself, sends heartbeats, and receives observation plans.
cloud:
  enabled: true
  url: https://api.thetelescope.net
  activation_code: 'BS-2026-XXXXXXXX'  # used once on first boot, then cleared
  api_key: ''                           # auto-populated after registration
  node_id: ''                           # auto-populated after registration
  auto_run_plans: true
  heartbeat_interval: 60
  plan_poll_interval: 300
  upload_images: false
  disconnect_park_timeout: 1800
ParameterTypeDefaultDescription
enabledbooltrueSet false to run the node entirely offline. No registration, heartbeats, or plan polling.
urlstringhttps://api.thetelescope.netBase URL of the cloud API. Change only if self-hosting the cloud server.
activation_codestring''Your BS-YYYY-XXXXXXXX Node Activation Code. Written here by the installer. Automatically cleared from the file after successful first-boot registration.
api_keystring''Auto-populated after registration. Can also be set via the ${CLOUD_NODE_API_KEY} environment variable for secrets management.
node_idstring''Auto-populated after registration. Saved to data/cloud_state.json so it survives config edits.
auto_run_plansbooltrueWhen true, new observation plans downloaded from the cloud are started automatically. Set false to require manual approval from the dashboard before any plan runs.
heartbeat_intervalint60Seconds between heartbeat POSTs to /api/v1/nodes/heartbeat. The cloud marks a node offline if no heartbeat is received within ~5 minutes.
plan_poll_intervalint300Seconds between plan polls to GET /api/v1/plan.
upload_imagesboolfalseWhen true, raw FITS files are also uploaded to POST /api/v1/images after each photometry run. Retained on the cloud for 14 days.
disconnect_park_timeoutint1800Seconds of failed heartbeats before the node parks the telescope as a safety measure. Set 0 to disable.
After the first successful registration, activation_code is automatically set to '' in config.yaml. Subsequent API calls use node_id and api_key from data/cloud_state.json. You never need to re-enter the activation code.

observatory — Location and Hardware Identity

The observatory section describes your physical setup. Coordinates are used by the scheduler to compute airmass, moon angle, and twilight times.
observatory:
  name: "Starfront Observatories, Rockwood TX"
  latitude: 31.3614    # decimal degrees N
  longitude: -99.4431  # decimal degrees E (negative = West)
  elevation: 525       # metres above sea level
  telescope: "ZWO Seestar S50"
  instrument: "ZWO Seestar S50 IMX462"
  observer: ""
ParameterTypeDefaultDescription
latitudefloatnullYour observing latitude in decimal degrees. Positive = North. Required for dawn parking and airmass calculations.
longitudefloatnullYour observing longitude in decimal degrees. Positive = East, negative = West.
elevationfloat0.0Site elevation in metres above sea level. Used for pressure-corrected airmass.
namestring''Human-readable site name shown in the dashboard and cloud node registry.
telescopestring'ZWO Seestar S50'Telescope model name. Used by the cloud to look up aperture and field-of-view parameters for scheduling.
instrumentstring'ZWO Seestar S50 IMX462'Camera/instrument description written into FITS headers.
observerstring''Your name, written into FITS headers and the cloud node registry.

photometry — Photometry Pipeline

The photometry section configures the aperture photometry pipeline that runs automatically on each new FITS file when image_watcher detects one.
photometry:
  enabled: true
  node_id: "seestar-live-001"
  filter_name: CV
  gain: 1
  read_noise: 5
  solver: astap           # astap | astrometry
  astap_path: astap
  astap_search_radius: 10
  solve_field_path: solve-field  # used when solver: astrometry
  force_plate_solve: true
  bjd_midpoint_correction: true
  aperture_factor: 1.5
  annulus_inner: 4
  annulus_outer: 6
  field_radius: 0.5
  mag_limit: 15
  mag_min: 10
  min_comparison_stars: 3
  snr_threshold: 20
  max_uncertainty: 0.3
  max_airmass: 3
  saturation_adu: 60000
  zp_scatter_warn: 0.15
  zp_scatter_max: 0.3
  pixel_scale: 2.4
  max_exposure_s: 30
  fwhm_fallback_px: 4.01
  comparison_catalogs:
    - aavso
    - apass
    - gaia
  comparison_star_file: ''
  comparison_target_count: 8
  target:
    name: ''        # leave blank to read from FITS OBJECT header
    ra_deg: null
    dec_deg: null
  fits_export:
    enabled: true
    export_dir: fits_export

Core settings

ParameterTypeDefaultDescription
enabledboolfalseSet true to run the pipeline on every new FITS file detected by the image watcher.
node_idstring''Node identifier stamped into every measurement dict and uploaded to the cloud.
filter_namestring'CV'Filter code written into photometry results and AAVSO submissions. CV = clear/visual band (standard for Seestar).
gainfloat1.0Camera gain in e⁻/ADU. Used for Poisson noise estimation in the SNR calculation.
read_noisefloat5.0Camera read noise in electrons. Combined with Poisson noise in the uncertainty budget.

Plate-solving

ParameterTypeDefaultDescription
astap_pathstring'astap'Path to the ASTAP binary. If ASTAP is not on your system PATH, set this to the full path, e.g. /usr/local/bin/astap.
astap_search_radiusint10ASTAP search radius in degrees. Increase if your Seestar’s pointing is far off (useful for initial sessions).
solverstring'astap'Plate-solver backend. 'astap' uses the bundled ASTAP binary; 'astrometry' uses Astrometry.net’s solve-field CLI.
solve_field_pathstring'solve-field'Path to the solve-field binary when solver: astrometry is selected. Ignored when using ASTAP.
force_plate_solvebooltrueAlways run the plate solver even if the FITS header already contains WCS keywords.
bjd_midpoint_correctionbooltrueCompute BJD at mid-exposure (DATE-OBS + EXPTIME/2). Set false for devices where DATE-OBS is already the mid- or end-point.
pixel_scalefloat2.4Pixel scale in arcseconds/pixel. Used by the plate solver and for aperture size calculations.

Aperture photometry

ParameterTypeDefaultDescription
aperture_factorfloat1.5Aperture radius = aperture_factor × FWHM. Larger values capture more signal but also more sky background noise.
annulus_innerfloat4.0Inner sky annulus radius in units of FWHM.
annulus_outerfloat6.0Outer sky annulus radius in units of FWHM.
fwhm_fallback_pxfloat4.01FWHM in pixels used when the automatic star-shape measurement fails.

Comparison stars and quality gates

ParameterTypeDefaultDescription
field_radiusfloat0.5Radius in degrees to search for comparison stars around the target.
mag_limitfloat15.0Faintest comparison star magnitude to include from catalogues.
mag_minfloat10.0Brightest comparison star magnitude to include (avoids saturated references).
min_comparison_starsint3Minimum comparison stars required for a valid measurement. Fewer stars than this causes the frame to be rejected.
snr_thresholdfloat20.0Minimum SNR for a good quality flag. Measurements below this threshold are marked acceptable or poor.
max_uncertaintyfloat0.3Maximum allowed photometric uncertainty in magnitudes. Results above this are flagged poor.
max_airmassfloat3.0Frames taken above this airmass are rejected — atmospheric extinction becomes unpredictable.
saturation_aduint60000ADU level treated as saturated. Saturated target pixels force quality=poor; saturated comparison stars are excluded from the zero-point ensemble.
zp_scatter_warnfloat0.15Zero-point ensemble scatter above this value blocks quality=good.
zp_scatter_maxfloat0.3Zero-point ensemble scatter above this value forces quality=poor.
comparison_catalogslist[aavso, apass, gaia]Catalogue priority order for comparison star lookup. aavso is tried first; gaia DR3 is the fallback for targets outside AAVSO VSX.
comparison_star_filestring''Path to a local JSON catalogue for offline or reproducible validation runs. Leave blank to use live catalogue queries.
comparison_target_countint8Target number of comparison stars to use in the zero-point ensemble.

Target override

ParameterTypeDefaultDescription
target.namestring''Target name. Leave blank to read from the FITS OBJECT header (standard for cloud-scheduled plans).
target.ra_degfloatnullTarget RA in decimal degrees. Leave null to read from FITS WCS.
target.dec_degfloatnullTarget Dec in decimal degrees. Leave null to read from FITS WCS.

FITS export

ParameterTypeDefaultDescription
fits_export.enabledbooltrueWrite an enhanced FITS file with photometry results embedded in the header after each measurement.
fits_export.export_dirstring'fits_export'Directory where enhanced FITS files are written (relative to the project root).

aavso — AAVSO Submission

The AAVSO section controls submission of photometry results to the American Association of Variable Star Observers via the WebObs API.
aavso:
  observer_code: "EGBA"
  username: ${AAVSO_USERNAME}
  password: ${AAVSO_PASSWORD}
  audit_dir: aavso_submissions
  dry_run: false
  submit_poor_quality: false
  submit_from_node: false
  chart_id: ''
You must set observer_code, username, and password before the node can make live AAVSO submissions. Without a valid observer code, all results are written to the audit directory but never POSTed to WebObs. Use ${AAVSO_USERNAME} and ${AAVSO_PASSWORD} environment variable references to keep credentials out of the tracked config file.
ParameterTypeDefaultDescription
observer_codestring''Your AAVSO OBSCODE (e.g. EGBA). Required for all submissions. Request one at aavso.org.
usernamestring''AAVSO login username. Required for live POST to WebObs. Accepts ${ENV_VAR} references.
passwordstring''AAVSO login password. Required for live POST. Accepts ${ENV_VAR} references.
audit_dirstring'aavso_submissions'Directory where AAVSO Extended File Format .txt files and WebObs response logs are written (one subdirectory per date).
dry_runboolfalseWhen true, the submission file is written to audit_dir but never POSTed to WebObs. Use this to validate format before going live.
submit_poor_qualityboolfalseWhen false, only good and acceptable quality measurements are submitted. poor results are written to audit but not POSTed.
submit_from_nodeboolfalseSubmit directly from the node rather than routing through the cloud data pipeline. Useful for standalone setups not connected to the cloud.
chart_idstring''Optional AAVSO chart ID to include in submissions for targets that have a standard comparison sequence.

safety — Safety Manager

The Safety Manager runs as a daemon thread that monitors telescope connectivity, parks the mount at dawn, and handles graceful shutdown on SIGTERM/SIGINT.
safety:
  enabled: true
  disconnect_timeout: 600
  heartbeat_interval: 30
  reconnect_attempts: 3
  reconnect_delay: 10
  park_at_dawn: true
  dawn_type: astronomical   # astronomical | nautical | civil
  observer:
    latitude: 31.3614
    longitude: -99.4431
ParameterTypeDefaultDescription
enabledbooltrueSet false to disable the safety watchdog entirely. Not recommended for unattended runs.
disconnect_timeoutint600Seconds of failed ALPACA heartbeats before the Safety Manager triggers an emergency park.
heartbeat_intervalint30Seconds between ALPACA ping checks (GET /connected).
reconnect_attemptsint3Number of reconnect attempts before the disconnect timer starts counting.
reconnect_delayint10Seconds between each reconnect attempt.
park_at_dawnbooltrueAutomatically park the telescope when the sun rises above the configured dawn elevation.
dawn_typestring'astronomical'Sun elevation threshold for dawn parking. astronomical = −18°, nautical = −12°, civil = −6°. At mid-latitudes in summer the sun may not reach −18° — try nautical if dawn parking never triggers.
observer.latitudefloat0.0Observer latitude for solar position calculation. Must be non-zero for dawn parking to work.
observer.longitudefloat0.0Observer longitude for solar position calculation.
Both safety.observer.latitude and safety.observer.longitude must be set to non-zero values for dawn parking to trigger. If these are left at 0.0, the Safety Manager cannot compute the sun’s elevation and dawn parking is silently skipped.

image_watcher — FITS File Monitor

The Image Watcher uses OS filesystem events (inotify on Linux, FSEvents on macOS, kqueue on BSD) to detect new FITS files written to the Seestar’s SMB share and pass them to the photometry pipeline.
image_watcher:
  enabled: true
  watch_path: /mnt/seestar
  debounce_delay: 2
ParameterTypeDefaultDescription
enabledboolfalseSet true to watch watch_path for new .fits and .fit files.
watch_pathstring'/mnt/seestar'Absolute path to the directory containing Seestar FITS output. Typically the SMB share mount point: /mnt/seestar (Linux), /Volumes/Seestar (macOS). The Node Agent attempts to auto-mount this share after connecting.
debounce_delayfloat2.0Seconds to wait after a file creation event before firing the callback. This lets partial writes finish so the pipeline receives a complete FITS file.

devices — ALPACA Device Enables

The devices section controls which ALPACA devices the Node Agent attempts to connect when you click “Connect” in the dashboard. Disable devices that are not present to suppress connection warnings.
devices:
  telescope:
    device_number: 0
    enabled: true
  camera:
    device_number: 0
    enabled: true
  focuser:
    device_number: 0
    enabled: false
  filterwheel:
    device_number: 0
    enabled: false
  covercalibrator:
    device_number: 0
    enabled: true
ParameterTypeDefaultDescription
telescope.enabledbooltrueConnect the ALPACA telescope device (slew, park, track).
camera.enabledbooltrueConnect the ALPACA camera device (expose, image download, state).
focuser.enabledboolfalseConnect the ALPACA focuser device. Required for autofocus.
filterwheel.enabledboolfalseConnect the ALPACA filter wheel device. Required for multi-band BVRI photometry.
covercalibrator.enabledbooltrueConnect the ALPACA cover calibrator (arm control on Seestar). Set false to suppress the 400 Client Error: CoverCalibrator warning if no device is configured at index 0.

alpaca — ALPACA Protocol Settings

The alpaca section controls how the Node Agent communicates with ALPACA-compatible devices on the local network, including Seestar discovery and the default server address.
alpaca:
  api_version: 1
  default_server:
    address: 172.22.6.32
    port: 32323
  discovery_port: 32227
  discovery_timeout: 5
ParameterTypeDefaultDescription
api_versionint1ALPACA API version to use. The current ASCOM ALPACA spec is version 1.
default_server.addressstring''IP address of the ALPACA device to connect to automatically. Set by the dashboard when you click “Set as default”.
default_server.portint11111Port of the default ALPACA server. Seestar typically uses 32323 when in Station Mode.
discovery_portint32227UDP port used for ALPACA discovery broadcasts. The ASCOM standard port is 32227; change only if your device uses a different port.
discovery_timeoutint5Seconds to wait for ALPACA discovery responses before giving up. Increase on slow or congested networks.

autofocus — Autofocus Sweep Defaults

Default parameters for the V-curve autofocus sweep. These are used when autofocus is triggered from the dashboard without explicit overrides.
autofocus:
  exposure_s: 2
  steps_per_side: 5
  step_size: 50
  settle_s: 1
  samples_per_point: 1
  min_position: null
  max_position: null
ParameterTypeDefaultDescription
exposure_sfloat2Exposure duration in seconds for each autofocus test frame.
steps_per_sideint5Number of focuser positions to sample on each side of centre. Total positions = 2 × steps_per_side + 1.
step_sizeint50Focuser step size (encoder counts) between test positions.
settle_sfloat1Seconds to wait after each focuser move before exposing.
samples_per_pointint1Number of frames averaged at each focuser position. Increase to reduce noise on poor seeing nights.
min_positionintnullFocuser lower bound for the sweep. null uses the device’s physical minimum.
max_positionintnullFocuser upper bound for the sweep. null uses the device’s physical maximum.

camera — Manual Exposure Defaults

Default camera settings used when triggering a manual exposure from the dashboard.
camera:
  binning: 1
  exposure_duration: 30
ParameterTypeDefaultDescription
binningint1Default binning factor for manual exposures (1 = no binning).
exposure_durationfloat30Default exposure duration in seconds for manual single exposures.

centering — Auto-Centering (Plate-Solve GoTo)

Settings for the closed-loop centering routine that plate-solves a short exposure and iteratively corrects the slew until the target is within tolerance.
centering:
  exposure_s: 3
  tolerance_arcmin: 3
  max_iterations: 4
  settle_s: 2
ParameterTypeDefaultDescription
exposure_sfloat3Exposure duration in seconds for each centering solve frame.
tolerance_arcminfloat3Acceptable pointing error in arcminutes. Centering stops when the plate-solve reports a residual below this threshold.
max_iterationsint4Maximum correction cycles before the routine gives up.
settle_sfloat2Seconds to wait after each corrective slew before taking the next centering frame.

logging — Log Format and Level

Controls the verbosity and format of the Node Agent’s log output.
logging:
  level: INFO
  format: '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
ParameterTypeDefaultDescription
levelstring'INFO'Python logging level. Options: DEBUG, INFO, WARNING, ERROR, CRITICAL. Use DEBUG when troubleshooting to see ALPACA HTTP traffic and detailed pipeline steps.
formatstring'%(asctime)s [%(levelname)s] %(name)s: %(message)s'Python logging format string for log lines written to file and the dashboard log stream.

pier_cam — Pier Camera (ZWO ASI Live Preview)

Optional ZWO ASI camera attached to the pier for a real-time sky or dome view. Requires the zwoasi Python package and the ZWO ASI SDK library.
pier_cam:
  enabled: false
  device_index: 0
  exposure_ms: 80
  gain: 200
  bin: 2
  target_fps: 10
  jpeg_quality: 75
  sdk_lib: ''
ParameterTypeDefaultDescription
enabledboolfalseSet true to start the pier camera live stream on Node Agent startup.
device_indexint0ZWO ASI device index (0 = first connected ASI camera).
exposure_msfloat80Exposure duration in milliseconds for each pier cam frame.
gainint200Camera gain. Adjust for your ambient light level.
binint2Binning factor applied to the sensor (2 = 2×2 binning). Reduces resolution but improves frame rate and SNR.
target_fpsfloat10Target frame rate for the MJPEG live stream. Actual rate is limited by exposure_ms.
jpeg_qualityint75JPEG compression quality (1–95). Lower values reduce bandwidth; higher values improve image clarity.
sdk_libstring''Path to the ZWO ASI SDK shared library (e.g. libASICamera2.so). Leave blank if the library is on the system LD_LIBRARY_PATH.

stacking — Live Sub-Frame Stacking Defaults

Default parameters for the live stacking session launched from the dashboard. Stacking co-adds sub-frames in real time using RANSAC sub-pixel alignment.
stacking:
  frames: 20
  exposure_s: 10
  preview_every: 1
ParameterTypeDefaultDescription
framesint20Number of sub-frames to stack in a live stacking session.
exposure_sfloat10Exposure duration in seconds for each sub-frame.
preview_everyint1Refresh the stacked preview image after every N frames. 1 updates on every frame; increase to reduce dashboard load on slow connections.

telescope — Telescope Slew Defaults

Default RA/Dec target and tracking rate used by the manual slew controls in the dashboard.
telescope:
  slew_ra: 23.6833
  slew_dec: 80.2692
  tracking_rate: 0
ParameterTypeDefaultDescription
slew_rafloat23.6833Default target RA in decimal hours, pre-populated in the dashboard slew form.
slew_decfloat80.2692Default target Dec in decimal degrees, pre-populated in the dashboard slew form.
tracking_rateint0Sidereal tracking rate index. 0 = sidereal. Not currently used for Seestar ALPACA (tracking is managed by the Seestar firmware).

Minimal Configuration Checklist

Before your first science run, verify these settings are filled in:
1
Observatory coordinates
2
Set observatory.latitude and observatory.longitude (decimal degrees). These are required for airmass computation, AAVSO submissions, and dawn parking.
3
AAVSO credentials
4
Set aavso.observer_code, aavso.username, and aavso.password. Consider using environment variable references (${AAVSO_PASSWORD}) to keep secrets out of the config file.
5
Image watcher path
6
Set image_watcher.watch_path to the mount point for your Seestar’s SMB share. The Node Agent will auto-mount it on macOS and Linux after connecting, but the path must exist as a mount point.
7
Cloud activation code
8
If you skipped the installer, paste your BS-YYYY-XXXXXXXX code into cloud.activation_code. It is consumed on first boot and automatically cleared.
9
Safety observer coordinates
10
Copy observatory.latitude / observatory.longitude into safety.observer.latitude / safety.observer.longitude so dawn parking works correctly.

Build docs developers (and LLMs) love