26#include <libnova/transform.h>
35#define SIDRATE 0.004178
36#define GOTONOVA_TIMEOUT 5
37#define GOTONOVA_CALDATE_RESULT " # #"
67 IUFillSwitchVector(&SyncCMRSP, SyncCMRS, 2,
getDeviceName(),
"SYNCCMR",
"Sync",
MOTION_TAB,
IP_RW,
ISR_1OFMANY, 0,
117 return (
const char *)
"GotoNova";
125 const struct timespec timeout = {0, 50000000L};
126 char initCMD[] =
":V#";
131 int nbytes_written = 0;
133 LOG_DEBUG(
"Initializing IOptron using :V# CMD...");
135 for (
int i = 0; i < 2; i++)
141 nanosleep(&timeout,
nullptr);
149 nanosleep(&timeout,
nullptr);
155 response[nbytes_read] =
'\0';
158 if (!strcmp(response,
"V1.00#"))
162 nanosleep(&timeout,
nullptr);
173 if (!strcmp(ParkPositionSP.
name, name))
182 ParkPositionS[currentSwitch].s =
ISS_ON;
191 if (!strcmp(GuideRateSP.
name, name))
200 GuideRateS[currentSwitch].s =
ISS_ON;
209 if (!strcmp(name, SyncCMRSP.
name))
229 int nbytes_written = 0;
231 const char *
cmd =
":SE?#";
251 response[nbytes_read] =
'\0';
254 tcflush(
PortFD, TCIFLUSH);
256 if (response[0] ==
'0')
262 LOGF_ERROR(
"Only received #%d bytes, expected 1.", nbytes_read);
269 int rc = getGotoNovaGuideRate(&guideRate);
273 GuideRateS[guideRate].s =
ISS_ON;
281 const struct timespec timeout = {0, 100000000L};
285 char RAStr[64], DecStr[64];
319 nanosleep(&timeout,
nullptr);
332 if (slewGotoNova() == 0)
335 LOGF_ERROR(
"Error Slewing to JNow RA %s - DEC %s\n", RAStr, DecStr);
345 LOGF_INFO(
"Slewing to RA: %s - DEC: %s", RAStr, DecStr);
351 char syncString[256];
360 LOG_ERROR(
"Error setting RA/DEC. Unable to Sync.");
369 case USE_REGULAR_SYNC:
375 if (GotonovaSyncCMR(syncString) < 0)
396 LOGF_DEBUG(
"%s Synchronization successful %s", (syncType == USE_REGULAR_SYNC ?
"CM" :
"CMR"), syncString);
397 LOG_INFO(
"Synchronization successful.");
406int LX200GotoNova::GotonovaSyncCMR(
char *matchedObject)
408 const struct timespec timeout = {0, 10000000L};
410 int nbytes_write = 0;
421 matchedObject[nbytes_read - 1] =
'\0';
426 nanosleep(&timeout,
nullptr);
428 tcflush(
PortFD, TCIFLUSH);
434int LX200GotoNova::slewGotoNova()
439 int nbytes_write = 0, nbytes_read = 0;
455 tcflush(
PortFD, TCIFLUSH);
470 int nbytes_written = 0;
472 snprintf(
cmd, 8,
":RC%d#", index);
488 struct ln_zonedate ltm;
493 ln_date_to_zonedate(utc, <m, utc_offset * 3600.0);
495 JD = ln_get_julian_day(utc);
512 if (setGotoNovaUTCOffset(utc_offset) < 0)
521int LX200GotoNova::setCalenderDate(
int fd,
int dd,
int mm,
int yy)
523 const struct timespec timeout = {0, 10000000L};
524 char read_buffer[16];
528 int nbytes_write = 0, nbytes_read = 0;
531 snprintf(read_buffer,
sizeof(read_buffer),
":SC %02d/%02d/%02d#", mm, dd, yy);
535 tcflush(
fd, TCIFLUSH);
542 tcflush(
fd, TCIFLUSH);
550 response[nbytes_read] =
'\0';
554 if (strncmp(response, good_result, strlen(good_result)) == 0)
560 nanosleep(&timeout,
nullptr);
561 tcflush(
fd, TCIFLUSH);
563 LOGF_DEBUG(
"Set date failed! Response: <%s>", response);
575 double final_longitude;
578 final_longitude = longitude - 360.0;
580 final_longitude = longitude;
582 if (!
isSimulation() && setGotoNovaLongitude(final_longitude) < 0)
584 LOG_ERROR(
"Error setting site longitude coordinates");
588 if (!
isSimulation() && setGotoNovaLatitude(latitude) < 0)
590 LOG_ERROR(
"Error setting site latitude coordinates");
596 fs_sexa(L, longitude, 4, 3600);
598 LOGF_INFO(
"Site location updated to Lat %.32s - Long %.32s", l, L);
603int LX200GotoNova::setGotoNovaLongitude(
double Long)
607 char temp_string[32];
616 snprintf(temp_string,
sizeof(temp_string),
":Sg %c%03d*%02d:%02d#", sign, abs(d), m, s);
618 return (setGotoNovaStandardProcedure(
PortFD, temp_string));
621int LX200GotoNova::setGotoNovaLatitude(
double Lat)
625 char temp_string[32];
634 snprintf(temp_string,
sizeof(temp_string),
":St %c%02d*%02d:%02d#", sign, abs(d), m, s);
636 return (setGotoNovaStandardProcedure(
PortFD, temp_string));
639int LX200GotoNova::setGotoNovaUTCOffset(
double hours)
641 char temp_string[16];
643 int h = 0, m = 0, s = 0;
652 snprintf(temp_string,
sizeof(temp_string),
":SG %c%02d#", sign, abs(h));
654 return (setGotoNovaStandardProcedure(
PortFD, temp_string));
657int LX200GotoNova::setGotoNovaStandardProcedure(
int fd,
const char *data)
659 const struct timespec timeout = {0, 10000000L};
662 int nbytes_write = 0, nbytes_read = 0;
669 error_type =
tty_read(
fd, bool_return, 1, 5, &nbytes_read);
672 nanosleep(&timeout,
nullptr);
673 tcflush(
fd, TCIFLUSH);
674 nanosleep(&timeout,
nullptr);
681 if (bool_return[0] ==
'0')
694 return (setGotoNovaTrackMode(mode) == 0);
697int LX200GotoNova::setGotoNovaTrackMode(
int mode)
702 snprintf(
cmd, 8,
":STR%d#", mode);
704 return setGotoNovaStandardProcedure(
PortFD,
cmd);
711 int nbytes_write = 0;
716 tcflush(
PortFD, TCIFLUSH);
720 LOG_INFO(
"Parking is in progress...");
748 LOG_INFO(
"Slew is complete. Tracking...");
774void LX200GotoNova::mountSim()
776 static struct timeval ltv;
782 gettimeofday(&tv,
nullptr);
784 if (ltv.tv_sec == 0 && ltv.tv_usec == 0)
787 dt = tv.tv_sec - ltv.tv_sec + (tv.tv_usec - ltv.tv_usec) / 1e6;
844int LX200GotoNova::getGotoNovaGuideRate(
int *rate)
846 char cmd[] =
":GGS#";
851 int nbytes_written = 0;
858 nbytes_read = strlen(response);
862 tcflush(
PortFD, TCIFLUSH);
881 response[nbytes_read] =
'\0';
884 *rate = atoi(response);
889 LOGF_ERROR(
"Only received #%d bytes, expected 1.", nbytes_read);
893int LX200GotoNova::setGotoNovaGuideRate(
int rate)
898 int nbytes_written = 0;
900 snprintf(
cmd, 16,
":SGS%0d#", rate);
909 tcflush(
PortFD, TCIFLUSH);
921int LX200GotoNova::setGotoNovaParkPosition(
int position)
923 char temp_string[16];
925 snprintf(temp_string,
sizeof(temp_string),
":STPKP%d#", position);
927 return (setGotoNovaStandardProcedure(
PortFD, temp_string));
930void LX200GotoNova::syncSideOfPier()
932 const char *
cmd =
":pS#";
934 char response[16] = { 0 };
935 int rc = 0, nbytes_read = 0, nbytes_written = 0;
939 tcflush(
PortFD, TCIOFLUSH);
945 LOGF_ERROR(
"Error writing to device %s (%d)", errmsg, rc);
954 LOGF_ERROR(
"Error reading from device %s (%d)", errmsg, rc);
958 response[nbytes_read - 1] =
'\0';
960 tcflush(
PortFD, TCIOFLUSH);
964 if (!strcmp(response,
"East"))
void setVersion(uint16_t vMajor, uint16_t vMinor)
Set driver version information to be defined in DRIVER_INFO property as vMajor.vMinor.
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
void defineProperty(INumberVectorProperty *property)
bool isSimulation() const
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
void setLabel(const char *label)
TelescopeStatus TrackState
void SetTelescopeCapability(uint32_t cap, uint8_t slewRateCount)
SetTelescopeCapability sets the Telescope capabilities. All capabilities must be initialized.
virtual void SetParked(bool isparked)
SetParked Change the mount parking status. The data park file (stored in ~/.indi/ParkData....
@ TELESCOPE_HAS_TRACK_MODE
void NewRaDec(double ra, double dec)
The child class calls this function when it has updates.
void setPierSide(TelescopePierSide side)
virtual bool isSlewComplete() override
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual bool SetSlewRate(int index) override
SetSlewRate Set desired slew rate index.
virtual bool checkConnection() override
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
virtual bool Park() override
Park the telescope to its home position.
virtual bool Goto(double, double) override
Move the scope to the supplied RA and DEC coordinates.
virtual bool UnPark() override
Unpark the telescope if already parked.
virtual bool updateLocation(double latitude, double longitude, double elevation) override
Update telescope location settings.
virtual bool ReadScopeStatus() override
Read telescope status.
virtual void getBasicData() override
virtual const char * getDefaultName() override
virtual bool Sync(double ra, double dec) override
Set the telescope current RA and DEC coordinates to the supplied RA and DEC coordinates.
virtual bool updateProperties() override
Called when connected state changes, to add/remove properties.
virtual bool initProperties() override
Called to initialize basic properties required all the time.
virtual bool updateTime(ln_date *utc, double utc_offset) override
Update telescope time, date, and UTC offset.
virtual bool SetTrackMode(uint8_t mode) override
SetTrackMode Set active tracking mode. Do not change track state.
virtual bool initProperties() override
Called to initialize basic properties required all the time.
virtual void slewError(int slewCode)
virtual bool updateProperties() override
Called when connected state changes, to add/remove properties.
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
void setLX200Capability(uint32_t cap)
const char * MOTION_TAB
MOTION_TAB Where all the motion control properties of the device are located.
const char * SITE_TAB
SITE_TAB Where all site information setting are located.
INDI::PropertySwitch AbortSP
INDI::PropertySwitch MovementNSSP
INDI::PropertyNumber EqNP
INDI::PropertySwitch SlewRateSP
INDI::PropertySwitch TrackModeSP
INDI::PropertySwitch MovementWESP
#define setLocalTime(fd, x, y, z)
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.
void getSexComponents(double value, int *d, int *m, int *s)
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 fs_sexa(char *out, double a, int w, int fracbase)
Converts a sexagesimal number to a string. sprint the variable a in sexagesimal format into out[].
Implementations for common driver routines.
void IUSaveConfigSwitch(FILE *fp, const ISwitchVectorProperty *svp)
Add a switch vector property value to the configuration file.
int IUFindOnSwitchIndex(const ISwitchVectorProperty *svp)
Returns the index of first ON switch it finds in the vector switch property.
void IUResetSwitch(ISwitchVectorProperty *svp)
Reset all switches in a switch vector property to OFF.
void IUFillSwitch(ISwitch *sp, const char *name, const char *label, ISState s)
Assign attributes for a switch property. The switch's auxiliary elements will be set to NULL.
void IUFillSwitchVector(ISwitchVectorProperty *svp, ISwitch *sp, int nsp, const char *dev, const char *name, const char *label, const char *group, IPerm p, ISRule r, double timeout, IPState s)
Assign attributes for a switch vector property. The vector's auxiliary elements will be set to NULL.
int IUUpdateSwitch(ISwitchVectorProperty *svp, ISState *states, char *names[], int n)
Update all switches in a switch vector property.
void IDSetSwitch(const ISwitchVectorProperty *svp, const char *fmt,...)
#define LOGF_INFO(fmt,...)
#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,...)
#define DEBUGF(priority, msg,...)
int setObjectRA(int fd, double ra, bool addSpace)
int setObjectDEC(int fd, double dec, bool addSpace)
int setCalenderDate(int fd, int dd, int mm, int yy, bool addSpace)
#define getLX200DEC(fd, x)
#define getLX200RA(fd, x)
#define GOTONOVA_CALDATE_RESULT