29#include <libnova/transform.h>
70 int mountType = Equatorial;
73 MountTypeSP[Equatorial].
fill(
"Equatorial",
"Equatorial", mountType == Equatorial ?
ISS_ON :
ISS_OFF);
76 if (mountType == Equatorial)
83 ElevationLimitNP[OVERHEAD].
fill(
"ELEVATION_OVERHEAD",
"Overhead",
"%g", 60, 90, 1, 90);
84 ElevationLimitNP[HORIZON].
fill(
"ELEVATION_HORIZON",
"Horizon",
"%g", -30, 0, 1, 0);
89 MeridianLimitNP[0].
fill(
"VALUE",
"Degrees (+/- 120)",
"%.f", -120, 120, 1, 0);
97 RefractSP[REFRACT_ON].
fill(
"REFRACTION_ON",
"On",
ISS_OFF);
98 RefractSP[REFRACT_OFF].
fill(
"REFRACTION_OFF",
"Off",
ISS_OFF);
103 SafetyLimitSP[SET_SAFETY_LIMIT].
fill(
"SET_SAFETY_LIMIT",
"Set",
ISS_OFF);
104 SafetyLimitSP[CLEAR_SAFETY_LIMIT].
fill(
"CLEAR_SAFETY_LIMIT",
"Clear",
ISS_OFF);
123 verboseReport =
false;
125 VerboseReportSP[1].
fill(
"Off",
"Off",
ISS_ON);
128 Report[0].
fill(
"Report",
"GU",
"-");
132 DebugCommandTP[0].fill(
"Command",
"",
"");
137 IsTracking[0].
fill(
"IsTracking",
"n",
"-");
140 IsSlewCompleted[0].
fill(
"IsSlewCompleted",
"N",
"-");
143 IsParked[0].
fill(
"IsParked",
"p/P",
"-");
146 IsParkginInProgress[0].
fill(
"IsParkginInProgress",
"I",
"-");
149 IsAtHomePosition[0].
fill(
"IsAtHomePosition",
"H",
"-");
152 MountAltAz[0].
fill(
"MountAltAz",
"A",
"-");
155 MountEquatorial[0].
fill(
"MountEquatorial",
"E",
"-");
158 PierNone[0].
fill(
"PierNone",
"",
"-");
161 PierEast[0].
fill(
"PierEast",
"T",
"-");
164 PierWest[0].
fill(
"PierWest",
"W",
"-");
167 DoesRefractionComp[0].
fill(
"DoesRefractionComp",
"r",
"-");
170 WaitingAtHome[0].
fill(
"WaitingAtHome",
"w",
"-");
173 IsHomePaused[0].
fill(
"IsHomePaused",
"u",
"-");
176 ParkFailed[0].
fill(
"ParkFailed",
"F",
"-");
179 SlewingHome[0].
fill(
"SlewingHome",
"h",
"-");
211 char status[DRIVER_LEN] = {0};
212 if (sendCommand(
":GU#", status))
214 if(strchr(status,
'P'))
226 if(sendCommand(
":GX90#", status))
228 std::string c = status;
238 if(sendCommand(
":Go#", status))
240 std::string c = status;
241 ElevationLimitNP[OVERHEAD].value = std::stoi(c);
244 if(sendCommand(
":Gh#", status))
246 std::string c = status;
247 ElevationLimitNP[HORIZON].value = std::stoi(c);
250 if(sendCommand(
":GXE9#", status))
252 std::string c = status;
253 MeridianLimitNP[0].setValue(std::stoi(c));
328 return "Pegasus NYX-101";
331const char *
ON =
"ON";
341 propertyTxt[0].setText(
ON);
345 propertyTxt[0].setText(
OFF);
349 propertyTxt[0].setText(
"-");
360 bool _IsTracking =
true;
361 SetPropertyText(IsTracking,
IPS_OK);
363 bool _IsSlewCompleted =
false;
364 SetPropertyText(IsSlewCompleted,
IPS_BUSY);
366 bool _IsParked =
false;
367 SetPropertyText(IsParked,
IPS_BUSY);
370 SetPropertyText(IsParkginInProgress,
IPS_BUSY);
373 SetPropertyText(IsAtHomePosition,
IPS_BUSY);
375 NYXTelescopeTrackMode _TrackingMode = TRACK_SIDEREAL;
381 bool _DoesRefractionComp =
false;
382 SetPropertyText(DoesRefractionComp,
IPS_BUSY);
385 SetPropertyText(WaitingAtHome,
IPS_BUSY);
388 SetPropertyText(IsHomePaused,
IPS_BUSY);
391 SetPropertyText(ParkFailed,
IPS_BUSY);
394 SetPropertyText(SlewingHome,
IPS_BUSY);
396 char status[DRIVER_LEN] = {0};
397 if(sendCommand(
":GU#", status))
399 Report[0].text = status;
404 switch (status[index++])
408 SetPropertyText(IsTracking,
IPS_BUSY);
411 _IsSlewCompleted =
true;
412 SetPropertyText(IsSlewCompleted,
IPS_OK);
416 SetPropertyText(IsParked,
IPS_BUSY);
420 SetPropertyText(IsParked,
IPS_OK);
424 SetPropertyText(IsParkginInProgress,
IPS_OK);
428 SetPropertyText(IsAtHomePosition,
IPS_OK);
431 _TrackingMode = TRACK_LUNAR;
434 _TrackingMode = TRACK_SOLAR;
437 _TrackingMode = TRACK_KING;
441 SetPropertyText(MountAltAz,
IPS_OK);
442 SetPropertyText(MountEquatorial,
IPS_BUSY);
446 SetPropertyText(MountEquatorial,
IPS_OK);
447 SetPropertyText(MountAltAz,
IPS_BUSY);
456 _DoesRefractionComp =
true;
457 SetPropertyText(DoesRefractionComp,
IPS_OK);
461 SetPropertyText(WaitingAtHome,
IPS_OK);
465 SetPropertyText(IsHomePaused,
IPS_OK);
469 SetPropertyText(ParkFailed,
IPS_OK);
473 SetPropertyText(SlewingHome,
IPS_OK);
483 if(_DoesRefractionComp )
508 SetPropertyText(PierNone,
IPS_OK);
509 SetPropertyText(PierEast,
IPS_BUSY);
510 SetPropertyText(PierWest,
IPS_BUSY);
513 SetPropertyText(PierEast,
IPS_OK);
514 SetPropertyText(PierNone,
IPS_BUSY);
515 SetPropertyText(PierWest,
IPS_BUSY);
518 SetPropertyText(PierWest,
IPS_OK);
519 SetPropertyText(PierEast,
IPS_BUSY);
520 SetPropertyText(PierNone,
IPS_BUSY);
527 if (_IsSlewCompleted)
530 LOG_INFO(
"Slew is complete. Tracking...");
540 if (wasTracking != _IsTracking)
555 char response[DRIVER_LEN] = {0};
556 if (sendCommand(
":Gm#", response))
558 if (response[0] ==
'W')
560 else if (response[0] ==
'E')
578 MeridianLimitNP.
update(values, names, n);
581 std::string command =
":SXE9," + std::to_string(MeridianLimitNP[0].getValue()) +
"#";;
582 sendCommand(command.c_str());
583 command =
":SXEA," + std::to_string(MeridianLimitNP[0].getValue()) +
"#";;
584 sendCommand(command.c_str());
587 LOGF_INFO(
"Meridian!: ", MeridianLimitNP[0].getValue());
596 MeridianLimitNP.
apply();
602 if(ElevationLimitNP.
update(values, names, n))
604 for(
int i = 0; i < n; ++i)
606 if(ElevationLimitNP[OVERHEAD].isNameMatch(names[i]))
608 std::string command =
":So" + std::to_string(
static_cast<int>(ElevationLimitNP[OVERHEAD].getValue())) +
"#";;
609 sendCommand(command.c_str());
611 else if(ElevationLimitNP[HORIZON].isNameMatch(names[i]))
613 std::string command =
":Sh" + std::to_string(
static_cast<int>(ElevationLimitNP[HORIZON].getValue())) +
"#";;
614 sendCommand(command.c_str());
617 ElevationLimitNP.
apply();
634 MountTypeSP.
update(states, names, n);
640 if (state ==
IPS_OK && previousType != targetType)
641 LOG_WARN(
"Restart mount in order to apply changes to Mount Type.");
650 GuideRateSP.
update(states, names, n);
656 if (state ==
IPS_OK && previousType != targetType)
657 LOG_WARN(
"RA and DEC guide rate changed.");
665 FlipSP.
update(states, names, n);
678 RebootSP.
update(states, names, n);
683 sendCommand(
":ERESET#");
691 SafetyLimitSP.
update(states, names, n);
695 case SET_SAFETY_LIMIT:
696 sendCommand(
":Sc1#");
699 case CLEAR_SAFETY_LIMIT:
700 sendCommand(
":Sc0#");
704 SafetyLimitSP.
apply();
709 RefractSP.
update(states, names, n);
726 VerboseReportSP.
update(states, names, n);
731 verboseReport =
true;
735 SetPropertyText(IsTracking,
IPS_IDLE);
736 SetPropertyText(IsSlewCompleted,
IPS_IDLE);
737 SetPropertyText(IsParked,
IPS_IDLE);
738 SetPropertyText(IsParkginInProgress,
IPS_IDLE);
739 SetPropertyText(IsAtHomePosition,
IPS_IDLE);
740 SetPropertyText(MountAltAz,
IPS_IDLE);
741 SetPropertyText(MountEquatorial,
IPS_IDLE);
742 SetPropertyText(PierNone,
IPS_IDLE);
743 SetPropertyText(PierEast,
IPS_IDLE);
744 SetPropertyText(PierWest,
IPS_IDLE);
745 SetPropertyText(DoesRefractionComp,
IPS_IDLE);
746 SetPropertyText(WaitingAtHome,
IPS_IDLE);
747 SetPropertyText(IsHomePaused,
IPS_IDLE);
748 SetPropertyText(ParkFailed,
IPS_IDLE);
749 SetPropertyText(SlewingHome,
IPS_IDLE);
750 verboseReport =
false;
755 VerboseReportSP.
apply();
767 if (DebugCommandTP.isNameMatch(name))
769 DebugCommandTP.update(texts, names, n);
770 for(
int i = 0; i < n; i++)
772 if(DebugCommandTP[0].isNameMatch(names[i]))
774 char status[DRIVER_LEN] = {0};
775 sendCommand(texts[i]);
824 char decCommand[DRIVER_LEN] = {0};
825 snprintf(decCommand, DRIVER_LEN,
":RE%f#", value);
827 char raCommand[DRIVER_LEN] = {0};
828 snprintf(raCommand, DRIVER_LEN,
":RA%f#", value);
830 return sendCommand(decCommand) && sendCommand(raCommand);
833bool LX200NYX101::setGuideRate(
int rate)
835 char command[DRIVER_LEN] = {0};
836 snprintf(command, DRIVER_LEN,
":R%d#", rate);
837 return sendCommand(command);
845 return sendCommand(
":TQ#");
848 return sendCommand(
":TS#");
851 return sendCommand(
":TL#");
854 return sendCommand(
":TK#");
860bool LX200NYX101::setMountType(
int type)
862 return sendCommand((
type == Equatorial) ?
":SXEM,1#" :
"::SXEM,3#");
865bool LX200NYX101::goToPark()
868 return sendCommand(
":hP#");
871bool LX200NYX101::goToUnPark()
873 return sendCommand(
":hR#");
878 bool rc = goToPark();
887 bool rc = goToUnPark();
896 char response[DRIVER_LEN] = {0};
897 bool rc = sendCommand(enabled ?
":Te#" :
":Td#", response, 4, 1);
898 return rc && response[0] ==
'1';
903 int h {0}, m {0}, s {0};
904 char command[DRIVER_LEN] = {0};
908 snprintf(command, DRIVER_LEN,
":SG%c%02d:%02d#", offset >= 0 ?
'+' :
'-', std::abs(h), m);
914 char command[DRIVER_LEN] = {0};
915 snprintf(command, DRIVER_LEN,
":SC%02d/%02d/%02d#", months, days, years % 100);
922 int d{0}, m{0}, s{0};
927 longitude = longitude - 360;
929 char command[DRIVER_LEN] = {0};
933 snprintf(command, DRIVER_LEN,
":Sg%c%03d*%02d:%02d#", longitude >= 0 ?
'+' :
'-', std::abs(d), m, s);
936 LOG_ERROR(
"Error setting site longitude coordinates");
941 snprintf(command, DRIVER_LEN,
":St%c%02d*%02d:%02d#", latitude >= 0 ?
'+' :
'-', std::abs(d), m, s);
944 LOG_ERROR(
"Error setting site latitude coordinates");
952bool LX200NYX101::sendCommand(
const char *
cmd,
char * res,
int cmd_len,
int res_len)
954 int nbytes_written = 0, nbytes_read = 0, rc = -1;
956 tcflush(
PortFD, TCIOFLUSH);
960 char hex_cmd[DRIVER_LEN * 3] = {0};
961 hexDump(hex_cmd,
cmd, cmd_len);
975 LOGF_ERROR(
"Serial write error: %s.", errstr);
986 rc =
tty_read(
PortFD, res, res_len, DRIVER_TIMEOUT, &nbytes_read);
1000 char hex_res[DRIVER_LEN * 3] = {0};
1001 hexDump(hex_res, res, res_len);
1009 tcflush(
PortFD, TCIOFLUSH);
1014void LX200NYX101::hexDump(
char * buf,
const char * data,
int size)
1016 for (
int i = 0; i < size; i++)
1017 sprintf(buf + 3 * i,
"%02X ",
static_cast<uint8_t
>(data[i]));
1020 buf[3 * size - 1] =
'\0';
1029 sendCommand(
":hC#");
1033 sendCommand(
":hF#");
1043std::vector<std::string> LX200NYX101::split(
const std::string &input,
const std::string ®ex)
1046 std::regex re(regex);
1047 std::sregex_token_iterator
1048 first{input.begin(), input.end(), re, -1},
1050 return {first, last};
void setDefaultBaudRate(BaudRate newRate)
setDefaultBaudRate Set default baud rate. The default baud rate is 9600 unless otherwise changed by t...
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)
bool isNameMatch(const char *otherName) const
bool update(const double values[], const char *const names[], int n)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
bool update(const ISState states[], const char *const names[], int n)
int findOnSwitchIndex() const
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, ISRule rule, double timeout, IPState state)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
TelescopeStatus TrackState
void SetTelescopeCapability(uint32_t cap, uint8_t slewRateCount)
SetTelescopeCapability sets the Telescope capabilities. All capabilities must be initialized.
Connection::Serial * serialConnection
virtual void SetParked(bool isparked)
SetParked Change the mount parking status. The data park file (stored in ~/.indi/ParkData....
@ TELESCOPE_HAS_PIER_SIDE
@ TELESCOPE_HAS_TRACK_MODE
@ TELESCOPE_CAN_CONTROL_TRACK
uint32_t GetTelescopeCapability() const
GetTelescopeCapability returns the capability of the Telescope.
void NewRaDec(double ra, double dec)
The child class calls this function when it has updates.
void setPierSide(TelescopePierSide side)
void SetParkDataType(TelescopeParkData type)
setParkDataType Sets the type of parking data stored in the park data file and presented to the user.
virtual bool initProperties() override
Called to initialize basic properties required all the time.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
virtual bool setUTCOffset(double offset) override
virtual bool UnPark() override
Unpark the telescope if already parked.
virtual bool setLocalDate(uint8_t days, uint8_t months, uint16_t years) override
virtual bool SetTrackMode(uint8_t mode) override
SetTrackMode Set active tracking mode. Do not change track state.
virtual bool SetSlewRate(int index) override
SetSlewRate Set desired slew rate index.
virtual bool updateLocation(double latitude, double longitude, double elevation) override
Update telescope location settings.
virtual bool Park() override
Park the telescope to its home position.
virtual const char * getDefaultName() override
virtual bool SetTrackEnabled(bool enabled) override
SetTrackEnabled Engages or disengages mount tracking. If there are no tracking modes available,...
virtual bool updateProperties() override
Called when connected state changes, to add/remove properties.
virtual bool ReadScopeStatus() override
Read telescope status.
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual IPState ExecuteHomeAction(TelescopeHomeAction action) override
Execute a homing action.
virtual bool initProperties() override
Called to initialize basic properties required all the time.
@ LX200_HAS_PULSE_GUIDING
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
virtual bool updateProperties() override
Called when connected state changes, to add/remove properties.
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
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 * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
INDI::PropertyNumber EqNP
INDI::PropertySwitch TrackStateSP
INDI::PropertySwitch SlewRateSP
INDI::PropertySwitch TrackModeSP
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 tty_nread_section(int fd, char *buf, int nsize, char stop_char, int timeout, int *nbytes_read)
read buffer from terminal with a delimiter
Implementations for common driver routines.
int IUGetConfigOnSwitchIndex(const char *dev, const char *property, int *index)
IUGetConfigOnSwitchIndex Opens configuration file and reads single switch property to find ON switch ...
#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,...)
const char * SETTINGS_TAB
int setStandardProcedure(int fd, const char *data)
#define getLX200DEC(fd, x)
#define getLX200RA(fd, x)