34 static std::unique_ptr<RigelDome> rigelDome(
new RigelDome());
38 #define DOME_TIMEOUT 3
40 #define SIM_SHUTTER_TIMER 5.0
41 #define SIM_FLAP_TIMER 5.0
42 #define SIM_DOME_HI_SPEED 5.0
43 #define SIM_DOME_LO_SPEED 0.5
60 IUFillSwitch(&OperationS[OPERATION_FIND_HOME],
"OPERATION_FIND_HOME",
"Find Home",
ISS_OFF);
61 IUFillSwitch(&OperationS[OPERATION_CALIBRATE],
"OPERATION_CALIBRATE",
"Calibrate",
ISS_OFF);
65 IUFillText(&InfoT[INFO_FIRMWARE],
"FIRMWARE",
"Version",
"NA");
66 IUFillText(&InfoT[INFO_MODEL],
"MODEL",
"Model",
"NA");
67 IUFillText(&InfoT[INFO_TICKS],
"TICKS_PER_REV",
"Ticks/Rev",
"NA");
68 IUFillText(&InfoT[INFO_BATTERY],
"BATTERY",
"Battery",
"NA");
87 bool RigelDome::getStartupValues()
91 InfoTP.
s = (readFirmware() && readModel() && readStepsPerRevolution()) ?
IPS_OK :
IPS_ALERT;
99 if (readShutterStatus())
102 if (readHomePosition())
125 char res[DRIVER_LEN] = {0};
126 sendCommand(
"PULSAR", res);
128 bool rc = readShutterStatus();
178 if (!strcmp(OperationSP.
name, name))
181 if (!strcmp(requestedOperation, OperationS[OPERATION_FIND_HOME].name))
186 OperationS[OPERATION_FIND_HOME].s =
ISS_ON;
188 LOG_INFO(
"Dome is moving to home position...");
196 else if (!strcmp(requestedOperation, OperationS[OPERATION_CALIBRATE].name))
201 OperationS[OPERATION_CALIBRATE].s =
ISS_ON;
227 if (strcmp(name, HomePositionNP.
name) == 0)
231 float homeAz = HomePositionN[
AXIS_AZ].value;
233 LOGF_INFO(
"Setting home position to %3.1f", homeAz);
256 bool isHoming = (OperationSP.
s ==
IPS_BUSY && OperationS[OPERATION_FIND_HOME].s ==
ISS_ON);
257 bool isCalibrating = (OperationSP.
s ==
IPS_BUSY && OperationS[OPERATION_CALIBRATE].s ==
ISS_ON);
261 LOG_INFO(
"Dome completed homing...");
267 else if (isCalibrating)
269 LOG_INFO(
"Dome completed calibration...");
296 ShutterState newShutterState = parseShutterState(m_rawShutterState);
302 if (readBatteryLevels())
314 char cmd[DRIVER_LEN] = {0}, res[DRIVER_LEN] = {0};
316 snprintf(
cmd, DRIVER_LEN,
"GO %3.1f", az);
317 if (sendCommand(
cmd, res) ==
false)
344 char cmd[DRIVER_LEN] = {0}, res[DRIVER_LEN] = {0};
346 snprintf(
cmd, DRIVER_LEN,
"ANGLE K %3.1f", az);
347 if (sendCommand(
cmd, res) ==
false)
350 return (res[0] ==
'A');
359 if (setParkAz(targetAz))
361 char res[DRIVER_LEN] = {0};
362 if (sendCommand(
"GO P", res) ==
false)
373 bool RigelDome::home()
375 char res[DRIVER_LEN] = {0};
376 if (sendCommand(
"GO H", res) ==
false)
379 return (res[0] ==
'A');
385 bool RigelDome::calibrate()
387 char res[DRIVER_LEN] = {0};
388 if (sendCommand(
"CALIBRATE", res) ==
false)
391 return (res[0] ==
'A');
397 bool RigelDome::setHome(
double az)
399 char cmd[DRIVER_LEN] = {0}, res[DRIVER_LEN] = {0};
401 snprintf(
cmd, DRIVER_LEN,
"HOME %3.1f", az);
402 if (sendCommand(
cmd, res) ==
false)
405 return (res[0] ==
'A');
421 char res[DRIVER_LEN] = {0};
425 m_TargetShutter = operation;
426 sendCommand(
"OPEN", res);
430 m_TargetShutter = operation;
431 sendCommand(
"CLOSE", res);
442 if (sendCommand(
"STOP"))
446 LOGF_INFO(
"%s is aborted.", OperationS[OPERATION_CALIBRATE].s ==
ISS_ON ?
"Calibration" :
"Finding home");
455 LOG_WARN(
"Shutter motion aborted!");
490 bool RigelDome::setShutterConnected(
bool enabled)
492 char cmd[DRIVER_LEN] = {0};
493 snprintf(
cmd, DRIVER_LEN,
"BBOND %d", enabled ? 1 : 0);
494 return sendCommand(
cmd);
500 bool RigelDome::isShutterConnected()
502 char res[DRIVER_LEN] = {0};
503 if (sendCommand(
"BBOND", res) ==
false)
505 bool rc = (std::stoi(res) != 0);
506 LOGF_DEBUG(
"Shutter is %s.", (rc ?
"connected" :
"disconnected"));
513 bool RigelDome::readStepsPerRevolution()
515 char res[DRIVER_LEN] = {0};
516 if (sendCommand(
"ENCREV", res) ==
false)
526 bool RigelDome::readBatteryLevels()
528 char res[DRIVER_LEN] = {0};
529 if (sendCommand(
"BAT", res) ==
false)
535 if (sscanf(res,
"%d %lf", &percent, &volts) != 2)
538 char levels[DRIVER_LEN] = {0};
539 snprintf(levels, DRIVER_LEN,
"%.2fv (%d%%)", volts / 1000.0, percent);
547 bool RigelDome::readPosition()
549 char res[DRIVER_LEN] = {0};
550 if (sendCommand(
"ANGLE", res) ==
false)
557 bool RigelDome::readHomePosition()
559 char res[DRIVER_LEN] = {0};
561 if (sendCommand(
"HOME", res) ==
false)
564 HomePositionN[0].value = std::stod(res);
571 bool RigelDome::setParkAz(
double az)
573 char cmd[DRIVER_LEN] = {0}, res[DRIVER_LEN] = {0};
575 snprintf(
cmd, DRIVER_LEN,
"PARK %3.1f", az);
576 if (sendCommand(
cmd, res) ==
false)
579 return res[0] ==
'A';
585 bool RigelDome::readState()
587 char res[DRIVER_LEN] = {0};
588 if (sendCommand(
"V", res) ==
false)
591 std::vector<std::string> fields = split(res,
"\t");
592 if (fields.size() < 13)
630 bool RigelDome::readShutterStatus()
632 char res[DRIVER_LEN] = {0};
633 if (sendCommand(
"SHUTTER", res) ==
false)
643 bool RigelDome::readFirmware()
645 char res[DRIVER_LEN] = {0};
647 if (sendCommand(
"VER", res) ==
false)
658 bool RigelDome::readModel()
660 char res[DRIVER_LEN] = {0};
662 if (sendCommand(
"PULSAR", res) ==
false)
673 bool RigelDome::sendCommand(
const char *
cmd,
char * res,
int cmd_len,
int res_len)
675 int nbytes_written = 0, nbytes_read = 0, rc = -1;
677 tcflush(
PortFD, TCIOFLUSH);
681 char hex_cmd[DRIVER_LEN * 3] = {0};
682 hexDump(hex_cmd,
cmd, cmd_len);
690 char formatted_command[DRIVER_LEN] = {0};
691 snprintf(formatted_command, DRIVER_LEN,
"%s\r",
cmd);
699 LOGF_ERROR(
"Serial write error: %s.", errstr);
707 rc =
tty_read(
PortFD, res, res_len, DRIVER_TIMEOUT, &nbytes_read);
721 char hex_res[DRIVER_LEN * 3] = {0};
722 hexDump(hex_res, res, res_len);
728 res[nbytes_read - 1] = 0;
732 tcflush(
PortFD, TCIOFLUSH);
740 void RigelDome::hexDump(
char * buf,
const char * data,
int size)
742 for (
int i = 0; i < size; i++)
743 sprintf(buf + 3 * i,
"%02X ",
static_cast<uint8_t
>(data[i]));
746 buf[3 * size - 1] =
'\0';
752 std::vector<std::string> RigelDome::split(
const std::string &input,
const std::string ®ex)
755 std::regex re(regex);
756 std::sregex_token_iterator
757 first{input.begin(), input.end(), re, -1},
759 return {first, last};
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 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 SetParked(bool isparked)
SetParked Change the mount parking status. The data park file (stored in ~/.indi/ParkData....
void SetDomeCapability(uint32_t cap)
SetDomeCapability set the dome capabilities. All capabilities must be initialized.
void SetAxis1Park(double value)
SetRAPark Set current AZ parking position. The data park file (stored in ~/.indi/ParkData....
void SetAxis1ParkDefault(double steps)
SetAxis1Park Set default AZ parking position.
ShutterOperation
Shutter operation command.
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
INumberVectorProperty DomeAbsPosNP
uint32_t GetDomeCapability() const
GetDomeCapability returns the capability of the dome.
ISwitchVectorProperty DomeShutterSP
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.
void setShutterState(const ShutterState &value)
void setDomeState(const DomeState &value)
bool InitPark()
InitPark Loads parking data (stored in ~/.indi/ParkData.xml) that contains parking status and parking...
Connection::Serial * serialConnection
void SetParkDataType(DomeParkData type)
setParkDataType Sets the type of parking data stored in the park data file and presented to the user.
ShutterState getShutterState() const
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
DomeState getDomeState() const
virtual bool SetCurrentPark() override
SetCurrentPark Set current coordinates/encoders value as the desired parking position.
virtual bool SetDefaultPark() override
SetDefaultPark Set default coordinates/encoders value as the desired parking position.
virtual IPState ControlShutter(ShutterOperation operation) override
Open or Close shutter.
virtual IPState UnPark() override
UnPark dome. The action of the Unpark command is dome specific, but it may include opening the shutte...
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual void TimerHit() override
Callback function to be called once SetTimer duration elapses.
virtual bool Sync(double az) override
Sync sets the dome current azimuth as the supplied azimuth position.
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
virtual IPState Move(DomeDirection dir, DomeMotionCommand operation) override
Move the Dome in a particular direction.
virtual IPState MoveAbs(double az) override
Move the Dome to an absolute azimuth.
virtual bool Abort() override
Abort all dome motion.
virtual IPState Park() override
Goto Park Position. The park position is an absolute azimuth value.
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
virtual const char * getDefaultName() override
virtual IPState MoveRel(double azDiff) override
Move the Dome to an relative position.
virtual bool Handshake() override
perform handshake with device to check communication
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
const char * SITE_TAB
SITE_TAB Where all site information setting 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.
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 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.
const char * IUFindOnSwitchName(ISState *states, char *names[], int n)
Returns the name of the first ON switch it finds in the supplied arguments.
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.
void IDSetNumber(const INumberVectorProperty *nvp, const char *fmt,...)
void IDSetSwitch(const ISwitchVectorProperty *svp, const char *fmt,...)
int IUUpdateNumber(INumberVectorProperty *nvp, double values[], char *names[], int n)
Update all numbers in a number vector property.
void IDSetText(const ITextVectorProperty *tvp, const char *fmt,...)
#define LOGF_INFO(fmt,...)
#define LOGF_DEBUG(fmt,...)
#define LOGF_ERROR(fmt,...)