31#define ERR_NC(res) (strcmp(res, "nc") > 0 ? "lens is not attached" : res)
33static std::unique_ptr<PinefeatCEF> pinefeatCEF(
new PinefeatCEF());
41 lastUpdate = std::chrono::steady_clock::now();
46 return "Pinefeat EF Lens Controller";
69 CalibrateSP[0].
fill(
"CALIBRATE",
"Calibrate",
ISS_OFF);
73 ApertureAbsNP[0].
fill(
"APERTURE_ABSOLUTE",
"f-stop",
"%.f", 0.0, 327.67, 0.0, 0.0);
77 ApertureRelNP[0].
fill(
"APERTURE_RELATIVE",
"f-stop",
"%.f", -327.68, 327.67, 0.0, 0.0);
81 ApertureRangeTP[0].
fill(
"APERTURE_RANGE",
"f-stop",
nullptr);
84 FocusDistanceTP[0].
fill(
"FOCUS_DISTANCE",
"meter",
nullptr);
87 FirmwareTP[0].
fill(
"FIRMWARE_VERSION",
"Version",
"Unknown");
111 std::string dist, aper;
112 if (readFocusPosition(pos)
114 && readFocusMaxPosition(
max)
115 && readFocusDistance(dist)
116 && readApertureRange(aper))
119 LOG_INFO(
"Parameters updated, the controller is ready for use.");
158 FocusDistanceTP[0].setText(dist);
159 FocusDistanceTP.
apply();
161 ApertureRangeTP[0].setText(aper);
162 ApertureRangeTP.
apply();
167 for (
int i = 0; i < 3; i++)
169 if (readFirmwareVersion())
177 LOG_ERROR(
"Can't detect the controller, please ensure the device is powered and the port is correct.");
181bool PinefeatCEF::readFirmwareVersion()
183 char res[CEF_BUF] = {0};
185 if (!sendCommand(
"v\n", res))
189 if (sscanf(res,
"%d.%d", &major, &minor) == 2)
191 firmwareMinor = minor;
194 FirmwareTP[0].setText(res);
197 LOGF_INFO(
"Detected firmware version %s.", res);
202bool PinefeatCEF::readFocusPosition(int32_t &pos)
204 char res[CEF_BUF] = {0};
206 if (!sendCommand(
"f\n", res))
209 int rc = sscanf(res,
"%d", &pos);
219bool PinefeatCEF::readFocusMaxPosition(int32_t &pos)
221 if (firmwareMinor < 3)
226 char res[CEF_BUF] = {0};
228 if (!sendCommand(
"r\n", res))
231 int rc = sscanf(res,
"%*d-%d", &pos);
241bool PinefeatCEF::readFocusDistance(std::string &result)
243 char res[CEF_BUF] = {0};
245 if (!sendCommand(
"d\n", res))
252bool PinefeatCEF::readApertureRange(std::string &result)
254 char res[CEF_BUF] = {0};
256 if (!sendCommand(
"a\n", res))
263bool PinefeatCEF::isNotMoving()
265 char res[CEF_BUF] = {0};
266 return sendCommand(
"e\n", res) && strstr(res,
"n");
269bool PinefeatCEF::moveFocusAbs(uint32_t position)
271 char cmd[CEF_BUF] = {0};
272 char res[CEF_BUF] = {0};
273 snprintf(
cmd, CEF_BUF,
"f%d\n", position);
275 if (!sendCommand(
cmd, res))
278 if (!strstr(res,
"ok"))
287bool PinefeatCEF::moveFocusRel(FocusDirection dir, uint32_t offset)
289 char cmd[CEF_BUF] = {0};
290 char res[CEF_BUF] = {0};
291 snprintf(
cmd, CEF_BUF,
"f%s%d\n", (dir ==
FOCUS_INWARD) ?
"-" :
"+", offset);
293 if (!sendCommand(
cmd, res))
296 if (!strstr(res,
"ok"))
305bool PinefeatCEF::setSpeed(
int speed)
307 char cmd[CEF_BUF] = {0};
308 char res[CEF_BUF] = {0};
309 snprintf(
cmd, CEF_BUF,
"s%d\n", speed);
311 if (!sendCommand(
cmd, res))
314 if (!strstr(res,
"ok"))
323bool PinefeatCEF::setApertureAbs(
double value)
325 char cmd[CEF_BUF] = {0};
326 char res[CEF_BUF] = {0};
327 snprintf(
cmd, CEF_BUF,
"a%.6g\n", value);
329 if (!sendCommand(
cmd, res))
332 if (!strstr(res,
"ok"))
338 LOGF_INFO(
"Aperture is set to f/%.6g.", value);
343bool PinefeatCEF::setApertureRel(
double value)
345 char cmd[CEF_BUF] = {0};
346 char res[CEF_BUF] = {0};
347 snprintf(
cmd, CEF_BUF,
"a%s%.6g\n", (value < 0) ?
"" :
"+", value);
349 if (!sendCommand(
cmd, res))
352 if (!strstr(res,
"ok"))
358 LOGF_INFO(
"Iris is %s by f/%.6g further.", (value > 0) ?
"closed" :
"opened", abs(value));
363bool PinefeatCEF::calibrate()
365 char res[CEF_BUF] = {0};
367 if (!sendCommand(
"c\n", res))
370 if (!strstr(res,
"ok"))
390 lastUpdate = std::chrono::steady_clock::now();
417 ApertureAbsNP.
update(values, names, n);
419 bool res = setApertureAbs(ApertureAbsNP[0].getValue());
425 ApertureAbsNP.
apply();
431 ApertureRelNP.
update(values, names, n);
433 bool res = setApertureRel(ApertureRelNP[0].getValue());
439 ApertureRelNP.
apply();
449 return setSpeed(speed);
454 if (!moveFocusAbs(targetTicks))
462 if (!moveFocusRel(dir, ticks))
473 auto now = std::chrono::steady_clock::now();
474 auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(now - lastUpdate).count();
476 if (elapsed >= 1 && isNotMoving())
479 std::string dist, aper;
480 if (readFocusPosition(pos)
482 && readFocusMaxPosition(
max)
483 && readFocusDistance(dist)
484 && readApertureRange(aper))
493bool PinefeatCEF::sendCommand(
const char *
cmd,
char * res)
495 int nbytes_written = 0, nbytes_read = 0, rc = -1;
497 tcflush(
PortFD, TCIOFLUSH);
505 LOGF_ERROR(
"Serial write error: %s.", errstr);
525 tcflush(
PortFD, TCIOFLUSH);
void setDefaultBaudRate(BaudRate newRate)
setDefaultBaudRate Set default baud rate. The default baud rate is 9600 unless otherwise changed by t...
const char * getDeviceName() const
void setDefaultPollingPeriod(uint32_t msec)
setDefaultPollingPeriod Change the default polling period to call TimerHit() function in the driver.
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.
INDI::PropertyNumber FocusRelPosNP
DefaultDevice * m_defaultDevice
void SetCapability(uint32_t cap)
FI::SetCapability sets the focuser capabilities. All capabilities must be initialized.
@ FOCUSER_HAS_VARIABLE_SPEED
INDI::PropertyNumber FocusSpeedNP
INDI::PropertyNumber FocusMaxPosNP
INDI::PropertyNumber FocusAbsPosNP
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Processes incoming new switch states from the client for this device. Handles updates to FocuserInter...
virtual bool updateProperties() override
Updates the state and definition of properties based on the current connection status....
virtual bool initProperties() override
Initializes the default properties for the focuser device. Sets up standard INDI properties,...
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Processes incoming new number values from the client for this device. Handles updates to FocuserInter...
Connection::Serial * serialConnection
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
const char * getName() const
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)
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)
const char * getDefaultName() override
IPState MoveAbsFocuser(uint32_t targetTicks) override
MoveFocuser the focuser to an absolute position.
IPState MoveRelFocuser(FocusDirection dir, uint32_t ticks) override
MoveFocuser the focuser to an relative position.
void TimerHit() override
Callback function to be called once SetTimer duration elapses.
bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Processes incoming new switch states from the client for this device. Handles updates to FocuserInter...
bool initProperties() override
Initializes the default properties for the focuser device. Sets up standard INDI properties,...
bool SetFocuserSpeed(int speed) override
SetFocuserSpeed Set Focuser speed.
bool updateProperties() override
Updates the state and definition of properties based on the current connection status....
bool Handshake() override
Performs a device-specific handshake after a connection is established. This method should be overrid...
bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Processes incoming new number values from the client for this device. Handles updates to FocuserInter...
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
const char * INFO_TAB
INFO_TAB Where all the properties for general information are located.
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
#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,...)