36 #include <sys/ioctl.h>
42 static std::unique_ptr<PegasusFalcon> falcon(
new PegasusFalcon());
47 lastStatusData.reserve(7);
70 IUFillNumber(&DerotateN[0],
"INTERVAL",
"Interval (ms)",
"%.f", 0, 10000, 1000, 0);
75 IUFillText(&FirmwareT[0],
"VERSION",
"Version",
"NA");
107 return "Pegasus Falcon";
113 bool PegasusFalcon::Handshake()
115 return getFirmware();
126 if (!strcmp(name, DerotateNP.
name))
128 const uint32_t ms =
static_cast<uint32_t
>(values[0]);
129 if (setDerotation(ms))
131 DerotateN[0].value = values[0];
133 LOGF_INFO(
"De-rotation is enabled and set to 1 step per %u milliseconds.", ms);
135 LOG_INFO(
"De-rotaiton is disabled.");
144 if (!strcmp(name,
"ABS_ROTATOR_ANGLE"))
145 if (std::abs(values[0] -
GotoRotatorN[0].value) <= 0.01)
163 if (!strcmp(name, ReloadFirmwareSP.
name))
180 char cmd[DRIVER_LEN] = {0}, res[DRIVER_LEN] = {0};
181 snprintf(
cmd, DRIVER_LEN,
"MD:%.2f", angle);
182 if (sendCommand(
cmd, res))
196 char res[DRIVER_LEN] = {0};
197 if (sendCommand(
"FH", res))
199 return (!strcmp(res,
"FH:1"));
210 char cmd[DRIVER_LEN] = {0}, res[DRIVER_LEN] = {0};
211 snprintf(
cmd, DRIVER_LEN,
"FN:%d", enabled ? 1 : 0);
212 if (sendCommand(
cmd, res))
214 return (!strncmp(res,
cmd, 4));
225 char cmd[DRIVER_LEN] = {0};
226 snprintf(
cmd, DRIVER_LEN,
"SD:%.2f", angle);
227 return sendCommand(
cmd,
nullptr);
233 bool PegasusFalcon::reloadFirmware()
235 return sendCommand(
"FF");
241 bool PegasusFalcon::setDerotation(uint32_t ms)
243 char cmd[DRIVER_LEN] = {0};
244 snprintf(
cmd, DRIVER_LEN,
"DR:%d", ms);
245 return sendCommand(
cmd,
nullptr);
272 bool PegasusFalcon::getFirmware()
274 char res[DRIVER_LEN] = {0};
275 if (sendCommand(
"FV", res))
287 bool PegasusFalcon::getStatusData()
289 char res[DRIVER_LEN] = {0};
290 if (sendCommand(
"FA", res))
292 std::vector<std::string> result = split(res,
":");
293 if (result.size() != 7)
295 LOG_WARN(
"Received wrong number of detailed sensor data. Retrying...");
299 if (result == lastStatusData)
303 const double position = std::stod(result[2]);
318 const bool derotation = std::stoi(result[5]) == 1;
319 const bool wasDerotated = DerotateN[0].value > 0;
321 if (derotation != wasDerotated)
327 const bool reversed = std::stoi(result[6]) == 1;
329 if (reversed != wasReversed)
336 lastStatusData = result;
346 bool PegasusFalcon::sendCommand(
const char *
cmd,
char * res,
int cmd_len,
int res_len)
348 int nbytes_written = 0, nbytes_read = 0, rc = -1;
350 tcflush(
PortFD, TCIOFLUSH);
354 char hex_cmd[DRIVER_LEN * 3] = {0};
355 hexDump(hex_cmd,
cmd, cmd_len);
363 char formatted_command[DRIVER_LEN] = {0};
364 snprintf(formatted_command, DRIVER_LEN,
"%s\n",
cmd);
372 LOGF_ERROR(
"Serial write error: %s.", errstr);
380 rc =
tty_read(
PortFD, res, res_len, DRIVER_TIMEOUT, &nbytes_read);
394 char hex_res[DRIVER_LEN * 3] = {0};
395 hexDump(hex_res, res, res_len);
401 res[nbytes_read - 1] = 0;
405 tcflush(
PortFD, TCIOFLUSH);
413 void PegasusFalcon::hexDump(
char * buf,
const char * data, uint32_t size)
415 for (uint32_t i = 0; i < size; i++)
416 sprintf(buf + 3 * i,
"%02X ",
static_cast<uint8_t
>(data[i]));
419 buf[3 * size - 1] =
'\0';
425 std::vector<std::string> PegasusFalcon::split(
const std::string &input,
const std::string ®ex)
428 std::regex re(regex);
429 std::sregex_token_iterator
430 first{input.begin(), input.end(), re, -1},
432 return {first, last};
438 void PegasusFalcon::cleanupResponse(
char *response)
440 std::string s(response);
441 s.erase(std::remove_if(s.begin(), s.end(),
444 return std::isspace(x);
446 strncpy(response, s.c_str(), DRIVER_LEN);
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.
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.
INumberVectorProperty GotoRotatorNP
void SetCapability(uint32_t cap)
SetRotatorCapability sets the Rotator capabilities. All capabilities must be initialized.
ISwitchVectorProperty ReverseRotatorSP
ISwitch ReverseRotatorS[2]
virtual bool initProperties() override
Initilize 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 ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
virtual IPState MoveRotator(double angle) override
move to degrees (Commmand "MD:nn.nn"; Response "MD:nn.nn")
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual void TimerHit() override
Callback function to be called once SetTimer duration elapses.
virtual bool AbortRotator() override
AbortRotator Abort all motion.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
virtual bool ReverseRotator(bool enabled) override
reverse action ("FN:0" disabled, "FN:1" enabled)
virtual bool SyncRotator(double angle) override
SyncRotator Set current angle as the supplied angle without moving the rotator.
const char * getDefaultName() override
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Saves the reverse direction property in the configuration file
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
void ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Update the value of an existing switch vector property.
void ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
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.
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 IUSaveConfigNumber(FILE *fp, const INumberVectorProperty *nvp)
Add a number vector property value to the configuration file.
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.
void IDSetNumber(const INumberVectorProperty *nvp, const char *fmt,...)
void IDSetSwitch(const ISwitchVectorProperty *svp, const char *fmt,...)
#define LOGF_INFO(fmt,...)
#define LOGF_DEBUG(fmt,...)
#define LOGF_ERROR(fmt,...)