mirror of
https://github.com/eddyem/small_tel.git
synced 2026-06-19 10:26:25 +03:00
add documentation
This commit is contained in:
215
Daemons/teldaemon_astrosib/Readme.md
Normal file
215
Daemons/teldaemon_astrosib/Readme.md
Normal file
@@ -0,0 +1,215 @@
|
||||
# teldaemon_astrosib
|
||||
|
||||
**teldaemon_astrosib** is a daemon that controls an [**Astrosib**](https://astrosib.ru/) telescope
|
||||
equipment via a serial line or virtual serial port over TCP. It provides a TCP/UNIX socket
|
||||
interface for clients, integrates with a
|
||||
[`weather_proxy`](https://github.com/eddyem/small_tel/tree/master/Daemons/weather_proxy) to enforce
|
||||
safety rules, and generates a FITS‑header file with current telescope status.
|
||||
|
||||
---
|
||||
|
||||
## Features
|
||||
|
||||
- **Shutter control** – open / close
|
||||
- **Focuser control** – absolute move, relative move, stop
|
||||
- **Cooler control** – switch primary mirror cooler on/off
|
||||
- **Heater control** – switch secondary mirror heater on/off
|
||||
- **Status reporting** – shutters state, focuser position, cooler/heater status, mirror and ambient
|
||||
temperatures
|
||||
- **Weather integration** – automatically closes shutters and prevents opening when weather is bad
|
||||
or data is stale
|
||||
- **Manual override** – via `SIGUSR1` (forbid) / `SIGUSR2` (allow) signals
|
||||
- **FITS header file** – writes current telescope state into a FITS‑style header file (e.g., for
|
||||
later use by image processing pipelines)
|
||||
- **Network interface** – supports both INET (TCP) and UNIX domain sockets
|
||||
- **Daemon mode** – forks, writes PID file, restarts child on crash
|
||||
|
||||
---
|
||||
|
||||
## Command‑line options
|
||||
|
||||
| Option | Argument | Default | Description |
|
||||
|----------------------|-------------------|-----------------------------|-----------------------------------------------------------------------------|
|
||||
| `-h`, `--help` | – | – | Show help |
|
||||
| `-v`, `--verbose` | – | 0 | Increase verbosity (each `-v` adds 1 level) |
|
||||
| `-l`, `--logfile` | *path* | – | Full path to log file (otherwise stderr) |
|
||||
| `-n`, `--node` | *string* | – | Node specification: IP, `name:IP`, or path for UNIX socket. For anonymous UNIX socket use `\0path` or `@path`. |
|
||||
| `-u`, `--unixsock` | – | 0 | Use UNIX socket instead of INET |
|
||||
| `-m`, `--maxclients` | *number* | 2 | Maximum number of simultaneously connected clients |
|
||||
| `-p`, `--pidfile` | *path* | `/tmp/teldaemon.pid` | PID file path |
|
||||
| `-d`, `--serialdev` | *path* | – | Full path to serial device (e.g. `/dev/ttyUSB0`) |
|
||||
| `-b`, `--baudrate` | *speed* | 9600 | Serial baud rate |
|
||||
| `-t`, `--sertmout` | *microseconds* | 1000000 (1 sec) | Serial read timeout (µs) |
|
||||
| `-H`, `--headerfile` | *path* | `/tmp/telescope.fits` | Output file for FITS‑style header |
|
||||
| `-N`, `--telname` | *name* | `Astro-M (1)` | Telescope name inserted into the header |
|
||||
| `-M`, `--headermask` | *bitmask* | `0xff` (all bits set) | Mask controlling which information appears in the header. Use `-1` to list bits. |
|
||||
|
||||
### Header mask bits (used with `-M`)
|
||||
|
||||
| Bit | Description |
|
||||
|-----|--------------------------|
|
||||
| 0 | telescope name |
|
||||
| 1 | focuser status |
|
||||
| 2 | cooler status |
|
||||
| 3 | heater status |
|
||||
| 4 | external temperature |
|
||||
| 5 | mirror temperature |
|
||||
| 6 | measurement time |
|
||||
|
||||
For example, if you are using an external focuser and want to prevent the possibility of its data
|
||||
being overwritten by the telescope data, use a mask `-M125` (alternatively: `-M0x7D` or `-M0b1111101`).
|
||||
|
||||
---
|
||||
|
||||
## Socket protocol
|
||||
|
||||
The daemon listens for text‑based commands on the configured socket. Each command returns one or
|
||||
more lines of output, terminated by newline (`\n`).
|
||||
|
||||
### Commands
|
||||
|
||||
| Command | Description | Example |
|
||||
|---------------------------------|-----------------------------------------------------------------------------|-----------------------------------|
|
||||
| `focrel <steps>` | Move focuser relatively (negative = inward, positive = outward) | `focrel = -500` |
|
||||
| `focabs <position>` | Move focuser to absolute position (0 … 65000) | `focabs = 32000` |
|
||||
| `focpos` | Get current focuser position | `focpos` → `focpos=12345` |
|
||||
| `open` | Open shutters (only if weather permits and observations not forbidden) | `open` |
|
||||
| `close` | Close shutters | `close` |
|
||||
| `status` | Get shutters state, temperatures, last error, and safety flags | `status` → (see example below) |
|
||||
| `focstop` | Immediately stop focuser movement | `focstop` |
|
||||
| `cooler <0/1>` | Switch primary mirror cooler off (0) or on (1) | `cooler = 1` |
|
||||
| `heater <0/1>` | Switch secondary mirror heater off (0) or on (1) | `heater = 0` |
|
||||
| `dtime` | Return server’s current UNIX time (seconds with milliseconds) | `dtime` → `UNIXT=1704067200.123` |
|
||||
| `help` | Show available commands (default handler) | `help` |
|
||||
|
||||
Each setter returns an `OK` answer in case of success or error code like `BADVAL` for bad value of setter.
|
||||
|
||||
### Example `status` response
|
||||
|
||||
```
|
||||
status=closed
|
||||
measuret=1779086249.480
|
||||
mirrortemp=6.2
|
||||
ambienttemp=6.3
|
||||
```
|
||||
|
||||
- `status` can be `opened`, `closed`, `intermediate` or `unknown`.
|
||||
- `measuret` is the time when the status was last read from the hardware.
|
||||
- `errored_command` appears if the last attempted command failed.
|
||||
- `FORBIDDEN` appears when observations have been manually disabled (`SIGUSR1`).
|
||||
- `BADWEATHER` appears when weather proxy reports unsafe conditions.
|
||||
|
||||
---
|
||||
|
||||
## Weather integration
|
||||
|
||||
The daemon retrieves weather data via the **weather_proxy** shared memory interface (`get_weather_data()`).
|
||||
Safety rules:
|
||||
|
||||
- If `weather.forceoff`, `weather.rain`, or `weather.weather > WEATHER_TERRIBLE` → shutters are closed and opening is blocked.
|
||||
- If the weather data is older than **900 seconds** (`WEATHER_LOST`) → treated as lost communication → shutters are closed and blocked.
|
||||
- When weather becomes good again, the daemon automatically resets the `BADWEATHER` flag and allows normal operation.
|
||||
|
||||
---
|
||||
|
||||
## Signal handling
|
||||
|
||||
| Signal | Effect (in child process) |
|
||||
|----------|------------------------------------------------------|
|
||||
| `SIGUSR1`| Forbid observations – close shutters and block open |
|
||||
| `SIGUSR2`| Allow observations – remove manual block |
|
||||
| `SIGTERM`| Stop the daemon and remove PID file |
|
||||
| `SIGINT` | Same as `SIGTERM` |
|
||||
|
||||
---
|
||||
|
||||
## FITS header file
|
||||
|
||||
The daemon writes a text file (default `/tmp/telescope.fits`) with **FITS‑like** keyword/value
|
||||
pairs. The file is updated every polling cycle (every 2 seconds) and can be used by external
|
||||
pipelines to record telescope state.
|
||||
|
||||
Example content:
|
||||
|
||||
```
|
||||
TELESCOP= 'Astro-M (1)' / Telescope name
|
||||
TELSTAT = 'closed' / Telescope shutters' status
|
||||
TELCOOLR= 0 / Primary mirror cooler status: 0/1 (off/on)
|
||||
TELHEATR= 0 / Secondary mirror heater status: 0/1 (off/on)
|
||||
TDOME = 6.3 / In-dome temperature, degC
|
||||
TMIRROR = 6.0 / Mirror temperature, degC
|
||||
TTELMEAS= 1779086301.494 / Measurement time: 2026-05-18 09:38:21
|
||||
```
|
||||
|
||||
The file is created atomically using `mkstemp()` + `rename()`.
|
||||
|
||||
---
|
||||
|
||||
## Building and dependencies
|
||||
|
||||
### Dependencies
|
||||
|
||||
- [libusefull_macros](https://github.com/eddyem/snippets_library) – common macros and helpers
|
||||
- [libweather_proxy](https://github.com/eddyem/weather_proxy) – shared memory weather data
|
||||
- `pthread`, `libc`
|
||||
|
||||
### Build
|
||||
|
||||
```bash
|
||||
git clone --depth=1 https://github.com/eddyem/small_tel.git
|
||||
cd small_tel/Daemons/teldaemon_astrosib
|
||||
make
|
||||
```
|
||||
|
||||
The resulting binary is `teldaemon_astrosib`.
|
||||
|
||||
### Installation
|
||||
|
||||
Copy the binary to a suitable location (e.g. `/usr/local/bin`).
|
||||
It is recommended to run the daemon as a system service (using init script, e.g. in `/etc/local.d/`)
|
||||
so that it starts automatically at boot.
|
||||
|
||||
---
|
||||
|
||||
## Usage example
|
||||
|
||||
Start the daemon with a UNIX socket and weather‑aware header:
|
||||
|
||||
```bash
|
||||
teldaemon_astrosib -u -n "/var/run/teldaemon.sock" \
|
||||
-d /dev/ttyUSB0 -b 115200 \
|
||||
-H /var/state/telescope.fits \
|
||||
-N "Astrosib-500" -M 0x7f
|
||||
```
|
||||
|
||||
Connect to the socket using `socat`, `nc` or my [`tty_term`](https://github.com/eddyem/tty_term):
|
||||
|
||||
```bash
|
||||
socat UNIX-CONNECT:/var/run/teldaemon.sock -
|
||||
> status
|
||||
```
|
||||
|
||||
Send `SIGUSR1` to forbid observations (e.g. before maintenance):
|
||||
|
||||
```bash
|
||||
kill -USR1 $(cat /tmp/teldaemon.pid)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- The serial protocol is specific to Astrosib hardware (commands like `FOCUSERGO?`,
|
||||
`SHUTTEROPEN?1,1,1,1,1`, etc. are hard‑coded).
|
||||
- Focuser absolute position range is **0 … 65000** (values outside this range are ignored).
|
||||
- The daemon polls the telescope every **2 seconds** (`T_INTERVAL`). During that interval it also
|
||||
processes client requests and checks weather.
|
||||
- If the serial device becomes unresponsive, the status will show `unknown` and the header will not
|
||||
be updated.
|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
**GNU General Public License v3.0** or later.
|
||||
See the `LICENSE` file in repository's root directory or <http://www.gnu.org/licenses/> for details.
|
||||
Reference in New Issue
Block a user