mirror of
https://github.com/eddyem/small_tel.git
synced 2026-02-01 04:45:02 +03:00
add weather processing to 10micron stellarium
This commit is contained in:
parent
6bfcc8730c
commit
b25c15cbfc
@ -9,7 +9,9 @@ main.c
|
|||||||
main.h
|
main.h
|
||||||
parseargs.c
|
parseargs.c
|
||||||
parseargs.h
|
parseargs.h
|
||||||
|
socket.c
|
||||||
|
socket.h
|
||||||
telescope.c
|
telescope.c
|
||||||
telescope.h
|
telescope.h
|
||||||
usefull_macros.c
|
usefull_macro.c
|
||||||
usefull_macros.h
|
usefull_macro.h
|
||||||
|
|||||||
@ -24,20 +24,23 @@
|
|||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "cmdlnopts.h"
|
#include "cmdlnopts.h"
|
||||||
#include "usefull_macros.h"
|
#include "parseargs.h"
|
||||||
|
#include "usefull_macro.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* here are global parameters initialisation
|
* here are global parameters initialisation
|
||||||
*/
|
*/
|
||||||
int help;
|
int help;
|
||||||
glob_pars G;
|
glob_pars G;
|
||||||
|
glob_pars *GP = NULL;
|
||||||
|
|
||||||
#define DEFAULT_COMDEV "/dev/ttyUSB0"
|
#define DEFAULT_COMDEV "/dev/ttyUSB0"
|
||||||
// port for connections
|
// port for connections
|
||||||
#define DEFAULT_PORT "10000"
|
#define DEFAULT_PORT "10000"
|
||||||
#define DEFAULT_DBGPORT "10001"
|
#define DEFAULT_DBGPORT "10001"
|
||||||
// accept only local connections
|
// weather server port and name
|
||||||
//#define ACCEPT_IP "192.168.3.225"
|
#define DEFAULT_WSPORT (12345)
|
||||||
|
#define DEFAULT_WSNAME "robotel1.sao.ru"
|
||||||
// default PID filename:
|
// default PID filename:
|
||||||
#define DEFAULT_PIDFILE "/tmp/stellariumdaemon.pid"
|
#define DEFAULT_PIDFILE "/tmp/stellariumdaemon.pid"
|
||||||
// default file with headers
|
// default file with headers
|
||||||
@ -52,6 +55,8 @@ glob_pars const Gdefault = {
|
|||||||
.pidfile = DEFAULT_PIDFILE,
|
.pidfile = DEFAULT_PIDFILE,
|
||||||
.crdsfile = DEFAULT_FITSHDR,
|
.crdsfile = DEFAULT_FITSHDR,
|
||||||
.emulation = 0,
|
.emulation = 0,
|
||||||
|
.weathserver = DEFAULT_WSNAME,
|
||||||
|
.weathport = DEFAULT_WSPORT,
|
||||||
.logfile = NULL // don't save logs
|
.logfile = NULL // don't save logs
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -70,6 +75,8 @@ myoption cmdlnopts[] = {
|
|||||||
{"pidfile", NEED_ARG, NULL, 'P', arg_string, APTR(&G.pidfile), _("pidfile (default: " DEFAULT_PIDFILE ")")},
|
{"pidfile", NEED_ARG, NULL, 'P', arg_string, APTR(&G.pidfile), _("pidfile (default: " DEFAULT_PIDFILE ")")},
|
||||||
{"port", NEED_ARG, NULL, 'p', arg_string, APTR(&G.port), _("port to connect (default: " DEFAULT_PORT ")")},
|
{"port", NEED_ARG, NULL, 'p', arg_string, APTR(&G.port), _("port to connect (default: " DEFAULT_PORT ")")},
|
||||||
{"dbgport", NEED_ARG, NULL, 'D', arg_string, APTR(&G.dbgport), _("port to connect for debug console (default: " DEFAULT_DBGPORT ")")},
|
{"dbgport", NEED_ARG, NULL, 'D', arg_string, APTR(&G.dbgport), _("port to connect for debug console (default: " DEFAULT_DBGPORT ")")},
|
||||||
|
{"wport", NEED_ARG, NULL, 'w', arg_int, APTR(&G.weathport), _("weather server port")},
|
||||||
|
{"wname", NEED_ARG, NULL, 'W', arg_string, APTR(&G.weathserver),_("weather server address")},
|
||||||
end_option
|
end_option
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -23,8 +23,6 @@
|
|||||||
#ifndef __CMDLNOPTS_H__
|
#ifndef __CMDLNOPTS_H__
|
||||||
#define __CMDLNOPTS_H__
|
#define __CMDLNOPTS_H__
|
||||||
|
|
||||||
#include "parseargs.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* here are some typedef's for global data
|
* here are some typedef's for global data
|
||||||
*/
|
*/
|
||||||
@ -35,11 +33,15 @@ typedef struct{
|
|||||||
char *pidfile; // name of PID file
|
char *pidfile; // name of PID file
|
||||||
char *logfile; // logging to this file
|
char *logfile; // logging to this file
|
||||||
char *crdsfile; // file where FITS-header should be written
|
char *crdsfile; // file where FITS-header should be written
|
||||||
|
char *weathserver; // weather server name
|
||||||
int emulation; // run in emulation mode
|
int emulation; // run in emulation mode
|
||||||
int rest_pars_num; // number of rest parameters
|
int rest_pars_num; // number of rest parameters
|
||||||
|
int weathport; // weather server port
|
||||||
char** rest_pars; // the rest parameters: array of char*
|
char** rest_pars; // the rest parameters: array of char*
|
||||||
} glob_pars;
|
} glob_pars;
|
||||||
|
|
||||||
|
// global parameters
|
||||||
|
extern glob_pars *GP;
|
||||||
|
|
||||||
glob_pars *parse_args(int argc, char **argv);
|
glob_pars *parse_args(int argc, char **argv);
|
||||||
#endif // __CMDLNOPTS_H__
|
#endif // __CMDLNOPTS_H__
|
||||||
|
|||||||
@ -22,7 +22,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
#include "emulation.h"
|
#include "emulation.h"
|
||||||
#include "usefull_macros.h"
|
#include "usefull_macro.h"
|
||||||
|
|
||||||
// emulation speed over RA & DEC (0.5 degr per sec)
|
// emulation speed over RA & DEC (0.5 degr per sec)
|
||||||
#define RA_SPEED (0.033)
|
#define RA_SPEED (0.033)
|
||||||
|
|||||||
@ -19,7 +19,8 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "libsofa.h"
|
#include "libsofa.h"
|
||||||
#include "usefull_macros.h"
|
#include "socket.h"
|
||||||
|
#include "usefull_macro.h"
|
||||||
|
|
||||||
#ifdef EBUG
|
#ifdef EBUG
|
||||||
void reprd(char* s, double ra, double dc){
|
void reprd(char* s, double ra, double dc){
|
||||||
@ -45,31 +46,73 @@ void radtodeg(double r){
|
|||||||
#define REP(a,b,c)
|
#define REP(a,b,c)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// temporal stubs for weather/place/DUT1 data; return 0 if all OK
|
// temporal stubs for weather/place/DUT1 data; user can change values of these variables
|
||||||
int getPlace(placeData *p){
|
static placeData place = {.slong = 0.7232763200, .slat = 0.7618977414, .salt = 2070.};
|
||||||
if(!p) return 0;
|
placeData *getPlace(){
|
||||||
/* Site longitude, latitude (radians) and height above the geoid (m). */
|
return &place;
|
||||||
p->slong = 0.7232763200;
|
|
||||||
p->slat = 0.7618977414;
|
|
||||||
/*
|
|
||||||
iauAf2a('+', 41, 26, 26.45, &p->slong); // longitude
|
|
||||||
iauAf2a('+', 43, 39, 12.69, &p->slat); // latitude
|
|
||||||
*/
|
|
||||||
p->salt = 2070.0; // altitude
|
|
||||||
//DBG("long: %.10f, lat: %.10f", p->slong, p->slat);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
int getWeath(placeWeather *w){
|
|
||||||
if(!w) return 0;
|
static localWeather weather = {0};
|
||||||
w->relhum = 0.7;
|
typedef struct{
|
||||||
w->tc = 1.;
|
const char *name;
|
||||||
w->php = 780.;
|
double *valptr;
|
||||||
return 0;
|
} weathpars;
|
||||||
|
#define WPCOUNT (7)
|
||||||
|
static weathpars WPars[WPCOUNT] = {
|
||||||
|
{"BTAHumid", &weather.relhum},
|
||||||
|
{"BTAPres", &weather.pres},
|
||||||
|
{"Exttemp", &weather.tc},
|
||||||
|
{"Rain", &weather.rain},
|
||||||
|
{"Clouds", &weather.clouds},
|
||||||
|
{"Wind", &weather.wind},
|
||||||
|
{"Time", &weather.time}
|
||||||
|
};
|
||||||
|
|
||||||
|
localWeather *getWeath(){
|
||||||
|
//DBG("DT=%zd", time(NULL) - (time_t)weather.time);
|
||||||
|
char *w = getweathbuffer();
|
||||||
|
//DBG("w=%s", w);
|
||||||
|
if(w){ // get new data - check it
|
||||||
|
int ctr = 0;
|
||||||
|
for(int i = 0; i < WPCOUNT; ++i){
|
||||||
|
if(getparval(WPars[i].name, w, WPars[i].valptr)) ++ctr;
|
||||||
|
}
|
||||||
|
if(ctr != WPCOUNT) WARN("Not full set of parameters in %s", w);
|
||||||
|
FREE(w);
|
||||||
|
}
|
||||||
|
if((time_t)weather.time == 0 || time(NULL) - (time_t)weather.time > 3600) return NULL;
|
||||||
|
return &weather;
|
||||||
}
|
}
|
||||||
int getDUT(almDut *a){
|
static almDut dut1 = {0};
|
||||||
if(!a) return 0;
|
almDut *getDUT(){
|
||||||
a->px = a->py = a->DUT1 = 0.;
|
// check DUT1 data HERE once per some time
|
||||||
return 0;
|
return &dut1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief r2sHMS - convert angle in radians into string "'HH:MM:SS.SS'"
|
||||||
|
* @param radians - angle
|
||||||
|
* @param hms (o) - string
|
||||||
|
* @param len - length of hms
|
||||||
|
*/
|
||||||
|
void r2sHMS(double radians, char *hms, int len){
|
||||||
|
char pm;
|
||||||
|
int i[4];
|
||||||
|
iauA2tf(2, radians, &pm, i);
|
||||||
|
snprintf(hms, len, "'%c%02d:%02d:%02d.%02d'", pm, i[0],i[1],i[2],i[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief r2sDMS - convert angle in radians into string "'DD:MM:SS.S'"
|
||||||
|
* @param radians - angle
|
||||||
|
* @param dms (o) - string
|
||||||
|
* @param len - length of hms
|
||||||
|
*/
|
||||||
|
void r2sDMS(double radians, char *dms, int len){
|
||||||
|
char pm;
|
||||||
|
int i[4];
|
||||||
|
iauA2af(1, radians, &pm, i);
|
||||||
|
snprintf(dms, len, "'%c%02d:%02d:%02d.%d'", pm, i[0],i[1],i[2],i[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -110,15 +153,89 @@ int get_MJDt(struct timeval *tval, sMJD *MJD){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief get_LST - calculate local siderial time
|
||||||
|
* @param mjd (i) - date/time for LST (utc1 & tt used)
|
||||||
|
* @param dUT1 - (UT1-UTC)
|
||||||
|
* @param slong - site longitude (radians)
|
||||||
|
* @param LST (o) - local sidereal time (radians)
|
||||||
|
* @return 0 if all OK
|
||||||
|
*/
|
||||||
|
int get_LST(sMJD *mjd, double dUT1, double slong, double *LST){
|
||||||
|
double ut11, ut12;
|
||||||
|
sMJD Mjd;
|
||||||
|
if(!mjd){
|
||||||
|
if(get_MJDt(NULL, &Mjd)) return 1;
|
||||||
|
}else memcpy(&Mjd, mjd, sizeof(sMJD));
|
||||||
|
if(iauUtcut1(Mjd.utc1, Mjd.utc2, dUT1, &ut11, &ut12)) return 2;
|
||||||
|
/*double era = iauEra00(ut11, ut12) + slong;
|
||||||
|
double eo = iauEe06a(mjd->tt1, mjd->tt2);
|
||||||
|
printf("ERA = %s; ", radtohrs(era));
|
||||||
|
printf("ERA-eo = %s\n", radtohrs(era-eo));*/
|
||||||
|
if(!LST) return 0;
|
||||||
|
double ST = iauGst06a(ut11, ut12, Mjd.tt1, Mjd.tt2);
|
||||||
|
ST += slong;
|
||||||
|
if(ST > D2PI) ST -= D2PI;
|
||||||
|
else if(ST < 0.) ST += D2PI;
|
||||||
|
*LST = ST;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief hor2eq - convert horizontal coordinates to polar
|
||||||
|
* @param h (i) - horizontal coordinates
|
||||||
|
* @param pc (o) - polar coordinates
|
||||||
|
* @param sidTime - sidereal time
|
||||||
|
*/
|
||||||
|
void hor2eq(horizCrds *h, polarCrds *pc, double sidTime){
|
||||||
|
if(!h || !pc) return;
|
||||||
|
placeData *p = getPlace();
|
||||||
|
iauAe2hd(h->az, DPI/2. - h->zd, p->slat, &pc->ha, &pc->dec); // A,H -> HA,DEC; phi - site latitude
|
||||||
|
pc->ra = sidTime - pc->ha;
|
||||||
|
pc->eo = 0.;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief eq2horH - convert polar coordinates to horizontal
|
||||||
|
* @param pc (i) - polar coordinates (only HA used)
|
||||||
|
* @param h (o) - horizontal coordinates
|
||||||
|
* @param sidTime - sidereal time
|
||||||
|
*/
|
||||||
|
void eq2horH(polarCrds *pc, horizCrds *h){
|
||||||
|
if(!h || !pc) return;
|
||||||
|
placeData *p = getPlace();
|
||||||
|
double alt;
|
||||||
|
iauHd2ae(pc->ha, pc->dec, p->slat, &h->az, &alt);
|
||||||
|
h->zd = DPI/2. - alt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief eq2hor - convert polar coordinates to horizontal
|
||||||
|
* @param pc (i) - polar coordinates (only RA used)
|
||||||
|
* @param h (o) - horizontal coordinates
|
||||||
|
* @param sidTime - sidereal time
|
||||||
|
*/
|
||||||
|
void eq2hor(polarCrds *pc, horizCrds *h, double sidTime){
|
||||||
|
if(!h || !pc) return;
|
||||||
|
double ha = sidTime - pc->ra + pc->eo;
|
||||||
|
placeData *p = getPlace();
|
||||||
|
double alt;
|
||||||
|
iauHd2ae(ha, pc->dec, p->slat, &h->az, &alt);
|
||||||
|
h->zd = DPI/2. - alt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief get_ObsPlace - calculate observed place (without PM etc) for given date @550nm
|
* @brief get_ObsPlace - calculate observed place (without PM etc) for given date @550nm
|
||||||
* @param tval (i) - time
|
* @param tval (i) - time
|
||||||
* @param p2000 (i) - polar coordinates for J2000 (only ra/dec used), ICRS (catalog)
|
* @param p2000 (i) - polar coordinates for J2000 (only ra/dec used), ICRS (catalog)
|
||||||
|
* @param weath (i) - weather data (relhum, temp, press) or NULL if none
|
||||||
* @param pnow (o) - polar coordinates for given epoch (or NULL)
|
* @param pnow (o) - polar coordinates for given epoch (or NULL)
|
||||||
* @param hnow (o) - horizontal coordinates for given epoch (or NULL)
|
* @param hnow (o) - horizontal coordinates for given epoch (or NULL)
|
||||||
* @return 0 if all OK
|
* @return 0 if all OK
|
||||||
*/
|
*/
|
||||||
int get_ObsPlace(struct timeval *tval, polarCrds *p2000, polarCrds *pnow, horizCrds *hnow){
|
int get_ObsPlace(struct timeval *tval, polarCrds *p2000, localWeather *weath, polarCrds *pnow, horizCrds *hnow){
|
||||||
double pr = 0.0; // RA proper motion (radians/year; Note 2)
|
double pr = 0.0; // RA proper motion (radians/year; Note 2)
|
||||||
double pd = 0.0; // Dec proper motion (radians/year)
|
double pd = 0.0; // Dec proper motion (radians/year)
|
||||||
double px = 0.0; // parallax (arcsec)
|
double px = 0.0; // parallax (arcsec)
|
||||||
@ -126,28 +243,26 @@ int get_ObsPlace(struct timeval *tval, polarCrds *p2000, polarCrds *pnow, horizC
|
|||||||
sMJD MJD;
|
sMJD MJD;
|
||||||
if(get_MJDt(tval, &MJD)) return -1;
|
if(get_MJDt(tval, &MJD)) return -1;
|
||||||
if(!p2000) return -1;
|
if(!p2000) return -1;
|
||||||
placeData p;
|
|
||||||
placeWeather w;
|
|
||||||
almDut d;
|
|
||||||
if(getPlace(&p)) return -1;
|
|
||||||
if(getWeath(&w)) return -1;
|
|
||||||
if(getDUT(&d)) return -1;
|
|
||||||
/* Effective wavelength (microns) */
|
/* Effective wavelength (microns) */
|
||||||
double wl = 0.55;
|
double wl = 0.55;
|
||||||
/* ICRS to observed. */
|
/* ICRS to observed. */
|
||||||
double aob, zob, hob, dob, rob, eo;
|
double aob, zob, hob, dob, rob, eo;
|
||||||
/*
|
double p = 0., t = 0., h = 0.;
|
||||||
DBG("iauAtco13(%g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g)",
|
if(weath){
|
||||||
p2000->ra, p2000->dec, pr, pd, px, rv, MJD.utc1, MJD.utc2, d.DUT1, p.slong, p.slat, p.salt,
|
p = weath->pres; t = weath->tc; h = weath->relhum;
|
||||||
d.px, d.py, w.php, w.tc, w.relhum, wl);
|
}
|
||||||
*/
|
/*
|
||||||
|
DBG("iauAtco13(%g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g)",
|
||||||
|
p2000->ra, p2000->dec, pr, pd, px, rv, MJD.utc1, MJD.utc2, d.DUT1, p.slong, p.slat, p.salt,
|
||||||
|
d.px, d.py, p, t, h, wl);
|
||||||
|
*/
|
||||||
if(iauAtco13(p2000->ra, p2000->dec,
|
if(iauAtco13(p2000->ra, p2000->dec,
|
||||||
pr, pd, px, rv,
|
pr, pd, px, rv,
|
||||||
MJD.utc1, MJD.utc2,
|
MJD.utc1, MJD.utc2,
|
||||||
d.DUT1,
|
dut1.DUT1,
|
||||||
p.slong, p.slat, p.salt,
|
place.slong, place.slat, place.salt,
|
||||||
d.px, d.py,
|
dut1.px, dut1.py,
|
||||||
w.php, w.tc, w.relhum,
|
p, t, h,
|
||||||
wl,
|
wl,
|
||||||
&aob, &zob,
|
&aob, &zob,
|
||||||
&hob, &dob, &rob, &eo)) return -1;
|
&hob, &dob, &rob, &eo)) return -1;
|
||||||
|
|||||||
@ -56,10 +56,14 @@ typedef struct{
|
|||||||
|
|
||||||
// place weather data
|
// place weather data
|
||||||
typedef struct{
|
typedef struct{
|
||||||
double relhum; // rel. humidity, 0..1
|
double relhum; // rel. humidity, 0..100%
|
||||||
double php; // atm. pressure (hectopascales)
|
double pres; // atm. pressure (mmHg)
|
||||||
double tc; // temperature, degrC
|
double tc; // temperature, degrC
|
||||||
} placeWeather;
|
double rain; // rain value (0..1)
|
||||||
|
double clouds; // clouds (0 - bad, >2500 - good)
|
||||||
|
double wind; // wind speed, m/s
|
||||||
|
double time; // measurements time
|
||||||
|
} localWeather;
|
||||||
|
|
||||||
// DUT/polar almanach data
|
// DUT/polar almanach data
|
||||||
typedef struct{
|
typedef struct{
|
||||||
@ -68,9 +72,15 @@ typedef struct{
|
|||||||
double py;
|
double py;
|
||||||
} almDut;
|
} almDut;
|
||||||
|
|
||||||
|
void r2sHMS(double radians, char *hms, int len);
|
||||||
|
void r2sDMS(double radians, char *hms, int len);
|
||||||
|
void hor2eq(horizCrds *h, polarCrds *pc, double sidTime);
|
||||||
|
void eq2horH(polarCrds *pc, horizCrds *h);
|
||||||
|
void eq2hor(polarCrds *pc, horizCrds *h, double sidTime);
|
||||||
int get_MJDt(struct timeval *tval, sMJD *MJD);
|
int get_MJDt(struct timeval *tval, sMJD *MJD);
|
||||||
int get_ObsPlace(struct timeval *tval, polarCrds *p2000, polarCrds *pnow, horizCrds *hnow);
|
int get_LST(sMJD *mjd, double dUT1, double slong, double *LST);
|
||||||
int getDUT(almDut *a);
|
int get_ObsPlace(struct timeval *tval, polarCrds *p2000, localWeather *weath, polarCrds *pnow, horizCrds *hnow);
|
||||||
int getWeath(placeWeather *w);
|
almDut *getDUT();
|
||||||
int getPlace(placeData *p);
|
localWeather *getWeath();
|
||||||
|
placeData *getPlace();
|
||||||
#endif // LIBSOFA_H__
|
#endif // LIBSOFA_H__
|
||||||
|
|||||||
@ -34,6 +34,7 @@
|
|||||||
#include "emulation.h"
|
#include "emulation.h"
|
||||||
#include "libsofa.h"
|
#include "libsofa.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "socket.h"
|
||||||
#include "telescope.h"
|
#include "telescope.h"
|
||||||
|
|
||||||
// daemon.c
|
// daemon.c
|
||||||
@ -45,9 +46,6 @@ extern void check4running(char *self, char *pidfilename, void (*iffound)(pid_t p
|
|||||||
// pause for incoming message waiting (out coordinates sent after that timeout)
|
// pause for incoming message waiting (out coordinates sent after that timeout)
|
||||||
#define SOCK_TMOUT (1)
|
#define SOCK_TMOUT (1)
|
||||||
|
|
||||||
// global parameters
|
|
||||||
static glob_pars *GP = NULL;
|
|
||||||
|
|
||||||
static pid_t childpid = 1; // PID of child process
|
static pid_t childpid = 1; // PID of child process
|
||||||
volatile int global_quit = 0;
|
volatile int global_quit = 0;
|
||||||
// quit by signal
|
// quit by signal
|
||||||
@ -56,12 +54,13 @@ void signals(int sig){
|
|||||||
if(childpid){ // parent process
|
if(childpid){ // parent process
|
||||||
restore_tty(); // restore all parameters
|
restore_tty(); // restore all parameters
|
||||||
unlink(GP->pidfile); // and remove pidfile
|
unlink(GP->pidfile); // and remove pidfile
|
||||||
|
weatherserver_disconnect();
|
||||||
}
|
}
|
||||||
DBG("Get signal %d, quit.\n", sig);
|
DBG("Get signal %d, quit.\n", sig);
|
||||||
global_quit = 1;
|
global_quit = 1;
|
||||||
sleep(1);
|
|
||||||
if(childpid) putlog("PID %d exit with status %d after child's %d death", getpid(), sig, childpid);
|
if(childpid) putlog("PID %d exit with status %d after child's %d death", getpid(), sig, childpid);
|
||||||
else WARNX("Child %d died with %d", getpid(), sig);
|
else WARNX("Child %d died with %d", getpid(), sig);
|
||||||
|
sleep(1);
|
||||||
exit(sig);
|
exit(sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,30 +227,33 @@ int proc_data(uint8_t *data, ssize_t len){
|
|||||||
double tagRA = RA2HRS(ra), tagDec = DEC2DEG(dec);
|
double tagRA = RA2HRS(ra), tagDec = DEC2DEG(dec);
|
||||||
DBG("RA: %u (%g), DEC: %d (%g)", ra, tagRA, dec, tagDec);
|
DBG("RA: %u (%g), DEC: %d (%g)", ra, tagRA, dec, tagDec);
|
||||||
// check RA/DEC
|
// check RA/DEC
|
||||||
horizCrds h;
|
horizCrds hnow; // without refraction
|
||||||
polarCrds p;
|
polarCrds p2000, pnow;
|
||||||
p.ra = tagRA/12. * M_PI;
|
p2000.ra = tagRA/12. * M_PI;
|
||||||
p.dec = tagDec * DD2R;
|
p2000.dec = tagDec * DD2R;
|
||||||
if(get_ObsPlace(NULL, &p, NULL, &h)){
|
// now J2000 obs Jnow
|
||||||
WARNX("Can't convert coordinates to horiz");
|
if(get_ObsPlace(NULL, &p2000, NULL, &pnow, &hnow)){
|
||||||
|
WARNX("Can't convert coordinates to Jnow");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#ifdef EBUG
|
#ifdef EBUG
|
||||||
int i[4], j[4]; char pm, pm1;
|
int i[4], j[4]; char pm, pm1;
|
||||||
iauA2af(2, h.az, &pm, i);
|
iauA2af(2, hnow.az, &pm, i);
|
||||||
iauA2af(2, h.zd, &pm1, j);
|
iauA2af(2, hnow.zd, &pm1, j);
|
||||||
DBG("az: %c%02d %02d %02d.%2.d, zd: %c%02d %02d %02d.%2.d",
|
DBG("az: %c%02d %02d %02d.%2.d, zd: %c%02d %02d %02d.%2.d",
|
||||||
pm, i[0],i[1],i[2],i[3],
|
pm, i[0],i[1],i[2],i[3],
|
||||||
pm1,j[0],j[1],j[2],j[3]);
|
pm1,j[0],j[1],j[2],j[3]);
|
||||||
iauA2af(2, M_PI_2 - h.zd, &pm, i);
|
iauA2af(2, M_PI_2 - hnow.zd, &pm, i);
|
||||||
DBG("h: %c%02d %02d %02d.%2.d", pm, i[0],i[1],i[2],i[3]);
|
DBG("h: %c%02d %02d %02d.%2.d", pm, i[0],i[1],i[2],i[3]);
|
||||||
#endif
|
#endif
|
||||||
if(h.zd > 80.*DD2R){
|
if(hnow.zd > 80.*DD2R){
|
||||||
WARNX("Z > 80degr, stop telescope");
|
WARNX("Z > 80degr, stop telescope");
|
||||||
putlog("Z>80 - stop!");
|
putlog("Z>80 - stop!");
|
||||||
stop_telescope();
|
stop_telescope();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
tagRA = (pnow.ra - pnow.eo) / M_PI * 12.;
|
||||||
|
tagDec = pnow.dec / DD2R;
|
||||||
if(!setCoords(tagRA, tagDec)) return 0;
|
if(!setCoords(tagRA, tagDec)) return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -318,7 +320,7 @@ static void *hdrthread(_U_ void *buf){
|
|||||||
// write FITS-header at most once per second
|
// write FITS-header at most once per second
|
||||||
while(!global_quit){
|
while(!global_quit){
|
||||||
wrhdr();
|
wrhdr();
|
||||||
usleep(1000); // give a chance to write/read for others
|
usleep(100000); // give a chance to write/read for others
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -446,6 +448,10 @@ static inline void main_proc(){
|
|||||||
if(pthread_create(&termthrd, NULL, termthread, NULL))
|
if(pthread_create(&termthrd, NULL, termthread, NULL))
|
||||||
ERR(_("Can't create terminal thread"));
|
ERR(_("Can't create terminal thread"));
|
||||||
}
|
}
|
||||||
|
// connect to weather daemon
|
||||||
|
if(!weatherserver_connect()){
|
||||||
|
DBG("Can't connect to weather server, will try later");
|
||||||
|
}
|
||||||
// open socket
|
// open socket
|
||||||
int sock = opensocket(GP->port);
|
int sock = opensocket(GP->port);
|
||||||
if(sock < 0){
|
if(sock < 0){
|
||||||
@ -488,6 +494,7 @@ int main(int argc, char **argv){
|
|||||||
if(GP->logfile) openlogfile(GP->logfile);
|
if(GP->logfile) openlogfile(GP->logfile);
|
||||||
putlog("Starting, master PID=%d", getpid());
|
putlog("Starting, master PID=%d", getpid());
|
||||||
|
|
||||||
|
#ifndef EBUG
|
||||||
while(1){
|
while(1){
|
||||||
childpid = fork();
|
childpid = fork();
|
||||||
if(childpid < 0){
|
if(childpid < 0){
|
||||||
@ -506,6 +513,9 @@ int main(int argc, char **argv){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
main_proc();
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,7 +34,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "cmdlnopts.h"
|
#include "cmdlnopts.h"
|
||||||
#include "usefull_macros.h"
|
#include "usefull_macro.h"
|
||||||
|
|
||||||
// global parameters
|
// global parameters
|
||||||
extern glob_pars *Global_parameters;
|
extern glob_pars *Global_parameters;
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
#include <libintl.h>// gettext
|
#include <libintl.h>// gettext
|
||||||
#include <ctype.h> // isalpha
|
#include <ctype.h> // isalpha
|
||||||
#include "parseargs.h"
|
#include "parseargs.h"
|
||||||
#include "usefull_macros.h"
|
#include "usefull_macro.h"
|
||||||
|
|
||||||
char *helpstring = "%s\n";
|
char *helpstring = "%s\n";
|
||||||
|
|
||||||
|
|||||||
208
Daemons/10micron_stellarium/socket.c
Normal file
208
Daemons/10micron_stellarium/socket.c
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the StelD project.
|
||||||
|
* Copyright 2021 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include "cmdlnopts.h"
|
||||||
|
#include "socket.h"
|
||||||
|
#include "usefull_macro.h"
|
||||||
|
|
||||||
|
// max time to wait answer from server
|
||||||
|
#define WAITANSTIME (1.0)
|
||||||
|
|
||||||
|
static int sockfd = -1; // server file descriptor
|
||||||
|
static pthread_t sock_thread;
|
||||||
|
static char buf[BUFSIZ]; // buffer for messages
|
||||||
|
static int Nread; // amount of bytes in buf
|
||||||
|
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
static void *getmessages(_U_ void *par);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief weatherserver_connect - connect to a weather server
|
||||||
|
* @return FALSE if failed
|
||||||
|
*/
|
||||||
|
int weatherserver_connect(){
|
||||||
|
if(sockfd > 0) return TRUE;
|
||||||
|
DBG("connect to %s:%d", GP->weathserver, GP->weathport);
|
||||||
|
char port[10];
|
||||||
|
snprintf(port, 10, "%d", GP->weathport);
|
||||||
|
struct addrinfo hints = {0}, *res, *p;
|
||||||
|
hints.ai_family = AF_INET;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
hints.ai_flags = AI_PASSIVE;
|
||||||
|
if(getaddrinfo(GP->weathserver, port, &hints, &res) != 0){
|
||||||
|
WARN("getaddrinfo()");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
// loop through all the results and connect to the first we can
|
||||||
|
for(p = res; p; p = p->ai_next){
|
||||||
|
if((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1){
|
||||||
|
WARN("socket");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(connect(sockfd, p->ai_addr, p->ai_addrlen) == -1){
|
||||||
|
WARN("connect()");
|
||||||
|
close(sockfd);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break; // if we get here, we have a successfull connection
|
||||||
|
}
|
||||||
|
if(!p){
|
||||||
|
WARNX("Can't connect to socket");
|
||||||
|
sockfd = -1;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
freeaddrinfo(res);
|
||||||
|
if(pthread_create(&sock_thread, NULL, getmessages, NULL)){
|
||||||
|
WARN("pthread_create()");
|
||||||
|
weatherserver_disconnect();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
DBG("connected, fd=%d", sockfd);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void weatherserver_disconnect(){
|
||||||
|
if(sockfd > -1){
|
||||||
|
pthread_kill(sock_thread, 9);
|
||||||
|
pthread_join(sock_thread, NULL);
|
||||||
|
close(sockfd);
|
||||||
|
}
|
||||||
|
sockfd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief getparval - return value of parameter
|
||||||
|
* @param par (i) - parameter value
|
||||||
|
* @param ansbuf (i) - buffer with server answer
|
||||||
|
* @param val (o) - value of parameter
|
||||||
|
* @return TRUE if parameter found and set `val` to its value
|
||||||
|
*/
|
||||||
|
int getparval(const char *par, const char *ansbuf, double *val){
|
||||||
|
if(!par || !ansbuf) return FALSE;
|
||||||
|
int ret = FALSE;
|
||||||
|
char *b = strdup(ansbuf);
|
||||||
|
char *parval = NULL, *token = strtok(b, "\n");
|
||||||
|
int l = strlen(par);
|
||||||
|
if(!token) goto rtn;
|
||||||
|
while(token){
|
||||||
|
if(strncmp(token, par, l) == 0){ // found
|
||||||
|
//DBG("token: '%s'", token);
|
||||||
|
parval = strchr(token, '=');
|
||||||
|
if(!parval) goto rtn;
|
||||||
|
++parval; while(*parval == ' ' || *parval == '\t') ++parval;
|
||||||
|
//DBG("parval: '%s'", parval);
|
||||||
|
ret = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
token = strtok(NULL, "\n");
|
||||||
|
}
|
||||||
|
if(parval && val){
|
||||||
|
*val = atof(parval);
|
||||||
|
//DBG("Set %s to %g", par, *val);
|
||||||
|
}
|
||||||
|
rtn:
|
||||||
|
FREE(b);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wait for answer from socket
|
||||||
|
* @return FALSE in case of error or timeout, TRUE if socket is ready
|
||||||
|
*/
|
||||||
|
static int canread(){
|
||||||
|
if(sockfd < 0) return FALSE;
|
||||||
|
fd_set fds;
|
||||||
|
struct timeval timeout;
|
||||||
|
int rc;
|
||||||
|
// wait not more than 10ms
|
||||||
|
timeout.tv_sec = 0;
|
||||||
|
timeout.tv_usec = 10000;
|
||||||
|
FD_ZERO(&fds);
|
||||||
|
FD_SET(sockfd, &fds);
|
||||||
|
do{
|
||||||
|
rc = select(sockfd+1, &fds, NULL, NULL, &timeout);
|
||||||
|
if(rc < 0){
|
||||||
|
if(errno != EINTR){
|
||||||
|
WARN("select()");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}while(1);
|
||||||
|
if(FD_ISSET(sockfd, &fds)) return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief getmessages - continuosly read data from server and fill buffer
|
||||||
|
*/
|
||||||
|
static void *getmessages(_U_ void *par){
|
||||||
|
write(sockfd, "get\n", 4);
|
||||||
|
while(sockfd > 0){
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
if(Nread == 0){
|
||||||
|
double t0 = dtime();
|
||||||
|
while(dtime() - t0 < WAITANSTIME && Nread < BUFSIZ){
|
||||||
|
if(!canread()) continue;
|
||||||
|
int n = read(sockfd, buf+Nread, BUFSIZ-Nread);
|
||||||
|
if(n == 0) break;
|
||||||
|
if(n < 0){
|
||||||
|
close(sockfd);
|
||||||
|
sockfd = -1;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
Nread += n;
|
||||||
|
}
|
||||||
|
if(Nread){
|
||||||
|
buf[Nread] = 0;
|
||||||
|
//DBG("got %d: %s", Nread, buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
if(Nread == 0){
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief getweathbuffer - read whole buffer with data and set Nread to zero
|
||||||
|
* @return NULL if no data or buffer (allocated here)
|
||||||
|
*/
|
||||||
|
char *getweathbuffer(){
|
||||||
|
if(!weatherserver_connect()) return NULL; // not connected & can't connect
|
||||||
|
char *ret = NULL;
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
if(Nread){
|
||||||
|
ret = strdup(buf);
|
||||||
|
Nread = 0;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
28
Daemons/10micron_stellarium/socket.h
Normal file
28
Daemons/10micron_stellarium/socket.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the StelD project.
|
||||||
|
* Copyright 2021 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef SOCKET_H__
|
||||||
|
#define SOCKET_H__
|
||||||
|
|
||||||
|
void weatherserver_disconnect();
|
||||||
|
int weatherserver_connect();
|
||||||
|
int getparval(const char *par, const char *ansbuf, double *val);
|
||||||
|
char *getweathbuffer();
|
||||||
|
|
||||||
|
#endif // SOCKET_H__
|
||||||
@ -28,7 +28,7 @@
|
|||||||
#include "libsofa.h"
|
#include "libsofa.h"
|
||||||
#include "main.h" // global_quit
|
#include "main.h" // global_quit
|
||||||
#include "telescope.h"
|
#include "telescope.h"
|
||||||
#include "usefull_macros.h"
|
#include "usefull_macro.h"
|
||||||
|
|
||||||
// polling timeout for answer from mount
|
// polling timeout for answer from mount
|
||||||
#ifndef T_POLLING_TMOUT
|
#ifndef T_POLLING_TMOUT
|
||||||
@ -45,6 +45,12 @@ static char *hdname = NULL;
|
|||||||
static double ptRAdeg, ptDECdeg; // target RA/DEC J2000
|
static double ptRAdeg, ptDECdeg; // target RA/DEC J2000
|
||||||
static int Target = 0; // target coordinates entered
|
static int Target = 0; // target coordinates entered
|
||||||
|
|
||||||
|
static double r = 0., d = 0.; // RA/DEC from wrhdr
|
||||||
|
static int mountstatus = 0; // return of :Gstat#
|
||||||
|
static time_t tlast = 0; // last time coordinates were refreshed
|
||||||
|
|
||||||
|
static int pause_communication = 0; // ==1 to prevent writing to port outside of terminal thread
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* read strings from terminal (ending with '\n') with timeout
|
* read strings from terminal (ending with '\n') with timeout
|
||||||
* @return NULL if nothing was read or pointer to static buffer
|
* @return NULL if nothing was read or pointer to static buffer
|
||||||
@ -96,7 +102,7 @@ static char *write_cmd(const char *cmd, char *buff){
|
|||||||
char *ans;
|
char *ans;
|
||||||
while(dtime() - t0 < T_POLLING_TMOUT){ // read answer
|
while(dtime() - t0 < T_POLLING_TMOUT){ // read answer
|
||||||
if((ans = read_string())){ // parse new data
|
if((ans = read_string())){ // parse new data
|
||||||
// DBG("got answer: %s", ans);
|
//DBG("got answer: %s", ans);
|
||||||
pthread_mutex_unlock(&mutex);
|
pthread_mutex_unlock(&mutex);
|
||||||
if(!buff) return NULL;
|
if(!buff) return NULL;
|
||||||
strncpy(buff, ans, BUFLEN-1);
|
strncpy(buff, ans, BUFLEN-1);
|
||||||
@ -108,22 +114,24 @@ static char *write_cmd(const char *cmd, char *buff){
|
|||||||
}
|
}
|
||||||
|
|
||||||
// write to telescope mount corrections: datetime, pressure and temperature
|
// write to telescope mount corrections: datetime, pressure and temperature
|
||||||
// @return 1 if time was corrected
|
// @return 1 if time and weather was corrected
|
||||||
static int makecorr(){
|
static int makecorr(){
|
||||||
int ret = 0;
|
if(pause_communication) return 0;
|
||||||
|
int ret = 1;
|
||||||
// write current date&time
|
// write current date&time
|
||||||
char buf[64], ibuff[BUFLEN], *ans;
|
char buf[64], ibuff[BUFLEN], *ans;
|
||||||
DBG("curtime: %s", write_cmd(":GUDT#", ibuff));
|
DBG("curtime: %s", write_cmd(":GUDT#", ibuff));
|
||||||
ans = write_cmd(":Gstat#", ibuff);
|
ans = write_cmd(":Gstat#", ibuff);
|
||||||
|
if(ans){
|
||||||
|
mountstatus = atoi(ans);
|
||||||
|
// if system is in tracking or unknown state - don't update data!
|
||||||
|
if(mountstatus == TEL_SLEWING || mountstatus == TEL_TRACKING) return 0;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* there's no GPS on this mount and there's no need for it!
|
* there's no GPS on this mount and there's no need for it!
|
||||||
write_cmd(":gT#", NULL); // correct time by GPS
|
write_cmd(":gT#", NULL); // correct time by GPS
|
||||||
ans = write_cmd(":gtg#", ibuff);
|
ans = write_cmd(":gtg#", ibuff);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if(!ans || *ans == '0'){ // system is in tracking or unknown state - don't update data!
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
WARNX("Refresh datetime");
|
WARNX("Refresh datetime");
|
||||||
time_t t = time(NULL);
|
time_t t = time(NULL);
|
||||||
struct tm *stm = localtime(&t);
|
struct tm *stm = localtime(&t);
|
||||||
@ -136,27 +144,33 @@ static int makecorr(){
|
|||||||
if(!ans || *ans != '1'){
|
if(!ans || *ans != '1'){
|
||||||
WARNX("Can't write current date/time");
|
WARNX("Can't write current date/time");
|
||||||
putlog("Can't set system time");
|
putlog("Can't set system time");
|
||||||
|
ret = 0;
|
||||||
}else{
|
}else{
|
||||||
putlog("Set system time by command %s", buf);
|
putlog("Set system time by command %s", buf);
|
||||||
ret = 1;
|
|
||||||
}
|
}
|
||||||
DBG("curtime: %s", write_cmd(":GUDT#", ibuff));
|
DBG("curtime: %s", write_cmd(":GUDT#", ibuff));
|
||||||
sprintf(buf, ":SREF0#"); // turn off 2-coord guiding & refraction
|
localWeather *w = getWeath();
|
||||||
write_cmd(buf, ibuff);
|
if(!w){
|
||||||
sprintf(buf, ":Sdat0#"); // turn off dual-axis tracking
|
ret = 0;
|
||||||
write_cmd(buf, ibuff);
|
putlog("Can't determine weather data");
|
||||||
/*placeWeather w;
|
}else{ // set refraction model data
|
||||||
if(getWeath(&w)) putlog("Can't determine weather data");
|
snprintf(buf, 64, ":SRPRS%.1f#", w->pres*1013./760.);
|
||||||
else{ // set refraction model data
|
|
||||||
snprintf(buf, 64, ":SRPRS%.1f#", w.php);
|
|
||||||
ans = write_cmd(buf, ibuff);
|
ans = write_cmd(buf, ibuff);
|
||||||
if(!ans || *ans != '1') putlog("Can't set pressure data of refraction model");
|
if(!ans || *ans != '1'){
|
||||||
else putlog("Correct pressure to %g", w.php);
|
ret = 0;
|
||||||
snprintf(buf, 64, ":SRTMP%.1f#", w.tc);
|
putlog("Can't set pressure data of refraction model");
|
||||||
|
}else putlog("Correct pressure to %gmmHg", w->pres);
|
||||||
|
snprintf(buf, 64, ":SRTMP%.1f#", w->tc);
|
||||||
ans = write_cmd(buf, ibuff);
|
ans = write_cmd(buf, ibuff);
|
||||||
if(!ans || *ans != '1') putlog("Can't set temperature data of refraction model");
|
if(!ans || *ans != '1'){
|
||||||
else putlog("Correct temperature to %g", w.tc);
|
ret = 0;
|
||||||
}*/
|
putlog("Can't set temperature data of refraction model");
|
||||||
|
}else putlog("Correct temperature to %g", w->tc);
|
||||||
|
}
|
||||||
|
sprintf(buf, ":SREF1#"); // turn on refraction correction
|
||||||
|
write_cmd(buf, ibuff);
|
||||||
|
sprintf(buf, ":Sdat1#"); // turn on dual-axis tracking
|
||||||
|
write_cmd(buf, ibuff);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,7 +215,8 @@ int connect_telescope(char *dev, char *hdrname){
|
|||||||
hdname = strdup(hdrname);
|
hdname = strdup(hdrname);
|
||||||
DBG("connected");
|
DBG("connected");
|
||||||
Target = 0;
|
Target = 0;
|
||||||
write_cmd(":gT#", NULL); // correct time by GPS
|
getWeath(); getPlace(); getDUT(); // determine starting values
|
||||||
|
//write_cmd(":gT#", NULL); // correct time by GPS
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,11 +227,15 @@ int connect_telescope(char *dev, char *hdrname){
|
|||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* send coordinates to telescope
|
* send coordinates to telescope
|
||||||
* @param ra - right ascention (hours)
|
* @param ra - right ascention (hours), Jnow without refraction
|
||||||
* @param dec - declination (degrees)
|
* @param dec - declination (degrees), Jnow without refraction
|
||||||
* @return 1 if all OK
|
* @return 1 if all OK
|
||||||
*/
|
*/
|
||||||
int point_telescope(double ra, double dec){
|
int point_telescope(double ra, double dec){
|
||||||
|
if(pause_communication){
|
||||||
|
putlog("Can't point telescope in paused mode");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
DBG("try to send ra=%g, decl=%g", ra, dec);
|
DBG("try to send ra=%g, decl=%g", ra, dec);
|
||||||
ptRAdeg = ra * 15.;
|
ptRAdeg = ra * 15.;
|
||||||
ptDECdeg = dec;
|
ptDECdeg = dec;
|
||||||
@ -322,10 +341,6 @@ static int printhdr(int fd, const char *key, const char *val, const char *cmnt){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static double r = 0., d = 0.; // RA/DEC from wrhdr
|
|
||||||
static int mountstatus = 0; // return of :Gstat#
|
|
||||||
static time_t tlast = 0; // last time coordinates were refreshed
|
|
||||||
/**
|
/**
|
||||||
* get coordinates
|
* get coordinates
|
||||||
* @param ra (o) - right ascension (hours)
|
* @param ra (o) - right ascension (hours)
|
||||||
@ -340,11 +355,15 @@ int get_telescope_coords(double *ra, double *decl){
|
|||||||
return mountstatus;
|
return mountstatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
void stop_telescope(){
|
void stop_telescope(){ // work even in paused mode if moving!
|
||||||
|
Target = 0;
|
||||||
|
if(pause_communication){
|
||||||
|
if(mountstatus == TEL_PARKED || mountstatus == TEL_STOPPED || mountstatus == TEL_INHIBITED
|
||||||
|
|| mountstatus == TEL_OUTLIMIT) return;
|
||||||
|
}
|
||||||
write_cmd(":RT9#", NULL); // stop tracking
|
write_cmd(":RT9#", NULL); // stop tracking
|
||||||
write_cmd(":AL#", NULL); // stop tracking
|
write_cmd(":AL#", NULL); // stop tracking
|
||||||
write_cmd(":STOP#", NULL); // halt moving
|
write_cmd(":STOP#", NULL); // halt moving
|
||||||
Target = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// site characteristics
|
// site characteristics
|
||||||
@ -391,18 +410,18 @@ static void getplace(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const char *statuses[12] = {
|
static const char *statuses[12] = {
|
||||||
[0] = "'Tracking'",
|
[TEL_TRACKING] = "'Tracking'",
|
||||||
[1] = "'Stopped or homing'",
|
[TEL_STOPHOM] = "'Stopped or homing'",
|
||||||
[2] = "'Slewing to park'",
|
[TEL_PARKING] = "'Slewing to park'",
|
||||||
[3] = "'Unparking'",
|
[TEL_UNPARKING] = "'Unparking'",
|
||||||
[4] = "'Slewing to home'",
|
[TEL_HOMING] = "'Slewing to home'",
|
||||||
[5] = "'Parked'",
|
[TEL_PARKED] = "'Parked'",
|
||||||
[6] = "'Slewing or going to stop'",
|
[TEL_SLEWING] = "'Slewing or going to stop'",
|
||||||
[7] = "'Stopped'",
|
[TEL_STOPPED] = "'Stopped'",
|
||||||
[8] = "'Motors inhibited, T too low'",
|
[TEL_INHIBITED] = "'Motors inhibited, T too low'",
|
||||||
[9] = "'Outside tracking limit'",
|
[TEL_OUTLIMIT] = "'Outside tracking limit'",
|
||||||
[10]= "'Following satellite'",
|
[TEL_FOLSAT]= "'Following satellite'",
|
||||||
[11]= "'Data inconsistency'"
|
[TEL_DATINCOSIST]= "'Data inconsistency'"
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -412,7 +431,7 @@ static const char *statuses[12] = {
|
|||||||
*/
|
*/
|
||||||
static const char* strstatus(int status){
|
static const char* strstatus(int status){
|
||||||
if(status < 0) return "'Signal lost'";
|
if(status < 0) return "'Signal lost'";
|
||||||
if(status < (int)(sizeof(statuses)/sizeof(char*)-1)) return statuses[status];
|
if(status < TEL_MAXSTATUS) return statuses[status];
|
||||||
if(status == 99) return "'Error'";
|
if(status == 99) return "'Error'";
|
||||||
return "'Unknown status'";
|
return "'Unknown status'";
|
||||||
}
|
}
|
||||||
@ -421,9 +440,21 @@ static const char* strstatus(int status){
|
|||||||
* @brief wrhdr - try to write into header file
|
* @brief wrhdr - try to write into header file
|
||||||
*/
|
*/
|
||||||
void wrhdr(){
|
void wrhdr(){
|
||||||
|
static time_t commWasPaused = 0;
|
||||||
|
if(pause_communication){ // don't allow pauses more for 15 minutes!
|
||||||
|
if(commWasPaused == 0){
|
||||||
|
commWasPaused = time(NULL);
|
||||||
|
return;
|
||||||
|
}else{
|
||||||
|
if(time(NULL) - commWasPaused > 15*60){
|
||||||
|
putlog("Clear communication pause after 15 minutes");
|
||||||
|
pause_communication = 0;
|
||||||
|
}else return;
|
||||||
|
}
|
||||||
|
}
|
||||||
static int failcounter = 0;
|
static int failcounter = 0;
|
||||||
static time_t lastcorr = 0; // last time of corrections made
|
static time_t lastcorr = 0; // last time of corrections made
|
||||||
if(time(NULL) - lastcorr > CORRECTIONS_TIMEDIFF){
|
if(time(NULL) - lastcorr > CORRECTIONS_TIMEDIFF){ // make correction once per hour
|
||||||
if(makecorr()) lastcorr = time(NULL);
|
if(makecorr()) lastcorr = time(NULL);
|
||||||
else lastcorr += 30; // failed -> check 30s later
|
else lastcorr += 30; // failed -> check 30s later
|
||||||
}
|
}
|
||||||
@ -437,6 +468,7 @@ void wrhdr(){
|
|||||||
DBG("Can't get RA!");
|
DBG("Can't get RA!");
|
||||||
signals(9);
|
signals(9);
|
||||||
}
|
}
|
||||||
|
DBG("Failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ans = write_cmd(":GD#", ibuff);
|
ans = write_cmd(":GD#", ibuff);
|
||||||
@ -446,8 +478,43 @@ void wrhdr(){
|
|||||||
DBG("Can't get DEC!");
|
DBG("Can't get DEC!");
|
||||||
signals(9);
|
signals(9);
|
||||||
}
|
}
|
||||||
|
DBG("Failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
almDut *dut = getDUT();
|
||||||
|
localWeather *weather = getWeath();
|
||||||
|
double LST = 0; // local sidereal time IN RADIANS!
|
||||||
|
|
||||||
|
placeData *place = getPlace();
|
||||||
|
if(get_LST(NULL, dut->DUT1, place->slong, &LST)){
|
||||||
|
DBG("Can't calculate coordinates, get from mount");
|
||||||
|
ans = write_cmd(":GS#", ibuff);
|
||||||
|
lst = dups(ans, 1);
|
||||||
|
if(!str2coord(ans, &LST)){
|
||||||
|
if(++failcounter == 10){
|
||||||
|
putlog("Lost connection with mount");
|
||||||
|
DBG("Can't get LST!");
|
||||||
|
signals(9);
|
||||||
|
}
|
||||||
|
DBG("Failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
LST *= 15.*DD2R; // convert hours to radians
|
||||||
|
}else{
|
||||||
|
lst = MALLOC(char, 32);
|
||||||
|
r2sHMS(LST, lst, 32);
|
||||||
|
}
|
||||||
|
sMJD mjd;
|
||||||
|
if(get_MJDt(NULL, &mjd)){
|
||||||
|
ans = write_cmd(":GJD1#", ibuff);
|
||||||
|
jd = dups(ans, 0);
|
||||||
|
}else{
|
||||||
|
jd = MALLOC(char, 32);
|
||||||
|
snprintf(jd, 32, "%.10f", mjd.MJD);
|
||||||
|
}
|
||||||
|
polarCrds pNow = {.ra = r*15.*DD2R, .dec = d*DD2R}; // coordinates now
|
||||||
|
horizCrds hNow;
|
||||||
|
eq2hor(&pNow, &hNow, LST);
|
||||||
failcounter = 0;
|
failcounter = 0;
|
||||||
tlast = time(NULL);
|
tlast = time(NULL);
|
||||||
// check it here, not in the beginning of function - to check connection with mount first
|
// check it here, not in the beginning of function - to check connection with mount first
|
||||||
@ -456,8 +523,6 @@ void wrhdr(){
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(!elevation || !longitude || !latitude) getplace();
|
if(!elevation || !longitude || !latitude) getplace();
|
||||||
ans = write_cmd(":GJD1#", ibuff); jd = dups(ans, 0);
|
|
||||||
ans = write_cmd(":GS#", ibuff); lst = dups(ans, 1);
|
|
||||||
ans = write_cmd(":GUDT#", ibuff);
|
ans = write_cmd(":GUDT#", ibuff);
|
||||||
if(ans){
|
if(ans){
|
||||||
char *comma = strchr(ans, ',');
|
char *comma = strchr(ans, ',');
|
||||||
@ -487,7 +552,13 @@ void wrhdr(){
|
|||||||
#define WRHDR(k, v, c) do{if(printhdr(fd, k, v, c)){goto returning;}}while(0)
|
#define WRHDR(k, v, c) do{if(printhdr(fd, k, v, c)){goto returning;}}while(0)
|
||||||
WRHDR("TIMESYS", "'UTC'", "Time system");
|
WRHDR("TIMESYS", "'UTC'", "Time system");
|
||||||
WRHDR("ORIGIN", "'SAO RAS'", "Organization responsible for the data");
|
WRHDR("ORIGIN", "'SAO RAS'", "Organization responsible for the data");
|
||||||
WRHDR("TELESCOP", "'Astrosib-500'", "Telescope name");
|
WRHDR("TELESCOP", TELESCOPE_NAME, "Telescope name");
|
||||||
|
snprintf(val, 22, "%.10f", dut->px);
|
||||||
|
WRHDR("POLARX", val, "IERS pole X coordinate, arcsec");
|
||||||
|
snprintf(val, 22, "%.10f", dut->py);
|
||||||
|
WRHDR("POLARY", val, "IERS pole Y coordinate, arcsec");
|
||||||
|
snprintf(val, 22, "%.10f", dut->py);
|
||||||
|
WRHDR("DUT1", val, "IERS `UT1-UTC`, sec");
|
||||||
if(Target){ // target coordinates entered - store them @header
|
if(Target){ // target coordinates entered - store them @header
|
||||||
snprintf(val, 22, "%.10f", ptRAdeg);
|
snprintf(val, 22, "%.10f", ptRAdeg);
|
||||||
WRHDR("TAGRA", val, "Target RA (J2000), degrees");
|
WRHDR("TAGRA", val, "Target RA (J2000), degrees");
|
||||||
@ -495,24 +566,47 @@ void wrhdr(){
|
|||||||
WRHDR("TAGDEC", val, "Target DEC (J2000), degrees");
|
WRHDR("TAGDEC", val, "Target DEC (J2000), degrees");
|
||||||
}
|
}
|
||||||
snprintf(val, 22, "%.10f", r*15.); // convert RA to degrees
|
snprintf(val, 22, "%.10f", r*15.); // convert RA to degrees
|
||||||
WRHDR("RA", val, "Telescope right ascension, current epoch");
|
WRHDR("RA", val, "Telescope right ascension, current epoch, deg");
|
||||||
snprintf(val, 22, "%.10f", d);
|
snprintf(val, 22, "%.10f", d);
|
||||||
WRHDR("DEC", val, "Telescope declination, current epoch");
|
WRHDR("DEC", val, "Telescope declination, current epoch, deg");
|
||||||
|
snprintf(val, 22, "%.10f", hNow.az * DR2D);
|
||||||
|
WRHDR("AZ", val, "Telescope azimuth, current epoch, deg");
|
||||||
|
snprintf(val, 22, "%.10f", hNow.zd * DR2D);
|
||||||
|
WRHDR("ZD", val, "Telescope zenith distance, current epoch, deg");
|
||||||
WRHDR("TELSTAT", strstatus(mountstatus), "Telescope mount status");
|
WRHDR("TELSTAT", strstatus(mountstatus), "Telescope mount status");
|
||||||
sMJD mjd;
|
|
||||||
if(!get_MJDt(NULL, &mjd)){
|
if(!get_MJDt(NULL, &mjd)){
|
||||||
snprintf(val, 22, "%.10f", 2000.+(mjd.MJD-MJD2000)/365.25); // calculate EPOCH/EQUINOX
|
snprintf(val, 22, "%.10f", 2000.+(mjd.MJD-MJD2000)/365.25); // calculate EPOCH/EQUINOX
|
||||||
WRHDR("EQUINOX", val, "Equinox of celestial coordinate system");
|
WRHDR("EQUINOX", val, "Equinox of celestial coordinate system");
|
||||||
snprintf(val, 22, "%.10f", mjd.MJD);
|
if(!jd){
|
||||||
WRHDR("MJD-END", val, "Modified julian date of observations end");
|
snprintf(val, 22, "%.10f", mjd.MJD);
|
||||||
|
WRHDR("MJD-END", val, "Modified julian date of observations end");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(jd){
|
||||||
|
WRHDR("MJD-END", jd, "Modified julian date of observations end");
|
||||||
}
|
}
|
||||||
if(jd) WRHDR("JD-END", jd, "Julian date of observations end");
|
|
||||||
if(pS) WRHDR("PIERSIDE", pS, "Pier side of telescope mount");
|
if(pS) WRHDR("PIERSIDE", pS, "Pier side of telescope mount");
|
||||||
if(elevation) WRHDR("ELEVAT", elevation, "Elevation of site over the sea level");
|
if(elevation) WRHDR("ELEVAT", elevation, "Elevation of site over the sea level");
|
||||||
if(longitude) WRHDR("LONGITUD", longitude, "Geo longitude of site (east negative)");
|
if(longitude) WRHDR("LONGITUD", longitude, "Geo longitude of site (east negative)");
|
||||||
if(latitude) WRHDR("LATITUDE", latitude, "Geo latitude of site (south negative)");
|
if(latitude) WRHDR("LATITUDE", latitude, "Geo latitude of site (south negative)");
|
||||||
if(lst) WRHDR("LSTEND", lst, "Local sidereal time of observations end");
|
if(lst) WRHDR("LSTEND", lst, "Local sidereal time of observations end");
|
||||||
if(date) WRHDR("DATE-END", date, "Date (UTC) of observations end");
|
if(date) WRHDR("DATE-END", date, "Date (UTC) of observations end");
|
||||||
|
if(weather){
|
||||||
|
snprintf(val, 22, "%.1f", weather->relhum);
|
||||||
|
WRHDR("HUMIDITY", val, "Relative humidity, %%");
|
||||||
|
snprintf(val, 22, "%.1f", weather->pres);
|
||||||
|
WRHDR("PRESSURE", val, "Atmospheric pressure, mmHg");
|
||||||
|
snprintf(val, 22, "%.1f", weather->tc);
|
||||||
|
WRHDR("EXTTEMP", val, "External temperature, degrC");
|
||||||
|
snprintf(val, 22, "%.0f", weather->rain);
|
||||||
|
WRHDR("RAIN", val, "Rain conditions");
|
||||||
|
snprintf(val, 22, "%.1f", weather->clouds);
|
||||||
|
WRHDR("SKYQUAL", val, "Sky quality (0 - wery bad, >2500 - good)");
|
||||||
|
snprintf(val, 22, "%.1f", weather->wind);
|
||||||
|
WRHDR("WINDSPD", val, "Wind speed (m/s)");
|
||||||
|
snprintf(val, 22, "%.0f", weather->time);
|
||||||
|
WRHDR("WEATTIME", val, "Unix time of weather measurements");
|
||||||
|
}
|
||||||
// WRHDR("", , "");
|
// WRHDR("", , "");
|
||||||
#undef WRHDR
|
#undef WRHDR
|
||||||
returning:
|
returning:
|
||||||
@ -543,9 +637,22 @@ void *term_thread(void *sockd){
|
|||||||
char *ch = strchr(buff, '\n');
|
char *ch = strchr(buff, '\n');
|
||||||
if(ch) *ch = 0;
|
if(ch) *ch = 0;
|
||||||
if(!buff[0]) continue; // empty string
|
if(!buff[0]) continue; // empty string
|
||||||
|
DBG("%s COMMAND: %s", peerIP, buff);
|
||||||
|
if(strcasecmp(buff, "pause") == 0){
|
||||||
|
DBG("PAUSED");
|
||||||
|
putlog("Port writing outside terminal thread is paused");
|
||||||
|
pause_communication = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(strcasecmp(buff, "continue") == 0){
|
||||||
|
DBG("CONTINUED");
|
||||||
|
putlog("Port writing outside terminal thread is restored by user");
|
||||||
|
pause_communication = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
char *ans = write_cmd(buff, ibuff);
|
char *ans = write_cmd(buff, ibuff);
|
||||||
putlog("%s COMMAND %s ANSWER %s", peerIP, buff, ibuff);
|
putlog("%s COMMAND %s ANSWER %s", peerIP, buff, ibuff);
|
||||||
DBG("%s COMMAND: %s ANSWER: %s", peerIP, buff, ibuff);
|
DBG("ANSWER: %s", ibuff);
|
||||||
if(ans){
|
if(ans){
|
||||||
ssize_t l = (ssize_t)strlen(ans);
|
ssize_t l = (ssize_t)strlen(ans);
|
||||||
if(l++){
|
if(l++){
|
||||||
|
|||||||
@ -29,6 +29,25 @@
|
|||||||
// make datetime/pressure/temperature corrections each CORRECTIONS_TIMEDIFF seconds
|
// make datetime/pressure/temperature corrections each CORRECTIONS_TIMEDIFF seconds
|
||||||
#define CORRECTIONS_TIMEDIFF (3600)
|
#define CORRECTIONS_TIMEDIFF (3600)
|
||||||
|
|
||||||
|
#define TELESCOPE_NAME "'Astrosib-500 (1)'"
|
||||||
|
|
||||||
|
// telescope statuses
|
||||||
|
typedef enum{
|
||||||
|
TEL_TRACKING = 0,
|
||||||
|
TEL_STOPHOM = 1,
|
||||||
|
TEL_PARKING = 2,
|
||||||
|
TEL_UNPARKING = 3,
|
||||||
|
TEL_HOMING = 4,
|
||||||
|
TEL_PARKED = 5,
|
||||||
|
TEL_SLEWING = 6,
|
||||||
|
TEL_STOPPED = 7,
|
||||||
|
TEL_INHIBITED = 8,
|
||||||
|
TEL_OUTLIMIT = 9,
|
||||||
|
TEL_FOLSAT = 10,
|
||||||
|
TEL_DATINCOSIST = 11,
|
||||||
|
TEL_MAXSTATUS = 12 // number of statuses
|
||||||
|
} tel_status;
|
||||||
|
|
||||||
int connect_telescope(char *dev, char *hdrname);
|
int connect_telescope(char *dev, char *hdrname);
|
||||||
int point_telescope(double ra, double decl);
|
int point_telescope(double ra, double decl);
|
||||||
int get_telescope_coords(double *ra, double *decl);
|
int get_telescope_coords(double *ra, double *decl);
|
||||||
|
|||||||
@ -19,8 +19,9 @@
|
|||||||
* MA 02110-1301, USA.
|
* MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "usefull_macros.h"
|
#include "usefull_macro.h"
|
||||||
#include <linux/limits.h> // PATH_MAX
|
#include <linux/limits.h> // PATH_MAX
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* function for different purposes that need to know time intervals
|
* function for different purposes that need to know time intervals
|
||||||
@ -393,49 +394,52 @@ int str2double(double *num, const char *str){
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FILE *Flog = NULL; // log file descriptor
|
|
||||||
static char *logname = NULL;
|
static char *logname = NULL;
|
||||||
// static time_t log_open_time = 0;
|
static pthread_mutex_t logmutex;
|
||||||
/**
|
|
||||||
* Try to open log file
|
|
||||||
* if failed show warning message
|
|
||||||
*/
|
|
||||||
void openlogfile(char *name){
|
|
||||||
if(!name){
|
|
||||||
WARNX(_("Need filename for log file"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
green(_("Try to open log file %s in append mode\n"), name);
|
|
||||||
fflush(stdout);
|
|
||||||
if(!(Flog = fopen(name, "a"))){
|
|
||||||
WARN(_("Can't open log file"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// log_open_time = time(NULL);
|
|
||||||
logname = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save message to log file, rotate logs every 24 hours
|
* @brief openlogfile - create log file: init mutex, test file open ability
|
||||||
|
* @param log - log structure
|
||||||
|
* @return 0 if all OK
|
||||||
*/
|
*/
|
||||||
|
int openlogfile(char *name){
|
||||||
|
FREE(logname);
|
||||||
|
pthread_mutex_destroy(&logmutex);
|
||||||
|
FILE *logfd = fopen(name, "a");
|
||||||
|
if(!logfd){
|
||||||
|
WARN("Can't open log file");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
fclose(logfd);
|
||||||
|
if(pthread_mutex_init(&logmutex, NULL)){
|
||||||
|
WARN("Can't init log mutes");
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
logname = strdup(name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int putlog(const char *fmt, ...){
|
int putlog(const char *fmt, ...){
|
||||||
if(!Flog) return 0;
|
if(!logname) return 0;
|
||||||
time_t t_now = time(NULL);
|
if(pthread_mutex_lock(&logmutex)){
|
||||||
/*if(t_now - log_open_time > 86400){ // rotate log
|
WARN("Can't lock log mutex");
|
||||||
fprintf(Flog, "\n\t\t%sRotate log\n", ctime(&t_now));
|
return 0;
|
||||||
fclose(Flog);
|
}
|
||||||
char newname[PATH_MAX];
|
int i = 0;
|
||||||
snprintf(newname, PATH_MAX, "%s.old", logname);
|
FILE *logfd = fopen(logname, "a");
|
||||||
if(rename(logname, newname)) WARN("rename()");
|
if(!logfd) goto rtn;
|
||||||
openlogfile(logname);
|
char strtm[128];
|
||||||
if(!Flog) return 0;
|
time_t t = time(NULL);
|
||||||
}*/
|
struct tm *curtm = localtime(&t);
|
||||||
int i = fprintf(Flog, "\n\t\t%s", ctime(&t_now));
|
strftime(strtm, 128, "%Y/%m/%d-%H:%M:%S", curtm);
|
||||||
|
i = fprintf(logfd, "%s\t", strtm);
|
||||||
va_list ar;
|
va_list ar;
|
||||||
va_start(ar, fmt);
|
va_start(ar, fmt);
|
||||||
i = vfprintf(Flog, fmt, ar);
|
i += vfprintf(logfd, fmt, ar);
|
||||||
va_end(ar);
|
va_end(ar);
|
||||||
fprintf(Flog, "\n");
|
i += fprintf(logfd, "\n");
|
||||||
fflush(Flog);
|
fclose(logfd);
|
||||||
|
rtn:
|
||||||
|
pthread_mutex_unlock(&logmutex);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
@ -138,7 +138,7 @@ int write_tty(const char *buff, size_t length);
|
|||||||
|
|
||||||
int str2double(double *num, const char *str);
|
int str2double(double *num, const char *str);
|
||||||
|
|
||||||
void openlogfile(char *name);
|
int openlogfile(char *name);
|
||||||
int putlog(const char *fmt, ...);
|
int putlog(const char *fmt, ...);
|
||||||
|
|
||||||
#endif // __USEFULL_MACROS_H__
|
#endif // __USEFULL_MACROS_H__
|
||||||
Loading…
x
Reference in New Issue
Block a user