Compare commits

...

6 Commits

Author SHA1 Message Date
92c3c54c65 Merge pull request #1 from thehanslevi/codex/readme-occurred-typo
Fix README typo
2026-06-19 08:32:08 +03:00
thehanslevi
94f1cf9656 Fix README typo 2026-06-18 21:16:03 -04:00
66e2bdfaac cont 2026-06-08 17:09:05 +03:00
f65daab527 next fixes 2026-06-04 18:24:26 +03:00
1f7aad348e fx 2026-06-02 18:31:17 +03:00
d355265995 start refactoring 2026-06-02 18:30:33 +03:00
16 changed files with 1117 additions and 1446 deletions

View File

@@ -49,7 +49,7 @@ static int campoll(cc_capture_status *st, float *remain){
if(capstat != CAPTURE_PROCESS){ if(capstat != CAPTURE_PROCESS){
if(st) *st = capstat; if(st) *st = capstat;
if(remain) *remain = 0.; if(remain) *remain = 0.;
return TRUE; return FALSE;
} }
if(sl_dtime() - texpstart > exptime){ if(sl_dtime() - texpstart > exptime){
if(st) *st = CAPTURE_READY; if(st) *st = CAPTURE_READY;

View File

@@ -187,7 +187,7 @@ clients connected.
When you send a command to server you will receive: When you send a command to server you will receive:
- one of answers - "OK" (all OK), "BUSY" (can't run setter because camera is busy), "FAIL" (some error - one of answers - "OK" (all OK), "BUSY" (can't run setter because camera is busy), "FAIL" (some error
occured), "BADKEY" (wrong key name) or "BADVAL" (wrong key's value) - for procedures and setters occurred), "BADKEY" (wrong key name) or "BADVAL" (wrong key's value) - for procedures and setters
(instead of "OK" you will give "parameter=value" for setter if all OK); (instead of "OK" you will give "parameter=value" for setter if all OK);
- "parameter=value" for getters. - "parameter=value" for getters.

View File

@@ -24,6 +24,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/un.h> // unix socket #include <sys/un.h> // unix socket
#include <unistd.h> #include <unistd.h>
#include <usefull_macros.h> #include <usefull_macros.h>
@@ -43,6 +44,82 @@ double __t0 = 0.;
static int ntries = 2; // amount of tries to send messages controlling the answer 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) double answer_timeout = 0.1; // timeout of waiting answer from server (not static for client.c)
static sem_t *sem = SEM_FAILED;
// client-side SHM lock
int cc_lock_shm(int isserver){
if(sem == SEM_FAILED){
DBG("Can't lock NULL");
return FALSE;
}
struct timespec ts = {.tv_sec = 0, .tv_nsec = 10000000};
DBG("Try to lock");
if(isserver){
int locked = TRUE;
while(sem_timedwait(sem, &ts) && locked){
switch(errno){
case EINTR:
DBG("Interrupt -> try to lock again");
break;
default: // timeout or other error -> force locking
DBG("Error locking -> force unlock");
locked = FALSE;
}
}
if(locked){
double t0 = sl_dtime();
while(sem_trywait(sem) && sl_dtime() - t0 < 0.1) sem_post(sem); // force locking
}
}else{
if(sem_timedwait(sem, &ts)){
DBG("Image semaphore is locked too long by other side");
return FALSE; // can't lock
}
}
DBG("Semaphore locked");
return TRUE;
}
void cc_unlock_shm(){
if(sem == SEM_FAILED){
DBG("Can't unlock NULL");
return;
}
if(sem_post(sem)){
switch(errno){
case EOVERFLOW: // already unlocked
break;
default: // not a valid? or other?
WARN("Can't unlock image semaphore");
LOGERR("Can't unlock image semaphore");
return;
}
}
DBG("Semaphore unlocked");
}
void cc_init_sem(int isserver){
if(sem != SEM_FAILED) return;
umask(0); // for read-write semaphore
// create samaphore if no
if(isserver){
sem = sem_open(SEM_NAME, O_CREAT, 0666, 1);
}else{
sem = sem_open(SEM_NAME, 0);
}
if(sem == SEM_FAILED){
LOGERR("sem_open failed: %s", strerror(errno));
}
}
void cc_remove_sem(){
if(sem == SEM_FAILED) return;
sem_close(sem);
DBG("semaphore closed\n");
if(-1 == sem_unlink(SEM_NAME))
LOGERR("Can't delete semaphore");
}
/** /**
* @brief cc_open_socket - create socket and open it * @brief cc_open_socket - create socket and open it
* @param isserver - TRUE for server, FALSE for client * @param isserver - TRUE for server, FALSE for client
@@ -134,15 +211,19 @@ int cc_senddata(int fd, void *data, size_t l){
DBG("fd=%d, l=%zd", fd, l); DBG("fd=%d, l=%zd", fd, l);
if(fd < 1 || !data || l < 1) return TRUE; // empty message if(fd < 1 || !data || l < 1) return TRUE; // empty message
DBG("send new data (size=%zd) to fd %d", l, fd); DBG("send new data (size=%zd) to fd %d", l, fd);
//strncpy((char*)data, "TEST image data\n", 17); size_t total = 0;
//l = 16; while(total < l){
if(l != (size_t)send(fd, data, l, MSG_NOSIGNAL)){ ssize_t sent = send(fd, (char*)data + total, l - total, MSG_NOSIGNAL);
WARN("write()"); if(sent <= 0){
LOGWARN("write()"); WARN("send()");
return FALSE; LOGWARN("send()");
break; // error
} }
total += sent;
}
if(total != l) return FALSE;
DBG("success"); DBG("success");
if(sl_globlog) LOGDBG("SEND data (size=%d) to fd %d", l, fd); LOGDBG("SEND data (size=%d) to fd %d", l, fd);
return TRUE; return TRUE;
} }
@@ -155,25 +236,36 @@ int cc_sendmessage(int fd, const char *msg, int l){
static int buflen = 0; static int buflen = 0;
if(l + 1 > buflen){ if(l + 1 > buflen){
buflen = 1024 * (1 + l/1024); buflen = 1024 * (1 + l/1024);
tmpbuf = realloc(tmpbuf, buflen); char *newbuf = realloc(tmpbuf, buflen);
if(!newbuf){
LOGERR("realloc())");
return FALSE;
}
tmpbuf = newbuf;
} }
DBG("send to fd %d:\n%s[%d]", fd, msg, l); DBG("send to fd %d:\n%s[%d]", fd, msg, l);
memcpy(tmpbuf, msg, l); memcpy(tmpbuf, msg, l);
if(msg[l-1] != '\n') tmpbuf[l++] = '\n'; if(msg[l-1] != '\n') tmpbuf[l++] = '\n';
if(l != send(fd, tmpbuf, l, MSG_NOSIGNAL)){ int total = 0;
WARN("write()"); while(total < l){
LOGWARN("write()"); ssize_t sent = send(fd, tmpbuf + total, l - total, MSG_NOSIGNAL);
pthread_mutex_unlock(&mutex); if(sent <= 0){
return FALSE; WARN("send()");
}else{ LOGWARN("send()");
//DBG("success"); break; // error
}
total += sent;
}
int ret = FALSE;
if(total == l){
ret = TRUE;
if(sl_globlog){ // logging turned ON if(sl_globlog){ // logging turned ON
tmpbuf[l-1] = 0; // remove trailing '\n' for logging tmpbuf[l-1] = 0; // remove trailing '\n' for logging
LOGDBG("SEND '%s'", tmpbuf); LOGDBG("SEND '%s'", tmpbuf);
} }
} }
pthread_mutex_unlock(&mutex); pthread_mutex_unlock(&mutex);
return TRUE; return ret;
} }
int cc_sendstrmessage(int fd, const char *msg){ int cc_sendstrmessage(int fd, const char *msg){
if(fd < 1 || !msg) return TRUE; // empty message if(fd < 1 || !msg) return TRUE; // empty message
@@ -230,36 +322,6 @@ char *cc_get_keyval(char **keyval){
return val; return val;
} }
/**
* 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
*/
int cc_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;
}
/** /**
* @brief cc_getshm - get shared memory segment for image * @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) * @param imsize - size of image data (in bytes): if !=0 allocate as server, else - as client (readonly)
@@ -268,7 +330,7 @@ int cc_canberead(int fd){
cc_IMG *cc_getshm(key_t key, size_t imsize){ cc_IMG *cc_getshm(key_t key, size_t imsize){
size_t shmsize = sizeof(cc_IMG) + imsize; size_t shmsize = sizeof(cc_IMG) + imsize;
shmsize = 1024 * (1 + shmsize / 1024); shmsize = 1024 * (1 + shmsize / 1024);
DBG("Allocate %zd bytes in shared memory", shmsize); DBG("Shared memory; sizeof(cc_IMG)=%zd, imsize=%zd", sizeof(cc_IMG), imsize);
int shmid = -1; int shmid = -1;
int flags = (imsize) ? IPC_CREAT | 0666 : 0; int flags = (imsize) ? IPC_CREAT | 0666 : 0;
shmid = shmget(key, 0, flags); shmid = shmget(key, 0, flags);
@@ -287,9 +349,15 @@ cc_IMG *cc_getshm(key_t key, size_t imsize){
WARN("Can't create shared memory segment %d", key); WARN("Can't create shared memory segment %d", key);
return NULL; return NULL;
} }
}else{
#ifdef EBUG
struct shmid_ds buf;
if(shmctl(shmid, IPC_STAT, &buf)) WARNX("Can't get SHM data");
else DBG("SHM size = %zd", buf.shm_segsz);
#endif
} }
flags = (imsize) ? 0 : SHM_RDONLY; // client opens memory in readonly mode flags = (imsize) ? 0 : SHM_RDONLY; // client opens memory in readonly mode
cc_IMG *ptr = shmat(shmid, NULL, flags); cc_IMG *ptr = shmat(shmid, NULL, 0);
if(ptr == (void*)-1){ if(ptr == (void*)-1){
if(imsize) WARN("Can't attach SHM segment %d", key); if(imsize) WARN("Can't attach SHM segment %d", key);
return NULL; return NULL;
@@ -453,8 +521,17 @@ int cc_read2buf(int fd, cc_strbuff *buf){
pthread_mutex_lock(&buf->mutex); pthread_mutex_lock(&buf->mutex);
if(!buf->buf || buf->buflen >= buf->bufsize) goto ret; if(!buf->buf || buf->buflen >= buf->bufsize) goto ret;
size_t maxlen = buf->bufsize - buf->buflen; size_t maxlen = buf->bufsize - buf->buflen;
ssize_t rd = read(fd, buf->buf + buf->buflen, maxlen); ssize_t rd;
if(rd <= 0) goto ret; do{
rd = read(fd, buf->buf + buf->buflen, maxlen);
if(rd <= 0){
if(errno == EINTR){
DBG("errno=%d, '%s'", errno, strerror(errno));
continue;
}
goto ret; // EAGAIN or other error -> client disconnected
}else break;
}while(1);
DBG("got %zd bytes", rd); DBG("got %zd bytes", rd);
if(rd) buf->buflen += rd; if(rd) buf->buflen += rd;
ret = TRUE; ret = TRUE;
@@ -470,7 +547,7 @@ ret:
* @return TRUE if got data * @return TRUE if got data
*/ */
int cc_refreshbuf(int fd, cc_strbuff *buf){ int cc_refreshbuf(int fd, cc_strbuff *buf){
if(!cc_canberead(fd)) return FALSE; if(!sl_canread(fd)) return FALSE;
return cc_read2buf(fd, buf); return cc_read2buf(fd, buf);
} }
@@ -548,7 +625,7 @@ static cc_hresult ask4cmd(int fd, cc_strbuff *buf, const char *cmdwargs){
if(!cc_sendstrmessage(fd, cmdwargs)) continue; if(!cc_sendstrmessage(fd, cmdwargs)) continue;
double t0 = sl_dtime(); double t0 = sl_dtime();
while(sl_dtime() - t0 < answer_timeout){ while(sl_dtime() - t0 < answer_timeout){
int r = cc_canberead(fd); int r = sl_canread(fd);
if(r == 0) continue; if(r == 0) continue;
else if(r < 0){ else if(r < 0){
LOGERR("Socket disconnected"); LOGERR("Socket disconnected");
@@ -651,54 +728,60 @@ cc_hresult cc_getfloat(int fd, cc_strbuff *cbuf, const char *cmd, float *val){
// get next record from external buffer, newlines==1 if every record ends with '\n' // 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 *cc_nextkw(char *buf, char record[FLEN_CARD], int newlines){
char *nextline = NULL; char *nextline = NULL;
int l = FLEN_CARD - 1; int l = FLEN_CARD;
if(newlines){ if(newlines){
char *e = strchr(buf, '\n'); char *e = strchr(buf, '\n');
if(e){ if(e){
if(e - buf < FLEN_CARD) l = e - buf; if(e - buf < FLEN_CARD) l = e - buf + 1;
nextline = e + 1; nextline = e + 1;
} }
}else nextline = buf + (FLEN_CARD - 1); }else nextline = buf + (FLEN_CARD - 1);
strncpy(record, buf, l); strncpy(record, buf, l);
record[l] = 0; if(l < FLEN_CARD) record[l] = 0;
return nextline; return nextline;
} }
/** /**
* @brief cc_kwfromfile - add records from file * @brief cc_kwfromfile - add records from file
* @param b - buffer to add * @param img - buffer to add
* @param filename - file name with FITS headers ('\n'-terminated or by 80 chars) * @param filename - file name with FITS headers ('\n'-terminated or by 80 chars)
* @return amount of bytes added * @return amount of bytes added
*/ */
size_t cc_kwfromfile(cc_charbuff *b, char *filename){ size_t cc_kwfromfile(cc_IMG *img, char *filename){
if(!b) return 0; if(!img) return 0;
sl_mmapbuf_t *buf = sl_mmap(filename); sl_mmapbuf_t *buf = sl_mmap(filename);
if(!buf || buf->len < 1){ if(!buf || buf->len < 1){
WARNX("Can't add FITS records from file %s", filename); WARNX("Can't add FITS records from file %s", filename);
LOGWARN("Can't add FITS records from file %s", filename); LOGWARN("Can't add FITS records from file %s", filename);
return 0; return 0;
} }
size_t blen0 = b->buflen; char rec[FLEN_CARD], card[FLEN_CARD];
char rec[FLEN_CARD+1], card[FLEN_CARD+1];
char *data = buf->data, *x = strchr(data, '\n'), *eodata = buf->data + buf->len; char *data = buf->data, *x = strchr(data, '\n'), *eodata = buf->data + buf->len;
int newlines = 0; int newlines = 0;
if(x && (x - data) < FLEN_CARD){ // we found newline -> this is a format with newlines if(x && (x - data) < FLEN_CARD){ // we found newline -> this is a format with newlines
newlines = 1; newlines = 1;
} }
size_t written = 0;
do{ do{
data = cc_nextkw(data, rec, newlines); data = cc_nextkw(data, rec, newlines);
if(data > eodata) break; if(data > eodata) break;
int status = 0, kt = 0; int status = 0, kt = 0;
fits_parse_template(rec, card, &kt, &status); fits_parse_template(rec, card, &kt, &status);
if(status) fits_report_error(stderr, status); if(status) fits_report_error(stderr, status);
else cc_charbufaddline(b, card); else{
if(img->headerstrings < FITS_HEADER_STRINGS_MAX){
++written;
snprintf(img->fitsheader[img->headerstrings++], FLEN_CARD, "%s", card);
}else break;
}
}while(data && *data); }while(data && *data);
sl_munmap(buf); sl_munmap(buf);
return b->buflen - blen0; return written;
} }
#if 0
/** /**
* @brief cc_charbuf2kw - write all keywords from `b` to file `f` * @brief cc_charbuf2kw - write all keywords from `b` to file `f`
* `b` should be prepared by cc_kwfromfile or similar * `b` should be prepared by cc_kwfromfile or similar
@@ -734,6 +817,7 @@ int cc_charbuf2kw(cc_charbuff *b, fitsfile *f){
} }
return TRUE; return TRUE;
} }
#endif
static size_t print_val(cc_partype_t t, void *val, char *buf, size_t bufl){ static size_t print_val(cc_partype_t t, void *val, char *buf, size_t bufl){
size_t l = 0; size_t l = 0;

View File

@@ -20,14 +20,21 @@
#include <fitsio.h> // FLEN_CARD #include <fitsio.h> // FLEN_CARD
#include <pthread.h> #include <pthread.h>
#include <semaphore.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> // for size_t #include <stdlib.h> // for size_t
// max strings in header
#define FITS_HEADER_STRINGS_MAX (1000)
// magic to mark our SHM // magic to mark our SHM
#define CC_SHM_MAGIC (0xdeadbeef) #define CC_SHM_MAGIC (0xdeadbeef)
// semaphore for SHM protection
#define SEM_NAME "ccdcapture"
// base image parameters - sent by socket and stored in shared memory // base image parameters - sent by socket and stored in shared memory
typedef struct __attribute__((packed, aligned(4))){ typedef struct __attribute__((packed)){
uint32_t MAGICK; // magick (DEADBEEF) - to mark our shm uint32_t MAGICK; // magick (DEADBEEF) - to mark our shm
double timestamp; // timestamp of image taken double timestamp; // timestamp of image taken
uint8_t bitpix; // bits per pixel (8 or 16) uint8_t bitpix; // bits per pixel (8 or 16)
@@ -39,6 +46,8 @@ typedef struct __attribute__((packed, aligned(4))){
size_t imnumber; // counter of images captured from server's start size_t imnumber; // counter of images captured from server's start
void *data; // pointer to data (next byte after this struct) - only for server void *data; // pointer to data (next byte after this struct) - only for server
/* `data` is uint8_t or uint16_t depending on `bitpix` */ /* `data` is uint8_t or uint16_t depending on `bitpix` */
char fitsheader[FITS_HEADER_STRINGS_MAX][FLEN_CARD]; // FITS-header for given image
size_t headerstrings; // amount of records in header
} cc_IMG; } cc_IMG;
typedef struct{ typedef struct{
@@ -192,9 +201,11 @@ typedef struct{
// wait for mutex locking // wait for mutex locking
#define CC_BUSY_TIMEOUT (1.0) #define CC_BUSY_TIMEOUT (1.0)
// wait for exposition ends (between subsequent check calls) // wait for exposition ends (between subsequent check calls)
#define CC_WAIT_TIMEOUT (2.0) #define CC_WAIT_TIMEOUT (15.0)
// client will disconnect after this time from last server message // client will disconnect after this time from last server message
#define CC_CLIENT_TIMEOUT (3.0) #define CC_CLIENT_TIMEOUT (30.0)
// minimal sleep (us) time when client waits for exp end
#define CC_IMWAIT_SLEEP (1000)
// fd - socket fd to send private messages, key, val - key and its value // 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); typedef cc_hresult (*cc_mesghandler)(int fd, const char *key, const char *val);
@@ -215,7 +226,6 @@ typedef enum{
} cc_camera_state; } cc_camera_state;
// common information about everything // common information about everything
#define CC_CMD_INFO "info"
#define CC_CMD_HELP "help" #define CC_CMD_HELP "help"
// restart server // restart server
#define CC_CMD_RESTART "restartTheServer" #define CC_CMD_RESTART "restartTheServer"
@@ -226,19 +236,17 @@ typedef enum{
#define CC_CMD_SHMEMKEY "shmemkey" #define CC_CMD_SHMEMKEY "shmemkey"
// CCD/CMOS // CCD/CMOS
#define CC_CMD_IMNUMBER "imnumber"
#define CC_CMD_PLUGINCMD "plugincmd" #define CC_CMD_PLUGINCMD "plugincmd"
#define CC_CMD_CAMLIST "camlist" #define CC_CMD_CAMLIST "camlist"
#define CC_CMD_CAMDEVNO "camdevno" #define CC_CMD_CAMDEVNO "camdevno"
#define CC_CMD_EXPOSITION "exptime" #define CC_CMD_EXPOSITION "exptime"
#define CC_CMD_LASTFNAME "lastfilename"
#define CC_CMD_FILENAME "filename"
#define CC_CMD_FILENAMEPREFIX "filenameprefix"
// rewrite=1 will rewrite files, =0 - not (only for `filename`) // rewrite=1 will rewrite files, =0 - not (only for `filename`)
#define CC_CMD_REWRITE "rewrite"
#define CC_CMD_HBIN "hbin" #define CC_CMD_HBIN "hbin"
#define CC_CMD_VBIN "vbin" #define CC_CMD_VBIN "vbin"
#define CC_CMD_CAMTEMPER "tcold" #define CC_CMD_CAMTEMPER "tcold"
#define CC_CMD_CAMFANSPD "ccdfanspeed" #define CC_CMD_CAMFANSPD "camfanspeed"
#define CC_CMD_CAMFLAGS "camflags"
#define CC_CMD_SHUTTER "shutter" #define CC_CMD_SHUTTER "shutter"
#define CC_CMD_CONFIO "confio" #define CC_CMD_CONFIO "confio"
#define CC_CMD_IO "io" #define CC_CMD_IO "io"
@@ -250,7 +258,7 @@ typedef enum{
// expstate=CAMERA_CAPTURE will start exposition, CAMERA_IDLE - cancel // expstate=CAMERA_CAPTURE will start exposition, CAMERA_IDLE - cancel
#define CC_CMD_EXPSTATE "expstate" #define CC_CMD_EXPSTATE "expstate"
#define CC_CMD_TREMAIN "tremain" #define CC_CMD_TREMAIN "tremain"
#define CC_CMD_8BIT "8bit" #define CC_CMD_8BIT "lowres"
#define CC_CMD_FASTSPD "fastspeed" #define CC_CMD_FASTSPD "fastspeed"
#define CC_CMD_DARK "dark" #define CC_CMD_DARK "dark"
#define CC_CMD_INFTY "infty" #define CC_CMD_INFTY "infty"
@@ -262,17 +270,21 @@ typedef enum{
#define CC_CMD_OBJECT "object" #define CC_CMD_OBJECT "object"
#define CC_CMD_PROGRAM "program" #define CC_CMD_PROGRAM "program"
#define CC_CMD_OBJTYPE "objtype" #define CC_CMD_OBJTYPE "objtype"
#define CC_CMD_HEADERFILES "headerfiles"
// focuser // focuser
#define CC_CMD_FOCLIST "foclist" #define CC_CMD_FOCLIST "foclist"
#define CC_CMD_FDEVNO "focdevno" #define CC_CMD_FDEVNO "focdevno"
#define CC_CMD_FGOTO "focpos" #define CC_CMD_FGOTO "focpos"
#define CC_CMD_FMINPOS "focminpos"
#define CC_CMD_FMAXPOS "focmaxpos"
#define CC_CMD_FTEMP "foctemp"
// wheel // wheel
#define CC_CMD_WLIST "wlist" #define CC_CMD_WLIST "wlist"
#define CC_CMD_WDEVNO "wdevno" #define CC_CMD_WDEVNO "wdevno"
#define CC_CMD_WPOS "wpos" #define CC_CMD_WPOS "wpos"
#define CC_CMD_WMAXPOS "wmaxpos"
#define CC_CMD_WTEMP "wtemp"
typedef enum{ // parameter type typedef enum{ // parameter type
CC_PAR_NONE, // no parameter CC_PAR_NONE, // no parameter
@@ -328,12 +340,16 @@ int cc_sendmessage(int fd, const char *msg, int l);
int cc_sendstrmessage(int fd, const char *msg); int cc_sendstrmessage(int fd, const char *msg);
char *cc_get_keyval(char **keyval); char *cc_get_keyval(char **keyval);
cc_IMG *cc_getshm(key_t key, size_t imsize); 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_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_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_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); 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); char *cc_nextkw(char *buf, char record[FLEN_CARD], int newlines);
size_t cc_kwfromfile(cc_charbuff *b, char *filename); size_t cc_kwfromfile(cc_IMG *img, char *filename);
int cc_charbuf2kw(cc_charbuff *b, fitsfile *f); //int cc_charbuf2kw(cc_charbuff *b, fitsfile *f);
void cc_init_sem(int isserver);
int cc_lock_shm(int isserver);
void cc_unlock_shm();
void cc_remove_sem();

View File

@@ -73,15 +73,20 @@ static int check_filenameprefix(char *buff, int buflen){
return FALSE; return FALSE;
} }
cc_charbuff *getFITSheader(cc_IMG *img){ /**
static cc_charbuff charbuf = {0}; * @brief fillFITSheader (server-side only!) - update img->fitsheader by image data and additional headers
cc_charbufclr(&charbuf); * @param img (io) - image to update
char card[FLEN_CARD+1], templ[2*FLEN_CARD+1], bufc[FLEN_CARD+1]; * @return img->headerstrings
*/
size_t fillFITSheader(cc_IMG *img){
if(!img) return 0;
img->headerstrings = 0;
char card[FLEN_CARD], templ[2*FLEN_CARD], bufc[FLEN_CARD];
#define FORMKW(in) \ #define FORMKW(in) \
do{ int status = 0, kt = 0; \ do{ int status = 0, kt = 0; \
fits_parse_template(in, card, &kt, &status); \ fits_parse_template(in, card, &kt, &status); \
if(status) fits_report_error(stderr, status);\ if(status) fits_report_error(stderr, status);\
else{cc_charbufaddline(&charbuf, card);} \ else if(img->headerstrings < FITS_HEADER_STRINGS_MAX) snprintf(img->fitsheader[img->headerstrings++], FLEN_CARD, "%s", card); \
}while(0) }while(0)
#define FORMINT(key, val, comment) do{ \ #define FORMINT(key, val, comment) do{ \
snprintf(templ, FLEN_CARD, "%s = %d / %s", key, val, comment); \ snprintf(templ, FLEN_CARD, "%s = %d / %s", key, val, comment); \
@@ -98,12 +103,6 @@ do{ int status = 0, kt = 0; \
calculate_stat(img); calculate_stat(img);
float tmpf = 0.0; float tmpf = 0.0;
int tmpi = 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("ORIGIN = 'SAO RAS' / Organization responsible for the data");
FORMKW("OBSERVAT = 'Special Astrophysical Observatory, Russia' / Observatory name"); FORMKW("OBSERVAT = 'Special Astrophysical Observatory, Russia' / Observatory name");
FORMKW("INSTRUME = 'direct imaging' / Instrument"); FORMKW("INSTRUME = 'direct imaging' / Instrument");
@@ -171,10 +170,10 @@ do{ int status = 0, kt = 0; \
if(wheel->getTbody && wheel->getTbody(&tmpf)) if(wheel->getTbody && wheel->getTbody(&tmpf))
FORMFLT("FILTTEMP", tmpf, "Filter wheel body temperature, degr C"); FORMFLT("FILTTEMP", tmpf, "Filter wheel body temperature, degr C");
} }
if(GP->addhdr){ // add records from files if(GP->addhdr){ // add records from server-side files
char **nxtfile = GP->addhdr; char **nxtfile = GP->addhdr;
while(*nxtfile){ while(*nxtfile){
cc_kwfromfile(&charbuf, *(nxtfile++)); cc_kwfromfile(img, *(nxtfile++));
} }
} }
// add these keywords after all to override records from files // add these keywords after all to override records from files
@@ -185,7 +184,7 @@ do{ int status = 0, kt = 0; \
if(camera->getModelName && camera->getModelName(bufc, FLEN_CARD)) if(camera->getModelName && camera->getModelName(bufc, FLEN_CARD))
FORMSTR("DETECTOR", bufc, "Detector model"); FORMSTR("DETECTOR", bufc, "Detector model");
if(GP->instrument) FORMSTR("INSTRUME", GP->instrument, "Instrument"); if(GP->instrument) FORMSTR("INSTRUME", GP->instrument, "Instrument");
return &charbuf; return img->headerstrings;
} }
// save FITS file `img` into GP->outfile or GP->outfileprefix_XXXX.fits // save FITS file `img` into GP->outfile or GP->outfileprefix_XXXX.fits
@@ -193,14 +192,10 @@ do{ int status = 0, kt = 0; \
// return FALSE if failed // return FALSE if failed
int saveFITS(cc_IMG *img, char **outp){ int saveFITS(cc_IMG *img, char **outp){
int ret = FALSE; int ret = FALSE;
if(!camera){
LOGERR("Can't save image: no camera device");
WARNX(_("Camera device unknown"));
return FALSE;
}
char fnam[PATH_MAX+1]; char fnam[PATH_MAX+1];
if(!GP->outfile && !GP->outfileprefix){ if(!GP->outfile && !GP->outfileprefix){
LOGWARN("Image not saved: neither filename nor filename prefix pointed"); LOGWARN("Image not saved: neither filename nor filename prefix pointed");
WARNX("Image not saved: neither filename nor filename prefix pointed");
return FALSE; return FALSE;
} }
if(GP->outfile){ // pointed specific output file name like "file.fits", check it if(GP->outfile){ // pointed specific output file name like "file.fits", check it
@@ -236,8 +231,20 @@ int saveFITS(cc_IMG *img, char **outp){
if(nbytes == 1) TRYFITS(fits_create_img, fp, BYTE_IMG, 2, naxes); if(nbytes == 1) TRYFITS(fits_create_img, fp, BYTE_IMG, 2, naxes);
else TRYFITS(fits_create_img, fp, USHORT_IMG, 2, naxes); else TRYFITS(fits_create_img, fp, USHORT_IMG, 2, naxes);
if(fitserror) goto cloerr; if(fitserror) goto cloerr;
cc_charbuff *bufhdr = getFITSheader(img); // write header
cc_charbuf2kw(bufhdr, fp); char key[FLEN_KEYWORD];
for(size_t i = 0; i < img->headerstrings; ++i){
char *rec = img->fitsheader[i];
char *eq = strchr(rec, '=');
int status = 0;
if(eq){ // found 'key = value / comment'
size_t l = eq - rec;
if(l > FLEN_KEYWORD-1) l = FLEN_KEYWORD-1;
memcpy(key, rec, l); key[l] = 0;
fits_update_card(fp, key, rec, &status);
}else fits_write_record(fp, rec, &status);
if(status) fits_report_error(stderr, status);
}
// creation date/time // creation date/time
int s = 0; int s = 0;
fits_write_date(fp, &s); fits_write_date(fp, &s);
@@ -377,11 +384,11 @@ void focusers(){
if(num < 0) num = 0; 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);
return; goto retn;
} }
if(!focuser->setDevNo(num)){ if(!focuser->setDevNo(num)){
WARNX(_("Can't set active focuser number")); WARNX(_("Can't set active focuser number"));
return; goto retn;
} }
char buf[BUFSIZ]; char buf[BUFSIZ];
if(focuser->getModelName(buf, BUFSIZ)){ if(focuser->getModelName(buf, BUFSIZ)){
@@ -395,18 +402,18 @@ void focusers(){
float minpos, maxpos, curpos; float minpos, maxpos, curpos;
if(!focuser->getMinPos(&minpos) || !focuser->getMaxPos(&maxpos)){ if(!focuser->getMinPos(&minpos) || !focuser->getMaxPos(&maxpos)){
WARNX(_("Can't get focuser limit positions")); WARNX(_("Can't get focuser limit positions"));
return; goto retn;
} }
verbose(1, "FOCMINPOS=%g", minpos); verbose(1, "FOCMINPOS=%g", minpos);
verbose(1, "FOCMAXPOS=%g", maxpos); verbose(1, "FOCMAXPOS=%g", maxpos);
DBG("FOCMINPOS=%g, FOCMAXPOS=%g", minpos, maxpos); DBG("FOCMINPOS=%g, FOCMAXPOS=%g", minpos, maxpos);
if(!focuser->getPos(&curpos)){ if(!focuser->getPos(&curpos)){
WARNX(_("Can't get current focuser position")); WARNX(_("Can't get current focuser position"));
return; goto retn;
} }
verbose(1, "FOCPOS=%g", curpos); verbose(1, "FOCPOS=%g", curpos);
DBG("Curpos = %g", curpos); DBG("Curpos = %g", curpos);
if(isnan(GP->gotopos) && isnan(GP->addsteps)) return; // no focuser commands if(isnan(GP->gotopos) && isnan(GP->addsteps)) goto retn; // no focuser commands
float tagpos = 0.; float tagpos = 0.;
if(!isnan(GP->gotopos)){ // set absolute position if(!isnan(GP->gotopos)){ // set absolute position
tagpos = GP->gotopos; tagpos = GP->gotopos;
@@ -416,13 +423,15 @@ void focusers(){
DBG("tagpos: %g", tagpos); DBG("tagpos: %g", tagpos);
if(tagpos < minpos || tagpos > maxpos){ if(tagpos < minpos || tagpos > maxpos){
WARNX(_("Can't set position %g: out of limits [%g, %g]"), tagpos, minpos, maxpos); WARNX(_("Can't set position %g: out of limits [%g, %g]"), tagpos, minpos, maxpos);
return; goto retn;
} }
if(tagpos - minpos < __FLT_EPSILON__){ if(tagpos - minpos < __FLT_EPSILON__){
if(!focuser->home(GP->async)) WARNX(_("Can't home focuser")); if(!focuser->home(GP->async)) WARNX(_("Can't home focuser"));
}else{ }else{
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:
focclose();
} }
cc_Wheel *startWheel(){ cc_Wheel *startWheel(){
@@ -465,11 +474,11 @@ void wheels(){
if(num < 0) num = 0; 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);
return; goto retn;
} }
if(!wheel->setDevNo(num)){ if(!wheel->setDevNo(num)){
WARNX(_("Can't set active wheel number")); WARNX(_("Can't set active wheel number"));
return; goto retn;
} }
char buf[BUFSIZ]; char buf[BUFSIZ];
if(wheel->getModelName(buf, BUFSIZ)){ if(wheel->getModelName(buf, BUFSIZ)){
@@ -485,17 +494,19 @@ void wheels(){
}else WARNX("Can't get current wheel position"); }else WARNX("Can't get current wheel position");
if(!wheel->getMaxPos(&maxpos)){ if(!wheel->getMaxPos(&maxpos)){
WARNX(_("Can't get max wheel position")); WARNX(_("Can't get max wheel position"));
return; goto retn;
} }
verbose(1, "WHEELMAXPOS=%d", maxpos); verbose(1, "WHEELMAXPOS=%d", maxpos);
pos = GP->setwheel; pos = GP->setwheel;
if(pos == -1) return; // no wheel commands if(pos == -1) goto retn; // no wheel commands
if(pos < 0 || pos > maxpos){ if(pos < 0 || pos > maxpos){
WARNX(_("Wheel position should be from 0 to %d"), maxpos); WARNX(_("Wheel position should be from 0 to %d"), maxpos);
return; goto retn;
} }
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:
closewheel();
} }
/* /*
static void closeall(){ static void closeall(){
@@ -916,6 +927,7 @@ int start_socket(int isserver){
} }
if(isserver){ if(isserver){
imsock = cc_open_socket(TRUE, GP->imageport, 2); // image socket should be networked imsock = cc_open_socket(TRUE, GP->imageport, 2); // image socket should be networked
DBG("imsock=%d, image port=%s", imsock, GP->imageport);
server(sock, imsock); server(sock, imsock);
}else{ }else{
#ifdef IMAGEVIEW #ifdef IMAGEVIEW

View File

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

508
client.c
View File

@@ -37,24 +37,26 @@
extern double answer_timeout; extern double answer_timeout;
static char sendbuf[BUFSIZ]; static char sendbuf[BUFSIZ];
static char *lastfilename = NULL;
// send message and wait any answer // 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) #define SENDMSG(...) do{DBG("SENDMSG"); snprintf(sendbuf, BUFSIZ-1, __VA_ARGS__); verbose(2, "\t> %s", sendbuf); if(!cc_sendstrmessage(sock, sendbuf)) ERRX("Server disconnected"); while(getans(sock, NULL));} while(0)
// send message and wait answer starting with 'cmd' // send message and wait answer starting with 'cmd'
#define SENDMSGW(cmd, ...) do{DBG("SENDMSGW"); snprintf(sendbuf, BUFSIZ-1, cmd __VA_ARGS__); verbose(2, "\t> %s", sendbuf); cc_sendstrmessage(sock, sendbuf);}while(!getans(sock, cmd)) #define SENDMSGW(cmd, ...) do{DBG("SENDMSGW"); snprintf(sendbuf, BUFSIZ-1, cmd __VA_ARGS__); verbose(2, "\t> %s", sendbuf); if(!cc_sendstrmessage(sock, sendbuf)) ERRX("Server disconnected");}while(!getans(sock, cmd))
// send command and wait for answer on it // send command and wait for answer on it
#define SENDCMDW(cmd) do{DBG("SENDCMDW"); strncpy(sendbuf, cmd, BUFSIZ-1); verbose(2, "\t> %s", sendbuf); cc_sendstrmessage(sock, sendbuf);}while(!getans(sock, cmd)) #define SENDCMDW(cmd) do{DBG("SENDCMDW"); strncpy(sendbuf, cmd, BUFSIZ-1); verbose(2, "\t> %s", sendbuf); if(!cc_sendstrmessage(sock, sendbuf)) ERRX("Server disconnected");}while(!getans(sock, cmd))
static volatile atomic_int expstate = CAMERA_CAPTURE; static volatile atomic_int expstate = CAMERA_CAPTURE;
static int xm0,ym0,xm1,ym1; // max format static int xm0,ym0,xm1,ym1; // max format
static int xc0,yc0,xc1,yc1; // current format static int xc0,yc0,xc1,yc1; // current format
#ifdef IMAGEVIEW static volatile atomic_int grabno = 0;
static volatile atomic_int grabno = 0, oldgrabno = 0; static int oldgrabno = 0;
// IPC key for shared memory // IPC key for shared memory
static cc_IMG ima = {0}, *shmima = NULL; // ima - local storage, shmima - shm (if available) static cc_IMG ima = {0}, *shmima = NULL; // ima - local storage, shmima - shm (if available)
static size_t imbufsz = 0; // image buffer for allocated `ima` static size_t imbufsz = 0; // image buffer for allocated `ima`
static uint8_t *imbuf = NULL; static uint8_t *imbuf = NULL; // we can't use shmima->data as it belongs to server, so we use `imbuf` and set ima.data = imbuf
#endif static int current_image_number = -1; // for net-parser - last number of exposed image
#if 0
// read message from queue or file descriptor // read message from queue or file descriptor
static char *readmsg(int fd){ static char *readmsg(int fd){
static cc_strbuff *buf = NULL; static cc_strbuff *buf = NULL;
@@ -70,65 +72,96 @@ static char *readmsg(int fd){
return FALSE; return FALSE;
} }
if(test()) return buf->string; if(test()) return buf->string;
if(1 == cc_canberead(fd)){ if(1 == sl_canread(fd)){
if(cc_read2buf(fd, buf)){ if(cc_read2buf(fd, buf)){
if(test()) return buf->string; if(test()) return buf->string;
}else ERRX("Server disconnected"); }else ERRX("Server disconnected");
} }
return NULL; return NULL;
} }
#endif
#define CMP_ANS(cmd, ans) strncmp(cmd, ans, sizeof(cmd)-1)
// parser of CCD server messages; return TRUE to exit from polling cycle of `getans` (if receive 'FAIL', 'OK' or 'BUSY') // parser of CCD server messages; return TRUE to exit from polling cycle of `getans` (if receive 'FAIL', 'OK' or 'BUSY')
static int parseans(char *ans){ static cc_hresult parseans(char *ans){
if(!ans) return FALSE; if(!ans) return CC_RESULT_BADKEY;
//TIMESTAMP("parseans() begin"); //TIMESTAMP("parseans() begin");
//DBG("Parsing of '%s'", ans); //DBG("Parsing of '%s'", ans);
if(0 == strcmp(cc_hresult2str(CC_RESULT_BUSY), ans)){ if(0 == strcmp(cc_hresult2str(CC_RESULT_OK), ans)) return CC_RESULT_OK;
WARNX("Server busy"); for(cc_hresult res = CC_RESULT_BUSY; res < CC_RESULT_NUM; ++res){
return FALSE; const char *resmsg = cc_hresult2str(res);
if(0 == strcmp(resmsg, ans)){
verbose(1, "Server answered: %s", resmsg);
return res;
}
} }
if(0 == strcmp(cc_hresult2str(CC_RESULT_FAIL), ans)) return TRUE;
if(0 == strcmp(cc_hresult2str(CC_RESULT_OK), ans)) return TRUE;
char *val = cc_get_keyval(&ans); // now `ans` is a key and `val` its value char *val = cc_get_keyval(&ans); // now `ans` is a key and `val` its value
if(0 == strcmp(CC_CMD_EXPSTATE, ans)){ if(0 == CMP_ANS(CC_CMD_EXPSTATE, ans)){
expstate = atoi(val); int st = atoi(val);
DBG("Exposition state: %d", expstate); atomic_store(&expstate, st);
return TRUE; DBG("Current state: %d", atomic_load(&expstate));
}else if(0 == strcmp(CC_CMD_FRAMEMAX, ans)){ return CC_RESULT_SILENCE;
}else if(0 == CMP_ANS(CC_CMD_FRAMEMAX, ans)){
sscanf(val, "%d,%d,%d,%d", &xm0, &ym0, &xm1, &ym1); sscanf(val, "%d,%d,%d,%d", &xm0, &ym0, &xm1, &ym1);
DBG("Got maxformat: %d,%d,%d,%d", xm0, ym0, xm1, ym1); DBG("Got maxformat: %d,%d,%d,%d", xm0, ym0, xm1, ym1);
return TRUE; return CC_RESULT_SILENCE;
}else if(0 == strcmp(CC_CMD_FRAMEFORMAT, ans)){ }else if(0 == CMP_ANS(CC_CMD_FRAMEFORMAT, ans)){
sscanf(val, "%d,%d,%d,%d", &xc0, &yc0, &xc1, &yc1); sscanf(val, "%d,%d,%d,%d", &xc0, &yc0, &xc1, &yc1);
DBG("Got current format: %d,%d,%d,%d", xc0, yc0, xc1, yc1); DBG("Got current format: %d,%d,%d,%d", xc0, yc0, xc1, yc1);
return TRUE; return CC_RESULT_SILENCE;
}else if(0 == strcmp(CC_CMD_INFTY, ans)) return TRUE; }else if(0 == CMP_ANS(CC_CMD_IMNUMBER, ans)){
current_image_number = atoi(val);
}
//TIMESTAMP("parseans() end"); //TIMESTAMP("parseans() end");
return FALSE; return CC_RESULT_SILENCE; // echo of sent command or something else
} }
// read until timeout all messages from server; return FALSE if there was no messages from server // read until timeout all messages from server; return FALSE if there was no messages from server
// if msg != NULL - wait for it in answer // if msg != NULL - wait for it in answer
static int getans(int sock, const char *msg){ static int getans(int sock, const char *msg){
double t0 = sl_dtime(); double t0 = sl_dtime();
char buf[BUFSIZ+1];
int idx = 0;
char *ans = NULL; char *ans = NULL;
while(sl_dtime() - t0 < answer_timeout){ TIMESTAMP("GetAns(%s)", msg);
char *s = readmsg(sock); double tmout = answer_timeout + 5.; // make first timeout larger for slow networks
if(!s) continue; // TODO: increase first timeout up to 15-30s (add key?)
cc_hresult res = CC_RESULT_FAIL;
while(sl_dtime() - t0 < tmout){
ans = NULL;
if(1 == sl_canread(sock)){
ssize_t got = read(sock, buf+idx, BUFSIZ-idx);
if(got > 0){
idx += got;
buf[idx] = 0;
char *nl = strchr(buf, '\n');
if(nl){
*nl = 0;
ans = buf;
DBG("got '%s'", ans);
}
}
}
if(!ans) continue;
// got answer -> make timeout less
tmout = answer_timeout;
t0 = sl_dtime(); t0 = sl_dtime();
ans = s;
TIMESTAMP("Got from server: %s", ans); TIMESTAMP("Got from server: %s", ans);
verbose(1, "\t%s", ans); verbose(1, "\t%s", ans);
DBG("1 msg-> %s, ans -> %s", msg, ans); DBG("1 msg-> %s, ans -> %s", msg, ans);
if(parseans(ans)){ res = parseans(ans);
DBG("2 msg-> %s, ans -> %s", msg, ans); DBG("2 msg-> %s, ans -> %s; result: %d", msg, ans, res);
if(msg && strncmp(ans, msg, strlen(msg))) continue; if(msg){
DBG("BREAK"); if(res != CC_RESULT_SILENCE || strncmp(ans, msg, strlen(msg))) continue;
else res = CC_RESULT_OK;
}
DBG("Got answer -> break");
break; break;
} }
TIMESTAMP("GetAns(%s), ans: '%s', result: %d", msg, ans, res);
} if(!ans) DBG("Got no answer from server; result=%d", res);
return ((ans) ? TRUE : FALSE); if(res == CC_RESULT_OK) return TRUE;
return FALSE;
} }
/** /**
@@ -149,16 +182,35 @@ static void send_headers(int sock){
DBG("infty=%d", GP->infty); DBG("infty=%d", GP->infty);
if(GP->infty > -1) SENDMSGW(CC_CMD_INFTY, "=%d", GP->infty); if(GP->infty > -1) SENDMSGW(CC_CMD_INFTY, "=%d", GP->infty);
// common information // common information
SENDMSG(CC_CMD_INFO); if(GP->listdevices) SENDCMDW(CC_CMD_CAMLIST);
if(GP->camdevno > -1) SENDMSGW(CC_CMD_CAMDEVNO, "=%d", GP->camdevno);
if(GP->info){
SENDCMDW(CC_CMD_HBIN);
SENDCMDW(CC_CMD_VBIN);
SENDCMDW(CC_CMD_CAMTEMPER);
SENDCMDW(CC_CMD_EXPOSITION);
SENDCMDW(CC_CMD_EXPSTATE);
}
// focuser // focuser
if(GP->listdevices) SENDMSG(CC_CMD_FOCLIST); if(GP->listdevices) SENDMSG(CC_CMD_FOCLIST);
if(GP->focdevno > -1) SENDMSG(CC_CMD_FDEVNO "=%d", GP->focdevno); if(GP->focdevno > -1) SENDMSG(CC_CMD_FDEVNO "=%d", GP->focdevno);
if(GP->info){
SENDCMDW(CC_CMD_FGOTO);
SENDCMDW(CC_CMD_FMINPOS);
SENDCMDW(CC_CMD_FMAXPOS);
SENDCMDW(CC_CMD_FTEMP);
}
if(!isnan(GP->gotopos)){ if(!isnan(GP->gotopos)){
SENDMSGW(CC_CMD_FGOTO, "=%g", GP->gotopos); SENDMSGW(CC_CMD_FGOTO, "=%g", GP->gotopos);
} }
// wheel // wheel
if(GP->listdevices) SENDCMDW(CC_CMD_WLIST); if(GP->listdevices) SENDCMDW(CC_CMD_WLIST);
if(GP->whldevno > -1) SENDMSGW(CC_CMD_WDEVNO, "=%d", GP->whldevno); if(GP->whldevno > -1) SENDMSGW(CC_CMD_WDEVNO, "=%d", GP->whldevno);
if(GP->info){
SENDCMDW(CC_CMD_WPOS);
SENDCMDW(CC_CMD_WMAXPOS);
SENDCMDW(CC_CMD_WTEMP);
}
if(GP->setwheel > -1) SENDMSGW(CC_CMD_WPOS, "=%d", GP->setwheel); if(GP->setwheel > -1) SENDMSGW(CC_CMD_WPOS, "=%d", GP->setwheel);
DBG("nxt"); DBG("nxt");
// CCD/CMOS // CCD/CMOS
@@ -181,8 +233,6 @@ static void send_headers(int sock){
SENDMSGW(CC_CMD_FRAMEFORMAT, "=%d,%d,%d,%d", GP->X0, GP->Y0, GP->X1, GP->Y1); SENDMSGW(CC_CMD_FRAMEFORMAT, "=%d,%d,%d,%d", GP->X0, GP->Y0, GP->X1, GP->Y1);
} }
if(GP->cancelexpose) SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_IDLE); if(GP->cancelexpose) SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_IDLE);
if(GP->listdevices) SENDCMDW(CC_CMD_CAMLIST);
if(GP->camdevno > -1) SENDMSGW(CC_CMD_CAMDEVNO, "=%d", GP->camdevno);
if(GP->hbin) SENDMSGW(CC_CMD_HBIN, "=%d", GP->hbin); if(GP->hbin) SENDMSGW(CC_CMD_HBIN, "=%d", GP->hbin);
if(GP->vbin) SENDMSGW(CC_CMD_VBIN, "=%d", GP->vbin); if(GP->vbin) SENDMSGW(CC_CMD_VBIN, "=%d", GP->vbin);
if(!isnan(GP->temperature)) SENDMSGW(CC_CMD_CAMTEMPER, "=%g", GP->temperature); if(!isnan(GP->temperature)) SENDMSGW(CC_CMD_CAMTEMPER, "=%g", GP->temperature);
@@ -200,16 +250,6 @@ static void send_headers(int sock){
if(GP->dark) SENDMSGW(CC_CMD_DARK, "=1"); if(GP->dark) SENDMSGW(CC_CMD_DARK, "=1");
else SENDMSGW(CC_CMD_DARK, "=0"); else SENDMSGW(CC_CMD_DARK, "=0");
} }
if(GP->outfile){
if(!*GP->outfile) SENDMSGW(CC_CMD_FILENAME, "=");
else SENDMSGW(CC_CMD_FILENAME, "=%s", makeabspath(GP->outfile, FALSE));
if(GP->rewrite) SENDMSGW(CC_CMD_REWRITE, "=1");
else SENDMSGW(CC_CMD_REWRITE, "=0");
}
if(GP->outfileprefix){
if(!*GP->outfileprefix) SENDMSGW(CC_CMD_FILENAMEPREFIX, "=");
else SENDMSGW(CC_CMD_FILENAMEPREFIX, "=%s", makeabspath(GP->outfileprefix, FALSE));
}
// FITS header keywords: // FITS header keywords:
#define CHKHDR(x, cmd) do{if(x) SENDMSG(cmd "=%s", x);}while(0) #define CHKHDR(x, cmd) do{if(x) SENDMSG(cmd "=%s", x);}while(0)
CHKHDR(GP->author, CC_CMD_AUTHOR); CHKHDR(GP->author, CC_CMD_AUTHOR);
@@ -219,107 +259,6 @@ static void send_headers(int sock){
CHKHDR(GP->prog_id, CC_CMD_PROGRAM); CHKHDR(GP->prog_id, CC_CMD_PROGRAM);
CHKHDR(GP->objtype, CC_CMD_OBJTYPE); CHKHDR(GP->objtype, CC_CMD_OBJTYPE);
#undef CHKHDR #undef CHKHDR
if(GP->addhdr){
char buf[1024], *ptr = buf, **sptr = GP->addhdr;
*buf = 0;
int L = 1024;
while(*sptr){
if(!**sptr){
++sptr; continue;
}
int N = snprintf(ptr, L-1, "%s,", *sptr++);
L -= N; ptr += N;
}
SENDMSGW(CC_CMD_HEADERFILES, "=%s", buf);
}
}
void client(int sock){
if(GP->restart){
SENDCMDW(CC_CMD_RESTART);
return;
}
send_headers(sock);
double t0 = sl_dtime(), tw = t0;
int Nremain = 0, nframe = 1;
// if client gives filename/prefix or Nframes, make exposition
if((GP->outfile && *GP->outfile) || (GP->outfileprefix && *GP->outfileprefix) || GP->nframes > 0){
Nremain = GP->nframes - 1;
if(Nremain < 1) Nremain = 0;
else GP->waitexpend = TRUE; // N>1 - wait for exp ends
SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE);
}else{
int cntr = 0;
while(sl_dtime() - t0 < CC_WAIT_TIMEOUT && cntr < 3)
if(!getans(sock, NULL)) ++cntr;
DBG("RETURN: no more data");
return;
}
double timeout = GP->waitexpend ? CC_CLIENT_TIMEOUT : CC_WAIT_TIMEOUT;
verbose(1, "Exposing frame 1...");
if(GP->waitexpend){
expstate = CAMERA_CAPTURE; // could be changed earlier
verbose(2, "Wait for exposition end");
}
while(sl_dtime() - t0 < timeout){
if(GP->waitexpend && sl_dtime() - tw > CC_WAIT_TIMEOUT){
SENDCMDW(CC_CMD_TREMAIN); // get remained time
tw = sl_dtime();
sprintf(sendbuf, "%s", CC_CMD_EXPSTATE);
cc_sendstrmessage(sock, sendbuf);
}
if(getans(sock, NULL)){ // got next portion of data
DBG("server message");
t0 = sl_dtime();
if(expstate == CAMERA_ERROR){
WARNX(_("Can't make exposition"));
continue;
}
//if(expstate != CAMERA_CAPTURE){
if(expstate == CAMERA_FRAMERDY){
verbose(2, "Frame ready!");
expstate = CAMERA_IDLE;
if(Nremain){
verbose(1, "\n");
if(GP->pause_len > 0){
double delta, time1 = sl_dtime() + GP->pause_len;
while(1){
SENDCMDW(CC_CMD_CAMTEMPER);
if((delta = time1 - sl_dtime()) < __FLT_EPSILON__) break;
if(delta > 1.) verbose(1, _("%d seconds till pause ends\n"), (int)delta);
if(delta > 6.) sleep(5);
else if(delta > 1.) sleep((int)delta);
else usleep((int)(delta*1e6 + 1));
}
}
verbose(1, "Exposing frame %d...", ++nframe);
--Nremain;
SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE);
}else{
GP->waitexpend = 0;
timeout = answer_timeout; // wait for last file name
}
}
}
}
if(GP->waitexpend) WARNX(_("Server timeout"));
// clear "filename" and "filenameprefix"
SENDMSGW(CC_CMD_FILENAME, "=");
SENDMSGW(CC_CMD_FILENAMEPREFIX, "=");
// clear "rewrite"
SENDMSGW(CC_CMD_REWRITE, "=0");
DBG("Timeout");
}
#ifdef IMAGEVIEW
static int controlfd = -1; // control socket FD
void init_grab_sock(int sock){
if(sock < 0) ERRX("Can't run without command socket");
controlfd = sock;
send_headers(sock);
if(!GP->forceimsock && !shmima){ // init shm buffer if user don't ask to work through image socket
shmima = cc_getshm(GP->shmkey, 0); // try to init client shm
}
} }
/** /**
@@ -329,10 +268,11 @@ void init_grab_sock(int sock){
static int readNbytes(int fd, size_t N, uint8_t *buf){ static int readNbytes(int fd, size_t N, uint8_t *buf){
size_t got = 0, need = N; size_t got = 0, need = N;
double t0 = sl_dtime(); double t0 = sl_dtime();
while(sl_dtime() - t0 < CC_CLIENT_TIMEOUT /*&& cc_canberead(fd)*/ && need){ while(sl_dtime() - t0 < CC_CLIENT_TIMEOUT /*&& sl_canread(fd)*/ && need){
t0 = sl_dtime(); t0 = sl_dtime();
ssize_t rd = read(fd, buf + got, need); ssize_t rd = read(fd, buf + got, need);
if(rd <= 0){ if(rd <= 0){
if(errno == EAGAIN || errno == EWOULDBLOCK) continue;
WARNX("Server disconnected"); WARNX("Server disconnected");
signals(1); signals(1);
} }
@@ -344,16 +284,35 @@ static int readNbytes(int fd, size_t N, uint8_t *buf){
/** /**
* @brief getimage - read image from shared memory or socket * @brief getimage - read image from shared memory or socket
* @param askheader == TRUE for storing FITS-header
* @return FALSE if failed to catch image
*/ */
static void getimage(){ static int getimage(int askheader){
FNAME(); FNAME();
int imsock = -1; int imsock = -1, shmlocked = FALSE, ret = FALSE;
static double oldtimestamp = -1.; static double oldtimestamp = -1.;
TIMESTAMP("Get image sizes"); TIMESTAMP("Get image sizes");
if(shmima){ // read image from shared memory if(shmima){ // read image from shared memory
DBG("Try to read from SHM");
double t0 = sl_dtime();
while(sl_dtime() - t0 < MUTEX_LOCK_TMOUT){
if(cc_lock_shm(FALSE)){
DBG("Locked");
shmlocked = TRUE;
break;
}
usleep(100);
}
if(!shmlocked){
WARNX("Can't lock shared memory");
return FALSE;
}
memcpy(&ima, shmima, sizeof(cc_IMG)); memcpy(&ima, shmima, sizeof(cc_IMG));
}else{ // get image by socket }else{ // get image by socket
if(imsock < 0){
DBG("Open socket @ %s", GP->imageport);
imsock = cc_open_socket(FALSE, GP->imageport, TRUE); imsock = cc_open_socket(FALSE, GP->imageport, TRUE);
}
if(imsock < 0) ERRX("getimage(): can't open image transport socket"); if(imsock < 0) ERRX("getimage(): can't open image transport socket");
// get image size // get image size
if(!readNbytes(imsock, sizeof(cc_IMG), (uint8_t*)&ima)){ if(!readNbytes(imsock, sizeof(cc_IMG), (uint8_t*)&ima)){
@@ -361,6 +320,10 @@ static void getimage(){
goto eofg; goto eofg;
} }
} }
if(ima.MAGICK != CC_SHM_MAGIC){
WARNX("Wrong image: bad magick");
goto eofg;
}
if(ima.bytelen < 1){ if(ima.bytelen < 1){
WARNX("Wrong image size"); WARNX("Wrong image size");
goto eofg; goto eofg;
@@ -376,82 +339,256 @@ static void getimage(){
ima.data = imbuf; // renew this value each time after getting `ima` from server ima.data = imbuf; // renew this value each time after getting `ima` from server
TIMESTAMP("Start of data read"); TIMESTAMP("Start of data read");
if(shmima){ if(shmima){
uint8_t *datastart = (uint8_t*)shmima + sizeof(cc_IMG); uint8_t *datastart = ((uint8_t*)shmima) + sizeof(cc_IMG);
DBG("first image byte: %d", *datastart);
memcpy(imbuf, datastart, ima.bytelen); memcpy(imbuf, datastart, ima.bytelen);
TIMESTAMP("Got by shared memory"); TIMESTAMP("Got by shared memory");
if(!askheader){
cc_unlock_shm();
shmlocked = FALSE;
}
ret = TRUE;
}else{ }else{
if(!readNbytes(imsock, ima.bytelen, imbuf)){ if(!readNbytes(imsock, ima.bytelen, imbuf)){
WARNX("Can't read image data"); WARNX("Can't read image data");
goto eofg; goto eofg;
} }
ret = TRUE;
TIMESTAMP("Got by socket"); TIMESTAMP("Got by socket");
} }
DBG("timestamps old-new=%g; imno: %zd", oldtimestamp-ima.timestamp, ima.imnumber); DBG("timestamps new-old=%g; imno: %zd", ima.timestamp - oldtimestamp, ima.imnumber);
if(ima.timestamp != oldtimestamp){ // test if image is really new if(ima.timestamp != oldtimestamp){ // test if image is really new
oldtimestamp = ima.timestamp; oldtimestamp = ima.timestamp;
grabno = ima.imnumber; atomic_store(&grabno, ima.imnumber);
TIMESTAMP("Got image #%zd", ima.imnumber); TIMESTAMP("Got image #%zd", ima.imnumber);
if(askheader){ // read FITS-header for later saving
if(shmima){
size_t rsz = FLEN_CARD * ima.headerstrings;
memcpy(ima.fitsheader, shmima->fitsheader, rsz);
}else{
uint8_t card[FLEN_CARD];
for(size_t i = 0; i < ima.headerstrings; ++i){
if(!readNbytes(imsock, FLEN_CARD, card)){
WARNX("Can't read full header, got %zd records from %zd", i, ima.headerstrings);
break;
}
memcpy(&ima.fitsheader[i], card, FLEN_CARD);
}
}
if(GP->addhdr){ // add records from client-side files
char **nxtfile = GP->addhdr;
while(*nxtfile){
cc_kwfromfile(&ima, *(nxtfile++));
}
}
}else ima.headerstrings = 0;
}else WARNX("Still got old image"); }else WARNX("Still got old image");
eofg: eofg:
if(!shmima) close(imsock); if(imsock != -1) close(imsock); // reopen in next time in case of error
if(shmlocked) cc_unlock_shm();
return ret;
} }
static void *grabnext(void _U_ *arg){ // daemon grabbing images through the net // get number of current image; return number or -1 if got error/timeout
static int curImNo(int sock){
if(shmima){
if(!cc_lock_shm(FALSE)) return -1;
int CurNo = shmima->imnumber;
cc_unlock_shm();
return CurNo;
}
// no shared memory: try to get number over TCP
SENDCMDW(CC_CMD_IMNUMBER);
return current_image_number;
}
void client(int sock){
if(sock < 0) ERRX("Can't run without command socket");
if(!GP->forceimsock && !shmima){ // init shm buffer if user don't ask to force workign through image socket
shmima = cc_getshm(GP->shmkey, 0); // try to init client shm
cc_init_sem(FALSE);
DBG("Got access to shared memory: %s", shmima ? "OK" : "FAIL");
}
if(GP->restart){
SENDCMDW(CC_CMD_RESTART);
return;
}
TIMEINIT();
send_headers(sock);
TIMESTAMP("Got headers");
double t0 = sl_dtime(), tw, tstart;
int Nremain = 0, nframe = 1;
// if client gives filename/prefix or Nframes, make exposition
if((GP->outfile && *GP->outfile) || (GP->outfileprefix && *GP->outfileprefix) || GP->nframes > 0){
Nremain = GP->nframes;
if(Nremain < 1) Nremain = 1;
SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE); // call to start capture
} else return; // just send headers and exit
double timeout = CC_CLIENT_TIMEOUT;
verbose(1, "Exposing frame 1...");
atomic_store(&expstate, CAMERA_CAPTURE); // could be changed earlier
DBG("Current state: %d", atomic_load(&expstate));
verbose(2, "Wait for exposition end");
t0 = sl_dtime();
tw = tstart = t0;
int lastImNo = curImNo(sock);
while(sl_dtime() - t0 < timeout){
if(sl_dtime() - tw > CC_WAIT_TIMEOUT){
SENDCMDW(CC_CMD_TREMAIN); // get remained time
tw = sl_dtime();
}
if(sl_dtime() - tstart < GP->exptime){
t0 = sl_dtime(); // refresh timeout until exp not ends
continue;
}else{
SENDCMDW(CC_CMD_EXPSTATE);
}
int curst = atomic_load(&expstate);
DBG("Current state: %d", curst);
if(curst == CAMERA_ERROR){
WARNX(_("Can't make exposition"));
if(Nremain > 1){
verbose(1, "Exposing frame %d...", nframe);
SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE);
tstart = sl_dtime();
}
continue;
}
if(curst == CAMERA_FRAMERDY){
atomic_store(&expstate, CAMERA_IDLE);
int cur = curImNo(sock);
DBG("Current state: %d, imno: %d", atomic_load(&expstate), cur);
if(Nremain > 1){ // start next capture
verbose(1, "Exposing frame %d...", nframe);
SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE);
tstart = sl_dtime();
}
int failed = TRUE;
if(lastImNo < cur){
lastImNo = cur;
verbose(2, "Frame ready, try to grab");
if(!getimage(TRUE)){
WARNX("Can't get next image");
}else{
if(saveFITS(&ima, &lastfilename)){
--Nremain;
++nframe;
failed = FALSE;
}
}
}else verbose(2, "Got already saved image, wait next");
if(failed && Nremain == 1){ // last image -> should re-expose
verbose(1, "Exposing frame %d...", nframe);
SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE);
tstart = sl_dtime();
}
if(Nremain > 0){
if(GP->pause_len > 0){
double delta, time1 = sl_dtime() + GP->pause_len;
while(1){
SENDCMDW(CC_CMD_CAMTEMPER);
if((delta = time1 - sl_dtime()) < __FLT_EPSILON__) break;
if(delta > 1.) verbose(1, _("%d seconds till pause ends\n"), (int)delta);
if(delta > 6.) sleep(5);
else if(delta > 1.) sleep((int)delta);
else usleep((int)(delta*1e6 + 1));
}
}
}else{
DBG("All images saved -> exit");
break;
}
}
}
if(Nremain > 0) WARNX(_("Server timeout"));
}
#ifdef IMAGEVIEW
static int controlfd = -1; // control socket FD
void init_grab_sock(int sock){
if(sock < 0) ERRX("Can't run without command socket");
controlfd = sock;
send_headers(sock);
if(!GP->forceimsock && !shmima){ // init shm buffer if user don't ask to work through image socket
shmima = cc_getshm(GP->shmkey, 0); // try to init client shm
cc_init_sem(FALSE);
}
}
// grab image for active viewer
static void *grabnext(void _U_ *arg){
FNAME(); FNAME();
if(controlfd < 0) return NULL; if(controlfd < 0) return NULL;
int sock = controlfd; int sock = controlfd;
int lastImNo = curImNo(sock);
while(1){ while(1){
if(!getWin()) exit(1); if(!getWin()) exit(1);
TIMESTAMP("End of cycle, start new"); TIMESTAMP("End of cycle, start new");
expstate = CAMERA_CAPTURE; atomic_store(&expstate, CAMERA_CAPTURE);
DBG("Current state: %d", atomic_load(&expstate));
TIMEINIT(); TIMEINIT();
SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE); // start capture SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE); // start capture
double timeout = GP->exptime + CC_CLIENT_TIMEOUT, t0 = sl_dtime(); double timeout = GP->exptime + CC_CLIENT_TIMEOUT, t0 = sl_dtime();
useconds_t sleept = 500000; // 0.5s useconds_t sleept = 500000; // 0.5s
if(GP->exptime < 0.5){ if(GP->exptime < 0.5){
sleept = (useconds_t)(GP->exptime * 500000.); sleept = (useconds_t)(GP->exptime * 250000.); // a quater of exposition time
if(sleept < 1000) sleept = 1000; if(sleept < CC_IMWAIT_SLEEP) sleept = CC_IMWAIT_SLEEP;
} }
// double exptime = GP->exptime; TIMESTAMP("Wait for exposition ends (%g s), sleep for %dus", timeout, sleept);
int curst = CAMERA_CAPTURE;
while(sl_dtime() - t0 < timeout){ while(sl_dtime() - t0 < timeout){
TIMESTAMP("Wait for exposition ends (%u us)", sleept); DBG("start sleep for %dus", sleept);
usleep(sleept); usleep(sleept);
TIMESTAMP("check answer"); SENDCMDW(CC_CMD_EXPSTATE);
// getans(sock, NULL); curst = atomic_load(&expstate);
//TIMESTAMP("EXPSTATE ===> %d", expstate); if(curst != CAMERA_CAPTURE) break;
if(expstate != CAMERA_CAPTURE) break; if(sl_dtime() - t0 > GP->exptime && sleept != CC_IMWAIT_SLEEP){
if(sl_dtime() - t0 < GP->exptime + 0.5) sleept = 1000; DBG("Set sleeping time to %dus", sleept);
sleept = CC_IMWAIT_SLEEP;
} }
if(sl_dtime() - t0 >= timeout || expstate != CAMERA_FRAMERDY){ }
WARNX("Image wasn't received"); int cur = curImNo(sock);
if(sl_dtime() - t0 >= timeout || curst != CAMERA_FRAMERDY || cur <= lastImNo){
WARNX("Image wasn't received, state: %d, waiting: %g, lastNo: %d, curNo: %d (timeout: %g)", curst, sl_dtime() - t0, lastImNo, cur, timeout);
continue; continue;
} }
TIMESTAMP("Frame ready"); lastImNo = cur;
getimage(); TIMESTAMP("Frame ready (%d from server's start)", cur);
getimage(FALSE);
} }
return NULL; return NULL;
} }
static void *waitimage(void _U_ *arg){ // passive waiting for next image // passive waiting for next image
static void *waitimage(void _U_ *arg){
FNAME(); FNAME();
if(controlfd < 0) return NULL; if(controlfd < 0) return NULL;
int sock = controlfd; int sock = controlfd;
int lastImNo = curImNo(sock);
double t0 = sl_dtime();
while(1){ while(1){
if(!getWin()) exit(1); if(!getWin()) exit(1);
getans(sock, NULL); double tcur = sl_dtime();
if(expstate != CAMERA_FRAMERDY){ if(tcur - t0 >= CC_WAIT_TIMEOUT){
usleep(1000); SENDCMDW(CC_CMD_EXPSTATE); // `ping` server to know if it disconnected
t0 = tcur;
}
int cur = curImNo(sock);
if(cur <= lastImNo){
usleep(CC_IMWAIT_SLEEP);
continue; continue;
} }
TIMESTAMP("End of cycle, start new"); lastImNo = cur;
TIMESTAMP("End of cycle #%d, start new", cur);
TIMEINIT(); TIMEINIT();
getimage(); getimage(FALSE);
expstate = CAMERA_IDLE; atomic_store(&expstate, CAMERA_IDLE);
DBG("Current state: %d", atomic_load(&expstate));
} }
return NULL; return NULL;
} }
// try to capture images through socket // try to capture images for viewer
int sockcaptured(cc_IMG **imgptr){ int sockcaptured(cc_IMG **imgptr){
//TIMESTAMP("sockcaptured() start"); //TIMESTAMP("sockcaptured() start");
if(!imgptr) return FALSE; if(!imgptr) return FALSE;
@@ -484,13 +621,12 @@ int sockcaptured(cc_IMG **imgptr){
} }
} }
}else{ // grab in process }else{ // grab in process
if(grabno != oldgrabno){ // image is ready int curno = atomic_load(&grabno);
TIMESTAMP("Image #%d ready", grabno); if(curno != oldgrabno){ // image is ready
TIMESTAMP("Image #%d ready", curno);
if(*imgptr && (*imgptr != &ima)) free(*imgptr); if(*imgptr && (*imgptr != &ima)) free(*imgptr);
*imgptr = &ima; /* *imgptr = &ima;
ssize_t delta = ima.imnumber - oldgrabno; oldgrabno = curno;
if(delta > 0 && delta != 1) WARNX("sockcaptured(): missed %zd images", delta-1);*/
oldgrabno = grabno;
framerate(); framerate();
//TIMESTAMP("sockcaptured() end, return TRUE"); //TIMESTAMP("sockcaptured() end, return TRUE");
return TRUE; return TRUE;

View File

@@ -56,7 +56,7 @@ sl_option_t cmdlnopts[] = {
{"focdevno",NEED_ARG, NULL, NA, arg_int, APTR(&G.focdevno), N_("focuser 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")}, {"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")}, {"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)")}, {"verbose", NO_ARGS, NULL, 'V', arg_none, APTR(&G.verbose), N_("verbose level (-V - main messages, -VV - secondary messages, -VVV - debug)")},
{"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 readout mode")}, {"fast", NO_ARGS, NULL, 'f', arg_none, APTR(&G.fast), N_("fast readout mode")},
@@ -71,7 +71,6 @@ sl_option_t cmdlnopts[] = {
{"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")}, {"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")},
@@ -111,6 +110,7 @@ sl_option_t cmdlnopts[] = {
{"viewer", NO_ARGS, &G.viewer,1, arg_none, NULL, N_("passive viewer (only get last images)")}, {"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")}, {"restart", NO_ARGS, &G.restart,1, arg_none, NULL, N_("restart image server")},
{"timeout", NEED_ARG, NULL, '0', arg_double, APTR(&G.anstmout), N_("network answer timeout (default: 0.1s)")}, {"timeout", NEED_ARG, NULL, '0', arg_double, APTR(&G.anstmout), N_("network answer timeout (default: 0.1s)")},
{"info", NO_ARGS, &G.info, 1, arg_none, NULL, N_("get base information about connected hardware (also increasing text messages level to 2)")},
{"shmkey", NEED_ARG, NULL, 'k', arg_int, APTR(&G.shmkey), N_("shared memory (with image data) key (default: 7777777)")}, {"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")}, {"forceimsock",NO_ARGS, &G.forceimsock,1, arg_none, NULL, N_("force using image through socket transition even if can use SHM")},

View File

@@ -42,9 +42,9 @@ typedef struct{
char **addhdr; // list of files from which to add header records char **addhdr; // list of files from which to add header records
char **plugincmd; // plugin commands char **plugincmd; // plugin commands
int restart; // restart server int restart; // restart server
int waitexpend; // wait while exposition ends
int cancelexpose; // cancel exp (for Grasshopper - forbid forever) int cancelexpose; // cancel exp (for Grasshopper - forbid forever)
int client; // run as client int client; // run as client
int info; // show main information about camera etc. in client's terminal
int viewer; // passive client (only get last images) int viewer; // passive client (only get last images)
int listdevices; // list connected devices int listdevices; // list connected devices
int fanspeed; // fan speed: 0-2 int fanspeed; // fan speed: 0-2

Binary file not shown.

View File

@@ -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: 2026-04-18 15:56+0300\n" "POT-Creation-Date: 2026-06-08 17:06+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"
@@ -62,7 +62,8 @@ msgid "rewrite output file if exists"
msgstr "" msgstr ""
#: cmdlnopts.c:59 #: cmdlnopts.c:59
msgid "verbose level (-V - messages, -VV - debug, -VVV - all shit)" msgid ""
"verbose level (-V - main messages, -VV - secondary messages, -VVV - debug)"
msgstr "" msgstr ""
#: cmdlnopts.c:60 #: cmdlnopts.c:60
@@ -117,142 +118,144 @@ msgstr ""
msgid "output file name" msgid "output file name"
msgstr "" msgstr ""
#: cmdlnopts.c:74 #: cmdlnopts.c:75
msgid "wait while exposition ends"
msgstr ""
#: cmdlnopts.c:76
msgid "N flushes before exposing (default: 1)" msgid "N flushes before exposing (default: 1)"
msgstr "" msgstr ""
#: cmdlnopts.c:77 #: cmdlnopts.c:76
msgid "horizontal binning to N pixels" msgid "horizontal binning to N pixels"
msgstr "" msgstr ""
#: cmdlnopts.c:78 #: cmdlnopts.c:77
msgid "vertical binning to N pixels" msgid "vertical binning to N pixels"
msgstr "" msgstr ""
#: cmdlnopts.c:79 #: cmdlnopts.c:78
msgid "make series of N frames" msgid "make series of N frames"
msgstr "" msgstr ""
#: cmdlnopts.c:80 #: cmdlnopts.c:79
msgid "make pause for N seconds between expositions" msgid "make pause for N seconds between expositions"
msgstr "" msgstr ""
#: cmdlnopts.c:81 #: cmdlnopts.c:80
msgid "set exposure time to given value (seconds!)" msgid "set exposure time to given value (seconds!)"
msgstr "" msgstr ""
#: cmdlnopts.c:82 #: cmdlnopts.c:81
msgid "cancel current exposition" msgid "cancel current exposition"
msgstr "" msgstr ""
#: cmdlnopts.c:83 #: cmdlnopts.c:82
msgid "" msgid ""
"absolute (not divided by binning!) frame X0 coordinate (-1 - all with " "absolute (not divided by binning!) frame X0 coordinate (-1 - all with "
"overscan)" "overscan)"
msgstr "" msgstr ""
#: cmdlnopts.c:84 #: cmdlnopts.c:83
msgid "absolute frame Y0 coordinate (-1 - all with overscan)" msgid "absolute frame Y0 coordinate (-1 - all with overscan)"
msgstr "" msgstr ""
#: cmdlnopts.c:85 #: cmdlnopts.c:84
msgid "absolute frame X1 coordinate (-1 - all with overscan)" msgid "absolute frame X1 coordinate (-1 - all with overscan)"
msgstr "" msgstr ""
#: cmdlnopts.c:86 #: cmdlnopts.c:85
msgid "absolute frame Y1 coordinate (-1 - all with overscan)" msgid "absolute frame Y1 coordinate (-1 - all with overscan)"
msgstr "" msgstr ""
#: cmdlnopts.c:88 #: cmdlnopts.c:87
msgid "open shutter" msgid "open shutter"
msgstr "" msgstr ""
#: cmdlnopts.c:89 #: cmdlnopts.c:88
msgid "close shutter" msgid "close shutter"
msgstr "" msgstr ""
#: cmdlnopts.c:90 #: cmdlnopts.c:89
msgid "run exposition on LOW @ pin5 I/O port" msgid "run exposition on LOW @ pin5 I/O port"
msgstr "" msgstr ""
#: cmdlnopts.c:91 #: cmdlnopts.c:90
msgid "run exposition on HIGH @ pin5 I/O port" msgid "run exposition on HIGH @ pin5 I/O port"
msgstr "" msgstr ""
#: cmdlnopts.c:92 #: cmdlnopts.c:91
msgid "get value of I/O port pins" msgid "get value of I/O port pins"
msgstr "" msgstr ""
#: cmdlnopts.c:93 #: cmdlnopts.c:92
msgid "move stepper motor asynchronous" msgid "move stepper motor asynchronous"
msgstr "" msgstr ""
#: cmdlnopts.c:95 #: cmdlnopts.c:94
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:96 #: cmdlnopts.c:95
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:98 #: cmdlnopts.c:97
msgid "move focuser to absolute position, mm" msgid "move focuser to absolute position, mm"
msgstr "" msgstr ""
#: cmdlnopts.c:99 #: cmdlnopts.c:98
msgid "move focuser to relative position, mm (only for standalone)" msgid "move focuser to relative position, mm (only for standalone)"
msgstr "" msgstr ""
#: cmdlnopts.c:101 #: cmdlnopts.c:100
msgid "set wheel position" msgid "set wheel position"
msgstr "" msgstr ""
#: cmdlnopts.c:103 #: cmdlnopts.c:102
msgid "CMOS gain level" msgid "CMOS gain level"
msgstr "" msgstr ""
#: cmdlnopts.c:104 #: cmdlnopts.c:103
msgid "CMOS brightness level" msgid "CMOS brightness level"
msgstr "" msgstr ""
#: cmdlnopts.c:106 #: cmdlnopts.c:105
msgid "logging file name (if run as server)" msgid "logging file name (if run as server)"
msgstr "" msgstr ""
#: cmdlnopts.c:107 #: cmdlnopts.c:106
msgid "UNIX socket name (command socket)" msgid "UNIX socket name (command socket)"
msgstr "" msgstr ""
#: cmdlnopts.c:108 #: cmdlnopts.c:107
msgid "local INET command socket port" msgid "local INET command socket port"
msgstr "" msgstr ""
#: cmdlnopts.c:109 #: cmdlnopts.c:108
msgid "INET image socket port" msgid "INET image socket port"
msgstr "" msgstr ""
#: cmdlnopts.c:110 #: cmdlnopts.c:109
msgid "run as client" msgid "run as client"
msgstr "" msgstr ""
#: cmdlnopts.c:111 #: cmdlnopts.c:110
msgid "passive viewer (only get last images)" msgid "passive viewer (only get last images)"
msgstr "" msgstr ""
#: cmdlnopts.c:112 #: cmdlnopts.c:111
msgid "restart image server" msgid "restart image server"
msgstr "" msgstr ""
#: cmdlnopts.c:113 #: cmdlnopts.c:112
msgid "network answer timeout (default: 0.1s)" msgid "network answer timeout (default: 0.1s)"
msgstr "" msgstr ""
#: cmdlnopts.c:113
msgid ""
"get base information about connected hardware (also increasing text messages "
"level to 2)"
msgstr ""
#: cmdlnopts.c:115 #: cmdlnopts.c:115
msgid "shared memory (with image data) key (default: 7777777)" msgid "shared memory (with image data) key (default: 7777777)"
msgstr "" msgstr ""
@@ -269,326 +272,352 @@ msgstr ""
msgid "Display image in OpenGL window" msgid "Display image in OpenGL window"
msgstr "" msgstr ""
#: ccdfunc.c:198 #: ccdfunc.c:216
msgid "Camera device unknown"
msgstr ""
#: ccdfunc.c:221
#, c-format #, c-format
msgid "Can't save file with prefix %s" msgid "Can't save file with prefix %s"
msgstr "" msgstr ""
#: ccdfunc.c:269 #: ccdfunc.c:276
#, c-format #, c-format
msgid "File saved as '%s'" msgid "File saved as '%s'"
msgstr "" msgstr ""
#: ccdfunc.c:278 #: ccdfunc.c:285
msgid "Error saving file" msgid "Error saving file"
msgstr "" msgstr ""
#: ccdfunc.c:333 #: ccdfunc.c:340
#, c-format #, c-format
msgid "Image stat:\n" msgid "Image stat:\n"
msgstr "" msgstr ""
#: ccdfunc.c:342 #: ccdfunc.c:349
msgid "Focuser device not pointed" msgid "Focuser device not pointed"
msgstr "" msgstr ""
#: ccdfunc.c:349 #: ccdfunc.c:356
msgid "No focusers found" msgid "No focusers found"
msgstr "" msgstr ""
#: ccdfunc.c:379 #: ccdfunc.c:386
#, c-format #, c-format
msgid "Found %d focusers, you point number %d" msgid "Found %d focusers, you point number %d"
msgstr "" msgstr ""
#: ccdfunc.c:383 #: ccdfunc.c:390
msgid "Can't set active focuser number" msgid "Can't set active focuser number"
msgstr "" msgstr ""
#: ccdfunc.c:397 #: ccdfunc.c:404
msgid "Can't get focuser limit positions" msgid "Can't get focuser limit positions"
msgstr "" msgstr ""
#: ccdfunc.c:404 #: ccdfunc.c:411
msgid "Can't get current focuser position" msgid "Can't get current focuser position"
msgstr "" msgstr ""
#: ccdfunc.c:418 #: ccdfunc.c:425
#, 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:422 #: ccdfunc.c:429
msgid "Can't home focuser" msgid "Can't home focuser"
msgstr "" msgstr ""
#: ccdfunc.c:424 #: ccdfunc.c:431
#, c-format #, c-format
msgid "Can't set position %g" msgid "Can't set position %g"
msgstr "" msgstr ""
#: ccdfunc.c:430 #: ccdfunc.c:439
msgid "Wheel device not pointed" msgid "Wheel device not pointed"
msgstr "" msgstr ""
#: ccdfunc.c:437 #: ccdfunc.c:446
msgid "No wheels found" msgid "No wheels found"
msgstr "" msgstr ""
#: ccdfunc.c:467 #: ccdfunc.c:476
#, c-format #, c-format
msgid "Found %d wheels, you point number %d" msgid "Found %d wheels, you point number %d"
msgstr "" msgstr ""
#: ccdfunc.c:471 #: ccdfunc.c:480
msgid "Can't set active wheel number" msgid "Can't set active wheel number"
msgstr "" msgstr ""
#: ccdfunc.c:487 #: ccdfunc.c:496
msgid "Can't get max wheel position" msgid "Can't get max wheel position"
msgstr "" msgstr ""
#: ccdfunc.c:494 #: ccdfunc.c:503
#, 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:498 #: ccdfunc.c:507
#, c-format #, c-format
msgid "Can't set wheel position %d" msgid "Can't set wheel position %d"
msgstr "" msgstr ""
#: ccdfunc.c:511 #: ccdfunc.c:522
msgid "Camera plugin have no capture polling funtion." msgid "Camera plugin have no capture polling funtion."
msgstr "" msgstr ""
#: ccdfunc.c:517 #: ccdfunc.c:528
#, c-format #, c-format
msgid "%.1f seconds till exposition ends" msgid "%.1f seconds till exposition ends"
msgstr "" msgstr ""
#: ccdfunc.c:532 #: ccdfunc.c:543
msgid "Camera device not pointed" msgid "Camera device not pointed"
msgstr "" msgstr ""
#: ccdfunc.c:539 ccdfunc.c:540 #: ccdfunc.c:550 ccdfunc.c:551
msgid "No cameras found" msgid "No cameras found"
msgstr "" msgstr ""
#: ccdfunc.c:560 #: ccdfunc.c:571
msgid "Camera plugin have no model name getter" msgid "Camera plugin have no model name getter"
msgstr "" msgstr ""
#: ccdfunc.c:571 #: ccdfunc.c:582
#, c-format #, c-format
msgid "Found %d cameras, you point number %d" msgid "Found %d cameras, you point number %d"
msgstr "" msgstr ""
#: ccdfunc.c:575 #: ccdfunc.c:586
msgid "Can't set active camera number" msgid "Can't set active camera number"
msgstr "" msgstr ""
#: ccdfunc.c:581 #: ccdfunc.c:592
msgid "Camera plugin have no custom commands" msgid "Camera plugin have no custom commands"
msgstr "" msgstr ""
#: ccdfunc.c:606 #: ccdfunc.c:617
msgid "Camera plugin have no fun speed setter" msgid "Camera plugin have no fun speed setter"
msgstr "" msgstr ""
#: ccdfunc.c:609 #: ccdfunc.c:620
msgid "Can't set fan speed" msgid "Can't set fan speed"
msgstr "" msgstr ""
#: ccdfunc.c:610 #: ccdfunc.c:621
#, c-format #, c-format
msgid "Set fan speed to %d" msgid "Set fan speed to %d"
msgstr "" msgstr ""
#: ccdfunc.c:615 #: ccdfunc.c:626
#, c-format #, c-format
msgid "Camera model: %s" msgid "Camera model: %s"
msgstr "" msgstr ""
#: ccdfunc.c:616 #: ccdfunc.c:627
#, c-format #, c-format
msgid "Pixel size: %g x %g" msgid "Pixel size: %g x %g"
msgstr "" msgstr ""
#: ccdfunc.c:622 #: ccdfunc.c:633
#, c-format #, c-format
msgid "Full array: %s" msgid "Full array: %s"
msgstr "" msgstr ""
#: ccdfunc.c:625 #: ccdfunc.c:636
#, c-format #, c-format
msgid "Field of view: %s" msgid "Field of view: %s"
msgstr "" msgstr ""
#: ccdfunc.c:628 #: ccdfunc.c:639
#, c-format #, c-format
msgid "Current format: %s" msgid "Current format: %s"
msgstr "" msgstr ""
#: ccdfunc.c:630 #: ccdfunc.c:641
msgid "Camera plugin have no temperature setter" msgid "Camera plugin have no temperature setter"
msgstr "" msgstr ""
#: ccdfunc.c:631
#, c-format
msgid "Can't set T to %g degC"
msgstr ""
#: ccdfunc.c:640
#, c-format
msgid "Shutter command: %s\n"
msgstr ""
#: ccdfunc.c:642 #: ccdfunc.c:642
#, c-format #, c-format
msgid "Can't set T to %g degC"
msgstr ""
#: ccdfunc.c:651
#, c-format
msgid "Shutter command: %s\n"
msgstr ""
#: ccdfunc.c:653
#, c-format
msgid "Can't run shutter command %s (unsupported?)" msgid "Can't run shutter command %s (unsupported?)"
msgstr "" msgstr ""
#: ccdfunc.c:645 #: ccdfunc.c:656
#, 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:647 #: ccdfunc.c:658
msgid "Can't configure (unsupported?)" msgid "Can't configure (unsupported?)"
msgstr "" msgstr ""
#: ccdfunc.c:654 #: ccdfunc.c:665
msgid "Can't get IOport state (unsupported?)" msgid "Can't get IOport state (unsupported?)"
msgstr "" msgstr ""
#: ccdfunc.c:657 #: ccdfunc.c:668
#, 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:659 #: ccdfunc.c:670
msgid "Can't set IOport" msgid "Can't set IOport"
msgstr "" msgstr ""
#: ccdfunc.c:666 #: ccdfunc.c:677
#, c-format #, c-format
msgid "Set gain to %g" msgid "Set gain to %g"
msgstr "" msgstr ""
#: ccdfunc.c:667 #: ccdfunc.c:678
#, c-format #, c-format
msgid "Can't set gain to %g" msgid "Can't set gain to %g"
msgstr "" msgstr ""
#: ccdfunc.c:672 #: ccdfunc.c:683
#, c-format #, c-format
msgid "Set brightness to %g" msgid "Set brightness to %g"
msgstr "" msgstr ""
#: ccdfunc.c:673 #: ccdfunc.c:684
#, c-format #, c-format
msgid "Can't set brightness to %g" msgid "Can't set brightness to %g"
msgstr "" msgstr ""
#: ccdfunc.c:679 server.c:284 #: ccdfunc.c:690 server.c:330
#, c-format #, c-format
msgid "Can't set binning %dx%d" msgid "Can't set binning %dx%d"
msgstr "" msgstr ""
#: ccdfunc.c:691 server.c:285 #: ccdfunc.c:702 server.c:331
msgid "Can't set given geometry" msgid "Can't set given geometry"
msgstr "" msgstr ""
#: ccdfunc.c:695 #: ccdfunc.c:706
#, c-format #, c-format
msgid "Can't set %d flushes" msgid "Can't set %d flushes"
msgstr "" msgstr ""
#: ccdfunc.c:698 #: ccdfunc.c:709
msgid "Camera plugin have no exposition setter" msgid "Camera plugin have no exposition setter"
msgstr "" msgstr ""
#: ccdfunc.c:700 #: ccdfunc.c:711
#, 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:703 #: ccdfunc.c:714
msgid "Can't change frame type" msgid "Can't change frame type"
msgstr "" msgstr ""
#: ccdfunc.c:706 #: ccdfunc.c:717
msgid "Can't set bit depth" msgid "Can't set bit depth"
msgstr "" msgstr ""
#: ccdfunc.c:708 #: ccdfunc.c:719
msgid "Can't set readout speed" msgid "Can't set readout speed"
msgstr "" msgstr ""
#: ccdfunc.c:709 #: ccdfunc.c:720
#, c-format #, c-format
msgid "Readout mode: %s" msgid "Readout mode: %s"
msgstr "" msgstr ""
#: ccdfunc.c:710 #: ccdfunc.c:721
msgid "Only show statistics" msgid "Only show statistics"
msgstr "" msgstr ""
#: ccdfunc.c:713 #: ccdfunc.c:724
msgid "Can't get current binning" msgid "Can't get current binning"
msgstr "" msgstr ""
#: ccdfunc.c:738 #: ccdfunc.c:749
#, c-format #, c-format
msgid "Capture frame %d" msgid "Capture frame %d"
msgstr "" msgstr ""
#: ccdfunc.c:739 ccdfunc.c:816 server.c:153 server.c:154 #: ccdfunc.c:750 ccdfunc.c:827 server.c:194 server.c:195
msgid "Camera plugin have no function `start exposition`" msgid "Camera plugin have no function `start exposition`"
msgstr "" msgstr ""
#: ccdfunc.c:741 ccdfunc.c:818 server.c:159 server.c:160 #: ccdfunc.c:752 ccdfunc.c:829 server.c:200 server.c:201
msgid "Can't start exposition" msgid "Can't start exposition"
msgstr "" msgstr ""
#: ccdfunc.c:746 #: ccdfunc.c:757
msgid "Can't capture image" msgid "Can't capture image"
msgstr "" msgstr ""
#: ccdfunc.c:749 #: ccdfunc.c:760
msgid "Read grabbed image" msgid "Read grabbed image"
msgstr "" msgstr ""
#: ccdfunc.c:751 ccdfunc.c:831 server.c:177 server.c:178 #: ccdfunc.c:762 ccdfunc.c:842 server.c:218 server.c:219
msgid "Camera plugin have no function `capture`" msgid "Camera plugin have no function `capture`"
msgstr "" msgstr ""
#: ccdfunc.c:753 ccdfunc.c:832 #: ccdfunc.c:764 ccdfunc.c:843
msgid "Can't grab image" msgid "Can't grab image"
msgstr "" msgstr ""
#: ccdfunc.c:767 client.c:289 #: ccdfunc.c:778 client.c:491
#, c-format #, c-format
msgid "%d seconds till pause ends\n" msgid "%d seconds till pause ends\n"
msgstr "" msgstr ""
#: ccdfunc.c:829 #: ccdfunc.c:840
msgid "Some error when capture" msgid "Some error when capture"
msgstr "" msgstr ""
#: server.c:205 #: server.c:247
msgid "No camera device" msgid "No camera device"
msgstr "" msgstr ""
#: client.c:275 #: client.c:449
msgid "Can't make exposition" msgid "Can't make exposition"
msgstr "" msgstr ""
#: client.c:305 #: client.c:503
msgid "Server timeout" msgid "Server timeout"
msgstr "" msgstr ""
#: imageview.c:51
msgid "Already initialized!"
msgstr ""
#: imageview.c:312
msgid "Can't init mutex!"
msgstr ""
#: imageview.c:425
#, c-format
msgid "Histogram conversion: %s"
msgstr ""
#: imageview.c:704
msgid "Can't open OpenGL window, image preview will be inaccessible"
msgstr ""
#: imageview.c:746
#, c-format
msgid "Equalization of histogram: %s"
msgstr ""
#: imageview.c:746
msgid "on"
msgstr ""
#: imageview.c:746
msgid "off"
msgstr ""

View File

@@ -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: 2026-04-18 15:55+0300\n" "POT-Creation-Date: 2026-06-08 16:46+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,217 +16,225 @@ 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:517 #: ccdfunc.c:528
#, c-format #, c-format
msgid "%.1f seconds till exposition ends" msgid "%.1f seconds till exposition ends"
msgstr "%.1f ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÜËÓÐÏÚÉÃÉÉ" msgstr "%.1f ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÜËÓÐÏÚÉÃÉÉ"
#: ccdfunc.c:767 client.c:289 #: ccdfunc.c:778 client.c:491
#, c-format #, c-format
msgid "%d seconds till pause ends\n" msgid "%d seconds till pause ends\n"
msgstr "%d ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÐÁÕÚÙ\n" msgstr "%d ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÐÁÕÚÙ\n"
#: cmdlnopts.c:104 #: imageview.c:51
msgid "Already initialized!"
msgstr "õÖÅ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÎÏ!"
#: cmdlnopts.c:103
msgid "CMOS brightness level" msgid "CMOS brightness level"
msgstr "ÕÒÏ×ÅÎØ ÑÒËÏÓÔÉ CMOS" msgstr "ÕÒÏ×ÅÎØ ÑÒËÏÓÔÉ CMOS"
#: cmdlnopts.c:103 #: cmdlnopts.c:102
msgid "CMOS gain level" msgid "CMOS gain level"
msgstr "ÕÒÏ×ÅÎØ Gain CMOS" msgstr "ÕÒÏ×ÅÎØ Gain CMOS"
#: ccdfunc.c:532 #: ccdfunc.c:543
msgid "Camera device not pointed" msgid "Camera device not pointed"
msgstr "õÓÔÒÏÊÓÔ×Ï Ó×ÅÏÐÒÉÅÍÎÉËÁ ÎÅ ÐÏÄËÌÀÞÅÎÏ" msgstr "õÓÔÒÏÊÓÔ×Ï Ó×ÅÏÐÒÉÅÍÎÉËÁ ÎÅ ÐÏÄËÌÀÞÅÎÏ"
#: ccdfunc.c:198 #: ccdfunc.c:626
msgid "Camera device unknown"
msgstr "õÓÔÒÏÊÓÔ×Ï Ó×ÅÏÐÒÉÅÍÎÉËÁ ÎÅ ÏÐÏÚÎÁÎÏ"
#: ccdfunc.c:615
#, c-format #, c-format
msgid "Camera model: %s" msgid "Camera model: %s"
msgstr "íÏÄÅÌØ Ó×ÅÔÏÐÒÉÅÍÎÉËÁ: %s" msgstr "íÏÄÅÌØ Ó×ÅÔÏÐÒÉÅÍÎÉËÁ: %s"
#: ccdfunc.c:511 #: ccdfunc.c:522
#, fuzzy #, fuzzy
msgid "Camera plugin have no capture polling funtion." msgid "Camera plugin have no capture polling funtion."
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ" msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
#: ccdfunc.c:581 #: ccdfunc.c:592
msgid "Camera plugin have no custom commands" msgid "Camera plugin have no custom commands"
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ" msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
#: ccdfunc.c:698 #: ccdfunc.c:709
#, fuzzy #, fuzzy
msgid "Camera plugin have no exposition setter" msgid "Camera plugin have no exposition setter"
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ" msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
#: ccdfunc.c:606 #: ccdfunc.c:617
#, fuzzy #, fuzzy
msgid "Camera plugin have no fun speed setter" msgid "Camera plugin have no fun speed setter"
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ" msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
#: ccdfunc.c:751 ccdfunc.c:831 server.c:177 server.c:178 #: ccdfunc.c:762 ccdfunc.c:842 server.c:218 server.c:219
#, fuzzy #, fuzzy
msgid "Camera plugin have no function `capture`" msgid "Camera plugin have no function `capture`"
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ" msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
#: ccdfunc.c:739 ccdfunc.c:816 server.c:153 server.c:154 #: ccdfunc.c:750 ccdfunc.c:827 server.c:194 server.c:195
#, fuzzy #, fuzzy
msgid "Camera plugin have no function `start exposition`" msgid "Camera plugin have no function `start exposition`"
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ" msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
#: ccdfunc.c:560 #: ccdfunc.c:571
#, fuzzy #, fuzzy
msgid "Camera plugin have no model name getter" msgid "Camera plugin have no model name getter"
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ" msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
#: ccdfunc.c:630 #: ccdfunc.c:641
#, fuzzy #, fuzzy
msgid "Camera plugin have no temperature setter" msgid "Camera plugin have no temperature setter"
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ" msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
#: ccdfunc.c:746 #: ccdfunc.c:757
msgid "Can't capture image" msgid "Can't capture image"
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ" msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
#: ccdfunc.c:703 #: ccdfunc.c:714
msgid "Can't change frame type" msgid "Can't change frame type"
msgstr "îÅ ÍÏÇÕ ÉÚÍÅÎÉÔØ ÔÉÐ ËÁÄÒÁ" msgstr "îÅ ÍÏÇÕ ÉÚÍÅÎÉÔØ ÔÉÐ ËÁÄÒÁ"
#: ccdfunc.c:647 #: ccdfunc.c:658
msgid "Can't configure (unsupported?)" msgid "Can't configure (unsupported?)"
msgstr "îÅ ÍÏÇÕ ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ (ÏÐÃÉÑ ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)" msgstr "îÅ ÍÏÇÕ ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ (ÏÐÃÉÑ ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)"
#: ccdfunc.c:654 #: ccdfunc.c:665
msgid "Can't get IOport state (unsupported?)" msgid "Can't get IOport state (unsupported?)"
msgstr "îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÓÏÓÔÏÑÎÉÅ ÐÏÒÔÁ I/O (ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)" msgstr "îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÓÏÓÔÏÑÎÉÅ ÐÏÒÔÁ I/O (ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)"
#: ccdfunc.c:713 #: ccdfunc.c:724
msgid "Can't get current binning" msgid "Can't get current binning"
msgstr "îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÔÅËÕÝÅÅ ÚÎÁÞÅÎÉÅ ÂÉÎÎÉÎÇÁ" msgstr "îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÔÅËÕÝÅÅ ÚÎÁÞÅÎÉÅ ÂÉÎÎÉÎÇÁ"
#: ccdfunc.c:404 #: ccdfunc.c:411
msgid "Can't get current focuser position" msgid "Can't get current focuser position"
msgstr "îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÔÅËÕÝÕÀ ÐÏÚÉÃÉÀ ÆÏËÕÓÅÒÁ" msgstr "îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÔÅËÕÝÕÀ ÐÏÚÉÃÉÀ ÆÏËÕÓÅÒÁ"
#: ccdfunc.c:397 #: ccdfunc.c:404
msgid "Can't get focuser limit positions" msgid "Can't get focuser limit positions"
msgstr "îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÐÒÅÄÅÌØÎÕÀ ÐÏÚÉÃÉÀ ÆÏËÕÓÅÒÁ" msgstr "îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÐÒÅÄÅÌØÎÕÀ ÐÏÚÉÃÉÀ ÆÏËÕÓÅÒÁ"
#: ccdfunc.c:487 #: ccdfunc.c:496
msgid "Can't get max wheel position" msgid "Can't get max wheel position"
msgstr "îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÐÒÅÄÅÌØÎÕÀ ÐÏÚÉÃÉÀ ËÏÌÅÓÁ" msgstr "îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÐÒÅÄÅÌØÎÕÀ ÐÏÚÉÃÉÀ ËÏÌÅÓÁ"
#: ccdfunc.c:753 ccdfunc.c:832 #: ccdfunc.c:764 ccdfunc.c:843
msgid "Can't grab image" msgid "Can't grab image"
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ" msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
#: ccdfunc.c:422 #: ccdfunc.c:429
msgid "Can't home focuser" msgid "Can't home focuser"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÆÏËÕÓÅÒ × ÎÕÌØ" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÆÏËÕÓÅÒ × ÎÕÌØ"
#: client.c:275 #: imageview.c:312
msgid "Can't init mutex!"
msgstr "îÅ ÍÏÇÕ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÔØ ÍØÀÔÅËÓ!"
#: client.c:449
msgid "Can't make exposition" msgid "Can't make exposition"
msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ ÜËÓÐÏÚÉÃÉÀ" msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ ÜËÓÐÏÚÉÃÉÀ"
#: ccdfunc.c:642 #: imageview.c:704
msgid "Can't open OpenGL window, image preview will be inaccessible"
msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ ÏËÎÏ OpenGL, ÏÔÏÂÒÁÖÅÎÉÅ ÂÕÄÅÔ ÎÅÄÏÓÔÕÐÎÏ"
#: ccdfunc.c:653
#, c-format #, c-format
msgid "Can't run shutter command %s (unsupported?)" msgid "Can't run shutter command %s (unsupported?)"
msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ ËÏÍÁÎÄÕ ÚÁÔ×ÏÒÁ %s (ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)" msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ ËÏÍÁÎÄÕ ÚÁÔ×ÏÒÁ %s (ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)"
#: ccdfunc.c:221 #: ccdfunc.c:216
#, c-format #, c-format
msgid "Can't save file with prefix %s" msgid "Can't save file with prefix %s"
msgstr "îÅ ÍÏÇÕ ÓÏÈÒÁÎÉÔØ ÆÁÊÌ Ó ÐÒÅÆÉËÓÏÍ %s" msgstr "îÅ ÍÏÇÕ ÓÏÈÒÁÎÉÔØ ÆÁÊÌ Ó ÐÒÅÆÉËÓÏÍ %s"
#: ccdfunc.c:695 #: ccdfunc.c:706
#, c-format #, c-format
msgid "Can't set %d flushes" msgid "Can't set %d flushes"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ %d ÓÂÒÏÓÏ×" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ %d ÓÂÒÏÓÏ×"
#: ccdfunc.c:659 #: ccdfunc.c:670
msgid "Can't set IOport" msgid "Can't set IOport"
msgstr "îÅ ÍÏÇÕ ÐÏÍÅÎÑÔØ ÚÎÁÞÅÎÉÑ ÐÏÒÔÁ I/O" msgstr "îÅ ÍÏÇÕ ÐÏÍÅÎÑÔØ ÚÎÁÞÅÎÉÑ ÐÏÒÔÁ I/O"
#: ccdfunc.c:631 #: ccdfunc.c:642
#, c-format #, c-format
msgid "Can't set T to %g degC" msgid "Can't set T to %g degC"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÔÅÍÐÅÒÁÔÕÒÕ × %g ÇÒÁÄã" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÔÅÍÐÅÒÁÔÕÒÕ × %g ÇÒÁÄã"
#: ccdfunc.c:575 #: ccdfunc.c:586
msgid "Can't set active camera number" msgid "Can't set active camera number"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÊ ËÁÍÅÒÙ" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÊ ËÁÍÅÒÙ"
#: ccdfunc.c:383 #: ccdfunc.c:390
msgid "Can't set active focuser number" msgid "Can't set active focuser number"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÇÏ ÆÏËÕÓÅÒÁ" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÇÏ ÆÏËÕÓÅÒÁ"
#: ccdfunc.c:471 #: ccdfunc.c:480
msgid "Can't set active wheel number" msgid "Can't set active wheel number"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÇÏ ËÏÌÅÓÁ" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÇÏ ËÏÌÅÓÁ"
#: ccdfunc.c:679 server.c:284 #: ccdfunc.c:690 server.c:330
#, c-format #, c-format
msgid "Can't set binning %dx%d" msgid "Can't set binning %dx%d"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÂÉÎÎÉÎÇ %dx%d" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÂÉÎÎÉÎÇ %dx%d"
#: ccdfunc.c:706 #: ccdfunc.c:717
msgid "Can't set bit depth" msgid "Can't set bit depth"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÒÁÚÒÑÄÎÏÓÔØ áãð" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÒÁÚÒÑÄÎÏÓÔØ áãð"
#: ccdfunc.c:673 #: ccdfunc.c:684
#, c-format #, c-format
msgid "Can't set brightness to %g" msgid "Can't set brightness to %g"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÑÒËÏÓÔØ × %g" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÑÒËÏÓÔØ × %g"
#: ccdfunc.c:700 #: ccdfunc.c:711
#, c-format #, c-format
msgid "Can't set exposure time to %f seconds" msgid "Can't set exposure time to %f seconds"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÜËÓÐÏÚÉÃÉÀ × %f ÓÅËÕÎÄ" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÜËÓÐÏÚÉÃÉÀ × %f ÓÅËÕÎÄ"
#: ccdfunc.c:609 #: ccdfunc.c:620
msgid "Can't set fan speed" msgid "Can't set fan speed"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ×ÅÎÔÉÌÑÔÏÒÏ×" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ×ÅÎÔÉÌÑÔÏÒÏ×"
#: ccdfunc.c:667 #: ccdfunc.c:678
#, c-format #, c-format
msgid "Can't set gain to %g" msgid "Can't set gain to %g"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ Gain × %g" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ Gain × %g"
#: ccdfunc.c:691 server.c:285 #: ccdfunc.c:702 server.c:331
msgid "Can't set given geometry" msgid "Can't set given geometry"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÇÅÏÍÅÔÒÉÀ" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÇÅÏÍÅÔÒÉÀ"
#: ccdfunc.c:424 #: ccdfunc.c:431
#, c-format #, c-format
msgid "Can't set position %g" msgid "Can't set position %g"
msgstr "îÅ ÍÏÇÕ ÉÚÍÅÎÉÔØ ÐÏÚÉÃÉÀ ÎÁ %g" msgstr "îÅ ÍÏÇÕ ÉÚÍÅÎÉÔØ ÐÏÚÉÃÉÀ ÎÁ %g"
#: ccdfunc.c:418 #: ccdfunc.c:425
#, 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 "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÐÏÚÉÃÉÀ %g: ×ÎÅ ÐÒÅÄÅÌÏ× [%g, %g]" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÐÏÚÉÃÉÀ %g: ×ÎÅ ÐÒÅÄÅÌÏ× [%g, %g]"
#: ccdfunc.c:708 #: ccdfunc.c:719
msgid "Can't set readout speed" msgid "Can't set readout speed"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ÓÞÉÔÙ×ÁÎÉÑ" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ÓÞÉÔÙ×ÁÎÉÑ"
#: ccdfunc.c:498 #: ccdfunc.c:507
#, c-format #, c-format
msgid "Can't set wheel position %d" msgid "Can't set wheel position %d"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÐÏÌÏÖÅÎÉÅ ËÏÌÅÓÁ %d" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÐÏÌÏÖÅÎÉÅ ËÏÌÅÓÁ %d"
#: ccdfunc.c:741 ccdfunc.c:818 server.c:159 server.c:160 #: ccdfunc.c:752 ccdfunc.c:829 server.c:200 server.c:201
msgid "Can't start exposition" msgid "Can't start exposition"
msgstr "îÅ ÍÏÇÕ ÎÁÞÁÔØ ÜËÓÐÏÚÉÃÉÀ" msgstr "îÅ ÍÏÇÕ ÎÁÞÁÔØ ÜËÓÐÏÚÉÃÉÀ"
#: ccdfunc.c:738 #: ccdfunc.c:749
#, c-format #, c-format
msgid "Capture frame %d" msgid "Capture frame %d"
msgstr "úÁÈ×ÁÔ ËÁÄÒÁ %d" msgstr "úÁÈ×ÁÔ ËÁÄÒÁ %d"
#: ccdfunc.c:628 #: ccdfunc.c:639
#, c-format #, c-format
msgid "Current format: %s" msgid "Current format: %s"
msgstr "ôÅËÕÝÉÊ ÆÏÒÍÁÔ: %s" msgstr "ôÅËÕÝÉÊ ÆÏÒÍÁÔ: %s"
@@ -235,157 +243,167 @@ msgstr "
msgid "Display image in OpenGL window" msgid "Display image in OpenGL window"
msgstr "ÏÔÏÂÒÁÖÅÎÉÅ ÉÚÏÂÒÁÖÅÎÉÑ × ÏËÎÅ OpenGL" msgstr "ÏÔÏÂÒÁÖÅÎÉÅ ÉÚÏÂÒÁÖÅÎÉÑ × ÏËÎÅ OpenGL"
#: ccdfunc.c:278 #: imageview.c:746
#, c-format
msgid "Equalization of histogram: %s"
msgstr "üË×ÁÌÉÚÁÃÉÑ ÇÉÓÔÏÇÒÁÍÍÙ: %s"
#: ccdfunc.c:285
msgid "Error saving file" msgid "Error saving file"
msgstr "ïÛÉÂËÁ ÓÏÈÒÁÎÅÎÉÑ ÆÁÊÌÁ" msgstr "ïÛÉÂËÁ ÓÏÈÒÁÎÅÎÉÑ ÆÁÊÌÁ"
#: ccdfunc.c:625 #: ccdfunc.c:636
#, c-format #, c-format
msgid "Field of view: %s" msgid "Field of view: %s"
msgstr "ðÏÌÅ ÚÒÅÎÉÑ: %s" msgstr "ðÏÌÅ ÚÒÅÎÉÑ: %s"
#: ccdfunc.c:269 #: ccdfunc.c:276
#, c-format #, c-format
msgid "File saved as '%s'" msgid "File saved as '%s'"
msgstr "æÁÊÌ ÓÏÈÒÁÎÅÎ ËÁË '%s'" msgstr "æÁÊÌ ÓÏÈÒÁÎÅÎ ËÁË '%s'"
#: ccdfunc.c:342 #: ccdfunc.c:349
msgid "Focuser device not pointed" msgid "Focuser device not pointed"
msgstr "õÓÔÒÏÊÓÔ×Ï ÆÏËÕÓÅÒÁ ÎÅ ÕËÁÚÁÎÏ" msgstr "õÓÔÒÏÊÓÔ×Ï ÆÏËÕÓÅÒÁ ÎÅ ÕËÁÚÁÎÏ"
#: ccdfunc.c:571 #: ccdfunc.c:582
#, c-format #, c-format
msgid "Found %d cameras, you point number %d" msgid "Found %d cameras, you point number %d"
msgstr "ïÂÎÁÒÕÖÅÎÏ %d ËÁÍÅÒ, ×Ù ÕËÁÚÁÌÉ %d" msgstr "ïÂÎÁÒÕÖÅÎÏ %d ËÁÍÅÒ, ×Ù ÕËÁÚÁÌÉ %d"
#: ccdfunc.c:379 #: ccdfunc.c:386
#, c-format #, c-format
msgid "Found %d focusers, you point number %d" msgid "Found %d focusers, you point number %d"
msgstr "ïÂÎÁÒÕÖÅÎÏ %d ÆÏËÕÓÅÒÏ×, ×Ù ÕËÁÚÁÌÉ %d" msgstr "ïÂÎÁÒÕÖÅÎÏ %d ÆÏËÕÓÅÒÏ×, ×Ù ÕËÁÚÁÌÉ %d"
#: ccdfunc.c:467 #: ccdfunc.c:476
#, c-format #, c-format
msgid "Found %d wheels, you point number %d" msgid "Found %d wheels, you point number %d"
msgstr "ïÂÎÁÒÕÖÅÎÏ %d ËÏÌÅÓ, ×Ù ÕËÁÚÁÌÉ %d" msgstr "ïÂÎÁÒÕÖÅÎÏ %d ËÏÌÅÓ, ×Ù ÕËÁÚÁÌÉ %d"
#: ccdfunc.c:622 #: ccdfunc.c:633
#, c-format #, c-format
msgid "Full array: %s" msgid "Full array: %s"
msgstr "ðÏÌÎÙÊ ÆÏÒÍÁÔ: %s" msgstr "ðÏÌÎÙÊ ÆÏÒÍÁÔ: %s"
#: cmdlnopts.c:109 #: imageview.c:425
#, c-format
msgid "Histogram conversion: %s"
msgstr "ðÒÅÏÂÒÁÚÏ×ÁÎÉÅ ÇÉÓÔÏÇÒÁÍÍÙ: %s"
#: cmdlnopts.c:108
msgid "INET image socket port" msgid "INET image socket port"
msgstr "ÐÏÒÔ ÌÏËÁÌØÎÏÇÏ ÓÅÔÅ×ÏÇÏ ÓÏËÅÔÁ ÐÅÒÅÄÁÞÉ ÉÚÏÂÒÁÖÅÎÉÑ" msgstr "ÐÏÒÔ ÌÏËÁÌØÎÏÇÏ ÓÅÔÅ×ÏÇÏ ÓÏËÅÔÁ ÐÅÒÅÄÁÞÉ ÉÚÏÂÒÁÖÅÎÉÑ"
#: ccdfunc.c:333 #: ccdfunc.c:340
#, c-format #, c-format
msgid "Image stat:\n" msgid "Image stat:\n"
msgstr "óÔÁÔÉÓÔÉËÁ ÐÏ ÉÚÏÂÒÁÖÅÎÉÀ: \n" msgstr "óÔÁÔÉÓÔÉËÁ ÐÏ ÉÚÏÂÒÁÖÅÎÉÀ: \n"
#: cmdlnopts.c:76 #: cmdlnopts.c:75
msgid "N flushes before exposing (default: 1)" msgid "N flushes before exposing (default: 1)"
msgstr "N ÚÁÓ×ÅÞÉ×ÁÎÉÊ ÐÅÒÅÄ ÜËÓÐÏÚÉÃÉÅÊ (ÐÏ ÕÍÏÌÞÁÎÉÀ: 1)" msgstr "N ÚÁÓ×ÅÞÉ×ÁÎÉÊ ÐÅÒÅÄ ÜËÓÐÏÚÉÃÉÅÊ (ÐÏ ÕÍÏÌÞÁÎÉÀ: 1)"
#: server.c:205 #: server.c:247
msgid "No camera device" msgid "No camera device"
msgstr "îÅ ÕËÁÚÁÎÏ ÕÓÔÒÏÊÓÔ×Ï ËÁÍÅÒÙ" msgstr "îÅ ÕËÁÚÁÎÏ ÕÓÔÒÏÊÓÔ×Ï ËÁÍÅÒÙ"
#: ccdfunc.c:539 ccdfunc.c:540 #: ccdfunc.c:550 ccdfunc.c:551
msgid "No cameras found" msgid "No cameras found"
msgstr "ëÁÍÅÒ ÎÅ ÏÂÎÁÒÕÖÅÎÏ" msgstr "ëÁÍÅÒ ÎÅ ÏÂÎÁÒÕÖÅÎÏ"
#: ccdfunc.c:349 #: ccdfunc.c:356
msgid "No focusers found" msgid "No focusers found"
msgstr "æÏËÕÓÅÒÏ× ÎÅ ÏÂÎÁÒÕÖÅÎÏ" msgstr "æÏËÕÓÅÒÏ× ÎÅ ÏÂÎÁÒÕÖÅÎÏ"
#: ccdfunc.c:437 #: ccdfunc.c:446
msgid "No wheels found" msgid "No wheels found"
msgstr "ôÕÒÅÌÅÊ ÎÅ ÏÂÎÁÒÕÖÅÎÏ" msgstr "ôÕÒÅÌÅÊ ÎÅ ÏÂÎÁÒÕÖÅÎÏ"
#: ccdfunc.c:710 #: ccdfunc.c:721
msgid "Only show statistics" msgid "Only show statistics"
msgstr "ôÏÌØËÏ ÏÔÏÂÒÁÚÉÔØ ÓÔÁÔÉÓÔÉËÕ" msgstr "ôÏÌØËÏ ÏÔÏÂÒÁÚÉÔØ ÓÔÁÔÉÓÔÉËÕ"
#: ccdfunc.c:616 #: ccdfunc.c:627
#, c-format #, c-format
msgid "Pixel size: %g x %g" msgid "Pixel size: %g x %g"
msgstr "òÁÚÍÅÒ ÐÉËÓÅÌÑ: %g x %g" msgstr "òÁÚÍÅÒ ÐÉËÓÅÌÑ: %g x %g"
#: ccdfunc.c:749 #: ccdfunc.c:760
msgid "Read grabbed image" msgid "Read grabbed image"
msgstr "óÞÉÔÙ×ÁÎÉÅ ÉÚÏÂÒÁÖÅÎÉÑ" msgstr "óÞÉÔÙ×ÁÎÉÅ ÉÚÏÂÒÁÖÅÎÉÑ"
#: ccdfunc.c:709 #: ccdfunc.c:720
#, c-format #, c-format
msgid "Readout mode: %s" msgid "Readout mode: %s"
msgstr "òÅÖÉÍ ÓÞÉÔÙ×ÁÎÉÑ: %s" msgstr "òÅÖÉÍ ÓÞÉÔÙ×ÁÎÉÑ: %s"
#: client.c:305 #: client.c:503
msgid "Server timeout" msgid "Server timeout"
msgstr "ôÁÊÍÁÕÔ ÓÅÒ×ÅÒÁ" msgstr "ôÁÊÍÁÕÔ ÓÅÒ×ÅÒÁ"
#: ccdfunc.c:672 #: ccdfunc.c:683
#, c-format #, c-format
msgid "Set brightness to %g" msgid "Set brightness to %g"
msgstr "õÓÔÁÎÏ×ÉÔØ ÑÒËÏÓÔØ × %g" msgstr "õÓÔÁÎÏ×ÉÔØ ÑÒËÏÓÔØ × %g"
#: ccdfunc.c:610 #: ccdfunc.c:621
#, c-format #, c-format
msgid "Set fan speed to %d" msgid "Set fan speed to %d"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ×ÅÎÔÉÌÑÔÏÒÏ× × %d" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ×ÅÎÔÉÌÑÔÏÒÏ× × %d"
#: ccdfunc.c:666 #: ccdfunc.c:677
#, c-format #, c-format
msgid "Set gain to %g" msgid "Set gain to %g"
msgstr "õÓÔÁÎÏ×ÉÔØ Gain × %g" msgstr "õÓÔÁÎÏ×ÉÔØ Gain × %g"
#: ccdfunc.c:640 #: ccdfunc.c:651
#, c-format #, c-format
msgid "Shutter command: %s\n" msgid "Shutter command: %s\n"
msgstr "ëÏÍÁÎÄÁ ÚÁÔ×ÏÒÁ: %s\n" msgstr "ëÏÍÁÎÄÁ ÚÁÔ×ÏÒÁ: %s\n"
#: ccdfunc.c:829 #: ccdfunc.c:840
msgid "Some error when capture" msgid "Some error when capture"
msgstr "ïÛÉÂËÁ ÐÒÉ ÚÁÈ×ÁÔÅ" msgstr "ïÛÉÂËÁ ÐÒÉ ÚÁÈ×ÁÔÅ"
#: ccdfunc.c:645 #: ccdfunc.c:656
#, c-format #, c-format
msgid "Try to configure I/O port as %d" msgid "Try to configure I/O port as %d"
msgstr "ðÏÐÙÔËÁ ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ ÐÏÒÔ I/O ËÁË %d" msgstr "ðÏÐÙÔËÁ ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ ÐÏÒÔ I/O ËÁË %d"
#: ccdfunc.c:657 #: ccdfunc.c:668
#, c-format #, c-format
msgid "Try to write %d to I/O port" msgid "Try to write %d to I/O port"
msgstr "ðÏÐÙÔËÁ ÚÁÐÉÓÉ %d × ÐÏÒÔ I/O" msgstr "ðÏÐÙÔËÁ ÚÁÐÉÓÉ %d × ÐÏÒÔ I/O"
#: cmdlnopts.c:107 #: cmdlnopts.c:106
msgid "UNIX socket name (command socket)" msgid "UNIX socket name (command socket)"
msgstr "ÉÍÑ UNIX-ÓÏËÅÔÁ" msgstr "ÉÍÑ UNIX-ÓÏËÅÔÁ"
#: ccdfunc.c:430 #: ccdfunc.c:439
msgid "Wheel device not pointed" msgid "Wheel device not pointed"
msgstr "õÓÔÒÏÊÓÔ×Ï ÔÕÒÅÌÉ ÎÅ ÕËÁÚÁÎÏ" msgstr "õÓÔÒÏÊÓÔ×Ï ÔÕÒÅÌÉ ÎÅ ÕËÁÚÁÎÏ"
#: ccdfunc.c:494 #: ccdfunc.c:503
#, c-format #, c-format
msgid "Wheel position should be from 0 to %d" msgid "Wheel position should be from 0 to %d"
msgstr "ðÏÚÉÃÉÑ ËÏÌÅÓÁ ÄÏÌÖÎÁ ÂÙÔØ ÏÔ 0 ÄÏ %d" msgstr "ðÏÚÉÃÉÑ ËÏÌÅÓÁ ÄÏÌÖÎÁ ÂÙÔØ ÏÔ 0 ÄÏ %d"
#: cmdlnopts.c:83 #: cmdlnopts.c:82
msgid "absolute (not divided by binning!) frame X0 coordinate (-1 - all " msgid "absolute (not divided by binning!) frame X0 coordinate (-1 - all "
"with overscan)" "with overscan)"
msgstr "ÁÂÓÏÌÀÔÎÁÑ (ÎÅ ÄÅÌÅÎÎÁÑ ÎÁ ÂÉÎÎÉÎÇ!) ËÏÏÒÄÉÎÁÔÁ X0 (-1 - ×ËÌÀÞÁÑ " msgstr "ÁÂÓÏÌÀÔÎÁÑ (ÎÅ ÄÅÌÅÎÎÁÑ ÎÁ ÂÉÎÎÉÎÇ!) ËÏÏÒÄÉÎÁÔÁ X0 (-1 - ×ËÌÀÞÁÑ "
"Ï×ÅÒÓËÁÎ)" "Ï×ÅÒÓËÁÎ)"
#: cmdlnopts.c:85 #: cmdlnopts.c:84
msgid "absolute frame X1 coordinate (-1 - all with overscan)" msgid "absolute frame X1 coordinate (-1 - all with overscan)"
msgstr "ÁÂÓÏÌÀÔÎÁÑ ËÏÏÒÄÉÎÁÔÁ X1 (-1 - ×ËÌÀÞÁÑ Ï×ÅÒÓËÁÎ)" msgstr "ÁÂÓÏÌÀÔÎÁÑ ËÏÏÒÄÉÎÁÔÁ X1 (-1 - ×ËÌÀÞÁÑ Ï×ÅÒÓËÁÎ)"
#: cmdlnopts.c:84 #: cmdlnopts.c:83
msgid "absolute frame Y0 coordinate (-1 - all with overscan)" msgid "absolute frame Y0 coordinate (-1 - all with overscan)"
msgstr "ÁÂÓÏÌÀÔÎÁÑ ËÏÏÒÄÉÎÁÔÁ Y0 (-1 - ×ËÌÀÞÁÑ Ï×ÅÒÓËÁÎ)" msgstr "ÁÂÓÏÌÀÔÎÁÑ ËÏÏÒÄÉÎÁÔÁ Y0 (-1 - ×ËÌÀÞÁÑ Ï×ÅÒÓËÁÎ)"
#: cmdlnopts.c:86 #: cmdlnopts.c:85
msgid "absolute frame Y1 coordinate (-1 - all with overscan)" msgid "absolute frame Y1 coordinate (-1 - all with overscan)"
msgstr "ÁÂÓÏÌÀÔÎÁÑ ËÏÏÒÄÉÎÁÔÁ Y1 (-1 - ×ËÌÀÞÁÑ Ï×ÅÒÓËÁÎ)" msgstr "ÁÂÓÏÌÀÔÎÁÑ ËÏÏÒÄÉÎÁÔÁ Y1 (-1 - ×ËÌÀÞÁÑ Ï×ÅÒÓËÁÎ)"
@@ -401,11 +419,11 @@ msgstr "
msgid "camera device plugin (e.g. devfli.so)" msgid "camera device plugin (e.g. devfli.so)"
msgstr "ÐÌÁÇÉÎ ËÁÍÅÒÙ (ÎÁÐÒÉÍÅÒ, devfli.so)" msgstr "ÐÌÁÇÉÎ ËÁÍÅÒÙ (ÎÁÐÒÉÍÅÒ, devfli.so)"
#: cmdlnopts.c:82 #: cmdlnopts.c:81
msgid "cancel current exposition" msgid "cancel current exposition"
msgstr "ÏÔÍÅÎÁ ÔÅËÕÝÅÊ ÜËÓÐÏÚÉÃÉÉ" msgstr "ÏÔÍÅÎÁ ÔÅËÕÝÅÊ ÜËÓÐÏÚÉÃÉÉ"
#: cmdlnopts.c:89 #: cmdlnopts.c:88
msgid "close shutter" msgid "close shutter"
msgstr "ÚÁËÒÙÔØ ÚÁÔ×ÏÒ" msgstr "ÚÁËÒÙÔØ ÚÁÔ×ÏÒ"
@@ -413,7 +431,7 @@ msgstr "
msgid "common device plugin (e.g devfli.so)" msgid "common device plugin (e.g devfli.so)"
msgstr "ÏÂÝÉÊ ÐÌÁÇÉÎ ÄÌÑ ×ÓÅÈ ÕÓÔÒÏÊÓÔ× (ÎÁÐÒÉÍÅÒ, devfli.so)" msgstr "ÏÂÝÉÊ ÐÌÁÇÉÎ ÄÌÑ ×ÓÅÈ ÕÓÔÒÏÊÓÔ× (ÎÁÐÒÉÍÅÒ, devfli.so)"
#: cmdlnopts.c:96 #: cmdlnopts.c:95
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 "ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ ÐÏÒÔ I/O × ÚÁÄÁÎÎÏÅ ÓÏÓÔÏÑÎÉÅ (ÄÅÓÑÔÉÞÎÏÅ ÞÉÓÌÏ, " msgstr "ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ ÐÏÒÔ I/O × ÚÁÄÁÎÎÏÅ ÓÏÓÔÏÑÎÉÅ (ÄÅÓÑÔÉÞÎÏÅ ÞÉÓÌÏ, "
@@ -444,11 +462,16 @@ msgid "force using image through socket transition even if can use SHM"
msgstr "ÐÒÉÎÕÄÉÔÅÌØÎÏ ÂÒÁÔØ ÉÚÏÂÒÁÖÅÎÉÑ ÉÚ ÓÏËÅÔÁ ÄÁÖÅ ÅÓÌÉ ×ÏÚÍÏÖÎÏ " msgstr "ÐÒÉÎÕÄÉÔÅÌØÎÏ ÂÒÁÔØ ÉÚÏÂÒÁÖÅÎÉÑ ÉÚ ÓÏËÅÔÁ ÄÁÖÅ ÅÓÌÉ ×ÏÚÍÏÖÎÏ "
"ÐÏÌØÚÏ×ÁÔØÓÑ ÒÁÚÄÅÌÑÅÍÏÊ ÐÁÍÑÔØÀ" "ÐÏÌØÚÏ×ÁÔØÓÑ ÒÁÚÄÅÌÑÅÍÏÊ ÐÁÍÑÔØÀ"
#: cmdlnopts.c:92 #: cmdlnopts.c:113
msgid "get base information about connected hardware (also increasing text "
"messages level to 2)"
msgstr ""
#: cmdlnopts.c:91
msgid "get value of I/O port pins" msgid "get value of I/O port pins"
msgstr "ÐÏÌÕÞÉÔØ ÚÎÁÞÅÎÉÅ ÐÏÒÔÁ I/O" msgstr "ÐÏÌÕÞÉÔØ ÚÎÁÞÅÎÉÅ ÐÏÒÔÁ I/O"
#: cmdlnopts.c:77 #: cmdlnopts.c:76
msgid "horizontal binning to N pixels" msgid "horizontal binning to N pixels"
msgstr "ÇÏÒÉÚÏÎÔÁÌØÎÙÊ ÂÉÎÎÉÎÇ × N ÐÉËÓÅÌÅÊ" msgstr "ÇÏÒÉÚÏÎÔÁÌØÎÙÊ ÂÉÎÎÉÎÇ × N ÐÉËÓÅÌÅÊ"
@@ -460,36 +483,36 @@ msgstr "
msgid "list connected devices" msgid "list connected devices"
msgstr "ÓÐÉÓÏË ÐÏÄËÌÀÞÅÎÎÙÈ ÕÓÔÒÏÊÓÔ×" msgstr "ÓÐÉÓÏË ÐÏÄËÌÀÞÅÎÎÙÈ ÕÓÔÒÏÊÓÔ×"
#: cmdlnopts.c:108 #: cmdlnopts.c:107
msgid "local INET command socket port" msgid "local INET command socket port"
msgstr "ÐÏÒÔ ÌÏËÁÌØÎÏÇÏ ÓÅÔÅ×ÏÇÏ ÓÏËÅÔÁ" msgstr "ÐÏÒÔ ÌÏËÁÌØÎÏÇÏ ÓÅÔÅ×ÏÇÏ ÓÏËÅÔÁ"
#: cmdlnopts.c:106 #: cmdlnopts.c:105
msgid "logging file name (if run as server)" msgid "logging file name (if run as server)"
msgstr "ÉÍÑ ÆÁÊÌÁ ÌÏÇÇÉÒÏ×ÁÎÉÑ (ÅÓÌÉ ÚÁÐÕÝÅÎ ÓÅÒ×ÅÒ)" msgstr "ÉÍÑ ÆÁÊÌÁ ÌÏÇÇÉÒÏ×ÁÎÉÑ (ÅÓÌÉ ÚÁÐÕÝÅÎ ÓÅÒ×ÅÒ)"
#: cmdlnopts.c:80 #: cmdlnopts.c:79
msgid "make pause for N seconds between expositions" msgid "make pause for N seconds between expositions"
msgstr "ÐÁÕÚÁ × N ÓÅËÕÎÄ ÍÅÖÄÕ ÜËÓÐÏÚÉÃÉÑÍÉ" msgstr "ÐÁÕÚÁ × N ÓÅËÕÎÄ ÍÅÖÄÕ ÜËÓÐÏÚÉÃÉÑÍÉ"
#: cmdlnopts.c:79 #: cmdlnopts.c:78
msgid "make series of N frames" msgid "make series of N frames"
msgstr "ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÓÔØ ÉÚ N ËÁÄÒÏ×" msgstr "ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÓÔØ ÉÚ N ËÁÄÒÏ×"
#: cmdlnopts.c:98 #: cmdlnopts.c:97
msgid "move focuser to absolute position, mm" msgid "move focuser to absolute position, mm"
msgstr "ÐÅÒÅÍÅÓÔÉÔØ ÆÏËÕÓÅÒ × ÁÂÓÏÌÀÔÎÏÅ ÐÏÌÏÖÅÎÉÅ, ÍÍ" msgstr "ÐÅÒÅÍÅÓÔÉÔØ ÆÏËÕÓÅÒ × ÁÂÓÏÌÀÔÎÏÅ ÐÏÌÏÖÅÎÉÅ, ÍÍ"
#: cmdlnopts.c:99 #: cmdlnopts.c:98
msgid "move focuser to relative position, mm (only for standalone)" msgid "move focuser to relative position, mm (only for standalone)"
msgstr "ÐÅÒÅÍÅÓÔÉÔØ ÆÏËÕÓÅÒ × ÏÔÎÏÓÉÔÅÌØÎÏÅ ÐÏÌÏÖÅÎÉÅ, ÍÍ (ÎÅ ÄÌÑ ÓÅÒ×ÅÒ/" msgstr "ÐÅÒÅÍÅÓÔÉÔØ ÆÏËÕÓÅÒ × ÏÔÎÏÓÉÔÅÌØÎÏÅ ÐÏÌÏÖÅÎÉÅ, ÍÍ (ÎÅ ÄÌÑ ÓÅÒ×ÅÒ/"
"ËÌÉÅÎÔ)" "ËÌÉÅÎÔ)"
#: cmdlnopts.c:93 #: cmdlnopts.c:92
msgid "move stepper motor asynchronous" msgid "move stepper motor asynchronous"
msgstr "ÁÓÉÎÈÒÏÎÎÏÅ Ä×ÉÖÅÎÉÅ ÛÁÇÏ×ÏÇÏ Ä×ÉÇÁÔÅÌÑ" msgstr "ÁÓÉÎÈÒÏÎÎÏÅ Ä×ÉÖÅÎÉÅ ÛÁÇÏ×ÏÇÏ Ä×ÉÇÁÔÅÌÑ"
#: cmdlnopts.c:113 #: cmdlnopts.c:112
msgid "network answer timeout (default: 0.1s)" msgid "network answer timeout (default: 0.1s)"
msgstr "" msgstr ""
@@ -513,7 +536,15 @@ msgstr "
msgid "observing program name" msgid "observing program name"
msgstr "ÎÁÚ×ÁÎÉÅ ÐÒÏÇÒÁÍÍÙ" msgstr "ÎÁÚ×ÁÎÉÅ ÐÒÏÇÒÁÍÍÙ"
#: cmdlnopts.c:88 #: imageview.c:746
msgid "off"
msgstr "×ÙËÌ"
#: imageview.c:746
msgid "on"
msgstr "×ËÌ"
#: cmdlnopts.c:87
msgid "open shutter" msgid "open shutter"
msgstr "ÏÔËÒÙÔØ ÚÁÔ×ÏÒ" msgstr "ÏÔËÒÙÔØ ÚÁÔ×ÏÒ"
@@ -521,7 +552,7 @@ msgstr "
msgid "output file name" msgid "output file name"
msgstr "ÉÍÑ ÆÁÊÌÁ" msgstr "ÉÍÑ ÆÁÊÌÁ"
#: cmdlnopts.c:111 #: cmdlnopts.c:110
msgid "passive viewer (only get last images)" msgid "passive viewer (only get last images)"
msgstr "ÐÁÓÓÉ×ÎÙÊ ÐÒÏÓÍÏÔÒ (ÔÏÌØËÏ ÐÏÓÌÅÄÎÉÅ ËÁÄÒÙ)" msgstr "ÐÁÓÓÉ×ÎÙÊ ÐÒÏÓÍÏÔÒ (ÔÏÌØËÏ ÐÏÓÌÅÄÎÉÅ ËÁÄÒÙ)"
@@ -529,7 +560,7 @@ msgstr "
msgid "program author" msgid "program author"
msgstr "Á×ÔÏÒ ÐÒÏÇÒÁÍÍÙ" msgstr "Á×ÔÏÒ ÐÒÏÇÒÁÍÍÙ"
#: cmdlnopts.c:112 #: cmdlnopts.c:111
msgid "restart image server" msgid "restart image server"
msgstr "ÐÅÒÅÚÁÐÕÓË ÓÅÒ×ÅÒÁ" msgstr "ÐÅÒÅÚÁÐÕÓË ÓÅÒ×ÅÒÁ"
@@ -537,15 +568,15 @@ msgstr "
msgid "rewrite output file if exists" msgid "rewrite output file if exists"
msgstr "ÐÅÒÅÚÁÐÉÓØ ×ÙÈÏÄÎÏÇÏ ÆÁÊÌÁ" msgstr "ÐÅÒÅÚÁÐÉÓØ ×ÙÈÏÄÎÏÇÏ ÆÁÊÌÁ"
#: cmdlnopts.c:110 #: cmdlnopts.c:109
msgid "run as client" msgid "run as client"
msgstr "ÚÁÐÕÓÔÉÔØ ËÌÉÅÎÔ" msgstr "ÚÁÐÕÓÔÉÔØ ËÌÉÅÎÔ"
#: cmdlnopts.c:91 #: cmdlnopts.c:90
msgid "run exposition on HIGH @ pin5 I/O port" msgid "run exposition on HIGH @ pin5 I/O port"
msgstr "ÚÁÐÕÓË ÜËÓÐÏÚÉÃÉÉ ÐÏ ÷ùóïëïíõ ÓÉÇÎÁÌÕ ÎÁ ËÏÎÔÁËÔÅ 5 ÐÏÒÔÁ I/O" msgstr "ÚÁÐÕÓË ÜËÓÐÏÚÉÃÉÉ ÐÏ ÷ùóïëïíõ ÓÉÇÎÁÌÕ ÎÁ ËÏÎÔÁËÔÅ 5 ÐÏÒÔÁ I/O"
#: cmdlnopts.c:90 #: cmdlnopts.c:89
msgid "run exposition on LOW @ pin5 I/O port" msgid "run exposition on LOW @ pin5 I/O port"
msgstr "ÚÁÐÕÓË ÜËÓÐÏÚÉÃÉÉ ÐÏ îéúëïíõ ÓÉÇÎÁÌÕ ÎÁ ËÏÎÔÁËÔÅ 5 ÐÏÒÔÁ I/O" msgstr "ÚÁÐÕÓË ÜËÓÐÏÚÉÃÉÉ ÐÏ îéúëïíõ ÓÉÇÎÁÌÕ ÎÁ ËÏÎÔÁËÔÅ 5 ÐÏÒÔÁ I/O"
@@ -557,11 +588,11 @@ msgstr "8-
msgid "set CCD temperature to given value (degr C)" msgid "set CCD temperature to given value (degr C)"
msgstr "ÕÓÔÁÎÏ×ÉÔØ ÔÅÍÐÅÒÁÔÕÒÕ Ó×ÅÔÏÐÒÉÅÍÎÉËÁ (ÇÒÁÄã)" msgstr "ÕÓÔÁÎÏ×ÉÔØ ÔÅÍÐÅÒÁÔÕÒÕ Ó×ÅÔÏÐÒÉÅÍÎÉËÁ (ÇÒÁÄã)"
#: cmdlnopts.c:95 #: cmdlnopts.c:94
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 "ÕÓÔÁÎÏ×ÉÔØ ÐÏÒÔ I/O (ÄÅÓÑÔÉÞÎÏÅ ÞÉÓÌÏ, pin1 - ÍÌÁÄÛÉÊ ÂÉÔ)" msgstr "ÕÓÔÁÎÏ×ÉÔØ ÐÏÒÔ I/O (ÄÅÓÑÔÉÞÎÏÅ ÞÉÓÌÏ, pin1 - ÍÌÁÄÛÉÊ ÂÉÔ)"
#: cmdlnopts.c:81 #: cmdlnopts.c:80
msgid "set exposure time to given value (seconds!)" msgid "set exposure time to given value (seconds!)"
msgstr "ÕÓÔÁÎÏ×ÉÔØ ×ÒÅÍÑ ÜËÓÐÏÚÉÃÉÉ (ÓÅËÕÎÄÙ!)" msgstr "ÕÓÔÁÎÏ×ÉÔØ ×ÒÅÍÑ ÜËÓÐÏÚÉÃÉÉ (ÓÅËÕÎÄÙ!)"
@@ -569,7 +600,7 @@ msgstr "
msgid "set fan speed (0 - off, 1 - low, 2 - high)" msgid "set fan speed (0 - off, 1 - low, 2 - high)"
msgstr "ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ×ÅÎÔÉÌÑÔÏÒÁ (0 - ×ÙËÌ, 1 - ÎÉÚËÁÑ, 2 - ×ÙÓÏËÁÑ)" msgstr "ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ×ÅÎÔÉÌÑÔÏÒÁ (0 - ×ÙËÌ, 1 - ÎÉÚËÁÑ, 2 - ×ÙÓÏËÁÑ)"
#: cmdlnopts.c:101 #: cmdlnopts.c:100
msgid "set wheel position" msgid "set wheel position"
msgstr "ÕÓÔÁÎÏ×ÉÔØ ÐÏÌÏÖÅÎÉÅ ËÏÌÅÓÁ" msgstr "ÕÓÔÁÎÏ×ÉÔØ ÐÏÌÏÖÅÎÉÅ ËÏÌÅÓÁ"
@@ -586,40 +617,21 @@ msgid "start (!=0) or stop(==0) infinity capturing loop"
msgstr "ÎÁÞÁÔØ (!=0) ÉÌÉ ÚÁËÏÎÞÉÔØ (==0) ÂÅÓËÏÎÅÞÎÙÊ ÃÉËÌ ÚÁÈ×ÁÔÁ ÉÚÏÂÒÁÖÅÎÉÊ" msgstr "ÎÁÞÁÔØ (!=0) ÉÌÉ ÚÁËÏÎÞÉÔØ (==0) ÂÅÓËÏÎÅÞÎÙÊ ÃÉËÌ ÚÁÈ×ÁÔÁ ÉÚÏÂÒÁÖÅÎÉÊ"
#: cmdlnopts.c:59 #: cmdlnopts.c:59
msgid "verbose level (-V - messages, -VV - debug, -VVV - all shit)" #, fuzzy
msgid "verbose level (-V - main messages, -VV - secondary messages, -VVV - "
"debug)"
msgstr "ÕÒÏ×ÅÎØ ÂÏÌÔÌÉ×ÏÓÔÉ (-V - ÓÏÏÂÝÅÎÉÑ, -VV - ÏÔÌÁÄËÁ, -VVV - ×ÓÅ)" msgstr "ÕÒÏ×ÅÎØ ÂÏÌÔÌÉ×ÏÓÔÉ (-V - ÓÏÏÂÝÅÎÉÑ, -VV - ÏÔÌÁÄËÁ, -VVV - ×ÓÅ)"
#: cmdlnopts.c:78 #: cmdlnopts.c:77
msgid "vertical binning to N pixels" msgid "vertical binning to N pixels"
msgstr "×ÅÒÔÉËÁÌØÎÙÊ ÂÉÎÎÉÎÇ × N ÐÉËÓÅÌÅÊ" msgstr "×ÅÒÔÉËÁÌØÎÙÊ ÂÉÎÎÉÎÇ × N ÐÉËÓÅÌÅÊ"
#: cmdlnopts.c:74
msgid "wait while exposition ends"
msgstr "ÖÄÁÔØ, ÐÏËÁ ÎÅ ËÏÎÞÉÔÓÑ ÜËÓÐÏÚÉÃÉÑ"
#: cmdlnopts.c:52 #: cmdlnopts.c:52
msgid "wheel device plugin (e.g. devdummy.so)" msgid "wheel device plugin (e.g. devdummy.so)"
msgstr "ÐÌÁÇÉÎ ÕÓÔÒÏÊÓÔ×Á ÔÕÒÅÌÉ (ÎÁÐÒÉÍÅÒ, devdummy.so)" msgstr "ÐÌÁÇÉÎ ÕÓÔÒÏÊÓÔ×Á ÔÕÒÅÌÉ (ÎÁÐÒÉÍÅÒ, devdummy.so)"
#~ msgid "Already initialized!" #~ msgid "Camera device unknown"
#~ msgstr "õÖÅ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÎÏ!" #~ msgstr "õÓÔÒÏÊÓÔ×Ï Ó×ÅÏÐÒÉÅÍÎÉËÁ ÎÅ ÏÐÏÚÎÁÎÏ"
#~ msgid "Can't init mutex!" #~ msgid "wait while exposition ends"
#~ msgstr "îÅ ÍÏÇÕ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÔØ ÍØÀÔÅËÓ!" #~ msgstr "ÖÄÁÔØ, ÐÏËÁ ÎÅ ËÏÎÞÉÔÓÑ ÜËÓÐÏÚÉÃÉÑ"
#~ msgid "Can't open OpenGL window, image preview will be inaccessible"
#~ msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ ÏËÎÏ OpenGL, ÏÔÏÂÒÁÖÅÎÉÅ ÂÕÄÅÔ ÎÅÄÏÓÔÕÐÎÏ"
#, c-format
#~ msgid "Equalization of histogram: %s"
#~ msgstr "üË×ÁÌÉÚÁÃÉÑ ÇÉÓÔÏÇÒÁÍÍÙ: %s"
#, c-format
#~ msgid "Histogram conversion: %s"
#~ msgstr "ðÒÅÏÂÒÁÚÏ×ÁÎÉÅ ÇÉÓÔÏÇÒÁÍÍÙ: %s"
#~ msgid "off"
#~ msgstr "×ÙËÌ"
#~ msgid "on"
#~ msgstr "×ËÌ"

View File

@@ -1,586 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-04-18 16:50+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"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=koi8-r\n"
"Content-Transfer-Encoding: 8bit\n"
#: ccdfunc.c:570
#, c-format
msgid "%.1f seconds till exposition ends"
msgstr "%.1f ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÜËÓÐÏÚÉÃÉÉ"
#. %d ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÐÁÕÚÙ\n
#: ccdfunc.c:805 client.c:260
#, c-format
msgid "%d seconds till pause ends\n"
msgstr "%d ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÐÁÕÚÙ\n"
#: imageview.c:282
msgid "Already initialized!"
msgstr "õÖÅ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÎÏ!"
#: cmdlnopts.c:97
msgid "CMOS brightness level"
msgstr "ÕÒÏ×ÅÎØ ÑÒËÏÓÔÉ CMOS"
#: cmdlnopts.c:96
msgid "CMOS gain level"
msgstr "ÕÒÏ×ÅÎØ Gain CMOS"
#: ccdfunc.c:584
msgid "Camera device not pointed"
msgstr "õÓÔÒÏÊÓÔ×Ï Ó×ÅÏÐÒÉÅÍÎÉËÁ ÎÅ ÐÏÄËÌÀÞÅÎÏ"
#: ccdfunc.c:155
msgid "Camera device unknown"
msgstr "õÓÔÒÏÊÓÔ×Ï Ó×ÅÏÐÒÉÅÍÎÉËÁ ÎÅ ÏÐÏÚÎÁÎÏ"
#: ccdfunc.c:643
#, c-format
msgid "Camera model: %s"
msgstr "íÏÄÅÌØ Ó×ÅÔÏÐÒÉÅÍÎÉËÁ: %s"
#: ccdfunc.c:762 ccdfunc.c:784 ccdfunc.c:825
msgid "Can't capture image"
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
#: ccdfunc.c:726
msgid "Can't change frame type"
msgstr "îÅ ÍÏÇÕ ÉÚÍÅÎÉÔØ ÔÉÐ ËÁÄÒÁ"
#: ccdfunc.c:671
msgid "Can't configure (unsupported?)"
msgstr "îÅ ÍÏÇÕ ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ (ÏÐÃÉÑ ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)"
#: ccdfunc.c:86
#, c-format
msgid "Can't find camera in plugin %s: %s"
msgstr "îÅ ÍÏÇÕ ÎÁÊÔÉ ÐÌÁÇÉÎ ËÁÍÅÒÙ %s: %s"
#: ccdfunc.c:75
#, c-format
msgid "Can't find focuser in plugin %s: %s"
msgstr "îÅ ÍÏÇÕ ÎÁÊÔÉ ÐÌÁÇÉÎ ÆÏËÕÓÅÒÁ %s: %s"
#: ccdfunc.c:63
#, c-format
msgid "Can't find plugin %s: %s"
msgstr "îÅ ÍÏÇÕ ÎÁÊÔÉ ÐÌÁÇÉÎ %s: %s"
#: ccdfunc.c:97
#, c-format
msgid "Can't find wheel in plugin %s: %s"
msgstr "îÅ ÍÏÇÕ ÎÁÊÔÉ ÐÌÁÇÉÎ ÔÕÒÅÌÉ %s: %s"
#: ccdfunc.c:677
msgid "Can't get IOport state (unsupported?)"
msgstr "îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÓÏÓÔÏÑÎÉÅ ÐÏÒÔÁ I/O (ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)"
#. GET binning should be AFTER setgeometry!
#: ccdfunc.c:735
msgid "Can't get current binning"
msgstr "îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÔÅËÕÝÅÅ ÚÎÁÞÅÎÉÅ ÂÉÎÎÉÎÇÁ"
#: ccdfunc.c:455
msgid "Can't get current focuser position"
msgstr "îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÔÅËÕÝÕÀ ÐÏÚÉÃÉÀ ÆÏËÕÓÅÒÁ"
#: ccdfunc.c:448
msgid "Can't get focuser limit positions"
msgstr "îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÐÒÅÄÅÌØÎÕÀ ÐÏÚÉÃÉÀ ÆÏËÕÓÅÒÁ"
#: ccdfunc.c:542
msgid "Can't get max wheel position"
msgstr "îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÐÒÅÄÅÌØÎÕÀ ÐÏÚÉÃÉÀ ËÏÌÅÓÁ"
#: ccdfunc.c:768 ccdfunc.c:788 ccdfunc.c:829
msgid "Can't grab image"
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
#: ccdfunc.c:473
msgid "Can't home focuser"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÆÏËÕÓÅÒ × ÎÕÌØ"
#: imageview.c:264
msgid "Can't init mutex!"
msgstr "îÅ ÍÏÇÕ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÔØ ÍØÀÔÅËÓ!"
#: client.c:247
msgid "Can't make exposition"
msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ ÜËÓÐÏÚÉÃÉÀ"
#: ccdfunc.c:748
msgid "Can't open OpenGL window, image preview will be inaccessible"
msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ ÏËÎÏ OpenGL, ÏÔÏÂÒÁÖÅÎÉÅ ÂÕÄÅÔ ÎÅÄÏÓÔÕÐÎÏ"
#: ccdfunc.c:665
#, c-format
msgid "Can't run shutter command %s (unsupported?)"
msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ ËÏÍÁÎÄÕ ÚÁÔ×ÏÒÁ %s (ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)"
#. îÅ ÍÏÇÕ ÓÏÈÒÁÎÉÔØ ÆÁÊÌ
#: ccdfunc.c:180
#, c-format
msgid "Can't save file with prefix %s"
msgstr "îÅ ÍÏÇÕ ÓÏÈÒÁÎÉÔØ ÆÁÊÌ Ó ÐÒÅÆÉËÓÏÍ %s"
#: ccdfunc.c:719
#, c-format
msgid "Can't set %d flushes"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ %d ÓÂÒÏÓÏ×"
#: ccdfunc.c:683
msgid "Can't set IOport"
msgstr "îÅ ÍÏÇÕ ÐÏÍÅÎÑÔØ ÚÎÁÞÅÎÉÑ ÐÏÒÔÁ I/O"
#: ccdfunc.c:656
#, c-format
msgid "Can't set T to %g degC"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÔÅÍÐÅÒÁÔÕÒÕ × %g ÇÒÁÄã"
#: ccdfunc.c:631
msgid "Can't set active camera number"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÊ ËÁÍÅÒÙ"
#: ccdfunc.c:434
msgid "Can't set active focuser number"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÇÏ ÆÏËÕÓÅÒÁ"
#: ccdfunc.c:526
msgid "Can't set active wheel number"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÇÏ ËÏÌÅÓÁ"
#: ccdfunc.c:705 server.c:223
#, c-format
msgid "Can't set binning %dx%d"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÂÉÎÎÉÎÇ %dx%d"
#: ccdfunc.c:729
msgid "Can't set bit depth"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÒÁÚÒÑÄÎÏÓÔØ áãð"
#: ccdfunc.c:697
#, c-format
msgid "Can't set brightness to %g"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÑÒËÏÓÔØ × %g"
#: ccdfunc.c:723
#, c-format
msgid "Can't set exposure time to %f seconds"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÜËÓÐÏÚÉÃÉÀ × %f ÓÅËÕÎÄ"
#: ccdfunc.c:637
msgid "Can't set fan speed"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ×ÅÎÔÉÌÑÔÏÒÏ×"
#: ccdfunc.c:691
#, c-format
msgid "Can't set gain to %g"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ Gain × %g"
#: ccdfunc.c:715 server.c:224
msgid "Can't set given geometry"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÇÅÏÍÅÔÒÉÀ"
#: ccdfunc.c:475
#, c-format
msgid "Can't set position %g"
msgstr "îÅ ÍÏÇÕ ÉÚÍÅÎÉÔØ ÐÏÚÉÃÉÀ ÎÁ %g"
#: ccdfunc.c:469
#, c-format
msgid "Can't set position %g: out of limits [%g, %g]"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÐÏÚÉÃÉÀ %g: ×ÎÅ ÐÒÅÄÅÌÏ× [%g, %g]"
#: ccdfunc.c:731
msgid "Can't set readout speed"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ÓÞÉÔÙ×ÁÎÉÑ"
#: ccdfunc.c:553
#, c-format
msgid "Can't set wheel position %d"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÐÏÌÏÖÅÎÉÅ ËÏÌÅÓÁ %d"
#: ccdfunc.c:758 server.c:121
msgid "Can't start exposition"
msgstr "îÅ ÍÏÇÕ ÎÁÞÁÔØ ÜËÓÐÏÚÉÃÉÀ"
#. úÁÈ×ÁÔ ËÁÄÒÁ %d\n
#: ccdfunc.c:756
#, c-format
msgid "Capture frame %d"
msgstr "úÁÈ×ÁÔ ËÁÄÒÁ %d"
#: cmdlnopts.c:107
msgid "Display image in OpenGL window"
msgstr "ïÔÏÂÒÁÖÅÎÉÅ ÉÚÏÂÒÁÖÅÎÉÑ × ÏËÎÅ OpenGL"
#: imageview.c:517
#, c-format
msgid "Equalization of histogram: %s"
msgstr "üË×ÁÌÉÚÁÃÉÑ ÇÉÓÔÏÇÒÁÍÍÙ: %s"
#: ccdfunc.c:343
msgid "Error saving file"
msgstr "ïÛÉÂËÁ ÓÏÈÒÁÎÅÎÉÑ ÆÁÊÌÁ"
#: ccdfunc.c:653
#, c-format
msgid "Field of view: %s"
msgstr "ðÏÌÅ ÚÒÅÎÉÑ: %s"
#: ccdfunc.c:334
#, c-format
msgid "File saved as '%s'"
msgstr "æÁÊÌ ÓÏÈÒÁÎÅÎ ËÁË '%s'"
#: ccdfunc.c:391
msgid "Focuser device not pointed"
msgstr "õÓÔÒÏÊÓÔ×Ï ÆÏËÕÓÅÒÁ ÎÅ ÕËÁÚÁÎÏ"
#: ccdfunc.c:627
#, c-format
msgid "Found %d cameras, you point number %d"
msgstr "ïÂÎÁÒÕÖÅÎÏ %d ËÁÍÅÒ, ×Ù ÕËÁÚÁÌÉ %d"
#: ccdfunc.c:430
#, c-format
msgid "Found %d focusers, you point number %d"
msgstr "ïÂÎÁÒÕÖÅÎÏ %d ÆÏËÕÓÅÒÏ×, ×Ù ÕËÁÚÁÌÉ %d"
#: ccdfunc.c:522
#, c-format
msgid "Found %d wheels, you point number %d"
msgstr "ïÂÎÁÒÕÖÅÎÏ %d ËÏÌÅÓ, ×Ù ÕËÁÚÁÌÉ %d"
#: ccdfunc.c:650
#, c-format
msgid "Full array: %s"
msgstr "ðÏÌÎÙÊ ÆÏÒÍÁÔ: %s"
#: imageview.c:408
#, c-format
msgid "Histogram conversion: %s"
msgstr "ðÒÅÏÂÒÁÚÏ×ÁÎÉÅ ÇÉÓÔÏÇÒÁÍÍÙ: %s"
#: ccdfunc.c:383
#, c-format
msgid "Image stat:\n"
msgstr "óÔÁÔÉÓÔÉËÁ ÐÏ ÉÚÏÂÒÁÖÅÎÉÀ: \n"
#: cmdlnopts.c:69
msgid "N flushes before exposing (default: 1)"
msgstr "N ÚÁÓ×ÅÞÉ×ÁÎÉÊ ÐÅÒÅÄ ÜËÓÐÏÚÉÃÉÅÊ (ÐÏ ÕÍÏÌÞÁÎÉÀ: 1)"
#: ccdfunc.c:161
msgid "Neither filename nor filename prefix pointed!"
msgstr "îÉ ÉÍÑ ÆÁÊÌÁ, ÎÉ ÐÒÅÆÉËÓ ÎÅ ÕËÁÚÁÎÙ!"
#: server.c:163
msgid "No camera device"
msgstr "îÅ ÕËÁÚÁÎÏ ÕÓÔÒÏÊÓÔ×Ï ËÁÍÅÒÙ"
#: ccdfunc.c:591 ccdfunc.c:592
msgid "No cameras found"
msgstr "ëÁÍÅÒ ÎÅ ÏÂÎÁÒÕÖÅÎÏ"
#: ccdfunc.c:398
msgid "No focusers found"
msgstr "æÏËÕÓÅÒÏ× ÎÅ ÏÂÎÁÒÕÖÅÎÏ"
#: ccdfunc.c:490
msgid "No wheels found"
msgstr "ôÕÒÅÌÅÊ ÎÅ ÏÂÎÁÒÕÖÅÎÏ"
#: ccdfunc.c:733
msgid "Only show statistics"
msgstr "ôÏÌØËÏ ÏÔÏÂÒÁÚÉÔØ ÓÔÁÔÉÓÔÉËÕ"
#: cmdlnopts.c:103
msgid "PID file (default: "
msgstr "PID-ÆÁÊÌ (ÐÏ ÕÍÏÌÞÁÎÉÀ: "
#: ccdfunc.c:644
#, c-format
msgid "Pixel size: %g x %g"
msgstr "òÁÚÍÅÒ ÐÉËÓÅÌÑ: %g x %g"
#: ccdfunc.c:765
msgid "Read grabbed image"
msgstr "óÞÉÔÙ×ÁÎÉÅ ÉÚÏÂÒÁÖÅÎÉÑ"
#: ccdfunc.c:732
#, c-format
msgid "Readout mode: %s"
msgstr "òÅÖÉÍ ÓÞÉÔÙ×ÁÎÉÑ: %s"
#: client.c:276
msgid "Server timeout"
msgstr "ôÁÊÍÁÕÔ ÓÅÒ×ÅÒÁ"
#: ccdfunc.c:696
#, c-format
msgid "Set brightness to %g"
msgstr "õÓÔÁÎÏ×ÉÔØ ÑÒËÏÓÔØ × %g"
#: ccdfunc.c:638
#, c-format
msgid "Set fan speed to %d"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ×ÅÎÔÉÌÑÔÏÒÏ× × %d"
#: ccdfunc.c:690
#, c-format
msgid "Set gain to %g"
msgstr "õÓÔÁÎÏ×ÉÔØ Gain × %g"
#: ccdfunc.c:663
#, c-format
msgid "Shutter command: %s\n"
msgstr "ëÏÍÁÎÄÁ ÚÁÔ×ÏÒÁ: %s\n"
#. "ðÏÐÙÔËÁ ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ ÐÏÒÔ I/O ËÁË %d\n"
#: ccdfunc.c:669
#, c-format
msgid "Try to configure I/O port as %d"
msgstr "ðÏÐÙÔËÁ ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ ÐÏÒÔ I/O ËÁË %d"
#. "ðÏÐÙÔËÁ ÚÁÐÉÓÉ %d × ÐÏÒÔ I/O\n"
#: ccdfunc.c:681
#, c-format
msgid "Try to write %d to I/O port"
msgstr "ðÏÐÙÔËÁ ÚÁÐÉÓÉ %d × ÐÏÒÔ I/O"
#: cmdlnopts.c:100
msgid "UNIX socket name"
msgstr "éÍÑ UNIX-ÓÏËÅÔÁ"
#: ccdfunc.c:483
msgid "Wheel device not pointed"
msgstr "õÓÔÒÏÊÓÔ×Ï ÔÕÒÅÌÉ ÎÅ ÕËÁÚÁÎÏ"
#: ccdfunc.c:549
#, c-format
msgid "Wheel position should be from 0 to %d"
msgstr "ðÏÚÉÃÉÑ ËÏÌÅÓÁ ÄÏÌÖÎÁ ÂÙÔØ ÏÔ 0 ÄÏ %d"
#: cmdlnopts.c:76
msgid "absolute (not divided by binning!) frame X0 coordinate (-1 - all "
"with overscan)"
msgstr "ÁÂÓÏÌÀÔÎÁÑ (ÎÅ ÄÅÌÅÎÎÁÑ ÎÁ ÂÉÎÎÉÎÇ!) ËÏÏÒÄÉÎÁÔÁ X0 (-1 - ×ËÌÀÞÁÑ Ï×ÅÒÓËÁÎ)"
#: cmdlnopts.c:78
msgid "absolute frame X1 coordinate (-1 - all with overscan)"
msgstr "ÁÂÓÏÌÀÔÎÁÑ ËÏÏÒÄÉÎÁÔÁ X1 (-1 - ×ËÌÀÞÁÑ Ï×ÅÒÓËÁÎ)"
#: cmdlnopts.c:77
msgid "absolute frame Y0 coordinate (-1 - all with overscan)"
msgstr "ÁÂÓÏÌÀÔÎÁÑ ËÏÏÒÄÉÎÁÔÁ Y0 (-1 - ×ËÌÀÞÁÑ Ï×ÅÒÓËÁÎ)"
#: cmdlnopts.c:79
msgid "absolute frame Y1 coordinate (-1 - all with overscan)"
msgstr "ÁÂÓÏÌÀÔÎÁÑ ËÏÏÒÄÉÎÁÔÁ Y1 (-1 - ×ËÌÀÞÁÑ Ï×ÅÒÓËÁÎ)"
#: cmdlnopts.c:65
msgid "add records to header from given file[s]"
msgstr "ÄÏÂÁ×ÉÔØ ÚÁÐÉÓÉ Ë ÛÁÐËÅ FITS-ÆÁÊÌÁ ÉÚ ÚÁÄÁÎÎÙÈ ÆÁÊÌÏ×"
#: cmdlnopts.c:47
msgid "camera device number (if many: 0, 1, 2 etc)"
msgstr "ÎÏÍÅÒ ÕÓÔÒÏÊÓÔ×Á ËÁÍÅÒÙ"
#: cmdlnopts.c:43
msgid "camera device plugin (e.g. devfli.so)"
msgstr "ÐÌÁÇÉÎ ËÁÍÅÒÙ (ÎÁÐÒÉÍÅÒ, devfli.so)"
#: cmdlnopts.c:75
msgid "cancel current exposition"
msgstr "ÏÔÍÅÎÁ ÔÅËÕÝÅÊ ÜËÓÐÏÚÉÃÉÉ"
#: cmdlnopts.c:82
msgid "close shutter"
msgstr "ÚÁËÒÙÔØ ÚÁÔ×ÏÒ"
#: cmdlnopts.c:42
msgid "common device plugin (e.g devfli.so)"
msgstr "ÏÂÝÉÊ ÐÌÁÇÉÎ ÄÌÑ ×ÓÅÈ ÕÓÔÒÏÊÓÔ× (ÎÁÐÒÉÍÅÒ, devfli.so)"
#: cmdlnopts.c:89
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
msgid "fast readout mode"
msgstr "ÂÙÓÔÒÙÊ ÒÅÖÉÍ ÓÞÉÔÙ×ÁÎÉÑ"
#: cmdlnopts.c:48
msgid "filter wheel device number (if many: 0, 1, 2 etc)"
msgstr "ÎÏÍÅÒ ÕÓÔÒÏÊÓÔ×Á ÔÕÒÅÌÉ"
#: cmdlnopts.c:49
msgid "focuser device number (if many: 0, 1, 2 etc)"
msgstr "ÎÏÍÅÒ ÕÓÔÒÏÊÓÔ×Á ÆÏËÕÓÅÒÁ"
#: cmdlnopts.c:44
msgid "focuser device plugin (e.g. devzwo.so)"
msgstr "ÐÌÁÇÉÎ ÆÏËÕÓÅÒÁ (ÎÁÐÒÉÍÅÒ, devzwo.so)"
#: cmdlnopts.c:85
msgid "get value of I/O port pins"
msgstr "ÐÏÌÕÞÉÔØ ÚÎÁÞÅÎÉÅ ÐÏÒÔÁ I/O"
#: cmdlnopts.c:70
msgid "horizontal binning to N pixels"
msgstr "ÇÏÒÉÚÏÎÔÁÌØÎÙÊ ÂÉÎÎÉÎÇ × N ÐÉËÓÅÌÅÊ"
#: cmdlnopts.c:61
msgid "instrument name"
msgstr "ÎÁÚ×ÁÎÉÅ ÐÒÉÂÏÒÁ"
#: cmdlnopts.c:46
msgid "list connected devices"
msgstr "ÓÐÉÓÏË ÐÏÄËÌÀÞÅÎÎÙÈ ÕÓÔÒÏÊÓÔ×"
#: cmdlnopts.c:101
msgid "local INET socket port"
msgstr "ÐÏÒÔ ÌÏËÁÌØÎÏÇÏ ÓÅÔÅ×ÏÇÏ ÓÏËÅÔÁ"
#: cmdlnopts.c:99
msgid "logging file name (if run as server)"
msgstr "ÉÍÑ ÆÁÊÌÁ ÌÏÇÇÉÒÏ×ÁÎÉÑ (ÅÓÌÉ ÚÁÐÕÝÅÎ ÓÅÒ×ÅÒ)"
#: cmdlnopts.c:73
msgid "make pause for N seconds between expositions"
msgstr "ÐÁÕÚÁ × N ÓÅËÕÎÄ ÍÅÖÄÕ ÜËÓÐÏÚÉÃÉÑÍÉ"
#: cmdlnopts.c:72
msgid "make series of N frames"
msgstr "ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÓÔØ ÉÚ N ËÁÄÒÏ×"
#: cmdlnopts.c:91
msgid "move focuser to absolute position, mm"
msgstr "ÐÅÒÅÍÅÓÔÉÔØ ÆÏËÕÓÅÒ × ÁÂÓÏÌÀÔÎÏÅ ÐÏÌÏÖÅÎÉÅ, ÍÍ"
#: cmdlnopts.c:92
msgid "move focuser to relative position, mm (only for standalone)"
msgstr "ÐÅÒÅÍÅÓÔÉÔØ ÆÏËÕÓÅÒ × ÏÔÎÏÓÉÔÅÌØÎÏÅ ÐÏÌÏÖÅÎÉÅ, ÍÍ (ÎÅ ÄÌÑ ÓÅÒ×ÅÒ/ËÌÉÅÎÔ)"
#: cmdlnopts.c:86
msgid "move stepper motor asynchronous"
msgstr "ÁÓÉÎÈÒÏÎÎÏÅ Ä×ÉÖÅÎÉÅ ÛÁÇÏ×ÏÇÏ Ä×ÉÇÁÔÅÌÑ"
#: cmdlnopts.c:53
msgid "not open shutter, when exposing (\"dark frames\")"
msgstr "ÎÅ ÏÔËÒÙ×ÁÔØ ÚÁÔ×ÏÒ ÐÒÉ ÜËÓÐÏÚÉÃÉÉ (\"ÔÅÍÎÏ×ÙÅ\")"
#: cmdlnopts.c:62
msgid "object name"
msgstr "ÎÁÚ×ÁÎÉÅ ÏÂßÅËÔÁ"
#: cmdlnopts.c:60
msgid "object type (neon, object, flat etc)"
msgstr "ÔÉÐ ÏÂßÅËÔÁ (neon, object, flat É Ô.Ä.)"
#: cmdlnopts.c:63
msgid "observers' names"
msgstr "ÉÍÅÎÁ ÎÁÂÌÀÄÁÔÅÌÅÊ"
#: cmdlnopts.c:64
msgid "observing program name"
msgstr "ÎÁÚ×ÁÎÉÅ ÐÒÏÇÒÁÍÍÙ"
#: imageview.c:517
msgid "off"
msgstr "×ÙËÌ"
#: imageview.c:517
msgid "on"
msgstr "×ËÌ"
#: cmdlnopts.c:81
msgid "open shutter"
msgstr "ÏÔËÒÙÔØ ÚÁÔ×ÏÒ"
#: cmdlnopts.c:66
msgid "output file name"
msgstr "ÉÍÑ ÆÁÊÌÁ"
#: cmdlnopts.c:59
msgid "program author"
msgstr "Á×ÔÏÒ ÐÒÏÇÒÁÍÍÙ"
#: cmdlnopts.c:104
msgid "restart image server"
msgstr "ÐÅÒÅÚÁÐÕÓË ÓÅÒ×ÅÒÁ"
#: cmdlnopts.c:51
msgid "rewrite output file if exists"
msgstr "ÐÅÒÅÚÁÐÉÓØ ×ÙÈÏÄÎÏÇÏ ÆÁÊÌÁ"
#: cmdlnopts.c:102
msgid "run as client"
msgstr "ÚÁÐÕÓÔÉÔØ ËÌÉÅÎÔ"
#: cmdlnopts.c:84
msgid "run exposition on HIGH @ pin5 I/O port"
msgstr ""
#: cmdlnopts.c:83
msgid "run exposition on LOW @ pin5 I/O port"
msgstr ""
#: cmdlnopts.c:54
msgid "run in 8-bit mode"
msgstr "8-ÂÉÔÎÙÊ ÒÅÖÉÍ"
#: cmdlnopts.c:56
msgid "set CCD temperature to given value (degr C)"
msgstr "ÕÓÔÁÎÏ×ÉÔØ ÔÅÍÐÅÒÁÔÕÒÕ Ó×ÅÔÏÐÒÉÅÍÎÉËÁ (ÇÒÁÄã)"
#: cmdlnopts.c:88
msgid "set I/O port pins to given value (decimal number, pin1 is LSB)"
msgstr "ÕÓÔÁÎÏ×ÉÔØ ÐÏÒÔ I/O (ÄÅÓÑÔÉÞÎÏÅ ÞÉÓÌÏ, pin1 - ÍÌÁÄÛÉÊ ÂÉÔ)"
#: cmdlnopts.c:74
msgid "set exposure time to given value (seconds!)"
msgstr "ÕÓÔÁÎÏ×ÉÔØ ×ÒÅÍÑ ÜËÓÐÏÚÉÃÉÉ (ÓÅËÕÎÄÙ!)"
#: cmdlnopts.c:57
msgid "set fan speed (0 - off, 1 - low, 2 - high)"
msgstr "ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ×ÅÎÔÉÌÑÔÏÒÁ (0 - ×ÙËÌ, 1 - ÎÉÚËÁÑ, 2 - ×ÙÓÏËÁÑ)"
#: cmdlnopts.c:94
msgid "set wheel position"
msgstr "ÕÓÔÁÎÏ×ÉÔØ ÐÏÌÏÖÅÎÉÅ ËÏÌÅÓÁ"
#: cmdlnopts.c:50
msgid "show this help"
msgstr "ÏÔÏÂÒÁÚÉÔØ ÜÔÕ ÓÐÒÁ×ËÕ"
#: cmdlnopts.c:52
msgid "verbose level (-V - messages, -VV - debug, -VVV - all shit)"
msgstr "ÕÒÏ×ÅÎØ ÂÏÌÔÌÉ×ÏÓÔÉ (-V - ÓÏÏÂÝÅÎÉÑ, -VV - ÏÔÌÁÄËÁ, -VVV - ×ÓÅ)"
#: cmdlnopts.c:71
msgid "vertical binning to N pixels"
msgstr "×ÅÒÔÉËÁÌØÎÙÊ ÂÉÎÎÉÎÇ × N ÐÉËÓÅÌÅÊ"
#: cmdlnopts.c:67
msgid "wait while exposition ends"
msgstr "ÖÄÁÔØ, ÐÏËÁ ÎÅ ËÏÎÞÉÔÓÑ ÜËÓÐÏÚÉÃÉÑ"
#: cmdlnopts.c:45
msgid "wheel device plugin (e.g. devdummy.so)"
msgstr "ÐÌÁÇÉÎ ÕÓÔÒÏÊÓÔ×Á ÔÕÒÅÌÉ (ÎÁÐÒÉÍÅÒ, devdummy.so)"

9
main.c
View File

@@ -34,6 +34,7 @@
#ifdef IMAGEVIEW #ifdef IMAGEVIEW
#include "imageview.h" #include "imageview.h"
#endif #endif
#include "server.h"
#include "socket.h" #include "socket.h"
static int isserver = FALSE; static int isserver = FALSE;
@@ -56,6 +57,7 @@ void signals(int signo){
if(signo) WARNX("Get signal %d - exit", signo); if(signo) WARNX("Get signal %d - exit", signo);
if(!GP->client){ if(!GP->client){
DBG("Cancel capturing and close all"); DBG("Cancel capturing and close all");
stop_server();
camstop(); camstop();
closewheel(); closewheel();
focclose(); focclose();
@@ -107,11 +109,14 @@ int main(int argc, char **argv){
if(!GP->client) isserver = TRUE; if(!GP->client) isserver = TRUE;
} }
if(GP->path && !GP->client) isserver = TRUE; if(GP->path && !GP->client) isserver = TRUE;
if(!GP->path && !GP->port){
WARNX("Point one of options: `port` or `path` for command socket");
}
if((isserver || GP->client) && !GP->imageport){ if((isserver || GP->client) && !GP->imageport){
GP->imageport = MALLOC(char, 32); GP->imageport = MALLOC(char, 32);
if(!GP->port) sprintf(GP->imageport, "12345"); if(!GP->port) sprintf(GP->imageport, "12345");
else snprintf(GP->imageport, 31, "%d", 1+atoi(GP->port)); else snprintf(GP->imageport, 31, "%d", 1+atoi(GP->port));
verbose(1, "Set image port to %s", GP->imageport); printf("Set image port to %s\n", GP->imageport);
} }
if(GP->client && (GP->commondev || GP->focuserdev || GP->cameradev || GP->wheeldev)) if(GP->client && (GP->commondev || GP->focuserdev || GP->cameradev || GP->wheeldev))
ERRX("Can't be client and standalone in same time!"); ERRX("Can't be client and standalone in same time!");
@@ -123,12 +128,14 @@ int main(int argc, char **argv){
OPENLOG(GP->logfile, lvl, 1); OPENLOG(GP->logfile, lvl, 1);
if(!sl_globlog) WARNX("Can't create log file"); if(!sl_globlog) WARNX("Can't create log file");
} }
if(GP->info && GP->verbose < 2) GP->verbose = 2; // increase verbose messages level for `info`
signal(SIGINT, signals); signal(SIGINT, signals);
signal(SIGQUIT, signals); signal(SIGQUIT, signals);
signal(SIGABRT, signals); signal(SIGABRT, signals);
signal(SIGTERM, signals); signal(SIGTERM, signals);
signal(SIGHUP, SIG_IGN); signal(SIGHUP, SIG_IGN);
signal(SIGTSTP, SIG_IGN); signal(SIGTSTP, SIG_IGN);
signal(SIGPIPE, SIG_IGN);
signal(SIGUSR1, signals); // restart server signal(SIGUSR1, signals); // restart server
if(!isserver){ // run in standalone or client mode if(!isserver){ // run in standalone or client mode
int camerainit = FALSE; int camerainit = FALSE;

533
server.c
View File

@@ -16,13 +16,16 @@
* 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 <stdatomic.h> #include <fcntl.h>
#include <netdb.h> #include <netdb.h>
#include <pthread.h> #include <pthread.h>
#include <poll.h> #include <poll.h>
#include <stdatomic.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <sys/mman.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/stat.h>
#include <usefull_macros.h> #include <usefull_macros.h>
#include "ccdfunc.h" #include "ccdfunc.h"
@@ -38,15 +41,15 @@ static _Atomic cc_camera_state camstate = CAMERA_IDLE;
#define FLAG_CANCEL (1<<1) #define FLAG_CANCEL (1<<1)
#define FLAG_RESTARTSERVER (1<<2) #define FLAG_RESTARTSERVER (1<<2)
static atomic_int camflags = 0, camfanspd = 0, confio = 0, nflushes, infty = 0; static atomic_int camflags = 0, camfanspd = 0, confio = 0, nflushes, infty = 0;
static char *outfile = NULL, *lastfile = NULL; // current output file name/prefix; last name of saved file
static cc_frameformat frmformatmax = {0}, curformat = {0}; // maximal format static cc_frameformat frmformatmax = {0}, curformat = {0}; // maximal format
static float focmaxpos = 0., focminpos = 0.; // focuser extremal positions static float focmaxpos = 0., focminpos = 0.; // focuser extremal positions
static int wmaxpos = 0.; // wheel max pos static int wmaxpos = 0.; // wheel max pos
static float tremain = 0.; // time when capture done static float tremain = 0.; // time when capture done
// IPC key for shared memory // IPC key for shared memory (for client's getter)
static key_t shmkey = IPC_PRIVATE; static key_t shmkey = IPC_PRIVATE;
static int isrunning = 1;
typedef struct{ typedef struct{
const char *key; const char *key;
@@ -55,36 +58,36 @@ typedef struct{
// cat | awk '{print "{ " $3 ", \"\" }," }' | sort // cat | awk '{print "{ " $3 ", \"\" }," }' | sort
strpair allcommands[] = { strpair allcommands[] = {
{ CC_CMD_8BIT, "run in 8 bit mode instead of 16 bit" },
{ CC_CMD_AUTHOR, "FITS 'AUTHOR' field" }, { CC_CMD_AUTHOR, "FITS 'AUTHOR' field" },
{ CC_CMD_BRIGHTNESS, "camera brightness" }, { CC_CMD_BRIGHTNESS, "camera brightness" },
{ CC_CMD_CAMDEVNO, "camera device number" }, { CC_CMD_CAMDEVNO, "camera device number" },
{ CC_CMD_CAMFLAGS, "get camflags (bits: 0-start capture, 1-cancel, 2-restart server"},
{ CC_CMD_CAMLIST, "list all connected cameras" }, { CC_CMD_CAMLIST, "list all connected cameras" },
{ CC_CMD_CAMFANSPD, "fan speed of camera" }, { CC_CMD_CAMFANSPD, "fan speed of camera" },
{ CC_CMD_CONFIO, "camera IO configuration" }, { CC_CMD_CONFIO, "camera IO configuration" },
{ CC_CMD_DARK, "don't open shutter @ exposure" }, { CC_CMD_DARK, "don't open shutter @ exposure" },
{ CC_CMD_EXPSTATE, "get exposition state (0: cancel, 1: capturing, 2: frame ready, 3: error) " { CC_CMD_EXPSTATE, "get exposition state (0: cancel, 1: capturing, 2: frame ready, 3: error) "
"or set (0: cancel, 1: start exp)\n also get camflags (bits: 0-start capture, 1-cancel, 2-restart server" }, "or set (0: cancel, 1: start exp)\n" },
{ CC_CMD_EXPOSITION, "exposition time" }, { CC_CMD_EXPOSITION, "exposition time" },
{ CC_CMD_FASTSPD, "fast readout speed" }, { CC_CMD_FASTSPD, "fast readout speed" },
{ CC_CMD_FILENAME, "save file with this name, like file.fits" },
{ CC_CMD_FILENAMEPREFIX,"prefix of files, like ex (will be saved as exXXXX.fits)" },
{ CC_CMD_FDEVNO, "focuser device number" }, { CC_CMD_FDEVNO, "focuser device number" },
{ CC_CMD_FOCLIST, "list all connected focusers" }, { CC_CMD_FOCLIST, "list all connected focusers" },
{ CC_CMD_FMAXPOS, "get maximal focuser position"},
{ CC_CMD_FMINPOS, "get minimal focuser position"},
{ CC_CMD_FGOTO, "focuser position" }, { CC_CMD_FGOTO, "focuser position" },
{ CC_CMD_FTEMP, "get focuser body temperature"},
{ CC_CMD_FRAMEFORMAT, "camera frame format (X0,Y0,X1,Y1)" }, { CC_CMD_FRAMEFORMAT, "camera frame format (X0,Y0,X1,Y1)" },
{ CC_CMD_GAIN, "camera gain" }, { CC_CMD_GAIN, "camera gain" },
{ CC_CMD_GETHEADERS, "get last file FITS headers" }, { CC_CMD_GETHEADERS, "get last file FITS headers" },
{ CC_CMD_HBIN, "horizontal binning" }, { CC_CMD_HBIN, "horizontal binning" },
{ CC_CMD_HEADERFILES, "add FITS records from these files (comma-separated list)" },
{ CC_CMD_HELP, "show this help" }, { CC_CMD_HELP, "show this help" },
{ CC_CMD_IMHEIGHT, "last image height" }, { CC_CMD_IMHEIGHT, "last image height" },
{ CC_CMD_IMNUMBER, "grabbed image number from server start"},
{ CC_CMD_IMWIDTH, "last image width" }, { CC_CMD_IMWIDTH, "last image width" },
{ CC_CMD_INFO, "connected devices state" },
{ CC_CMD_INFTY, "an infinity loop taking images until there's connected clients" }, { CC_CMD_INFTY, "an infinity loop taking images until there's connected clients" },
{ CC_CMD_INSTRUMENT, "FITS 'INSTRUME' field" }, { CC_CMD_INSTRUMENT, "FITS 'INSTRUME' field" },
{ CC_CMD_IO, "get/set camera IO" }, { CC_CMD_IO, "get/set camera IO" },
{ CC_CMD_LASTFNAME, "path to last saved file"}, { CC_CMD_8BIT, "run in 8 bit mode instead of 16 bit" },
{ CC_CMD_FRAMEMAX, "camera maximal available format" }, { CC_CMD_FRAMEMAX, "camera maximal available format" },
{ CC_CMD_NFLUSHES, "camera number of preflushes" }, { CC_CMD_NFLUSHES, "camera number of preflushes" },
{ CC_CMD_OBJECT, "FITS 'OBJECT' field" }, { CC_CMD_OBJECT, "FITS 'OBJECT' field" },
@@ -93,7 +96,6 @@ strpair allcommands[] = {
{ CC_CMD_PLUGINCMD, "custom camera plugin command" }, { CC_CMD_PLUGINCMD, "custom camera plugin command" },
{ CC_CMD_PROGRAM, "FITS 'PROG-ID' field" }, { CC_CMD_PROGRAM, "FITS 'PROG-ID' field" },
{ CC_CMD_RESTART, "restart server" }, { CC_CMD_RESTART, "restart server" },
{ CC_CMD_REWRITE, "rewrite file (if give `filename`, not `filenameprefix`)" },
{ CC_CMD_SHMEMKEY, "get shared memory key" }, { CC_CMD_SHMEMKEY, "get shared memory key" },
{ CC_CMD_SHUTTER, "camera shutter's operations" }, { CC_CMD_SHUTTER, "camera shutter's operations" },
{ CC_CMD_CAMTEMPER, "camera chip temperature" }, { CC_CMD_CAMTEMPER, "camera chip temperature" },
@@ -101,7 +103,9 @@ strpair allcommands[] = {
{ CC_CMD_VBIN, "vertical binning" }, { CC_CMD_VBIN, "vertical binning" },
{ CC_CMD_WDEVNO, "wheel device number" }, { CC_CMD_WDEVNO, "wheel device number" },
{ CC_CMD_WLIST, "list all connected wheels" }, { CC_CMD_WLIST, "list all connected wheels" },
{ CC_CMD_WMAXPOS, "get maximap wheel position"},
{ CC_CMD_WPOS, "wheel position" }, { CC_CMD_WPOS, "wheel position" },
{ CC_CMD_WTEMP, "get wheel body temperature"},
{NULL, NULL}, {NULL, NULL},
}; };
@@ -113,21 +117,55 @@ static int lock(){
//DBG("\n\nAlready locked"); //DBG("\n\nAlready locked");
return FALSE; return FALSE;
} }
//DBG("LOCK()");
return TRUE; return TRUE;
} }
static void unlock(){ static void unlock(){
if(pthread_mutex_unlock(&locmutex)) ERR("Can't unlock mutex"); if(pthread_mutex_unlock(&locmutex)){
LOGERR("Can't unlock socket mutex");
ERR("Can't unlock socket mutex");
}
//DBG("UNLOCK()");
} }
static cc_IMG *ima = NULL; static cc_IMG *ima = NULL;
// cleanup semaphore, stop server processes
void stop_server(){
isrunning = 0;
double t0 = sl_dtime();
// wait no more than 1s for graceful closing
while(sl_dtime() - t0 < 1.){
if(isrunning == -1) break;
usleep(1000);
}
// destroy semaphore
cc_remove_sem();
}
static void fixima(){ static void fixima(){
FNAME(); FNAME();
if(!camera) return; if(!camera) return;
double t0 = sl_dtime();
int locked = FALSE;
TIMESTAMP("Lock socket");
// lock socket operations
while(!(locked = lock()) && sl_dtime() - t0 < 0.5) usleep(1000);
if(!locked){
DBG("Still locked from outside -> unlock/lock");
while(!lock()) unlock(); // force unlocking if can't do this gracefully
}else DBG("LOCK takes %gs", sl_dtime()-t0);
int raw_width = curformat.w / GP->hbin, raw_height = curformat.h / GP->vbin; int raw_width = curformat.w / GP->hbin, raw_height = curformat.h / GP->vbin;
TIMESTAMP("Check SHM image");
// allocate memory for largest possible image // allocate memory for largest possible image
if(!ima) ima = cc_getshm(GP->shmkey, camera->array.h * camera->array.w * 2); if(!ima){
if(!ima) ERRX("Can't allocate memory for image"); ima = cc_getshm(GP->shmkey, camera->array.h * camera->array.w * 2);
if(!ima) ERR("Can't allocate memory for image");
// init shared semaphore
cc_init_sem(TRUE);
}
TIMESTAMP("Lock SHM image");
cc_lock_shm(TRUE);
shmkey = GP->shmkey; shmkey = GP->shmkey;
//if(raw_width == ima->w && raw_height == ima->h) return; // all OK //if(raw_width == ima->w && raw_height == ima->h) return; // all OK
DBG("curformat: %dx%d", curformat.w, curformat.h); DBG("curformat: %dx%d", curformat.w, curformat.h);
@@ -140,6 +178,9 @@ static void fixima(){
DBG("GP->_8bit=%d", GP->_8bit); DBG("GP->_8bit=%d", GP->_8bit);
ima->bytelen = raw_height * raw_width * cc_getNbytes(ima); ima->bytelen = raw_height * raw_width * cc_getNbytes(ima);
DBG("new image: %dx%d", raw_width, raw_height); DBG("new image: %dx%d", raw_width, raw_height);
cc_unlock_shm();
unlock();
TIMESTAMP("All OK");
} }
// functions for processCAM finite state machine // functions for processCAM finite state machine
@@ -169,8 +210,8 @@ static inline void cameracapturestate(){ // capturing - wait for exposition ends
if(cs != CAPTURE_PROCESS){ if(cs != CAPTURE_PROCESS){
TIMESTAMP("Capture ready"); TIMESTAMP("Capture ready");
tremain = 0.; tremain = 0.;
// now save frame // now capture frame
if(!ima->data) LOGERR("Can't save image: not initialized"); if(!ima || !ima->data) LOGERR("Can't capture image: data not initialized");
else{ else{
TIMESTAMP("start capture"); TIMESTAMP("start capture");
if(!camera->capture){ if(!camera->capture){
@@ -179,19 +220,20 @@ static inline void cameracapturestate(){ // capturing - wait for exposition ends
camstate = CAMERA_ERROR; camstate = CAMERA_ERROR;
return; return;
} }
cc_lock_shm(TRUE);
if(!camera->capture(ima)){ if(!camera->capture(ima)){
LOGERR("Can't capture image"); LOGERR("Can't capture image");
camstate = CAMERA_ERROR; camstate = CAMERA_ERROR;
return; return;
}else{ }else{
TIMESTAMP("Fill FITS header");
ima->gotstat = 0; // fresh image without statistics - recalculate when save ima->gotstat = 0; // fresh image without statistics - recalculate when save
ima->timestamp = sl_dtime(); // set timestamp ima->timestamp = sl_dtime(); // set timestamp
fillFITSheader(ima);
++ima->imnumber; // increment counter ++ima->imnumber; // increment counter
if(saveFITS(ima, &lastfile)){
DBG("LAST file name changed");
}
TIMESTAMP("Image saved");
} }
cc_unlock_shm();
TIMESTAMP("Captured and unlocked");
} }
camstate = CAMERA_FRAMERDY; camstate = CAMERA_FRAMERDY;
} }
@@ -205,12 +247,21 @@ static void* processCAM(_U_ void *d){
ERRX(_("No camera device")); ERRX(_("No camera device"));
} }
double logt = 0; double logt = 0;
while(1){ #ifdef EBUG
double T = sl_dtime();
#endif
while(isrunning){
if(camflags & FLAG_RESTARTSERVER){ if(camflags & FLAG_RESTARTSERVER){
LOGERR("User asks to restart"); LOGERR("User asks to restart");
signals(1); signals(1);
} }
usleep(100); #ifdef EBUG
if(sl_dtime() - T > 5.){
T = sl_dtime();
printf("\t\t\tprocessCAM(), 5 seconds\n");
}
#endif
usleep(1000);
if(tremain < 0.5 && tremain > 0.) usleep(tremain*1e6); if(tremain < 0.5 && tremain > 0.) usleep(tremain*1e6);
if(lock()){ if(lock()){
// log // log
@@ -237,22 +288,17 @@ static void* processCAM(_U_ void *d){
unlock(); unlock();
continue; continue;
} }
unlock();
cc_camera_state curstate = camstate; cc_camera_state curstate = camstate;
switch(curstate){ switch(curstate){
case CAMERA_IDLE:
cameraidlestate();
break;
case CAMERA_CAPTURE: case CAMERA_CAPTURE:
cameracapturestate(); cameracapturestate();
break; break;
case CAMERA_FRAMERDY: default:
// do nothing: when `server` got this state it sends "expstate=2" to all clients and changes state to IDLE cameraidlestate();
break;
case CAMERA_ERROR:
// do nothing: when `server` got this state it sends "expstate=3" to all clients and changes state to IDLE
break; break;
} }
unlock();
} }
} }
return NULL; return NULL;
@@ -267,8 +313,8 @@ static int camdevini(int n){
LOGERR("Can't set active camera number"); LOGERR("Can't set active camera number");
return FALSE; return FALSE;
} }
camdevno = n; atomic_store(&camdevno, n);
LOGMSG("Set camera device number to %d", camdevno); LOGMSG("Set camera device number to %d", n);
cc_frameformat step; cc_frameformat step;
if(camera->getgeomlimits) camera->getgeomlimits(&frmformatmax, &step); if(camera->getgeomlimits) camera->getgeomlimits(&frmformatmax, &step);
curformat = frmformatmax; curformat = frmformatmax;
@@ -291,8 +337,8 @@ static int focdevini(int n){
LOGERR("Can't set active focuser number"); LOGERR("Can't set active focuser number");
return FALSE; return FALSE;
} }
focdevno = n; atomic_store(&focdevno, n);
LOGMSG("Set focuser device number to %d", focdevno); LOGMSG("Set focuser device number to %d", n);
focuser->getMaxPos(&focmaxpos); focuser->getMaxPos(&focmaxpos);
focuser->getMinPos(&focminpos); focuser->getMinPos(&focminpos);
return TRUE; return TRUE;
@@ -303,8 +349,8 @@ static int wheeldevini(int n){
LOGERR("Can't set active wheel number"); LOGERR("Can't set active wheel number");
return FALSE; return FALSE;
} }
wheeldevno = n; atomic_store(&wheeldevno, n);
LOGMSG("Set wheel device number to %d", wheeldevno); LOGMSG("Set wheel device number to %d", n);
wheel->getMaxPos(&wmaxpos); wheel->getMaxPos(&wmaxpos);
return TRUE; return TRUE;
} }
@@ -323,9 +369,8 @@ static cc_hresult restarthandler(_U_ int fd, _U_ const char *key, _U_ const char
// image size // image size
static cc_hresult imsizehandler(int fd, const char *key, _U_ const char *val){ static cc_hresult imsizehandler(int fd, const char *key, _U_ const char *val){
char buf[64]; char buf[64];
// send image width/height in pixels if(!ima) return CC_RESULT_FAIL;
if(0 == strcmp(key, CC_CMD_IMHEIGHT)) snprintf(buf, 63, CC_CMD_IMHEIGHT "=%d", ima->h); snprintf(buf, 63, "%s=%d", key, (0 == strcmp(key, CC_CMD_IMHEIGHT)) ? ima->h : ima->w);
else snprintf(buf, 63, CC_CMD_IMWIDTH "=%d", ima->w);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE; return CC_RESULT_SILENCE;
} }
@@ -338,7 +383,8 @@ static cc_hresult camlisthandler(int fd, _U_ const char *key, _U_ const char *va
snprintf(buf, BUFSIZ-1, CC_CMD_CAMLIST "='%s'", modname); snprintf(buf, BUFSIZ-1, CC_CMD_CAMLIST "='%s'", modname);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
} }
if(camdevno > -1 && camera->setDevNo) camera->setDevNo(camdevno); int devno = atomic_load(&camdevno);
if(devno > -1 && camera->setDevNo) camera->setDevNo(devno);
return CC_RESULT_SILENCE; return CC_RESULT_SILENCE;
} }
static cc_hresult camsetNhandler(_U_ int fd, _U_ const char *key, _U_ const char *val){ static cc_hresult camsetNhandler(_U_ int fd, _U_ const char *key, _U_ const char *val){
@@ -350,7 +396,7 @@ static cc_hresult camsetNhandler(_U_ int fd, _U_ const char *key, _U_ const char
} }
if(!camdevini(num)) return CC_RESULT_FAIL; if(!camdevini(num)) return CC_RESULT_FAIL;
} }
snprintf(buf, 63, CC_CMD_CAMDEVNO "=%d", camdevno); snprintf(buf, 63, CC_CMD_CAMDEVNO "=%d", atomic_load(&camdevno));
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE; return CC_RESULT_SILENCE;
} }
@@ -371,76 +417,6 @@ static cc_hresult exphandler(int fd, _U_ const char *key, const char *val){
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE; return CC_RESULT_SILENCE;
} }
// show last filename of saved FITS
static cc_hresult lastfnamehandler(int fd, _U_ const char *key, _U_ const char *val){
char buf[PATH_MAX+32];
if(lastfile && *lastfile) snprintf(buf, PATH_MAX+31, CC_CMD_LASTFNAME "=%s", lastfile);
else snprintf(buf, PATH_MAX+31, CC_CMD_LASTFNAME "=");
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE;
}
// filename setter/getter
static cc_hresult namehandler(int fd, _U_ const char *key, const char *val){
char buf[PATH_MAX+32];
DBG("filename=%s", val);
if(val && *val){
DBG("Make abs path");
char *path = makeabspath(val, FALSE);
if(!path){
LOGERR("Can't create file '%s'", val);
return CC_RESULT_BADVAL;
}
FREE(outfile);
outfile = strdup(path);
GP->outfile = outfile;
GP->outfileprefix = NULL;
}else{ // clear names
DBG("Clear names");
GP->outfileprefix = NULL;
GP->outfile = NULL;
return CC_RESULT_OK;
}
if(!GP->outfile) return CC_RESULT_FAIL;
snprintf(buf, PATH_MAX+31, CC_CMD_FILENAME "=%s", GP->outfile);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE;
}
// filename prefix
static cc_hresult nameprefixhandler(_U_ int fd, _U_ const char *key, const char *val){
char buf[PATH_MAX+32];
DBG("filename prefix=%s", val);
if(val){
char *path = makeabspath(val, FALSE);
if(!path){
LOGERR("Can't create file '%s'", val);
return CC_RESULT_BADVAL;
}
FREE(outfile);
outfile = strdup(path);
GP->outfileprefix = outfile;
GP->outfile = NULL;
}else{ // clear names
GP->outfileprefix = NULL;
GP->outfile = NULL;
return CC_RESULT_OK;
}
if(!GP->outfileprefix) return CC_RESULT_FAIL;
snprintf(buf, PATH_MAX+31, CC_CMD_FILENAMEPREFIX "=%s", GP->outfileprefix);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE;
}
// rewrite
static cc_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 CC_RESULT_BADVAL;
GP->rewrite = n;
}
snprintf(buf, 63, CC_CMD_REWRITE "=%d", GP->rewrite);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE;
}
static cc_hresult binhandler(_U_ int fd, const char *key, const char *val){ static cc_hresult binhandler(_U_ int fd, const char *key, const char *val){
char buf[64]; char buf[64];
if(val){ if(val){
@@ -517,8 +493,9 @@ static cc_hresult camfanhandler(int fd, _U_ const char *key, _U_ const char *val
} }
const char *shutterstr[] = {"open", "close", "expose @high", "expose @low"}; const char *shutterstr[] = {"open", "close", "expose @high", "expose @low"};
static cc_hresult shutterhandler(_U_ int fd, _U_ const char *key, const char *val){ static cc_hresult shutterhandler(_U_ int fd, _U_ const char *key, const char *val){
char buf[64];
if(!camera->shuttercmd) return CC_RESULT_FAIL; if(!camera->shuttercmd) return CC_RESULT_FAIL;
if(val){ if(!val) return CC_RESULT_BADVAL;
int x = atoi(val); int x = atoi(val);
if(x < 0 || x >= SHUTTER_AMOUNT) return CC_RESULT_BADVAL; if(x < 0 || x >= SHUTTER_AMOUNT) return CC_RESULT_BADVAL;
int r = camera->shuttercmd((cc_shutter_op)x); int r = camera->shuttercmd((cc_shutter_op)x);
@@ -528,8 +505,9 @@ static cc_hresult shutterhandler(_U_ int fd, _U_ const char *key, const char *va
LOGWARN("Can't run shutter command '%s'", shutterstr[x]); LOGWARN("Can't run shutter command '%s'", shutterstr[x]);
return CC_RESULT_FAIL; return CC_RESULT_FAIL;
} }
} snprintf(buf, 63, "%s=%d", key, x);
return CC_RESULT_OK; if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE;
} }
static cc_hresult confiohandler(_U_ int fd, _U_ const char *key, _U_ const char *val){ static cc_hresult confiohandler(_U_ int fd, _U_ const char *key, _U_ const char *val){
char buf[64]; char buf[64];
@@ -636,29 +614,33 @@ static cc_hresult nflusheshandler(_U_ int fd, _U_ const char *key, _U_ const cha
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE; return CC_RESULT_SILENCE;
} }
static cc_hresult expstatehandler(_U_ int fd, _U_ const char *key, _U_ const char *val){ static cc_hresult expstatehandler(int fd, _U_ const char *key, const char *val){
char buf[64]; char buf[64];
if(val){ if(val){
int n = atoi(val); int n = atoi(val);
if(n == CAMERA_IDLE){ // cancel expositions if(n == CAMERA_IDLE){ // cancel expositions
camflags |= FLAG_CANCEL; camflags |= FLAG_CANCEL;
return CC_RESULT_OK;
} }
else if(n == CAMERA_CAPTURE){ // start exposition else if(n == CAMERA_CAPTURE){ // start exposition
if(GP->exptime < 1e-9){ if(GP->exptime < 1e-9){ // need exposition time to be set
snprintf(buf, 63, CC_CMD_EXPOSITION "=%g", GP->exptime);
cc_sendstrmessage(fd, buf);
return CC_RESULT_FAIL; return CC_RESULT_FAIL;
} }
if(camstate == CAMERA_CAPTURE){
DBG("Capture in process when user ask '%s=%s'", key, val);
return CC_RESULT_BUSY; // in progress
}
TIMESTAMP("Get FLAG_STARTCAPTURE"); TIMESTAMP("Get FLAG_STARTCAPTURE");
TIMEINIT(); TIMEINIT();
camflags |= FLAG_STARTCAPTURE; camflags |= FLAG_STARTCAPTURE;
return CC_RESULT_OK;
} }
else return CC_RESULT_BADVAL; else return CC_RESULT_BADVAL;
} }
snprintf(buf, 63, CC_CMD_EXPSTATE "=%d", camstate); snprintf(buf, 63, CC_CMD_EXPSTATE "=%d", camstate);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE;
}
static cc_hresult camflagshandler(int fd, _U_ const char *key, _U_ const char *val){
char buf[64];
snprintf(buf, 63, "camflags=%d", camflags); snprintf(buf, 63, "camflags=%d", camflags);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE; return CC_RESULT_SILENCE;
@@ -683,6 +665,16 @@ static cc_hresult _8bithandler(int fd, _U_ const char *key, const char *val){
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE; return CC_RESULT_SILENCE;
} }
static cc_hresult imnohandler(int fd, const char *key, const char _U_ *val){
if(!ima) return CC_RESULT_FAIL;
char buf[64];
cc_lock_shm(TRUE);
int No = ima->imnumber;
cc_unlock_shm();
snprintf(buf, 63, "%s=%d", key, No);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE;
}
static cc_hresult fastspdhandler(int fd, _U_ const char *key, const char *val){ static cc_hresult fastspdhandler(int fd, _U_ const char *key, const char *val){
char buf[64]; char buf[64];
if(!camera->setfastspeed) return CC_RESULT_FAIL; if(!camera->setfastspeed) return CC_RESULT_FAIL;
@@ -733,77 +725,6 @@ static cc_hresult FITSparhandler(int fd, const char *key, const char *val){
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE; return CC_RESULT_SILENCE;
} }
static cc_hresult FITSheaderhandler(int fd, _U_ const char *key, const char *val){
char buf[BUFSIZ], **sptr;
static char *curhdr = NULL;
static int firstrun = 1;
if(val){
int sz = 10, amount = 0;
// first we should check `val`
char b2[BUFSIZ], *bptr = buf;
snprintf(b2, BUFSIZ-1, "%s", val);
char **list = MALLOC(char*, sz), **lptr = list;
int L = BUFSIZ;
for(char *s = b2; ; s = NULL){
char *tok = strtok(s, ",;");
if(!tok){
*lptr = NULL;
break;
}
// check path
char *newpath = makeabspath(tok, TRUE);
DBG("next token: %s, path: %s", tok, newpath);
if(!newpath){ // error! Free list and return err
DBG("No such file");
sptr = list;
while(*sptr){
FREE(*sptr++);
}
FREE(list);
return CC_RESULT_BADVAL;
}
*lptr++ = strdup(newpath);
if(++amount == sz){
DBG("Realloc");
sz += 10;
list = realloc(list, sz*sizeof(char*));
bzero(&list[sz-10], 10*sizeof(char*));
}
int N = snprintf(bptr, L-1, "%s,", newpath);
bptr += N; L -= N;
}
// free old list and change its value
if(GP->addhdr){
DBG("Free old list");
sptr = GP->addhdr;
while(*sptr){
DBG("Free %s", *sptr);
free(*(sptr++));
}
}
GP->addhdr = list;
FREE(curhdr);
if(*val && *val != ',') curhdr = strdup(buf); // command with empty arg will clear curhdr
DBG("curhdr now: %s", curhdr);
}
if(!curhdr && firstrun){
firstrun = 0;
if(GP->addhdr && *GP->addhdr){
char *ptr = buf;
int L = BUFSIZ;
sptr = GP->addhdr;
while(*sptr){
DBG("Add to curhdr: %s", *sptr);
int N = snprintf(ptr, L-1, "%s,", *sptr++);
L -= N; ptr += N;
}
curhdr = strdup(buf);
}
}
snprintf(buf, BUFSIZ-1, CC_CMD_HEADERFILES "=%s", curhdr);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE;
}
/* /*
static cc_hresult handler(_U_ int fd, _U_ const char *key, _U_ const char *val){ static cc_hresult handler(_U_ int fd, _U_ const char *key, _U_ const char *val){
char buf[64]; char buf[64];
@@ -813,6 +734,22 @@ static cc_hresult handler(_U_ int fd, _U_ const char *key, _U_ const char *val){
/******************************************************************************* /*******************************************************************************
***************************** cc_Wheel handlers ********************************** ***************************** cc_Wheel handlers **********************************
******************************************************************************/ ******************************************************************************/
static cc_hresult wmaxposhandler(int fd, const char *key, _U_ const char *val){
if(wheel->Ndevices < 1) return CC_RESULT_FAIL;
char buf[64];
snprintf(buf, 63, "%s=%d", key, wmaxpos);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE;
}
static cc_hresult wtemphandler(int fd, const char *key, _U_ const char *val){
if(wheel->Ndevices < 1 || !wheel->getTbody) return CC_RESULT_FAIL;
char buf[64];
float t;
if(!wheel->getTbody(&t)) return CC_RESULT_FAIL;
snprintf(buf, 63, "%s=%.1f", key, t);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE;
}
static cc_hresult wlisthandler(int fd, _U_ const char *key, _U_ const char *val){ static cc_hresult wlisthandler(int fd, _U_ const char *key, _U_ const char *val){
if(wheel->Ndevices < 1) return CC_RESULT_FAIL; if(wheel->Ndevices < 1) return CC_RESULT_FAIL;
for(int i = 0; i < wheel->Ndevices; ++i){ for(int i = 0; i < wheel->Ndevices; ++i){
@@ -822,7 +759,8 @@ static cc_hresult wlisthandler(int fd, _U_ const char *key, _U_ const char *val)
snprintf(buf, BUFSIZ-1, CC_CMD_WLIST "='%s'", modname); snprintf(buf, BUFSIZ-1, CC_CMD_WLIST "='%s'", modname);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
} }
if(wheeldevno > -1) wheel->setDevNo(wheeldevno); int devno = atomic_load(&wheeldevno);
if(devno > -1) wheel->setDevNo(devno);
return CC_RESULT_SILENCE; return CC_RESULT_SILENCE;
} }
static cc_hresult wsetNhandler(int fd, _U_ const char *key, const char *val){ static cc_hresult wsetNhandler(int fd, _U_ const char *key, const char *val){
@@ -834,7 +772,7 @@ static cc_hresult wsetNhandler(int fd, _U_ const char *key, const char *val){
} }
if(!wheeldevini(num)) return CC_RESULT_FAIL; if(!wheeldevini(num)) return CC_RESULT_FAIL;
} }
snprintf(buf, 63, CC_CMD_WDEVNO "=%d", wheeldevno); snprintf(buf, 63, CC_CMD_WDEVNO "=%d", atomic_load(&wheeldevno));
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE; return CC_RESULT_SILENCE;
} }
@@ -859,17 +797,42 @@ static cc_hresult wgotohandler(_U_ int fd, _U_ const char *key, _U_ const char *
/******************************************************************************* /*******************************************************************************
**************************** Focuser handlers ********************************* **************************** Focuser handlers *********************************
******************************************************************************/ ******************************************************************************/
static cc_hresult fminposhandler(int fd, const char *key, _U_ const char *val){
if(focuser->Ndevices < 1) return CC_RESULT_FAIL;
char buf[64];
snprintf(buf, 63, "%s=%g", key, focminpos);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE;
}
static cc_hresult fmaxposhandler(int fd, const char *key, _U_ const char *val){
if(focuser->Ndevices < 1) return CC_RESULT_FAIL;
char buf[64];
snprintf(buf, 63, "%s=%g", key, focmaxpos);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE;
}
static cc_hresult ftemphandler(int fd, const char *key, _U_ const char *val){
if(focuser->Ndevices < 1 || !focuser->getTbody) return CC_RESULT_FAIL;
char buf[64];
float t;
if(!focuser->getTbody(&t)) return CC_RESULT_FAIL;
snprintf(buf, 63, "%s=%.1f", key, t);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE;
}
static cc_hresult foclisthandler(int fd, _U_ const char *key, _U_ const char *val){ static cc_hresult foclisthandler(int fd, _U_ const char *key, _U_ const char *val){
if(focuser->Ndevices < 1) return CC_RESULT_FAIL; if(focuser->Ndevices < 1) return CC_RESULT_FAIL;
for(int i = 0; i < focuser->Ndevices; ++i){ for(int i = 0; i < focuser->Ndevices; ++i){
char modname[256], buf[BUFSIZ]; char modname[256], buf[BUFSIZ];
if(focuser->setDevNo){
if(!focuser->setDevNo(i)) continue; if(!focuser->setDevNo(i)) continue;
}
focuser->getModelName(modname, 255); focuser->getModelName(modname, 255);
snprintf(buf, BUFSIZ-1, CC_CMD_FOCLIST "='%s'", modname); snprintf(buf, BUFSIZ-1, CC_CMD_FOCLIST "='%s'", modname);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
} }
if(focdevno > -1) focuser->setDevNo(focdevno); int devno = atomic_load(&focdevno);
if(devno > -1 && focuser->setDevNo) focuser->setDevNo(devno);
return CC_RESULT_SILENCE; return CC_RESULT_SILENCE;
} }
static cc_hresult fsetNhandler(int fd, _U_ const char *key, const char *val){ static cc_hresult fsetNhandler(int fd, _U_ const char *key, const char *val){
@@ -881,7 +844,7 @@ static cc_hresult fsetNhandler(int fd, _U_ const char *key, const char *val){
} }
if(!focdevini(num)) return CC_RESULT_FAIL; if(!focdevini(num)) return CC_RESULT_FAIL;
} }
snprintf(buf, 63, CC_CMD_FDEVNO "=%d", focdevno); snprintf(buf, 63, CC_CMD_FDEVNO "=%d", atomic_load(&focdevno));
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE; return CC_RESULT_SILENCE;
} }
@@ -910,65 +873,6 @@ static cc_hresult fgotohandler(int fd, _U_ const char *key, const char *val){
**************************** Common handlers ********************************** **************************** Common handlers **********************************
******************************************************************************/ ******************************************************************************/
// information about everything
static cc_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 && camera->getModelName(buf1, 255)){
snprintf(buf, BUFSIZ-1, CC_CMD_CAMLIST "='%s'", buf1);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
}
#define RUN(f, arg) do{if(CC_RESULT_DISCONNECTED == f(fd, arg, NULL)) return CC_RESULT_DISCONNECTED;}while(0)
RUN(namehandler, CC_CMD_FILENAME);
RUN(binhandler, CC_CMD_HBIN);
RUN(binhandler, CC_CMD_VBIN);
RUN(temphandler, CC_CMD_CAMTEMPER);
RUN(exphandler, CC_CMD_EXPOSITION);
RUN(lastfnamehandler, CC_CMD_LASTFNAME);
RUN(expstatehandler, CC_CMD_EXPSTATE);
#undef RUN
}
if(wheel){
DBG("chk wheel");
if(wheel->getModelName(buf1, 255)){
snprintf(buf, BUFSIZ-1, CC_CMD_WLIST "='%s'", buf1);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
}
if(wheel->getTbody(&f)){
snprintf(buf, BUFSIZ-1, "wtemp=%.1f", f);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
}
if(wheel->getPos(&i)){
snprintf(buf, BUFSIZ-1, CC_CMD_WPOS "=%d", i);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
}
snprintf(buf, BUFSIZ-1, "wmaxpos=%d", wmaxpos);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
}
if(focuser){
DBG("Chk focuser");
if(focuser->getModelName(buf1, 255)){
snprintf(buf, BUFSIZ-1, CC_CMD_FOCLIST "='%s'", buf1);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
}
if(focuser->getTbody(&f)){
snprintf(buf, BUFSIZ-1, "foctemp=%.1f", f);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
}
snprintf(buf, BUFSIZ-1, "focminpos=%g", focminpos);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
snprintf(buf, BUFSIZ-1, "focmaxpos=%g", focmaxpos);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
if(focuser->getPos(&f)){
snprintf(buf, BUFSIZ-1, CC_CMD_FGOTO "=%g", f);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
}
}
DBG("EOF");
return CC_RESULT_SILENCE;
}
// show help // show help
static cc_hresult helphandler(int fd, _U_ const char *key, _U_ const char *val){ static cc_hresult helphandler(int fd, _U_ const char *key, _U_ const char *val){
char buf[256]; char buf[256];
@@ -981,7 +885,7 @@ static cc_hresult helphandler(int fd, _U_ const char *key, _U_ const char *val){
return CC_RESULT_SILENCE; return CC_RESULT_SILENCE;
} }
// shared memory key // shared memory key getter
static cc_hresult shmemkeyhandler(int fd, _U_ const char *key, _U_ const char *val){ static cc_hresult shmemkeyhandler(int fd, _U_ const char *key, _U_ const char *val){
char buf[64]; char buf[64];
if(shmkey == IPC_PRIVATE) return CC_RESULT_FAIL; if(shmkey == IPC_PRIVATE) return CC_RESULT_FAIL;
@@ -1018,9 +922,15 @@ static cc_hresult pluginhandler(int fd, _U_ const char *key, const char *val){
// get headers // get headers
static cc_hresult gethdrshandler(int fd, _U_ const char *key, _U_ const char *val){ static cc_hresult gethdrshandler(int fd, _U_ const char *key, _U_ const char *val){
cc_charbuff *b = getFITSheader(ima); if(!ima) return CC_RESULT_FAIL;
if(!b) return CC_RESULT_FAIL; size_t nlines = ima->headerstrings;
if(!cc_sendstrmessage(fd, b->buf)) return CC_RESULT_DISCONNECTED; if(nlines < 1) return CC_RESULT_FAIL;
char buf[FLEN_CARD+1];
for(size_t n = 0; n < nlines; ++n){
snprintf(buf, FLEN_CARD+1, "%s\n", ima->fitsheader[n]);
if(!cc_sendstrmessage(fd, buf))
return CC_RESULT_DISCONNECTED;
}
return CC_RESULT_SILENCE; return CC_RESULT_SILENCE;
} }
@@ -1056,14 +966,14 @@ static cc_hresult chkfoc(char *val){
return CC_RESULT_FAIL; return CC_RESULT_FAIL;
} }
static cc_handleritem items[] = { static cc_handleritem items[] = {
{chktrue,infohandler, CC_CMD_INFO},
{NULL, helphandler, CC_CMD_HELP}, {NULL, helphandler, CC_CMD_HELP},
{NULL, restarthandler, CC_CMD_RESTART}, {NULL, restarthandler, CC_CMD_RESTART},
{chkcc, camlisthandler, CC_CMD_CAMLIST}, {chkcc, camlisthandler, CC_CMD_CAMLIST},
{chkcc, camflagshandler, CC_CMD_CAMFLAGS},
{chkcc, camsetNhandler, CC_CMD_CAMDEVNO}, {chkcc, camsetNhandler, CC_CMD_CAMDEVNO},
{chkcc, camfanhandler, CC_CMD_CAMFANSPD}, {chkcc, camfanhandler, CC_CMD_CAMFANSPD},
{chkcc, exphandler, CC_CMD_EXPOSITION}, {chkcc, exphandler, CC_CMD_EXPOSITION},
{chkcc, namehandler, CC_CMD_FILENAME}, {chkcc, imnohandler, CC_CMD_IMNUMBER},
{chkcc, binhandler, CC_CMD_HBIN}, {chkcc, binhandler, CC_CMD_HBIN},
{chkcc, binhandler, CC_CMD_VBIN}, {chkcc, binhandler, CC_CMD_VBIN},
{chkcc, temphandler, CC_CMD_CAMTEMPER}, {chkcc, temphandler, CC_CMD_CAMTEMPER},
@@ -1079,8 +989,6 @@ static cc_handleritem items[] = {
{chktrue,shmemkeyhandler, CC_CMD_SHMEMKEY}, {chktrue,shmemkeyhandler, CC_CMD_SHMEMKEY},
{chktrue,imsizehandler, CC_CMD_IMWIDTH}, {chktrue,imsizehandler, CC_CMD_IMWIDTH},
{chktrue,imsizehandler, CC_CMD_IMHEIGHT}, {chktrue,imsizehandler, CC_CMD_IMHEIGHT},
{chkcc, nameprefixhandler, CC_CMD_FILENAMEPREFIX},
{chkcc, rewritefilehandler, CC_CMD_REWRITE},
{chkcc, _8bithandler, CC_CMD_8BIT}, {chkcc, _8bithandler, CC_CMD_8BIT},
{chkcc, fastspdhandler, CC_CMD_FASTSPD}, {chkcc, fastspdhandler, CC_CMD_FASTSPD},
{chkcc, darkhandler, CC_CMD_DARK}, {chkcc, darkhandler, CC_CMD_DARK},
@@ -1094,14 +1002,17 @@ static cc_handleritem items[] = {
{NULL, FITSparhandler, CC_CMD_OBJECT}, {NULL, FITSparhandler, CC_CMD_OBJECT},
{NULL, FITSparhandler, CC_CMD_PROGRAM}, {NULL, FITSparhandler, CC_CMD_PROGRAM},
{NULL, FITSparhandler, CC_CMD_OBJTYPE}, {NULL, FITSparhandler, CC_CMD_OBJTYPE},
{NULL, FITSheaderhandler, CC_CMD_HEADERFILES},
{NULL, lastfnamehandler, CC_CMD_LASTFNAME},
{chkfoc, foclisthandler, CC_CMD_FOCLIST}, {chkfoc, foclisthandler, CC_CMD_FOCLIST},
{chkfoc, fsetNhandler, CC_CMD_FDEVNO}, {chkfoc, fsetNhandler, CC_CMD_FDEVNO},
{chkfoc, fgotohandler, CC_CMD_FGOTO}, {chkfoc, fgotohandler, CC_CMD_FGOTO},
{chkfoc, fminposhandler, CC_CMD_FMINPOS},
{chkfoc, fmaxposhandler, CC_CMD_FMAXPOS},
{chkfoc, ftemphandler, CC_CMD_FTEMP},
{chkwhl, wlisthandler, CC_CMD_WLIST}, {chkwhl, wlisthandler, CC_CMD_WLIST},
{chkwhl, wsetNhandler, CC_CMD_WDEVNO}, {chkwhl, wsetNhandler, CC_CMD_WDEVNO},
{chkwhl, wgotohandler, CC_CMD_WPOS}, {chkwhl, wgotohandler, CC_CMD_WPOS},
{chkwhl, wmaxposhandler, CC_CMD_WMAXPOS},
{chkwhl, wtemphandler, CC_CMD_WTEMP},
{NULL, NULL, NULL}, {NULL, NULL, NULL},
}; };
@@ -1109,10 +1020,25 @@ static cc_handleritem items[] = {
#define STRBUFSZ (255) #define STRBUFSZ (255)
// send image as raw data // send image as raw data
static void sendimage(int client){ static void *sendimage(void *C){
if(ima->h < 1 || ima->w < 1) return; if(!C || !ima || !ima->data) return NULL;
cc_senddata(client, ima, sizeof(cc_IMG)); int client = *(int*)C;
cc_senddata(client, ima->data, ima->bytelen); if(ima->h < 1 || ima->w < 1) return NULL;
DBG("client fd: %d", client);
do{
// send image body
if(!cc_senddata(client, ima, sizeof(cc_IMG))) break;
// send image itself (client can close socket if don't need image data)
if(!cc_senddata(client, ima->data, ima->bytelen)) break;
// send FITS header (client can close socket if don't need it)
for(size_t i = 0; i < ima->headerstrings; ++i){ // send header
if(!cc_senddata(client, &ima->fitsheader[i], FLEN_CARD)) break;
}
}while(0);
close(client);
TIMESTAMP("Image sent");
DBG("%d closed", client);
return NULL;
} }
void server(int sock, int imsock){ void server(int sock, int imsock){
@@ -1121,12 +1047,12 @@ void server(int sock, int imsock){
if(imsock < 0) WARNX("Server run without image transport socket"); if(imsock < 0) WARNX("Server run without image transport socket");
else if(listen(imsock, CC_MAXCLIENTS) == -1){ else if(listen(imsock, CC_MAXCLIENTS) == -1){
WARN("listen()"); WARN("listen()");
LOGWARN("listen()"); LOGERR("server(): error in listen() for image socket");
return; return;
} }
if(listen(sock, CC_MAXCLIENTS) == -1){ if(listen(sock, CC_MAXCLIENTS) == -1){
WARN("listen()"); WARN("listen()");
LOGWARN("listen()"); LOGERR("server(): error in listen() for command socket");
return; return;
} }
// init everything // init everything
@@ -1137,11 +1063,17 @@ void server(int sock, int imsock){
wheeldevini(0); wheeldevini(0);
if(startCCD()) --ctr; if(startCCD()) --ctr;
camdevini(0); camdevini(0);
if(ctr == 3) ERRX("No devices found"); if(ctr == 3){
LOGERR("server(): no devices found");
WARNX("No devices found");
}
// start camera thread // start camera thread
pthread_t camthread; pthread_t camthread;
if(camera){ if(camera){
if(pthread_create(&camthread, NULL, processCAM, NULL)) ERR("pthread_create()"); if(pthread_create(&camthread, NULL, processCAM, NULL)){
WARN("pthread_create()");
LOGERR("server(): pthread_create()");
}
} }
int nfd = 2; // only two listening sockets @start: command and image int nfd = 2; // only two listening sockets @start: command and image
struct pollfd poll_set[CC_MAXCLIENTS+2]; struct pollfd poll_set[CC_MAXCLIENTS+2];
@@ -1155,9 +1087,18 @@ void server(int sock, int imsock){
poll_set[0].events = POLLIN; poll_set[0].events = POLLIN;
poll_set[1].fd = imsock; poll_set[1].fd = imsock;
poll_set[1].events = POLLIN; poll_set[1].events = POLLIN;
while(1){ #ifdef EBUG
double T = sl_dtime();
#endif
while(isrunning == 1){
#ifdef EBUG
if(sl_dtime() - T > 5.){
T = sl_dtime();
printf("\t\t\tserver(), 5 seconds\n");
}
#endif
poll(poll_set, nfd, 1); // max timeout - 1ms poll(poll_set, nfd, 1); // max timeout - 1ms
//if(imsock > -1 && cc_canberead(imsock) > 0){ //if(imsock > -1 && sl_canread(imsock) > 0){
if(imsock > -1 && (poll_set[1].revents & POLLIN)){ if(imsock > -1 && (poll_set[1].revents & POLLIN)){
//uint8_t buf[32]; //uint8_t buf[32];
//int l = read(imsock, buf, 32); //int l = read(imsock, buf, 32);
@@ -1166,13 +1107,28 @@ void server(int sock, int imsock){
socklen_t len = sizeof(addr); socklen_t len = sizeof(addr);
int client = accept(imsock, (struct sockaddr*)&addr, &len); int client = accept(imsock, (struct sockaddr*)&addr, &len);
DBG("client=%d", client); DBG("client=%d", client);
// sending image could be a very long operation -> run it in separate thread
if(client > -1){ if(client > -1){
DBG("client fd: %d", client); if(ima->imnumber == 0){
sendimage(client); WARNX("Client wants an image, but there's no data");
close(client); close(client);
DBG("%d closed", client); }else{
pthread_t sendthread;
if(pthread_create(&sendthread, NULL, sendimage, (void*)&client)){
WARN("pthread_create()");
LOGWARN("pthread_create() error");
close(client);
}else{
DBG("Thread created -> detach");
if(pthread_detach(sendthread)){
WARN("pthread_detach()");
LOGWARN("pthread_detach() error");
pthread_cancel(sendthread);
close(client);
}else DBG("Thread detached");
}
}
}else{WARN("accept()"); DBG("disconnected");} }else{WARN("accept()"); DBG("disconnected");}
TIMESTAMP("Image sent");
} }
if(poll_set[0].revents & POLLIN){ // check main for accept() if(poll_set[0].revents & POLLIN){ // check main for accept()
struct sockaddr_in addr; struct sockaddr_in addr;
@@ -1193,6 +1149,7 @@ void server(int sock, int imsock){
} }
} }
} }
#if 0
// process some data & send messages to ALL // process some data & send messages to ALL
if(camstate == CAMERA_FRAMERDY || camstate == CAMERA_ERROR){ if(camstate == CAMERA_FRAMERDY || camstate == CAMERA_ERROR){
DBG("new image: timestamp=%.1f, num=%zd", ima->timestamp, ima->imnumber); DBG("new image: timestamp=%.1f, num=%zd", ima->timestamp, ima->imnumber);
@@ -1203,17 +1160,14 @@ void server(int sock, int imsock){
TIMESTAMP("Send message that all ready"); TIMESTAMP("Send message that all ready");
cc_sendstrmessage(poll_set[i].fd, buff); cc_sendstrmessage(poll_set[i].fd, buff);
} }
if(camstate == CAMERA_FRAMERDY && (GP->outfile || GP->outfileprefix)){ // send to all last file name if file saved
snprintf(buff, PATH_MAX+31, CC_CMD_LASTFNAME "=%s", lastfile);
for(int i = 2; i < nfd; ++i)
cc_sendstrmessage(poll_set[i].fd, buff);
}
camstate = CAMERA_IDLE; camstate = CAMERA_IDLE;
} }
#endif
// scan connections // scan connections
for(int fdidx = 2; fdidx < nfd; ++fdidx){ for(int fdidx = 2; fdidx < nfd; ++fdidx){
if((poll_set[fdidx].revents & POLLIN) == 0) continue; if((poll_set[fdidx].revents & POLLIN) == 0) continue;
int fd = poll_set[fdidx].fd; int fd = poll_set[fdidx].fd;
DBG("Got active fd=%d", fd);
cc_strbuff *curbuff = buffers[fdidx-1]; cc_strbuff *curbuff = buffers[fdidx-1];
int disconnected = 0; int disconnected = 0;
if(cc_read2buf(fd, curbuff)){ if(cc_read2buf(fd, curbuff)){
@@ -1236,7 +1190,7 @@ void server(int sock, int imsock){
} }
} }
// check `infty` // check `infty`
if(camstate == CAMERA_IDLE && infty){ // start new exposition if(camstate != CAMERA_CAPTURE && infty){ // start new exposition
// mark to start new capture in infinity loop when at least one client connected // mark to start new capture in infinity loop when at least one client connected
if(nfd > 2){ if(nfd > 2){
camflags |= FLAG_STARTCAPTURE; camflags |= FLAG_STARTCAPTURE;
@@ -1245,10 +1199,11 @@ void server(int sock, int imsock){
} }
} }
} }
// never reached WARNX("SERVER STOPPED!");
camstop();
focclose(); focclose();
closewheel(); closewheel();
closecam(); isrunning = -1;
} }
/** /**
@@ -1274,7 +1229,7 @@ char *makeabspath(const char *path, int shouldbe){
} }
if(!realpath(path, buf)){ if(!realpath(path, buf)){
WARN("realpath()"); WARN("realpath()");
return NULL; LOGWARN("realpath() error for %s", path);
}else ret = buf; }else ret = buf;
fclose(f); fclose(f);
if(unl) unlink(path); if(unl) unlink(path);

View File

@@ -18,6 +18,11 @@
#pragma once #pragma once
#include "ccdcapture.h"
// timeout of trying to lock mutex (if gone, force locking for server)
#define MUTEX_LOCK_TMOUT 0.5
// pause (seconds) between temperature logging // pause (seconds) between temperature logging
#define TLOG_PAUSE 60. #define TLOG_PAUSE 60.
@@ -25,3 +30,4 @@
void server(int fd, int imsock); void server(int fd, int imsock);
char *makeabspath(const char *path, int shouldbe); char *makeabspath(const char *path, int shouldbe);
void stop_server();