add documentation

This commit is contained in:
2026-05-18 11:50:36 +03:00
parent 75aafabc54
commit 7ca5498092
16 changed files with 928 additions and 40 deletions

View File

@@ -4,15 +4,11 @@ Different daemons & tools
- *10micron_stellarium* - simple daemon for 10-micron mount management from stellarium interface
- *astrosib* - some scripts used during observations
- *deprecated* - deprecated code
- *domedaemon-astrosib* - deprecated astrosib daemon
- *domedaemon_baader* - open/close Baaden dome by network query
- *domedaemon-astrosib* - open/close Astrosib dome by network query
- *netdaemon* - template for net-daemons
- *domedaemon-astrosib* - daemon for "Astrosib" all-sky dome management
- *domedaemon_baader* - daemon for "Baader Planetarium" all-sky dome management
- *netsocket* - scripts for management of network 220V-socket
- *send_coordinates* - get/send coordinates to 10-micron mount through stellarium daemon (almost deprecated)
- *teldaemon_astrosib* - open/close Astrosib-500 scope covers by network query
- *weatherdaemon* - weather daemon for old meteostation (almost deprecated)
- *weatherdaemon_multimeteo* - (pre-developed) version of weather daemon for ALL sensors on "Astro-M" complex
- *weatherdaemon_newmeteo* - daemon for new (chinese) meteostation (almost deprecated)
- *teldaemon_astrosib* - work with Astrosib-500 scope equipment by network query
- *weatherdaemon_multimeteo* - weather daemon for ALL meteo sensors on "Astro-M" complex
- *weather_database* - make database by data of almost deprecated weather daemons
- *weather_proxy* - (pre-developed) daemon gathering meteo data and sharing it on localhost over SHM
- *weather_proxy* - daemon gathering meteo data from `weatherdaemon_multimeteo` and sharing it on localhost over SHM

View File

@@ -0,0 +1 @@
Deprecated (old versions) of daemons; marked for further removal.

View File

