34 #define LAKESIDE_VERSION_MAJOR 1
35 #define LAKESIDE_VERSION_MINOR 1
51 #define LAKESIDE_TIMEOUT 2
52 #define LAKESIDE_LEN 7
57 #define LAKESIDE_TIMEOUT_RETRIES 2
59 static std::unique_ptr<Lakeside> lakeside(
new Lakeside());
83 IUFillNumber(&TemperatureN[0],
"TEMPERATURE",
"Celsius",
"%3.2f", -50, 70., 0., 0.);
88 IUFillNumber(&TemperatureKN[0],
"TEMPERATUREK",
"Kelvin",
"%3.2f", 0., 373.15, 0., 0.);
112 IUFillNumber(&StepSizeN[0],
"STEPSIZE",
"No. Steps",
"%.f", 1, 65536, 0, 1);
129 IUFillNumber(&Slope1IncN[0],
"SLOPE1INC",
"No. Steps (0-655356",
"%.f", 0, 65536, 0, 0);
134 IUFillNumber(&Slope1DeadbandN[0],
"SLOPE1DEADBAND",
"(0-255)",
"%.f", 0, 255, 0, 0);
139 IUFillNumber(&Slope1PeriodN[0],
"SLOPE1PERIOD",
"Minutes (0-99)",
"%.f", 0, 99, 0, 0);
150 IUFillNumber(&Slope2IncN[0],
"SLOPE2INC",
"No. Steps (0-65536)",
"%.f", 0, 65536, 0, 0);
155 IUFillNumber(&Slope2DeadbandN[0],
"SLOPE2DEADBAND",
"Steps (0-255)",
"%.f", 0, 255, 0, 0);
160 IUFillNumber(&Slope2PeriodN[0],
"SLOPE2PERIOD",
"Minutes (0-99)",
"%.f", 0, 99, 0, 0);
202 LOG_INFO(
"Lakeside parameters updated, focuser ready for use.");
251 if (LakesideOnline())
259 LOGF_INFO(
"Unable to connect to Lakeside Focuser. Please ensure the controller is powered on and the port (%s) is correct.",
276 return LakesideOnline();
293 bool Lakeside::SendCmd(
const char * in_cmd)
295 int nbytes_written = 0, rc = -1;
303 LOGF_ERROR(
"SendCmd: Write for command (%s) failed - %s", in_cmd, errstr);
318 bool Lakeside::ReadBuffer(
char * response)
320 int nbytes_read = 0, rc = -1;
329 LOGF_ERROR(
"ReadBuffer: Read failed - %s", errstr);
338 resp[nbytes_read] = 0;
348 bool Lakeside::LakesideOnline()
351 const char *
cmd =
"??#";
362 if (!ReadBuffer(resp))
368 LOGF_DEBUG(
"LakesideOnline: Received (%s)", resp);
370 if (!strncmp(resp,
"OK#", 3))
372 LOG_DEBUG(
"LakesideOnline: Received OK# - Lakeside responded");
377 LOGF_ERROR(
"LakesideOnline: OK# not found. Instead, received (%s)", resp);
386 bool Lakeside::updateMoveDirection()
397 if (!ReadBuffer(resp))
406 sscanf(resp,
"D%5d#", &temp);
411 LOGF_DEBUG(
"updateMoveDirection: Move Direction is (%d)", temp);
416 LOGF_DEBUG(
"updateMoveDirection: Move Direction is (%d)", temp);
420 LOGF_ERROR(
"updateMoveDirection: Unknown move Direction response (%s)", resp);
436 char Lakeside::DecodeBuffer(
char * in_response)
438 int temp = 0, pos = 0, rc = -1;
440 LOGF_DEBUG(
"DecodeBuffer: in_response (%s)", in_response);
443 if (!strncmp(in_response,
"DONE#", 5))
449 if (!strncmp(in_response,
"OK#", 3))
455 if (!strncmp(in_response,
"!#", 2))
461 if (!strcmp(
"TN/A#", in_response))
468 rc = sscanf(in_response,
"T%5d#", &temp);
472 TemperatureN[0].value = ((int) temp) / 2.0;
473 LOGF_DEBUG(
"DecodeBuffer: Result (%3.1f)", TemperatureN[0].value);
480 rc = sscanf(in_response,
"K%5d#", &temp);
484 TemperatureKN[0].value = ((int) temp) / 2.00;
485 LOGF_DEBUG(
"DecodeBuffer: Result (%3.2f)", TemperatureKN[0].value);
491 rc = sscanf(in_response,
"P%5d#", &pos);
498 LOGF_DEBUG(
"DecodeBuffer: Returned position (%d)", pos);
503 LOGF_ERROR(
"DecodeBuffer: Unknown response : (%s)", in_response);
514 bool Lakeside::updateTemperature()
518 char buffer_response =
'?';
525 if (!ReadBuffer(resp))
530 LOGF_DEBUG(
"updateTemperature: Read response (%s)", resp);
533 buffer_response = DecodeBuffer(resp);
536 if ( buffer_response ==
'T' )
552 bool Lakeside::updateTemperatureK()
556 char buffer_response =
'?';
563 if (!ReadBuffer(resp))
568 LOGF_DEBUG(
"updateTemperatureK: Read response (%s)", resp);
571 buffer_response = DecodeBuffer(resp);
574 if ( buffer_response ==
'K' )
590 bool Lakeside::updatePosition()
594 char buffer_response =
'?';
603 if (!ReadBuffer(resp))
608 LOGF_DEBUG(
"updatePosition: Fetched (%s)", resp);
611 buffer_response = DecodeBuffer(resp);
613 if ( buffer_response ==
'P' )
624 bool Lakeside::updateBacklash()
635 if (!ReadBuffer(resp))
642 sscanf(resp,
"B%5d#", &temp);
647 LOGF_DEBUG(
"updateBacklash: Backlash is (%d)", temp);
651 LOGF_ERROR(
"updateBacklash: Backlash request error (%s)", resp);
659 bool Lakeside::updateSlope1Inc()
670 if (!ReadBuffer(resp))
677 sscanf(resp,
"1%5d#", &temp);
681 Slope1IncN[0].value = temp;
682 LOGF_DEBUG(
"updateSlope1Inc: Slope 1 Increments is (%d)", temp);
686 LOGF_ERROR(
"updateSlope1Inc: Slope 1 Increment request error (%s)", resp);
694 bool Lakeside::updateSlope2Inc()
705 if (!ReadBuffer(resp))
712 sscanf(resp,
"2%5d#", &temp);
716 Slope2IncN[0].value = temp;
717 LOGF_DEBUG(
"updateSlope2Inc: Slope 2 Increments is (%d)", temp);
721 LOGF_ERROR(
"updateSlope2Inc: Slope 2 Increment request error (%s)", resp);
729 bool Lakeside::updateSlope1Dir()
740 if (!ReadBuffer(resp))
747 sscanf(resp,
"a%5d#", &temp);
752 LOGF_DEBUG(
"updateSlope1Dir: Slope 1 Direction is (%d)", temp);
760 LOGF_ERROR(
"updateSlope1Dir: Unknown Slope 1 Direction response (%s)", resp);
768 bool Lakeside::updateSlope2Dir()
779 if (!ReadBuffer(resp))
786 sscanf(resp,
"b%5d#", &temp);
791 LOGF_DEBUG(
"updateSlope2Dir: Slope 2 Direction is (%d)", temp);
799 LOGF_ERROR(
"updateSlope2Dir: Unknown Slope 2 Direction response (%s)", resp);
807 bool Lakeside::updateSlope1Deadband()
818 if (!ReadBuffer(resp))
825 sscanf(resp,
"c%5d#", &temp);
829 Slope1DeadbandN[0].value = temp;
830 LOGF_DEBUG(
"updateSlope1Deadband: Slope 1 Deadband is (%d)", temp);
834 LOGF_ERROR(
"updateSlope1Deadband: Slope 1 Deadband request error (%s)", resp);
842 bool Lakeside::updateSlope2Deadband()
853 if (!ReadBuffer(resp))
860 sscanf(resp,
"d%5d#", &temp);
864 Slope2DeadbandN[0].value = temp;
865 LOGF_DEBUG(
"updateSlope2Deadband: Slope 2 Deadband is (%d)", temp);
869 LOGF_ERROR(
"updateSlope2Deadband: Slope 2 Deadband request error (%s)", resp);
877 bool Lakeside::updateSlope1Period()
888 if (!ReadBuffer(resp))
895 sscanf(resp,
"e%5d#", &temp);
899 Slope1PeriodN[0].value = temp;
900 LOGF_DEBUG(
"updateSlope1Period: Slope 1 Period is (%d)", temp);
904 LOGF_ERROR(
"updateSlope1Period: Slope 1 Period request error (%s)", resp);
912 bool Lakeside::updateSlope2Period()
923 if (!ReadBuffer(resp))
930 sscanf(resp,
"f%5d#", &temp);
934 Slope2PeriodN[0].value = temp;
935 LOGF_DEBUG(
"updateSlope2Period: Slope 2 Period is (%d)", temp);
939 LOGF_ERROR(
"updateSlope2Period: Slope 2 Period request error (%s)", resp);
947 bool Lakeside::updateMaxTravel()
958 if (!ReadBuffer(resp))
965 sscanf(resp,
"I%5d#", &temp);
970 LOGF_DEBUG(
"updateMaxTravel: MaxTravel is (%d)", temp);
974 LOGF_ERROR(
"updateMaxTravel: MaxTravel request error (%s)", resp);
982 bool Lakeside::updateStepSize()
995 if (!ReadBuffer(resp))
1002 sscanf(resp,
"S%5d#", &temp);
1006 StepSizeN[0].value = temp;
1007 LOGF_DEBUG(
"updateStepSize: step size is (%d)", temp);
1011 LOGF_ERROR(
"updateStepSize: StepSize request error (%s)", resp);
1021 bool Lakeside::setCalibration()
1027 bool Lakeside::gotoPosition(uint32_t position)
1047 if ( calc_steps < 0 )
1049 sprintf(
cmd,
"CO%d#", abs(calc_steps));
1054 if ( calc_steps > 0 )
1057 sprintf(
cmd,
"CI%d#", calc_steps);
1063 LOGF_DEBUG(
"MoveFocuser: No steps to move. calc_steps = %d", calc_steps);
1069 tcflush(
PortFD, TCIOFLUSH);
1086 return setBacklash(steps);
1092 bool Lakeside::setBacklash(
int backlash )
1097 tcflush(
PortFD, TCIOFLUSH);
1100 sprintf(
cmd,
"CRB%d#", backlash);
1107 if (!ReadBuffer(resp))
1112 if (!strncmp(resp,
"OK#", 3))
1114 LOGF_INFO(
"Backlash steps set to %d", backlash);
1118 LOGF_ERROR(
"setBacklash: Unknown result (%s)", resp);
1129 bool Lakeside::setStepSize(
int stepsize )
1134 tcflush(
PortFD, TCIOFLUSH);
1137 sprintf(
cmd,
"CRS%d#", stepsize);
1144 if (!ReadBuffer(resp))
1149 if (!strncmp(resp,
"OK#", 3))
1155 LOGF_ERROR(
"setStepSize: Unknown result (%s)", resp);
1166 bool Lakeside::setMaxTravel(
int )
1183 tcflush(
PortFD, TCIOFLUSH);
1203 if (!ReadBuffer(resp))
1208 if (!strncmp(resp,
"OK#", 3))
1210 LOGF_DEBUG(
"setMoveDirection: Completed cmd (%s). Result - %s",
cmd, resp);
1212 LOG_INFO(
"Move Direction : Normal");
1214 LOG_INFO(
"Move Direction : Reversed");
1218 LOGF_ERROR(
"setMoveDirection: Unknown result (%s)", resp);
1226 bool Lakeside::setTemperatureTracking(
bool enable)
1228 int nbytes_written = 0, rc = -1;
1233 tcflush(
PortFD, TCIOFLUSH);
1243 LOGF_ERROR(
"setTemperatureTracking: Write for command (%s) failed - %s",
cmd, errstr);
1250 LOG_INFO(
"Temperature Tracking : Enabled");
1252 LOG_INFO(
"Temperature Tracking : Disabled");
1262 bool Lakeside::setActiveTemperatureSlope(uint32_t active_slope)
1268 tcflush(
PortFD, TCIOFLUSH);
1274 sprintf(
cmd,
"CRg%d#", active_slope);
1283 if (!ReadBuffer(resp))
1288 if (!strncmp(resp,
"OK#", 3))
1290 LOGF_INFO(
"Selected Active Temperature Slope is %d", active_slope);
1294 LOGF_ERROR(
"setActiveTemperatureSlope: Unknown result (%s)", resp);
1305 bool Lakeside::setSlope1Inc(uint32_t slope1_inc)
1310 tcflush(
PortFD, TCIOFLUSH);
1313 sprintf(
cmd,
"CR1%d#", slope1_inc);
1320 if (!ReadBuffer(resp))
1325 if (!strncmp(resp,
"OK#", 3))
1327 LOGF_INFO(
"Slope 1 0.1 counts per degree set to %d", slope1_inc);
1331 LOGF_ERROR(
"setSlope1Inc: Unknown result (%s)", resp);
1341 bool Lakeside::setSlope2Inc(uint32_t slope2_inc)
1346 tcflush(
PortFD, TCIOFLUSH);
1349 sprintf(
cmd,
"CR2%d#", slope2_inc);
1356 if (!ReadBuffer(resp))
1361 if (!strncmp(resp,
"OK#", 3))
1363 LOGF_INFO(
"Slope 2 0.1 counts per degree set to %d", slope2_inc);
1367 LOGF_ERROR(
"setSlope2Inc: Unknown result (%s)", resp);
1377 bool Lakeside::setSlope1Dir(uint32_t slope1_direction)
1382 tcflush(
PortFD, TCIOFLUSH);
1385 sprintf(
cmd,
"CRa%d#", slope1_direction);
1392 if (!ReadBuffer(resp))
1397 if (!strncmp(resp,
"OK#", 3))
1399 LOGF_INFO(
"Slope 1 Direction set to %d", slope1_direction);
1403 LOGF_ERROR(
"setSlope1Dir: Unknown result (%s)", resp);
1413 bool Lakeside::setSlope2Dir(uint32_t slope2_direction)
1418 tcflush(
PortFD, TCIOFLUSH);
1421 sprintf(
cmd,
"CRb%d#", slope2_direction);
1428 if (!ReadBuffer(resp))
1433 if (!strncmp(resp,
"OK#", 3))
1435 LOGF_INFO(
"Slope 2 Direction set to %d", slope2_direction);
1439 LOGF_ERROR(
"setSlope2Dir: Unknown result (%s)", resp);
1449 bool Lakeside::setSlope1Deadband(uint32_t slope1_deadband)
1454 tcflush(
PortFD, TCIOFLUSH);
1457 sprintf(
cmd,
"CRc%d#", slope1_deadband);
1464 if (!ReadBuffer(resp))
1469 if (!strncmp(resp,
"OK#", 3))
1471 LOGF_INFO(
"Slope 1 deadband set to %d", slope1_deadband);
1475 LOGF_ERROR(
"setSlope1Deadband: Unknown result (%s)", resp);
1485 bool Lakeside::setSlope2Deadband(uint32_t slope2_deadband)
1490 tcflush(
PortFD, TCIOFLUSH);
1493 sprintf(
cmd,
"CRd%d#", slope2_deadband);
1500 if (!ReadBuffer(resp))
1505 if (!strncmp(resp,
"OK#", 3))
1507 LOGF_INFO(
"Slope 2 deadband set to %d", slope2_deadband);
1511 LOGF_ERROR(
"setSlope2Deadband: Unknown result (%s)", resp);
1521 bool Lakeside::setSlope1Period(uint32_t slope1_period)
1526 tcflush(
PortFD, TCIOFLUSH);
1529 sprintf(
cmd,
"CRe%d#", slope1_period);
1536 if (!ReadBuffer(resp))
1541 if (!strncmp(resp,
"OK#", 3))
1543 LOGF_INFO(
"Slope 1 Period set to %d", slope1_period);
1547 LOGF_ERROR(
"setSlope1Period: Unknown result (%s)", resp);
1557 bool Lakeside::setSlope2Period(uint32_t slope2_period)
1562 tcflush(
PortFD, TCIOFLUSH);
1565 sprintf(
cmd,
"CRf%d#", slope2_period);
1572 if (!ReadBuffer(resp))
1577 if (!strncmp(resp,
"OK#", 3))
1579 LOGF_INFO(
"Slope 2 Period set to %d", slope2_period);
1583 LOGF_ERROR(
"setSlope2Period: Unknown result (%s)", resp);
1627 if (!strcmp(TemperatureTrackingSP.
name, name))
1632 bool rc = setTemperatureTracking((TemperatureTrackingS[0].s ==
ISS_ON));
1638 TemperatureTrackingS[last_index].s =
ISS_ON;
1643 TemperatureTrackingSP.
s =
IPS_OK;
1650 if (!strcmp(ActiveTemperatureSlopeSP.
name, name))
1662 if (current_slope == target_slope)
1664 ActiveTemperatureSlopeSP.
s =
IPS_OK;
1668 rc = setActiveTemperatureSlope(target_slope);
1674 ActiveTemperatureSlopeS[current_slope].s =
ISS_ON;
1680 ActiveTemperatureSlopeSP.
s =
IPS_OK;
1686 if (!strcmp(Slope1DirSP.
name, name))
1696 if (current_slope_dir1 == target_slope_dir1)
1702 rc = setSlope1Dir(target_slope_dir1);
1707 Slope1DirS[current_slope_dir1].s =
ISS_ON;
1720 if (!strcmp(Slope2DirSP.
name, name))
1730 if (current_slope_dir2 == target_slope_dir2)
1736 rc = setSlope2Dir(target_slope_dir2);
1741 Slope2DirS[current_slope_dir2].s =
ISS_ON;
1828 if (!strcmp (name, StepSizeNP.
name))
1837 if (!strcmp (name, Slope1IncNP.
name))
1839 int new_Slope1Inc = 0 ;
1842 for (nset = i = 0; i < n; i++)
1848 if (eqp == &Slope1IncN[0])
1851 new_Slope1Inc = (values[i]);
1854 nset += new_Slope1Inc >= -0xff && new_Slope1Inc <= 0xff;
1863 if( !setSlope1Inc(new_Slope1Inc))
1867 IDSetNumber(&Slope1IncNP,
"Setting new Slope1 increment failed.");
1873 Slope1IncN[0].value = new_Slope1Inc;
1882 IDSetNumber(&Slope1IncNP,
"Need exactly one parameter.");
1891 if (!strcmp (name, Slope2IncNP.
name))
1893 int new_Slope2Inc = 0 ;
1896 for (nset = i = 0; i < n; i++)
1902 if (eqp == &Slope2IncN[0])
1905 new_Slope2Inc = (values[i]);
1908 nset += new_Slope2Inc >= -0xff && new_Slope2Inc <= 0xff;
1917 if( !setSlope2Inc(new_Slope2Inc))
1921 IDSetNumber(&Slope2IncNP,
"Setting new Slope2 increment failed.");
1927 Slope2IncN[0].value = new_Slope2Inc;
1936 IDSetNumber(&Slope2IncNP,
"Need exactly one parameter.");
1945 if (!strcmp (name, Slope1DeadbandNP.
name))
1947 int new_Slope1Deadband = 0 ;
1950 for (nset = i = 0; i < n; i++)
1956 if (eqp == &Slope1DeadbandN[0])
1959 new_Slope1Deadband = (values[i]);
1962 nset += new_Slope1Deadband >= -0xff && new_Slope1Deadband <= 0xff;
1971 if( !setSlope1Deadband(new_Slope1Deadband))
1975 IDSetNumber(&Slope1DeadbandNP,
"Setting new Slope 1 Deadband failed.");
1981 Slope1DeadbandN[0].value = new_Slope1Deadband;
1990 IDSetNumber(&Slope1DeadbandNP,
"Need exactly one parameter.");
1999 if (!strcmp (name, Slope2DeadbandNP.
name))
2001 int new_Slope2Deadband = 0 ;
2004 for (nset = i = 0; i < n; i++)
2010 if (eqp == &Slope2DeadbandN[0])
2013 new_Slope2Deadband = (values[i]);
2016 nset += new_Slope2Deadband >= -0xff && new_Slope2Deadband <= 0xff;
2025 if( !setSlope2Deadband(new_Slope2Deadband))
2029 IDSetNumber(&Slope2DeadbandNP,
"Setting new Slope 2 Deadband failed.");
2035 Slope2DeadbandN[0].value = new_Slope2Deadband;
2044 IDSetNumber(&Slope2DeadbandNP,
"Need exactly one parameter.");
2053 if (!strcmp (name, Slope1PeriodNP.
name))
2055 int new_Slope1Period = 0 ;
2058 for (nset = i = 0; i < n; i++)
2064 if (eqp == &Slope1PeriodN[0])
2067 new_Slope1Period = (values[i]);
2070 nset += new_Slope1Period >= -0xff && new_Slope1Period <= 0xff;
2079 if( !setSlope1Period(new_Slope1Period))
2083 IDSetNumber(&Slope1PeriodNP,
"Setting new Slope 1 Period failed.");
2089 Slope1PeriodN[0].value = new_Slope1Period;
2098 IDSetNumber(&Slope1PeriodNP,
"Need exactly one parameter.");
2107 if (!strcmp (name, Slope2PeriodNP.
name))
2109 int new_Slope2Period = 0 ;
2112 for (nset = i = 0; i < n; i++)
2118 if (eqp == &Slope2PeriodN[0])
2121 new_Slope2Period = (values[i]);
2124 nset += new_Slope2Period >= -0xff && new_Slope2Period <= 0xff;
2133 if( !setSlope2Period(new_Slope2Period))
2137 IDSetNumber(&Slope2PeriodNP,
"Setting new Slope 2 Period failed.");
2143 Slope2PeriodN[0].value = new_Slope2Period;
2152 IDSetNumber(&Slope2PeriodNP,
"Need exactly one parameter.");
2167 void Lakeside::GetFocusParams ()
2169 if (updatePosition())
2172 if (updateTemperature())
2176 if (updateTemperatureK())
2179 if (updateBacklash())
2182 if (updateMaxTravel())
2185 if (updateStepSize())
2188 if (updateMoveDirection())
2191 if (updateSlope1Inc())
2194 if (updateSlope2Inc())
2197 if (updateSlope1Dir())
2200 if (updateSlope2Dir())
2203 if (updateSlope1Deadband())
2206 if (updateSlope2Deadband())
2209 if (updateSlope1Period())
2212 if (updateSlope1Period())
2227 targetPos = targetTicks;
2230 rc = gotoPosition(targetPos);
2240 bool IsMoving =
false;
2255 IsMoving = GetLakesideStatus();
2269 rc = updatePosition();
2279 rc = updateTemperature();
2280 if (rc && fabs(lastTemperature - TemperatureN[0].value) > TEMPERATURE_THRESHOLD)
2283 lastTemperature = TemperatureN[0].value;
2304 bool Lakeside::GetLakesideStatus()
2306 int rc = -1, nbytes_read = 0, count_timeouts = 1, pos = 0;
2309 bool read_buffer =
true;
2310 char buffer_response =
'?';
2316 memset(resp, 0,
sizeof(resp));
2323 LOGF_DEBUG(
"GetLakesideStatus: read buffer retry attempts : %d, error=%s", count_timeouts, errstr);
2331 rc = updatePosition();
2338 read_buffer =
false;
2344 LOGF_DEBUG(
"GetLakesideStatus: Read buffer contains : %s", resp);
2347 buffer_response = DecodeBuffer(resp);
2350 if ( buffer_response ==
'D' )
2352 LOG_DEBUG(
"GetLakesideStatus: Found DONE# after move request");
2355 rc = updatePosition();
2366 if ( buffer_response ==
'P' )
2369 rc = sscanf(resp,
"P%5d#", &pos);
2370 LOGF_INFO(
"Focuser Moving... position : %d", pos);
2380 if ( buffer_response ==
'T' )
2382 LOGF_DEBUG(
"GetLakesideStatus: Temperature status response found - %s", resp);
2392 if ( buffer_response ==
'K' )
2394 LOGF_DEBUG(
"GetLakesideStatus: Temperature in K status response found - %s", resp);
2404 LOGF_DEBUG(
"GetLakesideStatus: Unknown response from buffer read : (%s)", resp);
2432 LOGF_ERROR(
"AbortFocuser: Write command (%s) failed - %s",
cmd, errstr);
2440 void Lakeside::hexDump(
char * buf,
const char * data,
int size)
2442 for (
int i = 0; i < size; i++)
2443 sprintf(buf + 3 * i,
"%02X ",
static_cast<uint8_t
>(data[i]));
2446 buf[3 * size - 1] =
'\0';
virtual const char * port()
const char * getDeviceName() const
virtual bool Disconnect()
Disconnect from device.
void setDefaultPollingPeriod(uint32_t msec)
setDefaultPollingPeriod Change the default polling period to call TimerHit() function in the driver.
void setVersion(uint16_t vMajor, uint16_t vMinor)
Set driver version information to be defined in DRIVER_INFO property as vMajor.vMinor.
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
void defineProperty(INumberVectorProperty *property)
uint32_t getCurrentPollingPeriod() const
getCurrentPollingPeriod Return the current polling period.
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
virtual bool Connect()
Connect to the device. INDI::DefaultDevice implementation connects to appropriate connection interfac...
void addDebugControl()
Add Debug control to the driver.
INumberVectorProperty FocusBacklashNP
INumberVectorProperty FocusAbsPosNP
ISwitchVectorProperty FocusReverseSP
void SetCapability(uint32_t cap)
FI::SetCapability sets the focuser capabilities. All capabilities must be initialized.
INumber FocusBacklashN[1]
INumberVectorProperty FocusMaxPosNP
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
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
Connection::Serial * serialConnection
virtual IPState MoveAbsFocuser(uint32_t ticks) override
MoveFocuser the focuser to an absolute position.
virtual bool AbortFocuser() override
AbortFocuser all focus motion.
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
virtual void TimerHit() override
Callback function to be called once SetTimer duration elapses.
const char * getDefaultName() override
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 Handshake() override
perform handshake with device to check communication
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual bool SetFocuserBacklash(int32_t steps) override
SetFocuserBacklash Set the focuser backlash compensation value.
virtual bool ReverseFocuser(bool enabled) override
ReverseFocuser Reverse focuser motion direction.
virtual IPState MoveRelFocuser(FocusDirection dir, uint32_t ticks) override
MoveFocuser the focuser to an relative position.
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
int tty_read_section(int fd, char *buf, char stop_char, int timeout, int *nbytes_read)
read buffer from terminal with a delimiter
int tty_connect(const char *device, int bit_rate, int word_size, int parity, int stop_bits, int *fd)
Establishes a tty connection to a terminal device.
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.
Implementations for common driver routines.
void IUFillNumberVector(INumberVectorProperty *nvp, INumber *np, int nnp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a number vector property. The vector's auxiliary elements will be set to NULL.
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 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 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.
int IUUpdateSwitch(ISwitchVectorProperty *svp, ISState *states, char *names[], int n)
Update all switches in a switch vector 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.
#define LOGF_INFO(fmt,...)
#define LOGF_DEBUG(fmt,...)
#define LOGF_ERROR(fmt,...)
#define LAKESIDE_VERSION_MAJOR
#define LAKESIDE_VERSION_MINOR
#define LAKESIDE_TIMEOUT_RETRIES