29#include <libnova/transform.h>
51#define OAT_MEADE_COMMAND "OAT_MEADE_COMMAND"
52#define OAT_DEC_LOWER_LIMIT "OAT_DEC_LOWER_LIMIT"
53#define OAT_DEC_UPPER_LIMIT "OAT_DEC_UPPER_LIMIT"
54#define OAT_GET_DEBUG_LEVEL "OAT_GET_DEBUG_LEVEL"
55#define OAT_GET_ENABLED_DEBUG_LEVEL "OAT_GET_ENABLED_DEBUG_LEVEL"
56#define OAT_SET_DEBUG_LEVEL "OAT_GET_DEBUG_LEVEL"
104 IUFillNumber(&PolarAlignAltN,
"OAT_POLAR_ALT",
"Arcmin",
"%.f", -140.0, 140.0, 1.0, 0);
109 IUFillNumber(&PolarAlignAzN,
"OAT_POLAR_AZ",
"Arcmin",
"%.f", -320.0, 320.0, 1.0, 0);
111 "Polar Align Azimuth",
120 IUFillNumber(&RAHomeN,
"RA_HOME",
"Hours",
"%d", 1.0, 7.0, 1.0, 2);
125 IUFillNumber(&RAHomeOffsetN,
"OAT_RA_HOME_OFFSET",
"Steps",
"%d", -10000.0, 10000.0, 100.0, 0);
130 IUFillNumber(&DecLimitsN[0],
"OAT_DEC_LIMIT_LOWER",
"Lower",
"%.f", 0.0, -50.0, 0.0, 0);
131 IUFillNumber(&DecLimitsN[1],
"OAT_DEC_LIMIT_UPPER",
"Upper",
"%.f", 0.0, 180.0, 120.0, 0);
179 if(OATUpdateProperties() != 0)
183 if (OATUpdateFocuser() != 0)
185 LOG_WARN(
"Communication error on Focuser Update, this update aborted, will try again...");
190int LX200_OpenAstroTech::OATUpdateProperties()
201 tcflush(
PortFD, TCIOFLUSH);
205 int rc = executeMeadeCommand(
":GX#", value);
206 if (rc == 0 && strlen(value) > 10)
208 const char *motors = strchr(value,
',') + 1;
209 if(PolarAlignAzNP.
s ==
IPS_BUSY && motors[3] ==
'-')
214 if(PolarAlignAltNP.
s ==
IPS_BUSY && motors[4] ==
'-')
219 if(RAHomeNP.
s ==
IPS_BUSY && value[0] ==
'H')
233 if (!strcmp(name, MeadeCommandTP.
name))
245 char *
cmd = texts[0];
246 size_t len = strlen(
cmd);
251 MeadeCommandResult[0] = 0;
253 if(
cmd[0] ==
':' &&
cmd[len - 1] ==
'#')
255 err = executeMeadeCommand(
cmd, MeadeCommandResult);
257 else if(
cmd[0] ==
'@' &&
cmd[len - 1] ==
'#')
260 err = executeMeadeCommandBlind(
cmd);
262 else if(
cmd[0] ==
'&' &&
cmd[len - 1] ==
'#')
268 sprintf(MeadeCommandResult,
"%c", val);
281 IDSetText(&MeadeCommandTP,
"%s", MeadeCommandResult);
296 if (!strcmp(name, PolarAlignAltN.name) || !strcmp(name, PolarAlignAltNP.
name))
301 LOGF_WARN(
"Moving Polar Alt to %.3f", values[0]);
302 snprintf(read_buffer,
sizeof(read_buffer),
":MAL%.3f#", values[0]);
303 executeMeadeCommandBlind(read_buffer);
309 if (!strcmp(name, PolarAlignAzN.name) || !strcmp(name, PolarAlignAzNP.
name))
314 LOGF_WARN(
"Moving Polar Az to %.3f", values[0]);
315 snprintf(read_buffer,
sizeof(read_buffer),
":MAZ%.3f#", values[0]);
316 executeMeadeCommandBlind(read_buffer);
345 return "LX200 OpenAstroTech";
348int LX200_OpenAstroTech::executeMeadeCommand(
const char *
cmd,
char *data)
350 bool wait =
true, getchar =
false;
351 int len = strlen(
cmd);
357 if(!(
cmd[2] ==
'p' ||
cmd[2] ==
'B'))
361 else if(
cmd[2] ==
'B')
366 else if(
cmd[1] ==
'M' &&
cmd[2] ==
'A')
370 else if(
cmd[1] ==
'M' && (
cmd[2] ==
'X' ||
cmd[2] ==
'T'))
374 else if(
cmd[1] ==
'M' && (
cmd[2] ==
'g' ||
cmd[2] ==
'G'))
378 else if(
cmd[1] ==
'S' &&
cmd[2] !=
'C')
382 else if(
cmd[1] ==
'X' &&
cmd[2] ==
'S')
389 return executeMeadeCommandBlind(
cmd);
397 sprintf(data,
"%c", val);
401 sprintf(data,
"%s",
"null");
414 LOGF_WARN(
"Executed Meade Command error: %d %s -> '%s'", err,
cmd, data);
418 LOGF_INFO(
"Executed Meade Command: %d %s -> '%s'", wait,
cmd, data);
425char LX200_OpenAstroTech::getCommandChar(
int fd,
const char *
cmd)
428 int nbytes_write = 0, nbytes_read = 0, error_type;
436 error_type =
tty_read(
fd, read_buffer, 1, 5, &nbytes_read);
438 if (nbytes_read == 1)
441 return read_buffer[0];
445 LOGF_WARN(
"getCommandChar error: %d %s -> '%s'", error_type,
cmd, read_buffer);
449bool LX200_OpenAstroTech::executeMeadeCommandBlind(
const char *
cmd)
452 int nbytes_write = 0;
459 tcflush(
PortFD, TCIFLUSH);
463 LOGF_ERROR(
"CHECK CONNECTION: Error sending command %s",
cmd);
470int LX200_OpenAstroTech::flushIO(
int fd)
472 tcflush(
fd, TCIOFLUSH);
476 tcflush(
fd, TCIOFLUSH);
483 LOGF_DEBUG(
"flushIO: Information in buffer: Bytes: %u, string: %s", nbytes_read, discard_data);
487 while (error_type > 0);
497 LOGF_ERROR(
"MoveFocuser shouldn't be called: %d at %d for %d", dir, speed, duration);
499 char read_buffer[32];
501 if (dir != FocuserDirectionLast)
503 FocuserDirectionLast = dir;
504 LOGF_INFO(
"Applying backlash %d to %d", FocuserBacklash, output);
505 output += FocuserBacklash;
508 snprintf(read_buffer,
sizeof(read_buffer),
":FM%f#", output * reversed);
509 executeMeadeCommandBlind(read_buffer);
517 char read_buffer[32];
518 snprintf(read_buffer,
sizeof(read_buffer),
":Fp#");
519 if(!executeMeadeCommand(read_buffer, read_buffer))
524 targetTicks += FocuserBacklash;
529 targetTicks -= FocuserBacklash;
534 char read_buffer[32];
535 snprintf(read_buffer,
sizeof(read_buffer),
":FM%d#",
int(relTicks));
536 executeMeadeCommandBlind(read_buffer);
543 LOG_INFO(
"Unable to move focuser, out of range");
553 char read_buffer[64];
554 if (dir != FocuserDirectionLast)
556 FocuserDirectionLast = dir;
557 LOGF_INFO(
"Applying backlash %d to %d", FocuserBacklash, ticks);
558 ticks += FocuserBacklash;
562 snprintf(read_buffer,
sizeof(read_buffer),
":FM%d#", output * reversed);
563 executeMeadeCommandBlind(read_buffer);
571 FocuserBacklash = steps;
580 strncpy(
cmd,
":FQ#",
sizeof(
cmd));
581 executeMeadeCommandBlind(
cmd);
595 snprintf(
cmd,
sizeof(
cmd),
":FP%d#",
int(ticks));
602int LX200_OpenAstroTech::OATUpdateFocuser()
610 tcflush(
PortFD, TCIOFLUSH);
623 char valueStatus = getCommandChar(
PortFD,
":FB#");
624 if (valueStatus ==
'0')
631 else if (valueStatus ==
'1')
640 LOGF_WARN(
"Communication :FB# error, check connection: %d", valueStatus);
656 int rc = executeMeadeCommand(enabled ?
":MT1#" :
":MT0#", value);
657 LOGF_INFO(
"Set Tracking to %d: %d/'%s'", (
int)enabled, rc, value);
658 return rc == 0 && value[0] ==
'1';
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
INDI::PropertyNumber FocusRelPosNP
INDI::PropertySwitch FocusReverseSP
bool updateProperties()
updateProperties Define or Delete Rotator properties based on the connection status of the base devic...
void SetCapability(uint32_t cap)
FI::SetCapability sets the focuser capabilities. All capabilities must be initialized.
INDI::PropertyNumber FocusSyncNP
@ FOCUSER_HAS_VARIABLE_SPEED
INDI::PropertyNumber FocusSpeedNP
INDI::PropertyNumber FocusTimerNP
void initProperties(const char *groupName)
Initialize focuser properties. It is recommended to call this function within initProperties() of you...
INDI::PropertyNumber FocusMaxPosNP
INDI::PropertyNumber FocusBacklashNP
INDI::PropertyNumber FocusAbsPosNP
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
int findOnSwitchIndex() const
void SetTelescopeCapability(uint32_t cap, uint8_t slewRateCount)
SetTelescopeCapability sets the Telescope capabilities. All capabilities must be initialized.
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
@ TELESCOPE_CAN_CONTROL_TRACK
uint32_t GetTelescopeCapability() const
GetTelescopeCapability returns the capability of the Telescope.
bool updateProperties()
Called when connected state changes, to add/remove properties.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process the client newNumber command.
bool initProperties()
Called to initialize basic properties required all the time.
virtual bool ReadScopeStatus() override
Read telescope status.
virtual bool Handshake() override
perform handshake with device to check communication
virtual bool ReadScopeStatus() override
Read telescope status.
virtual bool AbortFocuser() override
AbortFocuser all focus motion.
IPState MoveAbsFocuser(uint32_t targetTicks) override
MoveFocuser the focuser to an absolute position.
virtual bool Handshake() override
perform handshake with device to check communication
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 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 ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
virtual bool SyncFocuser(uint32_t ticks) override
SyncFocuser Set current position to ticks without moving the focuser.
virtual const char * getDefaultName(void) override
IPState MoveFocuser(FocusDirection dir, int speed, uint16_t duration) override
MoveFocuser the focuser in a particular direction with a specific speed for a finite duration.
virtual bool SetFocuserBacklash(int32_t steps) override
SetFocuserBacklash Set the focuser backlash compensation value.
IPState MoveRelFocuser(FocusDirection dir, uint32_t ticks) override
MoveFocuser the focuser to an relative position.
virtual IPState ExecuteHomeAction(TelescopeHomeAction action) override
Execute a homing action.
LX200_OpenAstroTech(void)
const char * MOTION_TAB
MOTION_TAB Where all the motion control properties of the device are located.
const char * FOCUS_TAB
FOCUS_TAB Where all the properties for focuser are located.
const char * OPTIONS_TAB
OPTIONS_TAB Where all the driver's options are located. Those may include auxiliary controls,...
int tty_read(int fd, char *buf, int nbytes, int timeout, int *nbytes_read)
read buffer from terminal
int tty_read_section_expanded(int fd, char *buf, char stop_char, long timeout_seconds, long timeout_microseconds, int *nbytes_read)
read buffer from terminal with a delimiter
int tty_write_string(int fd, const char *buf, int *nbytes_written)
Writes a null terminated string to fd.
Implementations for common driver routines.
IText * IUFindText(const ITextVectorProperty *tvp, const char *name)
Find an IText member in a vector text property.
void IUFillNumberVector(INumberVectorProperty *nvp, INumber *np, int nnp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a number vector property. The vector's auxiliary elements will be set to NULL.
void IUFillTextVector(ITextVectorProperty *tvp, IText *tp, int ntp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a text vector property. The vector's auxiliary elements will be set to NULL.
void IUSaveText(IText *tp, const char *newtext)
Function to reliably save new text in a IText.
void IUFillText(IText *tp, const char *name, const char *label, const char *initialText)
Assign attributes for a text property. The text's auxiliary elements will be set to NULL.
void IUFillNumber(INumber *np, const char *name, const char *label, const char *format, double min, double max, double step, double value)
Assign attributes for a number property. The number's auxiliary elements will be set to NULL.
void IDSetNumber(const INumberVectorProperty *nvp, const char *fmt,...)
void IDSetText(const ITextVectorProperty *tvp, const char *fmt,...)
#define LOGF_INFO(fmt,...)
#define LOGF_WARN(fmt,...)
#define LOGF_DEBUG(fmt,...)
#define LOGF_ERROR(fmt,...)
#define DEBUGFDEVICE(device, priority, msg,...)
#define DEBUGF(priority, msg,...)
std::mutex lx200CommsLock
#define OAT_MEADE_COMMAND
std::mutex lx200CommsLock
int getCommandString(int fd, char *data, const char *cmd)