24 #include <libnova/julian_day.h>
37 {
"0010",
"Cube II EQ"},
38 {
"0011",
"SmartEQ Pro+"},
44 {
"0030",
"iEQ30 Pro"},
48 {
"0045",
"iEQ45 Pro EQ"},
49 {
"0046",
"iEQ45 Pro AA"},
55 {
"0121",
"CEM120-EC"},
56 {
"0122",
"CEM120-EC2"},
57 {
"5010",
"Cube II AA"},
58 {
"5035",
"AZ Mount Pro"},
59 {
"5045",
"iEQ45 Pro AA"}
68 char res[IOP_BUFFER] = {0};
76 bool Driver::sendCommand(
const char *command,
int count,
char *response, uint8_t timeout, uint8_t debugLog)
80 int nbytes_written = 0;
82 char res[IOP_BUFFER] = {0};
84 DEBUGFDEVICE(m_DeviceName, debugLog,
"CMD <%s>", command);
90 for (
int i = 0; i < 2; i++)
92 tcflush(PortFD, TCIOFLUSH);
94 if ((errCode =
tty_write(PortFD, command, strlen(command), &nbytes_written)) !=
TTY_OK)
107 errCode =
tty_read(PortFD, res, count, timeout, &nbytes_read);
122 res[nbytes_read - 1] = 0;
126 tcflush(PortFD, TCIOFLUSH);
130 strncpy(response, res, IOP_BUFFER);
137 char res[IOP_BUFFER] = {0};
147 for (
int i = 0; i < 2; i++)
149 if (
sendCommand(
":MountInfo#", 4, res, 3) ==
false)
168 m_Simulation = enable;
174 simData.JD = ln_get_julian_from_sys();
175 simData.utc_offset_minutes = 3 * 60;
176 simData.day_light_saving =
false;
185 simData.simInfo.longitude = 48.1;
186 simData.simInfo.latitude = 29.5;
191 simData.simInfo.gpsStatus = value;
196 simData.simInfo.systemStatus = value;
201 simData.simInfo.trackRate = value;
206 simData.simInfo.slewRate = value;
211 simData.simInfo.timeSource = value;
216 simData.simInfo.hemisphere = value;
231 simData.ra_guide_rate = raRate;
232 simData.de_guide_rate = deRate;
237 simData.simInfo.longitude = longitude;
238 simData.simInfo.latitude = latitude;
243 char res[IOP_BUFFER] = {0};
247 int iopLongitude =
simData.simInfo.longitude * 360000;
248 int iopLatitude = (
simData.simInfo.latitude + 90) * 360000;
249 snprintf(res, IOP_BUFFER,
"%c%08d%08d%d%d%d%d%d%d",
simData.simInfo.longitude > 0 ?
'+' :
'-',
250 iopLongitude, iopLatitude,
simData.simInfo.gpsStatus,
simData.simInfo.systemStatus,
simData.simInfo.trackRate,
257 if (strlen(res) != 23)
264 char longPart[16] = {0}, latPart[16] = {0};
265 strncpy(longPart, res, 9);
266 strncpy(latPart, res + 9, 8);
268 int arcsecLongitude = atoi(longPart);
269 int arcsecLatitude = atoi(latPart);
271 info->
longitude = arcsecLongitude / 360000.0;
272 info->
latitude = arcsecLatitude / 360000.0 - 90.0;
291 return (rc1 && rc2 && rc3);
296 char res[IOP_BUFFER] = {0};
300 else if (
sendCommand(
":MountInfo#", 4, res) ==
false)
313 char res[IOP_BUFFER] = {0};
316 strcpy(res,
"180321171001");
320 char mStr[16] = {0}, cStr[16] = {0};
321 strncpy(mStr, res, 6);
322 strncpy(cStr, res + 6, 6);
325 controllerFirmware = cStr;
332 char res[IOP_BUFFER] = {0};
335 strcpy(res,
"140324140101");
339 char mStr[16] = {0}, cStr[16] = {0};
340 strncpy(mStr, res, 6);
341 strncpy(cStr, res + 6, 6);
414 char res[IOP_BUFFER] = {0};
443 char cmd[IOP_BUFFER] = {0};
444 snprintf(
cmd, IOP_BUFFER,
":SR%u#",
static_cast<uint32_t
>(rate + 1));
446 simData.simInfo.slewRate = rate;
453 simData.simInfo.trackRate = rate;
474 if (rate < 0.1 || rate > 1.9)
477 char cmd[IOP_BUFFER] = {0};
478 snprintf(
cmd, IOP_BUFFER,
":RR%05u#",
static_cast<uint32_t
>(rate * 10000));
485 if (RARate < 0.01 || RARate > 0.9 || DERate < 0.01 || DERate > 0.9)
488 char cmd[IOP_BUFFER] = {0};
489 snprintf(
cmd, IOP_BUFFER,
":RG%02u%02u#",
static_cast<uint32_t
>(RARate * 100),
static_cast<uint32_t
>(DERate * 100));
496 char res[IOP_BUFFER] = {0};
499 snprintf(res, IOP_BUFFER,
"%02u%02u",
static_cast<uint32_t
>(
simData.ra_guide_rate * 100),
500 static_cast<uint32_t
>(
simData.de_guide_rate * 100));
504 char raStr[8] = {0}, deStr[8] = {0};
505 strncpy(raStr, res, 2);
506 strncpy(deStr, res + 2, 2);
508 *RARate = atoi(raStr) / 100.0;
509 *DERate = atoi(deStr) / 100.0;
516 char cmd[IOP_BUFFER] = {0};
542 snprintf(
cmd, IOP_BUFFER,
":Z%c%05u#", dir_c, ms);
562 char cmd[IOP_BUFFER] = {0};
565 int ieqValue =
static_cast<int>(az * 60 * 60 * 100);
567 snprintf(
cmd, IOP_BUFFER,
":SPA%09d#", ieqValue);
574 char cmd[IOP_BUFFER] = {0};
579 int ieqValue =
static_cast<int>(alt * 60 * 60 * 100);
580 snprintf(
cmd, IOP_BUFFER,
":SPH%08d#", ieqValue);
587 simData.simInfo.systemStatus =
simData.simInfo.rememberSystemStatus;
594 simData.simInfo.rememberSystemStatus =
simData.simInfo.systemStatus;
602 simData.simInfo.rememberSystemStatus =
simData.simInfo.systemStatus;
616 char cmd[IOP_BUFFER] = {0};
617 snprintf(
cmd, IOP_BUFFER,
":ST%d#", enabled ? 1 : 0);
626 uint32_t casRA =
ra * 15 * 60 * 60 * 100;
630 char cmd[IOP_BUFFER] = {0};
631 snprintf(
cmd, IOP_BUFFER,
":SRA%09u#", casRA);
640 uint32_t casDE = fabs(
de) * 60 * 60 * 100;
644 char cmd[IOP_BUFFER] = {0};
645 snprintf(
cmd, IOP_BUFFER,
":Sd%c%08u#",
de >= 0 ?
'+' :
'-', casDE);
652 uint32_t casLongitude = fabs(longitude) * 60 * 60 * 100;
654 simData.simInfo.longitude = longitude;
656 char cmd[IOP_BUFFER] = {0};
657 snprintf(
cmd, IOP_BUFFER,
":SLO%c%08u#", longitude >= 0 ?
'+' :
'-', casLongitude);
664 uint32_t casLatitude = fabs(latitude) * 60 * 60 * 100;
666 simData.simInfo.latitude = latitude;
668 char cmd[IOP_BUFFER] = {0};
669 snprintf(
cmd, IOP_BUFFER,
":SLA%c%08u#", latitude >= 0 ?
'+' :
'-', casLatitude);
676 uint64_t msJD = (
JD -
J2000) * 8.64e+7;
678 char cmd[IOP_BUFFER] = {0};
679 snprintf(
cmd, IOP_BUFFER,
":SUT%013" PRIu64
"#", msJD);
688 char cmd[IOP_BUFFER] = {0};
689 snprintf(
cmd, IOP_BUFFER,
":SG%c%03d#", offsetMinutes >= 0 ?
'+' :
'-', abs(offsetMinutes));
691 simData.utc_offset_minutes = offsetMinutes;
698 char cmd[IOP_BUFFER] = {0};
699 snprintf(
cmd, IOP_BUFFER,
":SDS%c#", enabled ?
'1' :
'0');
701 simData.day_light_saving = enabled;
708 char res[IOP_BUFFER] = {0};
711 snprintf(res, IOP_BUFFER,
"%c%08u%09u%d%d", (
simData.de >= 0 ?
'+' :
'-'),
712 static_cast<uint32_t
>(fabs(
simData.de) * 60 * 60 * 100),
718 if (strlen(res) != 20)
725 char deStr[16] = {0}, raStr[16] = {0};
727 strncpy(deStr, res, 9);
728 strncpy(raStr, res + 9, 9);
732 *
de = std::atoi(deStr) / (60.0 * 60.0 * 100.0);
733 *
ra = std::atoi(raStr) / (15.0 * 60.0 * 60.0 * 100.0);
749 char res[IOP_BUFFER] = {0};
752 snprintf(res, IOP_BUFFER,
"%c%03d%c%013" PRIu64, (
simData.utc_offset_minutes >= 0 ?
'+' :
'-'),
753 abs(
simData.utc_offset_minutes),
754 (
simData.day_light_saving ?
'1' :
'0'),
static_cast<uint64_t
>((
simData.JD -
J2000) * 8.64e+7));
759 if (strlen(res) != 18)
766 char offsetStr[16] = {0}, JDStr[16] = {0};
768 strncpy(offsetStr, res, 4);
769 strncpy(JDStr, res + 5, 13);
771 *utcOffsetMinutes = atoi(offsetStr);
772 *dayLightSaving = (res[4] ==
'1');
776 uint64_t iopJD = std::stoull(JDStr);
777 *
JD = (iopJD / 8.64e+7) +
J2000;
790 char res[IOP_BUFFER] = {0};
793 snprintf(res, IOP_BUFFER,
"%d%02d",
simData.mb_state,
simData.mb_limit);
801 degrees = std::stoi(res + 1);
821 char cmd[IOP_BUFFER] = {0};
822 snprintf(
cmd, IOP_BUFFER,
":SMT%d%02d#", action, degrees);
bool setTrackMode(IOP_TRACK_RATE rate)
void setSimulation(bool enable)
static const std::map< std::string, std::string > models
bool setPETEnabled(bool enabled)
bool setCustomRATrackRate(double rate)
bool setDaylightSaving(bool enabled)
bool startGuide(IOP_DIRECTION dir, uint32_t ms)
bool getUTCDateTime(double *JD, int *utcOffsetMinutes, bool *dayLightSaving)
bool setMeridianBehavior(IOP_MB_STATE action, uint8_t degrees)
void setSimGPSstatus(IOP_GPS_STATUS value)
void setSimSlewRate(IOP_SLEW_RATE value)
bool getPETEnabled(bool enabled)
bool getGuideRate(double *RARate, double *DERate)
bool getRADEFirmware(std::string &RAFirmware, std::string &DEFirmware)
bool sendCommand(const char *command, int count=1, char *response=nullptr, uint8_t timeout=IOP_TIMEOUT, uint8_t debugLog=INDI::Logger::DBG_DEBUG)
bool setGuideRate(double RARate, double DERate)
void setSimTrackRate(IOP_TRACK_RATE value)
bool getStatus(IOPInfo *info)
void setSimTimeSource(IOP_TIME_SOURCE value)
void setSimGuideRate(double raRate, double deRate)
bool setParkAz(double az)
bool setParkAlt(double alt)
bool setLatitude(double latitude)
Driver(const char *deviceName)
bool setLongitude(double longitude)
bool getCoords(double *ra, double *de, IOP_PIER_STATE *pierState, IOP_CW_STATE *cwState)
bool sendCommandOk(const char *command)
void setDebug(bool enable)
bool getMeridianBehavior(IOP_MB_STATE &action, uint8_t °rees)
bool stopMotion(IOP_DIRECTION dir)
bool setTrackEnabled(bool enabled)
bool setSlewRate(IOP_SLEW_RATE rate)
bool checkConnection(int fd)
void setSimHemisphere(IOP_HEMISPHERE value)
bool setUTCDateTime(double JD)
void setSimSytemStatus(IOP_SYSTEM_STATUS value)
void setSimLongLat(double longitude, double latitude)
bool setUTCOffset(int offsetMinutes)
struct IOPv3::Driver::@168 simData
bool getFirmwareInfo(FirmwareInfo *info)
bool setPECEnabled(bool enabled)
bool startMotion(IOP_DIRECTION dir)
static const uint16_t IOP_SLEW_RATES[]
bool getMainFirmware(std::string &mainFirmware, std::string &controllerFirmware)
bool getModel(std::string &model)
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,...)
Encapsulates classes and structures required for iOptron Command Set v3 implementation.
std::string ControllerFirmware
std::string MainBoardFirmware
IOP_HEMISPHERE hemisphere
IOP_SYSTEM_STATUS systemStatus
IOP_TIME_SOURCE timeSource