33 #define LIBRARY_TAB "Library"
34 #define FIRMWARE_TAB "Firmware data"
35 #define STATUS_TAB "ONStep Status"
37 #define ALIGN_TAB "Align"
38 #define OUTPUT_TAB "Outputs"
39 #define ENVIRONMENT_TAB "Weather"
40 #define ROTATOR_TAB "Rotator"
51 currentSubCatalog = 0;
85 return "LX200 OnStep";
130 uint8_t nSlewRate = 10;
207 IUFillSwitchVector(&
SetHomeSP,
SetHomeS, 2,
getDeviceName(),
"HOME_INIT",
"Homing",
SITE_TAB,
IP_RW,
ISR_ATMOST1, 60,
311 IUFillSwitchVector(&
OSPECReadSP,
OSPECReadS, 2,
getDeviceName(),
"PEC File",
"PEC File",
PEC_TAB,
IP_RW,
ISR_ATMOST1, 0,
361 #ifdef ONSTEP_NOTDONE
366 IUFillSwitchVector(&
OSOutput1SP,
OSOutput1S, 2,
getDeviceName(),
"Output 1",
"Output 1",
OUTPUT_TAB,
IP_RW,
ISR_ATMOST1, 60,
371 IUFillSwitchVector(&
OSOutput2SP,
OSOutput2S, 2,
getDeviceName(),
"Output 2",
"Output 2",
OUTPUT_TAB,
IP_RW,
ISR_ATMOST1, 60,
378 snprintf(port_name,
sizeof(port_name),
"Output %d", i);
419 addParameter(
"WEATHER_TEMPERATURE",
"Temperature (C)", -40, 85, 15);
420 addParameter(
"WEATHER_HUMIDITY",
"Humidity %", 0, 100, 15);
421 addParameter(
"WEATHER_BAROMETER",
"Pressure (hPa)", 0, 1500, 15);
422 addParameter(
"WEATHER_DEWPOINT",
"Dew Point (C)", 0, 100, 15);
423 addParameter(
"WEATHER_CPU_TEMPERATURE",
"OnStep CPU Temperature", -274, 200, -274);
436 if (dev !=
nullptr && strcmp(dev,
getDeviceName()) != 0)
return;
449 if (!activeConnection->
name().compare(
"CONNECTION_TCP"))
451 LOG_INFO(
"Network based connection, detection timeouts set to 2 seconds");
457 LOG_INFO(
"Non-Network based connection, detection timeouts set to 0.1 seconds");
501 if (error_or_fail > 0 && response[0] ==
'1')
518 LOGF_DEBUG(
"error_or_fail = %u, response = %c", error_or_fail, response[0]);
541 LOG_INFO(
"Version unknown or OnStepX (Checking for OnStepX Focusers)");
542 for (
int i = 0; i < 9; i++)
546 snprintf(
cmd,
sizeof(
cmd),
":F%dA#", i + 1);
549 if (!fail_or_error && read_buffer[0] ==
'1')
556 if(fail_or_error < 0)
559 LOGF_INFO(
"Function call failed in a way that says OnStep doesn't have this setup, stopping Focuser probing, return: %i",
580 LOG_INFO(
"At least one focuser found, showing interface");
584 LOG_DEBUG(
"Focusers checked Variables:");
590 if (error_or_fail > 0)
592 if (rotator_response[0] ==
'D' || rotator_response[0] ==
'R')
598 if (rotator_response[0] ==
'D')
606 LOG_WARN(
"Error on response to rotator check (:GX98#) CHECK CONNECTION");
635 #ifdef ONSTEP_NOTDONE
667 double longitude = -1000, latitude = -1000;
756 #ifdef ONSTEP_NOTDONE
775 LOG_INFO(
"Initialization Complete");
783 if (strstr(name,
"FOCUS_"))
785 if (strstr(name,
"ROTATOR_"))
788 if (strcmp(name,
"EQUATORIAL_EOD_COORD") == 0)
797 for (
int x = 0; x < n; x++)
809 if ((
ra >= 0) && (
ra <= 24) && (
dec >= -90) && (
dec <= 90))
816 LOG_DEBUG(
"Please unpark the mount before issuing any motion/sync commands.");
824 if (Telescope::CanSync())
828 if ((sw !=
nullptr) && (sw->s ==
ISS_ON))
863 char object_name[256];
893 snprintf(
cmd, 5,
":R%d#", (
int)values[0]);
900 LOGF_DEBUG(
"Setting Max Slew Rate to %f\n", values[0]);
920 double bklshdec = 0, bklshra = 0;
922 for (nset = i = 0; i < n; i++)
927 bklshdec = values[i];
928 LOGF_DEBUG(
"===CMD==> Backlash DEC= %f", bklshdec);
929 nset += bklshdec >= 0 && bklshdec <= 999;
934 LOGF_DEBUG(
"===CMD==> Backlash RA= %f", bklshra);
935 nset += bklshra >= 0 && bklshra <= 999;
941 snprintf(
cmd, 9,
":$BD%d#", (
int)bklshdec);
947 const struct timespec timeout = {0, 100000000L};
948 nanosleep(&timeout,
nullptr);
949 snprintf(
cmd, 9,
":$BR%d#", (
int)bklshra);
973 double minAlt = 0, maxAlt = 0;
976 for (nset = i = 0; i < n; i++)
982 nset += minAlt >= -30.0 && minAlt <= 30.0;
987 nset += maxAlt >= 60.0 && maxAlt <= 90.0;
1023 double minPMEast = 0, minPMWest = 0;
1025 for (nset = i = 0; i < n; i++)
1030 minPMEast = values[i];
1031 LOGF_DEBUG(
"===CMD==> minutesPastMeridianN[0]/East = %f", minPMEast);
1032 nset += minPMEast >= -180 && minPMEast <= 180;
1036 minPMWest = values[i];
1037 LOGF_DEBUG(
"===CMD==> minutesPastMeridianN[1]/West= %f", minPMWest);
1038 nset += minPMWest >= -180 && minPMWest <= 180;
1044 snprintf(
cmd, 20,
":SXE9,%d#", (
int) minPMEast);
1050 const struct timespec timeout = {0, 100000000L};
1051 nanosleep(&timeout,
nullptr);
1052 snprintf(
cmd, 20,
":SXEA,%d#", (
int) minPMWest);
1080 if ((values[0] >= -25000) && (values[0] <= 25000))
1082 snprintf(
cmd, 15,
":fR%d#", (
int)values[0]);
1099 for(
int i = 0; i < n; i++)
1101 int value = (int)values[i];
1109 snprintf(
cmd,
sizeof(
cmd),
":SXX%d,V%d#", port, value);
1116 LOGF_ERROR(
"Set port %d to value =%d failed", port, value);
1134 if ((values[0] >= -100) && (values[0] <= 100))
1137 snprintf(
cmd, 15,
":SX9A,%d#", (
int)values[0]);
1154 if ((values[0] >= 0) && (values[0] <= 100))
1156 snprintf(
cmd, 15,
":SX9C,%d#", (
int)values[0]);
1173 if ((values[0] >= 0) && (values[0] <= 100))
1175 snprintf(
cmd, 15,
":SX9B,%d#", (
int)values[0]);
1194 if (abs(values[0]) < 1000)
1196 snprintf(
cmd, 15,
":FC%+3.5f#", values[0]);
1214 if ((values[0] >= 1) && (values[0] <= 32768))
1216 snprintf(
cmd, 15,
":FD%d#", (
int)values[0]);
1233 if (strstr(name,
"WEATHER_"))
1263 LOG_WARN(
"Telescope is Parked, Unpark before tracking.");
1282 LOG_DEBUG(
"TrackStateSP intercept, OnStep driver, should never get here");
1320 snprintf(
cmd,
sizeof(
cmd),
":R%d#", index);
1327 LOGF_DEBUG(
"Setting Max Slew Rate to %u\n", index);
1596 snprintf(
cmd, 5,
":FZ#");
1604 snprintf(
cmd, 5,
":FH#");
1621 LOGF_INFO(
"Primary focuser set: Focuser 1 in INDI/Controllable Focuser = OnStep Focuser %d", index + 1);
1624 LOG_INFO(
"If using OnStep: Focuser 2 in INDI = OnStep Focuser 2");
1628 LOG_INFO(
"If using OnStep: Focuser 2 in INDI = OnStep Focuser 1");
1634 snprintf(
cmd, 7,
":FA%d#", index + 1 );
1635 for (i = 0; i < 9; i++)
1661 snprintf(
cmd, 5,
":F%d#", index + 1);
1678 strncpy(
cmd,
":f+#",
sizeof(
cmd));
1682 strncpy(
cmd,
":f-#",
sizeof(
cmd));
1686 strncpy(
cmd,
":fQ#",
sizeof(
cmd));
1689 const struct timespec timeout = {0, 100000000L};
1690 nanosleep(&timeout,
nullptr);
1712 strncpy(
cmd,
":r-#",
sizeof(
cmd));
1716 strncpy(
cmd,
":r+#",
sizeof(
cmd));
1777 else if (index == 1)
1814 if ((index_stars <= 8) && (index_stars >= 0))
1816 int stars = index_stars + 1;
1818 LOGF_INFO(
"Align index: %d, stars: %d", index_stars, stars);
1860 LOG_INFO(
"Step 1: Goto a bright star between 50 and 80 degrees N/S from the pole. Preferably on the Meridian.");
1861 LOG_INFO(
"Step 2: Make sure it is centered.");
1862 LOG_INFO(
"Step 3: Press Refine Polar Alignment.");
1863 LOG_INFO(
"Step 4: Using the mount's Alt and Az screws manually recenter the star. (Video mode if your camera supports it will be helpful.)");
1864 LOG_INFO(
"Optional: Start a new alignment.");
1873 snprintf(
cmd, 5,
":MP#");
1905 snprintf(
cmd,
sizeof(
cmd),
":Fc0#");
1912 snprintf(
cmd,
sizeof(
cmd),
":Fc1#");
1925 #ifdef ONSTEP_NOTDONE
1957 if (strstr(name,
"FOCUS"))
1962 if (strstr(name,
"ROTATOR"))
1990 && (strcmp(
VersionT[3].text,
"OnStep") || strcmp(
VersionT[3].text,
"On-Step")))
1992 LOG_INFO(
"Old OnStep (V1/V2 depreciated) detected, setting some defaults");
1993 LOG_INFO(
"Note: Everything should work, but it may have timeouts in places, as it's not tested against.");
1997 else if (
VersionT[2].text[0] ==
'3' && (strcmp(
VersionT[3].text,
"OnStep") || strcmp(
VersionT[3].text,
"On-Step")))
1999 LOG_INFO(
"V3 OnStep detected, setting some defaults");
2003 else if (
VersionT[2].text[0] ==
'4' && (strcmp(
VersionT[3].text,
"OnStep") || strcmp(
VersionT[3].text,
"On-Step")))
2005 LOG_INFO(
"V4 OnStep detected, setting some defaults");
2009 else if (
VersionT[2].text[0] ==
'5' && (strcmp(
VersionT[3].text,
"OnStep") || strcmp(
VersionT[3].text,
"On-Step")))
2011 LOG_INFO(
"V5 OnStep detected, setting some defaults");
2016 && (strcmp(
VersionT[3].text,
"OnStepX") || strcmp(
VersionT[3].text,
"On-Step")))
2018 LOG_INFO(
"OnStepX detected, setting some defaults");
2024 LOG_INFO(
"OnStep/OnStepX version could not be detected");
2032 LOG_INFO(
"=============== Parkdata loaded");
2037 LOG_INFO(
"=============== Parkdata Load Failed");
2048 if(error_or_fail != 1 || response[0] !=
'1')
2050 LOGF_WARN(
"===CMD==> Set Park Pos %s", response);
2055 LOG_WARN(
"Park Value set to current position");
2064 LOG_WARN(
"Park Position set to Default value, 20/80");
2076 if ((response[0] !=
'1') || (failure_or_error < 0))
2094 IDSetSwitch(&(Telescope::AbortSP),
"Abort slew failed.");
2097 Telescope::AbortSP.s =
IPS_OK;
2099 IDSetSwitch(&(Telescope::AbortSP),
"Slew aborted.");
2132 bool pier_not_set =
true;
2142 tcflush(
PortFD, TCIOFLUSH);
2156 if (error_or_fail > 1)
2163 if (sscanf(
OSStat,
"%s%[pIPF]%s%[0-9]%[0-9]%[0-9]", check_GU_valid1, &check_GU_valid2[0], check_GU_valid3,
2164 &check_GU_valid2[1], &check_GU_valid2[2], &check_GU_valid2[3]) != 1)
2166 LOG_WARN(
":GU# returned something that can not be right, this update aborted, will try again...");
2167 LOGF_DEBUG(
"Parameters matched: %u from %s", sscanf(
OSStat,
"%s%[pIPF]%s%[0-9]%[0-9]%[0-9]", check_GU_valid1,
2168 &check_GU_valid2[0], check_GU_valid3, &check_GU_valid2[1], &check_GU_valid2[2], &check_GU_valid2[3]),
OSStat);
2176 LOG_INFO(
"RA/DEC could not be read, possible solution if using (wireless) ethernet: Use port 9998");
2177 LOG_WARN(
"This update aborted, will try again...");
2186 #ifdef DEBUG_TRACKSTATE
2265 #ifdef DEBUG_TRACKSTATE
2269 LOG_DEBUG(
"EqNP is IPS_BUSY (Goto/slew or Parking)");
2277 LOG_DEBUG(
"EqNP is IPS_IDLE (Not Tracking or Parked)");
2281 LOG_DEBUG(
"EqNP is IPS_ALERT (Something wrong)");
2286 bool trackStateUpdateNeded =
false;
2292 trackStateUpdateNeded =
true;
2298 trackStateUpdateNeded =
true;
2306 trackStateUpdateNeded =
true;
2312 trackStateUpdateNeded =
true;
2315 if (trackStateUpdateNeded)
2317 #ifdef DEBUG_TRACKSTATE
2324 #ifdef DEBUG_TRACKSTATE
2329 bool update_needed =
false;
2337 update_needed =
true;
2338 #ifdef DEBUG_TRACKSTATE
2349 update_needed =
true;
2350 #ifdef DEBUG_TRACKSTATE
2360 update_needed =
true;
2361 #ifdef DEBUG_TRACKSTATE
2369 #ifdef DEBUG_TRACKSTATE
2372 update_needed =
true;
2376 #ifdef DEBUG_TRACKSTATE
2382 #ifdef DEBUG_TRACKSTATE
2385 LOG_DEBUG(
"EqNP is IPS_BUSY (Goto/slew or Parking)");
2393 LOG_DEBUG(
"EqNP is IPS_IDLE (Not Tracking or Parked)");
2397 LOG_DEBUG(
"EqNP is IPS_ALERT (Something wrong)");
2403 #ifdef DEBUG_TRACKSTATE
2530 LOG_INFO(
"Telescope detected having PEC, setting that capability");
2531 LOGF_DEBUG(
"capabilities = %x", capabilities);
2545 if (!strstr(
OSStat,
"S"))
2587 LOG_INFO(
"Telescope detected having Pier Side, adding that capability (many messages duplicated)");
2588 LOGF_DEBUG(
"capabilities = %x", capabilities);
2597 pier_not_set =
false;
2602 pier_not_set =
false;
2607 pier_not_set =
false;
2650 if (
OSStat[0] & 0b10000001 == 0b10000001)
2654 if (
OSStat[0] & 0b10000010 == 0b10000010)
2658 if (
OSStat[0] & 0b10000100 == 0b10000100)
2667 if (
OSStat[0] & 0b10001000 == 0b10001000)
2676 if ((
OSStat[0] & 0b10010000 == 0b10010000
2677 ||
OSStat[0] & 0b10100000 == 0b10100000))
2679 if (
OSStat[0] & 0b10100000 == 0b10100000)
2683 if (
OSStat[0] & 0b10010000 == 0b10010000)
2687 if (
OSStat[0] & 0b11000000 == 0b11000000)
2702 if (
OSStat[1] & 0b10000001 == 0b10000001)
2706 if (
OSStat[1] & 0b10000010 == 0b10000010)
2710 if (
OSStat[1] & 0b10000011 == 0b10000011)
2715 if (
OSStat[2] & 0b10000001 == 0b10000001)
2719 if (
OSStat[2] & 0b10000010 == 0b10000010)
2724 if (
OSStat[2] & 0b10000100 == 0b10000100)
2738 if (
OSStat[2] & 0b10001000 == 0b10001000)
2742 if (
OSStat[2] & 0b10010000 == 0b10010000)
2757 if (
OSStat[2] & 0b10100000 == 0b10100000)
2766 if (
OSStat[3] & 0b10000001 == 0b10000001)
2772 if (
OSStat[3] & 0b10000010 == 0b10000010)
2778 if (
OSStat[3] & 0b10000100 == 0b10000100)
2784 if (
OSStat[3] & 0b10001000 == 0b10001000)
2793 if (
OSStat[3] & 0b10010000 == 0b10010000)
2799 if (
OSStat[3] & 0b10100000 == 0b10100000)
2804 if (
OSStat[3] & 0b11000000 == 0b11000000)
2823 PulseGuideGU =
OSStat[6] & 0b01111111;
2824 GuideRateGU =
OSStat[7] & 0b01111111;
2825 LastError =
OSStat[8] & 0b01111111;
2906 #ifndef OnStep_Alpha
2917 if (error_or_fail > 1)
2941 LOG_WARN(
"Communication error on Pier Side (:Gm#), this update aborted, will try again...");
2949 double backlash_DEC, backlash_RA;
2952 if (BD_error > 1 && BR_error > 1)
2960 LOG_WARN(
"Communication error on backlash (:%BD#/:%BR#), this update aborted, will try again...");
2964 double pulseguiderate = 0.0;
2967 LOGF_DEBUG(
"Guide Rate String: %s", GuideValue);
2968 pulseguiderate = atof(GuideValue);
2969 LOGF_DEBUG(
"Guide Rate: %f", pulseguiderate);
2976 LOGF_DEBUG(
"Guide Rate String: %s", GuideValue);
2977 LOG_DEBUG(
"Guide rate error response, Not setting guide rate from :GX90# response, falling back to :GU#, which may not be accurate, if custom settings are used");
2979 switch(pulseguiderateint)
2982 pulseguiderate = (double)0.25;
2985 pulseguiderate = (double)0.5;
2988 pulseguiderate = (double)1.0;
2991 pulseguiderate = 0.0;
2992 LOG_DEBUG(
"Could not get guide rate from :GU# response, not setting");
2993 LOG_WARN(
"Communication error on Guide Rate (:GX90#/:GU#), this update aborted, will try again...");
2996 if (pulseguiderate != 0.0)
2998 LOGF_DEBUG(
"Guide Rate: %f", pulseguiderate);
3005 #ifndef OnStep_Alpha
3009 char merdidianflipauto_response[
RB_MAX_LEN] = {0};
3013 if (merdidianflipauto_response[0] ==
'1')
3020 else if (merdidianflipauto_response[0] ==
'0')
3030 LOG_WARN(
"Communication error on meridianAutoFlip (:GX95#), this update aborted, will try again...");
3039 char preferredpierside_response[
RB_MAX_LEN] = {0};
3043 if (strstr(preferredpierside_response,
"W"))
3049 else if (strstr(preferredpierside_response,
"E"))
3055 else if (strstr(preferredpierside_response,
"B"))
3061 else if (strstr(preferredpierside_response,
"%"))
3064 LOG_DEBUG(
":GX96 returned \% indicating early OnStepX bug");
3078 LOG_WARN(
"Communication error on Preferred Pier Side (:GX96#), this update aborted, will try again...");
3086 int gxea_error, gxe9_error;
3087 double minutes_past_Meridian_East, minutes_past_Meridian_West;
3101 LOG_WARN(
"Communication error on Degrees past Meridian West (:GXEA#), this update aborted, will try again...");
3107 LOG_WARN(
"Communication error on Degrees past Meridian East (:GXE9#), this update aborted, will try again...");
3123 LOGF_DEBUG(
"Elevation Limit Min: %s, %i Go_nbcar: %i", Go, Go_int, Go_error);
3127 LOG_WARN(
"Communication :Go# error, check connection.");
3140 LOGF_DEBUG(
"Elevation Limit Min: %s, %i Gh_nbcar: %i", Gh, Gh_int, Gh_error);
3144 LOG_WARN(
"Communication :Gh# error, check connection.");
3152 LOG_WARN(
"Communication error on Rotator Update, this update aborted, will try again...");
3158 double temperature_value;
3166 LOG_WARN(
"Communication error on Temperature (:GX9A#), this update aborted, will try again...");
3171 double humidity_value;
3179 LOG_WARN(
"Communication error on Humidity (:GX9C#), this update aborted, will try again...");
3185 double barometer_value;
3193 LOG_WARN(
"Communication error on Barometer (:GX9B#), this update aborted, will try again...");
3198 double dewpoint_value;
3206 LOG_WARN(
"Communication error on Dewpoint (:GX9E#), this update aborted, will try again...");
3213 double cputemp_value;
3215 if ( error_return >= 0 && !strcmp(cputemp_reponse,
"0") )
3221 LOGF_DEBUG(
"CPU Temp not responded to, disabling further checks, return values: error_return: %i, cputemp_reponse: %s",
3222 error_return, cputemp_reponse);
3240 for (
int driver_number = 1; driver_number < 3; driver_number++)
3244 snprintf(TMCDriverCMD,
sizeof(TMCDriverCMD),
":GXU%i#", driver_number);
3248 if (i == -4 && TMCDriverTempValue[0] ==
'0' )
3251 snprintf(ResponseText,
sizeof(ResponseText),
"TMC Reporting not detected, Axis %i", driver_number);
3253 LOG_DEBUG(
"TMC Drivers responding as if not there, disabling further checks");
3260 if (TMCDriverTempValue[0] == 0)
3267 char StepperState[1024] = {0};
3268 bool unknown_value =
false;
3269 int current_position = 0;
3270 while (TMCDriverTempValue[current_position] != 0 && unknown_value ==
false)
3272 if (TMCDriverTempValue[current_position] ==
',')
3278 if (TMCDriverTempValue[current_position] ==
'S' && TMCDriverTempValue[current_position + 1] ==
'T')
3280 strcat(StepperState,
"Standstill,");
3282 else if (TMCDriverTempValue[current_position] ==
'O' && TMCDriverTempValue[current_position + 1] ==
'A')
3284 strcat(StepperState,
"Open Load A Pair,");
3286 else if (TMCDriverTempValue[current_position] ==
'O' && TMCDriverTempValue[current_position + 1] ==
'B')
3288 strcat(StepperState,
"Open Load B Pair,");
3290 else if (TMCDriverTempValue[current_position] ==
'G' && TMCDriverTempValue[current_position + 1] ==
'A')
3292 strcat(StepperState,
"Short to Ground A Pair,");
3294 else if (TMCDriverTempValue[current_position] ==
'G' && TMCDriverTempValue[current_position + 1] ==
'B')
3296 strcat(StepperState,
"Short to Ground B Pair,");
3298 else if (TMCDriverTempValue[current_position] ==
'O' && TMCDriverTempValue[current_position + 1] ==
'T')
3300 strcat(StepperState,
"Over Temp (>150C),");
3302 else if (TMCDriverTempValue[current_position] ==
'P' && TMCDriverTempValue[current_position + 1] ==
'W')
3304 strcat(StepperState,
"Pre-Warning: Over Temp (>120C),");
3306 else if (TMCDriverTempValue[current_position] ==
'G' && TMCDriverTempValue[current_position + 1] ==
'F')
3308 strcat(StepperState,
"General Fault,");
3312 unknown_value =
true;
3315 current_position = current_position + 3;
3344 LOG_WARN(
"Communication error on Align Status Update, this update aborted, will try again...");
3352 LOG_WARN(
"Communication error on Focuser Update, this update aborted, will try again...");
3356 #ifndef OnStep_Alpha
3376 if(res < 0 || response[0] ==
'0')
3378 LOGF_ERROR(
"===CMD==> Track On %s", response);
3385 if(res < 0 || response[0] ==
'0')
3387 LOGF_ERROR(
"===CMD==> Track Off %s", response);
3396 years = years % 100;
3399 snprintf(
cmd,
CMD_MAX_LEN,
":SC%02d/%02d/%02d#", months, days, years);
3408 int nbytes_write = 0;
3415 tcflush(
PortFD, TCIFLUSH);
3420 LOGF_ERROR(
"CHECK CONNECTION: Error sending command %s",
cmd);
3430 char response[1] = {0};
3432 int nbytes_write = 0, nbytes_read = 0;
3439 tcflush(
PortFD, TCIFLUSH);
3446 tcflush(
PortFD, TCIFLUSH);
3449 if (nbytes_read < 1)
3451 LOG_WARN(
"Timeout/Error on response. Check connection.");
3455 return (response[0] ==
'0');
3462 int nbytes_write = 0, nbytes_read = 0;
3474 tcflush(
fd, TCIFLUSH);
3476 if (error_type !=
TTY_OK)
3479 term = strchr(data,
'#');
3484 data[nbytes_read] =
'\0';
3488 LOG_DEBUG(
"got RB_MAX_LEN bytes back (which should never happen), last byte set to null and possible overflow");
3500 tcflush(
fd, TCIOFLUSH);
3504 tcflush(
fd, TCIOFLUSH);
3509 if (error_type >= 0)
3511 LOGF_DEBUG(
"flushIO: Information in buffer: Bytes: %u, string: %s", nbytes_read, discard_data);
3515 while (error_type > 0);
3523 int nbytes_write = 0, nbytes_read = 0;
3530 tcflush(
fd, TCIFLUSH);
3536 tcflush(
fd, TCIFLUSH);
3538 term = strchr(data,
'#');
3543 data[nbytes_read] =
'\0';
3547 LOG_DEBUG(
"got RB_MAX_LEN bytes back, last byte set to null and possible overflow");
3553 if (error_type !=
TTY_OK)
3557 tcflush(
fd, TCIOFLUSH);
3561 if (sscanf(data,
"%lf", value) != 1)
3563 LOG_WARN(
"Invalid response, check connection");
3565 tcflush(
fd, TCIOFLUSH);
3578 int nbytes_write = 0, nbytes_read = 0;
3585 tcflush(
fd, TCIFLUSH);
3591 tcflush(
fd, TCIFLUSH);
3593 term = strchr(data,
'#');
3598 data[nbytes_read] =
'\0';
3602 LOG_DEBUG(
"got RB_MAX_LEN bytes back, last byte set to null and possible overflow");
3606 if (error_type !=
TTY_OK)
3610 tcflush(
fd, TCIOFLUSH);
3613 if (sscanf(data,
"%i", value) != 1)
3615 LOG_WARN(
"Invalid response, check connection");
3617 tcflush(
fd, TCIOFLUSH);
3627 int nbytes_write = 0, nbytes_read = 0;
3634 tcflush(
fd, TCIFLUSH);
3640 tcflush(
fd, TCIFLUSH);
3642 term = strchr(data,
'#');
3647 data[nbytes_read] =
'\0';
3651 LOG_DEBUG(
"got RB_MAX_LEN bytes back, last byte set to null and possible overflow");
3657 if (error_type !=
TTY_OK)
3675 double onstep_long = 360 - longitude ;
3676 while (onstep_long < 0)
3678 while (onstep_long > 360)
3683 LOG_ERROR(
"Error setting site longitude coordinates");
3689 LOG_ERROR(
"Error setting site latitude coordinates");
3693 char l[32] = {0}, L[32] = {0};
3694 fs_sexa(l, latitude, 3, 360000);
3695 fs_sexa(L, longitude, 4, 360000);
3697 LOGF_INFO(
"Site location updated to Lat %.32s - Long %.32s", l, L);
3708 snprintf(read_buffer,
sizeof(read_buffer),
":So%02d#",
max);
3717 char read_buffer[32];
3722 snprintf(read_buffer,
sizeof(read_buffer),
":Sg%.03d:%02d:%.02f#", d, m, s);
3730 snprintf(read_buffer,
sizeof(read_buffer),
":Sg%03d:%02d#", d, m);
3734 snprintf(read_buffer,
sizeof(read_buffer),
":Sg%03d:%02d#", d, m);
3742 char read_buffer[32];
3748 snprintf(read_buffer,
sizeof(read_buffer),
":St%+.02d:%02d:%.02f#", d, m, s);
3756 snprintf(read_buffer,
sizeof(read_buffer),
":St%+03d:%02d#", d, m);
3760 snprintf(read_buffer,
sizeof(read_buffer),
":St%+03d:%02d#", d, m);
3798 char read_buffer[32];
3801 snprintf(read_buffer,
sizeof(read_buffer),
":FR%5f#", output);
3812 char read_buffer[32];
3813 snprintf(read_buffer,
sizeof(read_buffer),
":FS%06d#",
int(targetTicks));
3819 LOG_INFO(
"Unable to move focuser, out of range");
3829 char read_buffer[32];
3832 snprintf(read_buffer,
sizeof(read_buffer),
":FR%04d#", output);
3842 strncpy(
cmd,
":FQ#",
sizeof(
cmd));
3859 if (error_or_fail > 1)
3870 if (error_or_fail > 0 )
3872 if (valueStatus[0] ==
'S')
3879 else if (valueStatus[0] ==
'M')
3888 LOG_WARN(
"Communication :FT# error, check connection.");
3899 LOG_WARN(
"Communication :FT# error, check connection.");
3915 LOGF_DEBUG(
"focus_max: %s, %i, fm_nbchar: %i", focus_max, focus_max_int, fm_error);
3919 LOG_WARN(
"Communication :FM# error, check connection.");
3920 LOGF_WARN(
"focus_max: %s, %u, fm_error: %i", focus_max, focus_max[0], fm_error);
3933 LOGF_DEBUG(
"focus_min: %s, %i fi_nbchar: %i", focus_min, focus_min_int, fi_error);
3937 LOG_WARN(
"Communication :FI# error, check connection.");
3951 LOGF_DEBUG(
"focus T°: %s, %i ft_nbcar: %i", focus_T, focus_T_int, ft_error);
3955 LOG_WARN(
"Communication :Ft# error, check connection.");
3968 LOGF_DEBUG(
"focus Differential T°: %s, %i fi_nbchar: %i", focus_TD, focus_TD_int, fe_error);
3972 LOG_WARN(
"Communication :Fe# error, check connection.");
3979 int focus_Coefficient_int ;
3985 LOGF_DEBUG(
"TFC Coefficient: %s, %i fC_nbchar: %i", focus_Coeficient, focus_Coefficient_int, fC_error);
3989 LOG_WARN(
"Communication :FC# error, check connection.");
3996 int focus_Deadband_int ;
4002 LOGF_DEBUG(
"TFC Deadband: %s, %i fD_nbchar: %i", focus_Deadband, focus_Deadband_int, fD_error);
4006 LOG_WARN(
"Communication :FD# error, check connection.");
4016 if (strcmp(response,
"0"))
4022 else if (strcmp(response,
"1"))
4029 LOGF_DEBUG(
"TFC Enable: fc_nbchar:%d Fc_response: %s", res, response);
4034 LOG_WARN(
"Communication :Fc# error, check connection.");
4049 if (error_return >= 0)
4051 if ( strcmp(value,
"0") )
4053 LOG_INFO(
"Focuser 2 called, but not present, disabling polling");
4065 LOGF_INFO(
"Focuser 2 called, but returned error %i on read, disabling further polling", error_return);
4075 if (error_or_fail > 0 && value[0] >
'0' && value[0] <
'9')
4077 int temp_value = (
unsigned int)(value[0]) -
'0';
4079 for (
int i = 0; i < 9; i++)
4083 if (temp_value == 0)
4087 else if (temp_value > 9 || temp_value < 0)
4091 LOGF_WARN(
"Active focuser returned out of range: %s, should be 0-9", temp_value);
4104 LOGF_DEBUG(
":Fa# returned outside values: %c, %u", value[0], value[0]);
4168 double double_value;
4172 if (error_or_fail == 1 && value[0] ==
'0')
4174 LOG_INFO(
"Detected Response that Rotator is not present, disabling further checks");
4178 if (error_or_fail < 1)
4180 LOG_WARN(
"Error talking to rotator, might be timeout (especially on network)");
4191 double min_rotator, max_rotator;
4194 bool changed_minmax =
false;
4199 if (error_or_fail > 1)
4201 changed_minmax =
true;
4206 if (error_or_fail > 1)
4208 changed_minmax =
true;
4219 if (error_or_fail > 1)
4221 if (value[0] ==
'S')
4227 else if (value[0] ==
'M')
4242 if (error_or_fail > 1)
4259 snprintf(
cmd,
sizeof(
cmd),
":rS%.03d:%02d:%02d#", d, m, s);
4283 LOG_INFO(
"Moving Rotator to Home");
4294 LOG_INFO(
"Aborting Rotation, de-rotation in same state");
4303 snprintf(
cmd,
sizeof(
cmd),
":rb%d#", steps);
4348 LOG_INFO(
"Sending Command to Start PEC Playback");
4349 strncpy(
cmd,
":$QZ+#",
sizeof(
cmd));
4355 LOG_DEBUG(
"Command to Playback PEC called when Controller does not support PEC");
4362 LOG_INFO(
"Command to Start Playback PEC called when Controller does not support PEC due to being Alt-Az, PEC Ignored going forward");
4376 LOG_INFO(
"Sending Command to Stop PEC Playback");
4377 strncpy(
cmd,
":$QZ-#",
sizeof(
cmd));
4383 LOG_DEBUG(
"Command to Stop Playing PEC called when Controller does not support PEC");
4396 LOG_INFO(
"Sending Command to Start PEC record");
4403 LOG_DEBUG(
"Command to Record PEC called when Controller does not support PEC");
4416 LOG_INFO(
"Sending Command to Clear PEC record");
4423 LOG_DEBUG(
"Command to clear PEC called when Controller does not support PEC");
4437 LOG_INFO(
"Sending Command to Save PEC to EEPROM");
4444 LOG_DEBUG(
"Command to save PEC called when Controller does not support PEC");
4459 LOG_INFO(
"Command to give PEC called when Controller does not support PEC due to being Alt-Az Disabled");
4474 if (error_or_fail > 1)
4481 if (value[0] ==
'I')
4487 LOG_INFO(
"Controller reports PEC Ignored and not supported");
4488 LOG_INFO(
"No Further PEC Commands will be processed, unless status changed");
4490 else if (value[0] ==
'R')
4496 else if (value[0] ==
'r')
4502 else if (value[0] ==
'P')
4508 else if (value[0] ==
'p')
4519 if (value[1] ==
'.')
4537 LOG_DEBUG(
"Timeout or other error on :$QZ?#");
4553 LOG_WARN(
"PEC Reading NOT Implemented");
4558 LOG_DEBUG(
"Command to Read PEC called when Controller does not support PEC");
4569 LOG_WARN(
"PEC Writing NOT Implemented");
4574 LOG_DEBUG(
"Command to Read PEC called when Controller does not support PEC");
4586 LOG_INFO(
"Sending Command to Start Alignment");
4595 if(error_or_fail != 4 || read_buffer[0] <
'0' || read_buffer[0] >
'9' || read_buffer[1] <
'0' || read_buffer[1] >
'9'
4596 || read_buffer[2] <
'0' || read_buffer[2] >
'9')
4598 LOGF_INFO(
"Getting Alignment Status: response Error, response = %s>", read_buffer);
4603 int max_stars = read_buffer[0] -
'0';
4604 if (stars > max_stars)
4606 LOG_INFO(
"Tried to start Align with too many stars.");
4607 LOGF_INFO(
"Starting Align with %d stars", max_stars);
4610 snprintf(
cmd,
sizeof(
cmd),
":A%.1d#", stars);
4611 LOGF_INFO(
"Started Align with %s, max possible stars: %d",
cmd, max_stars);
4626 LOG_INFO(
"Sending Command to Record Star");
4627 strncpy(
cmd,
":A+#",
sizeof(
cmd));
4645 char stars[5] = {0};
4646 int max_stars, current_star, align_stars;
4650 if(error_or_fail != 4 || read_buffer[0] <
'0' || read_buffer[0] >
'9' || read_buffer[1] <
'0' || read_buffer[1] >
'9'
4651 || read_buffer[2] <
'0' || read_buffer[2] >
'9')
4653 LOGF_INFO(
"Getting Alignment Status: response Error, response = %s>", read_buffer);
4656 max_stars = read_buffer[0] -
'0';
4657 current_star = read_buffer[1] -
'0';
4658 align_stars = read_buffer[2] -
'0';
4659 snprintf(stars,
sizeof(stars),
"%d", max_stars);
4661 snprintf(stars,
sizeof(stars),
"%d", current_star);
4663 snprintf(stars,
sizeof(stars),
"%d", align_stars);
4665 LOGF_DEBUG(
"Align: max_stars: %i current star: %u, align_stars %u", max_stars, current_star, align_stars);
4667 if (current_star <= align_stars)
4669 snprintf(msg,
sizeof(msg),
"%s Manual Align: Star %d/%d", read_buffer, current_star, align_stars );
4672 if (current_star > align_stars && max_stars > 1)
4674 LOGF_DEBUG(
"Align: current star: %u, align_stars %u",
int(current_star),
int(align_stars));
4675 snprintf(msg,
sizeof(msg),
"Manual Align: Completed");
4717 double altCor, azmCor;
4719 if (error_or_fail < 2)
4721 LOGF_INFO(
"Polar Align Error Status response Error, response = %s>", read_buffer);
4725 if (error_or_fail < 2)
4727 LOGF_INFO(
"Polar Align Error Status response Error, response = %s>", read_buffer);
4730 fs_sexa(sexabuf, (
double)azmCor / 3600, 4, 3600);
4731 snprintf(polar_error,
sizeof(polar_error),
"%f'' /%s", azmCor, sexabuf);
4733 fs_sexa(sexabuf, (
double)altCor / 3600, 4, 3600);
4734 snprintf(polar_error,
sizeof(polar_error),
"%f'' /%s", altCor, sexabuf);
4748 LOG_INFO(
"Alignment Done - May still be calculating");
4763 LOG_INFO(
"Sending Command to Finish Alignment and write");
4764 strncpy(
cmd,
":AW#",
sizeof(
cmd));
4780 #ifdef ONSTEP_NOTDONE
4859 command[5] = char(output);
4863 if (error_or_fail > 0)
4884 snprintf(read_buffer,
sizeof(read_buffer),
":RA%04f#", raRate);
4885 LOGF_INFO(
"Setting: Custom RA Rate to %04f", raRate);
4890 snprintf(read_buffer,
sizeof(read_buffer),
":RE%04f#", deRate);
4891 LOGF_INFO(
"Setting: Custom DE Rate to %04f", deRate);
4896 LOG_INFO(
"Custom RA and DE Rates successfully set");
4915 LOG_ERROR(
"OnStep slew/syncError called with value 0-goto possible, this is normal operation");
4918 LOG_ERROR(
"OnStep slew/syncError: Below the horizon limit");
4921 LOG_ERROR(
"OnStep slew/syncError: Above Overhead limit");
4924 LOG_ERROR(
"OnStep slew/syncError: Controller in standby, Usual issue fix: Turn tracking on");
4927 LOG_ERROR(
"OnStep slew/syncError: Mount is Parked");
4930 LOG_ERROR(
"OnStep slew/syncError: Goto in progress");
4933 LOG_ERROR(
"OnStep slew/syncError: Outside limits: Max/Min Dec, Under Pole Limit, Meridian Limit, Sync attempted to wrong pier side");
4936 LOG_ERROR(
"OnStep slew/syncError: Hardware Fault");
4939 LOG_ERROR(
"OnStep slew/syncError: Already in motion");
4942 LOG_ERROR(
"OnStep slew/syncError: Unspecified Error");
4945 LOG_ERROR(
"OnStep slew/syncError: Not in range of values that should be returned! INVALID, Something went wrong!");
4970 if (error_or_fail > 1)
4972 if (strcmp(read_buffer,
"N/A"))
4974 if (read_buffer[0] ==
'E' && read_buffer[1] >=
'0'
4975 && read_buffer[1] <=
'9')
4977 int error_code = read_buffer[1] -
'0';
4978 LOGF_DEBUG(
"Sync failed with response: %s, Error code: %i", read_buffer, error_code);
4986 LOG_ERROR(
"Unexpected return on sync call!");
4987 LOG_ERROR(
"Check system & Align if doing align to see if it went through!");
4994 LOG_ERROR(
"Communication error on sync! Re-issue sync!");
5002 LOG_INFO(
"OnStep: Synchronization successful.");
5026 if (error_or_fail == -4 && configured[0] ==
'0')
5029 LOG_INFO(
"Outputs not detected, disabling further checks");
5035 if(configured[i - 1] ==
'1')
5037 snprintf(getoutp,
sizeof(getoutp),
":GXY%d#", i);
5039 if (error_or_fail > 0)
5041 for(k = 0; k < strlen(port_name); k++)
5043 if(port_name[k] ==
',') port_name[k] =
'_';
5044 p_name[k] = port_name[k];
5051 LOGF_ERROR(
"Communication error on %s, ignoring, disconnect and reconnect to clear", getoutp);
5072 memset(<m, 0,
sizeof(ltm));
5073 memset(&utm, 0,
sizeof(utm));
5078 char utcStr[8] = {0};
5079 snprintf(utcStr, 8,
"%.2f", offset);
5084 LOG_WARN(
"Could not obtain UTC offset from mount!");
5090 LOG_WARN(
"Could not obtain local time from mount!");
5096 LOG_WARN(
"Could not obtain local date from mount!");
5102 snprintf(datetime,
MAXINDINAME,
"%sT%s", cdate, ctime);
5105 if (strptime(datetime,
"%FT%T", <m) ==
nullptr)
5107 LOGF_WARN(
"Could not process mount date and time: %s", datetime);
5113 time_epoch = mktime(<m);
5116 time_epoch -=
static_cast<int>(offset * 3600.0);
5119 localtime_r(&time_epoch, &utm);
5122 strftime(cdate,
MAXINDINAME,
"%Y-%m-%dT%H:%M:%S", &utm);
5137 int lat_dd = 0, lat_mm = 0, long_dd = 0, long_mm = 0;
5138 double lat_ssf = 0.0, long_ssf = 0.0;
5159 LOG_WARN(
"Failed to get site latitude from device.");
5165 snprintf(lat_sexagesimal,
MAXINDIFORMAT,
"%02d:%02d:%02.1lf", lat_dd, lat_mm, lat_ssf);
5172 snprintf(lat_sexagesimal,
MAXINDIFORMAT,
"%02d:%02d:%02.1lf", lat_dd, lat_mm, lat_ssf);
5180 LOG_WARN(
"Failed to get site latitude from device.");
5185 snprintf(lat_sexagesimal,
MAXINDIFORMAT,
"%02d:%02d:%02.1lf", lat_dd, lat_mm, lat_ssf);
5198 LOG_WARN(
"Failed to get site longitude from device.");
5204 snprintf(lng_sexagesimal,
MAXINDIFORMAT,
"%02d:%02d:%02.1lf", long_dd, long_mm, long_ssf);
5211 snprintf(lng_sexagesimal,
MAXINDIFORMAT,
"%02d:%02d:%02.1lf", long_dd, long_mm, long_ssf);
5219 LOG_WARN(
"Failed to get site longitude from device.");
5224 snprintf(lng_sexagesimal,
MAXINDIFORMAT,
"%02d:%02d:%02.1lf", long_dd, long_mm, long_ssf);
5229 LOGF_INFO(
"Mount has Latitude %s (%g) Longitude %s (%g) (Longitude sign in carthography format)",
5245 const struct timespec timeout = {0, 100000000L};
5249 char RAStr[64] = {0}, DecStr[64] = {0};
5294 nanosleep(&timeout,
nullptr);
5311 LOGF_ERROR(
"Error Slewing to JNow RA %s - DEC %s", RAStr, DecStr);
5321 LOGF_INFO(
"Slewing to RA: %s - DEC: %s", RAStr, DecStr);
5330 LOG_DEBUG(
"OnStep SyncParkStatus called");
5363 #ifdef DEBUG_TRACKSTATE
5373 LOG_DEBUG(
"TrackState: SCOPE_TRACKING");
5391 int utc_hour, utc_min;
5393 utc_hour = int(offset) * -1;
5394 utc_min = abs((offset -
int(offset)) * 60);
5395 if (utc_min > 30) utc_min = 45;
5396 snprintf(temp_string,
sizeof(temp_string),
":SG%03d:%02d#", utc_hour, utc_min);
The Interface class is the base class for all INDI connection plugins.
virtual std::string name()=0
const char * getDeviceName() 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....
Connection::Interface * getActiveConnection()
uint16_t getDriverInterface() const
INumberVectorProperty FocusAbsPosNP
INumberVectorProperty FocusRelPosNP
bool updateProperties()
updateProperties Define or Delete Rotator properties based on the connection status of the base devic...
void SetCapability(uint32_t cap)
FI::SetCapability sets the focuser capabilities. All capabilities must be initialized.
void initProperties(const char *groupName)
Initilize focuser properties. It is recommended to call this function within initProperties() of your...
bool processNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process focus number properties.
bool processSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process focus switch properties.
bool processSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process Rotator switch properties.
INumberVectorProperty RotatorBacklashNP
INumberVectorProperty GotoRotatorNP
void initProperties(const char *groupName)
Initilize Rotator properties. It is recommended to call this function within initProperties() of your...
bool updateProperties()
updateProperties Define or Delete Rotator properties based on the connection status of the base devic...
void SetCapability(uint32_t cap)
SetRotatorCapability sets the Rotator capabilities. All capabilities must be initialized.
INumber RotatorBacklashN[1]
bool processNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process Rotator number properties.
TelescopeStatus TrackState
ISwitchVectorProperty TrackStateSP
ISwitchVectorProperty ParkOptionSP
void SetAxis1Park(double value)
SetRAPark Set current RA/AZ parking position. The data park file (stored in ~/.indi/ParkData....
ISwitchVectorProperty MovementNSSP
ISwitchVectorProperty AbortSP
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
TelescopeParkData parkDataType
ITextVectorProperty TimeTP
INumberVectorProperty TargetNP
ISwitchVectorProperty CoordSP
bool isParked()
isParked is mount currently parked?
ISwitchVectorProperty PECStateSP
ISwitchVectorProperty SlewRateSP
INumberVectorProperty EqNP
@ TELESCOPE_HAS_TRACK_RATE
@ TELESCOPE_HAS_PIER_SIDE
@ TELESCOPE_CAN_CONTROL_TRACK
ISwitchVectorProperty ParkSP
uint32_t GetTelescopeCapability() const
GetTelescopeCapability returns the capability of the Telescope.
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....
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.
Provides interface to implement weather reporting functionality.
bool syncCriticalParameters()
updateWeatherState Send update weather state to client
void setParameterValue(std::string name, double value)
setParameterValue Update weather parameter value
bool setCriticalParameter(std::string param)
setCriticalParameter Set parameter that is considered critical to the operation of the observatory....
bool processNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process weather number properties.
virtual bool saveConfigItems(FILE *fp)
saveConfigItems Save parameters ranges in the config file.
ILightVectorProperty critialParametersLP
INumberVectorProperty ParametersNP
void addParameter(std::string name, std::string label, double numMinOk, double numMaxOk, double percWarning)
addParameter Add a physical weather measurable parameter to the weather driver. The weather value has...
void initProperties(const char *statusGroup, const char *paramsGroup)
Initilize focuser properties. It is recommended to call this function within initProperties() of your...
bool updateProperties()
updateProperties Define or Delete Rotator properties based on the connection status of the base devic...
virtual bool initProperties() override
Called to initialize basic properties required all the time.
virtual bool getLocalDate(char *dateString)
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
virtual bool getUTFOffset(double *offset)
virtual bool updateProperties() override
Called when connected state changes, to add/remove properties.
virtual bool getLocalTime(char *timeString)
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
virtual void ISGetProperties(const char *dev) override
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
@ LX200_HAS_PULSE_GUIDING
@ LX200_HAS_PRECISE_TRACKING_FREQ
@ LX200_HAS_ALIGNMENT_TYPE
@ LX200_HAS_TRACKING_FREQ
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual void getBasicData()
void setLX200Capability(uint32_t cap)
bool AbortRotator() override
AbortRotator Abort all motion.
char OldOSStat[RB_MAX_LEN]
IPState ClearPECBuffer(int axis)
virtual bool Goto(double ra, double dec) override
Move the scope to the supplied RA and DEC coordinates.
INumberVectorProperty BacklashNP
ISwitchVectorProperty AutoFlipSP
INumberVectorProperty FocuserTNP
IPState PECStatus(int axis)
virtual void Init_Outputs()
ITextVectorProperty OnstepStatTP
int getCommandSingleCharResponse(int fd, char *data, const char *cmd)
ISwitch OSFocus1InitializeS[4]
IPState MoveFocuser(FocusDirection dir, int speed, uint16_t duration) override
MoveFocuser the focuser in a particular direction with a specific speed for a finite duration.
int getCommandDoubleResponse(int fd, double *value, char *data, const char *cmd)
ISwitchVectorProperty OSRotatorDerotateSP
INumber ElevationLimitN[2]
int getCommandIntResponse(int fd, int *value, char *data, const char *cmd)
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
OnStepVersion OnStepMountVersion
ITextVectorProperty OSNAlignErrTP
virtual bool setLocalDate(uint8_t days, uint8_t months, uint16_t years) override
ISwitchVectorProperty OSNAlignStarsSP
ISwitchVectorProperty OSOutput1SP
INumberVectorProperty GuideRateNP
ISwitch PreferredPierSideS[3]
ISwitch OSRotatorDerotateS[2]
ISwitchVectorProperty OSNAlignPolarRealignSP
INumberVectorProperty ObjectNoNP
IPState OSDisableOutput(int output)
INumberVectorProperty minutesPastMeridianNP
INumberVectorProperty OSFocus2TargNP
virtual bool setUTCOffset(double offset) override
IPState OSEnableOutput(int output)
ISwitch OSNAlignWriteS[1]
ISwitchVectorProperty PreferredPierSideSP
INumber minutesPastMeridianN[2]
IPState AlignStartGeometric(int stars)
IPState StartPECPlayback(int axis)
bool SetRotatorBacklash(int32_t steps) override
SetRotatorBacklash Set the Rotatorer backlash compensation value.
virtual bool UnPark() override
Unpark the telescope if already parked.
IPState StopPECPlayback(int axis)
INumberVectorProperty OSSetPressureNP
ISwitch OSFocusSelectS[9]
ISwitchVectorProperty OSFocus2MotionSP
ITextVectorProperty OSNAlignTP
IPState SavePECBuffer(int axis)
ISwitchVectorProperty OSPECIndexSP
ISwitch OSFocus2MotionS[3]
ISwitch TFCCompensationS[2]
INumber OSSetTemperatureN[1]
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save parameters ranges in the config file.
ISwitchVectorProperty HomePauseSP
ISwitchVectorProperty TFCCompensationSP
virtual bool Sync(double ra, double dec) override
Set the telescope current RA and DEC coordinates to the supplied RA and DEC coordinates.
INumberVectorProperty OSSetAltitudeNP
virtual void getBasicData() override
virtual bool SetDefaultPark() override
SetDefaultPark Set default coordinates/encoders value as the desired parking position.
ISwitchVectorProperty OSPECStatusSP
IPState MoveRelFocuser(FocusDirection dir, uint32_t ticks) override
MoveFocuser the focuser to an relative position.
ISwitchVectorProperty OSPECRecordSP
bool sendOnStepCommand(const char *cmd)
virtual int setSiteLongitude(int fd, double Long)
long int OSTimeoutMicroSeconds
ISwitchVectorProperty OSFocus2RateSP
IPState MoveAbsFocuser(uint32_t targetTicks) override
MoveFocuser the focuser to an absolute position.
ISwitch FrequencyAdjustS[3]
IPState AlignAddStar()
AlignStartGeometric starts the OnStep Multistar align process.
virtual bool SetTrackEnabled(bool enabled) override
SetTrackEnabled Engages or disengages mount tracking. If there are no tracking modes available,...
ISwitch OSNAlignPolarRealignS[2]
virtual bool initProperties() override
Called to initialize basic properties required all the time.
ISwitchVectorProperty ReticSP
bool sendOnStepCommandBlind(const char *cmd)
INumber OSSetHumidityN[1]
INumber OutputPorts[PORTS_COUNT]
INumber OSSetAltitudeN[1]
IPState StartPECRecord(int axis)
bool OSSupports_bitfield_Gu
virtual int setSiteLatitude(int fd, double Long)
ISwitchVectorProperty OSNAlignWriteSP
long int OSTimeoutSeconds
virtual void SyncParkStatus(bool isparked) override
SyncParkStatus Update the state and switches for parking.
ISwitchVectorProperty FrequencyAdjustSP
INumberVectorProperty TFCCoefficientNP
virtual bool sendScopeLocation() override
int setMinElevationLimit(int fd, int min)
IPState ReadPECBuffer(int axis)
ISwitchVectorProperty OSFocus1InitializeSP
IPState WritePECBuffer(int axis)
ISwitchVectorProperty OSOutput2SP
char OldOSPier[RB_MAX_LEN]
IPState HomeRotator() override
HomeRotator Go to home position.
virtual bool Park() override
Park the telescope to its home position.
virtual void slewError(int slewCode) override
bool SetRotatorBacklashEnabled(bool enabled) override
SetRotatorBacklashEnabled Enables or disables the Rotator backlash compensation.
ISwitchVectorProperty OSPECReadSP
ISwitchVectorProperty SetHomeSP
INumberVectorProperty TFCDeadbandNP
ISwitchVectorProperty TrackAxisSP
INumberVectorProperty ElevationLimitNP
int getCommandSingleCharErrorOrLongResponse(int fd, char *data, const char *cmd)
virtual bool UpdateAlignErr()
virtual bool SetTrackRate(double raRate, double deRate) override
SetTrackRate Set custom tracking rates.
ISwitchVectorProperty OSNAlignSP
INumberVectorProperty OSSetHumidityNP
virtual bool sendScopeTime() override
ISwitch OSNAlignStarsS[9]
ITextVectorProperty VersionTP
bool OSGetOutputState(int output)
virtual bool UpdateAlignStatus()
INumber TFCCoefficientN[1]
IPState MoveRotator(double angle) override
MoveRotator Go to specific angle.
ISwitchVectorProperty TrackCompSP
void PrintTrackState()
PrintTrackState will print to the debug log the status of TrackState if DEBUG_TRACKSTATE is defined o...
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
INumber OSSetPressureN[1]
INumberVectorProperty MaxSlewRateNP
virtual const char * getDefaultName() override
ISwitchVectorProperty OSFocusSelectSP
ITextVectorProperty ObjectInfoTP
INumberVectorProperty OSSetTemperatureNP
virtual void ISGetProperties(const char *dev) override
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
virtual void SetParked(bool isparked) override
SetParked Change the mount parking status. The data park file (stored in ~/.indi/ParkData....
INumberVectorProperty OutputPorts_NP
virtual bool updateLocation(double latitude, double longitude, double elevation) override
Update telescope location settings.
virtual bool updateProperties() override
Called when connected state changes, to add/remove properties.
virtual bool ReadScopeStatus() override
Read telescope status.
bool AbortFocuser() override
AbortFocuser all focus motion.
virtual bool SetCurrentPark() override
SetCurrentPark Set current coordinates/encoders value as the desired parking position.
Provides interface to implement Rotator functionality.
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.
const char * SITE_TAB
SITE_TAB Where all site information setting are located.
const char * FOCUS_TAB
FOCUS_TAB Where all the properties for focuser are located.
void getSexComponentsIID(double value, int *d, int *m, double *s)
int f_scansexa(const char *str0, double *dp)
convert sexagesimal string str AxBxC to double. x can be anything non-numeric. Any missing A,...
void getSexComponents(double value, int *d, int *m, int *s)
int tty_read_section_expanded(int fd, char *buf, char stop_char, long timeout_seconds, long timeout_microseconds, int *nbytes_read)
read buffer from terminal with a delimiter
int tty_write_string(int fd, const char *buf, int *nbytes_written)
Writes a null terminated string to fd.
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_read_expanded(int fd, char *buf, int nbytes, long timeout_seconds, long timeout_microseconds, int *nbytes_read)
read buffer from terminal with a delimiter
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.
int IUUpdateSwitch(ISwitchVectorProperty *svp, ISState *states, char *names[], int n)
Update all switches in a switch vector property.
void IDSetLight(const ILightVectorProperty *lvp, const char *fmt,...)
void IDSetNumber(const INumberVectorProperty *nvp, const char *fmt,...)
void IDSetSwitch(const ISwitchVectorProperty *svp, const char *fmt,...)
int IUGetConfigNumber(const char *dev, const char *property, const char *member, double *value)
IUGetConfigNumber Opens configuration file and reads single number property.
void IDMessage(const char *dev, const char *fmt,...)
void IUUpdateMinMax(const INumberVectorProperty *nvp)
Function to update the min and max elements of a number in the client.
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,...)
#define DEBUGF(priority, msg,...)
std::mutex lx200CommsLock
@ ERR_GOTO_ERR_ABOVE_OVERHEAD
@ ERR_GOTO_ERR_OUTSIDE_LIMITS
@ ERR_GOTO_ERR_BELOW_HORIZON
@ ERR_GOTO_ERR_UNSPECIFIED
@ ERR_GOTO_ERR_HARDWARE_FAULT
int getSiteLongitude(int fd, int *ddd, int *mm, double *ssf)
int getSiteLatitudeAlt(int fd, int *dd, int *mm, double *ssf, const char *cmd)
int setMaxElevationLimit(int fd, int max)
int setObjectRA(int fd, double ra, bool addSpace)
int getLX200EquatorialFormat()
int setStandardProcedure(int fd, const char *data)
int setObjectDEC(int fd, double dec, bool addSpace)
int getSiteLongitudeAlt(int fd, int *ddd, int *mm, double *ssf, const char *cmd)
int getSiteLatitude(int fd, int *dd, int *mm, double *ssf)
int selectCatalogObject(int fd, int catalog, int NNNN)
#define getVersionDate(fd, x)
#define increaseReticleBrightness(fd)
#define getObjectInfo(fd, x)
#define getVersionTime(fd, x)
#define getLX200DEC(fd, x)
#define getVersionNumber(fd, x)
#define getLX200RA(fd, x)
#define decreaseReticleBrightness(fd)
#define getProductName(fd, x)
std::vector< uint8_t > buffer