# thoclabs/nightwatch architecture

> Architecture diagram of the GitHub repository thoclabs/nightwatch, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-28). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/thoclabs/nightwatch
- Repository: https://github.com/thoclabs/nightwatch
- Video tour (about a minute): https://gitdiagram.com/thoclabs/nightwatch/video

## Overview

NIGHTWATCH is a locally controlled, voice-operated autonomous observatory. The principal workflow turns spoken requests into telescope actions or spoken answers: voice input is processed by the pipeline and local-first LLM, tool calls are executed through the orchestrator, and results are formatted for speech. Observatory capabilities also cover safety and weather, telescope operation and imaging, observing support, meteor monitoring, and resilience. The README documents these capabilities; sampled source supports several integrations, while unsampled service wiring is not inferred.

Main entry points: [`nightwatch/orchestrator.py`](https://github.com/thoclabs/nightwatch/blob/main/nightwatch/orchestrator.py) (Orchestrator), [`nightwatch/voice_pipeline.py`](https://github.com/thoclabs/nightwatch/blob/main/nightwatch/voice_pipeline.py) (Voice pipeline), [`services/safety_monitor/monitor.py`](https://github.com/thoclabs/nightwatch/blob/main/services/safety_monitor/monitor.py) (Safety monitor), [`services/mount_control/lx200.py`](https://github.com/thoclabs/nightwatch/blob/main/services/mount_control/lx200.py) (Mount control)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_voice["Voice interaction"]
  node_voice_pipeline["Voice pipeline<br/>[voice_pipeline.py]"]
  node_speech_recognition["Whisper STT<br/>[whisper_service.py]"]
  node_speech_synthesis["Piper TTS<br/>[piper_service.py]"]
  node_llm["LLM client<br/>[llm_client.py]"]
  node_voice_tools["Voice tools<br/>[telescope_tools.py]"]
end

subgraph group_control["Command and safety"]
  node_orchestrator["Orchestrator<br/>[orchestrator.py]"]
  node_tool_executor["Tool executor<br/>[tool_executor.py]"]
  node_safety["Safety monitor<br/>[monitor.py]"]
  node_interlock["Safety interlock"]
  node_weather["Weather monitoring<br/>[unified.py]"]
  node_roof["Roof controller<br/>[roof_controller.py]"]
end

subgraph group_observatory["Observatory devices"]
  node_mount["Mount control<br/>[lx200.py]"]
  node_camera["Camera and analysis<br/>[frame_analyzer.py]"]
  node_focus["Focuser<br/>[focuser_service.py]"]
  node_guiding["PHD2 guiding<br/>[phd2_client.py]"]
end

subgraph group_observing["Observing support"]
  node_ephemeris["Ephemeris"]
  node_catalog["Target catalog<br/>[catalog.py]"]
  node_scheduler["Observing scheduler<br/>[scheduler.py]"]
  node_meteor["Meteor monitoring<br/>[meteor_service.py]"]
end

subgraph group_resilience["Operations and alerts"]
  node_alerts["Alerts<br/>[alert_manager.py]"]
  node_power["Power manager<br/>[power_manager.py]"]
end

node_operator(("Observer"))
node_onstepx["OnStepX controller<br/>[Config.h]"]
node_phd2["PHD2 service"]
node_local_audio["Audio device"]
node_weather_station["Weather hardware"]

node_operator -->|"speaks to"| node_voice_pipeline
node_voice_pipeline -->|"transcribes with"| node_speech_recognition
node_voice_pipeline -->|"submits request"| node_llm
node_llm -->|"returns tool calls"| node_voice_pipeline
node_voice_pipeline -->|"executes calls"| node_tool_executor
node_tool_executor -->|"dispatches commands"| node_orchestrator
node_orchestrator -->|"checks safety"| node_safety
node_safety -->|"reads conditions"| node_weather
node_orchestrator -->|"controls mount"| node_mount
node_mount -->|"controls"| node_onstepx
node_orchestrator -->|"controls enclosure"| node_roof
node_roof -->|"checks conditions"| node_weather
node_roof -->|"checks park state"| node_mount
node_orchestrator -->|"requests imaging"| node_camera
node_orchestrator -->|"controls focus"| node_focus
node_focus -->|"measures focus"| node_camera
node_orchestrator -->|"controls guiding"| node_guiding
node_guiding -->|"uses socket service"| node_phd2
node_orchestrator -->|"requests schedule"| node_scheduler
node_scheduler -.->|"uses targets"| node_catalog
node_scheduler -.->|"uses sky data"| node_ephemeris
node_orchestrator -->|"manages watches"| node_meteor
node_meteor -.->|"sends notifications"| node_alerts
node_safety -->|"applies safeguards"| node_interlock
node_safety -.->|"raises alerts"| node_alerts
node_power -.->|"supports safe shutdown"| node_mount
node_weather_station -->|"provides readings"| node_weather
node_voice_pipeline -->|"synthesizes response"| node_speech_synthesis
node_speech_synthesis -->|"plays audio"| node_local_audio

click node_voice_pipeline "https://github.com/thoclabs/nightwatch/blob/main/nightwatch/voice_pipeline.py"
click node_speech_recognition "https://github.com/thoclabs/nightwatch/blob/main/voice/stt/whisper_service.py"
click node_speech_synthesis "https://github.com/thoclabs/nightwatch/blob/main/voice/tts/piper_service.py"
click node_llm "https://github.com/thoclabs/nightwatch/blob/main/nightwatch/llm_client.py"
click node_voice_tools "https://github.com/thoclabs/nightwatch/blob/main/voice/tools/telescope_tools.py"
click node_orchestrator "https://github.com/thoclabs/nightwatch/blob/main/nightwatch/orchestrator.py"
click node_tool_executor "https://github.com/thoclabs/nightwatch/blob/main/nightwatch/tool_executor.py"
click node_safety "https://github.com/thoclabs/nightwatch/blob/main/services/safety_monitor/monitor.py"
click node_interlock "https://github.com/thoclabs/nightwatch/blob/main/nightwatch/safety_interlock.py"
click node_weather "https://github.com/thoclabs/nightwatch/blob/main/services/weather/unified.py"
click node_roof "https://github.com/thoclabs/nightwatch/blob/main/services/enclosure/roof_controller.py"
click node_mount "https://github.com/thoclabs/nightwatch/blob/main/services/mount_control/lx200.py"
click node_camera "https://github.com/thoclabs/nightwatch/blob/main/services/camera/frame_analyzer.py"
click node_focus "https://github.com/thoclabs/nightwatch/blob/main/services/focus/focuser_service.py"
click node_guiding "https://github.com/thoclabs/nightwatch/blob/main/services/guiding/phd2_client.py"
click node_ephemeris "https://github.com/thoclabs/nightwatch/blob/main/services/ephemeris/skyfield_service.py"
click node_catalog "https://github.com/thoclabs/nightwatch/blob/main/services/catalog/catalog.py"
click node_scheduler "https://github.com/thoclabs/nightwatch/blob/main/services/scheduling/scheduler.py"
click node_meteor "https://github.com/thoclabs/nightwatch/blob/main/services/meteor_tracking/meteor_service.py"
click node_alerts "https://github.com/thoclabs/nightwatch/blob/main/services/alerts/alert_manager.py"
click node_power "https://github.com/thoclabs/nightwatch/blob/main/services/power/power_manager.py"
click node_onstepx "https://github.com/thoclabs/nightwatch/blob/main/firmware/onstepx_config/Config.h"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_voice_pipeline,node_speech_recognition,node_speech_synthesis,node_llm,node_voice_tools toneBlue
class node_orchestrator,node_tool_executor,node_safety,node_interlock,node_weather,node_roof toneAmber
class node_mount,node_camera,node_focus,node_guiding,node_operator toneMint
class node_ephemeris,node_catalog,node_scheduler,node_meteor toneRose
class node_alerts,node_power,node_phd2,node_local_audio,node_weather_station toneIndigo
class node_onstepx toneTeal
```

## Components

### Voice interaction

- [Voice pipeline](https://github.com/thoclabs/nightwatch/blob/main/nightwatch/voice_pipeline.py): `nightwatch/voice_pipeline.py`
- [Whisper STT](https://github.com/thoclabs/nightwatch/blob/main/voice/stt/whisper_service.py): `voice/stt/whisper_service.py`
- [Piper TTS](https://github.com/thoclabs/nightwatch/blob/main/voice/tts/piper_service.py): `voice/tts/piper_service.py`
- [LLM client](https://github.com/thoclabs/nightwatch/blob/main/nightwatch/llm_client.py): `nightwatch/llm_client.py`
- [Voice tools](https://github.com/thoclabs/nightwatch/blob/main/voice/tools/telescope_tools.py): `voice/tools/telescope_tools.py`

### Command and safety

- [Orchestrator](https://github.com/thoclabs/nightwatch/blob/main/nightwatch/orchestrator.py): `nightwatch/orchestrator.py`
- [Tool executor](https://github.com/thoclabs/nightwatch/blob/main/nightwatch/tool_executor.py): `nightwatch/tool_executor.py`
- [Safety monitor](https://github.com/thoclabs/nightwatch/blob/main/services/safety_monitor/monitor.py): `services/safety_monitor/monitor.py`
- [Safety interlock](https://github.com/thoclabs/nightwatch/blob/main/nightwatch/safety_interlock.py): `nightwatch/safety_interlock.py`
- [Weather monitoring](https://github.com/thoclabs/nightwatch/blob/main/services/weather/unified.py): `services/weather/unified.py`
- [Roof controller](https://github.com/thoclabs/nightwatch/blob/main/services/enclosure/roof_controller.py): `services/enclosure/roof_controller.py`

### Observatory devices

- [Mount control](https://github.com/thoclabs/nightwatch/blob/main/services/mount_control/lx200.py): `services/mount_control/lx200.py`
- [Camera and analysis](https://github.com/thoclabs/nightwatch/blob/main/services/camera/frame_analyzer.py): `services/camera/frame_analyzer.py`
- [Focuser](https://github.com/thoclabs/nightwatch/blob/main/services/focus/focuser_service.py): `services/focus/focuser_service.py`
- [PHD2 guiding](https://github.com/thoclabs/nightwatch/blob/main/services/guiding/phd2_client.py): `services/guiding/phd2_client.py`

### Observing support

- [Ephemeris](https://github.com/thoclabs/nightwatch/blob/main/services/ephemeris/skyfield_service.py): `services/ephemeris/skyfield_service.py`
- [Target catalog](https://github.com/thoclabs/nightwatch/blob/main/services/catalog/catalog.py): `services/catalog/catalog.py`
- [Observing scheduler](https://github.com/thoclabs/nightwatch/blob/main/services/scheduling/scheduler.py): `services/scheduling/scheduler.py`
- [Meteor monitoring](https://github.com/thoclabs/nightwatch/blob/main/services/meteor_tracking/meteor_service.py): `services/meteor_tracking/meteor_service.py`

### Operations and alerts

- [Alerts](https://github.com/thoclabs/nightwatch/blob/main/services/alerts/alert_manager.py): `services/alerts/alert_manager.py`
- [Power manager](https://github.com/thoclabs/nightwatch/blob/main/services/power/power_manager.py): `services/power/power_manager.py`

### Other components

- **Observer**
- [OnStepX controller](https://github.com/thoclabs/nightwatch/blob/main/firmware/onstepx_config/Config.h): `firmware/onstepx_config/Config.h`
- **PHD2 service**
- **Audio device**
- **Weather hardware**

## Connections

- Observer → Voice pipeline: speaks to
- Voice pipeline → Whisper STT: transcribes with
- Voice pipeline → LLM client: submits request
- LLM client → Voice pipeline: returns tool calls
- Voice pipeline → Tool executor: executes calls
- Tool executor → Orchestrator: dispatches commands
- Orchestrator → Safety monitor: checks safety
- Safety monitor → Weather monitoring: reads conditions
- Orchestrator → Mount control: controls mount
- Mount control → OnStepX controller: controls
- Orchestrator → Roof controller: controls enclosure
- Roof controller → Weather monitoring: checks conditions
- Roof controller → Mount control: checks park state
- Orchestrator → Camera and analysis: requests imaging
- Orchestrator → Focuser: controls focus
- Focuser → Camera and analysis: measures focus
- Orchestrator → PHD2 guiding: controls guiding
- PHD2 guiding → PHD2 service: uses socket service
- Orchestrator → Observing scheduler: requests schedule
- Observing scheduler → Target catalog: uses targets
- Observing scheduler → Ephemeris: uses sky data
- Orchestrator → Meteor monitoring: manages watches
- Meteor monitoring → Alerts: sends notifications
- Safety monitor → Safety interlock: applies safeguards
- Safety monitor → Alerts: raises alerts
- Power manager → Mount control: supports safe shutdown
- Weather hardware → Weather monitoring: provides readings
- Voice pipeline → Piper TTS: synthesizes response
- Piper TTS → Audio device: plays audio
