mirror of
https://github.com/eddyem/CCD_Capture.git
synced 2025-12-06 10:45:13 +03:00
add client/server (not tested yet)
This commit is contained in:
parent
bd70ff5bc8
commit
ebf6a53d63
@ -19,7 +19,7 @@ add_definitions(-D_XOPEN_SOURCE=1234 -D_DEFAULT_SOURCE -D_GNU_SOURCE -DLOCALEDIR
|
|||||||
|
|
||||||
set(CMAKE_COLOR_MAKEFILE ON)
|
set(CMAKE_COLOR_MAKEFILE ON)
|
||||||
|
|
||||||
set(SOURCES main.c cmdlnopts.c ccdfunc.c)
|
set(SOURCES main.c cmdlnopts.c ccdfunc.c socket.c server.c client.c)
|
||||||
|
|
||||||
# cmake -DDEBUG=yes -> debugging
|
# cmake -DDEBUG=yes -> debugging
|
||||||
if(DEFINED DEBUG AND DEBUG STREQUAL "yes")
|
if(DEFINED DEBUG AND DEBUG STREQUAL "yes")
|
||||||
|
|||||||
@ -25,7 +25,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <usefull_macros.h>
|
#include <usefull_macros.h>
|
||||||
|
|
||||||
#include "ccdfunc.h"
|
#include "basestructs.h"
|
||||||
|
|
||||||
extern Camera camera;
|
extern Camera camera;
|
||||||
extern Focuser focuser;
|
extern Focuser focuser;
|
||||||
|
|||||||
@ -21,7 +21,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <usefull_macros.h>
|
#include <usefull_macros.h>
|
||||||
|
|
||||||
#include "ccdfunc.h"
|
#include "basestructs.h"
|
||||||
|
|
||||||
extern Camera camera;
|
extern Camera camera;
|
||||||
extern Focuser focuser;
|
extern Focuser focuser;
|
||||||
|
|||||||
@ -26,7 +26,7 @@
|
|||||||
#include <usefull_macros.h>
|
#include <usefull_macros.h>
|
||||||
#include <ASICamera2.h>
|
#include <ASICamera2.h>
|
||||||
|
|
||||||
#include "ccdfunc.h"
|
#include "basestructs.h"
|
||||||
|
|
||||||
extern Camera camera;
|
extern Camera camera;
|
||||||
extern Focuser focuser;
|
extern Focuser focuser;
|
||||||
@ -47,6 +47,7 @@ static struct{
|
|||||||
float mingain;
|
float mingain;
|
||||||
float maxbright;
|
float maxbright;
|
||||||
float minbright;
|
float minbright;
|
||||||
|
int maxbin;
|
||||||
} extrvalues = {0}; // extremal values
|
} extrvalues = {0}; // extremal values
|
||||||
|
|
||||||
static double starttime = 0.; // time when exposure started
|
static double starttime = 0.; // time when exposure started
|
||||||
@ -69,6 +70,7 @@ static int zwo_getfloat(float *f, ASI_CONTROL_TYPE t){
|
|||||||
long val; ASI_BOOL aut = ASI_FALSE;
|
long val; ASI_BOOL aut = ASI_FALSE;
|
||||||
if(ASI_SUCCESS != ASIGetControlValue(caminfo.CameraID, t, &val, &aut))
|
if(ASI_SUCCESS != ASIGetControlValue(caminfo.CameraID, t, &val, &aut))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
if(aut) DBG("VALUE IS AUTO!!!");
|
||||||
*f = (float) val;
|
*f = (float) val;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -142,6 +144,7 @@ static int startcapt(){
|
|||||||
static void asi_closecam(){
|
static void asi_closecam(){
|
||||||
FNAME();
|
FNAME();
|
||||||
if(caminfo.CameraID){
|
if(caminfo.CameraID){
|
||||||
|
camcancel();
|
||||||
ASICloseCamera(caminfo.CameraID);
|
ASICloseCamera(caminfo.CameraID);
|
||||||
caminfo.CameraID = 0;
|
caminfo.CameraID = 0;
|
||||||
}
|
}
|
||||||
@ -154,12 +157,10 @@ static int setdevno(int n){
|
|||||||
DBG("Camera #%d, name: %s, ID: %d", n, caminfo.Name, caminfo.CameraID);
|
DBG("Camera #%d, name: %s, ID: %d", n, caminfo.Name, caminfo.CameraID);
|
||||||
DBG("WxH: %ldx%ld, %s", caminfo.MaxWidth, caminfo.MaxHeight, caminfo.IsColorCam == ASI_TRUE ? "color" : "monochrome");
|
DBG("WxH: %ldx%ld, %s", caminfo.MaxWidth, caminfo.MaxHeight, caminfo.IsColorCam == ASI_TRUE ? "color" : "monochrome");
|
||||||
DBG("Pixel size: %1.1f mkm; gain: %1.2f e/ADU", caminfo.PixelSize, caminfo.ElecPerADU);
|
DBG("Pixel size: %1.1f mkm; gain: %1.2f e/ADU", caminfo.PixelSize, caminfo.ElecPerADU);
|
||||||
#ifdef EBUG
|
|
||||||
int *sup = caminfo.SupportedBins;
|
int *sup = caminfo.SupportedBins;
|
||||||
while(*sup){
|
while(*sup){
|
||||||
green("Supported bin: %d\n", *sup++);
|
extrvalues.maxbin = *sup++;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
camera.pixX = camera.pixY = (float)caminfo.PixelSize / 1e6; // um -> m
|
camera.pixX = camera.pixY = (float)caminfo.PixelSize / 1e6; // um -> m
|
||||||
camera.array = (frameformat){.w = caminfo.MaxWidth, .h = caminfo.MaxHeight, .xoff = 0, .yoff = 0};
|
camera.array = (frameformat){.w = caminfo.MaxWidth, .h = caminfo.MaxHeight, .xoff = 0, .yoff = 0};
|
||||||
camera.field = camera.array; // initial setup (will update later)
|
camera.field = camera.array; // initial setup (will update later)
|
||||||
@ -217,7 +218,10 @@ static int setdevno(int n){
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int camsetbrig(float b){
|
static int camsetbrig(float b){
|
||||||
if(b < extrvalues.minbright || b > extrvalues.maxbright) return FALSE;
|
if(b < extrvalues.minbright || b > extrvalues.maxbright){
|
||||||
|
WARNX(_("Brightness should be from %g to %g"), extrvalues.minbright, extrvalues.maxbright);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
return zwo_setfloat(b, ASI_BRIGHTNESS);
|
return zwo_setfloat(b, ASI_BRIGHTNESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,7 +237,10 @@ static int camsetexp(float t){
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int camsetgain(float g){
|
static int camsetgain(float g){
|
||||||
if(g < extrvalues.mingain || g > extrvalues.maxgain) return FALSE;
|
if(g < extrvalues.mingain || g > extrvalues.maxgain){
|
||||||
|
WARNX(_("Gain should be from %g to %g"), extrvalues.mingain, extrvalues.maxgain);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
return zwo_setfloat(g, ASI_GAIN);
|
return zwo_setfloat(g, ASI_GAIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,6 +250,10 @@ static int camgetgain(float *g){
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int camsett(float t){
|
static int camsett(float t){
|
||||||
|
if(caminfo.IsCoolerCam == ASI_FALSE){
|
||||||
|
DBG("Cooling unsupported");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
if(!zwo_setfloat(1., ASI_FAN_ON)){
|
if(!zwo_setfloat(1., ASI_FAN_ON)){
|
||||||
DBG("Can't set fan on");
|
DBG("Can't set fan on");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -251,6 +262,10 @@ static int camsett(float t){
|
|||||||
if(zwo_getfloat(&f, ASI_FAN_ON)){
|
if(zwo_getfloat(&f, ASI_FAN_ON)){
|
||||||
DBG("FAN: %g", f);
|
DBG("FAN: %g", f);
|
||||||
}
|
}
|
||||||
|
if(!zwo_setfloat(1., ASI_COOLER_ON)){
|
||||||
|
DBG("Can't set cooler on");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
if(!zwo_setfloat(t, ASI_TARGET_TEMP)){
|
if(!zwo_setfloat(t, ASI_TARGET_TEMP)){
|
||||||
DBG("Can't set target temperature");
|
DBG("Can't set target temperature");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -258,30 +273,25 @@ static int camsett(float t){
|
|||||||
if(zwo_getfloat(&f, ASI_TARGET_TEMP)){
|
if(zwo_getfloat(&f, ASI_TARGET_TEMP)){
|
||||||
DBG("Ttarg = %g", f);
|
DBG("Ttarg = %g", f);
|
||||||
}
|
}
|
||||||
if(!zwo_setfloat(1., ASI_COOLER_ON)){
|
|
||||||
DBG("Can't set cooler on");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if(!zwo_getfloat(&f, ASI_COOLER_ON)) return FALSE;
|
if(!zwo_getfloat(&f, ASI_COOLER_ON)) return FALSE;
|
||||||
DBG("COOLERON = %g", f);
|
DBG("COOLERON = %g", f);
|
||||||
usleep(100000);
|
#ifdef EBUG
|
||||||
double t0 = dtime();
|
double t0 = dtime();
|
||||||
float c, p, tn;
|
float c, p, tn;
|
||||||
while(dtime() - t0 < 10.){
|
while(dtime() - t0 < 1200.){
|
||||||
green("%.1f", dtime()-t0);
|
usleep(100000); // without this first ASI_FAN_ON will show false data
|
||||||
|
green("%.1f ", dtime()-t0);
|
||||||
zwo_getfloat(&f, ASI_FAN_ON);
|
zwo_getfloat(&f, ASI_FAN_ON);
|
||||||
zwo_getfloat(&t, ASI_TARGET_TEMP);
|
zwo_getfloat(&t, ASI_TARGET_TEMP);
|
||||||
zwo_getfloat(&c, ASI_COOLER_ON);
|
zwo_getfloat(&c, ASI_COOLER_ON);
|
||||||
zwo_getfloat(&tn, ASI_TEMPERATURE);
|
zwo_getfloat(&tn, ASI_TEMPERATURE);
|
||||||
zwo_getfloat(&p, ASI_COOLER_POWER_PERC);
|
zwo_getfloat(&p, ASI_COOLER_POWER_PERC);
|
||||||
printf("fan: %g, t: %g, cooler: %g, perc: %g, tnow: %g\n", f, t, c, p, tn/10.);
|
printf("fan: %g, t: %g, cooler: %g, perc: %g, tnow: %g\n", f, t, c, p, tn/10.);
|
||||||
if(f > 0.) break;
|
|
||||||
usleep(100000);
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int camgett(float *t){
|
static int camgett(float *t){
|
||||||
if(!t) return FALSE;
|
if(!t) return FALSE;
|
||||||
float curt;
|
float curt;
|
||||||
@ -295,7 +305,13 @@ static int gett(_U_ float *t){
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int camsetbin(int h, int v){
|
static int camsetbin(int h, int v){
|
||||||
if(h != v) return FALSE;
|
if(h != v){
|
||||||
|
WARNX(_("BinX and BinY should be equal"));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if(h > extrvalues.maxbin){
|
||||||
|
WARNX(_("Maximal binning value is %d"), extrvalues.maxbin);
|
||||||
|
}
|
||||||
if(zwo_setfloat(1., ASI_HARDWARE_BIN)){
|
if(zwo_setfloat(1., ASI_HARDWARE_BIN)){
|
||||||
curbin = h;
|
curbin = h;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -322,8 +338,9 @@ static int camsetgeom(frameformat *f){ // w,h, xoff, yoff
|
|||||||
DBG(_("Can't get geometry"));
|
DBG(_("Can't get geometry"));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
DBG("curformat: w=%d, h=%d, bin=%d", f->w, f->h, curbin);
|
||||||
DBG("w=%d, h=%d, bin=%d", f->w, f->h, curbin);
|
DBG("w=%d, h=%d, bin=%d", f->w, f->h, curbin);
|
||||||
if(ASI_SUCCESS != ASISetStartPos(caminfo.CameraID, f->xoff, f->yoff)){
|
if(ASI_SUCCESS != ASISetStartPos(caminfo.CameraID, f->xoff/curbin, f->yoff/curbin)){
|
||||||
DBG("Can't set start pos");
|
DBG("Can't set start pos");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -331,6 +348,7 @@ static int camsetgeom(frameformat *f){ // w,h, xoff, yoff
|
|||||||
DBG("Can't get start pos");
|
DBG("Can't get start pos");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
DBG("curstartpos: x=%d, y=%d", f->xoff, f->yoff);
|
||||||
camera.geometry = *f;
|
camera.geometry = *f;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -373,7 +391,20 @@ static int camgetio(_U_ int *io){ // not supported
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int camfan(_U_ fan_speed spd){ // not supported
|
static int camfan(_U_ fan_speed spd){ // not supported, just turn it on/off
|
||||||
|
switch(spd){
|
||||||
|
case FAN_OFF:
|
||||||
|
if(!zwo_setfloat(0., ASI_FAN_ON)){
|
||||||
|
DBG("Can't set fan off");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default: // turn ON
|
||||||
|
if(!zwo_setfloat(1., ASI_FAN_ON)){
|
||||||
|
DBG("Can't set fan on");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
138
basestructs.h
Normal file
138
basestructs.h
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the CCD_Capture project.
|
||||||
|
* Copyright 2022 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 BASESTRUCTS_H__
|
||||||
|
#define BASESTRUCTS_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
uint16_t *data; // image data
|
||||||
|
int w, h; // image size
|
||||||
|
uint16_t max, min; // min/max values
|
||||||
|
float avr, std; // statistics
|
||||||
|
} IMG;
|
||||||
|
|
||||||
|
// format of single frame
|
||||||
|
typedef struct{
|
||||||
|
int w; int h; // width & height
|
||||||
|
int xoff; int yoff; // X and Y offset
|
||||||
|
} frameformat;
|
||||||
|
|
||||||
|
typedef enum{
|
||||||
|
SHUTTER_OPEN, // open shutter now
|
||||||
|
SHUTTER_CLOSE, // close shutter now
|
||||||
|
SHUTTER_OPENATLOW, // ext. expose control @low
|
||||||
|
SHUTTER_OPENATHIGH, // -//- @high
|
||||||
|
SHUTTER_AMOUNT, // amount of entries
|
||||||
|
} shutter_op;
|
||||||
|
|
||||||
|
typedef enum{
|
||||||
|
CAPTURE_NO, // no capture initiated
|
||||||
|
CAPTURE_PROCESS, // in progress
|
||||||
|
CAPTURE_CANTSTART, // can't start
|
||||||
|
CAPTURE_ABORTED, // some error - aborted
|
||||||
|
CAPTURE_READY, // ready - user can read image
|
||||||
|
} capture_status;
|
||||||
|
|
||||||
|
typedef enum{
|
||||||
|
FAN_OFF,
|
||||||
|
FAN_LOW,
|
||||||
|
FAN_MID,
|
||||||
|
FAN_HIGH,
|
||||||
|
} fan_speed;
|
||||||
|
|
||||||
|
// all setters and getters of Camera, Focuser and Wheel should return TRUE if success or FALSE if failed or unsupported
|
||||||
|
// camera
|
||||||
|
typedef struct{
|
||||||
|
int (*check)(); // check if the device is available, connect and init
|
||||||
|
int Ndevices; // amount of devices found
|
||||||
|
void (*close)(); // disconnect & close device
|
||||||
|
int (*startexposition)(); // start exposition
|
||||||
|
int (*pollcapture)(capture_status *st, float *remain);// start or poll capture process, `remain` - time remain (s)
|
||||||
|
int (*capture)(IMG *ima); // capture an image, struct `ima` should be prepared before
|
||||||
|
void (*cancel)(); // cancel exposition
|
||||||
|
// setters:
|
||||||
|
int (*setDevNo)(int n); // set active device number
|
||||||
|
int (*setbrightness)(float b);
|
||||||
|
int (*setexp)(float e);
|
||||||
|
int (*setgain)(float g);
|
||||||
|
int (*setT)(float t);
|
||||||
|
int (*setbin)(int binh, int binv); // binning
|
||||||
|
int (*setnflushes)(int N); // flushes amount
|
||||||
|
int (*shuttercmd)(shutter_op s); // work with shutter
|
||||||
|
int (*confio)(int s); // configure IO-port
|
||||||
|
int (*setio)(int s); // set IO-port to given state
|
||||||
|
int (*setframetype)(int l); // set frametype: 1 - light, 0 - dark
|
||||||
|
int (*setbitdepth)(int h); // set bit depth: 1 - high, 0 - low
|
||||||
|
int (*setfastspeed)(int s); // set readout speed: 1 - fast, 0 - low
|
||||||
|
// geometry (if TRUE, all args are changed to suitable values)
|
||||||
|
int (*setgeometry)(frameformat *fmt); // set geometry in UNBINNED coordinates
|
||||||
|
int (*setfanspeed)(fan_speed spd); // set fan speed
|
||||||
|
// getters:
|
||||||
|
int (*getbrightness)(float *b);// get brightnes level
|
||||||
|
int (*getModelName)(char *n, int l);// string with model name (l - length of n in bytes)
|
||||||
|
int (*getgain)(float *g); // get gain value
|
||||||
|
int (*getmaxgain)(float *g);// get max available gain value
|
||||||
|
// get limits of geometry: maximal values and steps
|
||||||
|
int (*getgeomlimits)(frameformat *max, frameformat *step);
|
||||||
|
int (*getTcold)(float *t); // cold-side T
|
||||||
|
int (*getThot)(float *t); // hot-side T
|
||||||
|
int (*getTbody)(float *t); // body T
|
||||||
|
int (*getbin)(int *binh, int *binv);
|
||||||
|
int (*getio)(int *s); // get IO-port state
|
||||||
|
float pixX, pixY; // pixel size in um
|
||||||
|
frameformat field; // max field of view
|
||||||
|
frameformat array; // array format
|
||||||
|
frameformat geometry; // current geometry settings (as in setgeometry)
|
||||||
|
} Camera;
|
||||||
|
|
||||||
|
// focuser
|
||||||
|
typedef struct{
|
||||||
|
int (*check)(); // check if the device is available
|
||||||
|
int Ndevices;
|
||||||
|
void (*close)();
|
||||||
|
// setters:
|
||||||
|
int (*setDevNo)(int n); // set active device number
|
||||||
|
int (*setAbsPos)(int async, float n);// set absolute position (in millimeters!!!)
|
||||||
|
int (*home)(int async); // home device
|
||||||
|
// getters:
|
||||||
|
int (*getModelName)(char *n, int l);// string with model name (l - length of n in bytes)
|
||||||
|
int (*getTbody)(float *t); // body T
|
||||||
|
int (*getPos)(float *p); // current position number (starting from zero)
|
||||||
|
int (*getMaxPos)(float *p); // max position
|
||||||
|
int (*getMinPos)(float *p); // min position
|
||||||
|
} Focuser;
|
||||||
|
|
||||||
|
// wheel
|
||||||
|
typedef struct{
|
||||||
|
int (*check)(); // check if the device is available
|
||||||
|
int Ndevices;
|
||||||
|
void (*close)();
|
||||||
|
// setters:
|
||||||
|
int (*setDevNo)(int n); // set active device number
|
||||||
|
int (*setPos)(int n); // set absolute position (starting from 0)
|
||||||
|
// getters:
|
||||||
|
int (*getModelName)(char *n, int l);// string with model name (l - length of n in bytes)
|
||||||
|
int (*getTbody)(float *t); // body T
|
||||||
|
int (*getPos)(int *p); // current position number (starting from zero)
|
||||||
|
int (*getMaxPos)(int *p); // amount of positions
|
||||||
|
} Wheel;
|
||||||
|
|
||||||
|
#endif // BASESTRUCTS_H__
|
||||||
253
ccdfunc.c
253
ccdfunc.c
@ -41,9 +41,10 @@ static int fitserror = 0;
|
|||||||
#define TRYFITS(f, ...) \
|
#define TRYFITS(f, ...) \
|
||||||
do{ int status = 0; \
|
do{ int status = 0; \
|
||||||
f(__VA_ARGS__, &status); \
|
f(__VA_ARGS__, &status); \
|
||||||
if(status){ \
|
if(status){ \
|
||||||
fits_report_error(stderr, status); \
|
fits_report_error(stderr, status); \
|
||||||
fitserror = status;} \
|
LOGERR("Fits error %d", status); \
|
||||||
|
fitserror = status;} \
|
||||||
}while(0)
|
}while(0)
|
||||||
#define WRITEKEY(...) \
|
#define WRITEKEY(...) \
|
||||||
do{ int status = 0; \
|
do{ int status = 0; \
|
||||||
@ -105,16 +106,16 @@ static size_t curtime(char *s_time){ // current date/time
|
|||||||
return strftime(s_time, TMBUFSIZ, "%d/%m/%Y,%H:%M:%S", localtime(&tm));
|
return strftime(s_time, TMBUFSIZ, "%d/%m/%Y,%H:%M:%S", localtime(&tm));
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
static int check_filename(char *buff, char *outfile, char *ext){
|
// check if I can create file prefix_XXXX.fits
|
||||||
struct stat filestat;
|
static int check_filenameprefix(char *buff, int buflen){
|
||||||
int num;
|
for(int num = 1; num < 10000; num++){
|
||||||
for(num = 1; num < 10000; num++){
|
if(snprintf(buff, buflen-1, "%s_%04d.fits", GP->outfileprefix, num) < 1)
|
||||||
if(snprintf(buff, PATH_MAX, "%s_%04d.%s", outfile, num, ext) < 1)
|
return FALSE;
|
||||||
return 0;
|
struct stat filestat;
|
||||||
if(stat(buff, &filestat)) // no such file or can't stat()
|
if(stat(buff, &filestat)) // no such file or can't stat()
|
||||||
return 1;
|
return TRUE;
|
||||||
}
|
}
|
||||||
return 0;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -144,21 +145,37 @@ static void addrec(fitsfile *f, char *filename){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void saveFITS(IMG *img, char *filename){
|
// save FITS file `img` into GP->outfile or GP->outfileprefix_XXXX.fits
|
||||||
|
void saveFITS(IMG *img){
|
||||||
if(!camera){
|
if(!camera){
|
||||||
|
LOGERR("Can't save image: no camera device");
|
||||||
WARNX(_("Camera device unknown"));
|
WARNX(_("Camera device unknown"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
char buff[PATH_MAX], fnam[PATH_MAX];
|
char buff[PATH_MAX], fnam[PATH_MAX];
|
||||||
if(filename == NULL) return;
|
if(!GP->outfile && !GP->outfileprefix){
|
||||||
fitserror = 0;
|
LOGERR("Can't save image: neither filename nor filename prefix pointed");
|
||||||
if(!check_filename(fnam, filename, "fits") && !GP->rewrite){
|
WARNX(_("Neither filename nor filename prefix pointed!"));
|
||||||
// îÅ ÍÏÇÕ ÓÏÈÒÁÎÉÔØ ÆÁÊÌ
|
return;
|
||||||
WARNX(_("Can't save file"));
|
}
|
||||||
}else{
|
if(GP->outfile){ // pointed specific output file name like "file.fits", check it
|
||||||
if(GP->rewrite){
|
struct stat filestat;
|
||||||
DBG("REW");
|
int s = stat(GP->outfile, &filestat);
|
||||||
snprintf(fnam, PATH_MAX, "!%s.fits", filename);
|
if(s){ // not exists
|
||||||
|
snprintf(fnam, PATH_MAX-1, "%s", GP->outfile);
|
||||||
|
}else{ // exists
|
||||||
|
if(!GP->rewrite){
|
||||||
|
LOGERR("Can't save image: file %s exists", GP->outfile);
|
||||||
|
WARNX("File %s exists!", GP->outfile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
snprintf(fnam, PATH_MAX-1, "!%s", GP->outfile);
|
||||||
|
}
|
||||||
|
}else{ // user pointed output file prefix
|
||||||
|
if(!check_filenameprefix(fnam, PATH_MAX)){
|
||||||
|
// îÅ ÍÏÇÕ ÓÏÈÒÁÎÉÔØ ÆÁÊÌ
|
||||||
|
WARNX(_("Can't save file with prefix %s"), GP->outfileprefix);
|
||||||
|
LOGERR("Can't save image with prefix %s", GP->outfileprefix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int width = img->w, height = img->h;
|
int width = img->w, height = img->h;
|
||||||
@ -171,12 +188,13 @@ void saveFITS(IMG *img, char *filename){
|
|||||||
char bufc[FLEN_CARD];
|
char bufc[FLEN_CARD];
|
||||||
time_t savetime = time(NULL);
|
time_t savetime = time(NULL);
|
||||||
fitsfile *fp;
|
fitsfile *fp;
|
||||||
|
fitserror = 0;
|
||||||
TRYFITS(fits_create_file, &fp, fnam);
|
TRYFITS(fits_create_file, &fp, fnam);
|
||||||
if(fitserror) goto cloerr;
|
if(fitserror) goto cloerr;
|
||||||
TRYFITS(fits_create_img, fp, USHORT_IMG, 2, naxes);
|
TRYFITS(fits_create_img, fp, USHORT_IMG, 2, naxes);
|
||||||
if(fitserror) goto cloerr;
|
if(fitserror) goto cloerr;
|
||||||
// FILE / Input file original name
|
// FILE / Input file original name
|
||||||
WRITEKEY(fp, TSTRING, "FILE", filename, "Input file original name");
|
WRITEKEY(fp, TSTRING, "FILE", fnam, "Input file original name");
|
||||||
// ORIGIN / organization responsible for the data
|
// ORIGIN / organization responsible for the data
|
||||||
WRITEKEY(fp, TSTRING, "ORIGIN", "SAO RAS", "organization responsible for the data");
|
WRITEKEY(fp, TSTRING, "ORIGIN", "SAO RAS", "organization responsible for the data");
|
||||||
// OBSERVAT / Observatory name
|
// OBSERVAT / Observatory name
|
||||||
@ -200,8 +218,8 @@ void saveFITS(IMG *img, char *filename){
|
|||||||
camera->array.xoff + camera->array.w, camera->array.yoff + camera->array.h);
|
camera->array.xoff + camera->array.w, camera->array.yoff + camera->array.h);
|
||||||
WRITEKEY(fp, TSTRING, "ARRAYFLD", bufc, "Camera full array size");
|
WRITEKEY(fp, TSTRING, "ARRAYFLD", bufc, "Camera full array size");
|
||||||
// CRVAL1, CRVAL2 / Offset in X, Y
|
// CRVAL1, CRVAL2 / Offset in X, Y
|
||||||
if(GP->X0 > -1) WRITEKEY(fp, TINT, "X0", &GP->X0, "Subframe left border");
|
if(GP->X0 > -1) WRITEKEY(fp, TINT, "X0", &GP->X0, "Subframe left border without binning");
|
||||||
if(GP->Y0 > -1) WRITEKEY(fp, TINT, "Y0", &GP->Y0, "Subframe upper border");
|
if(GP->Y0 > -1) WRITEKEY(fp, TINT, "Y0", &GP->Y0, "Subframe upper border without binning");
|
||||||
if(GP->objtype) strncpy(bufc, GP->objtype, FLEN_CARD-1);
|
if(GP->objtype) strncpy(bufc, GP->objtype, FLEN_CARD-1);
|
||||||
else if(GP->dark) sprintf(bufc, "dark");
|
else if(GP->dark) sprintf(bufc, "dark");
|
||||||
else sprintf(bufc, "light");
|
else sprintf(bufc, "light");
|
||||||
@ -221,7 +239,7 @@ void saveFITS(IMG *img, char *filename){
|
|||||||
WRITEKEY(fp, TFLOAT, "STATAVR", &tmpf, "Average data value");
|
WRITEKEY(fp, TFLOAT, "STATAVR", &tmpf, "Average data value");
|
||||||
tmpf = img->std;
|
tmpf = img->std;
|
||||||
WRITEKEY(fp, TFLOAT, "STATSTD", &tmpf, "Std. of data value");
|
WRITEKEY(fp, TFLOAT, "STATSTD", &tmpf, "Std. of data value");
|
||||||
WRITEKEY(fp, TFLOAT, "CAMTEMP0", &GP->temperature, "Camera temperature at exp. start, degr C");
|
// WRITEKEY(fp, TFLOAT, "CAMTEMP0", &GP->temperature, "Camera temperature at exp. start, degr C");
|
||||||
if(camera->getTcold(&tmpf))
|
if(camera->getTcold(&tmpf))
|
||||||
WRITEKEY(fp, TFLOAT, "CAMTEMP", &tmpf, "Camera temperature at exp. end, degr C");
|
WRITEKEY(fp, TFLOAT, "CAMTEMP", &tmpf, "Camera temperature at exp. end, degr C");
|
||||||
if(camera->getTbody(&tmpf))
|
if(camera->getTbody(&tmpf))
|
||||||
@ -231,6 +249,12 @@ void saveFITS(IMG *img, char *filename){
|
|||||||
// EXPTIME / actual exposition time (sec)
|
// EXPTIME / actual exposition time (sec)
|
||||||
tmpd = GP->exptime;
|
tmpd = GP->exptime;
|
||||||
WRITEKEY(fp, TDOUBLE, "EXPTIME", &tmpd, "Actual exposition time (sec)");
|
WRITEKEY(fp, TDOUBLE, "EXPTIME", &tmpd, "Actual exposition time (sec)");
|
||||||
|
if(camera->getgain(&tmpf)){
|
||||||
|
WRITEKEY(fp, TFLOAT, "CAMGAIN", &tmpf, "CMOS gain value");
|
||||||
|
}
|
||||||
|
if(camera->getbrightness(&tmpf)){
|
||||||
|
WRITEKEY(fp, TFLOAT, "CAMBRIGH", &tmpf, "CMOS brightness value");
|
||||||
|
}
|
||||||
// DATE / Creation date (YYYY-MM-DDThh:mm:ss, UTC)
|
// DATE / Creation date (YYYY-MM-DDThh:mm:ss, UTC)
|
||||||
strftime(bufc, FLEN_VALUE, "%Y-%m-%dT%H:%M:%S", gmtime(&savetime));
|
strftime(bufc, FLEN_VALUE, "%Y-%m-%dT%H:%M:%S", gmtime(&savetime));
|
||||||
WRITEKEY(fp, TSTRING, "DATE", bufc, "Creation date (YYYY-MM-DDThh:mm:ss, UTC)");
|
WRITEKEY(fp, TSTRING, "DATE", bufc, "Creation date (YYYY-MM-DDThh:mm:ss, UTC)");
|
||||||
@ -301,14 +325,16 @@ void saveFITS(IMG *img, char *filename){
|
|||||||
TRYFITS(fits_close_file, fp);
|
TRYFITS(fits_close_file, fp);
|
||||||
cloerr:
|
cloerr:
|
||||||
if(fitserror == 0){
|
if(fitserror == 0){
|
||||||
|
LOGMSG("Save file '%s'", fnam);
|
||||||
verbose(1, _("File saved as '%s'"), fnam);
|
verbose(1, _("File saved as '%s'"), fnam);
|
||||||
}else{
|
}else{
|
||||||
|
LOGERR("Can't save %s", fnam);
|
||||||
WARNX(_("Error saving file"));
|
WARNX(_("Error saving file"));
|
||||||
fitserror = 0;
|
fitserror = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void calculate_stat(IMG *image){
|
void calculate_stat(IMG *image){
|
||||||
uint64_t Noverld = 0L, size = image->h*image->w;
|
uint64_t Noverld = 0L, size = image->h*image->w;
|
||||||
double sum = 0., sum2 = 0.;
|
double sum = 0., sum2 = 0.;
|
||||||
uint16_t max = 0, min = 65535;
|
uint16_t max = 0, min = 65535;
|
||||||
@ -340,6 +366,7 @@ static void calculate_stat(IMG *image){
|
|||||||
double avr = sum/sz;
|
double avr = sum/sz;
|
||||||
image->avr = avr;
|
image->avr = avr;
|
||||||
image->std = sqrt(fabs(sum2/sz - avr*avr));
|
image->std = sqrt(fabs(sum2/sz - avr*avr));
|
||||||
|
image->max = max; image->min = min;
|
||||||
if(GP->verbose){
|
if(GP->verbose){
|
||||||
printf(_("Image stat:\n"));
|
printf(_("Image stat:\n"));
|
||||||
printf("avr = %.1f, std = %.1f, Noverload = %ld\n", avr, image->std, Noverld);
|
printf("avr = %.1f, std = %.1f, Noverload = %ld\n", avr, image->std, Noverld);
|
||||||
@ -347,32 +374,45 @@ static void calculate_stat(IMG *image){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int startFocuser(void **dlh){
|
||||||
|
if(!GP->focuserdev && !GP->commondev){
|
||||||
|
verbose(3, _("Focuser device not pointed"));
|
||||||
|
return FALSE;
|
||||||
|
}else{
|
||||||
|
char *plugin = GP->commondev ? GP->commondev : GP->focuserdev;
|
||||||
|
if(!(*dlh = init_focuser(plugin))) return FALSE;
|
||||||
|
}
|
||||||
|
if(!focuser->check()){
|
||||||
|
verbose(3, _("No focusers found"));
|
||||||
|
focuser = NULL;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void focclose(void *dlh){
|
||||||
|
focuser->close();
|
||||||
|
dlclose(dlh);
|
||||||
|
focuser = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find focusers and work with each of them
|
* Find focusers and work with each of them
|
||||||
*/
|
*/
|
||||||
void focusers(){
|
void focusers(){
|
||||||
FNAME();
|
FNAME();
|
||||||
void *dlh = NULL;
|
void *dlh = NULL;
|
||||||
if(!GP->focuserdev && !GP->commondev){
|
if(!startFocuser(&dlh)) return;
|
||||||
verbose(3, _("Focuser device not pointed"));
|
|
||||||
return;
|
|
||||||
}else{
|
|
||||||
char *plugin = GP->commondev ? GP->commondev : GP->focuserdev;
|
|
||||||
if(!(dlh = init_focuser(plugin))) return;
|
|
||||||
}
|
|
||||||
if(!focuser->check()){
|
|
||||||
verbose(3, _("No focusers found"));
|
|
||||||
focuser = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(GP->listdevices){
|
if(GP->listdevices){
|
||||||
for(int i = 0; i < focuser->Ndevices; ++i){
|
for(int i = 0; i < focuser->Ndevices; ++i){
|
||||||
|
if(!focuser->setDevNo(i)) continue;
|
||||||
char modname[256];
|
char modname[256];
|
||||||
focuser->getModelName(modname, 255);
|
focuser->getModelName(modname, 255);
|
||||||
printf("Found focuser #%d: %s\n", i, modname);
|
printf("Found focuser #%d: %s\n", i, modname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int num = GP->focdevno;
|
int num = GP->focdevno;
|
||||||
|
if(num < 0) num = 0;
|
||||||
if(num > focuser->Ndevices - 1){
|
if(num > focuser->Ndevices - 1){
|
||||||
WARNX(_("Found %d focusers, you point number %d"), focuser->Ndevices, num);
|
WARNX(_("Found %d focusers, you point number %d"), focuser->Ndevices, num);
|
||||||
goto retn;
|
goto retn;
|
||||||
@ -422,9 +462,29 @@ void focusers(){
|
|||||||
if(!focuser->setAbsPos(GP->async, tagpos)) WARNX(_("Can't set position %g"), tagpos);
|
if(!focuser->setAbsPos(GP->async, tagpos)) WARNX(_("Can't set position %g"), tagpos);
|
||||||
}
|
}
|
||||||
retn:
|
retn:
|
||||||
focuser->close();
|
focclose(dlh);
|
||||||
|
}
|
||||||
|
|
||||||
|
int startWheel(void **dlh){
|
||||||
|
if(!GP->wheeldev && !GP->commondev){
|
||||||
|
verbose(3, _("Wheel device not pointed"));
|
||||||
|
return FALSE;
|
||||||
|
}else{
|
||||||
|
char *plugin = GP->commondev ? GP->commondev : GP->wheeldev;
|
||||||
|
if(!(*dlh = init_wheel(plugin))) return FALSE;
|
||||||
|
}
|
||||||
|
if(!wheel->check()){
|
||||||
|
verbose(3, _("No wheels found"));
|
||||||
|
wheel = NULL;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void closewheel(void *dlh){
|
||||||
|
wheel->close();
|
||||||
dlclose(dlh);
|
dlclose(dlh);
|
||||||
focuser = NULL;
|
wheel = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -433,26 +493,17 @@ retn:
|
|||||||
void wheels(){
|
void wheels(){
|
||||||
FNAME();
|
FNAME();
|
||||||
void *dlh = NULL;
|
void *dlh = NULL;
|
||||||
if(!GP->wheeldev && !GP->commondev){
|
if(!startWheel(&dlh)) return;
|
||||||
verbose(3, _("Wheel device not pointed"));
|
|
||||||
return;
|
|
||||||
}else{
|
|
||||||
char *plugin = GP->commondev ? GP->commondev : GP->wheeldev;
|
|
||||||
if(!(dlh = init_wheel(plugin))) return;
|
|
||||||
}
|
|
||||||
if(!wheel->check()){
|
|
||||||
verbose(3, _("No wheels found"));
|
|
||||||
wheel = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(GP->listdevices){
|
if(GP->listdevices){
|
||||||
for(int i = 0; i < wheel->Ndevices; ++i){
|
for(int i = 0; i < wheel->Ndevices; ++i){
|
||||||
|
if(!wheel->setDevNo(i)) continue;
|
||||||
char modname[256];
|
char modname[256];
|
||||||
wheel->getModelName(modname, 255);
|
wheel->getModelName(modname, 255);
|
||||||
printf("Found wheel #%d: %s\n", i, modname);
|
printf("Found wheel #%d: %s\n", i, modname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int num = GP->whldevno;
|
int num = GP->whldevno;
|
||||||
|
if(num < 0) num = 0;
|
||||||
if(num > wheel->Ndevices - 1){
|
if(num > wheel->Ndevices - 1){
|
||||||
WARNX(_("Found %d wheels, you point number %d"), wheel->Ndevices, num);
|
WARNX(_("Found %d wheels, you point number %d"), wheel->Ndevices, num);
|
||||||
goto retn;
|
goto retn;
|
||||||
@ -487,9 +538,7 @@ void wheels(){
|
|||||||
if(!wheel->setPos(pos))
|
if(!wheel->setPos(pos))
|
||||||
WARNX(_("Can't set wheel position %d"), pos);
|
WARNX(_("Can't set wheel position %d"), pos);
|
||||||
retn:
|
retn:
|
||||||
wheel->close();
|
closewheel(dlh);
|
||||||
dlclose(dlh);
|
|
||||||
wheel = NULL;
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
static void closeall(){
|
static void closeall(){
|
||||||
@ -500,22 +549,47 @@ static void closeall(){
|
|||||||
|
|
||||||
static capture_status capt(){
|
static capture_status capt(){
|
||||||
capture_status cs;
|
capture_status cs;
|
||||||
float tleave, tmpf;
|
float tremain, tmpf;
|
||||||
while(camera->pollcapture(&cs, &tleave)){
|
while(camera->pollcapture(&cs, &tremain)){
|
||||||
if(cs != CAPTURE_PROCESS) break;
|
if(cs != CAPTURE_PROCESS) break;
|
||||||
if(tleave > 0.1){
|
if(tremain > 0.1){
|
||||||
verbose(2, _("%.1f seconds till exposition ends"), tleave);
|
verbose(2, _("%.1f seconds till exposition ends"), tremain);
|
||||||
if(camera->getTcold(&tmpf)) verbose(1, "CCDTEMP=%.1f", tmpf);
|
if(camera->getTcold(&tmpf)) verbose(1, "CCDTEMP=%.1f", tmpf);
|
||||||
if(camera->getTbody(&tmpf)) verbose(1, "BODYTEMP=%.1f", tmpf);
|
if(camera->getTbody(&tmpf)) verbose(1, "BODYTEMP=%.1f", tmpf);
|
||||||
}
|
}
|
||||||
if(tleave > 6.) sleep(5);
|
if(tremain > 6.) sleep(5);
|
||||||
else if(tleave > 0.9) sleep((int)(tleave+0.99));
|
else if(tremain > 0.9) sleep((int)(tremain+0.99));
|
||||||
else usleep((int)(1e6*tleave) + 100000);
|
else usleep((int)(1e6*tremain) + 100000);
|
||||||
if(!camera) return CAPTURE_ABORTED;
|
if(!camera) return CAPTURE_ABORTED;
|
||||||
}
|
}
|
||||||
return cs;
|
return cs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int startCCD(void **dlh){
|
||||||
|
if(!GP->cameradev && !GP->commondev){
|
||||||
|
verbose(3, _("Camera device not pointed"));
|
||||||
|
return FALSE;
|
||||||
|
}else{
|
||||||
|
char *plugin = GP->commondev ? GP->commondev : GP->cameradev;
|
||||||
|
if(!(*dlh = init_camera(plugin))) return FALSE;
|
||||||
|
}
|
||||||
|
if(!camera->check()){
|
||||||
|
verbose(3, _("No cameras found"));
|
||||||
|
LOGWARN(_("No cameras found"));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void closecam(void *dlh){
|
||||||
|
if(!dlh) return;
|
||||||
|
DBG("Close cam");
|
||||||
|
camera->close();
|
||||||
|
DBG("close dlh");
|
||||||
|
dlclose(dlh);
|
||||||
|
camera = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find CCDs and work with each of them
|
* Find CCDs and work with each of them
|
||||||
*/
|
*/
|
||||||
@ -524,25 +598,17 @@ void ccds(){
|
|||||||
float tmpf;
|
float tmpf;
|
||||||
int tmpi;
|
int tmpi;
|
||||||
void *dlh = NULL;
|
void *dlh = NULL;
|
||||||
if(!GP->cameradev && !GP->commondev){
|
if(!startCCD(&dlh)) return;
|
||||||
verbose(3, _("Camera device not pointed"));
|
|
||||||
return;
|
|
||||||
}else{
|
|
||||||
char *plugin = GP->commondev ? GP->commondev : GP->cameradev;
|
|
||||||
if(!(dlh = init_camera(plugin))) return;
|
|
||||||
}
|
|
||||||
if(!camera->check()){
|
|
||||||
verbose(3, _("No cameras found"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(GP->listdevices){
|
if(GP->listdevices){
|
||||||
for(int i = 0; i < camera->Ndevices; ++i){
|
for(int i = 0; i < camera->Ndevices; ++i){
|
||||||
|
if(!camera->setDevNo(i)) continue;
|
||||||
char modname[256];
|
char modname[256];
|
||||||
camera->getModelName(modname, 255);
|
camera->getModelName(modname, 255);
|
||||||
printf("Found camera #%d: %s\n", i, modname);
|
printf("Found camera #%d: %s\n", i, modname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int num = GP->camdevno;
|
int num = GP->camdevno;
|
||||||
|
if(num < 0) num = 0;
|
||||||
if(num > camera->Ndevices - 1){
|
if(num > camera->Ndevices - 1){
|
||||||
WARNX(_("Found %d cameras, you point number %d"), camera->Ndevices, num);
|
WARNX(_("Found %d cameras, you point number %d"), camera->Ndevices, num);
|
||||||
goto retn;
|
goto retn;
|
||||||
@ -571,7 +637,7 @@ void ccds(){
|
|||||||
snprintf(buf, BUFSIZ, "(%d, %d)(%d, %d)", camera->field.xoff, camera->field.yoff,
|
snprintf(buf, BUFSIZ, "(%d, %d)(%d, %d)", camera->field.xoff, camera->field.yoff,
|
||||||
camera->field.xoff + camera->field.w, camera->field.yoff + camera->field.h);
|
camera->field.xoff + camera->field.w, camera->field.yoff + camera->field.h);
|
||||||
verbose(2, _("Field of view: %s"), buf);
|
verbose(2, _("Field of view: %s"), buf);
|
||||||
if(GP->temperature < 40.){
|
if(!isnan(GP->temperature)){
|
||||||
if(!camera->setT((float)GP->temperature))
|
if(!camera->setT((float)GP->temperature))
|
||||||
WARNX(_("Can't set T to %g degC"), GP->temperature);
|
WARNX(_("Can't set T to %g degC"), GP->temperature);
|
||||||
verbose(3, "SetT=%.1f", GP->temperature);
|
verbose(3, "SetT=%.1f", GP->temperature);
|
||||||
@ -603,29 +669,40 @@ void ccds(){
|
|||||||
WARNX(_("Can't set IOport"));
|
WARNX(_("Can't set IOport"));
|
||||||
}
|
}
|
||||||
if(GP->exptime < 0.) goto retn;
|
if(GP->exptime < 0.) goto retn;
|
||||||
|
if(!isnan(GP->gain)){
|
||||||
|
DBG("Change gain to %g", GP->gain);
|
||||||
|
if(camera->setgain(GP->gain)){
|
||||||
|
camera->getgain(&GP->gain);
|
||||||
|
verbose(1, _("Set gain to %g"), GP->gain);
|
||||||
|
}else WARNX(_("Can't set gain to %g"), GP->gain);
|
||||||
|
}
|
||||||
|
if(!isnan(GP->brightness)){
|
||||||
|
if(camera->setbrightness(GP->brightness)){
|
||||||
|
camera->getbrightness(&GP->brightness);
|
||||||
|
verbose(1, _("Set brightness to %g"), GP->brightness);
|
||||||
|
}else WARNX(_("Can't set brightness to %g"), GP->brightness);
|
||||||
|
}
|
||||||
/*********************** expose control ***********************/
|
/*********************** expose control ***********************/
|
||||||
// cancel previous exp
|
// cancel previous exp
|
||||||
camera->cancel();
|
camera->cancel();
|
||||||
if(!camera->setbin(GP->hbin, GP->vbin))
|
if(!camera->setbin(GP->hbin, GP->vbin))
|
||||||
WARNX(_("Can't set binning %dx%d"), GP->hbin, GP->vbin);
|
WARNX(_("Can't set binning %dx%d"), GP->hbin, GP->vbin);
|
||||||
if(GP->fullframe){
|
if(GP->X0 < 0) GP->X0 = x0; // default values
|
||||||
DBG("FULLFRAME");
|
if(GP->Y0 < 0) GP->Y0 = y0;
|
||||||
GP->X0 = x0; GP->Y0 = y0; GP->X1 = x1; GP->Y1 = y1;
|
if(GP->X1 < 0) GP->X1 = x1;
|
||||||
}
|
|
||||||
if(GP->X0 == -1) GP->X0 = x0; // default values
|
|
||||||
if(GP->Y0 == -1) GP->Y0 = y0;
|
|
||||||
if(GP->X1 == -1) GP->X1 = x1;
|
|
||||||
else if(GP->X1 > x1) GP->X1 = x1;
|
else if(GP->X1 > x1) GP->X1 = x1;
|
||||||
if(GP->Y1 == -1) GP->Y1 = y1;
|
if(GP->Y1 < 0) GP->Y1 = y1;
|
||||||
else if(GP->Y1 > y1) GP->Y1 = y1;
|
else if(GP->Y1 > y1) GP->Y1 = y1;
|
||||||
frameformat fmt = {.w = GP->X1 - GP->X0, .h = GP->Y1 - GP->Y0, .xoff = GP->X0, .yoff = GP->Y0};
|
frameformat fmt = {.w = GP->X1 - GP->X0, .h = GP->Y1 - GP->Y0, .xoff = GP->X0, .yoff = GP->Y0};
|
||||||
int raw_width = fmt.w / GP->hbin, raw_height = fmt.h / GP->vbin;
|
int raw_width = fmt.w / GP->hbin, raw_height = fmt.h / GP->vbin;
|
||||||
if(!camera->setgeometry(&fmt))
|
if(!camera->setgeometry(&fmt))
|
||||||
WARNX(_("Can't set given geometry"));
|
WARNX(_("Can't set given geometry"));
|
||||||
verbose(3, "Geometry: off=%d/%d, wh=%d/%d", fmt.xoff, fmt.yoff, fmt.w, fmt.h);
|
verbose(3, "Geometry: off=%d/%d, wh=%d/%d", fmt.xoff, fmt.yoff, fmt.w, fmt.h);
|
||||||
if(!camera->setnflushes(GP->nflushes))
|
if(GP->nflushes > 0){
|
||||||
WARNX(_("Can't set %d flushes"), GP->nflushes);
|
if(!camera->setnflushes(GP->nflushes))
|
||||||
verbose(3, "Nflushes=%d", GP->nflushes);
|
WARNX(_("Can't set %d flushes"), GP->nflushes);
|
||||||
|
else verbose(3, "Nflushes=%d", GP->nflushes);
|
||||||
|
}
|
||||||
if(!camera->setexp(GP->exptime))
|
if(!camera->setexp(GP->exptime))
|
||||||
WARNX(_("Can't set exposure time to %f seconds"), GP->exptime);
|
WARNX(_("Can't set exposure time to %f seconds"), GP->exptime);
|
||||||
tmpi = (GP->dark) ? 0 : 1;
|
tmpi = (GP->dark) ? 0 : 1;
|
||||||
@ -675,7 +752,7 @@ void ccds(){
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
calculate_stat(&ima);
|
calculate_stat(&ima);
|
||||||
saveFITS(&ima, GP->outfile);
|
saveFITS(&ima);
|
||||||
#ifdef IMAGEVIEW
|
#ifdef IMAGEVIEW
|
||||||
if(GP->showimage){ // display image
|
if(GP->showimage){ // display image
|
||||||
if((mainwin = getWin())){
|
if((mainwin = getWin())){
|
||||||
@ -748,11 +825,7 @@ void ccds(){
|
|||||||
DBG("FREE img");
|
DBG("FREE img");
|
||||||
FREE(img);
|
FREE(img);
|
||||||
retn:
|
retn:
|
||||||
DBG("Close cam");
|
closecam(dlh);
|
||||||
camera->close();
|
|
||||||
DBG("close dlh");
|
|
||||||
dlclose(dlh);
|
|
||||||
camera = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cancel(){
|
void cancel(){
|
||||||
|
|||||||
127
ccdfunc.h
127
ccdfunc.h
@ -20,125 +20,24 @@
|
|||||||
#ifndef CCDFUNC_H__
|
#ifndef CCDFUNC_H__
|
||||||
#define CCDFUNC_H__
|
#define CCDFUNC_H__
|
||||||
|
|
||||||
#include <stdint.h>
|
#include "basestructs.h"
|
||||||
|
|
||||||
typedef struct{
|
extern Camera *camera;
|
||||||
uint16_t *data; // image data
|
extern Focuser *focuser;
|
||||||
int w, h; // image size
|
extern Wheel *wheel;
|
||||||
uint16_t max, min; // min/max values
|
|
||||||
float avr, std; // statistics
|
|
||||||
} IMG;
|
|
||||||
|
|
||||||
// format of single frame
|
void calculate_stat(IMG *image);
|
||||||
typedef struct{
|
void saveFITS(IMG *img); // for imageview module
|
||||||
int w; int h; // width & height
|
|
||||||
int xoff; int yoff; // X and Y offset
|
|
||||||
} frameformat;
|
|
||||||
|
|
||||||
typedef enum{
|
|
||||||
SHUTTER_OPEN, // open shutter now
|
|
||||||
SHUTTER_CLOSE, // close shutter now
|
|
||||||
SHUTTER_OPENATLOW, // ext. expose control @low
|
|
||||||
SHUTTER_OPENATHIGH, // -//- @high
|
|
||||||
SHUTTER_AMOUNT, // amount of entries
|
|
||||||
} shutter_op;
|
|
||||||
|
|
||||||
typedef enum{
|
|
||||||
CAPTURE_NO, // no capture initiated
|
|
||||||
CAPTURE_PROCESS, // in progress
|
|
||||||
CAPTURE_CANTSTART, // can't start
|
|
||||||
CAPTURE_ABORTED, // some error - aborted
|
|
||||||
CAPTURE_READY, // ready - user can read image
|
|
||||||
} capture_status;
|
|
||||||
|
|
||||||
typedef enum{
|
|
||||||
FAN_OFF,
|
|
||||||
FAN_LOW,
|
|
||||||
FAN_MID,
|
|
||||||
FAN_HIGH,
|
|
||||||
} fan_speed;
|
|
||||||
|
|
||||||
// all setters and getters of Camera, Focuser and Wheel should return TRUE if success or FALSE if failed or unsupported
|
|
||||||
// camera
|
|
||||||
typedef struct{
|
|
||||||
int (*check)(); // check if the device is available, connect and init
|
|
||||||
int Ndevices; // amount of devices found
|
|
||||||
void (*close)(); // disconnect & close device
|
|
||||||
int (*startexposition)(); // start exposition
|
|
||||||
int (*pollcapture)(capture_status *st, float *remain);// start or poll capture process, `remain` - time remain (s)
|
|
||||||
int (*capture)(IMG *ima); // capture an image, struct `ima` should be prepared before
|
|
||||||
void (*cancel)(); // cancel exposition
|
|
||||||
// setters:
|
|
||||||
int (*setDevNo)(int n); // set active device number
|
|
||||||
int (*setbrightness)(float b);
|
|
||||||
int (*setexp)(float e);
|
|
||||||
int (*setgain)(float g);
|
|
||||||
int (*setT)(float t);
|
|
||||||
int (*setbin)(int binh, int binv); // binning
|
|
||||||
int (*setnflushes)(int N); // flushes amount
|
|
||||||
int (*shuttercmd)(shutter_op s); // work with shutter
|
|
||||||
int (*confio)(int s); // configure IO-port
|
|
||||||
int (*setio)(int s); // set IO-port to given state
|
|
||||||
int (*setframetype)(int l); // set frametype: 1 - light, 0 - dark
|
|
||||||
int (*setbitdepth)(int h); // set bit depth: 1 - high, 0 - low
|
|
||||||
int (*setfastspeed)(int s); // set readout speed: 1 - fast, 0 - low
|
|
||||||
// geometry (if TRUE, all args are changed to suitable values)
|
|
||||||
int (*setgeometry)(frameformat *fmt); // set geometry in UNBINNED coordinates
|
|
||||||
int (*setfanspeed)(fan_speed spd); // set fan speed
|
|
||||||
// getters:
|
|
||||||
int (*getbrightness)(float *b);// get brightnes level
|
|
||||||
int (*getModelName)(char *n, int l);// string with model name (l - length of n in bytes)
|
|
||||||
int (*getgain)(float *g); // get gain value
|
|
||||||
int (*getmaxgain)(float *g);// get max available gain value
|
|
||||||
// get limits of geometry: maximal values and steps
|
|
||||||
int (*getgeomlimits)(frameformat *max, frameformat *step);
|
|
||||||
int (*getTcold)(float *t); // cold-side T
|
|
||||||
int (*getThot)(float *t); // hot-side T
|
|
||||||
int (*getTbody)(float *t); // body T
|
|
||||||
int (*getbin)(int *binh, int *binv);
|
|
||||||
int (*getio)(int *s); // get IO-port state
|
|
||||||
float pixX, pixY; // pixel size in um
|
|
||||||
frameformat field; // max field of view
|
|
||||||
frameformat array; // array format
|
|
||||||
frameformat geometry; // current geometry settings (as in setgeometry)
|
|
||||||
} Camera;
|
|
||||||
|
|
||||||
// focuser
|
|
||||||
typedef struct{
|
|
||||||
int (*check)(); // check if the device is available
|
|
||||||
int Ndevices;
|
|
||||||
void (*close)();
|
|
||||||
// setters:
|
|
||||||
int (*setDevNo)(int n); // set active device number
|
|
||||||
int (*setAbsPos)(int async, float n);// set absolute position (in millimeters!!!)
|
|
||||||
int (*home)(int async); // home device
|
|
||||||
// getters:
|
|
||||||
int (*getModelName)(char *n, int l);// string with model name (l - length of n in bytes)
|
|
||||||
int (*getTbody)(float *t); // body T
|
|
||||||
int (*getPos)(float *p); // current position number (starting from zero)
|
|
||||||
int (*getMaxPos)(float *p); // max position
|
|
||||||
int (*getMinPos)(float *p); // min position
|
|
||||||
} Focuser;
|
|
||||||
|
|
||||||
// wheel
|
|
||||||
typedef struct{
|
|
||||||
int (*check)(); // check if the device is available
|
|
||||||
int Ndevices;
|
|
||||||
void (*close)();
|
|
||||||
// setters:
|
|
||||||
int (*setDevNo)(int n); // set active device number
|
|
||||||
int (*setPos)(int n); // set absolute position (starting from 0)
|
|
||||||
// getters:
|
|
||||||
int (*getModelName)(char *n, int l);// string with model name (l - length of n in bytes)
|
|
||||||
int (*getTbody)(float *t); // body T
|
|
||||||
int (*getPos)(int *p); // current position number (starting from zero)
|
|
||||||
int (*getMaxPos)(int *p); // amount of positions
|
|
||||||
} Wheel;
|
|
||||||
|
|
||||||
void saveFITS(IMG *img, char *filename); // for imageview module
|
|
||||||
void focusers();
|
void focusers();
|
||||||
void wheels();
|
void wheels();
|
||||||
void ccds();
|
void ccds();
|
||||||
void cancel();
|
void cancel();
|
||||||
|
|
||||||
|
int startCCD(void **dlh);
|
||||||
|
int startWheel(void **dlh);
|
||||||
|
int startFocuser(void **dlh);
|
||||||
|
void focclose(void *dlh);
|
||||||
|
void closewheel(void *dlh);
|
||||||
|
void closecam(void *dlh);
|
||||||
|
|
||||||
#endif // CCDFUNC_H__
|
#endif // CCDFUNC_H__
|
||||||
|
|||||||
176
client.c
Normal file
176
client.c
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the CCD_Capture project.
|
||||||
|
* Copyright 2022 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// client-side functions
|
||||||
|
#include <math.h> // isnan
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <usefull_macros.h>
|
||||||
|
|
||||||
|
#include "client.h"
|
||||||
|
#include "cmdlnopts.h"
|
||||||
|
#include "server.h" // for common commands names
|
||||||
|
#include "socket.h"
|
||||||
|
|
||||||
|
static char sendbuf[BUFSIZ];
|
||||||
|
#define SENDMSG(...) do{snprintf(sendbuf, BUFSIZ-1, __VA_ARGS__); verbose(2, "%s", sendbuf); sendstrmessage(sock, sendbuf); getans(sock);}while(0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check data from fd (polling function for client)
|
||||||
|
* @param fd - file descriptor
|
||||||
|
* @return 0 in case of timeout, 1 in case of fd have data, -1 if error
|
||||||
|
*/
|
||||||
|
static int canberead(int fd){
|
||||||
|
fd_set fds;
|
||||||
|
struct timeval timeout;
|
||||||
|
timeout.tv_sec = 0;
|
||||||
|
timeout.tv_usec = 100;
|
||||||
|
FD_ZERO(&fds);
|
||||||
|
FD_SET(fd, &fds);
|
||||||
|
do{
|
||||||
|
int rc = select(fd+1, &fds, NULL, NULL, &timeout);
|
||||||
|
if(rc < 0){
|
||||||
|
if(errno != EINTR){
|
||||||
|
LOGWARN("select()");
|
||||||
|
WARN("select()");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}while(1);
|
||||||
|
if(FD_ISSET(fd, &fds)){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *getans(int sock){
|
||||||
|
static char buf[BUFSIZ];
|
||||||
|
double t0 = dtime();
|
||||||
|
char *ans = NULL;
|
||||||
|
while(dtime() - t0 < ANSWER_TIMEOUT){
|
||||||
|
if(1 != canberead(sock)) continue;
|
||||||
|
int n = read(sock, buf, BUFSIZ-1);
|
||||||
|
if(n == 0){
|
||||||
|
WARNX("Server disconnected");
|
||||||
|
signals(1);
|
||||||
|
}
|
||||||
|
ans = buf;
|
||||||
|
buf[n] = 0;
|
||||||
|
DBG("Got from server: %s", buf);
|
||||||
|
verbose(1, "%s", buf);
|
||||||
|
}
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *makeabspath(const char *path){
|
||||||
|
static char buf[PATH_MAX];
|
||||||
|
if(!path) return NULL;
|
||||||
|
char *ret = NULL;
|
||||||
|
int unl = 0;
|
||||||
|
FILE *f = fopen(path, "r");
|
||||||
|
if(!f){
|
||||||
|
f = fopen(path, "a");
|
||||||
|
if(!f){
|
||||||
|
ERR("Can't create %s", path);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
unl = 1;
|
||||||
|
}
|
||||||
|
if(!realpath(path, buf)){
|
||||||
|
ERR("realpath()");
|
||||||
|
}else ret = buf;
|
||||||
|
fclose(f);
|
||||||
|
if(unl) unlink(path);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief processData - process here some actions and make messages for server
|
||||||
|
*/
|
||||||
|
static void process_data(int sock){
|
||||||
|
// focuser
|
||||||
|
if(GP->listdevices) SENDMSG(CMD_FOCLIST);
|
||||||
|
if(GP->focdevno > -1) SENDMSG(CMD_FDEVNO "=%d", GP->focdevno);
|
||||||
|
if(!isnan(GP->gotopos)){
|
||||||
|
SENDMSG(CMD_FGOTO "=%g", GP->gotopos);
|
||||||
|
}
|
||||||
|
// wheel
|
||||||
|
if(GP->listdevices) SENDMSG(CMD_WLIST);
|
||||||
|
if(GP->whldevno > -1) SENDMSG(CMD_WDEVNO "=%d", GP->whldevno);
|
||||||
|
if(GP->setwheel > -1) SENDMSG(CMD_WPOS "=%d", GP->setwheel);
|
||||||
|
// CCD/CMOS
|
||||||
|
if(GP->cancelexpose) SENDMSG(CMD_EXPSTATE "=%d", CAMERA_IDLE);
|
||||||
|
if(GP->listdevices) SENDMSG(CMD_CAMLIST);
|
||||||
|
if(GP->camdevno > -1) SENDMSG(CMD_CAMDEVNO "=%d", GP->camdevno);
|
||||||
|
if(GP->hbin) SENDMSG(CMD_HBIN "=%d", GP->hbin);
|
||||||
|
if(GP->vbin) SENDMSG(CMD_VBIN "=%d", GP->vbin);
|
||||||
|
if(!isnan(GP->temperature)) SENDMSG(CMD_CAMTEMPER "=%g", GP->temperature);
|
||||||
|
if(GP->shtr_cmd > -1) SENDMSG(CMD_SHUTTER "=%d", GP->shtr_cmd);
|
||||||
|
if(GP->confio > -1) SENDMSG(CMD_CONFIO "=%d", GP->confio);
|
||||||
|
if(GP->setio > -1) SENDMSG(CMD_IO "=%d", GP->setio);\
|
||||||
|
if(!isnan(GP->gain)) SENDMSG(CMD_GAIN "=%g", GP->gain);
|
||||||
|
if(!isnan(GP->brightness)) SENDMSG(CMD_BRIGHTNESS "=%g", GP->brightness);
|
||||||
|
if(GP->nflushes > 0) SENDMSG(CMD_NFLUSHES "=%d", GP->nflushes);
|
||||||
|
if(GP->rewrite) SENDMSG(CMD_REWRITE "=1");
|
||||||
|
else SENDMSG(CMD_REWRITE "=0");
|
||||||
|
if(GP->outfile) SENDMSG(CMD_FILENAME "=%s", makeabspath(GP->outfile));
|
||||||
|
if(GP->outfileprefix) SENDMSG(CMD_FILENAMEPREFIX "=%s", makeabspath(GP->outfileprefix));
|
||||||
|
// if client gives filename and exptime, make exposition
|
||||||
|
if(GP->exptime > -DBL_EPSILON){
|
||||||
|
SENDMSG(CMD_EXPOSITION "=%g", GP->exptime);
|
||||||
|
if(GP->outfile || GP->outfileprefix) SENDMSG(CMD_EXPSTATE "=%d", CAMERA_CAPTURE);
|
||||||
|
}
|
||||||
|
// common information
|
||||||
|
SENDMSG(CMD_INFO);
|
||||||
|
}
|
||||||
|
|
||||||
|
void client(int sock){
|
||||||
|
process_data(sock);
|
||||||
|
if(!GP->waitexpend) return;
|
||||||
|
double t0 = dtime(), tw = t0;
|
||||||
|
while(dtime() - t0 < CLIENT_TIMEOUT){
|
||||||
|
if(GP->waitexpend && dtime() - tw > WAIT_TIMEOUT){
|
||||||
|
SENDMSG(CMD_TREMAIN); // get remained time
|
||||||
|
tw = dtime();
|
||||||
|
sprintf(sendbuf, "%s", CMD_EXPSTATE);
|
||||||
|
verbose(2, "%s", sendbuf);
|
||||||
|
sendstrmessage(sock, sendbuf);
|
||||||
|
}
|
||||||
|
char *ans = getans(sock);
|
||||||
|
if(ans){
|
||||||
|
t0 = dtime();
|
||||||
|
char *val = get_keyval(ans);
|
||||||
|
if(val && 0 == strcmp(ans, CMD_EXPSTATE)){
|
||||||
|
int state = atoi(val);
|
||||||
|
if(state == CAMERA_ERROR){
|
||||||
|
WARNX(_("Can't make exposition"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(state != CAMERA_CAPTURE){
|
||||||
|
verbose(2, "Frame ready!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WARNX(_("Server timeout"));
|
||||||
|
DBG("Timeout");
|
||||||
|
}
|
||||||
33
client.h
Normal file
33
client.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the CCD_Capture project.
|
||||||
|
* Copyright 2022 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 CLIENT_H__
|
||||||
|
#define CLIENT_H__
|
||||||
|
|
||||||
|
// waiting for answer timeout
|
||||||
|
#define ANSWER_TIMEOUT 1.0
|
||||||
|
// wait for exposition ends (between subsequent check calls)
|
||||||
|
#define WAIT_TIMEOUT 2.0
|
||||||
|
// client will disconnect after this time from last server message
|
||||||
|
#define CLIENT_TIMEOUT 10.0
|
||||||
|
|
||||||
|
// client-side functions
|
||||||
|
void client(int fd);
|
||||||
|
|
||||||
|
#endif // CLIENT_H__
|
||||||
41
cmdlnopts.c
41
cmdlnopts.c
@ -9,24 +9,30 @@
|
|||||||
|
|
||||||
#include "cmdlnopts.h"
|
#include "cmdlnopts.h"
|
||||||
|
|
||||||
|
#define DEFAULT_PID_FILE "/tmp/CCD_Capture.pid"
|
||||||
|
|
||||||
static int help;
|
static int help;
|
||||||
glob_pars *GP = NULL;
|
glob_pars *GP = NULL;
|
||||||
// DEFAULTS
|
// DEFAULTS
|
||||||
// default global parameters
|
// default global parameters
|
||||||
static glob_pars G = {
|
static glob_pars G = {
|
||||||
.instrument = "direct imaging",
|
.instrument = NULL,
|
||||||
.exptime = -1,
|
.exptime = -1.,
|
||||||
.nframes = 1,
|
.nframes = 1,
|
||||||
.hbin = 1, .vbin = 1,
|
.hbin = 1, .vbin = 1,
|
||||||
.X0 = -1, .Y0 = -1,
|
.X0 = -1, .Y0 = -1,
|
||||||
.X1 = -1, .Y1 = -1,
|
.X1 = -1, .Y1 = -1,
|
||||||
.temperature = 1e6,
|
.focdevno = -1,
|
||||||
|
.camdevno = -1,
|
||||||
|
.whldevno = -1,
|
||||||
|
.temperature = NAN,
|
||||||
.shtr_cmd = -1,
|
.shtr_cmd = -1,
|
||||||
.confio = -1, .setio = -1,
|
.confio = -1, .setio = -1,
|
||||||
.gotopos = NAN, .addsteps = NAN,
|
.gotopos = NAN, .addsteps = NAN,
|
||||||
|
.pidfile = DEFAULT_PID_FILE,
|
||||||
|
.brightness = NAN, .gain = NAN,
|
||||||
.setwheel = -1,
|
.setwheel = -1,
|
||||||
.fanspeed = -1,
|
.fanspeed = -1,
|
||||||
.nflushes = 1
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -47,7 +53,7 @@ myoption cmdlnopts[] = {
|
|||||||
{"verbose", NO_ARGS, NULL, 'V', arg_none, APTR(&G.verbose), N_("verbose level (each -v increase it)")},
|
{"verbose", NO_ARGS, NULL, 'V', arg_none, APTR(&G.verbose), N_("verbose level (each -v increase it)")},
|
||||||
{"dark", NO_ARGS, NULL, 'd', arg_int, APTR(&G.dark), N_("not open shutter, when exposing (\"dark frames\")")},
|
{"dark", NO_ARGS, NULL, 'd', arg_int, APTR(&G.dark), N_("not open shutter, when exposing (\"dark frames\")")},
|
||||||
{"8bit", NO_ARGS, NULL, '8', arg_int, APTR(&G._8bit), N_("run in 8-bit mode")},
|
{"8bit", NO_ARGS, NULL, '8', arg_int, APTR(&G._8bit), N_("run in 8-bit mode")},
|
||||||
{"fast", NO_ARGS, NULL, 'f', arg_none, APTR(&G.fast), N_("fast (8MHz) readout mode")},
|
{"fast", NO_ARGS, NULL, 'f', arg_none, APTR(&G.fast), N_("fast readout mode")},
|
||||||
{"set-temp",NEED_ARG, NULL, 't', arg_double, APTR(&G.temperature),N_("set CCD temperature to given value (degr C)")},
|
{"set-temp",NEED_ARG, NULL, 't', arg_double, APTR(&G.temperature),N_("set CCD temperature to given value (degr C)")},
|
||||||
{"set-fan", NEED_ARG, NULL, 0, arg_int, APTR(&G.fanspeed), N_("set fan speed (0 - off, 1 - low, 2 - high)")},
|
{"set-fan", NEED_ARG, NULL, 0, arg_int, APTR(&G.fanspeed), N_("set fan speed (0 - off, 1 - low, 2 - high)")},
|
||||||
|
|
||||||
@ -58,6 +64,8 @@ myoption cmdlnopts[] = {
|
|||||||
{"obsname", NEED_ARG, NULL, 'N', arg_string, APTR(&G.observers), N_("observers' names")},
|
{"obsname", NEED_ARG, NULL, 'N', arg_string, APTR(&G.observers), N_("observers' names")},
|
||||||
{"prog-id", NEED_ARG, NULL, 'P', arg_string, APTR(&G.prog_id), N_("observing program name")},
|
{"prog-id", NEED_ARG, NULL, 'P', arg_string, APTR(&G.prog_id), N_("observing program name")},
|
||||||
{"addrec", MULT_PAR, NULL, 'r', arg_string, APTR(&G.addhdr), N_("add records to header from given file[s]")},
|
{"addrec", MULT_PAR, NULL, 'r', arg_string, APTR(&G.addhdr), N_("add records to header from given file[s]")},
|
||||||
|
{"outfile", NEED_ARG, NULL, 'o', arg_string, APTR(&G.outfile), N_("output file name")},
|
||||||
|
{"wait", NO_ARGS, &G.waitexpend,1,arg_none, NULL, N_("wait while exposition ends")},
|
||||||
|
|
||||||
{"nflushes",NEED_ARG, NULL, 'l', arg_int, APTR(&G.nflushes), N_("N flushes before exposing (default: 1)")},
|
{"nflushes",NEED_ARG, NULL, 'l', arg_int, APTR(&G.nflushes), N_("N flushes before exposing (default: 1)")},
|
||||||
{"hbin", NEED_ARG, NULL, 'h', arg_int, APTR(&G.hbin), N_("horizontal binning to N pixels")},
|
{"hbin", NEED_ARG, NULL, 'h', arg_int, APTR(&G.hbin), N_("horizontal binning to N pixels")},
|
||||||
@ -65,11 +73,11 @@ myoption cmdlnopts[] = {
|
|||||||
{"nframes", NEED_ARG, NULL, 'n', arg_int, APTR(&G.nframes), N_("make series of N frames")},
|
{"nframes", NEED_ARG, NULL, 'n', arg_int, APTR(&G.nframes), N_("make series of N frames")},
|
||||||
{"pause", NEED_ARG, NULL, 'p', arg_int, APTR(&G.pause_len), N_("make pause for N seconds between expositions")},
|
{"pause", NEED_ARG, NULL, 'p', arg_int, APTR(&G.pause_len), N_("make pause for N seconds between expositions")},
|
||||||
{"exptime", NEED_ARG, NULL, 'x', arg_double, APTR(&G.exptime), N_("set exposure time to given value (seconds!)")},
|
{"exptime", NEED_ARG, NULL, 'x', arg_double, APTR(&G.exptime), N_("set exposure time to given value (seconds!)")},
|
||||||
{"X0", NEED_ARG, NULL, 0, arg_int, APTR(&G.X0), N_("frame X0 coordinate (-1 - all with overscan)")},
|
{"cancel", NO_ARGS, &G.cancelexpose, 1,arg_none, NULL, N_("cancel current exposition")},
|
||||||
{"Y0", NEED_ARG, NULL, 0, arg_int, APTR(&G.Y0), N_("frame Y0 coordinate (-1 - all with overscan)")},
|
{"X0", NEED_ARG, NULL, 0, arg_int, APTR(&G.X0), N_("absolute (not divided by binning!) frame X0 coordinate (-1 - all with overscan)")},
|
||||||
{"X1", NEED_ARG, NULL, 0, arg_int, APTR(&G.X1), N_("frame X1 coordinate (-1 - all with overscan)")},
|
{"Y0", NEED_ARG, NULL, 0, arg_int, APTR(&G.Y0), N_("absolute frame Y0 coordinate (-1 - all with overscan)")},
|
||||||
{"Y1", NEED_ARG, NULL, 0, arg_int, APTR(&G.Y1), N_("frame Y1 coordinate (-1 - all with overscan)")},
|
{"X1", NEED_ARG, NULL, 0, arg_int, APTR(&G.X1), N_("absolute frame X1 coordinate (-1 - all with overscan)")},
|
||||||
{"fullframe",NO_ARGS, NULL, 0, arg_int, APTR(&G.fullframe), N_("grab full frame (with overscans)")},
|
{"Y1", NEED_ARG, NULL, 0, arg_int, APTR(&G.Y1), N_("absolute frame Y1 coordinate (-1 - all with overscan)")},
|
||||||
|
|
||||||
{"open-shutter",NO_ARGS,&G.shtr_cmd, SHUTTER_OPEN,arg_none,NULL, N_("open shutter")},
|
{"open-shutter",NO_ARGS,&G.shtr_cmd, SHUTTER_OPEN,arg_none,NULL, N_("open shutter")},
|
||||||
{"close-shutter",NO_ARGS,&G.shtr_cmd, SHUTTER_CLOSE,arg_none,NULL, N_("close shutter")},
|
{"close-shutter",NO_ARGS,&G.shtr_cmd, SHUTTER_CLOSE,arg_none,NULL, N_("close shutter")},
|
||||||
@ -86,6 +94,14 @@ myoption cmdlnopts[] = {
|
|||||||
|
|
||||||
{"wheel-set",NEED_ARG, NULL, 'w', arg_int, APTR(&G.setwheel), N_("set wheel position")},
|
{"wheel-set",NEED_ARG, NULL, 'w', arg_int, APTR(&G.setwheel), N_("set wheel position")},
|
||||||
|
|
||||||
|
{"gain", NEED_ARG, NULL, 0, arg_float, APTR(&G.gain), N_("CMOS gain level")},
|
||||||
|
{"brightness",NEED_ARG, NULL, 0, arg_float, APTR(&G.brightness),N_("CMOS brightness level")},
|
||||||
|
|
||||||
|
{"logfile", NEED_ARG, NULL, 0, arg_string, APTR(&G.logfile), N_("logging file name (if run as server)")},
|
||||||
|
{"path", NEED_ARG, NULL, 0, arg_string, APTR(&G.path), N_("UNIX socket name")},
|
||||||
|
{"port", NEED_ARG, NULL, 0, arg_string, APTR(&G.port), N_("local INET socket port")},
|
||||||
|
{"pidfile", NEED_ARG, NULL, 0, arg_string, APTR(&G.pidfile), N_("PID file (default: " DEFAULT_PID_FILE ")")},
|
||||||
|
|
||||||
#ifdef IMAGEVIEW
|
#ifdef IMAGEVIEW
|
||||||
{"display", NO_ARGS, NULL, 'D', arg_int, APTR(&G.showimage), N_("Display image in OpenGL window")},
|
{"display", NO_ARGS, NULL, 'D', arg_int, APTR(&G.showimage), N_("Display image in OpenGL window")},
|
||||||
#endif
|
#endif
|
||||||
@ -94,7 +110,6 @@ myoption cmdlnopts[] = {
|
|||||||
end_option
|
end_option
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse command line options and return dynamically allocated structure
|
* Parse command line options and return dynamically allocated structure
|
||||||
* to global parameters
|
* to global parameters
|
||||||
@ -104,12 +119,12 @@ myoption cmdlnopts[] = {
|
|||||||
*/
|
*/
|
||||||
glob_pars *parse_args(int argc, char **argv){
|
glob_pars *parse_args(int argc, char **argv){
|
||||||
// format of help: "Usage: progname [args]\n"
|
// format of help: "Usage: progname [args]\n"
|
||||||
change_helpstring("Usage: %s [args] <output file prefix>\n\n\tWhere args are:\n");
|
change_helpstring("Usage: %s [args] [output file prefix]\n\n\tWhere args are:\n");
|
||||||
// parse arguments
|
// parse arguments
|
||||||
parseargs(&argc, &argv, cmdlnopts);
|
parseargs(&argc, &argv, cmdlnopts);
|
||||||
if(help) showhelp(-1, cmdlnopts);
|
if(help) showhelp(-1, cmdlnopts);
|
||||||
if(argc > 0){
|
if(argc > 0){
|
||||||
G.outfile = strdup(argv[0]);
|
G.outfileprefix = strdup(argv[0]);
|
||||||
if(argc > 1){
|
if(argc > 1){
|
||||||
WARNX("%d unused parameters:\n", argc - 1);
|
WARNX("%d unused parameters:\n", argc - 1);
|
||||||
for(int i = 1; i < argc; ++i)
|
for(int i = 1; i < argc; ++i)
|
||||||
|
|||||||
27
cmdlnopts.h
27
cmdlnopts.h
@ -32,24 +32,32 @@ typedef struct{
|
|||||||
char *focuserdev; // focuser ...
|
char *focuserdev; // focuser ...
|
||||||
char *wheeldev; // wheel ...
|
char *wheeldev; // wheel ...
|
||||||
char *objname; // object's name
|
char *objname; // object's name
|
||||||
char *outfile; // output filename prefix
|
char *outfile; // output filename
|
||||||
|
char *outfileprefix;// output filename prefix
|
||||||
char *objtype; // type of object (dark/obj/bias)
|
char *objtype; // type of object (dark/obj/bias)
|
||||||
char *instrument; // instrument's name
|
char *instrument; // instrument's name
|
||||||
char *observers; // observers' names
|
char *observers; // observers' names
|
||||||
char *prog_id; // programm identificator
|
char *prog_id; // programm identificator
|
||||||
char *author; // programm author
|
char *author; // programm author
|
||||||
|
char *logfile; // when run as server log here
|
||||||
|
char *path; // UNIX socket name
|
||||||
|
char *port; // local INET socket port
|
||||||
|
char *pidfile; // PID file (default: /tmp/CCD_Capture.pid)
|
||||||
|
char **addhdr; // list of files from which to add header records
|
||||||
|
int waitexpend; // wait while exposition ends
|
||||||
|
int cancelexpose; // cancel exp
|
||||||
|
int client; // run as client
|
||||||
int listdevices; // list connected devices
|
int listdevices; // list connected devices
|
||||||
int fanspeed; // fan speed: 0-2
|
int fanspeed; // fan speed: 0-2
|
||||||
int noflush; // turn off bg flushing
|
int noflush; // turn off bg flushing
|
||||||
int camdevno; // camera number (0, 1, 2 etc)
|
int camdevno; // camera number (0, 1, 2 etc)
|
||||||
int focdevno;
|
int focdevno; // focuser -//-
|
||||||
int whldevno;
|
int whldevno; // wheel -//-
|
||||||
int dark; // dark frame
|
int dark; // dark frame
|
||||||
int nframes; // amount of frames to take
|
int nframes; // amount of frames to take
|
||||||
int hbin; int vbin; // binning
|
int hbin; int vbin; // binning
|
||||||
int X0; int Y0; // top left corner coordinate (-1 - all, including overscan)
|
int X0; int Y0; // top left corner coordinate (-1 - all, including overscan)
|
||||||
int X1; int Y1; // bottom right corner coordinate
|
int X1; int Y1; // bottom right corner coordinate
|
||||||
int fullframe; // grab full frame (with overscans)
|
|
||||||
int nflushes; // amount of flushes
|
int nflushes; // amount of flushes
|
||||||
int pause_len; // pause (in seconds) between expositions
|
int pause_len; // pause (in seconds) between expositions
|
||||||
int shtr_cmd; // shutter command (flishutter_t)
|
int shtr_cmd; // shutter command (flishutter_t)
|
||||||
@ -58,16 +66,17 @@ typedef struct{
|
|||||||
int getio; // get value of ioport
|
int getio; // get value of ioport
|
||||||
int setio; // set value of ioport
|
int setio; // set value of ioport
|
||||||
int confio; // configure ioport
|
int confio; // configure ioport
|
||||||
double exptime; // time of exposition in seconds
|
|
||||||
double temperature; // temperature of CCD
|
|
||||||
double gotopos; // move stepper motor of focuser to absolute position
|
|
||||||
double addsteps; // move stepper motor of focuser to relative position
|
|
||||||
int setwheel; // set wheel position
|
int setwheel; // set wheel position
|
||||||
int async; // asynchronous moving
|
int async; // asynchronous moving
|
||||||
int verbose; // each '-V' increases it
|
int verbose; // each '-V' increases it
|
||||||
int rewrite; // rewrite file
|
int rewrite; // rewrite file
|
||||||
int showimage; // show image preview
|
int showimage; // show image preview
|
||||||
char **addhdr; // list of files from which to add header records
|
float gain; // gain level (only for CMOS)
|
||||||
|
float brightness; // brightness (only for CMOS)
|
||||||
|
double exptime; // time of exposition in seconds
|
||||||
|
double temperature; // temperature of CCD
|
||||||
|
double gotopos; // move stepper motor of focuser to absolute position
|
||||||
|
double addsteps; // move stepper motor of focuser to relative position
|
||||||
} glob_pars;
|
} glob_pars;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -489,7 +489,7 @@ void* image_thread(_U_ void *data){
|
|||||||
if(win && win->winevt){
|
if(win && win->winevt){
|
||||||
if(win->winevt & WINEVT_SAVEIMAGE){ // save image
|
if(win->winevt & WINEVT_SAVEIMAGE){ // save image
|
||||||
verbose(2, "Make screenshot\n");
|
verbose(2, "Make screenshot\n");
|
||||||
saveFITS(img, "ScreenShot");
|
saveFITS(img);
|
||||||
win->winevt &= ~WINEVT_SAVEIMAGE;
|
win->winevt &= ~WINEVT_SAVEIMAGE;
|
||||||
}
|
}
|
||||||
if(win->winevt & WINEVT_ROLLCOLORFUN){
|
if(win->winevt & WINEVT_ROLLCOLORFUN){
|
||||||
|
|||||||
@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2022-03-01 20:35+0300\n"
|
"POT-Creation-Date: 2022-03-17 18:04+0300\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@ -17,472 +17,543 @@ msgstr ""
|
|||||||
"Content-Type: text/plain; charset=koi8-r\n"
|
"Content-Type: text/plain; charset=koi8-r\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
#: cmdlnopts.c:37
|
#: cmdlnopts.c:43
|
||||||
msgid "common device plugin (e.g devfli.so)"
|
msgid "common device plugin (e.g devfli.so)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:38
|
#: cmdlnopts.c:44
|
||||||
msgid "camera device plugin (e.g. devfli.so)"
|
msgid "camera device plugin (e.g. devfli.so)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:39
|
#: cmdlnopts.c:45
|
||||||
msgid "focuser device plugin (e.g. devzwo.so)"
|
msgid "focuser device plugin (e.g. devzwo.so)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:40
|
#: cmdlnopts.c:46
|
||||||
msgid "wheel device plugin (e.g. devdummy.so)"
|
msgid "wheel device plugin (e.g. devdummy.so)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:41
|
#: cmdlnopts.c:47
|
||||||
msgid "list connected devices"
|
msgid "list connected devices"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:42
|
#: cmdlnopts.c:48
|
||||||
msgid "camera device number (if many: 0, 1, 2 etc)"
|
msgid "camera device number (if many: 0, 1, 2 etc)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:43
|
#: cmdlnopts.c:49
|
||||||
msgid "filter wheel device number (if many: 0, 1, 2 etc)"
|
msgid "filter wheel device number (if many: 0, 1, 2 etc)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:44
|
#: cmdlnopts.c:50
|
||||||
msgid "focuser device number (if many: 0, 1, 2 etc)"
|
msgid "focuser device number (if many: 0, 1, 2 etc)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:45
|
#: cmdlnopts.c:51
|
||||||
msgid "show this help"
|
msgid "show this help"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:46
|
#: cmdlnopts.c:52
|
||||||
msgid "rewrite output file if exists"
|
msgid "rewrite output file if exists"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:47
|
#: cmdlnopts.c:53
|
||||||
msgid "verbose level (each -v increase it)"
|
msgid "verbose level (each -v increase it)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:48
|
#: cmdlnopts.c:54
|
||||||
msgid "not open shutter, when exposing (\"dark frames\")"
|
msgid "not open shutter, when exposing (\"dark frames\")"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:49
|
#: cmdlnopts.c:55
|
||||||
msgid "run in 8-bit mode"
|
msgid "run in 8-bit mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:50
|
|
||||||
msgid "fast (8MHz) readout mode"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: cmdlnopts.c:51
|
|
||||||
msgid "set CCD temperature to given value (degr C)"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: cmdlnopts.c:52
|
|
||||||
msgid "set fan speed (0 - off, 1 - low, 2 - high)"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: cmdlnopts.c:54
|
|
||||||
msgid "program author"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: cmdlnopts.c:55
|
|
||||||
msgid "object type (neon, object, flat etc)"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: cmdlnopts.c:56
|
#: cmdlnopts.c:56
|
||||||
msgid "instrument name"
|
msgid "fast readout mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:57
|
#: cmdlnopts.c:57
|
||||||
msgid "object name"
|
msgid "set CCD temperature to given value (degr C)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:58
|
#: cmdlnopts.c:58
|
||||||
msgid "observers' names"
|
msgid "set fan speed (0 - off, 1 - low, 2 - high)"
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: cmdlnopts.c:59
|
|
||||||
msgid "observing program name"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:60
|
#: cmdlnopts.c:60
|
||||||
msgid "add records to header from given file[s]"
|
msgid "program author"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:61
|
||||||
|
msgid "object type (neon, object, flat etc)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:62
|
#: cmdlnopts.c:62
|
||||||
msgid "N flushes before exposing (default: 1)"
|
msgid "instrument name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:63
|
#: cmdlnopts.c:63
|
||||||
msgid "horizontal binning to N pixels"
|
msgid "object name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:64
|
#: cmdlnopts.c:64
|
||||||
msgid "vertical binning to N pixels"
|
msgid "observers' names"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:65
|
#: cmdlnopts.c:65
|
||||||
msgid "make series of N frames"
|
msgid "observing program name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:66
|
#: cmdlnopts.c:66
|
||||||
msgid "make pause for N seconds between expositions"
|
msgid "add records to header from given file[s]"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:67
|
#: cmdlnopts.c:67
|
||||||
msgid "set exposure time to given value (seconds!)"
|
msgid "output file name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:68
|
#: cmdlnopts.c:68
|
||||||
msgid "frame X0 coordinate (-1 - all with overscan)"
|
msgid "wait while exposition ends"
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: cmdlnopts.c:69
|
|
||||||
msgid "frame Y0 coordinate (-1 - all with overscan)"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:70
|
#: cmdlnopts.c:70
|
||||||
msgid "frame X1 coordinate (-1 - all with overscan)"
|
msgid "N flushes before exposing (default: 1)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:71
|
#: cmdlnopts.c:71
|
||||||
msgid "frame Y1 coordinate (-1 - all with overscan)"
|
msgid "horizontal binning to N pixels"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:72
|
#: cmdlnopts.c:72
|
||||||
msgid "grab full frame (with overscans)"
|
msgid "vertical binning to N pixels"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:73
|
||||||
|
msgid "make series of N frames"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:74
|
#: cmdlnopts.c:74
|
||||||
msgid "open shutter"
|
msgid "make pause for N seconds between expositions"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:75
|
#: cmdlnopts.c:75
|
||||||
msgid "close shutter"
|
msgid "set exposure time to given value (seconds!)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:76
|
#: cmdlnopts.c:76
|
||||||
msgid "run exposition on LOW @ pin5 I/O port"
|
msgid "cancel current exposition"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:77
|
#: cmdlnopts.c:77
|
||||||
msgid "run exposition on HIGH @ pin5 I/O port"
|
msgid ""
|
||||||
|
"absolute (not divided by binning!) frame X0 coordinate (-1 - all with "
|
||||||
|
"overscan)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:78
|
#: cmdlnopts.c:78
|
||||||
msgid "get value of I/O port pins"
|
msgid "absolute frame Y0 coordinate (-1 - all with overscan)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:79
|
#: cmdlnopts.c:79
|
||||||
msgid "move stepper motor asynchronous"
|
msgid "absolute frame X1 coordinate (-1 - all with overscan)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:81
|
#: cmdlnopts.c:80
|
||||||
msgid "set I/O port pins to given value (decimal number, pin1 is LSB)"
|
msgid "absolute frame Y1 coordinate (-1 - all with overscan)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:82
|
#: cmdlnopts.c:82
|
||||||
|
msgid "open shutter"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:83
|
||||||
|
msgid "close shutter"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:84
|
||||||
|
msgid "run exposition on LOW @ pin5 I/O port"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:85
|
||||||
|
msgid "run exposition on HIGH @ pin5 I/O port"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:86
|
||||||
|
msgid "get value of I/O port pins"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:87
|
||||||
|
msgid "move stepper motor asynchronous"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:89
|
||||||
|
msgid "set I/O port pins to given value (decimal number, pin1 is LSB)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:90
|
||||||
msgid ""
|
msgid ""
|
||||||
"configure I/O port pins to given value (decimal number, pin1 is LSB, 1 == "
|
"configure I/O port pins to given value (decimal number, pin1 is LSB, 1 == "
|
||||||
"output, 0 == input)"
|
"output, 0 == input)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:84
|
#: cmdlnopts.c:92
|
||||||
msgid "move focuser to absolute position, mm"
|
msgid "move focuser to absolute position, mm"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:85
|
#: cmdlnopts.c:93
|
||||||
msgid "move focuser to relative position, mm"
|
msgid "move focuser to relative position, mm"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:87
|
#: cmdlnopts.c:95
|
||||||
msgid "set wheel position"
|
msgid "set wheel position"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:90
|
#: cmdlnopts.c:97
|
||||||
|
msgid "CMOS gain level"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:98
|
||||||
|
msgid "CMOS brightness level"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:100
|
||||||
|
msgid "logging file name (if run as server)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:101
|
||||||
|
msgid "UNIX socket name"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:102
|
||||||
|
msgid "local INET socket port"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:103
|
||||||
|
msgid "PID file (default: "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:106
|
||||||
msgid "Display image in OpenGL window"
|
msgid "Display image in OpenGL window"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:62
|
#: ccdfunc.c:63
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't find plugin %s: %s"
|
msgid "Can't find plugin %s: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:74
|
#: ccdfunc.c:75
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't find focuser in plugin %s: %s"
|
msgid "Can't find focuser in plugin %s: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:85
|
#: ccdfunc.c:86
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't find camera in plugin %s: %s"
|
msgid "Can't find camera in plugin %s: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:96
|
#: ccdfunc.c:97
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't find wheel in plugin %s: %s"
|
msgid "Can't find wheel in plugin %s: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:149
|
#: ccdfunc.c:152
|
||||||
msgid "Camera device unknown"
|
msgid "Camera device unknown"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. Не могу сохранить файл
|
#: ccdfunc.c:158
|
||||||
#: ccdfunc.c:157
|
msgid "Neither filename nor filename prefix pointed!"
|
||||||
msgid "Can't save file"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:304
|
#. Не могу сохранить файл
|
||||||
|
#: ccdfunc.c:177
|
||||||
|
#, c-format
|
||||||
|
msgid "Can't save file with prefix %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ccdfunc.c:329
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "File saved as '%s'"
|
msgid "File saved as '%s'"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:306
|
#: ccdfunc.c:332
|
||||||
msgid "Error saving file"
|
msgid "Error saving file"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:344
|
#: ccdfunc.c:371
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Image stat:\n"
|
msgid "Image stat:\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:357
|
#: ccdfunc.c:379
|
||||||
msgid "Focuser device not pointed"
|
msgid "Focuser device not pointed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:364
|
#: ccdfunc.c:386
|
||||||
msgid "No focusers found"
|
msgid "No focusers found"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:377
|
#: ccdfunc.c:417
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Found %d focusers, you point number %d"
|
msgid "Found %d focusers, you point number %d"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:381
|
#: ccdfunc.c:421
|
||||||
msgid "Can't set active focuser number"
|
msgid "Can't set active focuser number"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:395
|
#: ccdfunc.c:435
|
||||||
msgid "Can't get focuser limit positions"
|
msgid "Can't get focuser limit positions"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:402
|
#: ccdfunc.c:442
|
||||||
msgid "Can't get current focuser position"
|
msgid "Can't get current focuser position"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:416
|
#: ccdfunc.c:456
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't set position %g: out of limits [%g, %g]"
|
msgid "Can't set position %g: out of limits [%g, %g]"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:420
|
#: ccdfunc.c:460
|
||||||
msgid "Can't home focuser"
|
msgid "Can't home focuser"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:422
|
#: ccdfunc.c:462
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't set position %g"
|
msgid "Can't set position %g"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:437
|
#: ccdfunc.c:470
|
||||||
msgid "Wheel device not pointed"
|
msgid "Wheel device not pointed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:444
|
#: ccdfunc.c:477
|
||||||
msgid "No wheels found"
|
msgid "No wheels found"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:457
|
#: ccdfunc.c:508
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Found %d wheels, you point number %d"
|
msgid "Found %d wheels, you point number %d"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:461
|
#: ccdfunc.c:512
|
||||||
msgid "Can't set active wheel number"
|
msgid "Can't set active wheel number"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:477
|
#: ccdfunc.c:528
|
||||||
msgid "Can't get max wheel position"
|
msgid "Can't get max wheel position"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:484
|
#: ccdfunc.c:535
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Wheel position should be from 0 to %d"
|
msgid "Wheel position should be from 0 to %d"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:488
|
#: ccdfunc.c:539
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't set wheel position %d"
|
msgid "Can't set wheel position %d"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:507
|
#: ccdfunc.c:556
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%.1f seconds till exposition ends"
|
msgid "%.1f seconds till exposition ends"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:528
|
#: ccdfunc.c:570
|
||||||
msgid "Camera device not pointed"
|
msgid "Camera device not pointed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:535
|
#: ccdfunc.c:577 ccdfunc.c:578
|
||||||
msgid "No cameras found"
|
msgid "No cameras found"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:547
|
#: ccdfunc.c:613
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Found %d cameras, you point number %d"
|
msgid "Found %d cameras, you point number %d"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:551
|
#: ccdfunc.c:617
|
||||||
msgid "Can't set active camera number"
|
msgid "Can't set active camera number"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:557
|
#: ccdfunc.c:623
|
||||||
msgid "Can't set fan speed"
|
msgid "Can't set fan speed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:558
|
#: ccdfunc.c:624
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Set fan speed to %d"
|
msgid "Set fan speed to %d"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:563
|
#: ccdfunc.c:629
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Camera model: %s"
|
msgid "Camera model: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:564
|
#: ccdfunc.c:630
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Pixel size: %g x %g"
|
msgid "Pixel size: %g x %g"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:570
|
#: ccdfunc.c:636
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Full array: %s"
|
msgid "Full array: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:573
|
#: ccdfunc.c:639
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Field of view: %s"
|
msgid "Field of view: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:576
|
#: ccdfunc.c:642
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't set T to %g degC"
|
msgid "Can't set T to %g degC"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:583
|
#: ccdfunc.c:649
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Shutter command: %s\n"
|
msgid "Shutter command: %s\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:585
|
#: ccdfunc.c:651
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't run shutter command %s (unsupported?)"
|
msgid "Can't run shutter command %s (unsupported?)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. "Попытка сконфигурировать порт I/O как %d\n"
|
#. "Попытка сконфигурировать порт I/O как %d\n"
|
||||||
#: ccdfunc.c:589
|
#: ccdfunc.c:655
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Try to configure I/O port as %d"
|
msgid "Try to configure I/O port as %d"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:591
|
#: ccdfunc.c:657
|
||||||
msgid "Can't configure (unsupported?)"
|
msgid "Can't configure (unsupported?)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:597
|
#: ccdfunc.c:663
|
||||||
msgid "Can't get IOport state (unsupported?)"
|
msgid "Can't get IOport state (unsupported?)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. "Попытка записи %d в порт I/O\n"
|
#. "Попытка записи %d в порт I/O\n"
|
||||||
#: ccdfunc.c:601
|
#: ccdfunc.c:667
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Try to write %d to I/O port"
|
msgid "Try to write %d to I/O port"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:603
|
#: ccdfunc.c:669
|
||||||
msgid "Can't set IOport"
|
msgid "Can't set IOport"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:610
|
#: ccdfunc.c:676
|
||||||
|
#, c-format
|
||||||
|
msgid "Set gain to %g"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ccdfunc.c:677
|
||||||
|
#, c-format
|
||||||
|
msgid "Can't set gain to %g"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ccdfunc.c:682
|
||||||
|
#, c-format
|
||||||
|
msgid "Set brightness to %g"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ccdfunc.c:683
|
||||||
|
#, c-format
|
||||||
|
msgid "Can't set brightness to %g"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ccdfunc.c:689
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't set binning %dx%d"
|
msgid "Can't set binning %dx%d"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:624
|
#: ccdfunc.c:699
|
||||||
msgid "Can't set given geometry"
|
msgid "Can't set given geometry"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:627
|
#: ccdfunc.c:703
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't set %d flushes"
|
msgid "Can't set %d flushes"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:630
|
#: ccdfunc.c:707
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't set exposure time to %f seconds"
|
msgid "Can't set exposure time to %f seconds"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:633
|
#: ccdfunc.c:710
|
||||||
msgid "Can't change frame type"
|
msgid "Can't change frame type"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:636
|
#: ccdfunc.c:713
|
||||||
msgid "Can't set bit depth"
|
msgid "Can't set bit depth"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:638
|
#: ccdfunc.c:715
|
||||||
msgid "Can't set readout speed"
|
msgid "Can't set readout speed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:639
|
#: ccdfunc.c:716
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Readout mode: %s"
|
msgid "Readout mode: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:640
|
#: ccdfunc.c:717
|
||||||
msgid "Only show statistics"
|
msgid "Only show statistics"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. GET binning should be AFTER setgeometry!
|
#. GET binning should be AFTER setgeometry!
|
||||||
#: ccdfunc.c:642
|
#: ccdfunc.c:719
|
||||||
msgid "Can't get current binning"
|
msgid "Can't get current binning"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:655
|
#: ccdfunc.c:732
|
||||||
msgid "Can't open OpenGL window, image preview will be inaccessible"
|
msgid "Can't open OpenGL window, image preview will be inaccessible"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. Захват кадра %d\n
|
#. Захват кадра %d\n
|
||||||
#: ccdfunc.c:662
|
#: ccdfunc.c:739
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Capture frame %d"
|
msgid "Capture frame %d"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:664
|
#: ccdfunc.c:741 server.c:64
|
||||||
msgid "Can't start exposition"
|
msgid "Can't start exposition"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:668 ccdfunc.c:690 ccdfunc.c:731
|
#: ccdfunc.c:745 ccdfunc.c:767 ccdfunc.c:808
|
||||||
msgid "Can't capture image"
|
msgid "Can't capture image"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:671
|
#: ccdfunc.c:748
|
||||||
msgid "Read grabbed image"
|
msgid "Read grabbed image"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:674 ccdfunc.c:694 ccdfunc.c:735
|
#: ccdfunc.c:751 ccdfunc.c:771 ccdfunc.c:812
|
||||||
msgid "Can't grab image"
|
msgid "Can't grab image"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. %d секунд до окончания паузы\n
|
#. %d секунд до окончания паузы\n
|
||||||
#: ccdfunc.c:711
|
#: ccdfunc.c:788
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d seconds till pause ends\n"
|
msgid "%d seconds till pause ends\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: server.c:89
|
||||||
|
msgid "No camera device"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: client.c:164
|
||||||
|
msgid "Can't make exposition"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: client.c:174
|
||||||
|
msgid "Server timeout"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: imageview.c:264
|
#: imageview.c:264
|
||||||
msgid "Can't init mutex!"
|
msgid "Can't init mutex!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|||||||
320
locale/ru/ru.po
320
locale/ru/ru.po
@ -7,7 +7,7 @@
|
|||||||
msgid ""
|
msgid ""
|
||||||
msgstr "Project-Id-Version: PACKAGE VERSION\n"
|
msgstr "Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2022-03-01 20:27+0300\n"
|
"POT-Creation-Date: 2022-03-17 18:04+0300\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@ -16,13 +16,13 @@ msgstr "Project-Id-Version: PACKAGE VERSION\n"
|
|||||||
"Content-Type: text/plain; charset=koi8-r\n"
|
"Content-Type: text/plain; charset=koi8-r\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
#: ccdfunc.c:507
|
#: ccdfunc.c:556
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%.1f seconds till exposition ends"
|
msgid "%.1f seconds till exposition ends"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. %d секунд до окончания паузы\n
|
#. %d секунд до окончания паузы\n
|
||||||
#: ccdfunc.c:711
|
#: ccdfunc.c:788
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d seconds till pause ends\n"
|
msgid "%d seconds till pause ends\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -31,77 +31,85 @@ msgstr ""
|
|||||||
msgid "Already initialized!"
|
msgid "Already initialized!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:528
|
#: cmdlnopts.c:98
|
||||||
|
msgid "CMOS brightness level"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:97
|
||||||
|
msgid "CMOS gain level"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ccdfunc.c:570
|
||||||
msgid "Camera device not pointed"
|
msgid "Camera device not pointed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:149
|
#: ccdfunc.c:152
|
||||||
msgid "Camera device unknown"
|
msgid "Camera device unknown"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:563
|
#: ccdfunc.c:629
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Camera model: %s"
|
msgid "Camera model: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:668 ccdfunc.c:690 ccdfunc.c:731
|
#: ccdfunc.c:745 ccdfunc.c:767 ccdfunc.c:808
|
||||||
msgid "Can't capture image"
|
msgid "Can't capture image"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:633
|
#: ccdfunc.c:710
|
||||||
msgid "Can't change frame type"
|
msgid "Can't change frame type"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:591
|
#: ccdfunc.c:657
|
||||||
msgid "Can't configure (unsupported?)"
|
msgid "Can't configure (unsupported?)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:85
|
#: ccdfunc.c:86
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't find camera in plugin %s: %s"
|
msgid "Can't find camera in plugin %s: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:74
|
#: ccdfunc.c:75
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't find focuser in plugin %s: %s"
|
msgid "Can't find focuser in plugin %s: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:62
|
#: ccdfunc.c:63
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't find plugin %s: %s"
|
msgid "Can't find plugin %s: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:96
|
#: ccdfunc.c:97
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't find wheel in plugin %s: %s"
|
msgid "Can't find wheel in plugin %s: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:597
|
#: ccdfunc.c:663
|
||||||
msgid "Can't get IOport state (unsupported?)"
|
msgid "Can't get IOport state (unsupported?)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. GET binning should be AFTER setgeometry!
|
#. GET binning should be AFTER setgeometry!
|
||||||
#: ccdfunc.c:642
|
#: ccdfunc.c:719
|
||||||
msgid "Can't get current binning"
|
msgid "Can't get current binning"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:402
|
#: ccdfunc.c:442
|
||||||
msgid "Can't get current focuser position"
|
msgid "Can't get current focuser position"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:395
|
#: ccdfunc.c:435
|
||||||
msgid "Can't get focuser limit positions"
|
msgid "Can't get focuser limit positions"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:477
|
#: ccdfunc.c:528
|
||||||
msgid "Can't get max wheel position"
|
msgid "Can't get max wheel position"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:674 ccdfunc.c:694 ccdfunc.c:735
|
#: ccdfunc.c:751 ccdfunc.c:771 ccdfunc.c:812
|
||||||
msgid "Can't grab image"
|
msgid "Can't grab image"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:420
|
#: ccdfunc.c:460
|
||||||
msgid "Can't home focuser"
|
msgid "Can't home focuser"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -109,98 +117,113 @@ msgstr ""
|
|||||||
msgid "Can't init mutex!"
|
msgid "Can't init mutex!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:655
|
#: client.c:164
|
||||||
|
msgid "Can't make exposition"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ccdfunc.c:732
|
||||||
msgid "Can't open OpenGL window, image preview will be inaccessible"
|
msgid "Can't open OpenGL window, image preview will be inaccessible"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:585
|
#: ccdfunc.c:651
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't run shutter command %s (unsupported?)"
|
msgid "Can't run shutter command %s (unsupported?)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. Не могу сохранить файл
|
#. Не могу сохранить файл
|
||||||
#: ccdfunc.c:157
|
#: ccdfunc.c:177
|
||||||
msgid "Can't save file"
|
#, c-format
|
||||||
|
msgid "Can't save file with prefix %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:627
|
#: ccdfunc.c:703
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't set %d flushes"
|
msgid "Can't set %d flushes"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:603
|
#: ccdfunc.c:669
|
||||||
msgid "Can't set IOport"
|
msgid "Can't set IOport"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:576
|
#: ccdfunc.c:642
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't set T to %g degC"
|
msgid "Can't set T to %g degC"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:551
|
#: ccdfunc.c:617
|
||||||
msgid "Can't set active camera number"
|
msgid "Can't set active camera number"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:381
|
#: ccdfunc.c:421
|
||||||
msgid "Can't set active focuser number"
|
msgid "Can't set active focuser number"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:461
|
#: ccdfunc.c:512
|
||||||
msgid "Can't set active wheel number"
|
msgid "Can't set active wheel number"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:610
|
#: ccdfunc.c:689
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't set binning %dx%d"
|
msgid "Can't set binning %dx%d"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:636
|
#: ccdfunc.c:713
|
||||||
msgid "Can't set bit depth"
|
msgid "Can't set bit depth"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:630
|
#: ccdfunc.c:683
|
||||||
|
#, c-format
|
||||||
|
msgid "Can't set brightness to %g"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ccdfunc.c:707
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't set exposure time to %f seconds"
|
msgid "Can't set exposure time to %f seconds"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:557
|
#: ccdfunc.c:623
|
||||||
msgid "Can't set fan speed"
|
msgid "Can't set fan speed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:624
|
#: ccdfunc.c:677
|
||||||
|
#, c-format
|
||||||
|
msgid "Can't set gain to %g"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ccdfunc.c:699
|
||||||
msgid "Can't set given geometry"
|
msgid "Can't set given geometry"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:422
|
#: ccdfunc.c:462
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't set position %g"
|
msgid "Can't set position %g"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:416
|
#: ccdfunc.c:456
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't set position %g: out of limits [%g, %g]"
|
msgid "Can't set position %g: out of limits [%g, %g]"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:638
|
#: ccdfunc.c:715
|
||||||
msgid "Can't set readout speed"
|
msgid "Can't set readout speed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:488
|
#: ccdfunc.c:539
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't set wheel position %d"
|
msgid "Can't set wheel position %d"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:664
|
#: ccdfunc.c:741 server.c:64
|
||||||
msgid "Can't start exposition"
|
msgid "Can't start exposition"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. Захват кадра %d\n
|
#. Захват кадра %d\n
|
||||||
#: ccdfunc.c:662
|
#: ccdfunc.c:739
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Capture frame %d"
|
msgid "Capture frame %d"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:90
|
#: cmdlnopts.c:106
|
||||||
msgid "Display image in OpenGL window"
|
msgid "Display image in OpenGL window"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -209,40 +232,40 @@ msgstr ""
|
|||||||
msgid "Equalization of histogram: %s"
|
msgid "Equalization of histogram: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:306
|
#: ccdfunc.c:332
|
||||||
msgid "Error saving file"
|
msgid "Error saving file"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:573
|
#: ccdfunc.c:639
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Field of view: %s"
|
msgid "Field of view: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:304
|
#: ccdfunc.c:329
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "File saved as '%s'"
|
msgid "File saved as '%s'"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:357
|
#: ccdfunc.c:379
|
||||||
msgid "Focuser device not pointed"
|
msgid "Focuser device not pointed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:547
|
#: ccdfunc.c:613
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Found %d cameras, you point number %d"
|
msgid "Found %d cameras, you point number %d"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:377
|
#: ccdfunc.c:417
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Found %d focusers, you point number %d"
|
msgid "Found %d focusers, you point number %d"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:457
|
#: ccdfunc.c:508
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Found %d wheels, you point number %d"
|
msgid "Found %d wheels, you point number %d"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:570
|
#: ccdfunc.c:636
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Full array: %s"
|
msgid "Full array: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -252,190 +275,229 @@ msgstr ""
|
|||||||
msgid "Histogram conversion: %s"
|
msgid "Histogram conversion: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:344
|
#: ccdfunc.c:371
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Image stat:\n"
|
msgid "Image stat:\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:62
|
#: cmdlnopts.c:70
|
||||||
msgid "N flushes before exposing (default: 1)"
|
msgid "N flushes before exposing (default: 1)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:535
|
#: ccdfunc.c:158
|
||||||
|
msgid "Neither filename nor filename prefix pointed!"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: server.c:89
|
||||||
|
msgid "No camera device"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ccdfunc.c:577 ccdfunc.c:578
|
||||||
msgid "No cameras found"
|
msgid "No cameras found"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:364
|
#: ccdfunc.c:386
|
||||||
msgid "No focusers found"
|
msgid "No focusers found"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:444
|
#: ccdfunc.c:477
|
||||||
msgid "No wheels found"
|
msgid "No wheels found"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:640
|
#: ccdfunc.c:717
|
||||||
msgid "Only show statistics"
|
msgid "Only show statistics"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:564
|
#: cmdlnopts.c:103
|
||||||
|
msgid "PID file (default: "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ccdfunc.c:630
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Pixel size: %g x %g"
|
msgid "Pixel size: %g x %g"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:671
|
#: ccdfunc.c:748
|
||||||
msgid "Read grabbed image"
|
msgid "Read grabbed image"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:639
|
#: ccdfunc.c:716
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Readout mode: %s"
|
msgid "Readout mode: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:558
|
#: client.c:174
|
||||||
|
msgid "Server timeout"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ccdfunc.c:682
|
||||||
|
#, c-format
|
||||||
|
msgid "Set brightness to %g"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ccdfunc.c:624
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Set fan speed to %d"
|
msgid "Set fan speed to %d"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:583
|
#: ccdfunc.c:676
|
||||||
|
#, c-format
|
||||||
|
msgid "Set gain to %g"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ccdfunc.c:649
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Shutter command: %s\n"
|
msgid "Shutter command: %s\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. "Попытка сконфигурировать порт I/O как %d\n"
|
#. "Попытка сконфигурировать порт I/O как %d\n"
|
||||||
#: ccdfunc.c:589
|
#: ccdfunc.c:655
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Try to configure I/O port as %d"
|
msgid "Try to configure I/O port as %d"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. "Попытка записи %d в порт I/O\n"
|
#. "Попытка записи %d в порт I/O\n"
|
||||||
#: ccdfunc.c:601
|
#: ccdfunc.c:667
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Try to write %d to I/O port"
|
msgid "Try to write %d to I/O port"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:437
|
#: cmdlnopts.c:101
|
||||||
|
msgid "UNIX socket name"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ccdfunc.c:470
|
||||||
msgid "Wheel device not pointed"
|
msgid "Wheel device not pointed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ccdfunc.c:484
|
#: ccdfunc.c:535
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Wheel position should be from 0 to %d"
|
msgid "Wheel position should be from 0 to %d"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:60
|
#: cmdlnopts.c:77
|
||||||
|
msgid "absolute (not divided by binning!) frame X0 coordinate (-1 - all "
|
||||||
|
"with overscan)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:79
|
||||||
|
msgid "absolute frame X1 coordinate (-1 - all with overscan)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:78
|
||||||
|
msgid "absolute frame Y0 coordinate (-1 - all with overscan)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:80
|
||||||
|
msgid "absolute frame Y1 coordinate (-1 - all with overscan)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:66
|
||||||
msgid "add records to header from given file[s]"
|
msgid "add records to header from given file[s]"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:42
|
#: cmdlnopts.c:48
|
||||||
msgid "camera device number (if many: 0, 1, 2 etc)"
|
msgid "camera device number (if many: 0, 1, 2 etc)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:38
|
#: cmdlnopts.c:44
|
||||||
msgid "camera device plugin (e.g. devfli.so)"
|
msgid "camera device plugin (e.g. devfli.so)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:75
|
#: cmdlnopts.c:76
|
||||||
|
msgid "cancel current exposition"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:83
|
||||||
msgid "close shutter"
|
msgid "close shutter"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:37
|
#: cmdlnopts.c:43
|
||||||
msgid "common device plugin (e.g devfli.so)"
|
msgid "common device plugin (e.g devfli.so)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:82
|
#: cmdlnopts.c:90
|
||||||
msgid "configure I/O port pins to given value (decimal number, pin1 is LSB, "
|
msgid "configure I/O port pins to given value (decimal number, pin1 is LSB, "
|
||||||
"1 == output, 0 == input)"
|
"1 == output, 0 == input)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:50
|
#: cmdlnopts.c:56
|
||||||
msgid "fast (8MHz) readout mode"
|
msgid "fast readout mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:43
|
#: cmdlnopts.c:49
|
||||||
msgid "filter wheel device number (if many: 0, 1, 2 etc)"
|
msgid "filter wheel device number (if many: 0, 1, 2 etc)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:44
|
#: cmdlnopts.c:50
|
||||||
msgid "focuser device number (if many: 0, 1, 2 etc)"
|
msgid "focuser device number (if many: 0, 1, 2 etc)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:39
|
#: cmdlnopts.c:45
|
||||||
msgid "focuser device plugin (e.g. devzwo.so)"
|
msgid "focuser device plugin (e.g. devzwo.so)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:68
|
#: cmdlnopts.c:86
|
||||||
msgid "frame X0 coordinate (-1 - all with overscan)"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: cmdlnopts.c:70
|
|
||||||
msgid "frame X1 coordinate (-1 - all with overscan)"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: cmdlnopts.c:69
|
|
||||||
msgid "frame Y0 coordinate (-1 - all with overscan)"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: cmdlnopts.c:71
|
|
||||||
msgid "frame Y1 coordinate (-1 - all with overscan)"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: cmdlnopts.c:78
|
|
||||||
msgid "get value of I/O port pins"
|
msgid "get value of I/O port pins"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:72
|
#: cmdlnopts.c:71
|
||||||
msgid "grab full frame (with overscans)"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: cmdlnopts.c:63
|
|
||||||
msgid "horizontal binning to N pixels"
|
msgid "horizontal binning to N pixels"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:56
|
#: cmdlnopts.c:62
|
||||||
msgid "instrument name"
|
msgid "instrument name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:41
|
#: cmdlnopts.c:47
|
||||||
msgid "list connected devices"
|
msgid "list connected devices"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:66
|
#: cmdlnopts.c:102
|
||||||
|
msgid "local INET socket port"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:100
|
||||||
|
msgid "logging file name (if run as server)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:74
|
||||||
msgid "make pause for N seconds between expositions"
|
msgid "make pause for N seconds between expositions"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:65
|
#: cmdlnopts.c:73
|
||||||
msgid "make series of N frames"
|
msgid "make series of N frames"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:84
|
#: cmdlnopts.c:92
|
||||||
msgid "move focuser to absolute position, mm"
|
msgid "move focuser to absolute position, mm"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:85
|
#: cmdlnopts.c:93
|
||||||
msgid "move focuser to relative position, mm"
|
msgid "move focuser to relative position, mm"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:79
|
#: cmdlnopts.c:87
|
||||||
msgid "move stepper motor asynchronous"
|
msgid "move stepper motor asynchronous"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:48
|
#: cmdlnopts.c:54
|
||||||
msgid "not open shutter, when exposing (\"dark frames\")"
|
msgid "not open shutter, when exposing (\"dark frames\")"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:57
|
#: cmdlnopts.c:63
|
||||||
msgid "object name"
|
msgid "object name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:55
|
#: cmdlnopts.c:61
|
||||||
msgid "object type (neon, object, flat etc)"
|
msgid "object type (neon, object, flat etc)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:58
|
#: cmdlnopts.c:64
|
||||||
msgid "observers' names"
|
msgid "observers' names"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:59
|
#: cmdlnopts.c:65
|
||||||
msgid "observing program name"
|
msgid "observing program name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -447,62 +509,70 @@ msgstr ""
|
|||||||
msgid "on"
|
msgid "on"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:74
|
#: cmdlnopts.c:82
|
||||||
msgid "open shutter"
|
msgid "open shutter"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:54
|
#: cmdlnopts.c:67
|
||||||
|
msgid "output file name"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:60
|
||||||
msgid "program author"
|
msgid "program author"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:46
|
#: cmdlnopts.c:52
|
||||||
msgid "rewrite output file if exists"
|
msgid "rewrite output file if exists"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:77
|
#: cmdlnopts.c:85
|
||||||
msgid "run exposition on HIGH @ pin5 I/O port"
|
msgid "run exposition on HIGH @ pin5 I/O port"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:76
|
#: cmdlnopts.c:84
|
||||||
msgid "run exposition on LOW @ pin5 I/O port"
|
msgid "run exposition on LOW @ pin5 I/O port"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:49
|
#: cmdlnopts.c:55
|
||||||
msgid "run in 8-bit mode"
|
msgid "run in 8-bit mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:51
|
#: cmdlnopts.c:57
|
||||||
msgid "set CCD temperature to given value (degr C)"
|
msgid "set CCD temperature to given value (degr C)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:81
|
#: cmdlnopts.c:89
|
||||||
msgid "set I/O port pins to given value (decimal number, pin1 is LSB)"
|
msgid "set I/O port pins to given value (decimal number, pin1 is LSB)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:67
|
#: cmdlnopts.c:75
|
||||||
msgid "set exposure time to given value (seconds!)"
|
msgid "set exposure time to given value (seconds!)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:52
|
#: cmdlnopts.c:58
|
||||||
msgid "set fan speed (0 - off, 1 - low, 2 - high)"
|
msgid "set fan speed (0 - off, 1 - low, 2 - high)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:87
|
#: cmdlnopts.c:95
|
||||||
msgid "set wheel position"
|
msgid "set wheel position"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:45
|
#: cmdlnopts.c:51
|
||||||
msgid "show this help"
|
msgid "show this help"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:47
|
#: cmdlnopts.c:53
|
||||||
msgid "verbose level (each -v increase it)"
|
msgid "verbose level (each -v increase it)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:64
|
#: cmdlnopts.c:72
|
||||||
msgid "vertical binning to N pixels"
|
msgid "vertical binning to N pixels"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cmdlnopts.c:40
|
#: cmdlnopts.c:68
|
||||||
|
msgid "wait while exposition ends"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:46
|
||||||
msgid "wheel device plugin (e.g. devdummy.so)"
|
msgid "wheel device plugin (e.g. devdummy.so)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|||||||
85
main.c
85
main.c
@ -15,12 +15,15 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <omp.h>
|
#include <omp.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/types.h>
|
#include <sys/prctl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <usefull_macros.h>
|
#include <usefull_macros.h>
|
||||||
@ -31,8 +34,22 @@
|
|||||||
#include "imageview.h"
|
#include "imageview.h"
|
||||||
#endif
|
#endif
|
||||||
#include "omp.h"
|
#include "omp.h"
|
||||||
|
#include "socket.h"
|
||||||
|
|
||||||
|
static int isserver = FALSE;
|
||||||
|
static pid_t childpid = 0;
|
||||||
|
|
||||||
void signals(int signo){
|
void signals(int signo){
|
||||||
|
if(childpid){ // master process
|
||||||
|
DBG("Master killed with sig=%d", signo);
|
||||||
|
LOGWARN("Master killed with sig=%d", signo);
|
||||||
|
if(!GP->client){
|
||||||
|
DBG("Unlink pid file");
|
||||||
|
unlink(GP->pidfile);
|
||||||
|
}
|
||||||
|
exit(signo);
|
||||||
|
}
|
||||||
|
// slave: cancel exposition
|
||||||
WARNX("Get signal %d - exit", signo);
|
WARNX("Get signal %d - exit", signo);
|
||||||
DBG("Cancel capturing");
|
DBG("Cancel capturing");
|
||||||
cancel();
|
cancel();
|
||||||
@ -45,6 +62,7 @@ void signals(int signo){
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv){
|
int main(int argc, char **argv){
|
||||||
|
char *self = strdup(argv[0]);
|
||||||
initial_setup();
|
initial_setup();
|
||||||
/*
|
/*
|
||||||
int cpunumber = sysconf(_SC_NPROCESSORS_ONLN);
|
int cpunumber = sysconf(_SC_NPROCESSORS_ONLN);
|
||||||
@ -52,13 +70,70 @@ int main(int argc, char **argv){
|
|||||||
omp_set_num_threads(cpunumber);
|
omp_set_num_threads(cpunumber);
|
||||||
*/
|
*/
|
||||||
parse_args(argc, argv);
|
parse_args(argc, argv);
|
||||||
|
if(GP->outfile && GP->outfileprefix) ERRX("Can't use outfile name and prefix together");
|
||||||
|
if(GP->outfile && !GP->rewrite){
|
||||||
|
struct stat filestat;
|
||||||
|
if(0 == stat(GP->outfile, &filestat)) ERRX("File %s exists!", GP->outfile);
|
||||||
|
}
|
||||||
|
if(GP->port || GP->path){
|
||||||
|
if(GP->path){
|
||||||
|
WARNX("Options `port` and `path` can't be used together! Point `port` for TCP socket or `path` for UNIX.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
int port = atoi(GP->port);
|
||||||
|
if(port < PORTN_MIN || port > PORTN_MAX){
|
||||||
|
WARNX("Wrong port value: %d", port);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(!GP->client) isserver = TRUE;
|
||||||
|
}
|
||||||
|
if(GP->logfile){
|
||||||
|
int lvl = LOGLEVEL_WARN + GP->verbose;
|
||||||
|
DBG("level = %d", lvl);
|
||||||
|
if(lvl > LOGLEVEL_ANY) lvl = LOGLEVEL_ANY;
|
||||||
|
verbose(1, "Log file %s @ level %d\n", GP->logfile, lvl);
|
||||||
|
OPENLOG(GP->logfile, lvl, 1);
|
||||||
|
if(!globlog) WARNX("Can't create log file");
|
||||||
|
}
|
||||||
signal(SIGINT, signals);
|
signal(SIGINT, signals);
|
||||||
signal(SIGQUIT, signals);
|
signal(SIGQUIT, signals);
|
||||||
signal(SIGABRT, signals);
|
signal(SIGABRT, signals);
|
||||||
signal(SIGTERM, signals);
|
signal(SIGTERM, signals);
|
||||||
focusers();
|
signal(SIGHUP, SIG_IGN);
|
||||||
wheels();
|
signal(SIGTSTP, SIG_IGN);
|
||||||
ccds();
|
// check for another running process in server and standalone mode
|
||||||
return 0;
|
if(!GP->client) check4running(self, GP->pidfile);
|
||||||
|
if(!isserver && !GP->client){ // standalone mode
|
||||||
|
focusers();
|
||||||
|
wheels();
|
||||||
|
ccds();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGMSG("Started");
|
||||||
|
#ifndef EBUG
|
||||||
|
if(isserver){
|
||||||
|
unsigned int pause = 5;
|
||||||
|
while(1){
|
||||||
|
childpid = fork();
|
||||||
|
if(childpid){ // master
|
||||||
|
double t0 = dtime();
|
||||||
|
LOGMSG("Created child with pid %d", childpid);
|
||||||
|
wait(NULL);
|
||||||
|
LOGWARN("Child %d died", childpid);
|
||||||
|
if(dtime() - t0 < 1.) pause += 5;
|
||||||
|
else pause = 1;
|
||||||
|
if(pause > 900) pause = 900;
|
||||||
|
sleep(pause); // wait a little before respawn
|
||||||
|
}else{ // slave
|
||||||
|
prctl(PR_SET_PDEATHSIG, SIGTERM); // send SIGTERM to child when parent dies
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(GP->path) return start_socket(isserver, GP->path, FALSE);
|
||||||
|
if(GP->port) return start_socket(isserver, GP->port, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
808
server.c
Normal file
808
server.c
Normal file
@ -0,0 +1,808 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the CCD_Capture project.
|
||||||
|
* Copyright 2022 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 <stdatomic.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <poll.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <usefull_macros.h>
|
||||||
|
|
||||||
|
#include "ccdfunc.h"
|
||||||
|
#include "cmdlnopts.h"
|
||||||
|
#include "server.h"
|
||||||
|
#include "socket.h"
|
||||||
|
|
||||||
|
static atomic_int camdevno = 0, wheeldevno = 0, focdevno = 0; // current devices numbers
|
||||||
|
static _Atomic camera_state camstate = CAMERA_IDLE;
|
||||||
|
#define FLAG_STARTCAPTURE (1<<0)
|
||||||
|
#define FLAG_CANCEL (1<<1)
|
||||||
|
static atomic_int camflags = 0, camfanspd = 0, confio = 0, nflushes;
|
||||||
|
static char *outfile = NULL;
|
||||||
|
static pthread_mutex_t locmutex = PTHREAD_MUTEX_INITIALIZER; // mutex for wheel/camera/focuser functions
|
||||||
|
static frameformat frmformatmax = {0}, curformat = {0}; // maximal format
|
||||||
|
static void *camdev = NULL, *focdev = NULL, *wheeldev = NULL;
|
||||||
|
|
||||||
|
static float focmaxpos = 0., focminpos = 0.; // focuser extremal positions
|
||||||
|
static int wmaxpos = 0.; // wheel max pos
|
||||||
|
static float tremain = 0.; // time when capture done
|
||||||
|
|
||||||
|
static IMG ima = {0};
|
||||||
|
static void fixima(){
|
||||||
|
FREE(ima.data);
|
||||||
|
int raw_width = curformat.w / GP->hbin, raw_height = curformat.h / GP->vbin;
|
||||||
|
ima.h = curformat.h;
|
||||||
|
ima.w = curformat.w;
|
||||||
|
ima.data = MALLOC(uint16_t, raw_width * raw_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
// functions for processCAM finite state machine
|
||||||
|
static inline void cameraidlestate(){ // idle - wait for capture commands
|
||||||
|
if(camflags & FLAG_STARTCAPTURE){ // start capturing
|
||||||
|
camflags &= ~FLAG_STARTCAPTURE;
|
||||||
|
camstate = CAMERA_CAPTURE;
|
||||||
|
camera->cancel();
|
||||||
|
if(!camera->startexposition()){
|
||||||
|
LOGERR("Can't start exposition");
|
||||||
|
WARNX(_("Can't start exposition"));
|
||||||
|
camstate = CAMERA_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static inline void cameracapturestate(){ // capturing - wait for exposition ends
|
||||||
|
if(camflags & FLAG_CANCEL){ // cancel all expositions
|
||||||
|
camflags &= ~FLAG_CANCEL;
|
||||||
|
camera->cancel();
|
||||||
|
camstate = CAMERA_IDLE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
capture_status cs;
|
||||||
|
if(camera->pollcapture(&cs, &tremain)){
|
||||||
|
if(cs != CAPTURE_PROCESS){
|
||||||
|
tremain = 0.;
|
||||||
|
camstate = CAMERA_FRAMERDY;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// base camera thread
|
||||||
|
static void* processCAM(_U_ void *d){
|
||||||
|
if(!camera) ERRX(_("No camera device"));
|
||||||
|
camera_state curstate = camstate;
|
||||||
|
double logt = dtime();
|
||||||
|
while(1){
|
||||||
|
// log
|
||||||
|
if(dtime() - logt > TLOG_PAUSE){
|
||||||
|
logt = dtime();
|
||||||
|
float t;
|
||||||
|
if(camera->getTcold(&t)){
|
||||||
|
LOGMSG("CCDTEMP=%f", t);
|
||||||
|
}
|
||||||
|
if(camera->getThot(&t)){
|
||||||
|
LOGMSG("HOTTEMP=%f", t);
|
||||||
|
}
|
||||||
|
if(camera->getTbody(&t)){
|
||||||
|
LOGMSG("BODYTEMP=%f", t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch(curstate){
|
||||||
|
case CAMERA_IDLE:
|
||||||
|
cameraidlestate();
|
||||||
|
break;
|
||||||
|
case CAMERA_CAPTURE:
|
||||||
|
cameracapturestate();
|
||||||
|
break;
|
||||||
|
case CAMERA_FRAMERDY:
|
||||||
|
// do nothing: when `server` got this state it sends "expstate=2" to all clients and changes state to IDLE
|
||||||
|
break;
|
||||||
|
case CAMERA_ERROR:
|
||||||
|
// do nothing: when `server` got this state it sends "expstate=3" to all clients and changes state to IDLE
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// functions running @ each devno change
|
||||||
|
static int camdevini(int n){
|
||||||
|
if(!camera) return FALSE;
|
||||||
|
pthread_mutex_lock(&locmutex);
|
||||||
|
if(!camera->setDevNo(n)){
|
||||||
|
LOGERR("Can't set active camera number");
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
camdevno = n;
|
||||||
|
LOGMSG("Set camera device number to %d", camdevno);
|
||||||
|
frameformat step;
|
||||||
|
camera->getgeomlimits(&frmformatmax, &step);
|
||||||
|
curformat = frmformatmax;
|
||||||
|
if(GP->hbin < 1) GP->hbin = 1;
|
||||||
|
if(GP->vbin < 1) GP->vbin = 1;
|
||||||
|
fixima();
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
static int focdevini(int n){
|
||||||
|
if(!focuser) return FALSE;
|
||||||
|
pthread_mutex_lock(&locmutex);
|
||||||
|
if(!focuser->setDevNo(n)){
|
||||||
|
LOGERR("Can't set active focuser number");
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
focdevno = n;
|
||||||
|
LOGMSG("Set focuser device number to %d", focdevno);
|
||||||
|
focuser->getMaxPos(&focmaxpos);
|
||||||
|
focuser->getMinPos(&focminpos);
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
static int wheeldevini(int n){
|
||||||
|
if(!wheel) return FALSE;
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
if(!wheel->setDevNo(n)){
|
||||||
|
LOGERR("Can't set active wheel number");
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
wheeldevno = n;
|
||||||
|
LOGMSG("Set wheel device number to %d", wheeldevno);
|
||||||
|
wheel->getMaxPos(&wmaxpos);
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*************************** CCD/CMOS handlers *********************************
|
||||||
|
******************************************************************************/
|
||||||
|
static hresult camlisthandler(int fd, _U_ const char *key, _U_ const char *val){
|
||||||
|
char buf[BUFSIZ], modname[256];
|
||||||
|
pthread_mutex_lock(&locmutex);
|
||||||
|
for(int i = 0; i < camera->Ndevices; ++i){
|
||||||
|
if(!camera->setDevNo(i)) continue;
|
||||||
|
camera->getModelName(modname, 255);
|
||||||
|
snprintf(buf, BUFSIZ-1, CMD_CAMLIST "='%s'", modname);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
}
|
||||||
|
if(camdevno > -1) camera->setDevNo(camdevno);
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
static hresult camsetNhandler(_U_ int fd, _U_ const char *key, _U_ const char *val){
|
||||||
|
char buf[64];
|
||||||
|
if(val){
|
||||||
|
int num = atoi(val);
|
||||||
|
if(num > camera->Ndevices - 1 || num < 0){
|
||||||
|
return RESULT_BADVAL;
|
||||||
|
}
|
||||||
|
if(!camdevini(num)) return RESULT_FAIL;
|
||||||
|
}
|
||||||
|
snprintf(buf, 63, CMD_CAMDEVNO "=%d", camdevno);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
// exposition time setter/getter
|
||||||
|
static hresult exphandler(int fd, _U_ const char *key, const char *val){
|
||||||
|
char buf[64];
|
||||||
|
if(val){
|
||||||
|
double v = atof(val);
|
||||||
|
if(v < DBL_EPSILON) return RESULT_BADVAL;
|
||||||
|
if(camstate != CAMERA_CAPTURE){
|
||||||
|
pthread_mutex_lock(&locmutex);
|
||||||
|
if(camera->setexp(v)){
|
||||||
|
GP->exptime = v;
|
||||||
|
}else LOGWARN("Can't set exptime to %g", v);
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
snprintf(buf, 63, CMD_EXPOSITION "=%g", GP->exptime);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
// filename setter/getter
|
||||||
|
static hresult namehandler(int fd, _U_ const char *key, const char *val){
|
||||||
|
char buf[64];
|
||||||
|
if(val){
|
||||||
|
pthread_mutex_lock(&locmutex);
|
||||||
|
FREE(outfile);
|
||||||
|
outfile = strdup(val);
|
||||||
|
GP->outfile = outfile;
|
||||||
|
GP->outfileprefix = NULL;
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
}
|
||||||
|
if(!GP->outfile) return RESULT_FAIL;
|
||||||
|
snprintf(buf, 63, CMD_FILENAME "=%s", GP->outfile);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
// filename prefix
|
||||||
|
static hresult nameprefixhandler(_U_ int fd, _U_ const char *key, const char *val){
|
||||||
|
char buf[64];
|
||||||
|
if(val){
|
||||||
|
pthread_mutex_lock(&locmutex);
|
||||||
|
FREE(outfile);
|
||||||
|
outfile = strdup(val);
|
||||||
|
GP->outfileprefix = outfile;
|
||||||
|
GP->outfile = NULL;
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
}
|
||||||
|
if(!GP->outfileprefix) return RESULT_FAIL;
|
||||||
|
snprintf(buf, 63, CMD_FILENAMEPREFIX "=%s", GP->outfileprefix);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
// rewrite
|
||||||
|
static hresult rewritefilehandler(_U_ int fd, _U_ const char *key, const char *val){
|
||||||
|
char buf[64];
|
||||||
|
if(val){
|
||||||
|
int n = atoi(val);
|
||||||
|
if(n < 0 || n > 1) return RESULT_BADVAL;
|
||||||
|
pthread_mutex_lock(&locmutex);
|
||||||
|
GP->rewrite = n;
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
}
|
||||||
|
snprintf(buf, 63, CMD_REWRITE "=%d", GP->rewrite);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
static hresult binhandler(_U_ int fd, const char *key, const char *val){
|
||||||
|
char buf[64];
|
||||||
|
if(val){
|
||||||
|
int b = atoi(val);
|
||||||
|
if(b < 1) return RESULT_BADVAL;
|
||||||
|
if(0 == strcmp(key, CMD_HBIN)) GP->hbin = b;
|
||||||
|
else GP->vbin = b;
|
||||||
|
pthread_mutex_lock(&locmutex);
|
||||||
|
if(!camera->setbin(GP->hbin, GP->vbin)){
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
return RESULT_BADVAL;
|
||||||
|
}
|
||||||
|
fixima();
|
||||||
|
}
|
||||||
|
pthread_mutex_lock(&locmutex);
|
||||||
|
int r = camera->getbin(&GP->hbin, &GP->vbin);
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
if(r){
|
||||||
|
if(0 == strcmp(key, CMD_HBIN)) snprintf(buf, 63, "%s=%d", key, GP->hbin);
|
||||||
|
else snprintf(buf, 63, "%s=%d", key, GP->vbin);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
return RESULT_FAIL;
|
||||||
|
}
|
||||||
|
static hresult temphandler(_U_ int fd, _U_ const char *key, const char *val){
|
||||||
|
float f;
|
||||||
|
char buf[64];
|
||||||
|
if(val){
|
||||||
|
f = atof(val);
|
||||||
|
pthread_mutex_lock(&locmutex);
|
||||||
|
if(!camera->setT((float)f)){
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
LOGWARN("Can't set camera T to %.1f", f);
|
||||||
|
return RESULT_FAIL;
|
||||||
|
}
|
||||||
|
LOGMSG("Set camera T to %.1f", f);
|
||||||
|
}
|
||||||
|
pthread_mutex_lock(&locmutex);
|
||||||
|
int r = camera->getTcold(&f);
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
if(r){
|
||||||
|
snprintf(buf, 63, CMD_CAMTEMPER "=%.1f", f);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
pthread_mutex_lock(&locmutex);
|
||||||
|
r = camera->getTbody(&f);
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
if(r){
|
||||||
|
snprintf(buf, 63, "tbody=%.1f", f);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
}
|
||||||
|
pthread_mutex_lock(&locmutex);
|
||||||
|
r = camera->getThot(&f);
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
if(r){
|
||||||
|
snprintf(buf, 63, "thot=%.1f", f);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
}
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}else return RESULT_FAIL;
|
||||||
|
}
|
||||||
|
static hresult camfanhandler(_U_ int fd, _U_ const char *key, _U_ const char *val){
|
||||||
|
char buf[64];
|
||||||
|
if(val){
|
||||||
|
int spd = atoi(val);
|
||||||
|
if(spd < 0) return RESULT_BADVAL;
|
||||||
|
if(spd > FAN_HIGH) spd = FAN_HIGH;
|
||||||
|
pthread_mutex_lock(&locmutex);
|
||||||
|
int r = camera->setfanspeed((fan_speed)spd);
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
if(!r) return RESULT_FAIL;
|
||||||
|
camfanspd = spd;
|
||||||
|
}
|
||||||
|
snprintf(buf, 63, CMD_CAMFANSPD "=%d", camfanspd);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
const char *shutterstr[] = {"open", "close", "expose @high", "expose @low"};
|
||||||
|
static hresult shutterhandler(_U_ int fd, _U_ const char *key, const char *val){
|
||||||
|
if(val){
|
||||||
|
int x = atoi(val);
|
||||||
|
if(x < 0 || x >= SHUTTER_AMOUNT) return RESULT_BADVAL;
|
||||||
|
pthread_mutex_lock(&locmutex);
|
||||||
|
int r = camera->shuttercmd((shutter_op)x);
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
if(r){
|
||||||
|
LOGMSG("Shutter command '%s'", shutterstr[x]);
|
||||||
|
}else{
|
||||||
|
LOGWARN("Can't run shutter command '%s'", shutterstr[x]);
|
||||||
|
return RESULT_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return RESULT_OK;
|
||||||
|
}
|
||||||
|
static hresult confiohandler(_U_ int fd, _U_ const char *key, _U_ const char *val){
|
||||||
|
char buf[64];
|
||||||
|
if(val){
|
||||||
|
int io = atoi(val);
|
||||||
|
pthread_mutex_lock(&locmutex);
|
||||||
|
int r = camera->confio(io);
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
if(!r) return RESULT_FAIL;
|
||||||
|
confio = io;
|
||||||
|
}
|
||||||
|
snprintf(buf, 63, CMD_CONFIO "=%d", confio);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
static hresult iohandler(_U_ int fd, _U_ const char *key, _U_ const char *val){
|
||||||
|
char buf[64];
|
||||||
|
int io;
|
||||||
|
if(val){
|
||||||
|
io = atoi(val);
|
||||||
|
pthread_mutex_lock(&locmutex);
|
||||||
|
int r = camera->setio(io);
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
if(!r) return RESULT_FAIL;
|
||||||
|
}
|
||||||
|
pthread_mutex_lock(&locmutex);
|
||||||
|
int r = camera->getio(&io);
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
if(!r) return RESULT_FAIL;
|
||||||
|
snprintf(buf, 63, CMD_IO "=%d", io);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
static hresult gainhandler(_U_ int fd, _U_ const char *key, _U_ const char *val){
|
||||||
|
char buf[64];
|
||||||
|
float f;
|
||||||
|
if(val){
|
||||||
|
f = atof(val);
|
||||||
|
pthread_mutex_lock(&locmutex);
|
||||||
|
int r = camera->setgain(f);
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
if(!r) return RESULT_FAIL;
|
||||||
|
}
|
||||||
|
pthread_mutex_lock(&locmutex);
|
||||||
|
int r = camera->getgain(&f);
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
if(!r) return RESULT_FAIL;
|
||||||
|
snprintf(buf, 63, CMD_GAIN "=%.1f", f);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
static hresult brightnesshandler(_U_ int fd, _U_ const char *key, _U_ const char *val){
|
||||||
|
char buf[64];
|
||||||
|
float b;
|
||||||
|
if(val){
|
||||||
|
b = atof(val);
|
||||||
|
pthread_mutex_lock(&locmutex);
|
||||||
|
int r = camera->setbrightness(b);
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
if(!r) return RESULT_FAIL;
|
||||||
|
}
|
||||||
|
pthread_mutex_lock(&locmutex);
|
||||||
|
int r = camera->getbrightness(&b);
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
if(!r) return RESULT_FAIL;
|
||||||
|
snprintf(buf, 63, CMD_BRIGHTNESS "=%.1f", b);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
// set format: `format=X0,X1,Y0,Y1`
|
||||||
|
// get geomlimits: `maxformat=X0,X1,Y0,Y1`
|
||||||
|
static hresult formathandler(int fd, const char *key, const char *val){
|
||||||
|
char buf[64];
|
||||||
|
frameformat fmt;
|
||||||
|
if(val){
|
||||||
|
if(strcmp(key, CMD_FRAMEFORMAT)) return RESULT_BADKEY; // can't set maxformat
|
||||||
|
if(4 != sscanf(val, "%d,%d,%d,%d", &fmt.xoff, &fmt.yoff, &fmt.w, &fmt.h)) return RESULT_BADVAL;
|
||||||
|
fmt.w -= fmt.xoff; fmt.h -= fmt.yoff;
|
||||||
|
pthread_mutex_lock(&locmutex);
|
||||||
|
int r = camera->setgeometry(&fmt);
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
if(!r) return RESULT_FAIL;
|
||||||
|
curformat = fmt;
|
||||||
|
fixima();
|
||||||
|
}
|
||||||
|
if(strcmp(key, CMD_FRAMEMAX)) snprintf(buf, 63, CMD_FRAMEMAX "=%d,%d,%d,%d",
|
||||||
|
frmformatmax.xoff, frmformatmax.yoff, frmformatmax.xoff+frmformatmax.w, frmformatmax.yoff+frmformatmax.w);
|
||||||
|
else snprintf(buf, 63, CMD_FRAMEFORMAT "=%d,%d,%d,%d",
|
||||||
|
camera->array.xoff, camera->array.yoff, camera->array.xoff+camera->array.w, camera->array.yoff+camera->array.w);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
static hresult nflusheshandler(_U_ int fd, _U_ const char *key, _U_ const char *val){
|
||||||
|
char buf[64];
|
||||||
|
if(val){
|
||||||
|
int n = atoi(val);
|
||||||
|
if(n < 1) return RESULT_BADVAL;
|
||||||
|
pthread_mutex_lock(&locmutex);
|
||||||
|
if(!camera->setnflushes(n)){
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
return RESULT_FAIL;
|
||||||
|
}
|
||||||
|
nflushes = n;
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
}
|
||||||
|
snprintf(buf, 63, CMD_NFLUSHES "=%d", nflushes);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
static hresult expstatehandler(_U_ int fd, _U_ const char *key, _U_ const char *val){
|
||||||
|
char buf[64];
|
||||||
|
if(val){
|
||||||
|
int n = atoi(val);
|
||||||
|
if(n == CAMERA_IDLE){ // cancel expositions
|
||||||
|
camflags |= FLAG_CANCEL;
|
||||||
|
return RESULT_OK;
|
||||||
|
}
|
||||||
|
else if(n == CAMERA_CAPTURE){ // start exposition
|
||||||
|
camflags |= FLAG_STARTCAPTURE;
|
||||||
|
return RESULT_OK;
|
||||||
|
}
|
||||||
|
else return RESULT_BADVAL;
|
||||||
|
}
|
||||||
|
snprintf(buf, 63, CMD_EXPSTATE "=%d", camstate);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
snprintf(buf, 63, "camflags=%d", camflags);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
static hresult tremainhandler(_U_ int fd, _U_ const char *key, _U_ const char *val){
|
||||||
|
char buf[64];
|
||||||
|
snprintf(buf, 63, CMD_TREMAIN "=%g", tremain);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
static hresult handler(_U_ int fd, _U_ const char *key, _U_ const char *val){
|
||||||
|
char buf[64];
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
/*******************************************************************************
|
||||||
|
***************************** Wheel handlers **********************************
|
||||||
|
******************************************************************************/
|
||||||
|
static hresult wlisthandler(int fd, _U_ const char *key, _U_ const char *val){
|
||||||
|
if(wheel->Ndevices < 1) return RESULT_FAIL;
|
||||||
|
pthread_mutex_lock(&locmutex);
|
||||||
|
for(int i = 0; i < wheel->Ndevices; ++i){
|
||||||
|
if(!wheel->setDevNo(i)) continue;
|
||||||
|
char modname[256], buf[BUFSIZ];
|
||||||
|
wheel->getModelName(modname, 255);
|
||||||
|
snprintf(buf, BUFSIZ-1, CMD_WLIST "='%s'", modname);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
}
|
||||||
|
if(wheeldevno > -1) wheel->setDevNo(wheeldevno);
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
static hresult wsetNhandler(int fd, _U_ const char *key, const char *val){
|
||||||
|
char buf[64];
|
||||||
|
if(val){
|
||||||
|
int num = atoi(val);
|
||||||
|
if(num > wheel->Ndevices - 1 || num < 0){
|
||||||
|
return RESULT_BADVAL;
|
||||||
|
}
|
||||||
|
if(!wheeldevini(num)) return RESULT_FAIL;
|
||||||
|
}
|
||||||
|
snprintf(buf, 63, CMD_WDEVNO "=%d", wheeldevno);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static hresult wgotohandler(_U_ int fd, _U_ const char *key, _U_ const char *val){
|
||||||
|
char buf[64];
|
||||||
|
int pos;
|
||||||
|
if(val){
|
||||||
|
pos = atoi(val);
|
||||||
|
pthread_mutex_lock(&locmutex);
|
||||||
|
int r = wheel->setPos(pos);
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
if(!r) return RESULT_BADVAL;
|
||||||
|
}
|
||||||
|
pthread_mutex_lock(&locmutex);
|
||||||
|
int r = wheel->getPos(&pos);
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
if(!r) return RESULT_FAIL;
|
||||||
|
snprintf(buf, 63, CMD_WPOS "=%d", pos);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**************************** Focuser handlers *********************************
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
static hresult foclisthandler(int fd, _U_ const char *key, _U_ const char *val){
|
||||||
|
if(focuser->Ndevices < 1) return RESULT_FAIL;
|
||||||
|
pthread_mutex_lock(&locmutex);
|
||||||
|
for(int i = 0; i < focuser->Ndevices; ++i){
|
||||||
|
char modname[256], buf[BUFSIZ];
|
||||||
|
if(!focuser->setDevNo(i)) continue;
|
||||||
|
focuser->getModelName(modname, 255);
|
||||||
|
snprintf(buf, BUFSIZ-1, CMD_FOCLIST "='%s'", modname);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
}
|
||||||
|
if(focdevno > -1) focuser->setDevNo(focdevno);
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
static hresult fsetNhandler(int fd, _U_ const char *key, const char *val){
|
||||||
|
char buf[64];
|
||||||
|
if(val){
|
||||||
|
int num = atoi(val);
|
||||||
|
if(num > focuser->Ndevices - 1 || num < 0){
|
||||||
|
return RESULT_BADVAL;
|
||||||
|
}
|
||||||
|
if(!focdevini(num)) return RESULT_FAIL;
|
||||||
|
}
|
||||||
|
snprintf(buf, 63, CMD_FDEVNO "=%d", focdevno);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
static hresult fgotohandler(int fd, _U_ const char *key, const char *val){
|
||||||
|
char buf[64];
|
||||||
|
float f;
|
||||||
|
int r;
|
||||||
|
if(val){
|
||||||
|
f = atof(val);
|
||||||
|
if(f < focminpos || f > focmaxpos) return RESULT_BADVAL;
|
||||||
|
pthread_mutex_lock(&locmutex);
|
||||||
|
if(f - focminpos < __FLT_EPSILON__){
|
||||||
|
r = focuser->home(1);
|
||||||
|
}else{
|
||||||
|
r = focuser->setAbsPos(1, f);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
if(!r) return RESULT_FAIL;
|
||||||
|
}
|
||||||
|
pthread_mutex_lock(&locmutex);
|
||||||
|
r = focuser->getPos(&f);
|
||||||
|
pthread_mutex_unlock(&locmutex);
|
||||||
|
if(!r) return RESULT_FAIL;
|
||||||
|
snprintf(buf, 63, "FOCPOS=%g", f);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
static hresult handler(_U_ int fd, _U_ const char *key, _U_ const char *val){
|
||||||
|
char buf[64];
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// information about everything
|
||||||
|
static hresult infohandler(int fd, _U_ const char *key, _U_ const char *val){
|
||||||
|
char buf[BUFSIZ], buf1[256];
|
||||||
|
float f;
|
||||||
|
int i;
|
||||||
|
if(camera){
|
||||||
|
if(camera->getModelName(buf1, 255)){
|
||||||
|
snprintf(buf, BUFSIZ-1, CMD_CAMLIST "='%s'", buf1);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
}
|
||||||
|
namehandler(fd, CMD_FILENAME, NULL);
|
||||||
|
binhandler(fd, CMD_HBIN, NULL);
|
||||||
|
binhandler(fd, CMD_VBIN, NULL);
|
||||||
|
temphandler(fd, CMD_CAMTEMPER, NULL);
|
||||||
|
exphandler(fd, CMD_EXPOSITION, NULL);
|
||||||
|
}
|
||||||
|
if(wheel){
|
||||||
|
if(wheel->getModelName(buf1, 255)){
|
||||||
|
snprintf(buf, BUFSIZ-1, CMD_WLIST "='%s'", buf1);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
}
|
||||||
|
if(wheel->getTbody(&f)){
|
||||||
|
snprintf(buf, BUFSIZ-1, "WHEELTEMP=%.1f", f);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
}
|
||||||
|
if(wheel->getPos(&i)){
|
||||||
|
snprintf(buf, BUFSIZ-1, "WHEELPOS=%d", i);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
}
|
||||||
|
snprintf(buf, BUFSIZ-1, "WHEELMAXPOS=%d", wmaxpos);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
}
|
||||||
|
if(focuser){
|
||||||
|
if(focuser->getModelName(buf1, 255)){
|
||||||
|
snprintf(buf, BUFSIZ-1, CMD_FOCLIST "='%s'", buf1);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
}
|
||||||
|
if(focuser->getTbody(&f)){
|
||||||
|
snprintf(buf, BUFSIZ-1, "FOCTEMP=%.1f", f);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
}
|
||||||
|
snprintf(buf, BUFSIZ-1, "FOCMINPOS=%g", focminpos);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
snprintf(buf, BUFSIZ-1, "FOCMAXPOS=%g", focmaxpos);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
if(focuser->getPos(&f)){
|
||||||
|
snprintf(buf, BUFSIZ-1, "FOCPOS=%g", f);
|
||||||
|
sendstrmessage(fd, buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return RESULT_SILENCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for setters: do nothing when camera not in idle state
|
||||||
|
static int CAMbusy(){
|
||||||
|
if(camera && camstate != CAMERA_IDLE) return TRUE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int chktrue(_U_ char *val){
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
static int chkcam(char *val){
|
||||||
|
if(val && CAMbusy()) return RESULT_BUSY;
|
||||||
|
if(camera) return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
static int chkwheel(char *val){
|
||||||
|
if(val && CAMbusy()) return RESULT_BUSY;
|
||||||
|
if(wheel) return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
static int chkfoc(char *val){
|
||||||
|
if(val && CAMbusy()) return RESULT_BUSY;
|
||||||
|
if(focuser) return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
static handleritem items[] = {
|
||||||
|
{chktrue, infohandler, CMD_INFO},
|
||||||
|
{chkcam, camlisthandler, CMD_CAMLIST},
|
||||||
|
{chkcam, camsetNhandler, CMD_CAMDEVNO},
|
||||||
|
{chkcam, camfanhandler, CMD_CAMFANSPD},
|
||||||
|
{chkcam, exphandler, CMD_EXPOSITION},
|
||||||
|
{chkcam, namehandler, CMD_FILENAME},
|
||||||
|
{chkcam, binhandler, CMD_HBIN},
|
||||||
|
{chkcam, binhandler, CMD_VBIN},
|
||||||
|
{chkcam, temphandler, CMD_CAMTEMPER},
|
||||||
|
{chkcam, shutterhandler, CMD_SHUTTER},
|
||||||
|
{chkcam, confiohandler, CMD_CONFIO},
|
||||||
|
{chkcam, iohandler, CMD_IO},
|
||||||
|
{chkcam, gainhandler, CMD_GAIN},
|
||||||
|
{chkcam, brightnesshandler, CMD_BRIGHTNESS},
|
||||||
|
{chkcam, formathandler, CMD_FRAMEFORMAT},
|
||||||
|
{chkcam, formathandler, CMD_FRAMEMAX},
|
||||||
|
{chkcam, nflusheshandler, CMD_NFLUSHES},
|
||||||
|
{chkcam, expstatehandler, CMD_EXPSTATE},
|
||||||
|
{chkcam, nameprefixhandler, CMD_FILENAMEPREFIX},
|
||||||
|
{chkcam, rewritefilehandler, CMD_REWRITE},
|
||||||
|
{chktrue, tremainhandler, CMD_TREMAIN},
|
||||||
|
{chkfoc, foclisthandler, CMD_FOCLIST},
|
||||||
|
{chkfoc, fsetNhandler, CMD_FDEVNO},
|
||||||
|
{chkfoc, fgotohandler, CMD_FGOTO},
|
||||||
|
{chkwheel, wlisthandler, CMD_WLIST},
|
||||||
|
{chkwheel, wsetNhandler, CMD_WDEVNO},
|
||||||
|
{chkwheel, wgotohandler, CMD_WPOS},
|
||||||
|
{NULL, NULL, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CLBUFSZ BUFSIZ
|
||||||
|
|
||||||
|
void server(int sock){
|
||||||
|
// init everything
|
||||||
|
startCCD(&camdev);
|
||||||
|
camdevini(0);
|
||||||
|
startFocuser(&focdev);
|
||||||
|
focdevini(0);
|
||||||
|
startWheel(&wheeldev);
|
||||||
|
wheeldevini(0);
|
||||||
|
if(listen(sock, MAXCLIENTS) == -1){
|
||||||
|
WARN("listen");
|
||||||
|
LOGWARN("listen");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// start camera thread
|
||||||
|
pthread_t camthread;
|
||||||
|
if(camera){
|
||||||
|
if(pthread_create(&camthread, NULL, processCAM, NULL)) ERR("pthread_create()");
|
||||||
|
}
|
||||||
|
int nfd = 1; // only one socket @start
|
||||||
|
struct pollfd poll_set[MAXCLIENTS+1];
|
||||||
|
char buffers[MAXCLIENTS][CLBUFSZ]; // buffers for data reading
|
||||||
|
bzero(poll_set, sizeof(poll_set));
|
||||||
|
// ZERO - listening server socket
|
||||||
|
poll_set[0].fd = sock;
|
||||||
|
poll_set[0].events = POLLIN;
|
||||||
|
while(1){
|
||||||
|
poll(poll_set, nfd, 1); // max timeout - 1ms
|
||||||
|
if(poll_set[0].revents & POLLIN){ // check main for accept()
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
socklen_t len = sizeof(addr);
|
||||||
|
int client = accept(sock, (struct sockaddr*)&addr, &len);
|
||||||
|
DBG("New connection");
|
||||||
|
LOGMSG("SERVER got connection, fd=%d", client);
|
||||||
|
if(nfd == MAXCLIENTS + 1){
|
||||||
|
LOGWARN("Max amount of connections, disconnect fd=%d", client);
|
||||||
|
WARNX("Limit of connections reached");
|
||||||
|
close(client);
|
||||||
|
}else{
|
||||||
|
memset(&poll_set[nfd], 0, sizeof(struct pollfd));
|
||||||
|
poll_set[nfd].fd = client;
|
||||||
|
poll_set[nfd].events = POLLIN;
|
||||||
|
++nfd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// process some data & send messages to ALL
|
||||||
|
if(camstate == CAMERA_FRAMERDY || camstate == CAMERA_ERROR){
|
||||||
|
char buff[32];
|
||||||
|
int l = 0;
|
||||||
|
snprintf(buff, 31, CMD_EXPSTATE "=%d", camstate);
|
||||||
|
DBG("Send %s to %d clients", buff, nfd - 1);
|
||||||
|
for(int i = 1; i < nfd; ++i)
|
||||||
|
sendmessage(poll_set[i].fd, buff, l);
|
||||||
|
if(camstate == CAMERA_FRAMERDY){ // save frame
|
||||||
|
if(!ima.data) LOGERR("Can't save image: not initialized");
|
||||||
|
else{
|
||||||
|
if(!camera->capture(&ima)) LOGERR("Can't capture image");
|
||||||
|
else{
|
||||||
|
calculate_stat(&ima);
|
||||||
|
saveFITS(&ima);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
camstate = CAMERA_IDLE;
|
||||||
|
}
|
||||||
|
// scan connections
|
||||||
|
for(int fdidx = 1; fdidx < nfd; ++fdidx){
|
||||||
|
if((poll_set[fdidx].revents & POLLIN) == 0) continue;
|
||||||
|
int fd = poll_set[fdidx].fd;
|
||||||
|
if(!processData(fd, items, buffers[fdidx-1], CLBUFSZ)){ // socket closed
|
||||||
|
DBG("Client fd=%d disconnected", fd);
|
||||||
|
LOGMSG("SERVER client fd=%d disconnected", fd);
|
||||||
|
buffers[fdidx-1][0] = 0; // clear rest of data in buffer
|
||||||
|
close(fd);
|
||||||
|
// move last FD to current position
|
||||||
|
poll_set[fdidx] = poll_set[nfd - 1];
|
||||||
|
--nfd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
focclose(focdev);
|
||||||
|
closewheel(wheeldev);
|
||||||
|
closecam(camdev);
|
||||||
|
}
|
||||||
|
|
||||||
73
server.h
Normal file
73
server.h
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the CCD_Capture project.
|
||||||
|
* Copyright 2022 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 SERVER_H__
|
||||||
|
#define SERVER_H__
|
||||||
|
|
||||||
|
typedef enum{
|
||||||
|
CAMERA_IDLE, // idle state, client send this to cancel capture
|
||||||
|
CAMERA_CAPTURE, // capturing frame, client send this to start capture
|
||||||
|
CAMERA_FRAMERDY, // frame ready to be saved
|
||||||
|
CAMERA_ERROR // can't do exposition
|
||||||
|
} camera_state;
|
||||||
|
|
||||||
|
// pause (seconds) between temperature logging
|
||||||
|
#define TLOG_PAUSE 60.
|
||||||
|
|
||||||
|
// server-side functions
|
||||||
|
void server(int fd);
|
||||||
|
|
||||||
|
// common information about everything
|
||||||
|
#define CMD_INFO "info"
|
||||||
|
|
||||||
|
// CCD/CMOS
|
||||||
|
#define CMD_CAMLIST "camlist"
|
||||||
|
#define CMD_CAMDEVNO "camdevno"
|
||||||
|
#define CMD_EXPOSITION "exptime"
|
||||||
|
#define CMD_FILENAME "filename"
|
||||||
|
#define CMD_FILENAMEPREFIX "filenameprefix"
|
||||||
|
// rewrite=1 will rewrite files, =0 - not (only for `filename`)
|
||||||
|
#define CMD_REWRITE "rewrite"
|
||||||
|
#define CMD_HBIN "hbin"
|
||||||
|
#define CMD_VBIN "vbin"
|
||||||
|
#define CMD_CAMTEMPER "tcold"
|
||||||
|
#define CMD_CAMFANSPD "ccdfanspeed"
|
||||||
|
#define CMD_SHUTTER "shutter"
|
||||||
|
#define CMD_CONFIO "confio"
|
||||||
|
#define CMD_IO "io"
|
||||||
|
#define CMD_GAIN "gain"
|
||||||
|
#define CMD_BRIGHTNESS "brightness"
|
||||||
|
#define CMD_FRAMEFORMAT "format"
|
||||||
|
#define CMD_FRAMEMAX "maxformat"
|
||||||
|
#define CMD_NFLUSHES "nflushes"
|
||||||
|
// expstate=CAMERA_CAPTURE will start exposition, CAMERA_IDLE - cancel
|
||||||
|
#define CMD_EXPSTATE "expstate"
|
||||||
|
#define CMD_TREMAIN "tremain"
|
||||||
|
|
||||||
|
// focuser
|
||||||
|
#define CMD_FOCLIST "foclist"
|
||||||
|
#define CMD_FDEVNO "focdevno"
|
||||||
|
#define CMD_FGOTO "focgoto"
|
||||||
|
|
||||||
|
// wheel
|
||||||
|
#define CMD_WLIST "wlist"
|
||||||
|
#define CMD_WDEVNO "wdevno"
|
||||||
|
#define CMD_WPOS "wpos"
|
||||||
|
|
||||||
|
#endif // SERVER_H__
|
||||||
229
socket.c
Normal file
229
socket.c
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the CCD_Capture project.
|
||||||
|
* Copyright 2022 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 <ctype.h> // isspace
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/un.h> // unix socket
|
||||||
|
#include <usefull_macros.h>
|
||||||
|
|
||||||
|
#include "cmdlnopts.h"
|
||||||
|
#include "client.h"
|
||||||
|
#include "server.h"
|
||||||
|
#include "socket.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief start_socket - create socket and run client or server
|
||||||
|
* @param isserver - TRUE for server, FALSE for client
|
||||||
|
* @param path - UNIX-socket path or local INET socket port
|
||||||
|
* @param isnet - TRUE for INET socket, FALSE for UNIX
|
||||||
|
* @return 0 if OK
|
||||||
|
*/
|
||||||
|
int start_socket(int isserver, char *path, int isnet){
|
||||||
|
if(!path) return 1;
|
||||||
|
DBG("path/port: %s", path);
|
||||||
|
int sock = -1;
|
||||||
|
struct addrinfo hints = {0}, *res;
|
||||||
|
struct sockaddr_un unaddr = {0};
|
||||||
|
if(isnet){
|
||||||
|
DBG("Network socket");
|
||||||
|
hints.ai_family = AF_INET;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
hints.ai_flags = AI_PASSIVE;
|
||||||
|
if(getaddrinfo("127.0.0.1", path, &hints, &res) != 0){
|
||||||
|
ERR("getaddrinfo");
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
DBG("UNIX socket");
|
||||||
|
char apath[128];
|
||||||
|
if(*path == 0){
|
||||||
|
DBG("convert name");
|
||||||
|
apath[0] = 0;
|
||||||
|
strncpy(apath+1, path+1, 126);
|
||||||
|
}else if(strncmp("\\0", path, 2) == 0){
|
||||||
|
DBG("convert name");
|
||||||
|
apath[0] = 0;
|
||||||
|
strncpy(apath+1, path+2, 126);
|
||||||
|
}else strcpy(apath, path);
|
||||||
|
unaddr.sun_family = AF_UNIX;
|
||||||
|
hints.ai_addr = (struct sockaddr*) &unaddr;
|
||||||
|
hints.ai_addrlen = sizeof(unaddr);
|
||||||
|
memcpy(unaddr.sun_path, apath, 106); // if sun_path[0] == 0 we don't create a file
|
||||||
|
hints.ai_family = AF_UNIX;
|
||||||
|
hints.ai_socktype = SOCK_SEQPACKET;
|
||||||
|
res = &hints;
|
||||||
|
}
|
||||||
|
for(struct addrinfo *p = res; p; p = p->ai_next){
|
||||||
|
if((sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0){ // or SOCK_STREAM?
|
||||||
|
LOGWARN("socket()");
|
||||||
|
WARN("socket()");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(isserver){
|
||||||
|
int reuseaddr = 1;
|
||||||
|
if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(int)) == -1){
|
||||||
|
LOGWARN("setsockopt()");
|
||||||
|
WARN("setsockopt()");
|
||||||
|
close(sock); sock = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(bind(sock, p->ai_addr, p->ai_addrlen) == -1){
|
||||||
|
LOGWARN("bind()");
|
||||||
|
WARN("bind()");
|
||||||
|
close(sock); sock = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int enable = 1;
|
||||||
|
if(ioctl(sock, FIONBIO, (void *)&enable) < 0){ // make socket nonblocking
|
||||||
|
LOGERR("Can't make socket nonblocking");
|
||||||
|
ERRX("ioctl()");
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if(connect(sock, p->ai_addr, p->ai_addrlen) == -1){
|
||||||
|
LOGWARN("connect()");
|
||||||
|
WARN("connect()");
|
||||||
|
close(sock); sock = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(sock < 0){
|
||||||
|
LOGERR("Can't open socket");
|
||||||
|
ERRX("Can't open socket");
|
||||||
|
}
|
||||||
|
if(isnet) freeaddrinfo(res);
|
||||||
|
if(isserver) server(sock);
|
||||||
|
else client(sock);
|
||||||
|
close(sock);
|
||||||
|
signals(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// simple wrapper over write: add missed newline and log data
|
||||||
|
void sendmessage(int fd, const char *msg, int l){
|
||||||
|
if(fd < 1 || !msg || l < 1) return;
|
||||||
|
DBG("send to fd %d: %s [%d]", fd, msg, l);
|
||||||
|
char *tmpbuf = MALLOC(char, l+1);
|
||||||
|
memcpy(tmpbuf, msg, l);
|
||||||
|
if(msg[l-1] != '\n') tmpbuf[l++] = '\n';
|
||||||
|
if(l != write(fd, tmpbuf, l)){
|
||||||
|
LOGWARN("write()");
|
||||||
|
WARN("write()");
|
||||||
|
}else{
|
||||||
|
if(globlog){ // logging turned ON
|
||||||
|
tmpbuf[l-1] = 0; // remove trailing '\n' for logging
|
||||||
|
LOGMSG("SEND '%s'", tmpbuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FREE(tmpbuf);
|
||||||
|
}
|
||||||
|
void sendstrmessage(int fd, const char *msg){
|
||||||
|
if(fd < 1 || !msg) return;
|
||||||
|
int l = strlen(msg);
|
||||||
|
sendmessage(fd, msg, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
// text messages for `hresult`
|
||||||
|
static const char *resmessages[] = {
|
||||||
|
[RESULT_OK] = "OK",
|
||||||
|
[RESULT_BUSY] = "BUSY",
|
||||||
|
[RESULT_FAIL] = "FAIL",
|
||||||
|
[RESULT_BADKEY] = "BADKEY",
|
||||||
|
[RESULT_BADVAL] = "BADVAL",
|
||||||
|
[RESULT_SILENCE] = "",
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *hresult2str(hresult r){
|
||||||
|
if(r >= RESULT_NUM) return "BADRESULT";
|
||||||
|
return resmessages[r];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief get_keyval - get value of `key = val`
|
||||||
|
* @param keyval (io) - pair `key = val`, return `key`
|
||||||
|
* @return `val`
|
||||||
|
*/
|
||||||
|
char *get_keyval(char *keyval){
|
||||||
|
DBG("Got string %s", keyval);
|
||||||
|
// remove starting spaces in key
|
||||||
|
while(isspace(*keyval)) ++keyval;
|
||||||
|
char *val = strchr(keyval, '=');
|
||||||
|
if(val){ // got value: remove starting spaces in val
|
||||||
|
*val++ = 0;
|
||||||
|
while(isspace(*val)) ++val;
|
||||||
|
}
|
||||||
|
// remove trailing spaces in key
|
||||||
|
char *e = keyval + strlen(keyval) - 1; // last key symbol
|
||||||
|
while(isspace(*e) && e > keyval) --e;
|
||||||
|
e[1] = 0;
|
||||||
|
// now we have key (`str`) and val (or NULL)
|
||||||
|
DBG("key=%s, val=%s", keyval, val);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse string of data (command or key=val)
|
||||||
|
// the CONTENT of buffer `str` WILL BE BROKEN!
|
||||||
|
static void parsestring(int fd, handleritem *handlers, char *str){
|
||||||
|
if(fd < 1 || !handlers || !handlers->key || !str || !*str) return;
|
||||||
|
char *val = get_keyval(str);
|
||||||
|
if(val) LOGMSG("RECEIVE '%s=%s'", str, val);
|
||||||
|
else LOGMSG("RECEIVE '%s'", str);
|
||||||
|
for(handleritem *h = handlers; h->key; ++h){
|
||||||
|
if(strcmp(str, h->key) == 0){ // found command
|
||||||
|
if(h->chkfunction && !h->chkfunction(val)) sendstrmessage(fd, resmessages[RESULT_FAIL]);
|
||||||
|
else{
|
||||||
|
if(h->handler){
|
||||||
|
hresult r = h->handler(fd, str, val);
|
||||||
|
sendstrmessage(fd, hresult2str(r));
|
||||||
|
}else sendstrmessage(fd, resmessages[RESULT_FAIL]);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sendstrmessage(fd, resmessages[RESULT_BADKEY]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief processData - read (if available) data from fd and run processing, sending to fd messages for each command
|
||||||
|
* @param fd - socket file descriptor
|
||||||
|
* @param handlers - NULL-terminated array of handlers
|
||||||
|
* @param buf (io) - zero-terminated buffer for storing rest of data (without newline), its content will be changed
|
||||||
|
* @param buflen - its length
|
||||||
|
* @return FALSE if client closed (nothing to read)
|
||||||
|
*/
|
||||||
|
int processData(int fd, handleritem *handlers, char *buf, int buflen){
|
||||||
|
int curlen = strlen(buf);
|
||||||
|
if(curlen == buflen-1) curlen = 0; // buffer overflow - clear old content
|
||||||
|
ssize_t rd = read(fd, buf + curlen, buflen-1 - curlen);
|
||||||
|
if(rd <= 0) return FALSE;
|
||||||
|
DBG("got %s[%zd] from %d", buf, rd, fd);
|
||||||
|
char *restofdata = buf, *eptr = buf + curlen + rd;
|
||||||
|
*eptr = 0;
|
||||||
|
do{
|
||||||
|
char *nl = strchr(restofdata, '\n');
|
||||||
|
if(!nl) break;
|
||||||
|
*nl++ = 0;
|
||||||
|
parsestring(fd, handlers, restofdata);
|
||||||
|
restofdata = nl;
|
||||||
|
DBG("rest of data: %s", restofdata);
|
||||||
|
}while(1);
|
||||||
|
if(restofdata != buf) memmove(buf, restofdata, eptr - restofdata + 1);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
59
socket.h
Normal file
59
socket.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the CCD_Capture project.
|
||||||
|
* Copyright 2022 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 SERSOCK_H__
|
||||||
|
#define SERSOCK_H__
|
||||||
|
|
||||||
|
// max & min TCP socket port number
|
||||||
|
#define PORTN_MAX (65535)
|
||||||
|
#define PORTN_MIN (1024)
|
||||||
|
|
||||||
|
#define BUFLEN (1024)
|
||||||
|
// Max amount of connections
|
||||||
|
#define MAXCLIENTS (30)
|
||||||
|
|
||||||
|
typedef enum{
|
||||||
|
RESULT_OK, // all OK
|
||||||
|
RESULT_BUSY, // camera busy and no setters can be done
|
||||||
|
RESULT_FAIL, // failed running command
|
||||||
|
RESULT_BADVAL, // bad key's value
|
||||||
|
RESULT_BADKEY, // bad key
|
||||||
|
RESULT_SILENCE, // send nothing to client
|
||||||
|
RESULT_NUM
|
||||||
|
} hresult;
|
||||||
|
|
||||||
|
const char *hresult2str(hresult r);
|
||||||
|
|
||||||
|
// fd - socket fd to send private messages, key, val - key and its value
|
||||||
|
typedef hresult (*mesghandler)(int fd, const char *key, const char *val);
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
int (*chkfunction)(char *val); // function to check device is ready
|
||||||
|
mesghandler handler; // handler function
|
||||||
|
const char *key; // keyword
|
||||||
|
} handleritem;
|
||||||
|
|
||||||
|
int start_socket(int server, char *path, int isnet);
|
||||||
|
void sendmessage(int fd, const char *msg, int l);
|
||||||
|
void sendstrmessage(int fd, const char *msg);
|
||||||
|
char *get_keyval(char *keyval);
|
||||||
|
|
||||||
|
int processData(int fd, handleritem *handlers, char *buf, int buflen);
|
||||||
|
|
||||||
|
#endif // SERSOCK_H__
|
||||||
Loading…
x
Reference in New Issue
Block a user