26 #include <libnova/transform.h>
35 #define SIDRATE 0.004178
36 #define GOTONOVA_TIMEOUT 5
37 #define GOTONOVA_CALDATE_RESULT " # #"
63 IUFillSwitchVector(&SyncCMRSP, SyncCMRS, 2,
getDeviceName(),
"SYNCCMR",
"Sync",
MOTION_TAB,
IP_RW,
ISR_1OFMANY, 0,
113 return (
const char *)
"GotoNova";
121 const struct timespec timeout = {0, 50000000L};
122 char initCMD[] =
":V#";
127 int nbytes_written = 0;
129 LOG_DEBUG(
"Initializing IOptron using :V# CMD...");
131 for (
int i = 0; i < 2; i++)
137 nanosleep(&timeout,
nullptr);
145 nanosleep(&timeout,
nullptr);
151 response[nbytes_read] =
'\0';
154 if (!strcmp(response,
"V1.00#"))
158 nanosleep(&timeout,
nullptr);
169 if (!strcmp(ParkPositionSP.
name, name))
178 ParkPositionS[currentSwitch].s =
ISS_ON;
187 if (!strcmp(GuideRateSP.
name, name))
196 GuideRateS[currentSwitch].s =
ISS_ON;
205 if (!strcmp(name, SyncCMRSP.
name))
225 int nbytes_written = 0;
227 const char *
cmd =
":SE?#";
247 response[nbytes_read] =
'\0';
250 tcflush(
PortFD, TCIFLUSH);
252 if (response[0] ==
'0')
258 LOGF_ERROR(
"Only received #%d bytes, expected 1.", nbytes_read);
265 int rc = getGotoNovaGuideRate(&guideRate);
269 GuideRateS[guideRate].s =
ISS_ON;
277 const struct timespec timeout = {0, 100000000L};
281 char RAStr[64], DecStr[64];
313 nanosleep(&timeout,
nullptr);
325 if (slewGotoNova() == 0)
328 IDSetNumber(&
EqNP,
"Error Slewing to JNow RA %s - DEC %s\n", RAStr, DecStr);
337 LOGF_INFO(
"Slewing to RA: %s - DEC: %s", RAStr, DecStr);
343 char syncString[256];
360 case USE_REGULAR_SYNC:
366 if (GotonovaSyncCMR(syncString) < 0)
386 LOGF_DEBUG(
"%s Synchronization successful %s", (syncType == USE_REGULAR_SYNC ?
"CM" :
"CMR"), syncString);
387 LOG_INFO(
"Synchronization successful.");
396 int LX200GotoNova::GotonovaSyncCMR(
char *matchedObject)
398 const struct timespec timeout = {0, 10000000L};
400 int nbytes_write = 0;
411 matchedObject[nbytes_read - 1] =
'\0';
416 nanosleep(&timeout,
nullptr);
418 tcflush(
PortFD, TCIFLUSH);
424 int LX200GotoNova::slewGotoNova()
429 int nbytes_write = 0, nbytes_read = 0;
445 tcflush(
PortFD, TCIFLUSH);
460 int nbytes_written = 0;
462 snprintf(
cmd, 8,
":RC%d#", index);
478 struct ln_zonedate ltm;
483 ln_date_to_zonedate(utc, <m, utc_offset * 3600.0);
485 JD = ln_get_julian_day(utc);
502 if (setGotoNovaUTCOffset(utc_offset) < 0)
511 int LX200GotoNova::setCalenderDate(
int fd,
int dd,
int mm,
int yy)
513 const struct timespec timeout = {0, 10000000L};
514 char read_buffer[16];
518 int nbytes_write = 0, nbytes_read = 0;
521 snprintf(read_buffer,
sizeof(read_buffer),
":SC %02d/%02d/%02d#", mm, dd, yy);
525 tcflush(
fd, TCIFLUSH);
532 tcflush(
fd, TCIFLUSH);
540 response[nbytes_read] =
'\0';
544 if (strncmp(response, good_result, strlen(good_result)) == 0)
550 nanosleep(&timeout,
nullptr);
551 tcflush(
fd, TCIFLUSH);
553 LOGF_DEBUG(
"Set date failed! Response: <%s>", response);
565 double final_longitude;
568 final_longitude = longitude - 360.0;
570 final_longitude = longitude;
572 if (!
isSimulation() && setGotoNovaLongitude(final_longitude) < 0)
574 LOG_ERROR(
"Error setting site longitude coordinates");
578 if (!
isSimulation() && setGotoNovaLatitude(latitude) < 0)
580 LOG_ERROR(
"Error setting site latitude coordinates");
586 fs_sexa(L, longitude, 4, 3600);
588 LOGF_INFO(
"Site location updated to Lat %.32s - Long %.32s", l, L);
593 int LX200GotoNova::setGotoNovaLongitude(
double Long)
597 char temp_string[32];
606 snprintf(temp_string,
sizeof(temp_string),
":Sg %c%03d*%02d:%02d#", sign, abs(d), m, s);
608 return (setGotoNovaStandardProcedure(
PortFD, temp_string));
611 int LX200GotoNova::setGotoNovaLatitude(
double Lat)
615 char temp_string[32];
624 snprintf(temp_string,
sizeof(temp_string),
":St %c%02d*%02d:%02d#", sign, abs(d), m, s);
626 return (setGotoNovaStandardProcedure(
PortFD, temp_string));
629 int LX200GotoNova::setGotoNovaUTCOffset(
double hours)
631 char temp_string[16];
633 int h = 0, m = 0, s = 0;
642 snprintf(temp_string,
sizeof(temp_string),
":SG %c%02d#", sign, abs(h));
644 return (setGotoNovaStandardProcedure(
PortFD, temp_string));
647 int LX200GotoNova::setGotoNovaStandardProcedure(
int fd,
const char *data)
649 const struct timespec timeout = {0, 10000000L};
652 int nbytes_write = 0, nbytes_read = 0;
659 error_type =
tty_read(
fd, bool_return, 1, 5, &nbytes_read);
662 nanosleep(&timeout,
nullptr);
663 tcflush(
fd, TCIFLUSH);
664 nanosleep(&timeout,
nullptr);
671 if (bool_return[0] ==
'0')
684 return (setGotoNovaTrackMode(mode) == 0);
687 int LX200GotoNova::setGotoNovaTrackMode(
int mode)
692 snprintf(
cmd, 8,
":STR%d#", mode);
694 return setGotoNovaStandardProcedure(
PortFD,
cmd);
701 int nbytes_write = 0;
706 tcflush(
PortFD, TCIFLUSH);
710 LOG_INFO(
"Parking is in progress...");
738 LOG_INFO(
"Slew is complete. Tracking...");
763 void LX200GotoNova::mountSim()
765 static struct timeval ltv;
771 gettimeofday(&tv,
nullptr);
773 if (ltv.tv_sec == 0 && ltv.tv_usec == 0)
776 dt = tv.tv_sec - ltv.tv_sec + (tv.tv_usec - ltv.tv_usec) / 1e6;
833 int LX200GotoNova::getGotoNovaGuideRate(
int *rate)
835 char cmd[] =
":GGS#";
840 int nbytes_written = 0;
847 nbytes_read = strlen(response);
851 tcflush(
PortFD, TCIFLUSH);
870 response[nbytes_read] =
'\0';
873 *rate = atoi(response);
878 LOGF_ERROR(
"Only received #%d bytes, expected 1.", nbytes_read);
882 int LX200GotoNova::setGotoNovaGuideRate(
int rate)
887 int nbytes_written = 0;
889 snprintf(
cmd, 16,
":SGS%0d#", rate);
898 tcflush(
PortFD, TCIFLUSH);
910 int LX200GotoNova::setGotoNovaParkPosition(
int position)
912 char temp_string[16];
914 snprintf(temp_string,
sizeof(temp_string),
":STPKP%d#", position);
916 return (setGotoNovaStandardProcedure(
PortFD, temp_string));
919 void LX200GotoNova::syncSideOfPier()
921 const char *
cmd =
":pS#";
923 char response[16] = { 0 };
924 int rc = 0, nbytes_read = 0, nbytes_written = 0;
928 tcflush(
PortFD, TCIOFLUSH);
934 LOGF_ERROR(
"Error writing to device %s (%d)", errmsg, rc);
943 LOGF_ERROR(
"Error reading from device %s (%d)", errmsg, rc);
947 response[nbytes_read - 1] =
'\0';
949 tcflush(
PortFD, TCIOFLUSH);
953 if (!strcmp(response,
"East"))
const char * getDeviceName() const
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
TelescopeStatus TrackState
ISwitchVectorProperty MovementNSSP
ISwitchVectorProperty AbortSP
void SetTelescopeCapability(uint32_t cap, uint8_t slewRateCount)
SetTelescopeCapability sets the Telescope capabilities. All capabilities must be initialized.
ISwitchVectorProperty TrackModeSP
virtual void SetParked(bool isparked)
SetParked Change the mount parking status. The data park file (stored in ~/.indi/ParkData....
INumberVectorProperty EqNP
@ TELESCOPE_HAS_TRACK_MODE
void NewRaDec(double ra, double dec)
The child class calls this function when it has updates.
void setPierSide(TelescopePierSide side)
ISwitchVectorProperty MovementWESP
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.
#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 IDSetNumber(const INumberVectorProperty *nvp, const char *fmt,...)
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