34#define LAKESIDE_VERSION_MAJOR 1
35#define LAKESIDE_VERSION_MINOR 1
51#define LAKESIDE_TIMEOUT 2
57#define LAKESIDE_TIMEOUT_RETRIES 2
59static 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();
293bool 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);
318bool Lakeside::ReadBuffer(
char * response)
320 int nbytes_read = 0, rc = -1;
329 LOGF_ERROR(
"ReadBuffer: Read failed - %s", errstr);
338 resp[nbytes_read] = 0;
348bool 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);
386bool 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);
436char 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);
514bool 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' )
552bool 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' )
590bool 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' )
624bool 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);
659bool 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);
694bool 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);
729bool 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);
768bool 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);
807bool 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);
842bool 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);
877bool 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);
912bool 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);
947bool 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);
982bool 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);
1021bool Lakeside::setCalibration()
1027bool Lakeside::gotoPosition(uint32_t position)
1040 LOGF_ERROR(
"Position requested (%ld) is out of bounds between %g and %g", position,
FocusAbsPosNP[0].getMin(),
1047 if ( calc_steps < 0 )
1054 if ( calc_steps > 0 )
1063 LOGF_DEBUG(
"MoveFocuser: No steps to move. calc_steps = %d", calc_steps);
1069 tcflush(
PortFD, TCIOFLUSH);
1086 return setBacklash(steps);
1098bool Lakeside::setBacklash(
int backlash )
1103 tcflush(
PortFD, TCIOFLUSH);
1113 if (!ReadBuffer(resp))
1118 if (!strncmp(resp,
"OK#", 3))
1120 LOGF_INFO(
"Backlash steps set to %d", backlash);
1124 LOGF_ERROR(
"setBacklash: Unknown result (%s)", resp);
1135bool Lakeside::setStepSize(
int stepsize )
1140 tcflush(
PortFD, TCIOFLUSH);
1150 if (!ReadBuffer(resp))
1155 if (!strncmp(resp,
"OK#", 3))
1161 LOGF_ERROR(
"setStepSize: Unknown result (%s)", resp);
1172bool Lakeside::setMaxTravel(
int )
1189 tcflush(
PortFD, TCIOFLUSH);
1209 if (!ReadBuffer(resp))
1214 if (!strncmp(resp,
"OK#", 3))
1216 LOGF_DEBUG(
"setMoveDirection: Completed cmd (%s). Result - %s",
cmd, resp);
1218 LOG_INFO(
"Move Direction : Normal");
1220 LOG_INFO(
"Move Direction : Reversed");
1224 LOGF_ERROR(
"setMoveDirection: Unknown result (%s)", resp);
1232bool Lakeside::setTemperatureTracking(
bool enable)
1234 int nbytes_written = 0, rc = -1;
1239 tcflush(
PortFD, TCIOFLUSH);
1249 LOGF_ERROR(
"setTemperatureTracking: Write for command (%s) failed - %s",
cmd, errstr);
1256 LOG_INFO(
"Temperature Tracking : Enabled");
1258 LOG_INFO(
"Temperature Tracking : Disabled");
1268bool Lakeside::setActiveTemperatureSlope(uint32_t active_slope)
1274 tcflush(
PortFD, TCIOFLUSH);
1289 if (!ReadBuffer(resp))
1294 if (!strncmp(resp,
"OK#", 3))
1296 LOGF_INFO(
"Selected Active Temperature Slope is %d", active_slope);
1300 LOGF_ERROR(
"setActiveTemperatureSlope: Unknown result (%s)", resp);
1311bool Lakeside::setSlope1Inc(uint32_t slope1_inc)
1316 tcflush(
PortFD, TCIOFLUSH);
1326 if (!ReadBuffer(resp))
1331 if (!strncmp(resp,
"OK#", 3))
1333 LOGF_INFO(
"Slope 1 0.1 counts per degree set to %d", slope1_inc);
1337 LOGF_ERROR(
"setSlope1Inc: Unknown result (%s)", resp);
1347bool Lakeside::setSlope2Inc(uint32_t slope2_inc)
1352 tcflush(
PortFD, TCIOFLUSH);
1362 if (!ReadBuffer(resp))
1367 if (!strncmp(resp,
"OK#", 3))
1369 LOGF_INFO(
"Slope 2 0.1 counts per degree set to %d", slope2_inc);
1373 LOGF_ERROR(
"setSlope2Inc: Unknown result (%s)", resp);
1383bool Lakeside::setSlope1Dir(uint32_t slope1_direction)
1388 tcflush(
PortFD, TCIOFLUSH);
1398 if (!ReadBuffer(resp))
1403 if (!strncmp(resp,
"OK#", 3))
1405 LOGF_INFO(
"Slope 1 Direction set to %d", slope1_direction);
1409 LOGF_ERROR(
"setSlope1Dir: Unknown result (%s)", resp);
1419bool Lakeside::setSlope2Dir(uint32_t slope2_direction)
1424 tcflush(
PortFD, TCIOFLUSH);
1434 if (!ReadBuffer(resp))
1439 if (!strncmp(resp,
"OK#", 3))
1441 LOGF_INFO(
"Slope 2 Direction set to %d", slope2_direction);
1445 LOGF_ERROR(
"setSlope2Dir: Unknown result (%s)", resp);
1455bool Lakeside::setSlope1Deadband(uint32_t slope1_deadband)
1460 tcflush(
PortFD, TCIOFLUSH);
1470 if (!ReadBuffer(resp))
1475 if (!strncmp(resp,
"OK#", 3))
1477 LOGF_INFO(
"Slope 1 deadband set to %d", slope1_deadband);
1481 LOGF_ERROR(
"setSlope1Deadband: Unknown result (%s)", resp);
1491bool Lakeside::setSlope2Deadband(uint32_t slope2_deadband)
1496 tcflush(
PortFD, TCIOFLUSH);
1506 if (!ReadBuffer(resp))
1511 if (!strncmp(resp,
"OK#", 3))
1513 LOGF_INFO(
"Slope 2 deadband set to %d", slope2_deadband);
1517 LOGF_ERROR(
"setSlope2Deadband: Unknown result (%s)", resp);
1527bool Lakeside::setSlope1Period(uint32_t slope1_period)
1532 tcflush(
PortFD, TCIOFLUSH);
1542 if (!ReadBuffer(resp))
1547 if (!strncmp(resp,
"OK#", 3))
1549 LOGF_INFO(
"Slope 1 Period set to %d", slope1_period);
1553 LOGF_ERROR(
"setSlope1Period: Unknown result (%s)", resp);
1563bool Lakeside::setSlope2Period(uint32_t slope2_period)
1568 tcflush(
PortFD, TCIOFLUSH);
1578 if (!ReadBuffer(resp))
1583 if (!strncmp(resp,
"OK#", 3))
1585 LOGF_INFO(
"Slope 2 Period set to %d", slope2_period);
1589 LOGF_ERROR(
"setSlope2Period: Unknown result (%s)", resp);
1633 if (!strcmp(TemperatureTrackingSP.
name, name))
1638 bool rc = setTemperatureTracking((TemperatureTrackingS[0].s ==
ISS_ON));
1644 TemperatureTrackingS[last_index].s =
ISS_ON;
1649 TemperatureTrackingSP.
s =
IPS_OK;
1656 if (!strcmp(ActiveTemperatureSlopeSP.
name, name))
1668 if (current_slope == target_slope)
1670 ActiveTemperatureSlopeSP.
s =
IPS_OK;
1674 rc = setActiveTemperatureSlope(target_slope);
1680 ActiveTemperatureSlopeS[current_slope].s =
ISS_ON;
1686 ActiveTemperatureSlopeSP.
s =
IPS_OK;
1692 if (!strcmp(Slope1DirSP.
name, name))
1702 if (current_slope_dir1 == target_slope_dir1)
1708 rc = setSlope1Dir(target_slope_dir1);
1713 Slope1DirS[current_slope_dir1].s =
ISS_ON;
1726 if (!strcmp(Slope2DirSP.
name, name))
1736 if (current_slope_dir2 == target_slope_dir2)
1742 rc = setSlope2Dir(target_slope_dir2);
1747 Slope2DirS[current_slope_dir2].s =
ISS_ON;
1834 if (!strcmp (name, StepSizeNP.
name))
1843 if (!strcmp (name, Slope1IncNP.
name))
1845 int new_Slope1Inc = 0 ;
1848 for (nset = i = 0; i < n; i++)
1854 if (eqp == &Slope1IncN[0])
1857 new_Slope1Inc = (values[i]);
1860 nset += new_Slope1Inc >= -0xff && new_Slope1Inc <= 0xff;
1869 if( !setSlope1Inc(new_Slope1Inc))
1873 IDSetNumber(&Slope1IncNP,
"Setting new Slope1 increment failed.");
1879 Slope1IncN[0].value = new_Slope1Inc;
1888 IDSetNumber(&Slope1IncNP,
"Need exactly one parameter.");
1897 if (!strcmp (name, Slope2IncNP.
name))
1899 int new_Slope2Inc = 0 ;
1902 for (nset = i = 0; i < n; i++)
1908 if (eqp == &Slope2IncN[0])
1911 new_Slope2Inc = (values[i]);
1914 nset += new_Slope2Inc >= -0xff && new_Slope2Inc <= 0xff;
1923 if( !setSlope2Inc(new_Slope2Inc))
1927 IDSetNumber(&Slope2IncNP,
"Setting new Slope2 increment failed.");
1933 Slope2IncN[0].value = new_Slope2Inc;
1942 IDSetNumber(&Slope2IncNP,
"Need exactly one parameter.");
1951 if (!strcmp (name, Slope1DeadbandNP.
name))
1953 int new_Slope1Deadband = 0 ;
1956 for (nset = i = 0; i < n; i++)
1962 if (eqp == &Slope1DeadbandN[0])
1965 new_Slope1Deadband = (values[i]);
1968 nset += new_Slope1Deadband >= -0xff && new_Slope1Deadband <= 0xff;
1977 if( !setSlope1Deadband(new_Slope1Deadband))
1981 IDSetNumber(&Slope1DeadbandNP,
"Setting new Slope 1 Deadband failed.");
1987 Slope1DeadbandN[0].value = new_Slope1Deadband;
1996 IDSetNumber(&Slope1DeadbandNP,
"Need exactly one parameter.");
2005 if (!strcmp (name, Slope2DeadbandNP.
name))
2007 int new_Slope2Deadband = 0 ;
2010 for (nset = i = 0; i < n; i++)
2016 if (eqp == &Slope2DeadbandN[0])
2019 new_Slope2Deadband = (values[i]);
2022 nset += new_Slope2Deadband >= -0xff && new_Slope2Deadband <= 0xff;
2031 if( !setSlope2Deadband(new_Slope2Deadband))
2035 IDSetNumber(&Slope2DeadbandNP,
"Setting new Slope 2 Deadband failed.");
2041 Slope2DeadbandN[0].value = new_Slope2Deadband;
2050 IDSetNumber(&Slope2DeadbandNP,
"Need exactly one parameter.");
2059 if (!strcmp (name, Slope1PeriodNP.
name))
2061 int new_Slope1Period = 0 ;
2064 for (nset = i = 0; i < n; i++)
2070 if (eqp == &Slope1PeriodN[0])
2073 new_Slope1Period = (values[i]);
2076 nset += new_Slope1Period >= -0xff && new_Slope1Period <= 0xff;
2085 if( !setSlope1Period(new_Slope1Period))
2089 IDSetNumber(&Slope1PeriodNP,
"Setting new Slope 1 Period failed.");
2095 Slope1PeriodN[0].value = new_Slope1Period;
2104 IDSetNumber(&Slope1PeriodNP,
"Need exactly one parameter.");
2113 if (!strcmp (name, Slope2PeriodNP.
name))
2115 int new_Slope2Period = 0 ;
2118 for (nset = i = 0; i < n; i++)
2124 if (eqp == &Slope2PeriodN[0])
2127 new_Slope2Period = (values[i]);
2130 nset += new_Slope2Period >= -0xff && new_Slope2Period <= 0xff;
2139 if( !setSlope2Period(new_Slope2Period))
2143 IDSetNumber(&Slope2PeriodNP,
"Setting new Slope 2 Period failed.");
2149 Slope2PeriodN[0].value = new_Slope2Period;
2158 IDSetNumber(&Slope2PeriodNP,
"Need exactly one parameter.");
2173void Lakeside::GetFocusParams ()
2175 if (updatePosition())
2178 if (updateTemperature())
2182 if (updateTemperatureK())
2185 if (updateBacklash())
2188 if (updateMaxTravel())
2191 if (updateStepSize())
2194 if (updateMoveDirection())
2197 if (updateSlope1Inc())
2200 if (updateSlope2Inc())
2203 if (updateSlope1Dir())
2206 if (updateSlope2Dir())
2209 if (updateSlope1Deadband())
2212 if (updateSlope2Deadband())
2215 if (updateSlope1Period())
2218 if (updateSlope1Period())
2233 targetPos = targetTicks;
2236 rc = gotoPosition(targetPos);
2246 bool IsMoving =
false;
2261 IsMoving = GetLakesideStatus();
2275 rc = updatePosition();
2285 rc = updateTemperature();
2286 if (rc && fabs(lastTemperature - TemperatureN[0].value) > TEMPERATURE_THRESHOLD)
2289 lastTemperature = TemperatureN[0].value;
2310bool Lakeside::GetLakesideStatus()
2312 int rc = -1, nbytes_read = 0, count_timeouts = 1, pos = 0;
2315 bool read_buffer =
true;
2316 char buffer_response =
'?';
2322 memset(resp, 0,
sizeof(resp));
2329 LOGF_DEBUG(
"GetLakesideStatus: read buffer retry attempts : %d, error=%s", count_timeouts, errstr);
2337 rc = updatePosition();
2344 read_buffer =
false;
2350 LOGF_DEBUG(
"GetLakesideStatus: Read buffer contains : %s", resp);
2353 buffer_response = DecodeBuffer(resp);
2356 if ( buffer_response ==
'D' )
2358 LOG_DEBUG(
"GetLakesideStatus: Found DONE# after move request");
2361 rc = updatePosition();
2372 if ( buffer_response ==
'P' )
2375 rc = sscanf(resp,
"P%5d#", &pos);
2376 LOGF_INFO(
"Focuser Moving... position : %d", pos);
2386 if ( buffer_response ==
'T' )
2388 LOGF_DEBUG(
"GetLakesideStatus: Temperature status response found - %s", resp);
2398 if ( buffer_response ==
'K' )
2400 LOGF_DEBUG(
"GetLakesideStatus: Temperature in K status response found - %s", resp);
2410 LOGF_DEBUG(
"GetLakesideStatus: Unknown response from buffer read : (%s)", resp);
2438 LOGF_ERROR(
"AbortFocuser: Write command (%s) failed - %s",
cmd, errstr);
2446void Lakeside::hexDump(
char * buf,
const char * data,
int size)
2448 for (
int i = 0; i < size; i++)
2449 sprintf(buf + 3 * i,
"%02X ",
static_cast<uint8_t
>(data[i]));
2452 buf[3 * size - 1] =
'\0';
virtual const char * port()
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.
INDI::PropertySwitch FocusReverseSP
void SetCapability(uint32_t cap)
FI::SetCapability sets the focuser capabilities. All capabilities must be initialized.
INDI::PropertyNumber FocusMaxPosNP
INDI::PropertyNumber FocusBacklashNP
INDI::PropertyNumber FocusAbsPosNP
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Processes incoming new switch states from the client for this device. Handles updates to FocuserInter...
virtual bool updateProperties() override
Updates the state and definition of properties based on the current connection status....
virtual bool initProperties() override
Initializes the default properties for the focuser device. Sets up standard INDI properties,...
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Processes incoming new number values from the client for this device. Handles updates to FocuserInter...
Connection::Serial * serialConnection
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
void setPermission(IPerm permission)
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
Initializes the default properties for the focuser device. Sets up standard INDI properties,...
virtual void TimerHit() override
Callback function to be called once SetTimer duration elapses.
const char * getDefaultName() override
virtual bool SetFocuserBacklashEnabled(bool enabled) override
SetFocuserBacklashEnabled Enables or disables the focuser backlash compensation.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Processes incoming new number values from the client for this device. Handles updates to FocuserInter...
virtual bool updateProperties() override
Updates the state and definition of properties based on the current connection status....
virtual bool Handshake() override
Performs a device-specific handshake after a connection is established. This method should be overrid...
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Processes incoming new switch states from the client for this device. Handles updates to FocuserInter...
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.
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.
INumber * IUFindNumber(const INumberVectorProperty *nvp, const char *name)
Find an INumber member in a number text property.
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