26 #include <libnova/julian_day.h>
34 #define IEQPRO_TIMEOUT 5
36 static bool ieqpro_debug =
false;
37 static bool ieqpro_simulation =
false;
51 ieqpro_debug = enable;
56 ieqpro_simulation = enable;
117 char initCMD[] =
":V#";
122 int nbytes_written = 0;
126 for (
int i = 0; i < 2; i++)
128 if (ieqpro_simulation)
130 strcpy(response,
"V1.00#");
131 nbytes_read = strlen(response);
135 tcflush(
fd, TCIFLUSH);
156 response[nbytes_read] =
'\0';
159 if (!strcmp(response,
"V1.00#"))
171 char cmd[] =
":GAS#";
176 int nbytes_written = 0;
180 if (ieqpro_simulation)
184 nbytes_read = strlen(response);
188 tcflush(
fd, TCIFLUSH);
207 response[nbytes_read] =
'\0';
210 if (nbytes_read == 7)
219 tcflush(
fd, TCIFLUSH);
250 char cmd[] =
":MountInfo#";
255 int nbytes_written = 0;
259 if (ieqpro_simulation)
261 strcpy(response,
"0045");
262 nbytes_read = strlen(response);
266 tcflush(
fd, TCIFLUSH);
285 response[nbytes_read] =
'\0';
288 if (nbytes_read == 4)
290 std::map<std::string, std::string> models =
292 {
"0010",
"Cube II EQ"},
293 {
"0011",
"Smart EQ Pro+"},
295 {
"0026",
"CEM25-EC"},
296 {
"0030",
"iEQ30Pro"},
298 {
"0041",
"CEM40-EC"},
300 {
"0045",
"iEQ45 Pro EQ"},
301 {
"0046",
"iEQ45 Pro AA"},
303 {
"0061",
"CEM60-EC"},
305 {
"0121",
"CEM120-EC"},
306 {
"0122",
"CEM120-EC2"},
307 {
"5010",
"Cube II AA"},
308 {
"5035",
"AZ Mount Pro"},
309 {
"5045",
"iEQ45 Pro AA"},
312 if (models.find(response) != models.end())
313 info->
Model = models[response];
315 info->
Model =
"Unknown";
317 tcflush(
fd, TCIFLUSH);
329 char cmd[] =
":FW1#";
334 int nbytes_written = 0;
338 if (ieqpro_simulation)
340 strcpy(response,
"150324150101#");
341 nbytes_read = strlen(response);
345 tcflush(
fd, TCIFLUSH);
364 response[nbytes_read] =
'\0';
367 if (nbytes_read == 13)
369 char board[8] = {0}, controller[8] = {0};
371 strncpy(board, response, 6);
372 strncpy(controller, response + 6, 6);
377 tcflush(
fd, TCIFLUSH);
389 char cmd[] =
":FW2#";
394 int nbytes_written = 0;
398 if (ieqpro_simulation)
400 strcpy(response,
"140324140101#");
401 nbytes_read = strlen(response);
405 tcflush(
fd, TCIFLUSH);
424 response[nbytes_read] =
'\0';
427 if (nbytes_read == 13)
429 char ra[8] = {0},
dec[8] = {0};
431 strncpy(
ra, response, 6);
432 strncpy(
dec, response + 6, 6);
437 tcflush(
fd, TCIFLUSH);
452 int nbytes_written = 0;
479 if (ieqpro_simulation)
482 tcflush(
fd, TCIFLUSH);
491 tcflush(
fd, TCIFLUSH);
502 int nbytes_written = 0;
519 if (ieqpro_simulation)
521 strcpy(response,
"1");
522 nbytes_read = strlen(response);
526 tcflush(
fd, TCIFLUSH);
545 response[nbytes_read] =
'\0';
548 tcflush(
fd, TCIFLUSH);
558 char cmd[] =
":MSH#";
563 int nbytes_written = 0;
567 if (ieqpro_simulation)
569 strcpy(response,
"1");
570 nbytes_read = strlen(response);
574 tcflush(
fd, TCIFLUSH);
593 response[nbytes_read] =
'\0';
596 tcflush(
fd, TCIFLUSH);
611 int nbytes_written = 0;
615 if (ieqpro_simulation)
617 strcpy(response,
"1");
618 nbytes_read = strlen(response);
622 tcflush(
fd, TCIFLUSH);
641 response[nbytes_read] =
'\0';
644 tcflush(
fd, TCIFLUSH);
654 char cmd[] =
":SZP#";
659 int nbytes_written = 0;
663 if (ieqpro_simulation)
665 strcpy(response,
"1");
666 nbytes_read = strlen(response);
670 tcflush(
fd, TCIFLUSH);
689 response[nbytes_read] =
'\0';
692 tcflush(
fd, TCIFLUSH);
707 int nbytes_written = 0;
709 snprintf(
cmd, 16,
":SR%d#", ((
int)rate) + 1);
713 if (ieqpro_simulation)
716 strcpy(response,
"1");
717 nbytes_read = strlen(response);
721 tcflush(
fd, TCIFLUSH);
740 response[nbytes_read] =
'\0';
743 tcflush(
fd, TCIFLUSH);
758 int nbytes_written = 0;
763 strcpy(
cmd,
":RT0#");
766 strcpy(
cmd,
":RT1#");
769 strcpy(
cmd,
":RT2#");
772 strcpy(
cmd,
":RT3#");
775 strcpy(
cmd,
":RT4#");
781 if (ieqpro_simulation)
784 strcpy(response,
"1");
785 nbytes_read = strlen(response);
789 tcflush(
fd, TCIFLUSH);
808 response[nbytes_read] =
'\0';
811 tcflush(
fd, TCIFLUSH);
827 int nbytes_written = 0;
834 snprintf(
cmd, 16,
":RR%c%07.4f#", sign, fabs(rate));
838 if (ieqpro_simulation)
840 strcpy(response,
"1");
841 nbytes_read = strlen(response);
845 tcflush(
fd, TCIFLUSH);
864 response[nbytes_read] =
'\0';
867 tcflush(
fd, TCIFLUSH);
883 int nbytes_written = 0;
890 snprintf(
cmd, 16,
":RD%c%07.4f#", sign, fabs(rate));
894 if (ieqpro_simulation)
896 strcpy(response,
"1");
897 nbytes_read = strlen(response);
901 tcflush(
fd, TCIFLUSH);
920 response[nbytes_read] =
'\0';
923 tcflush(
fd, TCIFLUSH);
938 int nbytes_written = 0;
940 snprintf(
cmd, 16,
":RG%02d%02d#",
static_cast<int>(raRate * 100.0),
static_cast<int>(deRate * 100.0));
944 if (ieqpro_simulation)
946 simData.ra_guide_rate = raRate;
947 simData.de_guide_rate = deRate;
948 strcpy(response,
"1");
949 nbytes_read = strlen(response);
953 tcflush(
fd, TCIFLUSH);
972 response[nbytes_read] =
'\0';
975 tcflush(
fd, TCIFLUSH);
988 char response[8] = {0};
990 int nbytes_written = 0;
994 if (ieqpro_simulation)
996 snprintf(response, 8,
"%02d%02d#",
static_cast<int>(
simData.ra_guide_rate * 100),
997 static_cast<int>(
simData.de_guide_rate * 100));
998 nbytes_read = strlen(response);
1002 tcflush(
fd, TCIFLUSH);
1019 if (nbytes_read > 0)
1021 response[nbytes_read - 1] =
'\0';
1024 char raRateStr[8] = {0}, deRateStr[8] = {0};
1025 strncpy(response, raRateStr, 2);
1026 strncpy(response + 2, deRateStr, 2);
1027 *raRate = atoi(raRateStr) / 100.0;
1028 *deRate = atoi(deRateStr) / 100.0;
1029 tcflush(
fd, TCIFLUSH);
1042 int nbytes_written = 0;
1065 snprintf(
cmd, 16,
":M%c%05d#", dir_c, ms);
1069 if (ieqpro_simulation)
1073 tcflush(
fd, TCIFLUSH);
1083 tcflush(
fd, TCIFLUSH);
1089 char cmd[] =
":MP1#";
1093 int nbytes_read = 0;
1094 int nbytes_written = 0;
1098 if (ieqpro_simulation)
1102 strcpy(response,
"1");
1103 nbytes_read = strlen(response);
1107 tcflush(
fd, TCIFLUSH);
1124 if (nbytes_read > 0)
1126 response[nbytes_read] =
'\0';
1129 if (!strcmp(response,
"1"))
1131 tcflush(
fd, TCIFLUSH);
1147 char cmd[] =
":MP0#";
1151 int nbytes_read = 0;
1152 int nbytes_written = 0;
1156 if (ieqpro_simulation)
1159 strcpy(response,
"1");
1160 nbytes_read = strlen(response);
1164 tcflush(
fd, TCIFLUSH);
1181 if (nbytes_read > 0)
1183 response[nbytes_read] =
'\0';
1186 tcflush(
fd, TCIFLUSH);
1200 int nbytes_read = 0;
1201 int nbytes_written = 0;
1205 if (ieqpro_simulation)
1209 strcpy(response,
"1");
1210 nbytes_read = strlen(response);
1214 tcflush(
fd, TCIFLUSH);
1231 if (nbytes_read > 0)
1233 response[nbytes_read] =
'\0';
1236 tcflush(
fd, TCIFLUSH);
1246 char cmd[] =
":MS#";
1250 int nbytes_read = 0;
1251 int nbytes_written = 0;
1255 if (ieqpro_simulation)
1259 strcpy(response,
"1");
1260 nbytes_read = strlen(response);
1264 tcflush(
fd, TCIFLUSH);
1281 if (nbytes_read > 0)
1283 response[nbytes_read] =
'\0';
1286 if (!strcmp(response,
"1"))
1288 tcflush(
fd, TCIFLUSH);
1294 tcflush(
fd, TCIFLUSH);
1305 char cmd[] =
":CM#";
1309 int nbytes_read = 0;
1310 int nbytes_written = 0;
1314 if (ieqpro_simulation)
1316 strcpy(response,
"1");
1317 nbytes_read = strlen(response);
1321 tcflush(
fd, TCIFLUSH);
1338 if (nbytes_read > 0)
1340 response[nbytes_read] =
'\0';
1343 tcflush(
fd, TCIFLUSH);
1357 int nbytes_read = 0;
1358 int nbytes_written = 0;
1360 snprintf(
cmd, 32,
":ST%d#", enabled ? 1 : 0);
1364 if (ieqpro_simulation)
1367 strcpy(response,
"1");
1368 nbytes_read = strlen(response);
1372 tcflush(
fd, TCIFLUSH);
1389 if (nbytes_read > 0)
1391 response[nbytes_read] =
'\0';
1394 tcflush(
fd, TCIFLUSH);
1408 int nbytes_read = 0;
1409 int nbytes_written = 0;
1412 int ieqValue =
ra * 60 * 60 * 1000;
1414 snprintf(
cmd, 32,
":Sr%08d#", ieqValue);
1418 if (ieqpro_simulation)
1421 strcpy(response,
"1");
1422 nbytes_read = strlen(response);
1426 tcflush(
fd, TCIFLUSH);
1443 if (nbytes_read > 0)
1445 response[nbytes_read] =
'\0';
1448 tcflush(
fd, TCIFLUSH);
1463 int nbytes_read = 0;
1464 int nbytes_written = 0;
1472 int ieqValue = fabs(
dec) * 60 * 60 * 100;
1474 snprintf(
cmd, 32,
":Sd%c%08d#", sign, ieqValue);
1478 if (ieqpro_simulation)
1481 strcpy(response,
"1");
1482 nbytes_read = strlen(response);
1486 tcflush(
fd, TCIFLUSH);
1503 if (nbytes_read > 0)
1505 response[nbytes_read] =
'\0';
1508 tcflush(
fd, TCIFLUSH);
1523 int nbytes_read = 0;
1524 int nbytes_written = 0;
1531 int longitude_arcsecs = fabs(longitude) * 60 * 60;
1532 snprintf(
cmd, 16,
":Sg%c%06d#", sign, longitude_arcsecs);
1536 if (ieqpro_simulation)
1538 strcpy(response,
"1");
1539 nbytes_read = strlen(response);
1543 tcflush(
fd, TCIFLUSH);
1560 if (nbytes_read > 0)
1562 response[nbytes_read] =
'\0';
1565 tcflush(
fd, TCIFLUSH);
1580 int nbytes_read = 0;
1581 int nbytes_written = 0;
1588 int latitude_arcsecs = fabs(latitude) * 60 * 60;
1589 snprintf(
cmd, 16,
":St%c%06d#", sign, latitude_arcsecs);
1593 if (ieqpro_simulation)
1595 strcpy(response,
"1");
1596 nbytes_read = strlen(response);
1600 tcflush(
fd, TCIFLUSH);
1617 if (nbytes_read > 0)
1619 response[nbytes_read] =
'\0';
1622 tcflush(
fd, TCIFLUSH);
1636 int nbytes_read = 0;
1637 int nbytes_written = 0;
1639 strcpy(
cmd,
":Gg#");
1643 if (ieqpro_simulation)
1645 strcpy(response,
"+172800");
1646 nbytes_read = strlen(response);
1650 tcflush(
fd, TCIFLUSH);
1666 if (nbytes_read > 0)
1668 response[nbytes_read - 1] =
'\0';
1671 tcflush(
fd, TCIFLUSH);
1673 int longitude_arcsecs = 0;
1675 if (sscanf(response,
"%d", &longitude_arcsecs) > 0)
1677 *longitude = longitude_arcsecs / 3600.0;
1695 int nbytes_read = 0;
1696 int nbytes_written = 0;
1698 strcpy(
cmd,
":Gt#");
1702 if (ieqpro_simulation)
1704 strcpy(response,
"+106200");
1705 nbytes_read = strlen(response);
1709 tcflush(
fd, TCIFLUSH);
1725 if (nbytes_read > 0)
1727 response[nbytes_read - 1] =
'\0';
1730 tcflush(
fd, TCIFLUSH);
1732 int latitude_arcsecs = 0;
1734 if (sscanf(response,
"%d", &latitude_arcsecs) > 0)
1736 *latitude = latitude_arcsecs / 3600.0;
1754 int nbytes_read = 0;
1755 int nbytes_written = 0;
1757 snprintf(
cmd, 16,
":SC%02d%02d%02d#", yy, mm, dd);
1761 if (ieqpro_simulation)
1763 strcpy(response,
"1");
1764 nbytes_read = strlen(response);
1768 tcflush(
fd, TCIFLUSH);
1785 if (nbytes_read > 0)
1787 response[nbytes_read] =
'\0';
1790 tcflush(
fd, TCIFLUSH);
1804 int nbytes_read = 0;
1805 int nbytes_written = 0;
1807 snprintf(
cmd, 16,
":SL%02d%02d%02d#", hh, mm, ss);
1811 if (ieqpro_simulation)
1813 strcpy(response,
"1");
1814 nbytes_read = strlen(response);
1818 tcflush(
fd, TCIFLUSH);
1835 if (nbytes_read > 0)
1837 response[nbytes_read] =
'\0';
1840 tcflush(
fd, TCIFLUSH);
1854 int nbytes_read = 0;
1855 int nbytes_written = 0;
1858 strcpy(
cmd,
":SDS1#");
1860 strcpy(
cmd,
":SDS0#");
1864 if (ieqpro_simulation)
1866 strcpy(response,
"1");
1867 nbytes_read = strlen(response);
1871 tcflush(
fd, TCIFLUSH);
1888 if (nbytes_read > 0)
1890 response[nbytes_read] =
'\0';
1893 tcflush(
fd, TCIFLUSH);
1908 int nbytes_read = 0;
1909 int nbytes_written = 0;
1916 int offset_minutes = fabs(offset) * 60.0;
1918 snprintf(
cmd, 16,
":SG%c%03d#", sign, offset_minutes);
1922 if (ieqpro_simulation)
1924 strcpy(response,
"1");
1925 nbytes_read = strlen(response);
1929 tcflush(
fd, TCIFLUSH);
1946 if (nbytes_read > 0)
1948 response[nbytes_read] =
'\0';
1951 tcflush(
fd, TCIFLUSH);
1961 char cmd[] =
":GEC#";
1965 int nbytes_read = 0;
1966 int nbytes_written = 0;
1970 if (ieqpro_simulation)
1972 char ra_str[16], dec_str[16];
1980 int ieqDEC = fabs(
simData.dec) * 60 * 60 * 100;
1982 snprintf(dec_str, 16,
"%c%08d", sign, ieqDEC);
1984 int ieqRA =
simData.ra * 60 * 60 * 1000;
1985 snprintf(ra_str, 16,
"%08d", ieqRA);
1987 snprintf(response, 32,
"%s%s#", dec_str, ra_str);
1988 nbytes_read = strlen(response);
1992 tcflush(
fd, TCIFLUSH);
2009 if (nbytes_read > 0)
2011 tcflush(
fd, TCIFLUSH);
2012 response[nbytes_read] =
'\0';
2015 char ra_str[16] = {0}, dec_str[16] = {0};
2017 strncpy(dec_str, response, 9);
2018 strncpy(ra_str, response + 9, 8);
2020 int ieqDEC = atoi(dec_str);
2021 int ieqRA = atoi(ra_str);
2023 *
ra = ieqRA / (60.0 * 60.0 * 1000.0);
2024 *
dec = ieqDEC / (60.0 * 60.0 * 100.0);
2035 char cmd[] =
":GLT#";
2039 int nbytes_read = 0;
2040 int nbytes_written = 0;
2048 if (ieqpro_simulation)
2050 strncpy(response,
"+1800150321173000#", 32);
2051 nbytes_read = strlen(response);
2055 tcflush(
fd, TCIFLUSH);
2072 if (nbytes_read > 0)
2074 tcflush(
fd, TCIFLUSH);
2075 response[nbytes_read] =
'\0';
2078 char utc_str[8] = {0}, yy_str[8] = {0}, mm_str[8] = {0}, dd_str[8] = {0}, hh_str[8] = {0}, minute_str[8] = {0}, ss_str[8] = {0},
2082 strncpy(utc_str, response, 4);
2084 strncpy(dst_str, response + 4, 1);
2086 strncpy(yy_str, response + 5, 2);
2088 strncpy(mm_str, response + 7, 2);
2090 strncpy(dd_str, response + 9, 2);
2092 strncpy(hh_str, response + 11, 2);
2094 strncpy(minute_str, response + 13, 2);
2096 strncpy(ss_str, response + 15, 2);
2098 *utc_hours = atoi(utc_str) / 60.0;
2099 *yy = atoi(yy_str) + 2000;
2104 *minute = atoi(minute_str);
2107 ln_zonedate localTime;
2110 localTime.years = *yy;
2111 localTime.months = *mm;
2112 localTime.days = *dd;
2113 localTime.hours = *hh;
2114 localTime.minutes = *minute;
2115 localTime.seconds = *ss;
2116 localTime.gmtoff = *utc_hours * 3600;
2118 ln_zonedate_to_date(&localTime, &utcTime);
2120 *yy = utcTime.years;
2121 *mm = utcTime.months;
2123 *hh = utcTime.hours;
2124 *minute = utcTime.minutes;
2125 *ss = utcTime.seconds;
bool set_ieqpro_custom_de_track_rate(int fd, double rate)
bool goto_ieqpro_home(int fd)
bool set_ieqpro_latitude(int fd, double latitude)
bool set_ieqpro_current_home(int fd)
void set_sim_gps_status(IEQ_GPS_STATUS value)
bool start_ieqpro_guide(int fd, IEQ_DIRECTION dir, uint32_t ms)
void set_sim_dec(double dec)
bool get_ieqpro_main_firmware(int fd, FirmwareInfo *info)
bool find_ieqpro_home(int fd)
void set_sim_hemisphere(IEQ_HEMISPHERE value)
bool set_ieqpro_local_date(int fd, int yy, int mm, int dd)
bool get_ieqpro_utc_date_time(int fd, double *utc_hours, int *yy, int *mm, int *dd, int *hh, int *minute, int *ss)
bool get_ieqpro_status(int fd, IEQInfo *info)
bool set_ieqpro_daylight_saving(int fd, bool enabled)
bool set_ieqpro_local_time(int fd, int hh, int mm, int ss)
void set_ieqpro_debug(bool enable)
bool get_ieqpro_coords(int fd, double *ra, double *dec)
void set_sim_guide_rate(double ra, double de)
bool get_ieqpro_radec_firmware(int fd, FirmwareInfo *info)
void set_ieqpro_device(const char *name)
void set_ieqpro_simulation(bool enable)
bool get_ieqpro_firmware(int fd, FirmwareInfo *info)
bool set_ieqpro_custom_ra_track_rate(int fd, double rate)
bool set_ieqpro_dec(int fd, double dec)
bool set_ieqpro_guide_rate(int fd, double raRate, double deRate)
bool abort_ieqpro(int fd)
bool unpark_ieqpro(int fd)
bool set_ieqpro_track_mode(int fd, IEQ_TRACK_RATE rate)
void set_sim_system_status(IEQ_SYSTEM_STATUS value)
bool get_ieqpro_model(int fd, FirmwareInfo *info)
void set_sim_slew_rate(IEQ_SLEW_RATE value)
bool get_ieqpro_latitude(int fd, double *latitude)
bool check_ieqpro_connection(int fd)
bool set_ieqpro_ra(int fd, double ra)
bool set_ieqpro_slew_rate(int fd, IEQ_SLEW_RATE rate)
bool get_ieqpro_guide_rate(int fd, double *raRate, double *deRate)
bool start_ieqpro_motion(int fd, IEQ_DIRECTION dir)
void set_sim_time_source(IEQ_TIME_SOURCE value)
bool set_ieqpro_utc_offset(int fd, double offset)
bool set_ieqpro_longitude(int fd, double longitude)
bool get_ieqpro_longitude(int fd, double *longitude)
void set_sim_ra(double ra)
bool set_ieqpro_track_enabled(int fd, bool enabled)
bool stop_ieqpro_motion(int fd, IEQ_DIRECTION dir)
void set_sim_track_rate(IEQ_TRACK_RATE value)
int tty_read_section(int fd, char *buf, char stop_char, int timeout, int *nbytes_read)
read buffer from terminal with a delimiter
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
int tty_read(int fd, char *buf, int nbytes, int timeout, int *nbytes_read)
read buffer from terminal
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
Implementations for common driver routines.
#define DEBUGDEVICE(device, priority, msg)
#define DEBUGFDEVICE(device, priority, msg,...)
std::string ControllerFirmware
std::string MainBoardFirmware
IEQ_SYSTEM_STATUS rememberSystemStatus
IEQ_TIME_SOURCE timeSource
IEQ_SYSTEM_STATUS systemStatus
IEQ_HEMISPHERE hemisphere