mirror of
https://github.com/eddyem/small_tel.git
synced 2026-05-07 13:27:06 +03:00
Add readme, make some fixes
This commit is contained in:
@@ -1,22 +1,324 @@
|
|||||||
Weather daemon for several different weather stations
|
# superweatherdaemon Documentation
|
||||||
=====================================================
|
|
||||||
|
|
||||||
## Usage:
|
## Overview
|
||||||
|
|
||||||
```
|
**superweatherdaemon** is a weather monitoring daemon designed for astronomical observatories. It
|
||||||
Usage: weatherdaemon [args]
|
collects data from multiple heterogeneous weather stations (meteostations) via a plugin
|
||||||
Be careful: command line options have priority over config
|
architecture, computes a unified weather status, and provides control interfaces over TCP and local
|
||||||
Where args are:
|
UNIX sockets. The daemon can issue warnings, change weather level, and even trigger a forced
|
||||||
|
shutdown of instruments (e.g., close dome) when conditions become dangerous.
|
||||||
|
|
||||||
-P, --pidfile=arg pidfile name (default: /tmp/weatherdaemon.pid)
|
The project is written in C, uses CMake as its build system, and relies on the
|
||||||
-c, --conffile=arg configuration file name (consists all or a part of long-named parameters and their values (e.g. plugin=liboldweather.so)
|
[usefull_macros](https://github.com/eddyem/snippets_library) library for utilities and socket
|
||||||
-h, --help show this help
|
management.
|
||||||
-l, --logfile=arg save logs to file (default: none)
|
|
||||||
-p, --plugin=arg add this weather plugin (may be a lot of) (can occur multiple times)
|
## Dependencies
|
||||||
-v, --verb logfile verbocity level (each -v increased)
|
|
||||||
--port=arg network port to connect (default: 12345); hint: use "localhost:port" to make local net socket
|
- **Build tools**: CMake >= 4.0, C compiler with C11 support, `pkg-config`.
|
||||||
--sockpath=arg UNIX socket path (starting from '\0' for anonimous) of command socket
|
- **Library**: `usefull_macros` >= 0.3.5 (`sl_*` functions for logging, sockets, command-line parsing, etc.).
|
||||||
|
- **Optional**: `net-snmp` (for the SNMP UPS plugin).
|
||||||
|
|
||||||
|
On Gentoo/Calculate Linux, install the basic build dependencies:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
emerge dev-build/cmake dev-util/pkgconf
|
||||||
|
# usefull_macros must be installed from its own source; follow its documentation.
|
||||||
|
# For SNMP support:
|
||||||
|
emerge net-analyzer/net-snmp
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Building and Installation
|
||||||
|
|
||||||
TODO: brief documentation will be here
|
1. Clone or download the source tree.
|
||||||
|
2. Create a build directory and run CMake:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Customise enabled plugins with `-D` options (all are `ON` by default):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cmake .. -DDUMMY=OFF -DFDEXAMPLE=OFF -DHYDREON=ON -DBTAMETEO=ON ...
|
||||||
|
```
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
4. Building:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make
|
||||||
|
su -c "make install"
|
||||||
|
```
|
||||||
|
|
||||||
|
The main executable `superweatherdaemon` is installed into `bin`; the plugin shared libraries
|
||||||
|
(`lib*.so`) go to the library directory.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
The daemon can be configured entirely via command-line options, a configuration file, or both.
|
||||||
|
Command-line options take precedence.
|
||||||
|
|
||||||
|
### Command-line Options
|
||||||
|
|
||||||
|
| Option | Description |
|
||||||
|
|--------|-------------|
|
||||||
|
| `-h`, `--help` | Show help message and exit. |
|
||||||
|
| `-c <file>`, `--conffile <file>` | Use a configuration file. Point non-existant file to get help. |
|
||||||
|
| `-l <path>`, `--logfile=<path>` | Write logs to a file (default: none). |
|
||||||
|
| `-P <path>`, `--pidfile=<path>` | PID file (default `/tmp/superweatherdaemon.pid`). |
|
||||||
|
| `-p <spec>`, `--plugin=<spec>` | Add a weather plugin; can be repeated for different plugins. Format: `path:type:device` (see below). |
|
||||||
|
| `--port=<node>` | Network port for clients (default `12345`). Use `localhost:port` for local access only. |
|
||||||
|
| `--sockpath=<path>` | UNIX socket path (start with `@` for an abstract socket). |
|
||||||
|
| `-T <seconds>`, `--pollt <seconds>` | Max polling interval in seconds (integer). |
|
||||||
|
| `-v`, `--verb` | Increase verbosity level (each `-v` adds 1). |
|
||||||
|
|
||||||
|
### Plugin Specification
|
||||||
|
|
||||||
|
A plugin is a shared library (`.so`) that provides a `sensor_init` function. It is loaded with the
|
||||||
|
`--plugin` option.
|
||||||
|
|
||||||
|
Format:
|
||||||
|
|
||||||
|
```
|
||||||
|
--plugin=library:type:parameter
|
||||||
|
```
|
||||||
|
|
||||||
|
- `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.
|
||||||
|
- `parameter`: device path and optional speed (`/dev/ttyS0:9600`), UNIX socket name, or `host:port` for INET.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
--plugin=libreinhardt.so:D:/dev/ttyS0
|
||||||
|
--plugin=libwxa100.so:D:/dev/pl2303_0
|
||||||
|
--plugin=libhydreon.so:D:/dev/ch340_0:1200
|
||||||
|
--plugin=libbtameteo.so (no device, uses shared memory)
|
||||||
|
```
|
||||||
|
|
||||||
|
Multiple plugins are listed in order of **importance** (first ones are considered primary for
|
||||||
|
weather level calculation).
|
||||||
|
|
||||||
|
### Configuration File
|
||||||
|
|
||||||
|
The configuration file uses a simple `key = value` syntax, with `#` for comments. Example:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
# network port for clients
|
||||||
|
port = 4444
|
||||||
|
logfile = /var/log/meteo/superweather.log
|
||||||
|
verbose = 2
|
||||||
|
sockpath = "@weather"
|
||||||
|
pollt = 1
|
||||||
|
reinit_delay = 10
|
||||||
|
|
||||||
|
# Weather thresholds
|
||||||
|
ahtung_delay = 1800 # in seconds
|
||||||
|
good_wind = 5.0 # m/s
|
||||||
|
bad_wind = 10.0
|
||||||
|
terrible_wind = 15.0
|
||||||
|
good_humidity = 65.0 # percents
|
||||||
|
bad_humidity = 87.0
|
||||||
|
terrible_humidity = 94.0
|
||||||
|
good_clouds = 2500.0 # for reinhardt sensor in its units
|
||||||
|
bad_clouds = 2000.0
|
||||||
|
terrible_clouds = 500.0
|
||||||
|
clouds_negflag = 1 # 1 means the higher the value the better
|
||||||
|
good_sky = -40.0 # sky minus ambient temperature, degC
|
||||||
|
bad_sky = -10.0
|
||||||
|
terrible_sky = 0.0
|
||||||
|
# plugins - most important first
|
||||||
|
plugin = libwxa100.so:D:/dev/pl2303_0
|
||||||
|
plugin = libhydreon.so:D:/dev/ch340_0:1200
|
||||||
|
plugin = libbtameteo.so
|
||||||
|
plugin = libreinhardt.so:D:/dev/ttyS0
|
||||||
|
```
|
||||||
|
|
||||||
|
Run with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
superweatherdaemon -c /etc/weather.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
To run on system start you can use OpenRó `rc.local` mechanism.
|
||||||
|
|
||||||
|
## Plugins
|
||||||
|
|
||||||
|
Each weather station is implemented as a shared library exporting a single function:
|
||||||
|
|
||||||
|
```c
|
||||||
|
int sensor_init(sensordata_t *s);
|
||||||
|
```
|
||||||
|
|
||||||
|
The `sensordata_t` structure contains all required callbacks, data pointers, and private fields.
|
||||||
|
See `weathlib.h` for the full definition.
|
||||||
|
|
||||||
|
### Plugin Lifecycle
|
||||||
|
|
||||||
|
1. **Loading**: The main daemon calls `s = sensor_new(...)` to create `sensordata_t` structure,
|
||||||
|
opens given library with `dlopen` and calls `sensor_init` on that new `s`.
|
||||||
|
2. **Initialisation**:
|
||||||
|
- Set `s->name`, `s->Nvalues`, `s->values` array.
|
||||||
|
- Configure the communication channel (file descriptor) using `getFD(s->path)`.
|
||||||
|
- Create a worker thread that periodically reads sensor data and updates `s->values`.
|
||||||
|
Don't forget to lock `s->valmutex` on any operation with `s->values`.
|
||||||
|
3. **Data delivery**: Each time new data is available, call `s->freshdatahandler(s)`
|
||||||
|
(this is set by the daemon to `dumpsensors`). The main daemon then merges the data into the
|
||||||
|
global weather evaluation.
|
||||||
|
4. **Shutdown**: The daemon calls `s->kill(s)`, which must join the thread, close the file
|
||||||
|
descriptor, and free resources. Default `common_kill` handles most of this; plugins can override it.
|
||||||
|
|
||||||
|
If the plugin is disconnected for some reason (for example, the network connection is lost), the
|
||||||
|
daemon will try to reconnect every `reinit_delay` seconds.
|
||||||
|
|
||||||
|
### Available Plugins
|
||||||
|
|
||||||
|
| 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 |
|
||||||
|
| `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 |
|
||||||
|
| `libwxa100.so` | Vaisala WXA100 ultrasonic meteostation (serial, `0R0` command). | Serial |
|
||||||
|
| `libsnmp.so` | UPS monitor via SNMP (requires net-snmp). | Network |
|
||||||
|
| `liblightning.so` | AS3935-based lightning sensor (serial). | Serial |
|
||||||
|
|
||||||
|
### Writing a New Plugin
|
||||||
|
|
||||||
|
Use the existing plugins as templates. A minimal plugin must:
|
||||||
|
|
||||||
|
- Include `weathlib.h`.
|
||||||
|
- Define an array of `val_t` describing each measured quantity.
|
||||||
|
- Implement `sensor_init`:
|
||||||
|
- Allocate `s->values`, copy the template array.
|
||||||
|
- Set `s->Nvalues`, `s->name`.
|
||||||
|
- Open the device (use `getFD(s->path)` for serial/sockets) and set `s->fdes`.
|
||||||
|
If your plugin don't need file descriptor, you must set `s->fdes` to any non-negative value.
|
||||||
|
- Create a ring buffer if needed (`sl_RB_new`).
|
||||||
|
- Start the worker thread that reads data, updates values inside `pthread_mutex_lock(&s->valmutex)`,
|
||||||
|
and calls `s->freshdatahandler(s)` (outside mutex locked).
|
||||||
|
- Return `TRUE` on success, `FALSE` on failure (call `s->kill(s)` to clean up).
|
||||||
|
- The `weathlib.h` provides helper functions: `common_onrefresh`, `common_getval`, `common_kill`.
|
||||||
|
|
||||||
|
## Weather Level Calculation
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
|
||||||
|
### Special Flags
|
||||||
|
|
||||||
|
- **FORCE SHUTDOWN**: Some parameters (e.g., lightning within <= 5km, UPS on battery) carry the
|
||||||
|
`IS_FORCEDSHTDN` meaning and have `shtdnflag = 1`. When their value exceeds the terrible threshold,
|
||||||
|
the forced shutdown flag is raised, which immediately sets the weather level to PROHIBITED and is
|
||||||
|
typically used to cut power.
|
||||||
|
- **Manual FORBID**: An operator can send a signal (`SIGUSR1`) or a socket command to forbid
|
||||||
|
observations, which also forces PROHIBITED. `SIGUSR2` or a socket command clears forbidden flag.
|
||||||
|
|
||||||
|
### Hysteresis
|
||||||
|
|
||||||
|
Once a bad/terrible state is reached, the level is not lowered until `ahtung_delay` seconds have
|
||||||
|
passed since the last serious event. This prevents rapid toggling.
|
||||||
|
|
||||||
|
## Server Commands (Socket API)
|
||||||
|
|
||||||
|
The daemon listens on two interfaces:
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
Commands are sent as plain text strings, terminated by a newline.
|
||||||
|
|
||||||
|
### Common (read-only) Commands
|
||||||
|
|
||||||
|
| Command | Description |
|
||||||
|
|---------|-------------|
|
||||||
|
| `get` | Return all collected weather data (all stations). |
|
||||||
|
| `get=<N>` | Return data from plugin `<N>`. |
|
||||||
|
| `list` | List all loaded plugins with their names and value counts. |
|
||||||
|
| `time` | Return server UNIX time (float seconds). |
|
||||||
|
| `chklevel` | Show the `sense` (importance) level of every collected parameter. |
|
||||||
|
| `chklevel=<N>` | Same for a specific plugin. |
|
||||||
|
|
||||||
|
### Local-only (read-write) Commands
|
||||||
|
|
||||||
|
| Command | Description |
|
||||||
|
|---------|-------------|
|
||||||
|
| `forbid` | Get current FORBID flag (0/1). |
|
||||||
|
| `forbid=<0/1>` | Set/clear manual FORBID. |
|
||||||
|
| `forceoff` | Get FORCE SHUTDOWN flag. |
|
||||||
|
| `forceoff=<0/1>` | Set/clear it manually. |
|
||||||
|
| `weathlevel` | Get current weather level (0-3 for GOOD-PROHIBITED). |
|
||||||
|
| `weathlevel=<0..3>` | Force weather level (use with caution). |
|
||||||
|
| `setlevel=<plugin>:<param>=<sense>,...` | Change the `sense` field of one or more sensor parameters. Example: `setlevel=1:WIND=3,HUMIDITY=3` disables wind and humidity from station 1. |
|
||||||
|
| `mute=<N>` | Stop refreshing data from plugin `<N>` (mute). |
|
||||||
|
| `unmute=<N>` | Resume refreshing. |
|
||||||
|
| `ismuted=<N>` | Return 1 if muted, 0 otherwise. |
|
||||||
|
|
||||||
|
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`.
|
||||||
|
|
||||||
|
## Signals
|
||||||
|
|
||||||
|
| Signal | Effect |
|
||||||
|
|--------|--------|
|
||||||
|
| `SIGTERM`, `SIGINT`, `SIGQUIT` | Clean shutdown (removes PID file, kills plugins, destroys sockets). |
|
||||||
|
| `SIGHUP` | Ignored. |
|
||||||
|
| `SIGUSR1` | Set manual FORBID (weather level == PROHIBITED). |
|
||||||
|
| `SIGUSR2` | Clear manual FORBID. |
|
||||||
|
| `SIGPIPE` | Logged, used to detect network plugins disconnections. |
|
||||||
|
|
||||||
|
## Files
|
||||||
|
|
||||||
|
| File | Purpose |
|
||||||
|
|------|---------|
|
||||||
|
| `CMakeLists.txt` | Top-level build definition. |
|
||||||
|
| `cmdlnopts.c/.h` | Command-line and configuration file parsing. |
|
||||||
|
| `main.c` | Daemon entry point, signal handlers, forking. |
|
||||||
|
| `mainweather.c/.h` | Global weather evaluation, data collection, forced shutdown. |
|
||||||
|
| `sensors.c/.h` | Plugin management (load, unload, getters). |
|
||||||
|
| `server.c/.h` | TCP and UNIX socket servers. |
|
||||||
|
| `weathlib.c/.h` | Common plugin API, value definitions, helper functions. |
|
||||||
|
| `fd.c` | Function `getFD()` to open serial devices or sockets for plugins. |
|
||||||
|
| `example.config` | Sample configuration file. |
|
||||||
|
| `plugins/CMakeLists.txt` | Build file for all plugins. |
|
||||||
|
| `plugins/*.c` | Individual plugin source files. |
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
The project is released under the **GNU General Public License v3.0** or later. See the headers in
|
||||||
|
the source files for the full legal text.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*For further assistance or to report issues, please contact the maintainer: Edward V. Emelianov
|
||||||
|
<edward.emelianoff@gmail.com>.*
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ reinit_delay = 10
|
|||||||
|
|
||||||
# !!! Point plugins in order of meaning: the most important are first !!!
|
# !!! Point plugins in order of meaning: the most important are first !!!
|
||||||
# see help for plugins format
|
# see help for plugins format
|
||||||
# this should be furst as almost a half of its sensors are broken
|
|
||||||
plugin = libreinhardt.so:D:/dev/ttyS0
|
|
||||||
plugin = libwxa100.so:D:/dev/pl2303_0
|
plugin = libwxa100.so:D:/dev/pl2303_0
|
||||||
plugin = libhydreon.so:D:/dev/ch340_0:1200
|
plugin = libhydreon.so:D:/dev/ch340_0:1200
|
||||||
plugin = libbtameteo.so
|
plugin = libbtameteo.so
|
||||||
|
# this should be last as almost a half of its sensors are broken
|
||||||
|
plugin = libreinhardt.so:D:/dev/ttyS0
|
||||||
|
|||||||
@@ -56,7 +56,12 @@ static int openserial(const char *path){
|
|||||||
}
|
}
|
||||||
DBG("Opened %s @ %d", str, speed);
|
DBG("Opened %s @ %d", str, speed);
|
||||||
FREE(str);
|
FREE(str);
|
||||||
return serial->comfd;
|
int comfd = serial->comfd;
|
||||||
|
FREE(serial->portname);
|
||||||
|
FREE(serial->buf);
|
||||||
|
FREE(serial->format);
|
||||||
|
FREE(serial);
|
||||||
|
return comfd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -569,6 +569,7 @@ void refresh_sensval(sensordata_t *s){
|
|||||||
|
|
||||||
// set/clear `forbid` flag (by signals USR1 and USR2)
|
// set/clear `forbid` flag (by signals USR1 and USR2)
|
||||||
void forbid_observations(int f){
|
void forbid_observations(int f){
|
||||||
|
pthread_mutex_lock(&datamutex);
|
||||||
if(f) Forbidden = 1;
|
if(f) Forbidden = 1;
|
||||||
else Forbidden = 0;
|
else Forbidden = 0;
|
||||||
int curt = (int) time(NULL);
|
int curt = (int) time(NULL);
|
||||||
@@ -577,6 +578,7 @@ void forbid_observations(int f){
|
|||||||
collected_data[NLASTAHTUNG].time = curt;
|
collected_data[NLASTAHTUNG].time = curt;
|
||||||
sprintf(collected_data[NAHTUNGRSN].value.str, "FORBID");
|
sprintf(collected_data[NAHTUNGRSN].value.str, "FORBID");
|
||||||
collected_data[NAHTUNGRSN].time = curt;
|
collected_data[NAHTUNGRSN].time = curt;
|
||||||
|
pthread_mutex_unlock(&datamutex);
|
||||||
DBG("Change FORBID status to %d", f);
|
DBG("Change FORBID status to %d", f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,11 +55,11 @@ static void *mainthread(void *s){
|
|||||||
//if(!sensor->values[5].value.u && drand48() > 0.7) sensor->values[5].value.u = 1;
|
//if(!sensor->values[5].value.u && drand48() > 0.7) sensor->values[5].value.u = 1;
|
||||||
time_t cur = time(NULL);
|
time_t cur = time(NULL);
|
||||||
for(int i = 0; i < NS-1; ++i) sensor->values[i].time = cur;
|
for(int i = 0; i < NS-1; ++i) sensor->values[i].time = cur;
|
||||||
f = sensor->values[6].value.f - (drand48() - 0.52);
|
/*f = sensor->values[6].value.f - (drand48() - 0.52);
|
||||||
if(f > 0. && f < 60){
|
if(f > 0. && f < 60){
|
||||||
sensor->values[6].value.f = f;
|
sensor->values[6].value.f = f;
|
||||||
sensor->values[6].time = cur;
|
sensor->values[6].time = cur;
|
||||||
}
|
}*/
|
||||||
pthread_mutex_unlock(&sensor->valmutex);
|
pthread_mutex_unlock(&sensor->valmutex);
|
||||||
//DBG("unlocked");
|
//DBG("unlocked");
|
||||||
if(sensor->freshdatahandler) sensor->freshdatahandler(sensor);
|
if(sensor->freshdatahandler) sensor->freshdatahandler(sensor);
|
||||||
@@ -82,7 +82,7 @@ int sensor_init(sensordata_t *s){
|
|||||||
s->values[3].value.f = 600.;
|
s->values[3].value.f = 600.;
|
||||||
s->values[4].value.f = 89.;
|
s->values[4].value.f = 89.;
|
||||||
s->values[5].value.u = 0;
|
s->values[5].value.u = 0;
|
||||||
s->values[6].value.f = 4.5;
|
//s->values[6].value.f = 4.5;
|
||||||
if(pthread_create(&s->thread, NULL, mainthread, (void*)s)){
|
if(pthread_create(&s->thread, NULL, mainthread, (void*)s)){
|
||||||
s->kill(s);
|
s->kill(s);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|||||||
@@ -322,17 +322,7 @@ static void toomuch(int fd){
|
|||||||
const char *m = "Try later: too much clients connected\n";
|
const char *m = "Try later: too much clients connected\n";
|
||||||
send(fd, m, sizeof(m)-1, MSG_NOSIGNAL);
|
send(fd, m, sizeof(m)-1, MSG_NOSIGNAL);
|
||||||
shutdown(fd, SHUT_WR);
|
shutdown(fd, SHUT_WR);
|
||||||
DBG("shutdown, wait");
|
DBG("shutdown");
|
||||||
double t0 = sl_dtime();
|
|
||||||
uint8_t buf[8];
|
|
||||||
while(sl_dtime() - t0 < 90.){ // change this value to smaller for real work
|
|
||||||
if(sl_canread(fd)){
|
|
||||||
ssize_t got = read(fd, buf, 8);
|
|
||||||
DBG("Got=%zd", got);
|
|
||||||
if(got < 1) break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DBG("Disc after %gs", sl_dtime() - t0);
|
|
||||||
LOGWARN("Client fd=%d tried to connect after MAX reached", fd);
|
LOGWARN("Client fd=%d tried to connect after MAX reached", fd);
|
||||||
}
|
}
|
||||||
// new connections handler (return FALSE to reject client)
|
// new connections handler (return FALSE to reject client)
|
||||||
@@ -414,6 +404,7 @@ int start_servers(const char *netnode, const char *sockpath){
|
|||||||
if(sensor_alive(s)) continue;
|
if(sensor_alive(s)) continue;
|
||||||
// sensor isn't inited - try to do it
|
// sensor isn't inited - try to do it
|
||||||
DBG("sensor with path %s isn't inited, try", s->path);
|
DBG("sensor with path %s isn't inited, try", s->path);
|
||||||
|
s->kill(s); // clear resources
|
||||||
if(s->init){
|
if(s->init){
|
||||||
if(s->init(s)) LOGMSG("Sensor %s reinited @ %s", s->name, s->path);
|
if(s->init(s)) LOGMSG("Sensor %s reinited @ %s", s->name, s->path);
|
||||||
else DBG("Can't reinit");
|
else DBG("Can't reinit");
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
CMakeLists.txt
|
CMakeLists.txt
|
||||||
|
Readme.md
|
||||||
cmdlnopts.c
|
cmdlnopts.c
|
||||||
cmdlnopts.h
|
cmdlnopts.h
|
||||||
fd.c
|
fd.c
|
||||||
|
|||||||
@@ -76,6 +76,10 @@ void common_kill(sensordata_t *s){
|
|||||||
FNAME();
|
FNAME();
|
||||||
if(!s) return;
|
if(!s) return;
|
||||||
if(s->fdes > -1){ // inited and maybe have opened file/socket
|
if(s->fdes > -1){ // inited and maybe have opened file/socket
|
||||||
|
close(s->fdes);
|
||||||
|
s->fdes = -1;
|
||||||
|
DBG("FD closed");
|
||||||
|
usleep(5000);
|
||||||
if(pthread_equal(pthread_self(), s->thread)){
|
if(pthread_equal(pthread_self(), s->thread)){
|
||||||
DBG("Don't cancel myself");
|
DBG("Don't cancel myself");
|
||||||
}else{
|
}else{
|
||||||
@@ -86,9 +90,6 @@ void common_kill(sensordata_t *s){
|
|||||||
DBG("Done");
|
DBG("Done");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close(s->fdes);
|
|
||||||
s->fdes = -1;
|
|
||||||
DBG("FD closed");
|
|
||||||
}
|
}
|
||||||
DBG("Delete RB");
|
DBG("Delete RB");
|
||||||
if(s->ringbuffer) sl_RB_delete(&s->ringbuffer);
|
if(s->ringbuffer) sl_RB_delete(&s->ringbuffer);
|
||||||
|
|||||||
Reference in New Issue
Block a user