add some FITS header functions, change FITSsave, add plugin commands

This commit is contained in:
Edward Emelianov 2024-02-01 16:19:41 +03:00
parent a5926861bc
commit 869421d52f
15 changed files with 1058 additions and 584 deletions

View File

@ -25,7 +25,7 @@ option(APOGEE "Add support of Apogee cameras" OFF)
option(EXAMPLES "Some examples" OFF)
# default flags
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -W -Wextra")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -W -Wextra -fno-builtin-strlen")
# change wrong behaviour with install prefix
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT AND CMAKE_INSTALL_PREFIX MATCHES "/usr/local")
@ -51,7 +51,7 @@ set(CMAKE_COLOR_MAKEFILE ON)
# cmake -DDEBUG=yes -> debugging
if(DEBUG)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Og -g3 -ggdb -fno-builtin-strlen -Werror")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Og -g3 -ggdb -Werror")
add_definitions(-DEBUG)
set(CMAKE_BUILD_TYPE DEBUG)
set(CMAKE_VERBOSE_MAKEFILE "ON")
@ -122,7 +122,7 @@ set(RU_FILE ${LCPATH}/ru.po)
add_library(${PROJLIB} SHARED ${LIBSRC})
add_executable(${PROJ} ${SOURCES} ${PO_FILE} ${MO_FILE})
target_link_libraries(${PROJ} ${CFITSIO_LIBRARIES} ${X11_LIBRARIES} ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} ${${PROJ}_LIBRARIES} -lm ${CMAKE_DL_LIBS} ${PROJLIB})
target_link_libraries(${PROJLIB} ${${PROJLIB}_LIBRARIES})
target_link_libraries(${PROJLIB} ${CFITSIO_LIBRARIES} ${${PROJLIB}_LIBRARIES})
include_directories(${${PROJ}_INCLUDE_DIRS} .)
link_directories(${${PROJ}_LIBRARY_DIRS} )
set(PCFILE "${CMAKE_BINARY_DIR}/${PROJLIB}.pc")

View File

@ -1,10 +1,12 @@
cmake_minimum_required(VERSION 3.20)
set(CCDLIB devdummy)
SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
find_package(PkgConfig REQUIRED)
pkg_check_modules(${CCDLIB} REQUIRED usefull_macros)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} SRC)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} SRC)
include_directories(${${CCDLIB}_INCLUDE_DIRS} ..)
link_directories(${${CCDLIB}_LIBRARY_DIRS})

View File

