48 lastStatusData.reserve(7);
66 ReloadFirmwareSP[0].
fill(
"RELOAD",
"Reload",
ISS_OFF);
72 DerotateNP[0].
fill(
"INTERVAL",
"Interval (ms)",
"%.f", 0, 10000, 1000, 0);
77 RotatorSpeedNP[0].
fill(
"SPEED",
"Speed (steps/sec)",
"%.f", 10, 4500, 10, 500);
82 FirmwareTP[0].
fill(
"VERSION",
"Version",
"NA");
116 return "Pegasus FalconV2";
122bool PegasusFalconV2::Handshake()
128 if (!getRotatorSpeed())
129 LOG_WARN(
"Failed to read rotator speed during connection.");
144 const uint32_t ms =
static_cast<uint32_t
>(values[0]);
145 if (setDerotation(ms))
147 DerotateNP[0].setValue(values[0]);
149 LOGF_INFO(
"De-rotation is enabled and set to 1 step per %u milliseconds.", ms);
151 LOG_INFO(
"De-rotaiton is disabled.");
163 const uint32_t speed =
static_cast<uint32_t
>(values[0]);
164 if (setRotatorSpeed(speed))
166 RotatorSpeedNP[0].setValue(values[0]);
167 LOGF_INFO(
"Rotator speed set to %u steps/sec.", speed);
172 RotatorSpeedNP.
apply();
176 return Rotator::ISNewNumber(dev, name, values, names, n);
190 ReloadFirmwareSP.
apply();
196 return Rotator::ISNewSwitch(dev, name, states, names, n);
204 char cmd[DRIVER_LEN] = {0}, res[DRIVER_LEN] = {0};
205 snprintf(
cmd, DRIVER_LEN,
"MD:%.2f", angle);
206 if (sendCommand(
cmd, res))
220 char res[DRIVER_LEN] = {0};
221 if (sendCommand(
"FH", res))
223 return (!strcmp(res,
"FH:1"));
234 char cmd[DRIVER_LEN] = {0}, res[DRIVER_LEN] = {0};
235 snprintf(
cmd, DRIVER_LEN,
"FN:%d", enabled ? 1 : 0);
236 if (sendCommand(
cmd, res))
238 return (!strncmp(res,
cmd, 4));
249 char cmd[DRIVER_LEN] = {0};
250 snprintf(
cmd, DRIVER_LEN,
"SD:%.2f", angle);
251 return sendCommand(
cmd,
nullptr);
257bool PegasusFalconV2::reloadFirmware()
259 return sendCommand(
"FQ");
265bool PegasusFalconV2::setDerotation(uint32_t ms)
267 char cmd[DRIVER_LEN] = {0};
268 snprintf(
cmd, DRIVER_LEN,
"DR:%d", ms);
269 return sendCommand(
cmd,
nullptr);
275bool PegasusFalconV2::getRotatorSpeed()
277 char res[DRIVER_LEN] = {0};
278 if (sendCommand(
"FS", res))
281 std::vector<std::string> result = split(res,
":");
282 if (result.size() == 2 && result[0] ==
"FS")
286 const uint32_t speed = std::stoul(result[1]);
287 RotatorSpeedNP[0].setValue(speed);
289 LOGF_INFO(
"Rotator speed is %u steps/sec.", speed);
295 LOGF_ERROR(
"Failed to parse speed response: %s", res);
301 LOGF_ERROR(
"Invalid speed response format: %s", res);
312bool PegasusFalconV2::setRotatorSpeed(uint32_t speed)
314 char cmd[DRIVER_LEN] = {0}, res[DRIVER_LEN] = {0};
315 snprintf(
cmd, DRIVER_LEN,
"FS:%u", speed);
316 if (sendCommand(
cmd, res))
319 return (!strncmp(res,
"FS:", 3));
348bool PegasusFalconV2::getFirmware()
350 char res[DRIVER_LEN] = {0};
351 if (sendCommand(
"FV", res))
353 FirmwareTP[0].setText(res + 3);
363bool PegasusFalconV2::getStatusData()
365 char res[DRIVER_LEN] = {0};
366 if (sendCommand(
"FA", res))
368 std::vector<std::string> result = split(res,
":");
369 if (result.size() != 6)
371 LOG_WARN(
"Received wrong number of detailed sensor data. Retrying...");
375 if (result == lastStatusData)
379 const double position = std::stod(result[1]);
392 const bool reversed = std::stoi(result[5]) == 1;
394 if (reversed != wasReversed)
401 lastStatusData = result;
411bool PegasusFalconV2::sendCommand(
const char *
cmd,
char * res,
int cmd_len,
int res_len)
413 int nbytes_written = 0, nbytes_read = 0, rc = -1;
415 tcflush(
PortFD, TCIOFLUSH);
419 char hex_cmd[DRIVER_LEN * 3] = {0};
420 hexDump(hex_cmd,
cmd, cmd_len);
428 char formatted_command[DRIVER_LEN] = {0};
429 snprintf(formatted_command, DRIVER_LEN,
"%s\n",
cmd);
437 LOGF_ERROR(
"Serial write error: %s.", errstr);
445 rc =
tty_read(
PortFD, res, res_len, DRIVER_TIMEOUT, &nbytes_read);
459 char hex_res[DRIVER_LEN * 3] = {0};
460 hexDump(hex_res, res, res_len);
466 res[nbytes_read - 1] = 0;
470 tcflush(
PortFD, TCIOFLUSH);
478void PegasusFalconV2::hexDump(
char * buf,
const char * data, uint32_t size)
480 for (uint32_t i = 0; i < size; i++)
481 sprintf(buf + 3 * i,
"%02X ",
static_cast<uint8_t
>(data[i]));
484 buf[3 * size - 1] =
'\0';
490std::vector<std::string> PegasusFalconV2::split(
const std::string &input,
const std::string ®ex)
493 std::regex re(regex);
494 std::sregex_token_iterator
495 first{input.begin(), input.end(), re, -1},
497 return {first, last};
503void PegasusFalconV2::cleanupResponse(
char *response)
505 std::string s(response);
506 s.erase(std::remove_if(s.begin(), s.end(),
509 return std::isspace(x);
511 snprintf(response, DRIVER_LEN,
"%s", s.c_str());
void setPortMatchPattern(const std::string &pattern)
setPortMatchPattern Set a regex pattern used to automatically select a serial port from the discovere...
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.
void addAuxControls()
Add Debug, Simulation, and Configuration options to the driver.
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
void save(FILE *f) const
save Save property to configuration file.
bool isNameMatch(const char *otherName) const
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)
void SetCapability(uint32_t cap)
SetRotatorCapability sets the Rotator capabilities. All capabilities must be initialized.
INDI::PropertySwitch ReverseRotatorSP
INDI::PropertyNumber GotoRotatorNP
Connection::Serial * serialConnection
virtual bool initProperties() override
Initialize properties initial state and value. The child class must implement this function.
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Saves the reverse direction property in the configuration file
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Saves the reverse direction property in the configuration file
virtual bool AbortRotator() override
AbortRotator Abort all motion.
virtual void TimerHit() override
Callback function to be called once SetTimer duration elapses.
virtual bool initProperties() override
Initialize properties initial state and value. The child class must implement this function.
virtual bool ReverseRotator(bool enabled) override
reverse action ("FN:0" disabled, "FN:1" enabled)
const char * getDefaultName() override
virtual IPState MoveRotator(double angle) override
move to degrees (Command "MD:nn.nn"; Response "MD:nn.nn")
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
virtual bool SyncRotator(double angle) override
SyncRotator Set current angle as the supplied angle without moving the rotator.
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
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.
#define LOGF_INFO(fmt,...)
#define LOGF_DEBUG(fmt,...)
#define LOGF_ERROR(fmt,...)