32static std::unique_ptr<DomePro2> domepro2(
new DomePro2());
50 VersionTP[VERSION_FIRMWARE].
fill(
"VERSION_FIRMWARE",
"Firmware",
"NA");
51 VersionTP[VERSION_HARDWARE].
fill(
"VERSION_HARDWARE",
"Hardware",
"NA");
55 StatusTP[STATUS_DOME].
fill(
"STATUS_DOME",
"Dome",
"NA");
56 StatusTP[STATUS_SHUTTER].
fill(
"STATUS_SHUTTER",
"Shutter",
"NA");
60 SettingsNP[SETTINGS_AZ_CPR].
fill(
"SETTINGS_AZ_CPR",
"Az CPR (steps)",
"%.f", 0x20, 0x40000000, 0, 0);
61 SettingsNP[SETTINGS_AZ_COAST].
fill(
"SETTINGS_AZ_COAST",
"Az Coast (deg)",
"%.2f", 0, 15, 0, 0);
62 SettingsNP[SETTINGS_AZ_HOME].
fill(
"SETTINGS_AZ_HOME",
"Az Home (deg)",
"%.2f", 0, 360, 0, 0);
63 SettingsNP[SETTINGS_AZ_PARK].
fill(
"SETTINGS_AZ_PARK",
"Az Park (deg)",
"%.2f", 0, 360, 0, 0);
64 SettingsNP[SETTINGS_AZ_STALL_COUNT].
fill(
"SETTINGS_AZ_STALL_COUNT",
"Az Stall Count (steps)",
"%.f", 0, 0x40000000,
69 HomeSP[HOME_DISCOVER].
fill(
"HOME_DISCOVER",
"Discover",
ISS_OFF);
70 HomeSP[HOME_GOTO].
fill(
"HOME_GOTO",
"Goto",
ISS_OFF);
84bool DomePro2::setupInitialParameters()
98 if (getFirmwareVersion() && getHardwareConfig())
101 if (getDomeStatus() && getShutterStatus())
104 if (getDomeAzCPR() && getDomeAzCoast() && getDomeHomeAz() && getDomeParkAz() && getDomeAzStallCount())
118 return getFirmwareVersion();
138 setupInitialParameters();
167 for (
size_t i = 0; i < HomeSP.
count(); i++)
172 if (HomeSP[HOME_GOTO].isNameMatch(names[i]))
174 if (!gotoHomeDomeAz())
177 LOG_ERROR(
"Failed to go to Home Dome Az.");
185 else if (HomeSP[HOME_DISCOVER].isNameMatch(names[i]))
187 if (!discoverHomeDomeAz())
190 LOG_ERROR(
"Failed to discover Home Dome Az.");
223 for (
size_t i = 0; i < SettingsNP.
count(); i++)
225 if (SettingsNP[SETTINGS_AZ_CPR].isNameMatch(names[i]))
227 if (setDomeAzCPR(
static_cast<uint32_t
>(values[i])))
228 SettingsNP[SETTINGS_AZ_CPR].setValue(values[i]);
235 else if (SettingsNP[SETTINGS_AZ_COAST].isNameMatch(names[i]))
237 if (setDomeAzCoast(
static_cast<uint32_t
>(values[i])))
238 SettingsNP[SETTINGS_AZ_COAST].setValue(values[i]);
242 LOG_ERROR(
"Failed to set Dome AZ Coast.");
245 else if (SettingsNP[SETTINGS_AZ_HOME].isNameMatch(names[i]))
247 if (setDomeHomeAz(
static_cast<uint32_t
>(values[i])))
248 SettingsNP[SETTINGS_AZ_HOME].setValue(values[i]);
252 LOG_ERROR(
"Failed to set Dome AZ Home.");
255 else if (SettingsNP[SETTINGS_AZ_PARK].isNameMatch(names[i]))
257 if (setDomeParkAz(
static_cast<uint32_t
>(values[i])))
258 SettingsNP[SETTINGS_AZ_PARK].setValue(values[i]);
262 LOG_ERROR(
"Failed to set Dome AZ Park.");
265 else if (SettingsNP[SETTINGS_AZ_STALL_COUNT].isNameMatch(names[i]))
267 if (setDomeAzStallCount(
static_cast<uint32_t
>(values[i])))
268 SettingsNP[SETTINGS_AZ_STALL_COUNT].setValue(values[i]);
272 LOG_ERROR(
"Failed to set Dome AZ Stall Count.");
296 if(getDomeAzPos() && std::abs(currentAz -
DomeAbsPosNP[0].getValue()) > DOME_AZ_THRESHOLD)
299 std::string domeStatus = StatusTP[STATUS_DOME].
getText();
300 std::string shutterStatus = StatusTP[STATUS_SHUTTER].
getText();
301 if(getDomeStatus() && getShutterStatus() && (strcmp(domeStatus.c_str(), StatusTP[STATUS_DOME].
getText()) != 0 ||
302 strcmp(shutterStatus.c_str(), StatusTP[STATUS_DOME].
getText()) != 0))
307 if (StatusTP[STATUS_DOME].isNameMatch(
"Idle"))
325 int statusVal = processShutterStatus();
326 if (statusVal == 0x00)
328 else if (statusVal == 0x01)
330 else if ((statusVal >= 0x04 && statusVal <= 12) || statusVal >= 15)
332 else if (statusVal == 0x13)
348 uint32_t steps =
static_cast<uint32_t
>(az * (SettingsNP[SETTINGS_AZ_CPR].getValue() / 360));
349 if (gotoDomeAz(steps))
376 if(calibrateDomeAz(az))
390 if(killDomeAzMovement())
432 if (openDomeShutters())
437 if (closeDomeShutters())
448 if (!killDomeAzMovement())
503uint8_t DomePro2::processShutterStatus()
505 if (StatusTP[STATUS_SHUTTER].isNameMatch(
"Opened"))
507 else if (StatusTP[STATUS_SHUTTER].isNameMatch(
"Closed"))
509 else if (StatusTP[STATUS_SHUTTER].isNameMatch(
"Opening"))
511 else if (StatusTP[STATUS_SHUTTER].isNameMatch(
"Closing"))
513 else if (StatusTP[STATUS_SHUTTER].isNameMatch(
"ShutterError"))
515 else if (StatusTP[STATUS_SHUTTER].isNameMatch(
"shutter module is not communicating to the azimuth module"))
517 else if (StatusTP[STATUS_SHUTTER].isNameMatch(
"shutter 1 opposite direction timeout error on open occurred"))
519 else if (StatusTP[STATUS_SHUTTER].isNameMatch(
"shutter 1 opposite direction timeout error on close occurred"))
521 else if (StatusTP[STATUS_SHUTTER].isNameMatch(
"shutter 2 opposite direction timeout error on open occurred"))
523 else if (StatusTP[STATUS_SHUTTER].isNameMatch(
"shutter 2 opposite direction timeout error on close occurred"))
525 else if (StatusTP[STATUS_SHUTTER].isNameMatch(
"shutter 1 completion timeout error on open occurred"))
527 else if (StatusTP[STATUS_SHUTTER].isNameMatch(
"shutter 1 completion timeout error on close occurred"))
529 else if (StatusTP[STATUS_SHUTTER].isNameMatch(
"shutter 2 completion timeout error on open occurred"))
531 else if (StatusTP[STATUS_SHUTTER].isNameMatch(
"shutter 2 completion timeout error on close occurred"))
533 else if (StatusTP[STATUS_SHUTTER].isNameMatch(
"shutter 1 limit fault on open occurred"))
535 else if (StatusTP[STATUS_SHUTTER].isNameMatch(
"shutter 1 limit fault on close occurred"))
537 else if (StatusTP[STATUS_SHUTTER].isNameMatch(
"shutter 2 limit fault on open occurred"))
539 else if (StatusTP[STATUS_SHUTTER].isNameMatch(
"shutter 2 limit fault on close occurred"))
541 else if (StatusTP[STATUS_SHUTTER].isNameMatch(
"Shutter disabled (Shutter Enable input is not asserted)"))
543 else if (StatusTP[STATUS_SHUTTER].isNameMatch(
"Intermediate"))
545 else if (StatusTP[STATUS_SHUTTER].isNameMatch(
"GoTo"))
547 else if (StatusTP[STATUS_SHUTTER].isNameMatch(
"shutter 1 OCP trip on open occurred"))
549 else if (StatusTP[STATUS_SHUTTER].isNameMatch(
"shutter 1 OCP trip on close occurred"))
551 else if (StatusTP[STATUS_SHUTTER].isNameMatch(
"shutter 2 OCP trip on open occurred"))
553 else if (StatusTP[STATUS_SHUTTER].isNameMatch(
"shutter 2 OCP trip on close occurred"))
561bool DomePro2::getFirmwareVersion()
563 char res[DRIVER_LEN] = {0};
564 if (sendCommand(
"DGfv", res) ==
false)
568 if (sscanf(res,
"%X", &version) == 1)
570 char versionString[DRIVER_LEN] = {0};
571 snprintf(versionString, DRIVER_LEN,
"%d", version);
572 VersionTP[VERSION_FIRMWARE].setText(versionString);
582bool DomePro2::getHardwareConfig()
584 char res[DRIVER_LEN] = {0};
585 if (sendCommand(
"DGhc", res) ==
false)
589 if (sscanf(res,
"%X", &config) == 1)
591 char configString[DRIVER_LEN] = {0};
592 uint8_t index =
static_cast<uint8_t
>(config);
593 if (DomeHardware.count(index))
595 snprintf(configString, DRIVER_LEN,
"%s", DomeHardware.at(index).c_str());
596 VersionTP[VERSION_HARDWARE].setText(configString);
601 LOGF_WARN(
"Unknown model detected %d", config);
613bool DomePro2::getDomeStatus()
615 char res[DRIVER_LEN] = {0};
616 if (sendCommand(
"DGam", res) ==
false)
619 if (DomeStatus.count(res))
621 StatusTP[STATUS_DOME].setText(DomeStatus.at(res).c_str());
626 LOGF_WARN(
"Unknown dome status detected %d", res);
634bool DomePro2::getShutterStatus()
636 char res[DRIVER_LEN] = {0};
637 if (sendCommand(
"DGsx", res) ==
false)
641 if (sscanf(res,
"%X", &status) == 1)
643 char statusString[DRIVER_LEN] = {0};
644 uint8_t index =
static_cast<uint8_t
>(status);
645 if (ShutterStatus.count(index))
647 snprintf(statusString, DRIVER_LEN,
"%s", ShutterStatus.at(index).c_str());
648 StatusTP[STATUS_SHUTTER].setText(statusString);
653 LOGF_WARN(
"Unknown shutter status detected %d", status);
665bool DomePro2::getDomeAzCPR()
667 char res[DRIVER_LEN] = {0};
668 if (sendCommand(
"DGcp", res) ==
false)
672 if (sscanf(res,
"%X", &cpr) == 1)
674 SettingsNP[SETTINGS_AZ_CPR].setValue(cpr);
684bool DomePro2::setDomeAzCPR(uint32_t cpr)
686 char cmd[DRIVER_LEN] = {0};
687 if (cpr < 0x20 || cpr > 0x40000000)
689 LOG_ERROR(
"CPR value out of bounds (32 to 1,073,741,824)");
692 else if (cpr % 2 != 0)
694 LOG_ERROR(
"CPR value must be an even number");
697 snprintf(
cmd, DRIVER_LEN,
"DScp0x%08X", cpr);
698 if (sendCommand(
cmd) ==
false)
706bool DomePro2::getDomeAzCoast()
708 char res[DRIVER_LEN] = {0};
709 if (sendCommand(
"DGco", res) ==
false)
713 if (sscanf(res,
"%X", &coast) == 1)
715 SettingsNP[SETTINGS_AZ_COAST].setValue(coast * (360 / SettingsNP[SETTINGS_AZ_CPR].getValue()));
725bool DomePro2::setDomeAzCoast(uint32_t az)
727 char cmd[DRIVER_LEN] = {0};
728 uint32_t steps =
static_cast<uint32_t
>(az * (SettingsNP[SETTINGS_AZ_CPR].getValue() / 360));
734 snprintf(
cmd, DRIVER_LEN,
"DSco0x%08X", steps);
735 if (sendCommand(
cmd) ==
false)
743bool DomePro2::getDomeHomeAz()
745 char res[DRIVER_LEN] = {0};
746 if (sendCommand(
"DGha", res) ==
false)
750 if (sscanf(res,
"%X", &home) == 1)
752 SettingsNP[SETTINGS_AZ_HOME].setValue(home * (360 / SettingsNP[SETTINGS_AZ_CPR].getValue()));
762bool DomePro2::setDomeHomeAz(uint32_t az)
764 char cmd[DRIVER_LEN] = {0};
765 uint32_t steps =
static_cast<uint32_t
>(az * (SettingsNP[SETTINGS_AZ_CPR].getValue() / 360));
774 snprintf(
cmd, DRIVER_LEN,
"DSha0x%08X", steps);
775 if (sendCommand(
cmd) ==
false)
783bool DomePro2::getDomeParkAz()
785 char res[DRIVER_LEN] = {0};
786 if (sendCommand(
"DGpa", res) ==
false)
790 if (sscanf(res,
"%X", &park) == 1)
792 SettingsNP[SETTINGS_AZ_PARK].setValue(park * (360 / SettingsNP[SETTINGS_AZ_CPR].getValue()));
802bool DomePro2::setDomeParkAz(uint32_t az)
804 char cmd[DRIVER_LEN] = {0};
805 uint32_t steps =
static_cast<uint32_t
>(az * (SettingsNP[SETTINGS_AZ_CPR].getValue() / 360));
814 snprintf(
cmd, DRIVER_LEN,
"DSpa0x%08X", steps);
815 if (sendCommand(
cmd) ==
false)
823bool DomePro2::calibrateDomeAz(
double az)
825 char cmd[DRIVER_LEN] = {0};
826 uint32_t steps =
static_cast<uint32_t
>(az * (SettingsNP[SETTINGS_AZ_CPR].getValue() / 360));
834 snprintf(
cmd, DRIVER_LEN,
"DSca0x%08X", steps);
835 if (sendCommand(
cmd) ==
false)
843bool DomePro2::getDomeAzStallCount()
845 char res[DRIVER_LEN] = {0};
846 if (sendCommand(
"DGas", res) ==
false)
850 if (sscanf(res,
"%X", &count) == 1)
852 SettingsNP[SETTINGS_AZ_STALL_COUNT].setValue(count);
862bool DomePro2::setDomeAzStallCount(uint32_t count)
864 char cmd[DRIVER_LEN] = {0};
865 snprintf(
cmd, DRIVER_LEN,
"DSha0x%08X", count);
866 if (sendCommand(
cmd) ==
false)
874bool DomePro2::getDomeAzPos()
876 char res[DRIVER_LEN] = {0};
877 if (sendCommand(
"DGap", res) ==
false)
881 if (sscanf(res,
"%X", &pos) == 1)
883 DomeAbsPosNP[0].setValue(pos * (360 / SettingsNP[SETTINGS_AZ_CPR].getValue()));
893bool DomePro2::gotoDomeAz(uint32_t az)
895 char cmd[DRIVER_LEN] = {0};
896 if (az >= SettingsNP[SETTINGS_AZ_CPR].getValue())
898 snprintf(
cmd, DRIVER_LEN,
"DSgo0x%08X", az);
899 if (sendCommand(
cmd) ==
false)
907bool DomePro2::gotoDomePark()
909 if (sendCommand(
"DSgp") ==
false)
917bool DomePro2::killDomeAzMovement()
919 if (sendCommand(
"DXxa") ==
false)
927bool DomePro2::killDomeShutterMovement()
929 if (sendCommand(
"DXxs") ==
false)
937bool DomePro2::openDomeShutters()
939 if (sendCommand(
"DSso") ==
false)
947bool DomePro2::closeDomeShutters()
949 if (sendCommand(
"DSsc") ==
false)
957bool DomePro2::gotoHomeDomeAz()
959 if (sendCommand(
"DSah") ==
false)
967bool DomePro2::discoverHomeDomeAz()
969 if (sendCommand(
"DSdh") ==
false)
977bool DomePro2::setDomeLeftOn()
979 if (sendCommand(
"DSol") ==
false)
987bool DomePro2::setDomeRightOn()
989 if (sendCommand(
"DSor") ==
false)
997bool DomePro2::sendCommand(
const char *
cmd,
char * res,
int cmd_len,
int res_len)
999 int nbytes_written = 0, nbytes_read = 0, rc = -1;
1001 tcflush(
PortFD, TCIOFLUSH);
1005 char hex_cmd[DRIVER_LEN * 3] = {0};
1006 hexDump(hex_cmd,
cmd, cmd_len);
1014 char formatted_command[DRIVER_LEN] = {0};
1015 snprintf(formatted_command, DRIVER_LEN,
"!%s;",
cmd);
1023 LOGF_ERROR(
"Serial write error: %s.", errstr);
1031 rc =
tty_read(
PortFD, res, res_len, DRIVER_TIMEOUT, &nbytes_read);
1039 LOGF_ERROR(
"Serial read error: %s.", errstr);
1045 char hex_res[DRIVER_LEN * 3] = {0};
1046 hexDump(hex_res, res, res_len);
1052 res[nbytes_read - 1] = 0;
1056 tcflush(
PortFD, TCIOFLUSH);
1064void DomePro2::hexDump(
char * buf,
const char * data,
int size)
1066 for (
int i = 0; i < size; i++)
1067 sprintf(buf + 3 * i,
"%02X ",
static_cast<uint8_t
>(data[i]));
1070 buf[3 * size - 1] =
'\0';
1076std::vector<std::string> DomePro2::split(
const std::string &input,
const std::string ®ex)
1079 std::regex re(regex);
1080 std::sregex_token_iterator
1081 first{input.begin(), input.end(), re, -1},
1083 return {first, last};
void setDefaultBaudRate(BaudRate newRate)
setDefaultBaudRate Set default baud rate. The default baud rate is 9600 unless otherwise changed by t...
virtual void TimerHit() override
Callback function to be called once SetTimer duration elapses.
virtual IPState UnPark() override
UnPark dome. The action of the Unpark command is dome specific, but it may include opening the shutte...
virtual IPState ControlShutter(ShutterOperation operation) override
Open or Close shutter.
virtual bool Sync(double az) override
Sync sets the dome current azimuth as the supplied azimuth position.
virtual const char * getDefaultName() override
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual bool SetCurrentPark() override
SetCurrentPark Set current coordinates/encoders value as the desired parking position.
virtual IPState MoveRel(double azDiff) override
Move the Dome to an relative position.
virtual IPState MoveAbs(double az) override
Move the Dome to an absolute azimuth.
virtual bool initProperties() override
Initialize properties initial state and value. The child class must implement this function.
virtual bool SetDefaultPark() override
SetDefaultPark Set default coordinates/encoders value as the desired parking position.
virtual IPState Move(DomeDirection dir, DomeMotionCommand operation) override
Move the Dome in a particular direction.
virtual bool Handshake() override
perform handshake with device to check communication
virtual bool Abort() override
Abort all dome motion.
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Saves the Device Port and Dome Presets in the configuration file
virtual IPState Park() override
Goto Park Position. The park position is an absolute azimuth value.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
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.
ShutterState m_ShutterState
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
Initialize properties initial state and value. The child class must implement this function.
INDI::PropertySwitch ParkSP
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
INDI::PropertyNumber DomeAbsPosNP
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 Device Port and Dome Presets in the configuration file
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
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
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)
INDI::PropertyViewText * getText() const
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_WARN(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,...)