@ -41,6 +41,8 @@ static float camtemp = -30., exptime = 0.;
static cc_capture_status capstat = CAPTURE_NO;
static double texpstart = 0.;
static uint8_t bitpix = 16; // bit depth: 8 or 16
// sinusoide periods
static double sinPx = 100., sinPy = 200.;
static int campoll(cc_capture_status *st, float *remain){
if(capstat != CAPTURE_PROCESS){
@ -79,7 +81,7 @@ static int camcapt(cc_IMG *ima){
uint16_t *d = &((uint16_t*)ima->data)[y*ima->w/curvbin];
for(int x = 0; x < x1; x += curhbin){ // sinusoide 100x200
//*d++ = (uint16_t)(((n+x)%100)/99.*65535.);
*d++ = (uint16_t)((1. + sin((n+x) * M_PI/50.)*sin((n+y) * M_PI/100.))*32767.);
*d++ = (uint16_t)((1. + sin((n+x) * (2.*M_PI)/sinPx)*sin((n+y) * (2.*M_PI)/sinPy))*32767.);
}
}
}else{
@ -88,7 +90,7 @@ static int camcapt(cc_IMG *ima){
uint8_t *d = &((uint8_t*)ima->data)[y*ima->w/curvbin];
for(int x = 0; x < x1; x += curhbin){ // sinusoide 100x200
//*d++ = (uint16_t)(((n+x)%100)/99.*65535.);
*d++ = (uint8_t)((1. + sin((n+x) * M_PI/50.)*sin((n+y) * M_PI/100.))*127.);
*d++ = (uint8_t)((1. + sin((n+x) * (2.*M_PI)/sinPx)*sin((n+y) * (2.*M_PI)/sinPy))*127.);
}
}
}
@ -254,6 +256,37 @@ static int whlgetnam(char *n, int l){
return TRUE;
}
static const char* const helpmsg =
"Dummy camera custom plugin commands:\n"
"\tpx - set/get sin period over X axis (pix)\n"
"\tpy - -//- over Y axis\n"
;
static const char* const pmust = "Period must be not less than 1";
static const char *plugincmd(const char *str){
static char ans[BUFSIZ+1];
snprintf(ans, BUFSIZ, "%s", str);
char *val = cc_get_keyval(ans);
if(val){ // setters
if(0 == strcmp("px", ans)){
double f = atof(val);
if(f < 1.) return pmust;
sinPx = f;
}else if(0 == strcmp("py", ans)){
double f = atof(val);
if(f < 1.) return pmust;
sinPy = f;
}
} // getters/return
if(0 == strcmp("px", ans)){
snprintf(ans, BUFSIZ, "px=%g", sinPx);
return (const char*) ans;
}else if(0 == strcmp("py", ans)){
snprintf(ans, BUFSIZ, "yx=%g", sinPy);
return (const char*) ans;
}
return helpmsg;
}
static int stub(){
return TRUE;
}
@ -275,6 +308,7 @@ __attribute__ ((visibility("default"))) cc_Camera camera = {
.capture = camcapt,
.cancel = camcancel,
.startexposition = startexp,
.plugincmd = plugincmd,
// setters:
.setDevNo = setdevno,
.setbrightness = camsetbrig,

View File

@ -19,6 +19,7 @@
#include <ctype.h> // isspace
#include <dlfcn.h> // dlopen/close
#include <fcntl.h>
#include <float.h> // for float max
#include <netdb.h>
#include <stdio.h>
#include <string.h>
@ -40,6 +41,7 @@ double __t0 = 0.;
#endif
static int ntries = 2; // amount of tries to send messages controlling the answer
double answer_timeout = 0.1; // timeout of waiting answer from server (not static for client.c)
/**
* @brief cc_open_socket - create socket and open it
@ -146,7 +148,6 @@ int cc_senddata(int fd, void *data, size_t l){
// simple wrapper over write: add missed newline and log data
int cc_sendmessage(int fd, const char *msg, int l){
FNAME();
if(fd < 1 || !msg || l < 1) return TRUE; // empty message
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // thread safe
pthread_mutex_lock(&mutex);
@ -156,7 +157,7 @@ int cc_sendmessage(int fd, const char *msg, int l){
buflen = 1024 * (1 + l/1024);
tmpbuf = realloc(tmpbuf, buflen);
}
DBG("send to fd %d: %s [%d]", fd, msg, l);
DBG("send to fd %d:\n%s[%d]", fd, msg, l);
memcpy(tmpbuf, msg, l);
if(msg[l-1] != '\n') tmpbuf[l++] = '\n';
if(l != send(fd, tmpbuf, l, MSG_NOSIGNAL)){
@ -175,7 +176,6 @@ int cc_sendmessage(int fd, const char *msg, int l){
return TRUE;
}
int cc_sendstrmessage(int fd, const char *msg){
FNAME();
if(fd < 1 || !msg) return TRUE; // empty message
int l = strlen(msg);
return cc_sendmessage(fd, msg, l);
@ -194,10 +194,6 @@ static const char *resmessages[RESULT_NUM] = {
};
const char *cc_hresult2str(cc_hresult r){
/*red("ALL results:\n");
for(cc_hresult res = 0; res < RESULT_NUM; ++res){
printf("%d: %s\n", res, resmessages[res]);
}*/
if(r < 0 || r >= RESULT_NUM) return "BADRESULT";
return resmessages[r];
}
@ -216,7 +212,7 @@ cc_hresult cc_str2hresult(const char *str){
* @return `val`
*/
char *cc_get_keyval(char *keyval){
//DBG("Got string %s", keyval);
DBG("Got string %s", keyval);
// remove starting spaces in key
while(isspace(*keyval)) ++keyval;
char *val = strchr(keyval, '=');
@ -224,7 +220,7 @@ char *cc_get_keyval(char *keyval){
*val++ = 0;
while(isspace(*val)) ++val;
}
//DBG("val = %s (%zd bytes)", val, (val)?strlen(val):0);
DBG("val = %s (%zd bytes)", val, (val)?strlen(val):0);
// remove trailing spaces in key
char *e = keyval + strlen(keyval) - 1; // last key symbol
while(isspace(*e) && e > keyval) --e;
@ -264,43 +260,6 @@ int cc_canberead(int fd){
return 0;
}
/**
* @brief cc_setNtries, cc_getNtries - ntries setter and getter
* @param n - new amount of tries
* @return cc_setNtries returns TRUE if succeed, cc_getNtries returns current ntries value
*/
int cc_setNtries(int n){
if(n > 1000 || n < 1) return FALSE;
ntries = n;
return TRUE;
}
int cc_getNtries(){return ntries;}
static cc_hresult sendstrN(int fd, const char *str){
for(int i = 0; i < ntries; ++i){
if(!cc_sendstrmessage(fd, str)) continue;
double t0 = dtime();
while(dtime() - t0 < CC_ANSWER_TIMEOUT){
// TODO: continue the code
}
}
return FALSE;
}
/**
* @brief cc_sendint - send integer value over socket (make 2 tries)
* @param fd - socket fd
* @param cmd - setter
* @param val - value
* @return answer received
*/
cc_hresult cc_sendint(int fd, const char *cmd, int val){
#define BBUFS (63)
char buf[BBUFS+1];
snprintf(buf, BBUFS, "%s=%d\n", cmd, val);
return sendstrN(fd, buf);
}
/**
* @brief cc_getshm - get shared memory segment for image
* @param imsize - size of image data (in bytes): if !=0 allocate as server, else - as client (readonly)
@ -411,26 +370,84 @@ int cc_getNbytes(cc_IMG *image){
return n;
}
cc_charbuff *cc_bufnew(size_t size){
DBG("Allocate new buffer with size %zd", size);
cc_charbuff *b = MALLOC(cc_charbuff, 1);
b->bufsize = size;
b->buf = MALLOC(char, size);
/**
* @brief cc_strbufnew - allocate new buffer
* @param bufsize - size of full socket buffer
* @param stringsize - max length of string from buffer (excluding \0)
* @return allocated buffer
*/
cc_strbuff *cc_strbufnew(size_t bufsize, size_t stringsize){
if(bufsize < 8 || stringsize < 8){
WARNX("Need to allocate at least 8 bytes in buffers");
return NULL;
}
DBG("Allocate new string buffer with size %zd and string size %zd", bufsize, stringsize);
cc_strbuff *b = MALLOC(cc_strbuff, 1);
b->bufsize = bufsize;
b->buf = MALLOC(char, bufsize);
b->string = MALLOC(char, stringsize + 1); // for terminated zero
b->strlen = stringsize;
return b;
}
void cc_strbufdel(cc_strbuff **buf){
FREE((*buf)->buf);
FREE((*buf)->string);
FREE(*buf);
}
void cc_bufdel(cc_charbuff **buf){
cc_charbuff *cc_charbufnew(){
DBG("Allocate new char buffer with size %d", BUFSIZ);
cc_charbuff *b = MALLOC(cc_charbuff, 1);
b->bufsize = BUFSIZ;
b->buf = MALLOC(char, BUFSIZ);
return b;
}
// set buflen to 0
void cc_charbufclr(cc_charbuff *buf){
if(!buf) return;
buf->buflen = 0;
}
// put `l` bytes of `s` to b->buf and add terminated zero
void cc_charbufput(cc_charbuff *b, const char *s, size_t l){
if(!cc_charbuftest(b, l+1)) return;
DBG("add %zd bytes to buff", l);
memcpy(b->buf + b->buflen, s, l);
b->buflen += l;
b->buf[b->buflen] = 0;
}
void cc_charbufaddline(cc_charbuff *b, const char *s){
if(!b || !s) return;
size_t l = strlen(s);
if(l < 1 || !cc_charbuftest(b, l+2)) return;
cc_charbufput(b, s, l);
if(s[l-1] != '\n'){ // add trailing '\n'
b->buf[b->buflen++] = '\n';
b->buf[b->buflen] = 0;
}
}
// realloc buffer if its free size less than maxsize
int cc_charbuftest(cc_charbuff *b, size_t maxsize){
if(!b) return FALSE;
if(b->bufsize - b->buflen > maxsize + 1) return TRUE;
size_t newblks = (maxsize + BUFSIZ) / BUFSIZ;
b->bufsize += BUFSIZ * newblks;
DBG("Realloc charbuf to %zd", b->bufsize);
b->buf = realloc(b->buf, b->bufsize);
return TRUE;
}
void cc_charbufdel(cc_charbuff **buf){
FREE((*buf)->buf);
FREE(*buf);
}
/**
* @brief cc_read2buf - try to read next data portion from POLLED socket
* @param fd - socket fd to read from
* @param buf - buffer to read
* @return FALSE in case of buffer overflow or client disconnect, TRUE if got 0..n bytes of data
*/
int cc_read2buf(int fd, cc_charbuff *buf){
int cc_read2buf(int fd, cc_strbuff *buf){
int ret = FALSE;
if(!buf) return FALSE;
pthread_mutex_lock(&buf->mutex);
@ -446,30 +463,272 @@ ret:
return ret;
}
/**
* @brief cc_refreshbuf - same as cc_read2buf, but with polling
* @param fd - socket fd
* @param buf - buffer
* @return TRUE if got data
*/
int cc_refreshbuf(int fd, cc_strbuff *buf){
if(!cc_canberead(fd)) return FALSE;
return cc_read2buf(fd, buf);
}
/**
* @brief cc_getline - read '\n'-terminated string from `b` and substitute '\n' by 0
* @param b - input charbuf
* @param str (allocated outside) - string-receiver
* @param len - length of `str` (including terminating zero)
* @return amount of bytes read
* @return amount of bytes read (idx > b->strlen in case of string buffer overflow)
*/
size_t cc_getline(cc_charbuff *b, char *str, size_t len){
size_t cc_getline(cc_strbuff *b){
if(!b) return 0;
size_t idx = 0;
pthread_mutex_lock(&b->mutex);
if(!b->buf) goto ret;
--len; // for terminating zero
if(!b->buf || !b->string) goto ret;
char *ptr = b->buf;
for(; idx < b->buflen; ++idx) if(*ptr++ == '\n') break;
if(idx == b->buflen) goto ret;
size_t minlen = (len > idx) ? idx : len; // prevent `str` overflow
memcpy(str, b->buf, minlen);
str[minlen] = 0;
if(idx == b->buflen){
idx = 0; // didn't fount '\n'
goto ret;
}
size_t minlen = (b->strlen > idx) ? idx : b->strlen; // prevent `str` overflow
memcpy(b->string, b->buf, minlen);
b->string[minlen] = 0;
if(++idx < b->buflen){ // move rest of data in buffer to beginning
memmove(b->buf, b->buf+idx, b->buflen-idx);
b->buflen -= idx;
}else b->buflen = 0;
DBG("got string `%s`", b->string);
ret:
pthread_mutex_unlock(&b->mutex);
return idx;
}
/**
* @brief cc_setNtries, cc_getNtries - ntries setter and getter
* @param n - new amount of tries
* @return cc_setNtries returns TRUE if succeed, cc_getNtries returns current ntries value
*/
int cc_setNtries(int n){
if(n > 1000 || n < 1) return FALSE;
ntries = n;
return TRUE;
}
int cc_getNtries(){return ntries;}
/**
* @brief cc_setAnsTmout, cc_getAnsTmout - answer timeout setter/getter
* @param t - timeout, s (not less than 0.001s)
* @return true/timeout
*/
int cc_setAnsTmout(double t){
if(t < 0.001) return FALSE;
answer_timeout = t;
return TRUE;
}
double cc_getAnsTmout(){return answer_timeout;}
/**
* @brief ask4cmd - send string `cmdwargs` like "par=val"
* @param fd - fd of socket
* @param buf - buffer to store data read from socket
* @param cmdwargs (i) - "par=val"
* @return RESULT_OK if got same string or other error
*/
static cc_hresult ask4cmd(int fd, cc_strbuff *buf, const char *cmdwargs){
DBG("ask for command %s", cmdwargs);
char *key = strdup(cmdwargs);
cc_get_keyval(key); // pick out key from `cmdwargs`
int l = strlen(key);
cc_hresult ret = RESULT_FAIL;
for(int i = 0; i < ntries; ++i){
DBG("Try %d time", i+1);
if(!cc_sendstrmessage(fd, cmdwargs)) continue;
double t0 = dtime();
while(dtime() - t0 < answer_timeout){
int r = cc_canberead(fd);
if(r == 0) continue;
else if(r < 0){
LOGERR("Socket disconnected");
WARNX("Socket disconnected");
ret = RESULT_DISCONNECTED;
goto rtn;
}
while(cc_refreshbuf(fd, buf));
DBG("read");
size_t got = 0;
while((got = cc_getline(buf))){
if(got >= BUFSIZ){
DBG("Client fd=%d gave buffer overflow", fd);
LOGMSG("SERVER client fd=%d buffer overflow", fd);
}else if(got){
if(strncmp(buf->string, key, l) == 0){
ret = RESULT_OK;
goto rtn;
}else{ // answers like 'OK' etc
cc_hresult r = cc_str2hresult(buf->string);
if(r != RESULT_NUM){ // some other data
ret = r;
goto rtn;
}
}
}
cc_refreshbuf(fd, buf);
}
}
}
rtn:
DBG("returned with `%s`", cc_hresult2str(ret));
FREE(key);
return ret;
}
#define BBUFS (63)
/**
* @brief cc_setint - send integer value over socket
* @param fd - socket fd
* @param cmd - setter
* @param val - new value
* @return answer received
*/
cc_hresult cc_setint(int fd, cc_strbuff *cbuf, const char *cmd, int val){
char buf[BBUFS+1];
snprintf(buf, BBUFS, "%s=%d\n", cmd, val);
return ask4cmd(fd, cbuf, buf);
}
/**
* @brief cc_getint - getter for integer value
*/
cc_hresult cc_getint(int fd, cc_strbuff *cbuf, const char *cmd, int *val){
char buf[BBUFS+1];
snprintf(buf, BBUFS, "%s\n", cmd);
cc_hresult r = ask4cmd(fd, cbuf, buf);
if(r == RESULT_OK){
char *sv = cc_get_keyval(cbuf->string);
if(!sv) return RESULT_FAIL;
char *ep;
long L = strtol(sv, &ep, 0);
if(sv == ep || L < INT_MIN || L > INT_MAX) return RESULT_BADVAL;
if(val) *val = (int) L;
}
return r;
}
/**
* @brief cc_setfloat - send float value over socket
* @param fd - socket fd
* @param cmd - setter
* @param val - new value
* @return answer received
*/
cc_hresult cc_setfloat(int fd, cc_strbuff *cbuf, const char *cmd, float val){
char buf[BBUFS+1];
snprintf(buf, BBUFS, "%s=%g\n", cmd, val);
return ask4cmd(fd, cbuf, buf);
}
/**
* @brief cc_getfloat - getter for float value
*/
cc_hresult cc_getfloat(int fd, cc_strbuff *cbuf, const char *cmd, float *val){
char buf[BBUFS+1];
snprintf(buf, BBUFS, "%s\n", cmd);
cc_hresult r = ask4cmd(fd, cbuf, buf);
if(r == RESULT_OK){
char *sv = cc_get_keyval(cbuf->string);
if(!sv) return RESULT_FAIL;
char *ep;
double d = strtod(sv, &ep);
if(sv == ep || d < (-FLT_MAX) || d > FLT_MAX) return RESULT_BADVAL;
if(val) *val = (float)d;
}
return r;
}
// get next record from external buffer, newlines==1 if every record ends with '\n'
char *cc_nextkw(char *buf, char record[FLEN_CARD+1], int newlines){
char *nextline = NULL;
int l = FLEN_CARD - 1;
if(newlines){
char *e = strchr(buf, '\n');
if(e){
if(e - buf < FLEN_CARD) l = e - buf;
nextline = e + 1;
}
}else nextline = buf + (FLEN_CARD - 1);
strncpy(record, buf, l);
record[l] = 0;
return nextline;
}
/**
* @brief cc_kwfromfile - add records from file
* @param b - buffer to add
* @param filename - file name with FITS headers ('\n'-terminated or by 80 chars)
* @return amount of bytes added
*/
size_t cc_kwfromfile(cc_charbuff *b, char *filename){
if(!b) return 0;
mmapbuf *buf = My_mmap(filename);
if(!buf || buf->len < 1){
WARNX("Can't add FITS records from file %s", filename);
LOGWARN("Can't add FITS records from file %s", filename);
return 0;
}
size_t blen0 = b->buflen;
char rec[FLEN_CARD+1], card[FLEN_CARD+1];
char *data = buf->data, *x = strchr(data, '\n'), *eodata = buf->data + buf->len;
int newlines = 0;
if(x && (x - data) < FLEN_CARD){ // we found newline -> this is a format with newlines
newlines = 1;
}
do{
data = cc_nextkw(data, rec, newlines);
if(data > eodata) break;
int status = 0, kt = 0;
fits_parse_template(rec, card, &kt, &status);
if(status) fits_report_error(stderr, status);
else cc_charbufaddline(b, card);
}while(data && *data);
My_munmap(buf);
return b->buflen - blen0;
}
/**
* @brief cc_charbuf2kw - write all keywords from `b` to file `f`
* `b` should be prepared by cc_kwfromfile or similar
* @param b - buffer with '\n'-separated FITS keys
* @param f - file to write
* @return FALSE if failed
*/
int cc_charbuf2kw(cc_charbuff *b, fitsfile *f){
if(!b || !f || !b->buflen) return FALSE;
char key[FLEN_KEYWORD + 1], card[FLEN_CARD+1]; // keyword to update
char *c = b->buf, *eof = b->buf + b->buflen;
while(c < eof){
char *e = strchr(c, '\n');
if(!e || e > eof) break;
//char *ek = strchr(c, ' ');
char *eq = strchr(c, '=');
//if(eq > ek) eq = ek; // if keyword is shorter than 8 letters
//size_t l = eq-c; if(l > FLEN_KEYWORD) l = FLEN_KEYWORD;
//memcpy(key, c, l); key[l] = 0;
memcpy(key, c, 8); key[8] = 0;
size_t l = e - c; if(l > FLEN_CARD) l = FLEN_CARD;
memcpy(card, c, l); card[l] = 0;
int status = 0;
if(eq - c == 8){ // key = val
DBG("Update key `%s` with `%s`", key, card);
fits_update_card(f, key, card, &status);
}else{ // comment etc
DBG("Write full record `%s`", card);
fits_write_record(f, card, &status);
}
if(status) fits_report_error(stderr, status);
c = e + 1;
}
return TRUE;
}

View File

@ -17,6 +17,8 @@
*/
#pragma once
#include <fitsio.h> // FLEN_CARD
#include <pthread.h>
#include <stdint.h>
#include <stdlib.h> // for size_t
@ -30,6 +32,7 @@ typedef struct __attribute__((packed, aligned(4))){
double timestamp; // timestamp of image taken
uint8_t bitpix; // bits per pixel (8 or 16)
int w, h; // image size
int gotstat; // stat counted
uint16_t max, min; // min/max values
float avr, std; // statistics
size_t bytelen; // size of image in bytes
@ -107,6 +110,7 @@ typedef struct{
int (*getTbody)(float *t); // body T
int (*getbin)(int *binh, int *binv);
int (*getio)(int *s); // get IO-port state
const char* (*plugincmd)(const char *str); // custom camera plugin command (get string as input, send string as output or NULL if failed)
float pixX, pixY; // pixel size in um
cc_frameformat field; // max field of view
cc_frameformat array; // array format
@ -145,11 +149,6 @@ typedef struct{
int (*getMaxPos)(int *p); // amount of positions
} cc_Wheel;
cc_Focuser *open_focuser(const char *pluginname);
cc_Camera *open_camera(const char *pluginname);
cc_Wheel *open_wheel(const char *pluginname);
int cc_getNbytes(cc_IMG *image);
/****** Content of old socket.h ******/
// max & min TCP socket port number
@ -161,8 +160,6 @@ int cc_getNbytes(cc_IMG *image);
// wait for mutex locking
#define CC_BUSY_TIMEOUT (1.0)
// waiting for answer timeout
#define CC_ANSWER_TIMEOUT (0.01)
// wait for exposition ends (between subsequent check calls)
#define CC_WAIT_TIMEOUT (2.0)
// client will disconnect after this time from last server message
@ -179,11 +176,6 @@ typedef enum{
RESULT_NUM
} cc_hresult;
const char *cc_hresult2str(cc_hresult r);
cc_hresult cc_str2hresult(const char *str);
int cc_setNtries(int n);
int cc_getNtries();
// fd - socket fd to send private messages, key, val - key and its value
typedef cc_hresult (*cc_mesghandler)(int fd, const char *key, const char *val);
@ -193,16 +185,6 @@ typedef struct{
const char *key; // keyword
} cc_handleritem;
int cc_open_socket(int isserver, char *path, int isnet);
int cc_senddata(int fd, void *data, size_t l);
int cc_sendmessage(int fd, const char *msg, int l);
int cc_sendstrmessage(int fd, const char *msg);
char *cc_get_keyval(char *keyval);
cc_IMG *cc_getshm(key_t key, size_t imsize);
int cc_canberead(int fd);
cc_hresult cc_sendint(int fd, const char *cmd, int val);
/****** Content of old server.h ******/
typedef enum{
@ -224,6 +206,7 @@ typedef enum{
#define CC_CMD_SHMEMKEY "shmemkey"
// CCD/CMOS
#define CC_CMD_PLUGINCMD "plugincmd"
#define CC_CMD_CAMLIST "camlist"
#define CC_CMD_CAMDEVNO "camdevno"
#define CC_CMD_EXPOSITION "exptime"
@ -252,6 +235,7 @@ typedef enum{
#define CC_CMD_DARK "dark"
#define CC_CMD_INFTY "infty"
// FITS file keywords
#define CC_CMD_GETHEADERS "getheaders"
#define CC_CMD_AUTHOR "author"
#define CC_CMD_INSTRUMENT "instrument"
#define CC_CMD_OBSERVER "observer"
@ -270,6 +254,15 @@ typedef enum{
#define CC_CMD_WDEVNO "wdevno"
#define CC_CMD_WPOS "wpos"
typedef struct{
char* buf; // databuffer
size_t bufsize; // size of `buf`
size_t buflen; // current buffer length
char *string; // last \n-ended string from `buf`
size_t strlen; // max length of `string`
pthread_mutex_t mutex; // mutex for atomic data access
} cc_strbuff;
typedef struct{
char* buf; // databuffer
size_t bufsize; // size of `buf`
@ -277,7 +270,46 @@ typedef struct{
pthread_mutex_t mutex; // mutex for atomic data access
} cc_charbuff;
cc_charbuff *cc_bufnew(size_t size);
void cc_bufdel(cc_charbuff **buf);
int cc_read2buf(int fd, cc_charbuff *buf);
size_t cc_getline(cc_charbuff *b, char *str, size_t len);
#define cc_buff_lock(b) pthread_mutex_lock(&b->mutex)
#define cc_buff_trylock(b) pthread_mutex_trylock(&b->mutex)
#define cc_buff_unlock(b) pthread_mutex_unlock(&b->mutex)
cc_Focuser *open_focuser(const char *pluginname);
cc_Camera *open_camera(const char *pluginname);
cc_Wheel *open_wheel(const char *pluginname);
cc_charbuff *cc_charbufnew();
int cc_charbuftest(cc_charbuff *b, size_t maxsize);
void cc_charbufclr(cc_charbuff *buf);
void cc_charbufdel(cc_charbuff **buf);
void cc_charbufput(cc_charbuff *b, const char *s, size_t l);
void cc_charbufaddline(cc_charbuff *b, const char *s);
cc_strbuff *cc_strbufnew(size_t size, size_t stringsize);
void cc_strbufdel(cc_strbuff **buf);
const char *cc_hresult2str(cc_hresult r);
cc_hresult cc_str2hresult(const char *str);
int cc_setNtries(int n);
int cc_getNtries();
int cc_setAnsTmout(double t);
double cc_getAnsTmout();
int cc_getNbytes(cc_IMG *image);
int cc_read2buf(int fd, cc_strbuff *buf);
int cc_refreshbuf(int fd, cc_strbuff *buf);
size_t cc_getline(cc_strbuff *b);
int cc_open_socket(int isserver, char *path, int isnet);
int cc_senddata(int fd, void *data, size_t l);
int cc_sendmessage(int fd, const char *msg, int l);
int cc_sendstrmessage(int fd, const char *msg);
char *cc_get_keyval(char *keyval);
cc_IMG *cc_getshm(key_t key, size_t imsize);
int cc_canberead(int fd);
cc_hresult cc_setint(int fd, cc_strbuff *cbuf, const char *cmd, int val);
cc_hresult cc_getint(int fd, cc_strbuff *cbuf, const char *cmd, int *val);
cc_hresult cc_setfloat(int fd, cc_strbuff *cbuf, const char *cmd, float val);
cc_hresult cc_getfloat(int fd, cc_strbuff *cbuf, const char *cmd, float *val);
char *cc_nextkw(char *buf, char record[FLEN_CARD+1], int newlines);
size_t cc_kwfromfile(cc_charbuff *b, char *filename);
int cc_charbuf2kw(cc_charbuff *b, fitsfile *f);

318
ccdfunc.c
View File

@ -73,59 +73,118 @@ static int check_filenameprefix(char *buff, int buflen){
return FALSE;
}
// get next record from external text file, newlines==1 if every record ends with '\n'
static char *getnextrec(char *buf, char *record, int newlines){
char *nextline = NULL;
int l = FLEN_CARD - 1;
if(newlines){
char *e = strchr(buf, '\n');
if(e){
if(e - buf < FLEN_CARD) l = e - buf;
nextline = e + 1;
}
}else nextline = buf + (FLEN_CARD - 1);
strncpy(record, buf, l);
record[l] = 0;
return nextline;
}
cc_charbuff *getFITSheader(cc_IMG *img){
static cc_charbuff charbuf = {0};
cc_charbufclr(&charbuf);
char card[FLEN_CARD+1], templ[2*FLEN_CARD+1], bufc[FLEN_CARD+1];
#define FORMKW(in) \
do{ int status = 0, kt = 0; \
fits_parse_template(in, card, &kt, &status); \
if(status) fits_report_error(stderr, status);\
else{cc_charbufaddline(&charbuf, card);} \
}while(0)
#define FORMINT(key, val, comment) do{ \
snprintf(templ, FLEN_CARD, "%s = %d / %s", key, val, comment); \
FORMKW(templ); \
}while(0)
#define FORMFLT(key, val, comment) do{ \
snprintf(templ, FLEN_CARD, "%s = %g / %s", key, val, comment); \
FORMKW(templ); \
}while(0)
#define FORMSTR(key, val, comment) do{ \
snprintf(templ, 2*FLEN_CARD, "%s = '%s' / %s", key, val, comment); \
FORMKW(templ); \
}while(0)
calculate_stat(img);
float tmpf = 0.0;
int tmpi = 0;
/* FORMKW("COMMENT this is just a test comment - 0");
FORMKW("COMMENT this is just a test comment - 1");
FORMKW("COMMENT this is just a test comment - 2");
FORMKW("HIERARCH longsome1 = 'this is just a test comment'");
FORMKW("HIERARCH longsome2 = 'this is just a test comment'");
FORMKW("HIERARCH longsome3 = 'this is just a test comment'");*/
FORMKW("ORIGIN = 'SAO RAS' / Organization responsible for the data");
FORMKW("OBSERVAT = 'Special Astrophysical Observatory, Russia' / Observatory name");
FORMKW("INSTRUME = 'direct imaging' / Instrument");
snprintf(templ, FLEN_CARD, "VIEWFLD = '(%d, %d)(%d, %d)' / Camera maximal field of view", camera->field.xoff, camera->field.yoff,
camera->field.xoff + camera->field.w, camera->field.yoff + camera->field.h);
FORMKW(templ);
snprintf(templ, FLEN_CARD, "ARRAYFLD = '(%d, %d)(%d, %d)' / Camera full array size (with overscans)", camera->array.xoff, camera->array.yoff,
camera->array.xoff + camera->array.w, camera->array.yoff + camera->array.h);
FORMKW(templ);
snprintf(templ, FLEN_CARD, "GEOMETRY = '(%d, %d)(%d, %d)' / Camera current frame geometry", camera->geometry.xoff, camera->geometry.yoff,
camera->geometry.xoff + camera->geometry.w, camera->geometry.yoff + camera->geometry.h);
FORMKW(templ);
if(GP->X0 > -1) FORMINT("X0", GP->X0, "Subframe left border without binning");
if(GP->Y0 > -1) FORMINT("Y0", GP->Y0, "Subframe upper border without binning");
if(GP->dark) sprintf(bufc, "dark");
else if(GP->objtype) strncpy(bufc, GP->objtype, FLEN_CARD);
else sprintf(bufc, "light");
FORMSTR("IMAGETYP", bufc, "Image type");
FORMINT("DATAMIN", 0, "Min pixel value");
FORMINT("DATAMAX", (1<<img->bitpix) - 1, "Max pixel value");
FORMINT("STATMIN", img->min, "Min data value");
FORMINT("STATMAX", img->max, "Max data value");
FORMFLT("STATAVR", img->avr, "Average data value");
FORMFLT("STATSTD", img->std, "Std. of data value");
if(camera->getTcold && camera->getTcold(&tmpf))
FORMFLT("CAMTEMP", tmpf, "Camera temperature at exp. end, degr C");
if(camera->getTbody && camera->getTbody(&tmpf))
FORMFLT("BODYTEMP", tmpf, "Camera body temperature at exp. end, degr C");
if(camera->getThot && camera->getThot(&tmpf))
FORMFLT("HOTTEMP", tmpf, "Camera peltier hot side temperature at exp. end, degr C");
FORMFLT( "EXPTIME", GP->exptime, "Actual exposition time (sec)");
if(camera->getgain && camera->getgain(&tmpf))
FORMFLT("CAMGAIN", tmpf, "CMOS gain value");
if(camera->getbrightness && camera->getbrightness(&tmpf))
FORMFLT("CAMBRIGH", tmpf, "CMOS brightness value");
/**
* @brief addrec - add FITS records from file
* @param f (i) - FITS filename
* @param filename (i) - name of file
*/
static void addrec(fitsfile *f, char *filename){
mmapbuf *buf = My_mmap(filename);
char rec[FLEN_CARD];
if(!buf || buf->len < 1){
WARNX("Empty header file %s", filename);
return;
snprintf(templ, 2*FLEN_CARD, "TIMESTAM = %.3f / Time of acquisition end (UNIX)", img->timestamp);
FORMKW(templ);
// BINNING / Binning
snprintf(templ, FLEN_CARD, "BINNING = '%d x %d' / Binning (hbin x vbin)", GP->hbin, GP->vbin);
FORMKW(templ);
FORMINT("XBINNING", GP->hbin, "Binning factor used on X axis");
FORMINT("YBINNING", GP->vbin, "Binning factor used on Y axis");
if(focuser){ // there is a focuser device - add info
if(focuser->getModelName && focuser->getModelName(bufc, FLEN_CARD))
FORMSTR("FOCUSER", bufc, "Focuser model");
if(focuser->getPos && focuser->getPos(&tmpf))
FORMFLT("FOCUS", tmpf, "Current focuser position, mm");
if(focuser->getMinPos && focuser->getMinPos(&tmpf))
FORMFLT("FOCMIN", tmpf, "Minimal focuser position, mm");
if(focuser->getMaxPos && focuser->getMaxPos(&tmpf))
FORMFLT("FOCMAX", tmpf, "Maximal focuser position, mm");
if(focuser->getTbody && focuser->getTbody(&tmpf))
FORMFLT("FOCTEMP", tmpf, "Focuser body temperature, degr C");
}
char *data = buf->data, *x = strchr(data, '\n'), *eodata = buf->data + buf->len;
int newlines = 0;
if(x && (x - data) < FLEN_CARD){ // we found newline -> this is a format with newlines
newlines = 1;
}
do{
data = getnextrec(data, rec, newlines);
verbose(4, "check record _%s_", rec);
int keytype, status = 0;
char newcard[FLEN_CARD], keyname[FLEN_CARD];
fits_parse_template(rec, newcard, &keytype, &status);
if(status){
fits_report_error(stderr, status);
continue;
if(wheel){ // there is a filter wheel device - add info
if(wheel->getModelName && wheel->getModelName(bufc, FLEN_CARD)){
FORMSTR("WHEEL", bufc, "Filter wheel model");
}
verbose(4, "reformatted to _%s_", newcard);
strncpy(keyname, newcard, FLEN_CARD);
char *eq = strchr(keyname, '='); if(eq) *eq = 0;
eq = strchr(keyname, ' '); if(eq) *eq = 0;
//DBG("keyname: %s", keyname);
fits_update_card(f, keyname, newcard, &status);
if(status) fits_report_error(stderr, status);
if(data > eodata) break;
}while(data && *data);
My_munmap(buf);
if(wheel->getPos && wheel->getPos(&tmpi))
FORMINT("FILTER", tmpi, "Current filter number");
if(wheel->getMaxPos && wheel->getMaxPos(&tmpi))
FORMINT("FILTMAX", tmpi, "Amount of filter positions");
if(wheel->getTbody && wheel->getTbody(&tmpf))
FORMFLT("FILTTEMP", tmpf, "Filter wheel body temperature, degr C");
}
if(GP->addhdr){ // add records from files
char **nxtfile = GP->addhdr;
while(*nxtfile){
cc_kwfromfile(&charbuf, *(nxtfile++));
}
}
// add these keywords after all to override records from files
if(GP->observers) FORMSTR("OBSERVER", GP->observers, "Observers");
if(GP->prog_id) FORMSTR("PROG-ID", GP->prog_id, "Observation program identifier");
if(GP->author) FORMSTR("AUTHOR", GP->author, "Author of the program");
if(GP->objname) FORMSTR("OBJECT", GP->objname, "Object name");
if(camera->getModelName && camera->getModelName(bufc, FLEN_CARD))
FORMSTR("DETECTOR", bufc, "Detector model");
if(GP->instrument) FORMSTR("INSTRUME", GP->instrument, "Instrument");
return &charbuf;
}
// save FITS file `img` into GP->outfile or GP->outfileprefix_XXXX.fits
@ -138,7 +197,7 @@ int saveFITS(cc_IMG *img, char **outp){
WARNX(_("Camera device unknown"));
return FALSE;
}
char buff[PATH_MAX+1], fnam[PATH_MAX+1];
char fnam[PATH_MAX+1];
if(!GP->outfile && !GP->outfileprefix){
LOGWARN("Image not saved: neither filename nor filename prefix pointed");
return FALSE;
@ -163,13 +222,8 @@ int saveFITS(cc_IMG *img, char **outp){
LOGERR("Can't save image with prefix %s", GP->outfileprefix);
}
}
calculate_stat(img);
int width = img->w, height = img->h;
long naxes[2] = {width, height};
double tmpd = 0.0;
float tmpf = 0.0;
int tmpi = 0;
struct tm *tm_time;
char bufc[FLEN_CARD];
double dsavetime = dtime();
@ -182,129 +236,29 @@ int saveFITS(cc_IMG *img, char **outp){
if(nbytes == 1) TRYFITS(fits_create_img, fp, BYTE_IMG, 2, naxes);
else TRYFITS(fits_create_img, fp, USHORT_IMG, 2, naxes);
if(fitserror) goto cloerr;
// ORIGIN / organization responsible for the data
WRITEKEY(fp, TSTRING, "ORIGIN", "SAO RAS", "organization responsible for the data");
// OBSERVAT / Observatory name
WRITEKEY(fp, TSTRING, "OBSERVAT", "Special Astrophysical Observatory, Russia", "Observatory name");
WRITEKEY(fp, TSTRING, "INSTRUME", "direct imaging", "Instrument");
snprintf(bufc, FLEN_VALUE, "(%d, %d)(%d, %d)", camera->field.xoff, camera->field.yoff,
camera->field.xoff + camera->field.w, camera->field.yoff + camera->field.h);
WRITEKEY(fp, TSTRING, "VIEWFLD", bufc, "Camera maximal field of view");
snprintf(bufc, FLEN_VALUE, "(%d, %d)(%d, %d)", camera->array.xoff, camera->array.yoff,
camera->array.xoff + camera->array.w, camera->array.yoff + camera->array.h);
WRITEKEY(fp, TSTRING, "ARRAYFLD", bufc, "Camera full array size (with overscans)");
snprintf(bufc, FLEN_VALUE, "(%d, %d)(%d, %d)", camera->geometry.xoff, camera->geometry.yoff,
camera->geometry.xoff + camera->geometry.w, camera->geometry.yoff + camera->geometry.h);
WRITEKEY(fp, TSTRING, "GEOMETRY", bufc, "Camera current frame geometry"); // CRVAL1, CRVAL2 / Offset in X, Y
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 without binning");
if(GP->dark) sprintf(bufc, "dark");
else if(GP->objtype) strncpy(bufc, GP->objtype, FLEN_CARD-1);
else sprintf(bufc, "light");
// IMAGETYP / object, flat, dark, bias, scan, eta, neon, push
WRITEKEY(fp, TSTRING, "IMAGETYP", bufc, "Image type");
// DATAMAX, DATAMIN / Max, min pixel value
tmpi = 0;
WRITEKEY(fp, TINT, "DATAMIN", &tmpi, "Min pixel value");
tmpi = (1<<img->bitpix) - 1;
WRITEKEY(fp, TINT, "DATAMAX", &tmpi, "Max pixel value");
tmpi = img->min;
WRITEKEY(fp, TUSHORT, "STATMIN", &tmpi, "Min data value");
tmpi = img->max;
WRITEKEY(fp, TUSHORT, "STATMAX", &tmpi, "Max data value");
tmpf = img->avr;
WRITEKEY(fp, TFLOAT, "STATAVR", &tmpf, "Average data value");
tmpf = img->std;
WRITEKEY(fp, TFLOAT, "STATSTD", &tmpf, "Std. of data value");
// WRITEKEY(fp, TFLOAT, "CAMTEMP0", &GP->temperature, "Camera temperature at exp. start, degr C");
if(camera->getTcold(&tmpf))
WRITEKEY(fp, TFLOAT, "CAMTEMP", &tmpf, "Camera temperature at exp. end, degr C");
if(camera->getTbody(&tmpf))
WRITEKEY(fp, TFLOAT, "BODYTEMP", &tmpf, "Camera body temperature at exp. end, degr C");
if(camera->getThot(&tmpf))
WRITEKEY(fp, TFLOAT, "HOTTEMP", &tmpf, "Camera peltier hot side temperature at exp. end, degr C");
// EXPTIME / actual exposition time (sec)
tmpd = GP->exptime;
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)
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)");
cc_charbuff *bufhdr = getFITSheader(img);
cc_charbuf2kw(bufhdr, fp);
// creation date/time
int s = 0;
fits_write_date(fp, &s);
/*
s = 0;
fits_write_comment(fp, bufhdr->buf, &s);
s = 0;
fits_write_history(fp, bufhdr->buf, &s);
*/
tm_time = localtime(&savetime);
strftime(bufc, FLEN_VALUE, "File creation time (UNIX)", tm_time);
WRITEKEY(fp, TDOUBLE, "UNIXTIME", &dsavetime, bufc);
WRITEKEY(fp, TDOUBLE, "TIMESTAM", &img->timestamp, "Time of acquisition end");
strftime(bufc, 80, "%Y/%m/%d", tm_time);
// DATE-OBS / DATE (YYYY/MM/DD) OF OBS.
WRITEKEY(fp, TSTRING, "DATE-OBS", bufc, "DATE OF OBS. (YYYY/MM/DD, local)");
strftime(bufc, 80, "%H:%M:%S", tm_time);
WRITEKEY(fp, TDOUBLE, "UNIXTIME", &dsavetime, "File creation time (UNIX)");
strftime(bufc, FLEN_VALUE, "%Y/%m/%d", tm_time);
WRITEKEY(fp, TSTRING, "DATE-OBS", bufc, "Date of observation (YYYY/MM/DD, local)");
strftime(bufc, FLEN_VALUE, "%H:%M:%S", tm_time);
WRITEKEY(fp, TSTRING, "TIME", bufc, "Creation time (hh:mm:ss, local)");
// BINNING / Binning
if(GP->hbin != 1 || GP->vbin != 1){
snprintf(bufc, 80, "%d x %d", GP->hbin, GP->vbin);
WRITEKEY(fp, TSTRING, "BINNING", bufc, "Binning (hbin x vbin)");
tmpi = GP->hbin;
WRITEKEY(fp, TINT, "XBINNING", &tmpi, "binning factor used on X axis");
tmpi = GP->vbin;
WRITEKEY(fp, TINT, "YBINNING", &tmpi, "binning factor used on Y axis");
}
if(focuser){ // there is a focuser device - add info
if(focuser->getModelName(buff, PATH_MAX))
WRITEKEY(fp, TSTRING, "FOCUSER", buff, "Focuser model");
if(focuser->getPos(&tmpf))
WRITEKEY(fp, TFLOAT, "FOCUS", &tmpf, "Current focuser position, mm");
if(focuser->getMinPos(&tmpf))
WRITEKEY(fp, TFLOAT, "FOCMIN", &tmpf, "Minimal focuser position, mm");
if(focuser->getMaxPos(&tmpf))
WRITEKEY(fp, TFLOAT, "FOCMAX", &tmpf, "Maximal focuser position, mm");
if(focuser->getTbody(&tmpf))
WRITEKEY(fp, TFLOAT, "FOCTEMP", &tmpf, "Focuser body temperature, degr C");
}
if(wheel){ // there is a filter wheel device - add info
if(wheel->getModelName(buff, PATH_MAX))
WRITEKEY(fp, TSTRING, "WHEEL", buff, "Filter wheel model");
if(wheel->getPos(&tmpi))
WRITEKEY(fp, TINT, "FILTER", &tmpi, "Current filter number");
if(wheel->getMaxPos(&tmpi))
WRITEKEY(fp, TINT, "FILTMAX", &tmpi, "Amount of filter positions");
if(wheel->getTbody(&tmpf))
WRITEKEY(fp, TFLOAT, "FILTTEMP", &tmpf, "Filter wheel body temperature, degr C");
}
if(GP->addhdr){ // add records from files
char **nxtfile = GP->addhdr;
while(*nxtfile){
addrec(fp, *nxtfile++);
}
}
// add these keywords after all to change things in files with static records
// OBSERVER / Observers
if(GP->observers)
WRITEKEY(fp, TSTRING, "OBSERVER", GP->observers, "Observers");
// PROG-ID / Observation program identifier
if(GP->prog_id)
WRITEKEY(fp, TSTRING, "PROG-ID", GP->prog_id, "Observation program identifier");
// AUTHOR / Author of the program
if(GP->author)
WRITEKEY(fp, TSTRING, "AUTHOR", GP->author, "Author of the program");
// OBJECT / Object name
if(GP->objname){
WRITEKEY(fp, TSTRING, "OBJECT", GP->objname, "Object name");
}
// FILE / Input file original name
char *n = fnam;
if(*n == '!') ++n;
WRITEKEY(fp, TSTRING, "FILE", n, "Input file original name");
// DETECTOR / detector
if(camera->getModelName(buff, PATH_MAX))
WRITEKEY(fp, TSTRING, "DETECTOR", buff, "Detector model");
// INSTRUME / Instrument
if(GP->instrument)
WRITEKEY(fp, TSTRING, "INSTRUME", GP->instrument, "Instrument");
s = 0; fits_write_comment(fp, "Input file original name:", &s);
s = 0; fits_write_comment(fp, n, &s);
//WRITEKEY(fp, TSTRING, "FILE", n, "Input file original name");
if(nbytes == 1) TRYFITS(fits_write_img, fp, TBYTE, 1, width * height, img->data);
else TRYFITS(fits_write_img, fp, TUSHORT, 1, width * height, img->data);
if(fitserror) goto cloerr;
@ -394,6 +348,7 @@ static void stat16(cc_IMG *image){
void calculate_stat(cc_IMG *image){
if(!image || image->gotstat) return;
int nbytes = ((7 + image->bitpix) / 8);
if(nbytes == 1) stat8(image);
else stat16(image);
@ -402,6 +357,7 @@ void calculate_stat(cc_IMG *image){
printf("avr = %.1f, std = %.1f\n", image->avr, image->std);
printf("max = %u, min = %u, size = %d pix\n", image->max, image->min, image->w * image->h);
}
image->gotstat = 1;
}
cc_Focuser *startFocuser(){
@ -643,6 +599,19 @@ int prepare_ccds(){
WARNX(_("Can't set active camera number"));
goto retn;
}
// run plugincmd handler if available
if(GP->plugincmd){
DBG("Plugincmd");
if(!camera->plugincmd) WARNX(_("Camera plugin have no custom commands"));
else{
char **p = GP->plugincmd;
DBG("got %s", *p);
while(p && *p){
printf("Command: %s\nAnswer: %s\n", *p, camera->plugincmd(*p));
++p;
}
}
}
if(GP->fanspeed > -1){
if(GP->fanspeed > FAN_HIGH) GP->fanspeed = FAN_HIGH;
if(!camera->setfanspeed((cc_fan_speed)GP->fanspeed))
@ -791,6 +760,7 @@ DBG("w=%d, h=%d", raw_width, raw_height);
WARNX(_("Can't grab image"));
break;
}
ima.gotstat = 0;
TIMESTAMP("Calc stat");
calculate_stat(&ima);
TIMESTAMP("Save fits");

View File

@ -24,6 +24,7 @@ extern cc_Focuser *focuser;
extern cc_Wheel *wheel;
void calculate_stat(cc_IMG *image);
cc_charbuff *getFITSheader(cc_IMG *img);
int saveFITS(cc_IMG *img, char **outp); // for imageview module
void focusers();
void wheels();

View File

@ -32,6 +32,8 @@
#include "server.h" // for common commands names
#include "socket.h"
extern double answer_timeout;
static char sendbuf[BUFSIZ];
// send message and wait any answer
#define SENDMSG(...) do{DBG("SENDMSG"); snprintf(sendbuf, BUFSIZ-1, __VA_ARGS__); verbose(2, "\t> %s", sendbuf); cc_sendstrmessage(sock, sendbuf); while(getans(sock, NULL));} while(0)
@ -52,17 +54,16 @@ static uint8_t *imbuf = NULL;
#endif
static char *readmsg(int fd){
static cc_charbuff *buf = NULL;
static char line[BUFSIZ];
if(!buf) buf = cc_bufnew(BUFSIZ);
static cc_strbuff *buf = NULL;
if(!buf) buf = cc_strbufnew(BUFSIZ, 255);
if(1 == cc_canberead(fd)){
if(cc_read2buf(fd, buf)){
size_t got = cc_getline(buf, line, BUFSIZ);
if(got >= BUFSIZ){
size_t got = cc_getline(buf);
if(got > 255){
DBG("Client fd=%d gave buffer overflow", fd);
LOGMSG("SERVER client fd=%d buffer overflow", fd);
}else if(got){
return line;
return buf->string;
}
}else ERRX("Server disconnected");
}
@ -103,7 +104,7 @@ static int parseans(char *ans){
static int getans(int sock, const char *msg){
double t0 = dtime();
char *ans = NULL;
while(dtime() - t0 < CC_ANSWER_TIMEOUT){
while(dtime() - t0 < answer_timeout){
char *s = readmsg(sock);
if(!s) continue;
t0 = dtime();
@ -118,7 +119,6 @@ DBG("1 msg-> %s, ans -> %s", msg, ans);
break;
}
}
//DBG("GETANS: %s, %s", ans, (dtime()-t0 > CC_ANSWER_TIMEOUT) ? "timeout" : "got answer");
return ((ans) ? TRUE : FALSE);
}
@ -126,6 +126,9 @@ DBG("1 msg-> %s, ans -> %s", msg, ans);
* @brief processData - process here some actions and make messages for server
*/
static void send_headers(int sock){
if(GP->exptime > -DBL_EPSILON) SENDMSGW(CC_CMD_EXPOSITION, "=%g", GP->exptime);
DBG("infty=%d", GP->infty);
if(GP->infty > -1) SENDMSGW(CC_CMD_INFTY, "=%d", GP->infty);
// common information
SENDMSG(CC_CMD_INFO);
// focuser
@ -188,7 +191,6 @@ static void send_headers(int sock){
if(!*GP->outfileprefix) SENDMSGW(CC_CMD_FILENAMEPREFIX, "=");
else SENDMSGW(CC_CMD_FILENAMEPREFIX, "=%s", makeabspath(GP->outfileprefix, FALSE));
}
if(GP->exptime > -DBL_EPSILON) SENDMSGW(CC_CMD_EXPOSITION, "=%g", GP->exptime);
// FITS header keywords:
#define CHKHDR(x, cmd) do{if(x) SENDMSG(cmd "=%s", x);}while(0)
CHKHDR(GP->author, CC_CMD_AUTHOR);
@ -218,7 +220,6 @@ void client(int sock){
SENDCMDW(CC_CMD_RESTART);
return;
}
if(GP->infty > -1) SENDMSGW(CC_CMD_INFTY, "=%d", GP->infty);
send_headers(sock);
double t0 = dtime(), tw = t0;
int Nremain = 0, nframe = 1;
@ -278,7 +279,7 @@ void client(int sock){
SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE);
}else{
GP->waitexpend = 0;
timeout = CC_ANSWER_TIMEOUT; // wait for last file name
timeout = answer_timeout; // wait for last file name
}
}
}

View File

@ -34,19 +34,25 @@ static glob_pars G = {
.infty = -1
};
// need this to proper work with only-long args
//#define NA (-__COUNTER__)
// TODO: fix the bug in usefull_macros first!!!
#define NA (0)
/*
* Define command line options by filling structure:
* name has_arg flag val type argptr help
*/
myoption cmdlnopts[] = {
{"plugin" ,NEED_ARG, NULL, 0, arg_string, APTR(&G.commondev), N_("common device plugin (e.g devfli.so)")},
{"plugin" ,NEED_ARG, NULL, NA, arg_string, APTR(&G.commondev), N_("common device plugin (e.g devfli.so)")},
{"plugincmd",MULT_PAR, NULL, '_', arg_string, APTR(&G.plugincmd), N_("custom camera device plugin command")},
{"cameradev", NEED_ARG, NULL, 'C', arg_string, APTR(&G.cameradev), N_("camera device plugin (e.g. devfli.so)")},
{"focuserdev", NEED_ARG,NULL, 'F', arg_string, APTR(&G.focuserdev),N_("focuser device plugin (e.g. devzwo.so)")},
{"wheeldev", NEED_ARG, NULL, 'W', arg_string, APTR(&G.wheeldev), N_("wheel device plugin (e.g. devdummy.so)")},
{"list", NO_ARGS, NULL, 'L', arg_int, APTR(&G.listdevices),N_("list connected devices")},
{"camdevno",NEED_ARG, NULL, 0, arg_int, APTR(&G.camdevno), N_("camera device number (if many: 0, 1, 2 etc)")},
{"wheeldevno",NEED_ARG, NULL, 0, arg_int, APTR(&G.whldevno), N_("filter wheel device number (if many: 0, 1, 2 etc)")},
{"focdevno",NEED_ARG, NULL, 0, arg_int, APTR(&G.focdevno), N_("focuser device number (if many: 0, 1, 2 etc)")},
{"camdevno",NEED_ARG, NULL, NA, arg_int, APTR(&G.camdevno), N_("camera device number (if many: 0, 1, 2 etc)")},
{"wheeldevno",NEED_ARG, NULL, NA, arg_int, APTR(&G.whldevno), N_("filter wheel device number (if many: 0, 1, 2 etc)")},
{"focdevno",NEED_ARG, NULL, NA, arg_int, APTR(&G.focdevno), N_("focuser device number (if many: 0, 1, 2 etc)")},
{"help", NO_ARGS, &help, 1, arg_none, NULL, N_("show this help")},
{"rewrite", NO_ARGS, &G.rewrite,1, arg_none, NULL, N_("rewrite output file if exists")},
{"verbose", NO_ARGS, NULL, 'V', arg_none, APTR(&G.verbose), N_("verbose level (-V - messages, -VV - debug, -VVV - all shit)")},
@ -54,7 +60,7 @@ myoption cmdlnopts[] = {
{"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 readout mode")},
{"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, NA, arg_int, APTR(&G.fanspeed), N_("set fan speed (0 - off, 1 - low, 2 - high)")},
{"author", NEED_ARG, NULL, 'A', arg_string, APTR(&G.author), N_("program author")},
{"objtype", NEED_ARG, NULL, 'Y', arg_string, APTR(&G.objtype), N_("object type (neon, object, flat etc)")},
@ -73,10 +79,10 @@ myoption cmdlnopts[] = {
{"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!)")},
{"cancel", NO_ARGS, &G.cancelexpose, 1,arg_none, NULL, N_("cancel current exposition")},
{"X0", NEED_ARG, NULL, 0, arg_int, APTR(&G.X0), N_("absolute (not divided by binning!) frame X0 coordinate (-1 - all with overscan)")},
{"Y0", NEED_ARG, NULL, 0, arg_int, APTR(&G.Y0), N_("absolute frame Y0 coordinate (-1 - all with overscan)")},
{"X1", NEED_ARG, NULL, 0, arg_int, APTR(&G.X1), N_("absolute frame X1 coordinate (-1 - all with overscan)")},
{"Y1", NEED_ARG, NULL, 0, arg_int, APTR(&G.Y1), N_("absolute frame Y1 coordinate (-1 - all with overscan)")},
{"X0", NEED_ARG, NULL, NA, arg_int, APTR(&G.X0), N_("absolute (not divided by binning!) frame X0 coordinate (-1 - all with overscan)")},
{"Y0", NEED_ARG, NULL, NA, arg_int, APTR(&G.Y0), N_("absolute frame Y0 coordinate (-1 - all with overscan)")},
{"X1", NEED_ARG, NULL, NA, arg_int, APTR(&G.X1), N_("absolute frame X1 coordinate (-1 - all with overscan)")},
{"Y1", NEED_ARG, NULL, NA, 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")},
{"close-shutter",NO_ARGS,&G.shtr_cmd, SHUTTER_CLOSE,arg_none,NULL, N_("close shutter")},
@ -93,20 +99,20 @@ myoption cmdlnopts[] = {
{"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")},
{"gain", NEED_ARG, NULL, NA, arg_float, APTR(&G.gain), N_("CMOS gain level")},
{"brightness",NEED_ARG, NULL, NA, 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 (command socket)")},
{"port", NEED_ARG, NULL, 0, arg_string, APTR(&G.port), N_("local INET command socket port")},
{"imageport",NEED_ARG, NULL, 0, arg_string, APTR(&G.imageport), N_("INET image socket port")},
{"logfile", NEED_ARG, NULL, NA, arg_string, APTR(&G.logfile), N_("logging file name (if run as server)")},
{"path", NEED_ARG, NULL, NA, arg_string, APTR(&G.path), N_("UNIX socket name (command socket)")},
{"port", NEED_ARG, NULL, NA, arg_string, APTR(&G.port), N_("local INET command socket port")},
{"imageport",NEED_ARG, NULL, NA, arg_string, APTR(&G.imageport), N_("INET image socket port")},
{"client", NO_ARGS, &G.client,1, arg_none, NULL, N_("run as client")},
{"viewer", NO_ARGS, &G.viewer,1, arg_none, NULL, N_("passive viewer (only get last images)")},
{"restart", NO_ARGS, &G.restart,1, arg_none, NULL, N_("restart image server")},
{"shmkey", NEED_ARG, NULL, 'k', arg_int, APTR(&G.shmkey), N_("shared memory (with image data) key (default: 7777777)")},
{"forceimsock",NO_ARGS, &G.forceimsock,1, arg_none, NULL, N_("force using image through socket transition even if can use SHM)")},
{"infty", NEED_ARG, NULL, 0, arg_int, APTR(&G.infty), N_("start (!=0) or stop(==0) infinity capturing loop")},
{"infty", NEED_ARG, NULL, NA, arg_int, APTR(&G.infty), N_("start (!=0) or stop(==0) infinity capturing loop")},
#ifdef IMAGEVIEW
{"display", NO_ARGS, NULL, 'D', arg_int, APTR(&G.showimage), N_("Display image in OpenGL window")},

View File

@ -40,6 +40,7 @@ typedef struct{
char *port; // local INET socket port
char *imageport; // port to send/receive images (by default == port+1)
char **addhdr; // list of files from which to add header records
char **plugincmd; // plugin commands
int restart; // restart server
int waitexpend; // wait while exposition ends
int cancelexpose; // cancel exp (for Grasshopper - forbid forever)

View File

@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.20)
include_directories(..)
add_executable(ccd_client main.c)
add_executable(ccd_client ccd_client.c)
target_link_libraries(ccd_client ccdcapture usefull_macros)

134
examples/ccd_client.c Normal file
View File

@ -0,0 +1,134 @@
/*
* This file is part of the CCD_Capture project.
* Copyright 2023 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/>.
*/
/*
* A simple example to take 8-bit images with default size and given exposition time.
* Works in `infinity` mode or requesting each file after receiving previous.
*/
#include <stdio.h>
#include <string.h>
#include <usefull_macros.h>
#include "socket.h"
typedef struct{
char *sockname; // UNIX socket name of command socket or port of local socket
int isun; // command socket is UNIX socket instead of INET
int shmkey; // shared memory (with image data) key
int infty; // run in infinity loop (if not - run by requests)
int nframes; // amount of frames to take
int help; // show this help
double exptime; // time of exposition in seconds
} glob_pars;
static glob_pars G = {
.shmkey = 7777777,
.nframes = 10
};
/*
* Define command line options by filling structure:
* name has_arg flag val type argptr help
*/
myoption cmdlnopts[] = {
{"sock", NEED_ARG, NULL, 's', arg_string, APTR(&G.sockname), "command socket name or port"},
{"isun", NO_ARGS, NULL, 'U', arg_int, APTR(&G.isun), "use UNIX socket"},
{"shmkey", NEED_ARG, NULL, 'k', arg_int, APTR(&G.shmkey), "shared memory (with image data) key (default: 7777777)"},
{"infty", NO_ARGS, NULL, 'i', arg_int, APTR(&G.infty), "run in infinity capturing loop (else - request each frame)"},
{"nframes", NEED_ARG, NULL, 'n', arg_int, APTR(&G.nframes), "make series of N frames"},
{"exptime", NEED_ARG, NULL, 'x', arg_double, APTR(&G.exptime), "set exposure time to given value (seconds!)"},
{"help", NO_ARGS, NULL, 'h', arg_int, APTR(&G.help), "show this help"},
};
static cc_IMG *shimg = NULL, img = {0};
static int refresh_img(){
if(!shimg) return FALSE;
static size_t imnumber = 0;
if(shimg->imnumber == imnumber) return FALSE;
imnumber = shimg->imnumber;
void *optr = img.data;
memcpy(&img, shimg, sizeof(img));
img.data = realloc(optr, img.bytelen);
memcpy(img.data, (uint8_t*)shimg + sizeof(cc_IMG), img.bytelen);
return TRUE;
}
#define STRBUFSZ (256)
int main(int argc, char **argv){
initial_setup();
parseargs(&argc, &argv, cmdlnopts);
if(G.help) showhelp(-1, cmdlnopts);
if(argc > 0){
WARNX("%d unused parameters:", argc);
for(int i = 0; i < argc; ++i)
printf("%4d: %s\n", i, argv[i]);
}
if(!G.sockname) ERRX("Point socket name or port");
cc_strbuff *cbuf = cc_strbufnew(BUFSIZ, STRBUFSZ);
int sock = cc_open_socket(FALSE, G.sockname, !G.isun);
if(sock < 0) ERR("Can't open socket %s", G.sockname);
int shmemkey = 0;
if(RESULT_OK == cc_getint(sock, cbuf, CC_CMD_SHMEMKEY, &shmemkey)){
green("Got shm key: %d\n", shmemkey);
}else{
red("Can't read shmkey, try yours\n");
shmemkey = G.shmkey;
}
if(RESULT_OK == cc_setint(sock, cbuf, CC_CMD_INFTY, 1)) green("ask for INFTY\n");
else red("Can't ask for INFTY\n");
float xt = 0.f;
if(RESULT_OK == cc_getfloat(sock, cbuf, CC_CMD_EXPOSITION, &xt)){
green("Old exp time: %gs\n", xt);
}
fflush(stdout);
if(RESULT_OK == cc_setfloat(sock, cbuf, CC_CMD_EXPOSITION, 0.5)) green("ask for exptime 0.5s\n");
else red("Can't change exptime to 0.5s\n");
shimg = cc_getshm(shmemkey, 0);
if(!shimg) ERRX("Can't get shared memory segment");
int i = 0;
time_t oldtime = time(NULL);
double oldtimestamp = shimg->timestamp;
do{
if(cc_refreshbuf(sock, cbuf) && cc_getline(cbuf)){
printf("\t\tServer sent: `%s`\n", cbuf->string);
}
time_t now = time(NULL);
if(now - oldtime > 5){
WARNX("No new images for 5 seconds");
break;
}
if(!refresh_img()){
usleep(1000);
continue;
}
++i;
oldtime = now;
printf("Got image #%zd, size %dx%d, bitpix %d, time %g\n", img.imnumber, img.w, img.h, img.bitpix, img.timestamp-oldtimestamp);
}while(i < 2);
if(RESULT_OK != cc_setint(sock, cbuf, CC_CMD_INFTY, 0)) red("Can't clear INFTY\n");
if(xt > 0.){
if(RESULT_OK != cc_setfloat(sock, cbuf, CC_CMD_EXPOSITION, xt)) red("Can't return exptime to %gs\n", xt);
}
cc_strbufdel(&cbuf);
close(sock);
return 0;
}

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-01-24 11:37+0300\n"
"POT-Creation-Date: 2024-02-01 14:36+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -17,545 +17,553 @@ msgstr ""
"Content-Type: text/plain; charset=koi8-r\n"
"Content-Transfer-Encoding: 8bit\n"
#: cmdlnopts.c:42
#: cmdlnopts.c:47
msgid "common device plugin (e.g devfli.so)"
msgstr ""
#: cmdlnopts.c:43
msgid "camera device plugin (e.g. devfli.so)"
msgstr ""
#: cmdlnopts.c:44
msgid "focuser device plugin (e.g. devzwo.so)"
msgstr ""
#: cmdlnopts.c:45
msgid "wheel device plugin (e.g. devdummy.so)"
msgstr ""
#: cmdlnopts.c:46
msgid "list connected devices"
msgstr ""
#: cmdlnopts.c:47
msgid "camera device number (if many: 0, 1, 2 etc)"
msgstr ""
#: cmdlnopts.c:48
msgid "filter wheel device number (if many: 0, 1, 2 etc)"
msgid "custom camera device plugin command"
msgstr ""
#: cmdlnopts.c:49
msgid "focuser device number (if many: 0, 1, 2 etc)"
msgid "camera device plugin (e.g. devfli.so)"
msgstr ""
#: cmdlnopts.c:50
msgid "show this help"
msgid "focuser device plugin (e.g. devzwo.so)"
msgstr ""
#: cmdlnopts.c:51
msgid "rewrite output file if exists"
msgid "wheel device plugin (e.g. devdummy.so)"
msgstr ""
#: cmdlnopts.c:52
msgid "verbose level (-V - messages, -VV - debug, -VVV - all shit)"
msgid "list connected devices"
msgstr ""
#: cmdlnopts.c:53
msgid "not open shutter, when exposing (\"dark frames\")"
msgid "camera device number (if many: 0, 1, 2 etc)"
msgstr ""
#: cmdlnopts.c:54
msgid "run in 8-bit mode"
msgid "filter wheel device number (if many: 0, 1, 2 etc)"
msgstr ""
#: cmdlnopts.c:55
msgid "fast readout mode"
msgid "focuser device number (if many: 0, 1, 2 etc)"
msgstr ""
#: cmdlnopts.c:56
msgid "set CCD temperature to given value (degr C)"
msgid "show this help"
msgstr ""
#: cmdlnopts.c:57
msgid "set fan speed (0 - off, 1 - low, 2 - high)"
msgid "rewrite output file if exists"
msgstr ""
#: cmdlnopts.c:58
msgid "verbose level (-V - messages, -VV - debug, -VVV - all shit)"
msgstr ""
#: cmdlnopts.c:59
msgid "program author"
msgid "not open shutter, when exposing (\"dark frames\")"
msgstr ""
#: cmdlnopts.c:60
msgid "object type (neon, object, flat etc)"
msgid "run in 8-bit mode"
msgstr ""
#: cmdlnopts.c:61
msgid "instrument name"
msgid "fast readout mode"
msgstr ""
#: cmdlnopts.c:62
msgid "object name"
msgid "set CCD temperature to given value (degr C)"
msgstr ""
#: cmdlnopts.c:63
msgid "observers' names"
msgstr ""
#: cmdlnopts.c:64
msgid "observing program name"
msgid "set fan speed (0 - off, 1 - low, 2 - high)"
msgstr ""
#: cmdlnopts.c:65
msgid "add records to header from given file[s]"
msgid "program author"
msgstr ""
#: cmdlnopts.c:66
msgid "output file name"
msgid "object type (neon, object, flat etc)"
msgstr ""
#: cmdlnopts.c:67
msgid "wait while exposition ends"
msgid "instrument name"
msgstr ""
#: cmdlnopts.c:68
msgid "object name"
msgstr ""
#: cmdlnopts.c:69
msgid "N flushes before exposing (default: 1)"
msgid "observers' names"
msgstr ""
#: cmdlnopts.c:70
msgid "horizontal binning to N pixels"
msgid "observing program name"
msgstr ""
#: cmdlnopts.c:71
msgid "vertical binning to N pixels"
msgid "add records to header from given file[s]"
msgstr ""
#: cmdlnopts.c:72
msgid "make series of N frames"
msgid "output file name"
msgstr ""
#: cmdlnopts.c:73
msgid "make pause for N seconds between expositions"
msgstr ""
#: cmdlnopts.c:74
msgid "set exposure time to given value (seconds!)"
msgid "wait while exposition ends"
msgstr ""
#: cmdlnopts.c:75
msgid "cancel current exposition"
msgid "N flushes before exposing (default: 1)"
msgstr ""
#: cmdlnopts.c:76
msgid "horizontal binning to N pixels"
msgstr ""
#: cmdlnopts.c:77
msgid "vertical binning to N pixels"
msgstr ""
#: cmdlnopts.c:78
msgid "make series of N frames"
msgstr ""
#: cmdlnopts.c:79
msgid "make pause for N seconds between expositions"
msgstr ""
#: cmdlnopts.c:80
msgid "set exposure time to given value (seconds!)"
msgstr ""
#: cmdlnopts.c:81
msgid "cancel current exposition"
msgstr ""
#: cmdlnopts.c:82
msgid ""
"absolute (not divided by binning!) frame X0 coordinate (-1 - all with "
"overscan)"
msgstr ""
#: cmdlnopts.c:77
#: cmdlnopts.c:83
msgid "absolute frame Y0 coordinate (-1 - all with overscan)"
msgstr ""
#: cmdlnopts.c:78
#: cmdlnopts.c:84
msgid "absolute frame X1 coordinate (-1 - all with overscan)"
msgstr ""
#: cmdlnopts.c:79
#: cmdlnopts.c:85
msgid "absolute frame Y1 coordinate (-1 - all with overscan)"
msgstr ""
#: cmdlnopts.c:81
#: cmdlnopts.c:87
msgid "open shutter"
msgstr ""
#: cmdlnopts.c:82
#: cmdlnopts.c:88
msgid "close shutter"
msgstr ""
#: cmdlnopts.c:83
#: cmdlnopts.c:89
msgid "run exposition on LOW @ pin5 I/O port"
msgstr ""
#: cmdlnopts.c:84
#: cmdlnopts.c:90
msgid "run exposition on HIGH @ pin5 I/O port"
msgstr ""
#: cmdlnopts.c:85
#: cmdlnopts.c:91
msgid "get value of I/O port pins"
msgstr ""
#: cmdlnopts.c:86
#: cmdlnopts.c:92
msgid "move stepper motor asynchronous"
msgstr ""
#: cmdlnopts.c:88
#: cmdlnopts.c:94
msgid "set I/O port pins to given value (decimal number, pin1 is LSB)"
msgstr ""
#: cmdlnopts.c:89
#: cmdlnopts.c:95
msgid ""
"configure I/O port pins to given value (decimal number, pin1 is LSB, 1 == "
"output, 0 == input)"
msgstr ""
#: cmdlnopts.c:91
#: cmdlnopts.c:97
msgid "move focuser to absolute position, mm"
msgstr ""
#: cmdlnopts.c:92
#: cmdlnopts.c:98
msgid "move focuser to relative position, mm (only for standalone)"
msgstr ""
#: cmdlnopts.c:94
#: cmdlnopts.c:100
msgid "set wheel position"
msgstr ""
#: cmdlnopts.c:96
#: cmdlnopts.c:102
msgid "CMOS gain level"
msgstr ""
#: cmdlnopts.c:97
#: cmdlnopts.c:103
msgid "CMOS brightness level"
msgstr ""
#: cmdlnopts.c:99
#: cmdlnopts.c:105
msgid "logging file name (if run as server)"
msgstr ""
#: cmdlnopts.c:100
#: cmdlnopts.c:106
msgid "UNIX socket name (command socket)"
msgstr ""
#: cmdlnopts.c:101
#: cmdlnopts.c:107
msgid "local INET command socket port"
msgstr ""
#: cmdlnopts.c:102
#: cmdlnopts.c:108
msgid "INET image socket port"
msgstr ""
#: cmdlnopts.c:103
#: cmdlnopts.c:109
msgid "run as client"
msgstr ""
#: cmdlnopts.c:104
#: cmdlnopts.c:110
msgid "passive viewer (only get last images)"
msgstr ""
#: cmdlnopts.c:105
#: cmdlnopts.c:111
msgid "restart image server"
msgstr ""
#: cmdlnopts.c:107
#: cmdlnopts.c:113
msgid "shared memory (with image data) key (default: 7777777)"
msgstr ""
#: cmdlnopts.c:108
#: cmdlnopts.c:114
msgid "force using image through socket transition even if can use SHM)"
msgstr ""
#: cmdlnopts.c:109
#: cmdlnopts.c:115
msgid "start (!=0) or stop(==0) infinity capturing loop"
msgstr ""
#: cmdlnopts.c:112
#: cmdlnopts.c:118
msgid "Display image in OpenGL window"
msgstr ""
#: ccdfunc.c:138
#: ccdfunc.c:197
msgid "Camera device unknown"
msgstr ""
#. Не могу сохранить файл
#: ccdfunc.c:162
#: ccdfunc.c:221
#, c-format
msgid "Can't save file with prefix %s"
msgstr ""
#: ccdfunc.c:315
#: ccdfunc.c:269
#, c-format
msgid "File saved as '%s'"
msgstr ""
#: ccdfunc.c:324
#: ccdfunc.c:278
msgid "Error saving file"
msgstr ""
#: ccdfunc.c:401
#: ccdfunc.c:356
#, c-format
msgid "Image stat:\n"
msgstr ""
#: ccdfunc.c:409
#: ccdfunc.c:365
msgid "Focuser device not pointed"
msgstr ""
#: ccdfunc.c:416
#: ccdfunc.c:372
msgid "No focusers found"
msgstr ""
#: ccdfunc.c:447
#: ccdfunc.c:403
#, c-format
msgid "Found %d focusers, you point number %d"
msgstr ""
#: ccdfunc.c:451
#: ccdfunc.c:407
msgid "Can't set active focuser number"
msgstr ""
#: ccdfunc.c:465
#: ccdfunc.c:421
msgid "Can't get focuser limit positions"
msgstr ""
#: ccdfunc.c:472
#: ccdfunc.c:428
msgid "Can't get current focuser position"
msgstr ""
#: ccdfunc.c:486
#: ccdfunc.c:442
#, c-format
msgid "Can't set position %g: out of limits [%g, %g]"
msgstr ""
#: ccdfunc.c:490
#: ccdfunc.c:446
msgid "Can't home focuser"
msgstr ""
#: ccdfunc.c:492
#: ccdfunc.c:448
#, c-format
msgid "Can't set position %g"
msgstr ""
#: ccdfunc.c:500
#: ccdfunc.c:456
msgid "cc_Wheel device not pointed"
msgstr ""
#: ccdfunc.c:507
#: ccdfunc.c:463
msgid "No wheels found"
msgstr ""
#: ccdfunc.c:538
#: ccdfunc.c:494
#, c-format
msgid "Found %d wheels, you point number %d"
msgstr ""
#: ccdfunc.c:542
#: ccdfunc.c:498
msgid "Can't set active wheel number"
msgstr ""
#: ccdfunc.c:558
#: ccdfunc.c:514
msgid "Can't get max wheel position"
msgstr ""
#: ccdfunc.c:565
#: ccdfunc.c:521
#, c-format
msgid "cc_Wheel position should be from 0 to %d"
msgstr ""
#: ccdfunc.c:569
#: ccdfunc.c:525
#, c-format
msgid "Can't set wheel position %d"
msgstr ""
#: ccdfunc.c:586
#: ccdfunc.c:542
#, c-format
msgid "%.1f seconds till exposition ends"
msgstr ""
#: ccdfunc.c:601
#: ccdfunc.c:557
msgid "Camera device not pointed"
msgstr ""
#: ccdfunc.c:608 ccdfunc.c:609
#: ccdfunc.c:564 ccdfunc.c:565
msgid "No cameras found"
msgstr ""
#: ccdfunc.c:639
#: ccdfunc.c:595
#, c-format
msgid "Found %d cameras, you point number %d"
msgstr ""
#: ccdfunc.c:643
#: ccdfunc.c:599
msgid "Can't set active camera number"
msgstr ""
#: ccdfunc.c:649
#: ccdfunc.c:605
msgid "Camera plugin have no custom commands"
msgstr ""
#: ccdfunc.c:618
msgid "Can't set fan speed"
msgstr ""
#: ccdfunc.c:650
#: ccdfunc.c:619
#, c-format
msgid "Set fan speed to %d"
msgstr ""
#: ccdfunc.c:655
#: ccdfunc.c:624
#, c-format
msgid "Camera model: %s"
msgstr ""
#: ccdfunc.c:656
#: ccdfunc.c:625
#, c-format
msgid "Pixel size: %g x %g"
msgstr ""
#: ccdfunc.c:662
#: ccdfunc.c:631
#, c-format
msgid "Full array: %s"
msgstr ""
#: ccdfunc.c:665
#: ccdfunc.c:634
#, c-format
msgid "Field of view: %s"
msgstr ""
#: ccdfunc.c:668
#: ccdfunc.c:637
#, c-format
msgid "Current format: %s"
msgstr ""
#: ccdfunc.c:671
#: ccdfunc.c:640
#, c-format
msgid "Can't set T to %g degC"
msgstr ""
#: ccdfunc.c:679
#: ccdfunc.c:648
#, c-format
msgid "Shutter command: %s\n"
msgstr ""
#: ccdfunc.c:681
#: ccdfunc.c:650
#, c-format
msgid "Can't run shutter command %s (unsupported?)"
msgstr ""
#. "Попытка сконфигурировать порт I/O как %d\n"
#: ccdfunc.c:685
#: ccdfunc.c:654
#, c-format
msgid "Try to configure I/O port as %d"
msgstr ""
#: ccdfunc.c:687
#: ccdfunc.c:656
msgid "Can't configure (unsupported?)"
msgstr ""
#: ccdfunc.c:694
#: ccdfunc.c:663
msgid "Can't get IOport state (unsupported?)"
msgstr ""
#. "Попытка записи %d в порт I/O\n"
#: ccdfunc.c:698
#: ccdfunc.c:667
#, c-format
msgid "Try to write %d to I/O port"
msgstr ""
#: ccdfunc.c:700
#: ccdfunc.c:669
msgid "Can't set IOport"
msgstr ""
#: ccdfunc.c:707
#: ccdfunc.c:676
#, c-format
msgid "Set gain to %g"
msgstr ""
#: ccdfunc.c:708
#: ccdfunc.c:677
#, c-format
msgid "Can't set gain to %g"
msgstr ""
#: ccdfunc.c:713
#: ccdfunc.c:682
#, c-format
msgid "Set brightness to %g"
msgstr ""
#: ccdfunc.c:714
#: ccdfunc.c:683
#, c-format
msgid "Can't set brightness to %g"
msgstr ""
#: ccdfunc.c:720 server.c:264
#: ccdfunc.c:689 server.c:265
#, c-format
msgid "Can't set binning %dx%d"
msgstr ""
#: ccdfunc.c:732 server.c:265
#: ccdfunc.c:701 server.c:266
msgid "Can't set given geometry"
msgstr ""
#: ccdfunc.c:736
#: ccdfunc.c:705
#, c-format
msgid "Can't set %d flushes"
msgstr ""
#: ccdfunc.c:740
#: ccdfunc.c:709
#, c-format
msgid "Can't set exposure time to %f seconds"
msgstr ""
#: ccdfunc.c:743
#: ccdfunc.c:712
msgid "Can't change frame type"
msgstr ""
#: ccdfunc.c:746
#: ccdfunc.c:715
msgid "Can't set bit depth"
msgstr ""
#: ccdfunc.c:748
#: ccdfunc.c:717
msgid "Can't set readout speed"
msgstr ""
#: ccdfunc.c:749
#: ccdfunc.c:718
#, c-format
msgid "Readout mode: %s"
msgstr ""
#: ccdfunc.c:750
#: ccdfunc.c:719
msgid "Only show statistics"
msgstr ""
#. GET binning should be AFTER setgeometry!
#: ccdfunc.c:752
#: ccdfunc.c:721
msgid "Can't get current binning"
msgstr ""
#. Захват кадра %d\n
#: ccdfunc.c:777
#: ccdfunc.c:746
#, c-format
msgid "Capture frame %d"
msgstr ""
#: ccdfunc.c:779 ccdfunc.c:853 server.c:148
#: ccdfunc.c:748 ccdfunc.c:823 server.c:150
msgid "Can't start exposition"
msgstr ""
#: ccdfunc.c:784
#: ccdfunc.c:753
msgid "Can't capture image"
msgstr ""
#: ccdfunc.c:787
#: ccdfunc.c:756
msgid "Read grabbed image"
msgstr ""
#: ccdfunc.c:791 ccdfunc.c:866
#: ccdfunc.c:760 ccdfunc.c:836
msgid "Can't grab image"
msgstr ""
#. %d секунд до окончания паузы\n
#: ccdfunc.c:803 client.c:270
#: ccdfunc.c:773 client.c:271
#, c-format
msgid "%d seconds till pause ends\n"
msgstr ""
#: ccdfunc.c:864
#: ccdfunc.c:834
msgid "Some error when capture"
msgstr ""
#: server.c:188
#: server.c:189
msgid "No camera device"
msgstr ""
#: client.c:255
#: client.c:256
msgid "Can't make exposition"
msgstr ""
#: client.c:286
#: client.c:287
msgid "Server timeout"
msgstr ""

View File

@ -7,7 +7,7 @@
msgid ""
msgstr "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-01-24 11:35+0300\n"
"POT-Creation-Date: 2024-02-01 14:35+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\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-Transfer-Encoding: 8bit\n"
#: ccdfunc.c:586
#: ccdfunc.c:542
#, c-format
msgid "%.1f seconds till exposition ends"
msgstr "%.1f ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÜËÓÐÏÚÉÃÉÉ"
#. %d Ñ<>екунд до окончаниÑ<C2B8> паузы\n
#: ccdfunc.c:803 client.c:270
#: ccdfunc.c:773 client.c:271
#, c-format
msgid "%d seconds till pause ends\n"
msgstr "%d ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÐÁÕÚÙ\n"
@ -31,65 +31,69 @@ msgstr "%d
msgid "Already initialized!"
msgstr "õÖÅ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÎÏ!"
#: cmdlnopts.c:97
#: cmdlnopts.c:103
msgid "CMOS brightness level"
msgstr "ÕÒÏ×ÅÎØ ÑÒËÏÓÔÉ CMOS"
#: cmdlnopts.c:96
#: cmdlnopts.c:102
msgid "CMOS gain level"
msgstr "ÕÒÏ×ÅÎØ Gain CMOS"
#: ccdfunc.c:601
#: ccdfunc.c:557
msgid "Camera device not pointed"
msgstr "õÓÔÒÏÊÓÔ×Ï Ó×ÅÏÐÒÉÅÍÎÉËÁ ÎÅ ÐÏÄËÌÀÞÅÎÏ"
#: ccdfunc.c:138
#: ccdfunc.c:197
msgid "Camera device unknown"
msgstr "õÓÔÒÏÊÓÔ×Ï Ó×ÅÏÐÒÉÅÍÎÉËÁ ÎÅ ÏÐÏÚÎÁÎÏ"
#: ccdfunc.c:655
#: ccdfunc.c:624
#, c-format
msgid "Camera model: %s"
msgstr "íÏÄÅÌØ Ó×ÅÔÏÐÒÉÅÍÎÉËÁ: %s"
#: ccdfunc.c:784
#: ccdfunc.c:605
msgid "Camera plugin have no custom commands"
msgstr ""
#: ccdfunc.c:753
msgid "Can't capture image"
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
#: ccdfunc.c:743
#: ccdfunc.c:712
msgid "Can't change frame type"
msgstr "îÅ ÍÏÇÕ ÉÚÍÅÎÉÔØ ÔÉÐ ËÁÄÒÁ"
#: ccdfunc.c:687
#: ccdfunc.c:656
msgid "Can't configure (unsupported?)"
msgstr "îÅ ÍÏÇÕ ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ (ÏÐÃÉÑ ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)"
#: ccdfunc.c:694
#: ccdfunc.c:663
msgid "Can't get IOport state (unsupported?)"
msgstr "îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÓÏÓÔÏÑÎÉÅ ÐÏÒÔÁ I/O (ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)"
#. GET binning should be AFTER setgeometry!
#: ccdfunc.c:752
#: ccdfunc.c:721
msgid "Can't get current binning"
msgstr "îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÔÅËÕÝÅÅ ÚÎÁÞÅÎÉÅ ÂÉÎÎÉÎÇÁ"
#: ccdfunc.c:472
#: ccdfunc.c:428
msgid "Can't get current focuser position"
msgstr "îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÔÅËÕÝÕÀ ÐÏÚÉÃÉÀ ÆÏËÕÓÅÒÁ"
#: ccdfunc.c:465
#: ccdfunc.c:421
msgid "Can't get focuser limit positions"
msgstr "îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÐÒÅÄÅÌØÎÕÀ ÐÏÚÉÃÉÀ ÆÏËÕÓÅÒÁ"
#: ccdfunc.c:558
#: ccdfunc.c:514
msgid "Can't get max wheel position"
msgstr "îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÐÒÅÄÅÌØÎÕÀ ÐÏÚÉÃÉÀ ËÏÌÅÓÁ"
#: ccdfunc.c:791 ccdfunc.c:866
#: ccdfunc.c:760 ccdfunc.c:836
msgid "Can't grab image"
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
#: ccdfunc.c:490
#: ccdfunc.c:446
msgid "Can't home focuser"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÆÏËÕÓÅÒ × ÎÕÌØ"
@ -97,7 +101,7 @@ msgstr "
msgid "Can't init mutex!"
msgstr "îÅ ÍÏÇÕ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÔØ ÍØÀÔÅËÓ!"
#: client.c:255
#: client.c:256
msgid "Can't make exposition"
msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ ÜËÓÐÏÚÉÃÉÀ"
@ -105,110 +109,110 @@ msgstr "
msgid "Can't open OpenGL window, image preview will be inaccessible"
msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ ÏËÎÏ OpenGL, ÏÔÏÂÒÁÖÅÎÉÅ ÂÕÄÅÔ ÎÅÄÏÓÔÕÐÎÏ"
#: ccdfunc.c:681
#: ccdfunc.c:650
#, c-format
msgid "Can't run shutter command %s (unsupported?)"
msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ ËÏÍÁÎÄÕ ÚÁÔ×ÏÒÁ %s (ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)"
#. Ð<>е могу Ñ<>охраниÑÑŒ файл
#: ccdfunc.c:162
#: ccdfunc.c:221
#, c-format
msgid "Can't save file with prefix %s"
msgstr "îÅ ÍÏÇÕ ÓÏÈÒÁÎÉÔØ ÆÁÊÌ Ó ÐÒÅÆÉËÓÏÍ %s"
#: ccdfunc.c:736
#: ccdfunc.c:705
#, c-format
msgid "Can't set %d flushes"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ %d ÓÂÒÏÓÏ×"
#: ccdfunc.c:700
#: ccdfunc.c:669
msgid "Can't set IOport"
msgstr "îÅ ÍÏÇÕ ÐÏÍÅÎÑÔØ ÚÎÁÞÅÎÉÑ ÐÏÒÔÁ I/O"
#: ccdfunc.c:671
#: ccdfunc.c:640
#, c-format
msgid "Can't set T to %g degC"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÔÅÍÐÅÒÁÔÕÒÕ × %g ÇÒÁÄã"
#: ccdfunc.c:643
#: ccdfunc.c:599
msgid "Can't set active camera number"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÊ ËÁÍÅÒÙ"
#: ccdfunc.c:451
#: ccdfunc.c:407
msgid "Can't set active focuser number"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÇÏ ÆÏËÕÓÅÒÁ"
#: ccdfunc.c:542
#: ccdfunc.c:498
msgid "Can't set active wheel number"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÇÏ ËÏÌÅÓÁ"
#: ccdfunc.c:720 server.c:264
#: ccdfunc.c:689 server.c:265
#, c-format
msgid "Can't set binning %dx%d"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÂÉÎÎÉÎÇ %dx%d"
#: ccdfunc.c:746
#: ccdfunc.c:715
msgid "Can't set bit depth"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÒÁÚÒÑÄÎÏÓÔØ áãð"
#: ccdfunc.c:714
#: ccdfunc.c:683
#, c-format
msgid "Can't set brightness to %g"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÑÒËÏÓÔØ × %g"
#: ccdfunc.c:740
#: ccdfunc.c:709
#, c-format
msgid "Can't set exposure time to %f seconds"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÜËÓÐÏÚÉÃÉÀ × %f ÓÅËÕÎÄ"
#: ccdfunc.c:649
#: ccdfunc.c:618
msgid "Can't set fan speed"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ×ÅÎÔÉÌÑÔÏÒÏ×"
#: ccdfunc.c:708
#: ccdfunc.c:677
#, c-format
msgid "Can't set gain to %g"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ Gain × %g"
#: ccdfunc.c:732 server.c:265
#: ccdfunc.c:701 server.c:266
msgid "Can't set given geometry"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÇÅÏÍÅÔÒÉÀ"
#: ccdfunc.c:492
#: ccdfunc.c:448
#, c-format
msgid "Can't set position %g"
msgstr "îÅ ÍÏÇÕ ÉÚÍÅÎÉÔØ ÐÏÚÉÃÉÀ ÎÁ %g"
#: ccdfunc.c:486
#: ccdfunc.c:442
#, c-format
msgid "Can't set position %g: out of limits [%g, %g]"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÐÏÚÉÃÉÀ %g: ×ÎÅ ÐÒÅÄÅÌÏ× [%g, %g]"
#: ccdfunc.c:748
#: ccdfunc.c:717
msgid "Can't set readout speed"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ÓÞÉÔÙ×ÁÎÉÑ"
#: ccdfunc.c:569
#: ccdfunc.c:525
#, c-format
msgid "Can't set wheel position %d"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÐÏÌÏÖÅÎÉÅ ËÏÌÅÓÁ %d"
#: ccdfunc.c:779 ccdfunc.c:853 server.c:148
#: ccdfunc.c:748 ccdfunc.c:823 server.c:150
msgid "Can't start exposition"
msgstr "îÅ ÍÏÇÕ ÎÁÞÁÔØ ÜËÓÐÏÚÉÃÉÀ"
#. Захват кадра %d\n
#: ccdfunc.c:777
#: ccdfunc.c:746
#, c-format
msgid "Capture frame %d"
msgstr "úÁÈ×ÁÔ ËÁÄÒÁ %d"
#: ccdfunc.c:668
#: ccdfunc.c:637
#, c-format
msgid "Current format: %s"
msgstr ""
#: cmdlnopts.c:112
#: cmdlnopts.c:118
msgid "Display image in OpenGL window"
msgstr "ïÔÏÂÒÁÖÅÎÉÅ ÉÚÏÂÒÁÖÅÎÉÑ × ÏËÎÅ OpenGL"
@ -217,40 +221,40 @@ msgstr "
msgid "Equalization of histogram: %s"
msgstr "üË×ÁÌÉÚÁÃÉÑ ÇÉÓÔÏÇÒÁÍÍÙ: %s"
#: ccdfunc.c:324
#: ccdfunc.c:278
msgid "Error saving file"
msgstr "ïÛÉÂËÁ ÓÏÈÒÁÎÅÎÉÑ ÆÁÊÌÁ"
#: ccdfunc.c:665
#: ccdfunc.c:634
#, c-format
msgid "Field of view: %s"
msgstr "ðÏÌÅ ÚÒÅÎÉÑ: %s"
#: ccdfunc.c:315
#: ccdfunc.c:269
#, c-format
msgid "File saved as '%s'"
msgstr "æÁÊÌ ÓÏÈÒÁÎÅÎ ËÁË '%s'"
#: ccdfunc.c:409
#: ccdfunc.c:365
msgid "Focuser device not pointed"
msgstr "õÓÔÒÏÊÓÔ×Ï ÆÏËÕÓÅÒÁ ÎÅ ÕËÁÚÁÎÏ"
#: ccdfunc.c:639
#: ccdfunc.c:595
#, c-format
msgid "Found %d cameras, you point number %d"
msgstr "ïÂÎÁÒÕÖÅÎÏ %d ËÁÍÅÒ, ×Ù ÕËÁÚÁÌÉ %d"
#: ccdfunc.c:447
#: ccdfunc.c:403
#, c-format
msgid "Found %d focusers, you point number %d"
msgstr "ïÂÎÁÒÕÖÅÎÏ %d ÆÏËÕÓÅÒÏ×, ×Ù ÕËÁÚÁÌÉ %d"
#: ccdfunc.c:538
#: ccdfunc.c:494
#, c-format
msgid "Found %d wheels, you point number %d"
msgstr "ïÂÎÁÒÕÖÅÎÏ %d ËÏÌÅÓ, ×Ù ÕËÁÚÁÌÉ %d"
#: ccdfunc.c:662
#: ccdfunc.c:631
#, c-format
msgid "Full array: %s"
msgstr "ðÏÌÎÙÊ ÆÏÒÍÁÔ: %s"
@ -260,240 +264,245 @@ msgstr "
msgid "Histogram conversion: %s"
msgstr "ðÒÅÏÂÒÁÚÏ×ÁÎÉÅ ÇÉÓÔÏÇÒÁÍÍÙ: %s"
#: cmdlnopts.c:102
#: cmdlnopts.c:108
#, fuzzy
msgid "INET image socket port"
msgstr "ÐÏÒÔ ÌÏËÁÌØÎÏÇÏ ÓÅÔÅ×ÏÇÏ ÓÏËÅÔÁ"
#: ccdfunc.c:401
#: ccdfunc.c:356
#, c-format
msgid "Image stat:\n"
msgstr "óÔÁÔÉÓÔÉËÁ ÐÏ ÉÚÏÂÒÁÖÅÎÉÀ: \n"
#: cmdlnopts.c:69
#: cmdlnopts.c:75
msgid "N flushes before exposing (default: 1)"
msgstr "N ÚÁÓ×ÅÞÉ×ÁÎÉÊ ÐÅÒÅÄ ÜËÓÐÏÚÉÃÉÅÊ (ÐÏ ÕÍÏÌÞÁÎÉÀ: 1)"
#: server.c:188
#: server.c:189
msgid "No camera device"
msgstr "îÅ ÕËÁÚÁÎÏ ÕÓÔÒÏÊÓÔ×Ï ËÁÍÅÒÙ"
#: ccdfunc.c:608 ccdfunc.c:609
#: ccdfunc.c:564 ccdfunc.c:565
msgid "No cameras found"
msgstr "ëÁÍÅÒ ÎÅ ÏÂÎÁÒÕÖÅÎÏ"
#: ccdfunc.c:416
#: ccdfunc.c:372
msgid "No focusers found"
msgstr "æÏËÕÓÅÒÏ× ÎÅ ÏÂÎÁÒÕÖÅÎÏ"
#: ccdfunc.c:507
#: ccdfunc.c:463
msgid "No wheels found"
msgstr "ôÕÒÅÌÅÊ ÎÅ ÏÂÎÁÒÕÖÅÎÏ"
#: ccdfunc.c:750
#: ccdfunc.c:719
msgid "Only show statistics"
msgstr "ôÏÌØËÏ ÏÔÏÂÒÁÚÉÔØ ÓÔÁÔÉÓÔÉËÕ"
#: ccdfunc.c:656
#: ccdfunc.c:625
#, c-format
msgid "Pixel size: %g x %g"
msgstr "òÁÚÍÅÒ ÐÉËÓÅÌÑ: %g x %g"
#: ccdfunc.c:787
#: ccdfunc.c:756
msgid "Read grabbed image"
msgstr "óÞÉÔÙ×ÁÎÉÅ ÉÚÏÂÒÁÖÅÎÉÑ"
#: ccdfunc.c:749
#: ccdfunc.c:718
#, c-format
msgid "Readout mode: %s"
msgstr "òÅÖÉÍ ÓÞÉÔÙ×ÁÎÉÑ: %s"
#: client.c:286
#: client.c:287
msgid "Server timeout"
msgstr "ôÁÊÍÁÕÔ ÓÅÒ×ÅÒÁ"
#: ccdfunc.c:713
#: ccdfunc.c:682
#, c-format
msgid "Set brightness to %g"
msgstr "õÓÔÁÎÏ×ÉÔØ ÑÒËÏÓÔØ × %g"
#: ccdfunc.c:650
#: ccdfunc.c:619
#, c-format
msgid "Set fan speed to %d"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ×ÅÎÔÉÌÑÔÏÒÏ× × %d"
#: ccdfunc.c:707
#: ccdfunc.c:676
#, c-format
msgid "Set gain to %g"
msgstr "õÓÔÁÎÏ×ÉÔØ Gain × %g"
#: ccdfunc.c:679
#: ccdfunc.c:648
#, c-format
msgid "Shutter command: %s\n"
msgstr "ëÏÍÁÎÄÁ ÚÁÔ×ÏÒÁ: %s\n"
#: ccdfunc.c:864
#: ccdfunc.c:834
msgid "Some error when capture"
msgstr ""
#. "Попытка Ñ<>конфигурироваÑÑŒ порт I/O как %d\n"
#: ccdfunc.c:685
#: ccdfunc.c:654
#, c-format
msgid "Try to configure I/O port as %d"
msgstr "ðÏÐÙÔËÁ ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ ÐÏÒÔ I/O ËÁË %d"
#. "Попытка запиÑ<C2B8>и %d в порт I/O\n"
#: ccdfunc.c:698
#: ccdfunc.c:667
#, c-format
msgid "Try to write %d to I/O port"
msgstr "ðÏÐÙÔËÁ ÚÁÐÉÓÉ %d × ÐÏÒÔ I/O"
#: cmdlnopts.c:100
#: cmdlnopts.c:106
#, fuzzy
msgid "UNIX socket name (command socket)"
msgstr "éÍÑ UNIX-ÓÏËÅÔÁ"
#: cmdlnopts.c:76
#: cmdlnopts.c:82
msgid "absolute (not divided by binning!) frame X0 coordinate (-1 - all "
"with overscan)"
msgstr "ÁÂÓÏÌÀÔÎÁÑ (ÎÅ ÄÅÌÅÎÎÁÑ ÎÁ ÂÉÎÎÉÎÇ!) ËÏÏÒÄÉÎÁÔÁ X0 (-1 - ×ËÌÀÞÁÑ "
"Ï×ÅÒÓËÁÎ)"
#: cmdlnopts.c:78
#: cmdlnopts.c:84
msgid "absolute frame X1 coordinate (-1 - all with overscan)"
msgstr "ÁÂÓÏÌÀÔÎÁÑ ËÏÏÒÄÉÎÁÔÁ X1 (-1 - ×ËÌÀÞÁÑ Ï×ÅÒÓËÁÎ)"
#: cmdlnopts.c:77
#: cmdlnopts.c:83
msgid "absolute frame Y0 coordinate (-1 - all with overscan)"
msgstr "ÁÂÓÏÌÀÔÎÁÑ ËÏÏÒÄÉÎÁÔÁ Y0 (-1 - ×ËÌÀÞÁÑ Ï×ÅÒÓËÁÎ)"
#: cmdlnopts.c:79
#: cmdlnopts.c:85
msgid "absolute frame Y1 coordinate (-1 - all with overscan)"
msgstr "ÁÂÓÏÌÀÔÎÁÑ ËÏÏÒÄÉÎÁÔÁ Y1 (-1 - ×ËÌÀÞÁÑ Ï×ÅÒÓËÁÎ)"
#: cmdlnopts.c:65
#: cmdlnopts.c:71
msgid "add records to header from given file[s]"
msgstr "ÄÏÂÁ×ÉÔØ ÚÁÐÉÓÉ Ë ÛÁÐËÅ FITS-ÆÁÊÌÁ ÉÚ ÚÁÄÁÎÎÙÈ ÆÁÊÌÏ×"
#: cmdlnopts.c:47
#: cmdlnopts.c:53
msgid "camera device number (if many: 0, 1, 2 etc)"
msgstr "ÎÏÍÅÒ ÕÓÔÒÏÊÓÔ×Á ËÁÍÅÒÙ"
#: cmdlnopts.c:43
#: cmdlnopts.c:49
msgid "camera device plugin (e.g. devfli.so)"
msgstr "ÐÌÁÇÉÎ ËÁÍÅÒÙ (ÎÁÐÒÉÍÅÒ, devfli.so)"
#: cmdlnopts.c:75
#: cmdlnopts.c:81
msgid "cancel current exposition"
msgstr "ÏÔÍÅÎÁ ÔÅËÕÝÅÊ ÜËÓÐÏÚÉÃÉÉ"
#: ccdfunc.c:500
#: ccdfunc.c:456
#, fuzzy
msgid "cc_Wheel device not pointed"
msgstr "õÓÔÒÏÊÓÔ×Ï ÔÕÒÅÌÉ ÎÅ ÕËÁÚÁÎÏ"
#: ccdfunc.c:565
#: ccdfunc.c:521
#, fuzzy, c-format
msgid "cc_Wheel position should be from 0 to %d"
msgstr "ðÏÚÉÃÉÑ ËÏÌÅÓÁ ÄÏÌÖÎÁ ÂÙÔØ ÏÔ 0 ÄÏ %d"
#: cmdlnopts.c:82
#: cmdlnopts.c:88
msgid "close shutter"
msgstr "ÚÁËÒÙÔØ ÚÁÔ×ÏÒ"
#: cmdlnopts.c:42
#: cmdlnopts.c:47
msgid "common device plugin (e.g devfli.so)"
msgstr "ÏÂÝÉÊ ÐÌÁÇÉÎ ÄÌÑ ×ÓÅÈ ÕÓÔÒÏÊÓÔ× (ÎÁÐÒÉÍÅÒ, devfli.so)"
#: cmdlnopts.c:89
#: cmdlnopts.c:95
msgid "configure I/O port pins to given value (decimal number, pin1 is LSB, "
"1 == output, 0 == input)"
msgstr "ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ ÐÏÒÔ I/O × ÚÁÄÁÎÎÏÅ ÓÏÓÔÏÑÎÉÅ (ÄÅÓÑÔÉÞÎÏÅ ÞÉÓÌÏ, "
"pin1 - ÍÌÁÄÛÉÊ ÂÉÔ, 1 - ×ÙÈÏÄ, 0 - ×ÈÏÄ)"
#: cmdlnopts.c:55
#: cmdlnopts.c:48
#, fuzzy
msgid "custom camera device plugin command"
msgstr "ÐÌÁÇÉÎ ËÁÍÅÒÙ (ÎÁÐÒÉÍÅÒ, devfli.so)"
#: cmdlnopts.c:61
msgid "fast readout mode"
msgstr "ÂÙÓÔÒÙÊ ÒÅÖÉÍ ÓÞÉÔÙ×ÁÎÉÑ"
#: cmdlnopts.c:48
#: cmdlnopts.c:54
msgid "filter wheel device number (if many: 0, 1, 2 etc)"
msgstr "ÎÏÍÅÒ ÕÓÔÒÏÊÓÔ×Á ÔÕÒÅÌÉ"
#: cmdlnopts.c:49
#: cmdlnopts.c:55
msgid "focuser device number (if many: 0, 1, 2 etc)"
msgstr "ÎÏÍÅÒ ÕÓÔÒÏÊÓÔ×Á ÆÏËÕÓÅÒÁ"
#: cmdlnopts.c:44
#: cmdlnopts.c:50
msgid "focuser device plugin (e.g. devzwo.so)"
msgstr "ÐÌÁÇÉÎ ÆÏËÕÓÅÒÁ (ÎÁÐÒÉÍÅÒ, devzwo.so)"
#: cmdlnopts.c:108
#: cmdlnopts.c:114
msgid "force using image through socket transition even if can use SHM)"
msgstr ""
#: cmdlnopts.c:85
#: cmdlnopts.c:91
msgid "get value of I/O port pins"
msgstr "ÐÏÌÕÞÉÔØ ÚÎÁÞÅÎÉÅ ÐÏÒÔÁ I/O"
#: cmdlnopts.c:70
#: cmdlnopts.c:76
msgid "horizontal binning to N pixels"
msgstr "ÇÏÒÉÚÏÎÔÁÌØÎÙÊ ÂÉÎÎÉÎÇ × N ÐÉËÓÅÌÅÊ"
#: cmdlnopts.c:61
#: cmdlnopts.c:67
msgid "instrument name"
msgstr "ÎÁÚ×ÁÎÉÅ ÐÒÉÂÏÒÁ"
#: cmdlnopts.c:46
#: cmdlnopts.c:52
msgid "list connected devices"
msgstr "ÓÐÉÓÏË ÐÏÄËÌÀÞÅÎÎÙÈ ÕÓÔÒÏÊÓÔ×"
#: cmdlnopts.c:101
#: cmdlnopts.c:107
#, fuzzy
msgid "local INET command socket port"
msgstr "ÐÏÒÔ ÌÏËÁÌØÎÏÇÏ ÓÅÔÅ×ÏÇÏ ÓÏËÅÔÁ"
#: cmdlnopts.c:99
#: cmdlnopts.c:105
msgid "logging file name (if run as server)"
msgstr "ÉÍÑ ÆÁÊÌÁ ÌÏÇÇÉÒÏ×ÁÎÉÑ (ÅÓÌÉ ÚÁÐÕÝÅÎ ÓÅÒ×ÅÒ)"
#: cmdlnopts.c:73
#: cmdlnopts.c:79
msgid "make pause for N seconds between expositions"
msgstr "ÐÁÕÚÁ × N ÓÅËÕÎÄ ÍÅÖÄÕ ÜËÓÐÏÚÉÃÉÑÍÉ"
#: cmdlnopts.c:72
#: cmdlnopts.c:78
msgid "make series of N frames"
msgstr "ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÓÔØ ÉÚ N ËÁÄÒÏ×"
#: cmdlnopts.c:91
#: cmdlnopts.c:97
msgid "move focuser to absolute position, mm"
msgstr "ÐÅÒÅÍÅÓÔÉÔØ ÆÏËÕÓÅÒ × ÁÂÓÏÌÀÔÎÏÅ ÐÏÌÏÖÅÎÉÅ, ÍÍ"
#: cmdlnopts.c:92
#: cmdlnopts.c:98
msgid "move focuser to relative position, mm (only for standalone)"
msgstr "ÐÅÒÅÍÅÓÔÉÔØ ÆÏËÕÓÅÒ × ÏÔÎÏÓÉÔÅÌØÎÏÅ ÐÏÌÏÖÅÎÉÅ, ÍÍ (ÎÅ ÄÌÑ ÓÅÒ×ÅÒ/"
"ËÌÉÅÎÔ)"
#: cmdlnopts.c:86
#: cmdlnopts.c:92
msgid "move stepper motor asynchronous"
msgstr "ÁÓÉÎÈÒÏÎÎÏÅ Ä×ÉÖÅÎÉÅ ÛÁÇÏ×ÏÇÏ Ä×ÉÇÁÔÅÌÑ"
#: cmdlnopts.c:53
#: cmdlnopts.c:59
msgid "not open shutter, when exposing (\"dark frames\")"
msgstr "ÎÅ ÏÔËÒÙ×ÁÔØ ÚÁÔ×ÏÒ ÐÒÉ ÜËÓÐÏÚÉÃÉÉ (\"ÔÅÍÎÏ×ÙÅ\")"
#: cmdlnopts.c:62
#: cmdlnopts.c:68
msgid "object name"
msgstr "ÎÁÚ×ÁÎÉÅ ÏÂßÅËÔÁ"
#: cmdlnopts.c:60
#: cmdlnopts.c:66
msgid "object type (neon, object, flat etc)"
msgstr "ÔÉÐ ÏÂßÅËÔÁ (neon, object, flat É Ô.Ä.)"
#: cmdlnopts.c:63
#: cmdlnopts.c:69
msgid "observers' names"
msgstr "ÉÍÅÎÁ ÎÁÂÌÀÄÁÔÅÌÅÊ"
#: cmdlnopts.c:64
#: cmdlnopts.c:70
msgid "observing program name"
msgstr "ÎÁÚ×ÁÎÉÅ ÐÒÏÇÒÁÍÍÙ"
@ -505,91 +514,91 @@ msgstr "
msgid "on"
msgstr "×ËÌ"
#: cmdlnopts.c:81
#: cmdlnopts.c:87
msgid "open shutter"
msgstr "ÏÔËÒÙÔØ ÚÁÔ×ÏÒ"
#: cmdlnopts.c:66
#: cmdlnopts.c:72
msgid "output file name"
msgstr "ÉÍÑ ÆÁÊÌÁ"
#: cmdlnopts.c:104
#: cmdlnopts.c:110
msgid "passive viewer (only get last images)"
msgstr ""
#: cmdlnopts.c:59
#: cmdlnopts.c:65
msgid "program author"
msgstr "Á×ÔÏÒ ÐÒÏÇÒÁÍÍÙ"
#: cmdlnopts.c:105
#: cmdlnopts.c:111
msgid "restart image server"
msgstr "ÐÅÒÅÚÁÐÕÓË ÓÅÒ×ÅÒÁ"
#: cmdlnopts.c:51
#: cmdlnopts.c:57
msgid "rewrite output file if exists"
msgstr "ÐÅÒÅÚÁÐÉÓØ ×ÙÈÏÄÎÏÇÏ ÆÁÊÌÁ"
#: cmdlnopts.c:103
#: cmdlnopts.c:109
msgid "run as client"
msgstr "ÚÁÐÕÓÔÉÔØ ËÌÉÅÎÔ"
#: cmdlnopts.c:84
#: cmdlnopts.c:90
msgid "run exposition on HIGH @ pin5 I/O port"
msgstr ""
#: cmdlnopts.c:83
#: cmdlnopts.c:89
msgid "run exposition on LOW @ pin5 I/O port"
msgstr ""
#: cmdlnopts.c:54
#: cmdlnopts.c:60
msgid "run in 8-bit mode"
msgstr "8-ÂÉÔÎÙÊ ÒÅÖÉÍ"
#: cmdlnopts.c:56
#: cmdlnopts.c:62
msgid "set CCD temperature to given value (degr C)"
msgstr "ÕÓÔÁÎÏ×ÉÔØ ÔÅÍÐÅÒÁÔÕÒÕ Ó×ÅÔÏÐÒÉÅÍÎÉËÁ (ÇÒÁÄã)"
#: cmdlnopts.c:88
#: cmdlnopts.c:94
msgid "set I/O port pins to given value (decimal number, pin1 is LSB)"
msgstr "ÕÓÔÁÎÏ×ÉÔØ ÐÏÒÔ I/O (ÄÅÓÑÔÉÞÎÏÅ ÞÉÓÌÏ, pin1 - ÍÌÁÄÛÉÊ ÂÉÔ)"
#: cmdlnopts.c:74
#: cmdlnopts.c:80
msgid "set exposure time to given value (seconds!)"
msgstr "ÕÓÔÁÎÏ×ÉÔØ ×ÒÅÍÑ ÜËÓÐÏÚÉÃÉÉ (ÓÅËÕÎÄÙ!)"
#: cmdlnopts.c:57
#: cmdlnopts.c:63
msgid "set fan speed (0 - off, 1 - low, 2 - high)"
msgstr "ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ×ÅÎÔÉÌÑÔÏÒÁ (0 - ×ÙËÌ, 1 - ÎÉÚËÁÑ, 2 - ×ÙÓÏËÁÑ)"
#: cmdlnopts.c:94
#: cmdlnopts.c:100
msgid "set wheel position"
msgstr "ÕÓÔÁÎÏ×ÉÔØ ÐÏÌÏÖÅÎÉÅ ËÏÌÅÓÁ"
#: cmdlnopts.c:107
#: cmdlnopts.c:113
msgid "shared memory (with image data) key (default: 7777777)"
msgstr ""
#: cmdlnopts.c:50
#: cmdlnopts.c:56
msgid "show this help"
msgstr "ÏÔÏÂÒÁÚÉÔØ ÜÔÕ ÓÐÒÁ×ËÕ"
#: cmdlnopts.c:109
#: cmdlnopts.c:115
msgid "start (!=0) or stop(==0) infinity capturing loop"
msgstr ""
#: cmdlnopts.c:52
#: cmdlnopts.c:58
msgid "verbose level (-V - messages, -VV - debug, -VVV - all shit)"
msgstr "ÕÒÏ×ÅÎØ ÂÏÌÔÌÉ×ÏÓÔÉ (-V - ÓÏÏÂÝÅÎÉÑ, -VV - ÏÔÌÁÄËÁ, -VVV - ×ÓÅ)"
#: cmdlnopts.c:71
#: cmdlnopts.c:77
msgid "vertical binning to N pixels"
msgstr "×ÅÒÔÉËÁÌØÎÙÊ ÂÉÎÎÉÎÇ × N ÐÉËÓÅÌÅÊ"
#: cmdlnopts.c:67
#: cmdlnopts.c:73
msgid "wait while exposition ends"
msgstr "ÖÄÁÔØ, ÐÏËÁ ÎÅ ËÏÎÞÉÔÓÑ ÜËÓÐÏÚÉÃÉÑ"
#: cmdlnopts.c:45
#: cmdlnopts.c:51
msgid "wheel device plugin (e.g. devdummy.so)"
msgstr "ÐÌÁÇÉÎ ÕÓÔÒÏÊÓÔ×Á ÔÕÒÅÌÉ (ÎÁÐÒÉÍÅÒ, devdummy.so)"

View File

@ -73,6 +73,7 @@ strpair allcommands[] = {
{ CC_CMD_FGOTO, "focuser position" },
{ CC_CMD_FRAMEFORMAT, "camera frame format (X0,Y0,X1,Y1)" },
{ CC_CMD_GAIN, "camera gain" },
{ CC_CMD_GETHEADERS, "get last file FITS headers" },
{ CC_CMD_HBIN, "horizontal binning" },
{ CC_CMD_HEADERFILES, "add FITS records from these files (comma-separated list)" },
{ CC_CMD_HELP, "show this help" },
@ -88,9 +89,10 @@ strpair allcommands[] = {
{ CC_CMD_OBJECT, "FITS 'OBJECT' field" },
{ CC_CMD_OBJTYPE, "FITS 'IMAGETYP' field" },
{ CC_CMD_OBSERVER, "FITS 'OBSERVER' field" },
{ CC_CMD_PLUGINCMD, "custom camera plugin command" },
{ CC_CMD_PROGRAM, "FITS 'PROG-ID' field" },
{ CC_CMD_RESTART, "restart server" },
{ CC_CMD_REWRITE, "rewrite file (if give `filename`, not `filenameprefix`" },
{ CC_CMD_REWRITE, "rewrite file (if give `filename`, not `filenameprefix`)" },
{ CC_CMD_SHMEMKEY, "get shared memory key" },
{ CC_CMD_SHUTTER, "camera shutter's operations" },
{ CC_CMD_CAMTEMPER, "camera chip temperature" },
@ -166,10 +168,9 @@ static inline void cameracapturestate(){ // capturing - wait for exposition ends
camstate = CAMERA_ERROR;
return;
}else{
/*if(lastfile){ (move calcstat into savefits)
TIMESTAMP("Calc stat");
calculate_stat(ima);
}*/
ima->gotstat = 0; // fresh image without statistics - recalculate when save
ima->timestamp = dtime(); // set timestamp
++ima->imnumber; // increment counter
if(saveFITS(ima, &lastfile)){
DBG("LAST file name changed");
}
@ -954,6 +955,24 @@ static cc_hresult inftyhandler(int fd, _U_ const char *key, const char *val){
return RESULT_SILENCE;
}
// custom camera plugin command
static cc_hresult pluginhandler(int fd, _U_ const char *key, const char *val){
if(!camera->plugincmd) return RESULT_BADKEY;
const char *r = camera->plugincmd(val);
if(!r) return RESULT_FAIL;
if(*r == 0) return RESULT_OK;
if(!cc_sendstrmessage(fd, r)) return RESULT_DISCONNECTED;
return RESULT_SILENCE;
}
// get headers
static cc_hresult gethdrshandler(int fd, _U_ const char *key, _U_ const char *val){
cc_charbuff *b = getFITSheader(ima);
if(!b) return RESULT_FAIL;
if(!cc_sendstrmessage(fd, b->buf)) return RESULT_DISCONNECTED;
return RESULT_SILENCE;
}
// for setters: do nothing when camera not in idle state
static int CAMbusy(){
if(camera && camstate != CAMERA_IDLE){
@ -1015,7 +1034,9 @@ static cc_handleritem items[] = {
{chkcc, fastspdhandler, CC_CMD_FASTSPD},
{chkcc, darkhandler, CC_CMD_DARK},
{chkcc, inftyhandler, CC_CMD_INFTY},
{chkcc, pluginhandler, CC_CMD_PLUGINCMD},
{NULL, tremainhandler, CC_CMD_TREMAIN},
{chkcc, gethdrshandler, CC_CMD_GETHEADERS},
{NULL, FITSparhandler, CC_CMD_AUTHOR},
{NULL, FITSparhandler, CC_CMD_INSTRUMENT},
{NULL, FITSparhandler, CC_CMD_OBSERVER},
@ -1034,6 +1055,7 @@ static cc_handleritem items[] = {
};
#define CLBUFSZ BUFSIZ
#define STRBUFSZ (255)
// send image as raw data
static void sendimage(int client){
@ -1072,11 +1094,10 @@ void server(int sock, int imsock){
}
int nfd = 2; // only two listening sockets @start: command and image
struct pollfd poll_set[CC_MAXCLIENTS+2];
cc_charbuff *buffers[CC_MAXCLIENTS];
cc_strbuff *buffers[CC_MAXCLIENTS];
for(int i = 0; i < CC_MAXCLIENTS; ++i){
buffers[i] = cc_bufnew(CLBUFSZ);
buffers[i] = cc_strbufnew(CLBUFSZ, STRBUFSZ);
}
char string[CLBUFSZ]; // string to read data from buffers
bzero(poll_set, sizeof(poll_set));
// ZERO - listening server socket
poll_set[0].fd = sock;
@ -1123,10 +1144,7 @@ void server(int sock, int imsock){
}
// process some data & send messages to ALL
if(camstate == CAMERA_FRAMERDY || camstate == CAMERA_ERROR){
if(camstate == CAMERA_FRAMERDY){
ima->timestamp = dtime(); // set timestamp
++ima->imnumber; // increment counter
}
DBG("new image: timestamp=%.1f, num=%zd", ima->timestamp, ima->imnumber);
char buff[PATH_MAX+32];
snprintf(buff, PATH_MAX, CC_CMD_EXPSTATE "=%d", camstate);
DBG("Send %s to %d clients", buff, nfd - 2);
@ -1145,15 +1163,15 @@ void server(int sock, int imsock){
for(int fdidx = 2; fdidx < nfd; ++fdidx){
if((poll_set[fdidx].revents & POLLIN) == 0) continue;
int fd = poll_set[fdidx].fd;
cc_charbuff *curbuff = buffers[fdidx-1];
cc_strbuff *curbuff = buffers[fdidx-1];
int disconnected = 0;
if(cc_read2buf(fd, curbuff)){
size_t got = cc_getline(curbuff, string, CLBUFSZ);
size_t got = cc_getline(curbuff);
if(got >= CLBUFSZ){
DBG("Client fd=%d gave buffer overflow", fd);
LOGMSG("SERVER client fd=%d buffer overflow", fd);
}else if(got){
if(!parsestring(fd, items, string)) disconnected = 1;
if(!parsestring(fd, items, curbuff->string)) disconnected = 1;
}
}else disconnected = 1;
if(disconnected){
@ -1254,4 +1272,3 @@ static int parsestring(int fd, cc_handleritem *handlers, char *str){
DBG("Command not found!");
return cc_sendstrmessage(fd, cc_hresult2str(RESULT_BADKEY));
}