@@ -1,5 +1,204 @@
New version of "Astrosib" dome daemon.
# domedaemonastrosib
Based on snippets_library ver. >= 0.3.2
Allow more functionality than old one.
**domedaemonastrosib** is a daemon that controls an [**Astrosib**](https://astrosib.ru/) allsky
dome via a serial line. It provides a TCP/UNIX socket interface for clients, integrates with a
weather proxy to enforce safety rules, and generates a FITSstyle header file with current dome
status.
---
## Features
- **Dome open/close** fully open or close the dome
- **Stop movement** immediately stop any ongoing dome motion
- **Independent cover control** open or close only the northern or southern cover
- **Relay control** switch three auxiliary relays (power, light, etc.)
- **Status reporting** cover states, encoder angles, relay states, rain sensor, motor currents,
temperatures
- **Weather integration** automatically closes the dome and prevents opening when weather is bad
or data is stale
- **Manual override** via `SIGUSR1` (forbid) / `SIGUSR2` (allow) signals
- **FITS header file** writes current dome state into a FITSstyle 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
---
## Commandline options
| Option | Argument | Default | Description |
|----------------------|-------------------|-----------------------------------|-------------------------------------------------------------------|
| `-h`, `--help` | | | Show help |
| `-d`, `--device` | *path* | | Full path to serial device (e.g. `/dev/ttyUSB0`) |
| `-n`, `--node` | *string* | `55555` | Node specification: port number for TCP, or path for UNIX socket |
| `-l`, `--logfile` | *path* | | Full path to log file |
| `-u`, `--unix` | | 0 | Use UNIX socket instead of TCP |
| `-v`, `--verbose` | | 0 | Increase verbosity (each `-v` adds 1 level) |
| `-p`, `--pidfile` | *path* | `/tmp/domedaemon.pid` | PID file path |
| `-H`, `--headerfile` | *path* | `/tmp/dome.fits` | Output file for FITSstyle header |
| `-N`, `--domename` | *name* | `Astrosib` | Dome name inserted into the header |
---
## Socket protocol
The daemon listens for textbased commands on the configured socket. Each command returns one or
more lines of output, terminated by newline (`\n`).
### Commands
| Command | Description | Example |
|---------------------------------|----------------------------------------------------------------------------|----------------------------------------------|
| `unixt` | Return servers current UNIX time (seconds with two decimal places) | `unixt``unixt=1704067200.12` |
| `status` | Get dome status in old format (four numbers) | `status``status=3,3,0,0` |
| `statust` | Get dome status in humanreadable format | `statust` → (see example below) |
| `relay1``relay3` | Get/set relay state (0 = off, 1 = on) | `relay1``relay1=1` (if queried without argument) |
| `open` | Fully open dome (only if weather permits and observations not forbidden) | `open` |
| `close` | Fully close dome | `close` |
| `stop` | Immediately stop dome movement | `stop` |
| `half1``half2` | Get/set state of a single cover (0 = closed, 1 = opened) | `half1 0` |
Each setter returns an `OK` answer in case of success or error code like `BADVAL` for bad value of
setter.
### Example `statust` response
```
status=3,3,0,0
operations=permitted
cover1=closed
cover2=closed
angle1=0
angle2=0
relay1=0
relay2=0
relay3=0
reqtime=1779087731.049449921
```
- `operations` can be `permitted` or `forbidden` (manual override).
- `cover1` / `cover2` report `closed`, `opened` or `intermediate`.
- `angle1` / `angle2` are encoder values (degrees).
- `relay1``relay3` show the current state of each relay.
- `reqtime` is the time when the status was last read from the hardware.
---
## 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_BAD` → dome is closed and opening is blocked.
- If the weather data is older than **300 seconds** (`WEATHER_LOST`) → treated as lost communication → dome is closed and blocked.
- When weather becomes good again, the daemon automatically resets the `BadWeather` flag and allows normal operation.
The weather is polled every **5 seconds** (`WEATH_POLL`).
---
## Signal handling
| Signal | Effect (in child process) |
|----------|------------------------------------------------------|
| `SIGUSR1`| Forbid observations close dome and block open |
| `SIGUSR2`| Allow observations remove manual block |
| `SIGTERM`| Stop the daemon and remove PID file |
| `SIGINT` | Same as `SIGTERM` |
| `SIGHUP` | Same as `SIGTERM` |
---
## FITS header file
The daemon writes a text file (default `/tmp/dome.fits`) with **FITSlike** keyword/value pairs.
The file is updated every polling cycle (every 5 seconds) and can be used by external pipelines to record dome state.
Example content:
```
DOME = 'Astrosib' / Dome manufacturer/name
DOMESTAT= 'idle' / Dome status
DOMECVR1= 'closed' / Dome cover 1 status
DOMECVR2= 'closed' / Dome cover 2 status
DOMEANG1= 0 / Dome cover 1 angle
DOMEANG2= 0 / Dome cover 2 angle
DOMERLY1= 0 / Dome relay1 state
DOMERLY2= 0 / Dome relay2 state
DOMERLY3= 0 / Dome relay3 state
TDOMMEAS= 1779090474.704 / Measurement time: 2026-05-18 10:47:54
```
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/small_tel/tree/master/Daemons/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/domedaemon-astrosib
mkdir build
cd build
cmake ..
make
```
The resulting binary is `domedaemon`.
### Installation
Copy the binary to a suitable location (e.g. `/usr/local/bin`) or run `sudo make install`.
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 weatheraware header:
```bash
domedaemon -vv -d /dev/ttyS3 -l /var/log/telescope/domedaemon.log
```
Connect to the socket using `socat`, `nc` or my [`tty_term`](https://github.com/eddyem/tty_term):
```bash
nc localhost 55555
> statust
```
Send `SIGUSR1` to forbid observations (e.g. before maintenance):
```bash
killall -USR1 domedaemon
```
---
## Notes
- The serial protocol is specific to Astrosib hardware (commands like `STATUS`, `OPENDOME`,
`CLOSEDOME`, `STOPDOME`, `SHUTTERMOVEDEG`, `SWITCHTOGGILE` are hardcoded).
- Encoder values are reported as raw integers; interpretation depends on the physical setup.
- The daemon polls the dome every **5 seconds** (`T_INTERVAL`). During that interval it also
processes client requests and checks weather.
- If the serial device becomes unresponsive, the status will return an error 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.

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 19.0.1, 2026-05-15T14:43:04. -->
<!-- Written by QtCreator 19.0.1, 2026-05-18T10:54:40. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>

View File

@@ -1,3 +1,4 @@
Readme.md
astrosib_proto.h
dome.c
dome.h

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 19.0.1, 2026-05-15T14:02:48. -->
<!-- Written by QtCreator 19.0.1, 2026-05-18T11:16:57. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>

View File

@@ -0,0 +1,219 @@
# domedaemon_baader
**domedaemon_baader** is a daemon that controls a [**Baader
Planetarium**](https://www.baader-planetarium.com/) allsky dome via a serial line. It provides a
TCP/UNIX socket interface for clients, integrates with a weather proxy to enforce safety rules, and
generates a FITSstyle header file with current dome status and weather sensor data.
---
## Features
- **Dome open/close** fully open or close the dome
- **Stop movement** immediately stop any ongoing dome motion
- **Weather sensor integration** reads rain/cloud status from the domes internal sensor
- **Error reporting** reports rain, timeout, and powerloss error codes
- **Weather proxy integration** automatically closes the dome and blocks opening when external
weather is bad or data is stale
- **Manual override** via `SIGUSR1` (forbid) / `SIGUSR2` (allow) signals
- **FITS header file** writes current dome state and weather sensor status into a FITSstyle
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
---
## Commandline options
| Option | Argument | Default | Description |
|----------------------|-------------------|---------------------------------|----------------------------------------------------------------------------|
| `-h`, `--help` | | | Show help |
| `-d`, `--serialdev` | *path* | | Full path to serial device (e.g. `/dev/ttyS1`) |
| `-n`, `--node` | *string* | | Node specification: IP, `name:IP`, or path for UNIX socket. For anonymous UNIX socket use `\0path` or `@path`. |
| `-l`, `--logfile` | *path* | | Full path to log file |
| `-u`, `--unixsock` | | 0 | Use UNIX socket instead of INET |
| `-v`, `--verbose` | | 0 | Increase verbosity (each `-v` adds 1 level; 0: only errors, 1: +warnings, 2: +messages, 3: +debug info) |
| `-p`, `--pidfile` | *path* | `/tmp/domedaemon.pid` | PID file path |
| `-H`, `--headerfile` | *path* | `/tmp/dome.fits` | Output file for FITSstyle header |
| `-N`, `--domename` | *name* | `Baader` | Dome name inserted into the header |
| `-b`, `--baudrate` | *speed* | 9600 | Serial baud rate |
| `-T`, `--sertmout` | *microseconds* | 5000 | Serial read timeout (µs) |
| `-m`, `--maxclients` | *number* | 2 | Maximum number of simultaneously connected clients |
---
## Socket protocol
The daemon listens for textbased commands on the configured socket. Each command returns one or
more lines of output, terminated by newline (`\n`).
### Commands
| Command | Description | Example |
|---------------------------------|-----------------------------------------------------------------------------|----------------------------------------------|
| `open` | Fully open dome (only if weather permits and observations not forbidden) | `open` |
| `close` | Fully close dome | `close` |
| `stop` | Immediately stop dome movement | `stop` |
| `status` | Get dome status and temperatures | `status` → (see example below) |
| `weather` | Get weather sensor status | `weather``weather=good` |
| `dtime` | Return servers 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=opened
measuret=1704067200.123
error=closed@timeout@powerloss
FORBIDDEN
BADWEATHER
errored_command=open
```
- `status` can be `opened`, `closed`, `intermediate` or `unknown`.
- `measuret` is the time when the status was last read from the hardware.
- `error` appears when the dome reports an error. It encodes up to three flags:
- `closed` base error (dome closed due to error)
- `@rain` rain sensor triggered
- `@timeout` watchdog timeout
- `@powerloss` power loss detected
- `FORBIDDEN` appears when observations have been manually disabled (`SIGUSR1`).
- `BADWEATHER` appears when weather proxy reports unsafe conditions.
- `errored_command` shows the last command that failed.
---
## Weather integration
The daemon retrieves external weather data via the **weather_proxy** shared memory interface
(`get_weather_data()`).
Safety rules:
- If `weather.forceoff`, `weather.rain`, or `weather.weather > WEATHER_BAD` → dome is closed and opening is blocked.
- If the weather data is older than **300 seconds** (`WEATHER_LOST`) → treated as lost communication → dome is closed and blocked.
- When weather becomes good again, the daemon automatically resets the `BADWEATHER` flag and allows normal operation.
The weather is polled every **5 seconds** (`T_INTERVAL`).
---
## Domeinternal weather sensor
The daemon also reads the domes builtin weather sensor via the `d#ask_wea` command.
Possible states:
- `0``good` (no rain/clouds)
- `1``rain/clouds`
- other → `unknown`
This status is written into the FITS header as `DOMEWEAT`.
---
## Signal handling
| Signal | Effect (in child process) |
|----------|------------------------------------------------------|
| `SIGUSR1`| Forbid observations close dome and block open |
| `SIGUSR2`| Allow observations remove manual block |
| `SIGTERM`| Stop the daemon and remove PID file |
| `SIGINT` | Same as `SIGTERM` |
| `SIGQUIT`| Same as `SIGTERM` |
---
## FITS header file
The daemon writes a text file (default `/tmp/dome.fits`) with **FITSlike** keyword/value pairs.
The file is updated every polling cycle (every 5 seconds) and can be used by external pipelines to
record dome state.
Example content:
```
OPERATIO= 'FORBIDDEN' / Observations are forbidden
DOME = 'Baader' / Dome manufacturer/name
DOMESTAT= 'closed' / Dome status
DOMEWEAT= 'good' / Dome weather sensor status
DOMEECOD= 0 / Dome error code: Rain|Watchdog|Power
TDOMMEAS= 1779091627.907 / Measurement time: 2026-05-18 11:07:07
```
The `OPERATIO` keyword appears only when observations are manually forbidden via `SIGUSR1`.
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/small_tel/tree/master/Daemons/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/domedaemon_baader
make
```
The resulting binary is `domedaemon`.
### 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 TCP local-only socket and weatheraware header:
```bash
domedaemon -d /dev/ttyS2 -l /var/log/telescope/domedaemon.log -vv \
-n localhost:55555 -H /tmp/dome.fitsheader
```
Connect to the socket using `socat`, `nc` or my [`tty_term`](https://github.com/eddyem/tty_term):
```bash
nc localhost 55555
> status
```
Send `SIGUSR1` to forbid observations (e.g. before maintenance):
```bash
killall -USR1 domedaemon
```
Don't send signals USR1/USR2 to father process (its PID stored in pidfile): it simply ignores them.
Send them by `killall` to both processes, or by `kill` to daughter process.
---
## Notes
- The serial protocol is specific to Baader Planetarium hardware. Commands such as `d#opendom`, `d#closdom`, `d#stopdom`, `d#get_dom`, `d#ask_wea`, and `d#warning` are hardcoded in `commands.h`.
- The dome returns numerical values:
- Position codes: `1111` = fully opened, `2222` = fully closed, anything else = intermediate.
- Weather codes: `0` = good, `1` = rain/clouds, other = unknown.
- Error codes are bitencoded: `1` = rain, `10` = timeout, `100` = power loss.
- The daemon polls the dome every **5 seconds** (`T_INTERVAL`). During that interval it also processes client requests and checks external 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.

View File

@@ -1,3 +1,4 @@
Readme.md
commands.h
header.c
header.h

View File

@@ -1 +1,2 @@
A simple tool to send/receive coordinates from telescope
A simple tool to send/receive coordinates to/from telescope over `10micron_stellarium` daemon.

View 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 FITSheader 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 FITSstyle 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
---
## Commandline 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 FITSstyle 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 textbased 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 servers 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 **FITSlike** 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 weatheraware 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 hardcoded).
- 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.

View File

@@ -1,3 +1,4 @@
Readme.md
commands.h
header.c
header.h

View File

@@ -1,4 +1,5 @@
Collect weather data from new meteostation in sqlite3 database.
// This is old version and need to be modificated for working with modern weather daemon)
Parameters:

View File

@@ -0,0 +1,245 @@
The `weather_proxy` package offers a lightweight daemon (`weather_proxy`) that receives data from
[`supermeteodaemon`](https://github.com/eddyem/small_tel/tree/master/Daemons/weatherdaemon_multimeteo)
via a TCP or UNIX socket, parses it, and makes it available locally through a
shared memory segment. A client library (`libweather.so`) and a simple command-line utility
(`chkweather`) are also provided to easily retrieve and check weather conditions.
---
## Overview
The main daemon (`weather_proxy`) connects to a running `supermeteodaemon` process, parses the
incoming FITS-header-style data stream, and regularly updates a POSIX shared memory segment
(`/weather_shm`). A named semaphore (`/weather_sem`) protects the shared data. The client library
offers the `get_weather_data()` function to read this shared memory and return the data in a
`weather_data_t` structure. The `chkweather` utility uses this function to quickly check the
current weather status and produce an exit code suitable for scripting.
## Components
The project consists of the following source files:
| File | Description |
|------|-------------|
| `weather_daemon.c` | The main proxy daemon. |
| `weather_client.c` | The client library (`libweather.so`) with `get_weather_data()`. |
| `weather_data.h` | Common data structure and definitions. |
| `chkweather.c` | A simple commandline tool to check weather status. |
| `weather_clt_example.c` | Example usage of the client library. |
| `Makefile` | Builds the daemon, client library, and utilities. |
## Building
The package requires a C compiler (e.g., `gcc`) and the [`usefull_macros` library](https://github.com/eddyem/snippets_library).
To install the latter clone its code and use `cmake`/`make`:
```bash
git clone --depth=1 https://github.com/eddyem/snippets_library
cd snippets_library
mkdir build
cd build
cmake ..
make
su -c "make install"
# or "sudo make install" if you have "sudo" configured
```
Then build the project:
```bash
make
```
This produces:
- `weather_proxy` the main daemon
- `libweather.so` the shared client library
- `chkweather` the weather check utility
- `weather_clt_example` an example client
To install:
```bash
su -c "make install"
```
This copies `libweather.so` to `/usr/local/lib`, installs `weather_data.h` in `/usr/local/include`,
and places the executables in `/usr/local/bin`.
## Usage
### Running the proxy daemon (`weather_proxy`)
```bash
weather_proxy -n <node> [-u] [-l <logfile>] [-p <pidfile>] [-f <fitsheader>] [-v]
```
#### Options
| Option | Description |
|--------|-------------|
| `-n <node>` | Connection endpoint. For TCP: `host:port`. For UNIX sockets: path to socket. Required. |
| `-u` | Use a UNIX socket instead of TCP. |
| `-l <file>` | Write log messages to the specified file. |
| `-p <file>` | PID file (default `/tmp/weather_proxy.pid`). |
| `-f <file>` | Save the latest weather data as a FITSheader file. |
| `-v` | Increase verbosity (can be used multiple times). |
#### Example
Connect to `supermeteodaemon` on TCP port 12345 at `localhost`:
```bash
weather_proxy -n localhost:12345 -v -l /var/log/weather_proxy.log
```
Use a UNIX socket and store the FITS header:
```bash
weather_proxy -n /tmp/superweather.sock -u -f /tmp/latest_weather.header
```
### Checking weather (`chkweather`)
`chkweather` reads the shared memory and prints the current weather data. It returns an exit code
according to the weather condition:
| Exit Code | Meaning |
|-----------|---------|
| `0` | Weather is good observations may start. |
| `1` | Weather is bad cannot start, but ongoing observations may continue. |
| `2` | Weather is terrible close the dome, park. |
| `3` | Weather is prohibited power off equipment, prepare to shut down the computer (or data is too old). |
Example:
```bash
if ./chkweather; then
echo "Conditions are good - starting observations"
else
echo "Bad weather - stopping"
fi
```
### Using the client library in your own code
The library provides a single function:
```c
#include "weather_data.h"
int get_weather_data(weather_data_t *data);
```
It fills the `weather_data_t` structure with the latest weather information. Returns `0` on
success, `-1` on failure.
#### `weather_data_t` structure
```c
typedef struct {
weather_condition_t weather; // condition (0..3)
float windmax; // max wind in last hour (m/s)
float wind; // current wind speed (m/s)
float clouds; // sky "quality" (>2500 = good)
float exttemp; // external temperature (°C)
float pressure; // atmospheric pressure (mmHg)
float humidity; // relative humidity (%)
int rain; // 1 if rain is detected
int forceoff; // forced poweroff flag
time_t last_update; // timestamp of the data
} weather_data_t;
```
The `weather_condition_t` enum:
| Value | Meaning |
|-------|---------|
| `WEATHER_GOOD` (0) | Clear for observations |
| `WEATHER_BAD` (1) | Unfavourable but not critical |
| `WEATHER_TERRIBLE` (2) | Dangerous conditions close and park |
| `WEATHER_PROHIBITED` (3) | Emergency close, park and prepare for powering off |
Example client:
```c
#include "weather_data.h"
#include <stdio.h>
int main() {
weather_data_t wd;
if (get_weather_data(&wd) == 0) {
printf("Weather: %d, Temp: %.1f C\n", wd.weather, wd.exttemp);
}
return 0;
}
```
Compile with:
```bash
gcc -o myclient myclient.c -lweather
```
## Data Flow
1. **supermeteodaemon** collects data from various sensors and outputs it as lines of `KEY=VALUE`
pairs (FITS-header style).
2. **weather_proxy** connects to the socket, sends a `"get\n"` command, and parses the incoming
lines.
3. It extracts the fields: `WEATHER`, `WINDMAX1`, `PRECIP`, `CLOUDS`, `WIND`, `EXTTEMP`,
`PRESSURE`, `HUMIDITY`, `FORCEOFF`, and `TMEAS` (the timestamp).
4. The data is stored in a POSIX shared memory segment (`/weather_shm`) and is protected by a named
semaphore (`/weather_sem`).
5. Client applications (like `chkweather` or your own code) use `get_weather_data()` to read the
shared memory safely.
## Signals
The daemon responds to:
- **SIGUSR1** Forbid observations (sets an internal `forbidden` flag which overrides the current
weather to `WEATHER_PROHIBITED`).
- **SIGUSR2** Permit observations (clears the `forbidden` flag).
These signals are only handled by the worker child process; the parent monitor process ignores
them. So you can send them simply by `killall -sUSR1 weather_proxy`.
## FITSHeader Output
If the `-f <file>` option is given, the daemon writes each received `KEY=VALUE` line to a temporary
file and, when the data set is complete (i.e., the `TWEATH` line is received), it atomically
replaces the target file. This produces a plaintext file that can be used as a FITS header or for
other applications.
Example generated file:
```
WIND = 4.30 / Wind, m/s
WINDMAX = 5.90 / Maximal wind speed for last 24 hours
WINDMAX1= 5.90 / Maximal wind speed for last hour
WINDDIR = 32.75 / Wind direction, degr (CW from north to FROM)
WINDDIR1= 25.97 / Mean wind speed direction for last hour
WINDDIR2= 35.37 / Mean wind speed^2 direction for last hour
HUMIDITY= 57.50 / Humidity, percent
EXTTEMP = 9.00 / Ambient temperature, degC
PRESSURE= 585.72 / Atmospheric pressure, mmHg
PRECIP = 0 / Precipitation (1 - yes, 0 - no)
PRECIPLV= 0.00 / Cumulative precipitation level (mm)
CLOUDS = 2399.50 / Integral sky quality value (bigger - better)
WEATHER = 0 / Weather (0..3: good/bad/terrible/prohibited)
TSINCERN= 20 / Minutes since rain (20 means a lot of)
RAINPOW = 0 / Rain strength, 0..255
RAINAVG = 0 / Average rain strength, 0..255
RSAMBL = 48 / Ambient light by rain sensor, 0..255
RSFREEZ = 0 / Rain sensor is freezed
TWEATH = 1779085104 / Last weather time: 2026-05-18 09:18:24
```
----
## License
Copyright © 2026 Edward V. Emelianov.
**GNU General Public License v3.0** or later.
See the `LICENSE` file in repository's root directory or [http://www.gnu.org/licenses/](http://www.gnu.org/licenses/)
for details.

View File

@@ -1,3 +1,4 @@
Readme.md
weather_client.c
weather_clt_example.c
weather_daemon.c

View File

@@ -44,14 +44,14 @@ emerge net-analyzer/net-snmp
```
Available plugin options:
- `DUMMY`  Dummy weather station for testing.
- `FDEXAMPLE`  Example file descriptor plugin.
- `HYDREON`  Hydreon RG-11 rain sensor.
- `BTAMETEO`  BTA 6-m telescope main meteostation (shared memory).
- `REINHARDT`  Old Reinhardt meteostation.
- `WXA100`  Vaisala WXA100 ultrasonic station.
- `SNMP`  UPS monitoring via SNMP.
- `LIGHTNING`  AS3935-based lightning sensor.
- `DUMMY` Dummy weather station for testing.
- `FDEXAMPLE` Example file descriptor plugin.
- `HYDREON` Hydreon RG-11 rain sensor.
- `BTAMETEO` BTA 6-m telescope main meteostation (shared memory).
- `REINHARDT` Old Reinhardt meteostation.
- `WXA100` Vaisala WXA100 ultrasonic station.
- `SNMP` UPS monitoring via SNMP.
- `LIGHTNING` AS3935-based lightning sensor.
4. Building:
@@ -94,7 +94,7 @@ Format:
```
- `library`: path to the shared library, e.g. `libwxa100.so`.
- `type`: Connection type  `D` for serial device, `U` for UNIX socket, `N` for INET socket.
- `type`: Connection type `D` for serial device, `U` for UNIX socket, `N` for INET socket.
- `parameter`: device path and optional speed (`/dev/ttyS0:9600`), UNIX socket name, or `host:port` for INET.
Examples:
@@ -150,7 +150,7 @@ Run with:
superweatherdaemon -c /etc/weather.conf
```
To run on system start you can use OpenRó `rc.local` mechanism.
To run on system start you can use OpenRС `rc.local` mechanism.
## Plugins
@@ -185,8 +185,8 @@ daemon will try to reconnect every `reinit_delay` seconds.
| Library | Sensor | Type |
|---------|--------|------|
| `libwsdummy.so` | Dummy station  outputs random walk data around realistic values. | Test / Development |
| `libfdex.so` | Example of a filedescriptor based plugin. Prompts for commaseparated values. | Example |
| `libwsdummy.so` | Dummy station outputs random walk data around realistic values. | Test / Development |
| `libfdex.so` | Example of a filedescriptor based plugin. Prompts for commaseparated values. | Example |
| `libhydreon.so` | Hydreon RG-11 optical rain sensor. | Serial |
| `libbtameteo.so` | BTA 6-m telescope main meteostation (shared memory). | Shared Memory |
| `libreinhardt.so` | Old Reinhardt meteostation (serial, `?U` command). | Serial |
@@ -216,22 +216,22 @@ Use the existing plugins as templates. A minimal plugin must:
The daemon combines data from all active plugins and continuously evaluates a global **weather
level**:
- `0`  **GOOD**: observations can start safely.
- `1`  **BAD**: risky to start, but can continue.
- `2`  **TERRIBLE**: dome must close, instruments park.
- `3`  **PROHIBITED**: complete shutdown, power off equipment.
- `0` **GOOD**: observations can start safely.
- `1` **BAD**: risky to start, but can continue.
- `2` **TERRIBLE**: dome must close, instruments park.
- `3` **PROHIBITED**: complete shutdown, power off equipment.
### Criteria
Each weather parameter (wind speed, humidity, clouds, sky temperature, lightning distance,
precipitation, etc.) has configurable thresholds:
- `good`  below/above this (depending on sign) the condition is good.
- `bad`  above this the condition is bad.
- `terrible`  above this the condition is terrible.
- `prohibited`  (if defined) above this the condition goes directly to PROHIBITED.
- `negflag`  if `1`, a smaller value is worse (e.g., clouds).
- `shtdnflag`  if `1`, entering the terrible/prohibited range also sets the **FORCE SHUTDOWN** flag.
- `good` below/above this (depending on sign) the condition is good.
- `bad` above this the condition is bad.
- `terrible` above this the condition is terrible.
- `prohibited` (if defined) above this the condition goes directly to PROHIBITED.
- `negflag` if `1`, a smaller value is worse (e.g., clouds).
- `shtdnflag` if `1`, entering the terrible/prohibited range also sets the **FORCE SHUTDOWN** flag.
### Special Flags
@@ -251,9 +251,9 @@ passed since the last serious event. This prevents rapid toggling.
The daemon listens on two interfaces:
1. **Network socket** (TCP, default port 12345)  read-only (in meaning they cannot change any
1. **Network socket** (TCP, default port 12345) read-only (in meaning they cannot change any
parameters) access for remote clients.
2. **Local UNIX socket** (abstract or filesystem, default `@weather`)  full control for local applications.
2. **Local UNIX socket** (abstract or filesystem, default `@weather`) full control for local applications.
Commands are sent as plain text strings, terminated by a newline.
@@ -285,7 +285,7 @@ Commands are sent as plain text strings, terminated by a newline.
Reply format: each line is a FITS-like `KEY = value / comment` string; commands that set something
usually echo back the variable and its new value. For `get=<N>` each `KEY` have a suffix in square
brackets  number of plugin, e.g. `WIND[1]= 10.1 / Wind speed, m/s`.
brackets number of plugin, e.g. `WIND[1]= 10.1 / Wind speed, m/s`.
## Signals