29 #include <libnova/transform.h>
35 #define CMD_MAX_LEN 32
49 #define OAT_MEADE_COMMAND "OAT_MEADE_COMMAND"
50 #define OAT_DEC_LOWER_LIMIT "OAT_DEC_LOWER_LIMIT"
51 #define OAT_DEC_UPPER_LIMIT "OAT_DEC_UPPER_LIMIT"
52 #define OAT_GET_DEBUG_LEVEL "OAT_GET_DEBUG_LEVEL"
53 #define OAT_GET_ENABLED_DEBUG_LEVEL "OAT_GET_ENABLED_DEBUG_LEVEL"
54 #define OAT_SET_DEBUG_LEVEL "OAT_GET_DEBUG_LEVEL"
69 IUFillNumber(&PolarAlignAltN,
"OAT_POLAR_ALT",
"Arcmin",
"%.f", -140.0, 140.0, 1.0, 0);
74 IUFillNumber(&PolarAlignAzN,
"OAT_POLAR_AZ",
"Arcmin",
"%.f", -320.0, 320.0, 1.0, 0);
76 "Polar Align Azimuth",
85 IUFillNumber(&RAHomeN,
"RA_HOME",
"Hours",
"%d", 1.0, 7.0, 1.0, 2);
90 IUFillNumber(&RAHomeOffsetN,
"OAT_RA_HOME_OFFSET",
"Steps",
"%d", -10000.0, 10000.0, 100.0, 0);
95 IUFillNumber(&DecLimitsN[0],
"OAT_DEC_LIMIT_LOWER",
"Lower",
"%.f", -20000.0, 0.0, 1000.0, 0);
96 IUFillNumber(&DecLimitsN[1],
"OAT_DEC_LIMIT_UPPER",
"Upper",
"%.f", 0.0, 50000.0, 1000.0, 0);
140 if(OATUpdateProperties() != 0)
144 if (OATUpdateFocuser() != 0)
146 LOG_WARN(
"Communication error on Focuser Update, this update aborted, will try again...");
151 int LX200_OpenAstroTech::OATUpdateProperties()
161 tcflush(
PortFD, TCIOFLUSH);
165 int rc = executeMeadeCommand(
":GX#", value);
166 if (rc == 0 && strlen(value) > 10)
168 const char *motors = strchr(value,
',') + 1;
169 if(PolarAlignAzNP.
s ==
IPS_BUSY && motors[3] ==
'-') {
173 if(PolarAlignAltNP.
s ==
IPS_BUSY && motors[4] ==
'-') {
177 if(RAHomeNP.
s ==
IPS_BUSY && value[0] ==
'H')
191 if (!strcmp(name, MeadeCommandTP.
name))
202 char *
cmd = texts[0];
203 size_t len = strlen(
cmd);
205 if(len > 2 &&
cmd[0] ==
':' &&
cmd[len-1] ==
'#') {
207 MeadeCommandResult[0] = 0;
208 int err = executeMeadeCommand(texts[0], MeadeCommandResult);
213 IDSetText(&MeadeCommandTP,
"%s", MeadeCommandResult);
218 IDSetText(&MeadeCommandTP,
"%s", MeadeCommandResult);
234 if (!strcmp(name, PolarAlignAltN.name) || !strcmp(name, PolarAlignAltNP.
name))
239 LOGF_WARN(
"Moving Polar Alt to %.3f", values[0]);
240 snprintf(read_buffer,
sizeof(read_buffer),
":MAL%.3f#", values[0]);
241 executeMeadeCommandBlind(read_buffer);
247 if (!strcmp(name, PolarAlignAzN.name) || !strcmp(name, PolarAlignAzNP.
name))
252 LOGF_WARN(
"Moving Polar Az to %.3f", values[0]);
253 snprintf(read_buffer,
sizeof(read_buffer),
":MAZ%.3f#", values[0]);
254 executeMeadeCommandBlind(read_buffer);
269 if (!strcmp(name, HomeS.name))
274 return executeMeadeCommandBlind(
":hF#");
282 return const_cast<const char *
>(
"LX200 OpenAstroTech");
285 int LX200_OpenAstroTech::executeMeadeCommand(
const char *
cmd,
char *data)
287 bool wait =
true, getchar =
false;
288 int len = strlen(
cmd);
292 if(!(
cmd[2] ==
'p' ||
cmd[2] ==
'B')) {
294 }
else if(
cmd[2] ==
'B') {
297 }
else if(
cmd[1] ==
'M' &&
cmd[2] ==
'A') {
302 return executeMeadeCommandBlind(
cmd);
307 sprintf(data,
"%c", val);
312 LOGF_WARN(
"Executed Meade Command error: %d %s -> '%s'", err,
cmd, data);
314 LOGF_INFO(
"Executed Meade Command: %d %s -> '%s'", wait,
cmd, data);
321 char LX200_OpenAstroTech::getCommandChar(
int fd,
const char *
cmd)
324 int nbytes_write = 0, nbytes_read = 0, error_type;
331 error_type =
tty_read(
fd, read_buffer, 1, 5, &nbytes_read);
333 if (nbytes_read == 1) {
334 LOGF_INFO(
"getCommandChar 3: %s -> '%s'",
cmd, read_buffer);
335 return read_buffer[0];
339 LOGF_WARN(
"getCommandChar error: %d %s -> '%s'", error_type,
cmd, read_buffer);
343 bool LX200_OpenAstroTech::executeMeadeCommandBlind(
const char *
cmd)
346 int nbytes_write = 0;
353 tcflush(
PortFD, TCIFLUSH);
356 LOGF_ERROR(
"CHECK CONNECTION: Error sending command %s",
cmd);
363 int LX200_OpenAstroTech::flushIO(
int fd)
365 tcflush(
fd, TCIOFLUSH);
369 tcflush(
fd, TCIOFLUSH);
373 if (error_type >= 0) {
374 LOGF_DEBUG(
"flushIO: Information in buffer: Bytes: %u, string: %s", nbytes_read, discard_data);
377 }
while (error_type > 0);
386 LOGF_ERROR(
"MoveFocuser shouldn't be called: %d at %d for %d", dir, speed, duration);
388 char read_buffer[32];
390 if (dir != FocuserDirectionLast) {
391 FocuserDirectionLast = dir;
392 LOGF_INFO(
"Applying backlash %d to %d", FocuserBacklash, output);
393 output += FocuserBacklash;
396 snprintf(read_buffer,
sizeof(read_buffer),
":FM%f#", output);
397 executeMeadeCommandBlind(read_buffer);
405 char read_buffer[32];
406 snprintf(read_buffer,
sizeof(read_buffer),
":Fp#");
407 if(!executeMeadeCommand(read_buffer, read_buffer)) {
410 targetTicks += FocuserBacklash;
413 targetTicks -= FocuserBacklash;
418 char read_buffer[32];
419 snprintf(read_buffer,
sizeof(read_buffer),
":FM%d#",
int(relTicks));
420 executeMeadeCommandBlind(read_buffer);
427 LOG_INFO(
"Unable to move focuser, out of range");
436 char read_buffer[32];
437 if (dir != FocuserDirectionLast) {
438 FocuserDirectionLast = dir;
439 LOGF_INFO(
"Applying backlash %d to %d", FocuserBacklash, ticks);
440 ticks += FocuserBacklash;
444 snprintf(read_buffer,
sizeof(read_buffer),
":FM%d#", output);
445 executeMeadeCommandBlind(read_buffer);
453 FocuserBacklash = steps;
462 strncpy(
cmd,
":FQ#",
sizeof(
cmd));
463 executeMeadeCommandBlind(
cmd);
468 void LX200_OpenAstroTech::initFocuserProperties(
const char * groupName)
511 "Reverse Motion", groupName,
IP_RW,
518 "Backlash", groupName,
IP_RW,
528 int LX200_OpenAstroTech::OATUpdateFocuser()
535 tcflush(
PortFD, TCIOFLUSH);
546 char valueStatus = getCommandChar(
PortFD,
":FB#");
547 if (valueStatus ==
'0')
554 else if (valueStatus ==
'1')
563 LOGF_WARN(
"Communication :FB# error, check connection: %d", valueStatus);
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
INumberVectorProperty FocusSpeedNP
INumberVectorProperty FocusSyncNP
INumberVectorProperty FocusBacklashNP
ISwitchVectorProperty FocusBacklashSP
INumberVectorProperty FocusAbsPosNP
INumberVectorProperty FocusRelPosNP
bool updateProperties()
updateProperties Define or Delete Rotator properties based on the connection status of the base devic...
DefaultDevice * m_defaultDevice
INumberVectorProperty FocusTimerNP
ISwitchVectorProperty FocusReverseSP
void SetCapability(uint32_t cap)
FI::SetCapability sets the focuser capabilities. All capabilities must be initialized.
INumber FocusBacklashN[1]
void initProperties(const char *groupName)
Initilize focuser properties. It is recommended to call this function within initProperties() of your...
@ FOCUSER_HAS_VARIABLE_SPEED
INumberVectorProperty FocusMaxPosNP
ISwitch FocusBacklashS[2]
ISwitchVectorProperty FocusAbortSP
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
bool updateProperties()
Called when connected state changes, to add/remove properties.
bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process the client newSwitch command.
bool initProperties()
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 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 updateProperties() override
Called when connected state changes, to add/remove properties.
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
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 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.
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.
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.
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 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 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 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 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.
IText * IUFindText(const ITextVectorProperty *tvp, const char *name)
Find an IText member in a vector text property.
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
int getCommandString(int fd, char *data, const char *cmd)
@ value
the parser finished reading a JSON value