26#include <libnova/julian_day.h>
61 LOGF_ERROR(
"Main board firmware is %s while minimum required firmware is %s. Please upgrade the mount firmware.",
80 std::string code = res;
83 return oneMount.code == code;
92 LOGF_ERROR(
"Mount with code %s is not recognized.", res);
105 char board[8] = {0}, controller[8] = {0};
107 snprintf(board,
sizeof(board),
"%.6s", res);
108 snprintf(controller,
sizeof(controller),
"%.6s", res + 6);
125 char ra[8] = {0}, de[8] = {0};
127 snprintf(
ra,
sizeof(
ra),
"%.6s", res);
128 snprintf(de,
sizeof(de),
"%.6s", res + 6);
215 snprintf(
cmd,
DRIVER_LEN,
":SR%d#", (
static_cast<int>(rate) + 1));
227 strcpy(
cmd,
":RT0#");
230 strcpy(
cmd,
":RT1#");
233 strcpy(
cmd,
":RT2#");
236 strcpy(
cmd,
":RT3#");
239 strcpy(
cmd,
":RT4#");
252 rate = std::max(0.5, std::min(rate, 1.5));
258 snprintf(
cmd,
DRIVER_LEN,
":RR%05d#",
static_cast<int>(rate * 1e5));
269 raRate = std::max(0.01, std::min(raRate, 0.9));
271 deRate = std::max(0.1, std::min(deRate, 0.99));
275 snprintf(
cmd,
DRIVER_LEN,
":RG%02d%02d#",
static_cast<int>(raRate * 100.0),
static_cast<int>(deRate * 100.0));
336 return res[0] ==
'1';
363 return res[0] ==
'1';
378 return sendCommand(enabled ?
":ST1#" :
":ST0#", res, -1, 1);
387 int ieqValue =
static_cast<int>(
ra * 60 * 60 * 1000);
400 int ieqValue =
static_cast<int>(fabs(
dec) * 60 * 60 * 100);
413 int ieqValue =
static_cast<int>(az * 60 * 60 * 100);
426 int ieqValue =
static_cast<int>(alt * 60 * 60 * 100);
428 snprintf(
cmd,
DRIVER_LEN,
":Sa%c%08d#", (alt >= 0) ?
'+' :
'-', ieqValue);
442 int ieqValue =
static_cast<int>(az * 60 * 60 * 100);
457 alt = std::max(0.0, alt);
460 int ieqValue =
static_cast<int>(alt * 60 * 60 * 100);
472 int arcsecs =
static_cast<int>(fabs(longitude) * 60 * 60);
473 snprintf(
cmd,
DRIVER_LEN,
":Sg%c%06d#", (longitude >= 0) ?
'+' :
'-', arcsecs);
483 int arcsecs =
static_cast<int>(fabs(latitude) * 60 * 60);
484 snprintf(
cmd,
DRIVER_LEN,
":St%c%06d#", (latitude >= 0) ?
'+' :
'-', arcsecs);
512 return sendCommand(enabled ?
":SDS1#" :
":SDS0#", res, -1, 1);
520 int offset_minutes =
static_cast<int>(fabs(offset_hours) * 60.0);
521 snprintf(
cmd, 16,
":SG%c%03d#", (offset_hours >= 0) ?
'+' :
'-', offset_minutes);
536 static constexpr size_t EXPECTED_LEN = 17;
537 static constexpr int32_t DEC_MIN = -32400000;
538 static constexpr int32_t DEC_MAX = 32400000;
539 static constexpr int32_t RA_MIN = 0;
540 static constexpr int32_t RA_MAX = 86400000;
543 size_t resLen = strlen(res);
544 if (resLen < EXPECTED_LEN)
546 LOGF_ERROR(
"Invalid GEC response: expected %zu chars, got %zu ('%s')",
547 EXPECTED_LEN, resLen, res);
552 if (res[0] !=
'+' && res[0] !=
'-')
554 LOGF_ERROR(
"Invalid GEC response: expected sign at position 0, got '%c' ('%s')",
560 for (
size_t i = 1; i < 9; i++)
562 if (!isdigit(
static_cast<unsigned char>(res[i])))
564 LOGF_ERROR(
"Invalid GEC response: non-digit at position %zu ('%s')", i, res);
570 for (
size_t i = 9; i < 17; i++)
572 if (!isdigit(
static_cast<unsigned char>(res[i])))
574 LOGF_ERROR(
"Invalid GEC response: non-digit at position %zu ('%s')", i, res);
583 if (rawDec < DEC_MIN || rawDec > DEC_MAX)
585 LOGF_ERROR(
"Invalid GEC response: DEC %d out of range [%d, %d]",
586 rawDec, DEC_MIN, DEC_MAX);
590 if (rawRa < RA_MIN || rawRa > RA_MAX)
592 LOGF_ERROR(
"Invalid GEC response: RA %d out of range [%d, %d]",
593 rawRa, RA_MIN, RA_MAX);
619 ln_zonedate localTime;
622 localTime.years = *yy;
623 localTime.months = *mm;
624 localTime.days = *dd;
625 localTime.hours = *hh;
626 localTime.minutes = *minute;
627 localTime.seconds = *ss;
628 localTime.gmtoff =
static_cast<long>(*utc_hours * 3600);
630 ln_zonedate_to_date(&localTime, &utcTime);
633 *mm = utcTime.months;
636 *minute = utcTime.minutes;
637 *ss =
static_cast<int>(utcTime.seconds);
652 char longitude[8] = {0}, latitude[8] = {0}, status[8] = {0};
654 snprintf(longitude,
sizeof(longitude),
"%.7s", res);
655 snprintf(latitude,
sizeof(latitude),
"%.6s", res + 7);
656 snprintf(status,
sizeof(status),
"%.6s", res + 13);
713 axisHa = 18 - haAxis;
734 double decPA = info.
latitude >= 0 ? 90 - Dec : 90 +
737 if ((ha > 2 && ha < 10) || (ha < -2 && ha > -10))
741 reason =
"Hour Angle";
745 double decDiff = std::fabs(decPA - std::fabs(decAxis));
750 reason =
"pole angle";
755 reason =
"uncertain";
759 LOGF_DEBUG(
"getPierSide pole Axis %f, haAxis %f, axisHa %f, ha %f, decPa %f, %s pierSide %s", decAxis, haAxis, axisHa, ha,
771 int nbytes_written = 0, nbytes_read = 0, rc = -1;
792 LOGF_ERROR(
"Serial write error: %s.", errstr);
815 hexDump(hex_res, res, res_len);
830 for (
int i = 0; i < size; i++)
831 sprintf(buf + 3 * i,
"%02X ",
static_cast<uint8_t
>(data[i]));
834 buf[3 * size - 1] =
'\0';
840 if (command ==
"MSH")
847 LOG_ERROR(
"Finding home is only supported on CEM40, GEM45 and CEM60 mounts.");
852 else if (command ==
"RR")
857 LOG_ERROR(
"Tracking rate is not supported on Altitude-Azimuth mounts.");
861 else if (command ==
"RG" || command ==
"AG")
866 LOG_ERROR(
"Guide rate is not supported on Altitude-Azimuth mounts.");
870 if (command ==
"MP0" || command ==
"MP1" || command ==
"SPA" || command ==
"SPH")
878 LOG_ERROR(
"Parking only supported on CEM40, GEM45, CEM60, iEQPro 30 and iEQ Pro 45.");
894 snprintf(str,
sizeof(str),
"%.*s",
static_cast<int>(size), data);
896 int iVal = atoi(str);
static const uint8_t DRIVER_LEN
void hexDump(char *buf, const char *data, int size)
hexDump Helper function to print non-string commands to the logger so it is easier to debug
virtual bool setCurrentHome()
virtual bool setRA(double ra)
virtual bool setSlewRate(SlewRate rate)
bool getStatus(Info *info)
FirmwareInfo m_FirmwareInfo
virtual bool setTrackEnabled(bool enabled)
bool initCommunication(int fd)
initCommunication Checks if communication with the mount is working
virtual bool setLocalDate(int yy, int mm, int dd)
bool isCommandSupported(const std::string &command, bool silent=false)
isCommandSupported Check if specific iOptron command is supported for this mount model
virtual bool setAlt(double alt)
bool getCoords(double *ra, double *dec)
bool getPierSide(IEQ_PIER_SIDE *pierSide)
double DecodeString(const char *data, size_t size, double factor)
DecodeString converts the string to a double by dividing by the factor.
virtual bool setParkAlt(double alt)
virtual bool setLatitude(double latitude)
virtual bool setParkAz(double az)
virtual bool getGuideRate(double *raRate, double *deRate)
virtual bool setAz(double az)
static constexpr const double ieqDegrees
virtual bool setDE(double dec)
virtual bool setUTCOffset(double offset_hours)
virtual bool stopMotion(Direction dir)
virtual bool setGuideRate(double raRate, double deRate)
static const char DRIVER_STOP_CHAR
const std::vector< MountInfo > m_MountList
bool sendCommand(const char *cmd, char *res=nullptr, int cmd_len=-1, int res_len=-1)
sendCommand Send a string command to device.
virtual bool setDST(bool enabled)
static constexpr const double ieqHours
bool getUTCDateTime(double *utc_hours, int *yy, int *mm, int *dd, int *hh, int *minute, int *ss)
virtual bool setLongitude(double longitude)
virtual bool setCustomRATrackRate(double rate)
static const uint8_t DRIVER_TIMEOUT
virtual bool startGuide(Direction dir, uint32_t ms)
virtual bool startMotion(Direction dir)
virtual bool setLocalTime(int hh, int mm, int ss)
virtual bool setTrackMode(TrackRate rate)
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
double rangeHA(double r)
rangeHA Limits the hour angle value to be between -12 —> 12
int tty_read(int fd, char *buf, int nbytes, int timeout, int *nbytes_read)
read buffer from terminal
int tty_write_string(int fd, const char *buf, int *nbytes_written)
Writes a null terminated string to fd.
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
int tty_nread_section(int fd, char *buf, int nsize, char stop_char, int timeout, int *nbytes_read)
read buffer from terminal with a delimiter
double get_local_hour_angle(double sideral_time, double ra)
get_local_hour_angle Returns local hour angle of an object
Implementations for common driver routines.
double get_local_sidereal_time(double longitude)
get_local_sidereal_time Returns local sidereal time given longitude and system clock.
#define LOGF_DEBUG(fmt,...)
#define LOG_ERROR(txt)
Shorter logging macros. In order to use these macros, the function (or method) "getDeviceName()" must...
#define LOGF_ERROR(fmt,...)
const char * pierSideStr(IEQ_PIER_SIDE ps)
std::string MainBoardFirmware
std::string ControllerFirmware
SystemStatus systemStatus