Instrument Neutral Distributed Interface INDI  2.0.2
pegasus_focuscube.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2  Copyright(c) 2021 Chrysikos Efstathios. All rights reserved.
3 
4  Pegasus FocusCube
5 
6  This program is free software; you can redistribute it and/or modify it
7  under the terms of the GNU General Public License as published by the Free
8  Software Foundation; either version 2 of the License, or (at your option)
9  any later version.
10 
11  This program is distributed in the hope that it will be useful, but WITHOUT
12  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14  more details.
15 
16  You should have received a copy of the GNU Library General Public License
17  along with this library; see the file COPYING.LIB. If not, write to
18  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  Boston, MA 02110-1301, USA.
20 
21  The full GNU General Public License is included in this distribution in the
22  file called LICENSE.
23 *******************************************************************************/
24 #include "pegasus_focuscube.h"
25 
26 #include "indicom.h"
28 
29 #include <cmath>
30 #include <cstring>
31 #include <memory>
32 
33 #include <termios.h>
34 #include <unistd.h>
35 
36 #define DMFC_TIMEOUT 3
37 #define FOCUS_SETTINGS_TAB "Settings"
38 #define TEMPERATURE_THRESHOLD 0.1
39 
40 static std::unique_ptr<PegasusFocusCube> focusCube(new PegasusFocusCube());
41 
43 {
44  // Can move in Absolute & Relative motions, can AbortFocuser motion.
51 }
52 
54 {
56 
57  // Focuser temperature
58  IUFillNumber(&TemperatureN[0], "TEMPERATURE", "Celsius", "%6.2f", -50, 70., 0., 0.);
59  IUFillNumberVector(&TemperatureNP, TemperatureN, 1, getDeviceName(), "FOCUS_TEMPERATURE", "Temperature",
61 
62  // Max Speed
63  IUFillNumber(&MaxSpeedN[0], "Value", "", "%6.2f", 100, 1000., 100., 400.);
64  IUFillNumberVector(&MaxSpeedNP, MaxSpeedN, 1, getDeviceName(), "MaxSpeed", "", FOCUS_SETTINGS_TAB, IP_RW, 0, IPS_IDLE);
65 
66  // Encoders
67  IUFillSwitch(&EncoderS[ENCODERS_ON], "On", "", ISS_ON);
68  IUFillSwitch(&EncoderS[ENCODERS_OFF], "Off", "", ISS_OFF);
69  IUFillSwitchVector(&EncoderSP, EncoderS, 2, getDeviceName(), "Encoders", "", FOCUS_SETTINGS_TAB, IP_RW, ISR_1OFMANY, 0,
70  IPS_IDLE);
71 
72  // LED
73  IUFillSwitch(&LEDS[LED_OFF], "Off", "", ISS_ON);
74  IUFillSwitch(&LEDS[LED_ON], "On", "", ISS_OFF);
75  IUFillSwitchVector(&LEDSP, LEDS, 2, getDeviceName(), "LED", "", FOCUS_SETTINGS_TAB, IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
76 
77  // Firmware Version
78  IUFillText(&FirmwareVersionT[0], "Version", "Version", "");
79  IUFillTextVector(&FirmwareVersionTP, FirmwareVersionT, 1, getDeviceName(), "Firmware", "Firmware", MAIN_CONTROL_TAB, IP_RO,
80  0, IPS_IDLE);
81 
82  // Relative and absolute movement
83  FocusRelPosN[0].min = 0.;
84  FocusRelPosN[0].max = 50000.;
85  FocusRelPosN[0].value = 0;
86  FocusRelPosN[0].step = 1000;
87 
88  FocusAbsPosN[0].min = 0.;
89  FocusAbsPosN[0].value = 0;
90  FocusAbsPosN[0].step = 1000;
91 
92  // Backlash compensation
93  FocusBacklashN[0].min = 1; // 0 is off.
94  FocusBacklashN[0].max = 1000;
95  FocusBacklashN[0].value = 1;
96  FocusBacklashN[0].step = 1;
97 
98  FocusMaxPosN[0].max = 1317500;
99  FocusMaxPosN[0].value = 1317500;
100  FocusAbsPosN[0].max = 1317500;
101 
102  //LED Default ON
103  LEDS[LED_ON].s = ISS_ON;
104  LEDS[LED_OFF].s = ISS_OFF;
105 
106  addDebugControl();
109 
110  return true;
111 }
112 
114 {
116 
117  if (isConnected())
118  {
119  defineProperty(&MaxSpeedNP);
120  defineProperty(&TemperatureNP);
121  defineProperty(&EncoderSP);
122  defineProperty(&LEDSP);
123  defineProperty(&FirmwareVersionTP);
124  }
125  else
126  {
127  deleteProperty(MaxSpeedNP.name);
128  deleteProperty(TemperatureNP.name);
129  deleteProperty(EncoderSP.name);
130  deleteProperty(LEDSP.name);
131  deleteProperty(FirmwareVersionTP.name);
132  }
133 
134  return true;
135 }
136 
138 {
139  if (ack())
140  {
141  LOGF_INFO("%s is online. Getting focus parameters...", this->getDeviceName());
142  return true;
143  }
144 
145  LOGF_INFO(
146  "Error retrieving data from %s, please ensure device is powered and the port is correct.", this->getDeviceName());
147  return false;
148 }
149 
151 {
152  return "Pegasus FocusCube";
153 }
154 
155 bool PegasusFocusCube::ack()
156 {
157  int nbytes_written = 0, nbytes_read = 0, rc = -1;
158  char errstr[MAXRBUF];
159  char cmd[2] = {0};
160  char res[16] = {0};
161 
162  cmd[0] = '#';
163  cmd[1] = 0xA;
164 
165  LOGF_DEBUG("CMD <%#02X>", cmd[0]);
166 
167  tcflush(PortFD, TCIOFLUSH);
168 
169  if ((rc = tty_write(PortFD, cmd, 2, &nbytes_written)) != TTY_OK)
170  {
171  tty_error_msg(rc, errstr, MAXRBUF);
172  LOGF_ERROR("Ack error: %s.", errstr);
173  return false;
174  }
175 
176  if ((rc = tty_read_section(PortFD, res, 0xA, DMFC_TIMEOUT, &nbytes_read)) != TTY_OK)
177  {
178  tty_error_msg(rc, errstr, MAXRBUF);
179  LOGF_ERROR("Ack error: %s.", errstr);
180  return false;
181  }
182 
183  // Get rid of 0xA
184  res[nbytes_read - 1] = 0;
185 
186 
187  if( res[nbytes_read - 2] == '\r') res[nbytes_read - 2] = 0;
188 
189  LOGF_DEBUG("RES <%s>", res);
190 
191  tcflush(PortFD, TCIOFLUSH);
192 
193  if(strstr(res, "OK_FC") != nullptr)
194  return true;
195 
196  return false;
197 }
198 
199 
200 bool PegasusFocusCube::SyncFocuser(uint32_t ticks)
201 {
202  int nbytes_written = 0, rc = -1;
203  char cmd[16] = {0};
204 
205  snprintf(cmd, 16, "W:%ud", ticks);
206  cmd[strlen(cmd)] = 0xA;
207 
208  LOGF_DEBUG("CMD <%s>", cmd);
209 
210  // Set Position
211  if ((rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
212  {
213  char errstr[MAXRBUF];
214  tty_error_msg(rc, errstr, MAXRBUF);
215  LOGF_ERROR("sync error: %s.", errstr);
216  return false;
217  }
218 
219  this->ignoreResponse();
220 
221  return true;
222 }
223 
224 bool PegasusFocusCube::move(uint32_t newPosition)
225 {
226  int nbytes_written = 0, rc = -1;
227  char cmd[16] = {0};
228 
229  snprintf(cmd, 16, "M:%ud", newPosition);
230  cmd[strlen(cmd)] = 0xA;
231 
232  LOGF_DEBUG("CMD <%s>", cmd);
233 
234  // Set Position
235  if ((rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
236  {
237  char errstr[MAXRBUF];
238  tty_error_msg(rc, errstr, MAXRBUF);
239  LOGF_ERROR("move error: %s.", errstr);
240  return false;
241  }
242 
243  this->ignoreResponse();
244 
245  return true;
246 }
247 
248 bool PegasusFocusCube::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
249 {
250  if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
251  {
252 
253  // Encoders
254  if (!strcmp(name, EncoderSP.name))
255  {
256  IUUpdateSwitch(&EncoderSP, states, names, n);
257  bool rc = setEncodersEnabled(EncoderS[ENCODERS_ON].s == ISS_ON);
258  EncoderSP.s = rc ? IPS_OK : IPS_ALERT;
259  IDSetSwitch(&EncoderSP, nullptr);
260  return true;
261  }
262 
263  // LED
264  if (!strcmp(name, LEDSP.name))
265  {
266  IUUpdateSwitch(&LEDSP, states, names, n);
267  bool rc = setLedEnabled(LEDS[LED_ON].s == ISS_ON);
268  LEDSP.s = rc ? IPS_OK : IPS_ALERT;
269  IDSetSwitch(&LEDSP, nullptr);
270  return true;
271  }
272  }
273  return INDI::Focuser::ISNewSwitch(dev, name, states, names, n);
274 }
275 
276 bool PegasusFocusCube::ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
277 {
278  if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
279  {
280  // MaxSpeed
281  if (strcmp(name, MaxSpeedNP.name) == 0)
282  {
283  IUUpdateNumber(&MaxSpeedNP, values, names, n);
284  bool rc = setMaxSpeed(MaxSpeedN[0].value);
285  MaxSpeedNP.s = rc ? IPS_OK : IPS_ALERT;
286  IDSetNumber(&MaxSpeedNP, nullptr);
287  return true;
288  }
289 
290  }
291 
292  return INDI::Focuser::ISNewNumber(dev, name, values, names, n);
293 }
294 
295 void PegasusFocusCube::ignoreResponse()
296 {
297  int nbytes_read = 0;
298  char res[64];
299  tty_read_section(PortFD, res, 0xA, DMFC_TIMEOUT, &nbytes_read);
300 }
301 
302 bool PegasusFocusCube::updateFocusParams()
303 {
304  int nbytes_written = 0, nbytes_read = 0, rc = -1;
305  char errstr[MAXRBUF];
306  char cmd[3] = {0};
307  char res[64];
308  cmd[0] = 'A';
309  cmd[1] = 0xA;
310 
311  LOGF_DEBUG("CMD <%#02X>", cmd[0]);
312 
313  tcflush(PortFD, TCIOFLUSH);
314 
315  if ((rc = tty_write(PortFD, cmd, 2, &nbytes_written)) != TTY_OK)
316  {
317  tty_error_msg(rc, errstr, MAXRBUF);
318  LOGF_ERROR("GetFocusParams error: %s.", errstr);
319  return false;
320  }
321 
322 
323  if ((rc = tty_read_section(PortFD, res, 0xA, DMFC_TIMEOUT, &nbytes_read)) != TTY_OK)
324  {
325  tty_error_msg(rc, errstr, MAXRBUF);
326  LOGF_ERROR("GetFocusParams error: %s.", errstr);
327  return false;
328  }
329 
330  res[nbytes_read - 1] = 0;
331 
332  // Check for '\r' at end of string and replace with nullptr (DMFC firmware version 2.8)
333  if( res[nbytes_read - 2] == '\r') res[nbytes_read - 2] = 0;
334 
335  LOGF_DEBUG("RES <%s>", res);
336 
337  tcflush(PortFD, TCIOFLUSH);
338 
339  char *token = std::strtok(res, ":");
340 
341  // #1 Status
342  if (token == nullptr || (strstr(token, "OK_FC") == nullptr))
343  {
344  LOGF_ERROR("Invalid status response. %s", res);
345  return false;
346  }
347 
348  // #2 Version
349  token = std::strtok(nullptr, ":");
350 
351  if (token == nullptr)
352  {
353  LOG_ERROR("Invalid version response.");
354  return false;
355  }
356 
357  if (FirmwareVersionT[0].text == nullptr || strcmp(FirmwareVersionT[0].text, token))
358  {
359  IUSaveText(&FirmwareVersionT[0], token);
360  FirmwareVersionTP.s = IPS_OK;
361  IDSetText(&FirmwareVersionTP, nullptr);
362  }
363 
364  // #3 Motor Type
365  token = std::strtok(nullptr, ":");
366 
367  // #4 Temperature
368  token = std::strtok(nullptr, ":");
369 
370  if (token == nullptr)
371  {
372  LOG_ERROR("Invalid temperature response.");
373  return false;
374  }
375 
376  double temperature = atof(token);
377  if (temperature == -127)
378  {
379  TemperatureNP.s = IPS_ALERT;
380  IDSetNumber(&TemperatureNP, nullptr);
381  }
382  else
383  {
384  if (fabs(temperature - TemperatureN[0].value) > TEMPERATURE_THRESHOLD)
385  {
386  TemperatureN[0].value = temperature;
387  TemperatureNP.s = IPS_OK;
388  IDSetNumber(&TemperatureNP, nullptr);
389  }
390  }
391 
392  // #5 Position
393  token = std::strtok(nullptr, ":");
394 
395  if (token == nullptr)
396  {
397  LOG_ERROR("Invalid position response.");
398  return false;
399  }
400 
401  currentPosition = atoi(token);
402  if (currentPosition != FocusAbsPosN[0].value)
403  {
404  FocusAbsPosN[0].value = currentPosition;
405  IDSetNumber(&FocusAbsPosNP, nullptr);
406  }
407 
408  // #6 Moving Status
409  token = std::strtok(nullptr, ":");
410 
411  if (token == nullptr)
412  {
413  LOG_ERROR("Invalid moving status response.");
414  return false;
415  }
416 
417  isMoving = (token[0] == '1');
418 
419  // #7 LED Status
420  token = std::strtok(nullptr, ":");
421 
422  if (token == nullptr)
423  {
424  LOG_ERROR("Invalid LED response.");
425  return false;
426  }
427 
428  int ledStatus = atoi(token);
429  if (ledStatus >= 0 && ledStatus <= 1)
430  {
431  IUResetSwitch(&LEDSP);
432  LEDS[ledStatus].s = ISS_ON;
433  LEDSP.s = IPS_OK;
434  IDSetSwitch(&LEDSP, nullptr);
435  }
436 
437  // #8 Reverse Status
438  token = std::strtok(nullptr, ":");
439 
440  if (token == nullptr)
441  {
442  LOG_ERROR("Invalid reverse response.");
443  return false;
444  }
445 
446  int reverseStatus = atoi(token);
447  if (reverseStatus >= 0 && reverseStatus <= 1)
448  {
450  FocusReverseS[INDI_ENABLED].s = (reverseStatus == 1) ? ISS_ON : ISS_OFF;
451  FocusReverseS[INDI_DISABLED].s = (reverseStatus == 0) ? ISS_ON : ISS_OFF;
453  IDSetSwitch(&FocusReverseSP, nullptr);
454  }
455 
456  // #9 Encoder status
457  token = std::strtok(nullptr, ":");
458 
459  if (token == nullptr)
460  {
461  LOG_ERROR("Invalid encoder response.");
462  return false;
463  }
464 
465  int encoderStatus = atoi(token);
466  if (encoderStatus >= 0 && encoderStatus <= 1)
467  {
468  IUResetSwitch(&EncoderSP);
469  EncoderS[encoderStatus].s = ISS_ON;
470  EncoderSP.s = IPS_OK;
471  IDSetSwitch(&EncoderSP, nullptr);
472  }
473 
474  // #10 Backlash
475  token = std::strtok(nullptr, ":");
476 
477  if (token == nullptr)
478  {
479  LOG_ERROR("Invalid encoder response.");
480  return false;
481  }
482 
483  int backlash = atoi(token);
484  // If backlash is zero then compensation is disabled
485  if (backlash == 0 && FocusBacklashS[INDI_ENABLED].s == ISS_ON)
486  {
487  LOG_WARN("Backlash value is zero, disabling backlash switch...");
488 
492  IDSetSwitch(&FocusBacklashSP, nullptr);
493  }
494  else if (backlash > 0 && (FocusBacklashS[INDI_DISABLED].s == ISS_ON || backlash != FocusBacklashN[0].value))
495  {
496  if (backlash != FocusBacklashN[0].value)
497  {
498  FocusBacklashN[0].value = backlash;
500  IDSetNumber(&FocusBacklashNP, nullptr);
501  }
502 
504  {
508  IDSetSwitch(&FocusBacklashSP, nullptr);
509  }
510  }
511 
512  return true;
513 }
514 
515 bool PegasusFocusCube::setMaxSpeed(uint16_t speed)
516 {
517  int nbytes_written = 0, rc = -1;
518  char cmd[16] = {0};
519 
520  snprintf(cmd, 16, "S:%d", speed);
521  cmd[strlen(cmd)] = 0xA;
522 
523  LOGF_DEBUG("CMD <%s>", cmd);
524 
525  tcflush(PortFD, TCIOFLUSH);
526 
527  // Set Speed
528  if ((rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
529  {
530  char errstr[MAXRBUF];
531  tty_error_msg(rc, errstr, MAXRBUF);
532  LOGF_ERROR("setMaxSpeed error: %s.", errstr);
533  return false;
534  }
535 
536  this->ignoreResponse();
537  return true;
538 }
539 
541 {
542  int nbytes_written = 0, rc = -1;
543  char cmd[16] = {0};
544 
545  snprintf(cmd, 16, "N:%d", enabled ? 1 : 0);
546  cmd[strlen(cmd)] = 0xA;
547 
548  LOGF_DEBUG("CMD <%s>", cmd);
549 
550  tcflush(PortFD, TCIOFLUSH);
551 
552  // Reverse
553  if ((rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
554  {
555  char errstr[MAXRBUF];
556  tty_error_msg(rc, errstr, MAXRBUF);
557  LOGF_ERROR("Reverse error: %s.", errstr);
558  return false;
559  }
560 
561  this->ignoreResponse();
562 
563  return true;
564 }
565 
566 bool PegasusFocusCube::setLedEnabled(bool enable)
567 {
568  int nbytes_written = 0, rc = -1;
569  char cmd[16] = {0};
570 
571  snprintf(cmd, 16, "L:%d", enable ? 2 : 1);
572  cmd[strlen(cmd)] = 0xA;
573 
574  LOGF_DEBUG("CMD <%s>", cmd);
575 
576  tcflush(PortFD, TCIOFLUSH);
577 
578  // Led
579  if ((rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
580  {
581  char errstr[MAXRBUF];
582  tty_error_msg(rc, errstr, MAXRBUF);
583  LOGF_ERROR("Led error: %s.", errstr);
584  return false;
585  }
586 
587  this->ignoreResponse();
588  return true;
589 }
590 
591 bool PegasusFocusCube::setEncodersEnabled(bool enable)
592 {
593  int nbytes_written = 0, rc = -1;
594  char cmd[16] = {0};
595 
596  snprintf(cmd, 16, "E:%d", enable ? 0 : 1);
597  cmd[strlen(cmd)] = 0xA;
598 
599  LOGF_DEBUG("CMD <%s>", cmd);
600 
601  tcflush(PortFD, TCIOFLUSH);
602 
603  // Encoders
604  if ((rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
605  {
606  char errstr[MAXRBUF];
607  tty_error_msg(rc, errstr, MAXRBUF);
608  LOGF_ERROR("Encoder error: %s.", errstr);
609  return false;
610  }
611 
612  this->ignoreResponse();
613  return true;
614 }
615 
617 {
618  int nbytes_written = 0, rc = -1;
619  char cmd[16] = {0};
620 
621  snprintf(cmd, 16, "C:%d", steps);
622  cmd[strlen(cmd)] = 0xA;
623 
624  LOGF_DEBUG("CMD <%s>", cmd);
625 
626  tcflush(PortFD, TCIOFLUSH);
627 
628  // Backlash
629  if ((rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
630  {
631  char errstr[MAXRBUF];
632  tty_error_msg(rc, errstr, MAXRBUF);
633  LOGF_ERROR("Backlash error: %s.", errstr);
634  return false;
635  }
636 
637  this->ignoreResponse();
638  return true;
639 }
640 
642 {
643  if (!enabled)
644  return SetFocuserBacklash(0);
645 
646  return SetFocuserBacklash(FocusBacklashN[0].value > 0 ? FocusBacklashN[0].value : 1);
647 }
648 
649 
651 {
652  targetPosition = targetTicks;
653 
654  bool rc = move(targetPosition);
655 
656  if (!rc)
657  return IPS_ALERT;
658 
660 
661  return IPS_BUSY;
662 }
663 
665 {
666  double newPosition = 0;
667  bool rc = false;
668 
669  if (dir == FOCUS_INWARD)
670  newPosition = FocusAbsPosN[0].value - ticks;
671  else
672  newPosition = FocusAbsPosN[0].value + ticks;
673 
674  rc = move(newPosition);
675 
676  if (!rc)
677  return IPS_ALERT;
678 
679  FocusRelPosN[0].value = ticks;
681 
682  return IPS_BUSY;
683 }
684 
686 {
687  if (!isConnected())
688  {
690  return;
691  }
692 
693  bool rc = updateFocusParams();
694 
695  if (rc)
696  {
698  {
699  if (isMoving == false)
700  {
703  IDSetNumber(&FocusAbsPosNP, nullptr);
704  IDSetNumber(&FocusRelPosNP, nullptr);
705  LOG_INFO("Focuser reached requested position.");
706  }
707  }
708  }
709 
711 }
712 
714 {
715  int nbytes_written;
716  char cmd[2] = { 'H', 0xA };
717 
718  if (tty_write(PortFD, cmd, 2, &nbytes_written) == TTY_OK)
719  {
722  IDSetNumber(&FocusAbsPosNP, nullptr);
723  IDSetNumber(&FocusRelPosNP, nullptr);
724  this->ignoreResponse();
725  return true;
726  }
727  else
728  return false;
729 }
730 
732 {
734  IUSaveConfigSwitch(fp, &EncoderSP);
735  IUSaveConfigNumber(fp, &MaxSpeedNP);
736  IUSaveConfigSwitch(fp, &LEDSP);
737 
738  return true;
739 }
void setDefaultBaudRate(BaudRate newRate)
setDefaultBaudRate Set default baud rate. The default baud rate is 9600 unless otherwise changed by t...
bool isConnected() const
Definition: basedevice.cpp:520
const char * getDeviceName() const
Definition: basedevice.cpp:821
void setDefaultPollingPeriod(uint32_t msec)
setDefaultPollingPeriod Change the default polling period to call TimerHit() function in the driver.
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
void defineProperty(INumberVectorProperty *property)
uint32_t getCurrentPollingPeriod() const
getCurrentPollingPeriod Return the current polling period.
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
void addDebugControl()
Add Debug control to the driver.
INumberVectorProperty FocusBacklashNP
ISwitchVectorProperty FocusBacklashSP
INumberVectorProperty FocusAbsPosNP
INumberVectorProperty FocusRelPosNP
ISwitchVectorProperty FocusReverseSP
void SetCapability(uint32_t cap)
FI::SetCapability sets the focuser capabilities. All capabilities must be initialized.
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Saves the Device Port and Focuser Presets in the configuration file
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.
Definition: indifocuser.cpp:42
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
Connection::Serial * serialConnection
Definition: indifocuser.h:116
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual void TimerHit() override
Callback function to be called once SetTimer duration elapses.
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual IPState MoveAbsFocuser(uint32_t targetTicks) override
MoveFocuser the focuser to an absolute position.
const char * getDefaultName() override
virtual bool SetFocuserBacklashEnabled(bool enabled) override
SetFocuserBacklashEnabled Enables or disables the focuser backlash compensation.
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Saves the Device Port and Focuser Presets in the configuration file
virtual bool ReverseFocuser(bool enabled) override
ReverseFocuser Reverse focuser motion direction.
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
virtual IPState MoveRelFocuser(FocusDirection dir, uint32_t ticks) override
MoveFocuser the focuser to an relative position.
virtual bool AbortFocuser() override
AbortFocuser all focus motion.
virtual bool SyncFocuser(uint32_t ticks) override
SyncFocuser Set current position to ticks without moving the focuser.
virtual bool SetFocuserBacklash(int32_t steps) override
SetFocuserBacklash Set the focuser backlash compensation value.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
virtual bool Handshake() override
perform handshake with device to check communication
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
ISState
Switch state.
Definition: indiapi.h:150
@ ISS_OFF
Definition: indiapi.h:151
@ ISS_ON
Definition: indiapi.h:152
@ IP_RW
Definition: indiapi.h:186
@ IP_RO
Definition: indiapi.h:184
IPState
Property state.
Definition: indiapi.h:160
@ IPS_BUSY
Definition: indiapi.h:163
@ IPS_ALERT
Definition: indiapi.h:164
@ IPS_IDLE
Definition: indiapi.h:161
@ IPS_OK
Definition: indiapi.h:162
@ ISR_1OFMANY
Definition: indiapi.h:173
int tty_read_section(int fd, char *buf, char stop_char, int timeout, int *nbytes_read)
read buffer from terminal with a delimiter
Definition: indicom.c:566
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
Definition: indicom.c:424
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
Definition: indicom.c:1167
Implementations for common driver routines.
@ TTY_OK
Definition: indicom.h:150
void IUSaveConfigSwitch(FILE *fp, const ISwitchVectorProperty *svp)
Add a switch vector property value to the configuration file.
Definition: indidevapi.c:25
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.
Definition: indidevapi.c:272
void IUResetSwitch(ISwitchVectorProperty *svp)
Reset all switches in a switch vector property to OFF.
Definition: indidevapi.c:148
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.
Definition: indidevapi.c:291
void IUSaveText(IText *tp, const char *newtext)
Function to reliably save new text in a IText.
Definition: indidevapi.c:36
void IUSaveConfigNumber(FILE *fp, const INumberVectorProperty *nvp)
Add a number vector property value to the configuration file.
Definition: indidevapi.c:15
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.
Definition: indidevapi.c:158
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.
Definition: indidevapi.c:198
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.
Definition: indidevapi.c:180
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.
Definition: indidevapi.c:235
int IUUpdateSwitch(ISwitchVectorProperty *svp, ISState *states, char *names[], int n)
Update all switches in a switch vector property.
Definition: indidriver.c:1308
void IDSetNumber(const INumberVectorProperty *nvp, const char *fmt,...)
Definition: indidriver.c:1211
void IDSetSwitch(const ISwitchVectorProperty *svp, const char *fmt,...)
Definition: indidriver.c:1231
int IUUpdateNumber(INumberVectorProperty *nvp, double values[], char *names[], int n)
Update all numbers in a number vector property.
Definition: indidriver.c:1362
void IDSetText(const ITextVectorProperty *tvp, const char *fmt,...)
Definition: indidriver.c:1191
#define LOGF_INFO(fmt,...)
Definition: indilogger.h:82
#define LOG_WARN(txt)
Definition: indilogger.h:73
#define LOGF_DEBUG(fmt,...)
Definition: indilogger.h:83
#define LOG_ERROR(txt)
Shorter logging macros. In order to use these macros, the function (or method) "getDeviceName()" must...
Definition: indilogger.h:72
#define LOGF_ERROR(fmt,...)
Definition: indilogger.h:80
#define LOG_INFO(txt)
Definition: indilogger.h:74
#define MAXRBUF
Definition: indiserver.cpp:102
#define DMFC_TIMEOUT
#define TEMPERATURE_THRESHOLD
#define FOCUS_SETTINGS_TAB
__u8 cmd[4]
Definition: pwc-ioctl.h:2
char name[MAXINDINAME]
Definition: indiapi.h:323
char name[MAXINDINAME]
Definition: indiapi.h:371
char name[MAXINDINAME]
Definition: indiapi.h:250