25 #include <libnova/transform.h>
26 #include <libnova/precession.h>
29 #include <libnova/utility.h>
38 constexpr uint16_t SynscanDriver::SIM_SLEW_RATE[];
44 m_MountInfo.push_back(
"--");
45 m_MountInfo.push_back(
"--");
46 m_MountInfo.push_back(
"--");
47 m_MountInfo.push_back(
"--");
48 m_MountInfo.push_back(
"--");
83 IUFillText(&StatusT[MI_FW_VERSION],
"MI_FW_VERSION",
"Firmware",
"-");
84 IUFillText(&StatusT[MI_MOUNT_MODEL],
"MI_MOUNT_MODEL",
"Model",
"-");
85 IUFillText(&StatusT[MI_GOTO_STATUS],
"MI_GOTO_STATUS",
"Goto",
"-");
86 IUFillText(&StatusT[MI_POINT_STATUS],
"MI_POINT_STATUS",
"Pointing",
"-");
87 IUFillText(&StatusT[MI_TRACK_MODE],
"MI_TRACK_MODE",
"Tracking Mode",
"-");
94 IUFillNumber(&CustomSlewRateN[
AXIS_RA],
"AXIS1",
"RA/AZ (arcsecs/s)",
"%.2f", 0.05, 800, 10, 0);
95 IUFillNumber(&CustomSlewRateN[
AXIS_DE],
"AXIS2",
"DE/AL (arcsecs/s)",
"%.2f", 0.05, 800, 10, 0);
187 void SynscanDriver::setupParams()
197 int SynscanDriver::hexStrToInteger(
const std::string &res)
203 result = std::stoi(res,
nullptr, 16);
205 catch (std::invalid_argument &)
207 LOGF_ERROR(
"Failed to parse %s to integer.", res.c_str());
215 char res[SYN_RES] = {0};
220 if (!sendCommand(
"J", res))
225 LOG_ERROR(
"Mount is not aligned. Please align the mount first and connect again.");
244 if (strcmp(name,
"GUIDE_RATE") == 0)
253 if (strcmp(name, CustomSlewRateNP.
name) == 0)
257 LOG_ERROR(
"Cannot change rate while slewing.");
270 if (!strcmp(name, HorizontalCoordsNP.
name))
274 LOG_WARN(
"Unpark mount before issuing GOTO commands.");
281 double newAlt = 0, newAz = 0;
282 for (
int i = 0; i < n; i++)
285 if (horp == &HorizontalCoordsN[
AXIS_AZ])
288 nset += newAz >= 0. && newAz <= 360.0;
290 else if (horp == &HorizontalCoordsN[
AXIS_ALT])
293 nset += newAlt >= -90. && newAlt <= 90.0;
297 if (nset == 2 &&
GotoAzAlt(newAz, newAlt))
301 IDSetNumber(&HorizontalCoordsNP,
"Altitude or Azimuth missing or invalid.");
322 if (svp.isNameMatch(GotoModeSP.
name))
324 svp.update(states, names, n);
325 auto sp = svp.findOnSwitch();
327 assert(sp !=
nullptr);
329 if (sp->isNameMatch(GotoModeS[0].name))
341 bool SynscanDriver::echo()
343 char res[SYN_RES] = {0};
344 return sendCommand(
"Kx", res);
347 bool SynscanDriver::readFirmware()
350 char res[SYN_RES] = {0};
351 if (sendCommand(
"V", res))
353 m_FirmwareVersion =
static_cast<double>(hexStrToInteger(std::string(&res[0], 2)));
354 m_FirmwareVersion +=
static_cast<double>(hexStrToInteger(std::string(&res[2], 2))) / 100;
355 m_FirmwareVersion +=
static_cast<double>(hexStrToInteger(std::string(&res[4], 2))) / 10000;
357 LOGF_INFO(
"Firmware version: %lf", m_FirmwareVersion);
359 IUSaveText(&StatusT[MI_FW_VERSION], m_MountInfo[MI_FW_VERSION].c_str());
361 if (m_FirmwareVersion < 3.38 || (m_FirmwareVersion >= 4.0 && m_FirmwareVersion < 4.38))
363 LOGF_WARN(
"Firmware version is too old. Update Synscan firmware to %s",
364 m_FirmwareVersion < 3.38 ?
"v3.38+" :
"v4.38+");
371 LOG_WARN(
"Firmware version is too old. Update Synscan firmware to v4.38+");
376 bool SynscanDriver::readTracking()
379 char res[SYN_RES] = {0};
380 if (sendCommand(
"t", res))
383 m_TrackingFlag = res[0];
396 m_MountInfo[MI_TRACK_MODE] =
"Tracking off";
399 m_MountInfo[MI_TRACK_MODE] =
"Alt/Az tracking";
402 m_MountInfo[MI_TRACK_MODE] =
"EQ tracking";
405 m_MountInfo[MI_TRACK_MODE] =
"PEC mode";
415 bool SynscanDriver::readModel()
418 std::map<int, std::string> models =
420 {0,
"EQ6 GOTO Series"},
421 {1,
"HEQ5 GOTO Series"},
422 {2,
"EQ5 GOTO Series"},
423 {3,
"EQ3 GOTO Series"},
424 {4,
"EQ8 GOTO Series"},
425 {5,
"AZ-EQ6 GOTO Series"},
426 {6,
"AZ-EQ5 GOTO Series"},
427 {160,
"AllView GOTO Series"},
428 {161,
"Virtuoso Alt/Az mount"},
429 {165,
"AZ-GTi GOTO Series"}
433 char res[SYN_RES] = {0};
435 if (!sendCommand(
"m", res))
438 m_MountModel = res[0];
441 if (m_MountModel >= 128 && m_MountModel <= 143)
442 IUSaveText(&StatusT[MI_MOUNT_MODEL],
"AZ GOTO Series");
444 else if (m_MountModel >= 144 && m_MountModel <= 159)
445 IUSaveText(&StatusT[MI_MOUNT_MODEL],
"Dob GOTO Series");
446 else if (models.count(m_MountModel) > 0)
447 IUSaveText(&StatusT[MI_MOUNT_MODEL], models[m_MountModel].c_str());
449 IUSaveText(&StatusT[MI_MOUNT_MODEL],
"Unknown model");
451 m_isAltAz = m_MountModel > 4;
453 LOGF_INFO(
"Driver is running in %s mode.", m_isAltAz ?
"Alt-Az" :
"Equatorial");
454 LOGF_INFO(
"Detected mount: %s. Mount must be aligned from the handcontroller before using the driver.",
455 StatusT[MI_MOUNT_MODEL].text);
468 char res[SYN_RES] = {0};
471 if (sendCommand(
"L", res))
472 m_MountInfo[MI_GOTO_STATUS] = res[0];
475 if (m_isAltAz ==
false && sendCommand(
"p", res))
477 m_MountInfo[MI_POINT_STATUS] = res[0];
486 if (isSlewComplete())
495 if (isSlewComplete())
513 memset(res, 0, SYN_RES);
514 if (!sendCommand(
"e", res))
517 uint32_t n1 = 0, n2 = 0;
518 sscanf(res,
"%x,%x#", &n1, &n2);
519 double ra =
static_cast<double>(n1) / 0x100000000 * 360.0;
520 double de =
static_cast<double>(n2) / 0x100000000 * 360.0;
524 J2000Pos.declination =
rangeDec(de);
529 CurrentRA = epochPos.rightascension;
530 CurrentDE = epochPos.declination;
533 fs_sexa(Axis1Coords, J2000Pos.rightascension, 2, 3600);
534 fs_sexa(Axis2Coords, J2000Pos.declination, 2, 3600);
535 LOGF_DEBUG(
"J2000 RA <%s> DE <%s>", Axis1Coords, Axis2Coords);
538 fs_sexa(Axis1Coords, CurrentRA, 2, 3600);
539 fs_sexa(Axis2Coords, CurrentDE, 2, 3600);
540 LOGF_DEBUG(
"JNOW RA <%s> DE <%s>", Axis1Coords, Axis2Coords);
546 memset(res, 0, SYN_RES);
547 if (!sendCommand(
"z", res))
550 sscanf(res,
"%x,%x#", &n1, &n2);
551 double az =
static_cast<double>(n1) / 0x100000000 * 360.0;
552 double al =
static_cast<double>(n2) / 0x100000000 * 360.0;
555 HorizontalCoordsN[
AXIS_AZ].value = az;
556 HorizontalCoordsN[
AXIS_ALT].value = al;
560 fs_sexa(Axis1Coords, az, 2, 3600);
561 fs_sexa(Axis2Coords, al, 2, 3600);
562 LOGF_DEBUG(
"AZ <%s> ALT <%s>", Axis1Coords, Axis2Coords);
571 char cmd[SYN_RES] = {0}, res[SYN_RES] = {0};
578 return sendCommand(
cmd, res, 2);
583 char cmd[SYN_RES] = {0}, res[SYN_RES] = {0};
590 return sendCommand(
cmd, res);
593 bool SynscanDriver::SetAltAzMode(
bool enable)
625 char cmd[SYN_RES] = {0}, res[SYN_RES] = {0};
637 epochPos.declination =
dec;
640 if (goto_AltAz && m_isAltAz)
654 double dec_pos = J2000Pos.declination;
655 if (J2000Pos.declination < 0)
656 dec_pos = dec_pos + 360;
658 uint32_t n1 = J2000Pos.rightascension * 15.0 / 360 * 0x100000000;
659 uint32_t n2 = dec_pos / 360 * 0x100000000;
661 LOGF_DEBUG(
"Goto - JNow RA: %g JNow DE: %g J2000 RA: %g J2000 DE: %g",
ra,
dec, J2000Pos.rightascension,
662 J2000Pos.declination);
664 snprintf(
cmd, SYN_RES,
"r%08X,%08X", n1, n2);
665 if (sendCommand(
cmd, res, 18))
678 char cmd[SYN_RES] = {0}, res[SYN_RES] = {0};
683 if (m_isAltAz ==
false)
695 uint32_t n1 = az / 360.0 * 0x100000000;
696 uint32_t n2 = alt / 360.0 * 0x100000000;
698 LOGF_DEBUG(
"Goto - Az: %.2f Alt: %.2f", az, alt);
700 snprintf(
cmd, SYN_RES,
"b%08X,%08X", n1, n2);
701 if (sendCommand(
cmd, res, 18))
717 char AzStr[16], AltStr[16];
718 fs_sexa(AzStr, parkAZ, 2, 3600);
719 fs_sexa(AltStr, parkAlt, 2, 3600);
720 LOGF_DEBUG(
"Parking to Az (%s) Alt (%s)...", AzStr, AltStr);
725 LOG_INFO(
"Parking is in progress...");
742 char res[SYN_RES] = {0};
745 memset(res, 0, SYN_RES);
746 if (!sendCommand(
"z", res))
749 uint32_t n1 = 0, n2 = 0;
750 sscanf(res,
"%ux,%ux#", &n1, &n2);
751 double az =
static_cast<double>(n1) / 0x100000000 * 360.0;
752 double al =
static_cast<double>(n2) / 0x100000000 * 360.0;
755 char AzStr[16], AltStr[16];
759 LOGF_DEBUG(
"Setting current parking position to coordinates Az (%s) Alt (%s)...", AzStr, AltStr);
770 LOG_DEBUG(
"Setting Park Data to Default.");
808 double customRate = CustomSlewRateN[
AXIS_DE].value;
811 if (m_CustomGuideDE > 0)
814 customRate = m_CustomGuideDE;
820 rc = (rate < 10) ? slewFixedRate(move, rate) : slewVariableRate(move, customRate);
823 LOG_ERROR(
"Error setting N/S motion direction.");
827 else if (!m_CustomGuideDE)
828 LOGF_INFO(
"Moving toward %s.", (move ==
SYN_N) ?
"North" :
"South");
832 if (slewFixedRate(move, 0) ==
false)
837 else if (!m_CustomGuideDE)
838 LOGF_INFO(
"Movement toward %s halted.", (move ==
SYN_N) ?
"North" :
"South");
853 double customRate = CustomSlewRateN[
AXIS_RA].value;
856 if (m_CustomGuideRA > 0)
859 customRate = m_CustomGuideRA;
865 rc = (rate < 10) ? slewFixedRate(move, rate) : slewVariableRate(move, customRate);
868 LOG_ERROR(
"Error setting W/E motion direction.");
872 else if (!m_CustomGuideRA)
873 LOGF_INFO(
"Moving toward %s.", (move ==
SYN_W) ?
"West" :
"East");
877 if (slewFixedRate(move, 0) ==
false)
882 else if (!m_CustomGuideRA)
883 LOGF_INFO(
"Movement toward %s halted.", (move ==
SYN_W) ?
"West" :
"East");
892 m_TargetSlewRate = s + 1;
897 bool SynscanDriver::passThruCommand(
int cmd,
int target,
int msgsize,
int data,
int numReturn)
900 int bytesRead, bytesWritten;
932 retval = retval << 8;
937 retval = retval << 8;
947 bool SynscanDriver::sendTime()
954 time_t now = time (
nullptr);
955 strftime(timeString,
MAXINDINAME,
"%T", gmtime(&now));
963 char res[SYN_RES] = {0};
964 if (sendCommand(
"h", res))
966 ln_zonedate localTime;
968 int offset, daylightflag;
970 localTime.hours = res[0];
971 localTime.minutes = res[1];
972 localTime.seconds = res[2];
973 localTime.months = res[3];
974 localTime.days = res[4];
975 localTime.years = res[5];
976 offset =
static_cast<int>(res[6]);
980 localTime.gmtoff = offset;
982 daylightflag = res[7];
983 localTime.years += 2000;
984 localTime.gmtoff *= 3600;
986 ln_zonedate_to_date(&localTime, &utcTime);
992 sec =
static_cast<int>(utcTime.seconds);
993 sprintf(utc,
"%04d-%02d-%dT%d:%02d:%02d", utcTime.years, utcTime.months, utcTime.days, utcTime.hours,
994 utcTime.minutes, sec);
995 if (daylightflag == 1)
997 sprintf(ofs,
"%d", offset);
1004 LOGF_INFO(
"Mount UTC Time %s Offset %d", utc, offset);
1011 bool SynscanDriver::sendLocation()
1013 char res[SYN_RES] = {0};
1025 if (!sendCommand(
"w", res))
1030 int a, b, c, d, e, f, g, h;
1066 char LongitudeStr[32] = {0}, LatitudeStr[32] = {0};
1067 fs_sexa(LongitudeStr, lon, 2, 3600);
1068 fs_sexa(LatitudeStr, lat, 2, 3600);
1069 LOGF_INFO(
"Mount Longitude %s Latitude %s", LongitudeStr, LatitudeStr);
1076 char cmd[SYN_RES] = {0}, res[SYN_RES] = {0};
1080 struct ln_zonedate ltm;
1082 ln_date_to_zonedate(utc, <m, utc_offset * 3600.0);
1090 cmd[2] = ltm.minutes;
1091 cmd[3] =
static_cast<char>(ltm.seconds);
1092 cmd[4] = ltm.months;
1096 cmd[7] = utc_offset > 0 ?
static_cast<uint8_t
>(utc_offset) :
static_cast<uint8_t
>(256 + utc_offset);
1100 LOGF_INFO(
"Setting mount date/time to %04d-%02d-%02d %d:%02d:%02d UTC Offset: %.2f",
1101 ltm.years, ltm.months, ltm.days, ltm.hours, ltm.minutes,
static_cast<int>(rint(ltm.seconds)), utc_offset);
1106 return sendCommand(
cmd, res, 9);
1112 char cmd[SYN_RES] = {0}, res[SYN_RES] = {0};
1113 bool IsWest =
false;
1115 ln_lnlat_posn p1 { 0, 0 };
1126 CurrentDE = latitude > 0 ? 90 : -90;
1132 if (longitude > 180)
1134 p1.lng = 360.0 - longitude;
1142 ln_lnlat_to_hlnlat(&p1, &p2);
1143 LOGF_INFO(
"Update location to latitude %d:%d:%1.2f longitude %d:%d:%1.2f",
1144 p2.lat.degrees, p2.lat.minutes, p2.lat.seconds, p2.lng.degrees, p2.lng.minutes, p2.lng.seconds);
1147 cmd[1] = p2.lat.degrees;
1148 cmd[2] = p2.lat.minutes;
1149 cmd[3] = rint(p2.lat.seconds);
1150 cmd[4] = (p2.lat.neg == 0) ? 0 : 1;
1151 cmd[5] = p2.lng.degrees;
1152 cmd[6] = p2.lng.minutes;
1153 cmd[7] = rint(p2.lng.seconds);
1154 cmd[8] = IsWest ? 1 : 0;
1156 return sendCommand(
cmd, res, 9);
1161 char cmd[SYN_RES] = {0}, res[SYN_RES] = {0};
1172 epochPos.declination =
dec;
1178 uint32_t n1 = J2000Pos.rightascension * 15.0 / 360 * 0x100000000;
1179 uint32_t n2 = J2000Pos.declination / 360 * 0x100000000;
1181 LOGF_DEBUG(
"Sync - JNow RA: %g JNow DE: %g J2000 RA: %g J2000 DE: %g",
ra,
dec, J2000Pos.rightascension,
1182 J2000Pos.declination);
1184 snprintf(
cmd, SYN_RES,
"s%08X,%08X", n1, n2);
1185 return sendCommand(
cmd, res, 18);
1188 void SynscanDriver::sendStatus()
1190 bool BasicMountInfoHasChanged =
false;
1192 if (std::string(StatusT[MI_GOTO_STATUS].text) != m_MountInfo[MI_GOTO_STATUS])
1194 IUSaveText(&StatusT[MI_GOTO_STATUS], m_MountInfo[MI_GOTO_STATUS].c_str());
1195 BasicMountInfoHasChanged =
true;
1197 if (std::string(StatusT[MI_POINT_STATUS].text) != m_MountInfo[MI_POINT_STATUS])
1199 IUSaveText(&StatusT[MI_POINT_STATUS], m_MountInfo[MI_POINT_STATUS].c_str());
1200 BasicMountInfoHasChanged =
true;
1202 if (std::string(StatusT[MI_TRACK_MODE].text) != m_MountInfo[MI_TRACK_MODE])
1204 IUSaveText(&StatusT[MI_TRACK_MODE], m_MountInfo[MI_TRACK_MODE].c_str());
1205 BasicMountInfoHasChanged =
true;
1208 if (BasicMountInfoHasChanged)
1215 bool SynscanDriver::sendCommand(
const char *
cmd,
char * res,
int cmd_len,
int res_len)
1217 int nbytes_written = 0, nbytes_read = 0, rc = -1;
1219 tcflush(
PortFD, TCIOFLUSH);
1223 char hex_cmd[SYN_RES * 3] = {0};
1224 hexDump(hex_cmd,
cmd, cmd_len);
1238 LOGF_ERROR(
"Serial write error: %s.", errstr);
1254 LOGF_ERROR(
"Serial read error: %s.", errstr);
1260 char hex_res[SYN_RES * 3] = {0};
1261 hexDump(hex_res, res, res_len);
1269 tcflush(
PortFD, TCIOFLUSH);
1274 void SynscanDriver::hexDump(
char * buf,
const char * data,
int size)
1276 for (
int i = 0; i < size; i++)
1277 sprintf(buf + 3 * i,
"%02X ",
static_cast<uint8_t
>(data[i]));
1280 buf[3 * size - 1] =
'\0';
1283 void SynscanDriver::mountSim()
1285 static struct timeval ltv;
1291 gettimeofday(&tv,
nullptr);
1293 if (ltv.tv_sec == 0 && ltv.tv_usec == 0)
1296 dt = tv.tv_sec - ltv.tv_sec + (tv.tv_usec - ltv.tv_usec) / 1e6;
1299 da = currentSlewRate * dt;
1306 CurrentRA =
range24(CurrentRA);
1317 dx = TargetRA - CurrentRA;
1325 CurrentRA = TargetRA;
1329 CurrentRA += da / 15.;
1331 CurrentRA -= da / 15.;
1335 else if (CurrentRA > 24)
1338 dx = TargetDE - CurrentDE;
1341 CurrentDE = TargetDE;
1366 bool SynscanDriver::slewFixedRate(SynscanDirection direction, uint8_t rate)
1368 char cmd[SYN_RES] = {0}, res[SYN_RES] = {0};
1373 cmd[2] = (direction ==
SYN_N || direction ==
SYN_S) ? 17 : 16;
1376 cmd[3] = (direction ==
SYN_N || direction ==
SYN_W) ? 36 : 37;
1378 cmd[3] = (direction ==
SYN_N || direction ==
SYN_W) ? 37 : 36;
1382 return sendCommand(
cmd, res, 8);
1385 bool SynscanDriver::slewVariableRate(SynscanDirection direction,
double rate)
1387 char cmd[SYN_RES] = {0}, res[SYN_RES] = {0};
1391 uint16_t synRate = rint(rate * 4);
1396 cmd[2] = (direction ==
SYN_N || direction ==
SYN_S) ? 17 : 16;
1398 cmd[3] = (direction ==
SYN_N || direction ==
SYN_W) ? 6 : 7;
1400 cmd[4] = synRate >> 8;
1402 cmd[5] = synRate & 0xFF;
1404 return sendCommand(
cmd, res, 8);
1473 static_cast<SynscanDriver *
>(context)->guideTimeoutCallbackNS();
1478 static_cast<SynscanDriver *
>(context)->guideTimeoutCallbackWE();
1481 void SynscanDriver::guideTimeoutCallbackNS()
1486 m_CustomGuideDE = m_GuideNSTID = 0;
1489 void SynscanDriver::guideTimeoutCallbackWE()
1494 m_CustomGuideRA = m_GuideWETID = 0;
1497 bool SynscanDriver::isSlewComplete()
1499 char res[SYN_RES] = {0};
1501 if (!sendCommand(
"L", res))
1504 return res[0] ==
'0';
const char * getDeviceName() const
INDI::PropertySwitch getSwitch(const char *name) const
virtual bool saveConfig(bool silent=false, const char *property=nullptr)
Save the current properties in a configuration file.
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)
bool isSimulation() const
void addAuxControls()
Add Debug, Simulation, and Configuration options to the driver.
void setDriverInterface(uint16_t value)
setInterface Set driver interface. By default the driver interface is set to GENERAL_DEVICE....
uint16_t getDriverInterface() const
virtual void GuideComplete(INDI_EQ_AXIS axis)
Call GuideComplete once the guiding pulse is complete.
INumberVectorProperty GuideNSNP
void initGuiderProperties(const char *deviceName, const char *groupName)
Initilize guider properties. It is recommended to call this function within initProperties() of your ...
INumberVectorProperty GuideWENP
void processGuiderProperties(const char *name, double values[], char *names[], int n)
Call this function whenever client updates GuideNSNP or GuideWSP properties in the primary device....
TelescopeStatus TrackState
void SetAxis1Park(double value)
SetRAPark Set current RA/AZ parking position. The data park file (stored in ~/.indi/ParkData....
TelescopePierSide currentPierSide
ISwitchVectorProperty MovementNSSP
void SetAxis1ParkDefault(double steps)
SetRAPark Set default RA/AZ parking position.
void SetTelescopeCapability(uint32_t cap, uint8_t slewRateCount)
SetTelescopeCapability sets the Telescope capabilities. All capabilities must be initialized.
INumberVectorProperty LocationNP
virtual bool initProperties() override
Called to initialize basic properties required all the time.
ITextVectorProperty TimeTP
double GetAxis1Park() const
double GetAxis2Park() const
bool isParked()
isParked is mount currently parked?
virtual int AddTrackMode(const char *name, const char *label, bool isDefault=false)
AddTrackMode.
ISwitchVectorProperty TrackModeSP
ISwitchVectorProperty SlewRateSP
virtual bool updateProperties() override
Called when connected state changes, to add/remove properties.
virtual void SetParked(bool isparked)
SetParked Change the mount parking status. The data park file (stored in ~/.indi/ParkData....
@ TELESCOPE_HAS_PIER_SIDE
@ TELESCOPE_HAS_TRACK_MODE
@ TELESCOPE_CAN_CONTROL_TRACK
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
IGeographicCoordinates m_Location
uint32_t GetTelescopeCapability() const
GetTelescopeCapability returns the capability of the Telescope.
void NewRaDec(double ra, double dec)
The child class calls this function when it has updates.
void setPierSide(TelescopePierSide side)
bool InitPark()
InitPark Loads parking data (stored in ~/.indi/ParkData.xml) that contains parking status and parking...
ISwitchVectorProperty MovementWESP
void SetAxis2Park(double steps)
SetDEPark Set current DEC/ALT parking position. The data park file (stored in ~/.indi/ParkData....
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
void SetParkDataType(TelescopeParkData type)
setParkDataType Sets the type of parking data stored in the park data file and presented to the user.
void SetAxis2ParkDefault(double steps)
SetDEParkDefault Set default DEC/ALT parking position.
virtual bool Park() override
Park the telescope to its home position.
static void guideTimeoutHelperWE(void *context)
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual bool updateProperties() override
Called when connected state changes, to add/remove properties.
virtual bool Sync(double ra, double dec) override
Set the telescope current RA and DEC coordinates to the supplied RA and DEC coordinates.
virtual bool SetSlewRate(int index) override
SetSlewRate Set desired slew rate index.
static void guideTimeoutHelperNS(void *context)
virtual bool UnPark() override
Unpark the telescope if already parked.
virtual bool initProperties() override
Called to initialize basic properties required all the time.
virtual bool SetCurrentPark() override
SetCurrentPark Set current coordinates/encoders value as the desired parking position.
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 GuideEast(uint32_t ms) override
Guide east for ms milliseconds. East is defined as RA+.
virtual bool MoveNS(INDI_DIR_NS dir, TelescopeMotionCommand command) override
Start or Stop the telescope motion in the direction dir.
virtual bool updateLocation(double latitude, double longitude, double elevation) override
Update telescope location settings.
virtual bool ReadScopeStatus() override
Read telescope status.
virtual bool Goto(double, double) override
Move the scope to the supplied RA and DEC coordinates.
virtual bool SetTrackEnabled(bool enabled) override
SetTrackEnabled Engages or disengages mount tracking. If there are no tracking modes available,...
virtual bool Abort() override
Abort any telescope motion including tracking if possible.
virtual bool SetDefaultPark() override
SetDefaultPark Set default coordinates/encoders value as the desired parking position.
virtual bool Handshake() override
perform handshake with device to check communication
virtual IPState GuideWest(uint32_t ms) override
Guide west for ms milliseconds. West is defined as RA-.
virtual bool GotoAzAlt(double az, double alt)
virtual IPState GuideNorth(uint32_t ms) override
Guide north for ms milliseconds. North is defined as DEC+.
virtual IPState GuideSouth(uint32_t ms) override
Guide south for ms milliseconds. South is defined as DEC-.
virtual bool MoveWE(INDI_DIR_WE dir, TelescopeMotionCommand command) override
Move the telescope in the direction dir.
virtual bool updateTime(ln_date *utc, double utc_offset) override
Update telescope time, date, and UTC offset.
virtual bool SetTrackMode(uint8_t mode) override
SetTrackMode Set active tracking mode. Do not change track state.
const char * GUIDE_TAB
GUIDE_TAB Where all the properties for guiding are located.
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
const char * MOTION_TAB
MOTION_TAB Where all the motion control properties of the device are located.
void IERmTimer(int timerid)
Remove the timer with the given timerid, as returned from IEAddTimer() or IEAddPeriodicTimer().
int IEAddTimer(int millisecs, IE_TCF *fp, void *p)
Register a new single-shot timer function, fp, to be called with ud as argument after ms.
#define NARRAY(a)
Handy macro to find the number of elements in array a[]. Must be used with actual array,...
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
double range24(double r)
range24 Limits a number to be between 0-24 range.
double rangeDec(double decdegrees)
rangeDec Limits declination value to be in -90 to 90 range.
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 fs_sexa(char *out, double a, int w, int fracbase)
Converts a sexagesimal number to a string. sprint the variable a in sexagesimal format into out[].
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.
double get_local_sidereal_time(double longitude)
get_local_sidereal_time Returns local sideral time given longitude and system clock.
#define TRACKRATE_SIDEREAL
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.
INumber * IUFindNumber(const INumberVectorProperty *nvp, const char *name)
Find an INumber member in a number text property.
int IUFindOnSwitchIndex(const ISwitchVectorProperty *svp)
Returns the index of first ON switch it finds in the vector switch property.
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.
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.
ISwitch * IUFindSwitch(const ISwitchVectorProperty *svp, const char *name)
Find an ISwitch member in a vector switch property.
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_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,...)
void J2000toObserved(IEquatorialCoordinates *J2000pos, double jd, IEquatorialCoordinates *observed)
*J2000toObserved converts catalogue to observed
void EquatorialToHorizontal(IEquatorialCoordinates *object, IGeographicCoordinates *observer, double JD, IHorizontalCoordinates *position)
EquatorialToHorizontal Calculate horizontal coordinates from equatorial coordinates.
void HorizontalToEquatorial(IHorizontalCoordinates *object, IGeographicCoordinates *observer, double JD, IEquatorialCoordinates *position)
HorizontalToEquatorial Calculate Equatorial EOD Coordinates from horizontal coordinates.
void ObservedToJ2000(IEquatorialCoordinates *observed, double jd, IEquatorialCoordinates *J2000pos)
ObservedToJ2000 converts an observed position to a J2000 catalogue position removes aberration,...
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values