12 static std::unique_ptr<RBFOCUS> rbfocus(
new RBFOCUS());
26 IUFillNumber(&TemperatureN[0],
"TEMPERATURE",
"Celsius",
"%6.2f", -50, 70., 0., 0.);
32 IUFillSwitchVector(&focuserHoldSP, focuserHoldS, 2,
getDeviceName(),
"Focuser Hold",
"",
OPTIONS_TAB,
IP_RW,
ISR_1OFMANY, 0,
37 IUFillSwitchVector(&dirSP, dirS, 2,
getDeviceName(),
"Direction",
"",
OPTIONS_TAB,
IP_RW,
ISR_1OFMANY, 0,
90 LOG_INFO(
"Error retrieving data from RBFocuser, please ensure RBFocus controller is powered and the port is correct.");
101 int nbytes_written = 0, nbytes_read = 0, rc = -1;
105 tcflush(
PortFD, TCIOFLUSH);
108 bool success =
false;
109 while (numChecks < 3 && !success)
116 if(!transmissionSuccess)
119 LOGF_ERROR(
"Handshake Attempt %i, tty transmission error: %s.", numChecks, errstr);
122 bool responseSuccess = (rc =
tty_read(
PortFD, resp, 4, DRIVER_TIMEOUT, &nbytes_read)) ==
TTY_OK;
126 LOGF_ERROR(
"Handshake Attempt %i, updatePosition response error: %s.", numChecks, errstr);
129 success = transmissionSuccess && responseSuccess;
134 LOG_INFO(
"Handshake failed after 3 attempts");
138 tcflush(
PortFD, TCIOFLUSH);
140 return !strcmp(resp,
"OK!#");
144 bool RBFOCUS::readTemperature()
146 char res[DRIVER_RES] = {0};
148 if (sendCommand(
"Q#", res) ==
false)
152 int rc = sscanf(res,
"C%d#", &temp);
155 TemperatureN[0].value = temp / 100.0;
158 LOGF_ERROR(
"Unknown error: focuser temperature value (%s)", res);
165 bool RBFOCUS::readVersion()
169 bool RBFOCUS::readHold()
171 char res[DRIVER_RES] = {0};
173 if (sendCommand(
"V#", res) ==
false)
178 if(strcmp(res,
"Enable") == 0)
183 else if (strcmp(res,
"Disable") == 0)
194 bool RBFOCUS::readDir()
196 char res[DRIVER_RES] = {0};
198 if (sendCommand(
"B#", res) ==
false)
203 if(strcmp(res,
"Reversed") == 0)
208 else if (strcmp(res,
"Normal") == 0)
219 bool RBFOCUS::readPosition()
221 char res[DRIVER_RES] = {0};
223 if (sendCommand(
"P#", res) ==
false)
227 int rc = sscanf(res,
"%d#", &pos);
239 bool RBFOCUS::isMoving()
241 char res[DRIVER_RES] = {0};
243 if (sendCommand(
"J#", res) ==
false)
246 if (strcmp(res,
"M1:OK") == 0)
248 else if (strcmp(res,
"M0:OK") == 0)
251 LOGF_ERROR(
"Unknown error: isMoving value (%s)", res);
256 bool RBFOCUS::MaxPos()
258 char res[DRIVER_RES] = {0};
260 if (sendCommand(
"X#", res) ==
false)
264 int rc = sscanf(res,
"%u#", &mPos);
273 LOGF_ERROR(
"Invalid Response: focuser hold value (%s)", res);
284 char cmd[DRIVER_RES] = {0};
286 snprintf(
cmd, DRIVER_RES,
"H%d#", mPos);
290 Focuser::SyncPresets(mPos);
298 char cmd[DRIVER_RES] = {0};
299 snprintf(
cmd, DRIVER_RES,
"I%d#", ticks);
300 return sendCommand(
cmd);
305 char cmd[DRIVER_RES] = {0};
306 snprintf(
cmd, DRIVER_RES,
"T%d#", targetTicks);
308 if (sendCommand(
cmd) ==
false)
311 targetPos = targetTicks;
325 bool rc = readPosition();
335 rc = readTemperature();
338 if (fabs(lastTemperature - TemperatureN[0].value) >= 0.5)
341 lastTemperature = TemperatureN[0].value;
352 LOG_INFO(
"Focuser reached requested position.");
361 return sendCommand(
"L#");
363 bool RBFOCUS::setHold()
365 return sendCommand(
"C#");
367 bool RBFOCUS::setDir()
369 return sendCommand(
"D#");
373 if (strcmp(focuserHoldSP.
name, name) == 0)
381 if (current_mode == target_mode)
391 focuserHoldS[current_mode].s =
ISS_ON;
402 if (strcmp(dirSP.
name, name) == 0)
410 if (current_mode == target_mode)
420 dirS[current_mode].s =
ISS_ON;
436 bool RBFOCUS::sendCommand(
const char *
cmd,
char * res)
438 int nbytes_written = 0, nbytes_read = 0, rc = -1;
440 tcflush(
PortFD, TCIOFLUSH);
448 LOGF_ERROR(
"Serial write error: %s.", errstr);
464 res[nbytes_read - 1] = 0;
468 tcflush(
PortFD, TCIOFLUSH);
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)
uint32_t getCurrentPollingPeriod() const
getCurrentPollingPeriod Return the current polling period.
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
INumberVectorProperty FocusAbsPosNP
void SetCapability(uint32_t cap)
FI::SetCapability sets the focuser capabilities. All capabilities must be initialized.
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
virtual void SyncPresets(uint32_t ticks)
syncPresets Updates the min/max/step range of the preset as per the maximum name of Absolute Focus Tr...
virtual IPState MoveAbsFocuser(uint32_t targetTicks) override
MoveAbsFocuser Move to an absolute target position.
virtual bool SyncFocuser(uint32_t ticks) override
MoveRelFocuser Move focuser for a relative amount of ticks in a specific direction.
virtual void TimerHit() override
Callback function to be called once SetTimer duration elapses.
virtual bool Handshake() override
Handshake Try to communicate with Focuser and see if there is a valid response.
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual bool SetFocuserMaxPosition(uint32_t ticks) override
SetFocuserMaxPosition Update focuser maximum position. It only updates the PresetNP property limits.
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
const char * getDefaultName() override
virtual bool AbortFocuser() override
AbortFocuser all focus motion.
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
const char * OPTIONS_TAB
OPTIONS_TAB Where all the driver's options are located. Those may include auxiliary controls,...
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
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.
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 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 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.
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_DEBUG(fmt,...)
#define LOGF_ERROR(fmt,...)