Instrument Neutral Distributed Interface INDI  2.0.2
ieq45.cpp
Go to the documentation of this file.
1 #if 0
2 IEQ45 Basic Driver
3 Copyright (C) 2011 Nacho Mas (mas.ignacio@gmail.com). Only litle changes
4 from lx200basic made it by Jasem Mutlaq (mutlaqja@ikarustech.com)
5 
6 This library is free software;
7 you can redistribute it and / or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation;
10 either
11 version 2.1 of the License, or (at your option) any later version.
12 
13 This library is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY;
15 without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18 
19 You should have received a copy of the GNU Lesser General Public
20 License along with this library;
21 if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110 - 1301 USA
23 
24 #endif
25 
26 #include "ieq45.h"
27 
28 #include "config.h"
29 #include "ieq45driver.h"
30 #include "indicom.h"
31 
32 #include <stdio.h>
33 #include <string.h>
34 #include <math.h>
35 #include <unistd.h>
36 
37 
38 #include <memory>
39 
40 const int POLLMS_OVERRIDE = 100; // Period of update, 1 second.
41 const char *mydev = "IEQ45"; // Name of our device.
42 
43 const char *BASIC_GROUP = "Main Control"; // Main Group
44 const char *OPTIONS_GROUP = "Options"; // Options Group
45 
46 /* Handy Macros */
47 #define currentRA EquatorialCoordsRN[0].value
48 #define currentDEC EquatorialCoordsRN[1].value
49 
50 static void ISPoll(void *);
51 static void retry_connection(void *);
52 
53 static class Loader
54 {
55  std::unique_ptr<IEQ45Basic> telescope;
56  public:
57  Loader()
58  {
59  telescope.reset(new IEQ45Basic());
60  IEAddTimer(POLLMS_OVERRIDE, ISPoll, nullptr);
61  }
62 } loader;
63 
64 /**************************************************************************************
65 **
66 ***************************************************************************************/
67 void ISPoll(void *p)
68 {
69  INDI_UNUSED(p);
70 
71  telescope->ISPoll();
72  IEAddTimer(POLLMS_OVERRIDE, ISPoll, nullptr);
73 }
74 
75 /**************************************************************************************
76 ** IEQ45 Basic constructor
77 ***************************************************************************************/
79 {
80  init_properties();
81 
82  lastSet = -1;
83  fd = -1;
84  simulation = false;
85  lastRA = 0;
86  lastDEC = 0;
87  currentSet = 0;
88 
89  IDLog("Initializing from IEQ45 device...\n");
90  IDLog("Driver Version: 0.1 (2011-11-07)\n");
91 
92  enable_simulation(false);
93 }
94 
95 /**************************************************************************************
96 **
97 ***************************************************************************************/
99 {
100 }
101 
102 /**************************************************************************************
103 ** Initialize all properties & set default values.
104 ***************************************************************************************/
105 void IEQ45Basic::init_properties()
106 {
107  // Connection#include <stdio.h>
108 #include <string.h>
109  IUFillSwitch(&ConnectS[0], "CONNECT", "Connect", ISS_OFF);
110  IUFillSwitch(&ConnectS[1], "DISCONNECT", "Disconnect", ISS_ON);
111  IUFillSwitchVector(&ConnectSP, ConnectS, NARRAY(ConnectS), mydev, "CONNECTION", "Connection", BASIC_GROUP, IP_RW,
112  ISR_1OFMANY, 60, IPS_IDLE);
113 
114  // Coord Set
115  IUFillSwitch(&OnCoordSetS[0], "SLEW", "Slew", ISS_ON);
116  IUFillSwitch(&OnCoordSetS[1], "SYNC", "Sync", ISS_OFF);
117  IUFillSwitchVector(&OnCoordSetSP, OnCoordSetS, NARRAY(OnCoordSetS), mydev, "ON_COORD_SET", "On Set", BASIC_GROUP,
118  IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
119 
120  //Track MODE
121  IUFillSwitch(&TrackModeS[0], "SIDEREAL", "Sidereal", ISS_ON);
122  IUFillSwitch(&TrackModeS[1], "LUNAR", "Lunar", ISS_OFF);
123  IUFillSwitch(&TrackModeS[2], "SOLAR", "Solar", ISS_OFF);
124  IUFillSwitch(&TrackModeS[3], "ZERO", "Stop", ISS_OFF);
125  IUFillSwitchVector(&TrackModeSP, TrackModeS, NARRAY(TrackModeS), mydev, "TRACK_MODE", "Track Mode", BASIC_GROUP,
126  IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
127 
128  // Abort
129  IUFillSwitch(&AbortSlewS[0], "ABORT", "Abort", ISS_OFF);
130  IUFillSwitchVector(&AbortSlewSP, AbortSlewS, NARRAY(AbortSlewS), mydev, "ABORT_MOTION", "Abort Slew/Track",
132 
133  // Port
134  IUFillText(&PortT[0], "PORT", "Port", "/dev/ttyS0");
135  IUFillTextVector(&PortTP, PortT, NARRAY(PortT), mydev, "DEVICE_PORT", "Ports", BASIC_GROUP, IP_RW, 0, IPS_IDLE);
136 
137  // Equatorial Coords
138  IUFillNumber(&EquatorialCoordsRN[0], "RA", "RA H:M:S", "%10.6m", 0., 24., 0., 0.);
139  IUFillNumber(&EquatorialCoordsRN[1], "DEC", "Dec D:M:S", "%10.6m", -90., 90., 0., 0.);
140  IUFillNumberVector(&EquatorialCoordsRNP, EquatorialCoordsRN, NARRAY(EquatorialCoordsRN), mydev,
141  "EQUATORIAL_EOD_COORD", "Equatorial JNow", BASIC_GROUP, IP_RW, 0, IPS_IDLE);
142 }
143 
144 /**************************************************************************************
145 ** Define IEQ45 Basic properties to clients.
146 ***************************************************************************************/
147 void IEQ45Basic::ISGetProperties(const char *dev)
148 {
149  if (dev != nullptr && strcmp(mydev, dev))
150  return;
151 
152  // Main Control
153  IDDefSwitch(&ConnectSP, nullptr);
154  IDDefText(&PortTP, nullptr);
155  IDDefNumber(&EquatorialCoordsRNP, nullptr);
156  IDDefSwitch(&OnCoordSetSP, nullptr);
157  IDDefSwitch(&TrackModeSP, nullptr);
158  IDDefSwitch(&AbortSlewSP, nullptr);
159 }
160 
161 /**************************************************************************************
162 ** Process Text properties
163 ***************************************************************************************/
164 void IEQ45Basic::ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
165 {
166  // Ignore if not ours
167  if (strcmp(dev, mydev))
168  return;
169 
170  // ===================================
171  // Port Name
172  // ===================================
173  if (!strcmp(name, PortTP.name))
174  {
175  if (IUUpdateText(&PortTP, texts, names, n) < 0)
176  return;
177 
178  PortTP.s = IPS_OK;
179  IDSetText(&PortTP, nullptr);
180  return;
181  }
182 
183  if (is_connected() == false)
184  {
185  IDMessage(mydev, "IEQ45 is offline. Please connect before issuing any commands.");
186  reset_all_properties();
187  return;
188  }
189 }
190 
191 /**************************************************************************************
192 **
193 ***************************************************************************************/
194 void IEQ45Basic::ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
195 {
196  // Ignore if not ours
197  if (strcmp(dev, mydev))
198  return;
199 
200  if (is_connected() == false)
201  {
202  IDMessage(mydev, "IEQ45 is offline. Please connect before issuing any commands.");
203  reset_all_properties();
204  return;
205  }
206 
207  // ===================================
208  // Equatorial Coords
209  // ===================================
210  if (!strcmp(name, EquatorialCoordsRNP.name))
211  {
212  int i = 0, nset = 0, error_code = 0;
213  double newRA = 0, newDEC = 0;
214 
215  for (nset = i = 0; i < n; i++)
216  {
217  INumber *eqp = IUFindNumber(&EquatorialCoordsRNP, names[i]);
218  if (eqp == &EquatorialCoordsRN[0])
219  {
220  newRA = values[i];
221  nset += newRA >= 0 && newRA <= 24.0;
222  }
223  else if (eqp == &EquatorialCoordsRN[1])
224  {
225  newDEC = values[i];
226  nset += newDEC >= -90.0 && newDEC <= 90.0;
227  }
228  }
229 
230  if (nset == 2)
231  {
232  char RAStr[32], DecStr[32];
233 
234  fs_sexa(RAStr, newRA, 2, 3600);
235  fs_sexa(DecStr, newDEC, 2, 3600);
236 
237 #ifdef INDI_DEBUG
238  IDLog("We received JNow RA %g - DEC %g\n", newRA, newDEC);
239  IDLog("We received JNow RA %s - DEC %s\n", RAStr, DecStr);
240 #endif
241 
242  if (!simulation &&
243  ((error_code = setObjectRA(fd, newRA)) < 0 || (error_code = setObjectDEC(fd, newDEC)) < 0))
244  {
245  handle_error(&EquatorialCoordsRNP, error_code, "Setting RA/DEC");
246  return;
247  }
248 
249  targetRA = newRA;
250  targetDEC = newDEC;
251 
252  if (process_coords() == false)
253  {
254  EquatorialCoordsRNP.s = IPS_ALERT;
255  IDSetNumber(&EquatorialCoordsRNP, nullptr);
256  }
257  } // end nset
258  else
259  {
260  EquatorialCoordsRNP.s = IPS_ALERT;
261  IDSetNumber(&EquatorialCoordsRNP, "RA or Dec missing or invalid");
262  }
263 
264  return;
265  } /* end EquatorialCoordsWNP */
266 }
267 
268 /**************************************************************************************
269 **
270 ***************************************************************************************/
271 void IEQ45Basic::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
272 {
273  // ignore if not ours //
274  if (strcmp(mydev, dev))
275  return;
276 
277  // ===================================
278  // Connect Switch
279  // ===================================
280  if (!strcmp(name, ConnectSP.name))
281  {
282  if (IUUpdateSwitch(&ConnectSP, states, names, n) < 0)
283  return;
284 
285  connect_telescope();
286  return;
287  }
288 
289  if (is_connected() == false)
290  {
291  IDMessage(mydev, "IEQ45 is offline. Please connect before issuing any commands.");
292  reset_all_properties();
293  return;
294  }
295 
296  // ===================================
297  // Coordinate Set
298  // ===================================
299  if (!strcmp(name, OnCoordSetSP.name))
300  {
301  if (IUUpdateSwitch(&OnCoordSetSP, states, names, n) < 0)
302  return;
303 
304  currentSet = get_switch_index(&OnCoordSetSP);
305  OnCoordSetSP.s = IPS_OK;
306  IDSetSwitch(&OnCoordSetSP, nullptr);
307  }
308 
309  // ===================================
310  // Track Mode Set
311  // ===================================
312  if (!strcmp(name, TrackModeSP.name))
313  {
314  if (IUUpdateSwitch(&TrackModeSP, states, names, n) < 0)
315  return;
316 
317  int trackMode = get_switch_index(&TrackModeSP);
318  selectTrackingMode(fd, trackMode);
319  TrackModeSP.s = IPS_OK;
320  IDSetSwitch(&TrackModeSP, nullptr);
321  }
322 
323  // ===================================
324  // Abort slew
325  // ===================================
326  if (!strcmp(name, AbortSlewSP.name))
327  {
328  IUResetSwitch(&AbortSlewSP);
329  abortSlew(fd);
330 
331  if (EquatorialCoordsRNP.s == IPS_BUSY)
332  {
333  AbortSlewSP.s = IPS_OK;
334  EquatorialCoordsRNP.s = IPS_IDLE;
335  IDSetSwitch(&AbortSlewSP, "Slew aborted.");
336  IDSetNumber(&EquatorialCoordsRNP, nullptr);
337  }
338 
339  return;
340  }
341 }
342 
343 /**************************************************************************************
344 ** Retry connecting to the telescope on error. Give up if there is no hope.
345 ***************************************************************************************/
346 void IEQ45Basic::handle_error(INumberVectorProperty *nvp, int err, const char *msg)
347 {
348  nvp->s = IPS_ALERT;
349 
350  /* First check to see if the telescope is connected */
352  {
353  /* The telescope is off locally */
354  ConnectS[0].s = ISS_OFF;
355  ConnectS[1].s = ISS_ON;
356  ConnectSP.s = IPS_BUSY;
357  IDSetSwitch(&ConnectSP, "Telescope is not responding to commands, will retry in 10 seconds.");
358 
359  IDSetNumber(nvp, nullptr);
360  IEAddTimer(10000, retry_connection, &fd);
361  return;
362  }
363 
364  /* If the error is a time out, then the device doesn't support this property */
365  if (err == -2)
366  {
367  nvp->s = IPS_ALERT;
368  IDSetNumber(nvp, "Device timed out. Current device may be busy or does not support %s. Will retry again.", msg);
369  }
370  else
371  /* Changing property failed, user should retry. */
372  IDSetNumber(nvp, "%s failed.", msg);
373 
374  fault = true;
375 }
376 
377 /**************************************************************************************
378 ** Set all properties to idle and reset most switches to clean state.
379 ***************************************************************************************/
380 void IEQ45Basic::reset_all_properties()
381 {
382  ConnectSP.s = IPS_IDLE;
383  OnCoordSetSP.s = IPS_IDLE;
384  TrackModeSP.s = IPS_IDLE;
385  AbortSlewSP.s = IPS_IDLE;
386  PortTP.s = IPS_IDLE;
387  EquatorialCoordsRNP.s = IPS_IDLE;
388 
389  IUResetSwitch(&OnCoordSetSP);
390  IUResetSwitch(&TrackModeSP);
391  IUResetSwitch(&AbortSlewSP);
392 
393  OnCoordSetS[0].s = ISS_ON;
394  TrackModeS[0].s = ISS_ON;
395  ConnectS[0].s = ISS_OFF;
396  ConnectS[1].s = ISS_ON;
397 
398  IDSetSwitch(&ConnectSP, nullptr);
399  IDSetSwitch(&OnCoordSetSP, nullptr);
400  IDSetSwitch(&TrackModeSP, nullptr);
401  IDSetSwitch(&AbortSlewSP, nullptr);
402  IDSetText(&PortTP, nullptr);
403  IDSetNumber(&EquatorialCoordsRNP, nullptr);
404 }
405 
406 /**************************************************************************************
407 **
408 ***************************************************************************************/
409 void IEQ45Basic::correct_fault()
410 {
411  fault = false;
412  IDMessage(mydev, "Telescope is online.");
413 }
414 
415 /**************************************************************************************
416 **
417 ***************************************************************************************/
418 bool IEQ45Basic::is_connected()
419 {
420  if (simulation)
421  return true;
422 
423  return (ConnectSP.sp[0].s == ISS_ON);
424 }
425 
426 /**************************************************************************************
427 **
428 ***************************************************************************************/
429 static void retry_connection(void *p)
430 {
431  int fd = *((int *)p);
432 
434  telescope->connection_lost();
435  else
436  telescope->connection_resumed();
437 }
438 
439 /**************************************************************************************
440 **
441 ***************************************************************************************/
443 {
444  if (is_connected() == false || simulation)
445  return;
446 
447  double dx, dy;
448  int error_code = 0;
449 
450  switch (EquatorialCoordsRNP.s)
451  {
452  case IPS_IDLE:
455  if (fabs(currentRA - lastRA) > 0.01 || fabs(currentDEC - lastDEC) > 0.01)
456  {
457  lastRA = currentRA;
459  IDSetNumber(&EquatorialCoordsRNP, nullptr);
460  IDLog("IDLE update coord\n");
461  }
462  break;
463 
464  case IPS_BUSY:
467  dx = targetRA - currentRA;
468  dy = targetDEC - currentDEC;
469 
470  // Wait until acknowledged or within threshold
471  if (fabs(dx) <= (3 / (900.0)) && fabs(dy) <= (3 / 60.0))
472  {
473  lastRA = currentRA;
475  IUResetSwitch(&OnCoordSetSP);
476  OnCoordSetSP.s = IPS_OK;
477  EquatorialCoordsRNP.s = IPS_OK;
478  IDSetNumber(&EquatorialCoordsRNP, nullptr);
479 
480  switch (currentSet)
481  {
482  case IEQ45_SLEW:
483  OnCoordSetSP.sp[IEQ45_SLEW].s = ISS_ON;
484  IDSetSwitch(&OnCoordSetSP, "Slew is complete.");
485  break;
486 
487  case IEQ45_SYNC:
488  break;
489  }
490  }
491  else
492  IDSetNumber(&EquatorialCoordsRNP, nullptr);
493  break;
494 
495  case IPS_OK:
496 
497  if ((error_code = getIEQ45RA(fd, &currentRA)) < 0 || (error_code = getIEQ45DEC(fd, &currentDEC)) < 0)
498  {
499  handle_error(&EquatorialCoordsRNP, error_code, "Getting RA/DEC");
500  return;
501  }
502 
503  if (fault == true)
504  correct_fault();
505 
506  if ((currentRA != lastRA) || (currentDEC != lastDEC))
507  {
508  lastRA = currentRA;
510  //IDLog("IPS_OK update coords %g %g\n",currentRA,currentDEC);
511  IDSetNumber(&EquatorialCoordsRNP, nullptr);
512  }
513  break;
514 
515  case IPS_ALERT:
516  break;
517  }
518 }
519 
520 /**************************************************************************************
521 **
522 ***************************************************************************************/
523 bool IEQ45Basic::process_coords()
524 {
525  int error_code;
526  char syncString[256];
527  char RAStr[32], DecStr[32];
528  double dx, dy;
529 
530  switch (currentSet)
531  {
532  // Slew
533  case IEQ45_SLEW:
534  lastSet = IEQ45_SLEW;
535  if (EquatorialCoordsRNP.s == IPS_BUSY)
536  {
537  IDLog("Aborting Slew\n");
538  abortSlew(fd);
539 
540  // sleep for 100 mseconds
541  usleep(100000);
542  }
543 
544  if (!simulation && (error_code = Slew(fd)))
545  {
546  slew_error(error_code);
547  return false;
548  }
549 
550  EquatorialCoordsRNP.s = IPS_BUSY;
551  fs_sexa(RAStr, targetRA, 2, 3600);
552  fs_sexa(DecStr, targetDEC, 2, 3600);
553  IDSetNumber(&EquatorialCoordsRNP, "Slewing to JNow RA %s - DEC %s", RAStr, DecStr);
554  IDLog("Slewing to JNow RA %s - DEC %s\n", RAStr, DecStr);
555  break;
556 
557  // Sync
558  case IEQ45_SYNC:
559  lastSet = IEQ45_SYNC;
560  EquatorialCoordsRNP.s = IPS_IDLE;
561 
562  if (!simulation && (error_code = Sync(fd, syncString) < 0))
563  {
564  IDSetNumber(&EquatorialCoordsRNP, "Synchronization failed.");
565  return false;
566  }
567 
568  if (simulation)
569  {
570  EquatorialCoordsRN[0].value = EquatorialCoordsRN[0].value;
571  EquatorialCoordsRN[1].value = EquatorialCoordsRN[1].value;
572  }
573 
574  EquatorialCoordsRNP.s = IPS_OK;
575  IDLog("Synchronization successful %s\n", syncString);
576  IDSetNumber(&EquatorialCoordsRNP, "Synchronization successful.");
577  break;
578  }
579 
580  return true;
581 }
582 
583 /**************************************************************************************
584 **
585 ***************************************************************************************/
586 int IEQ45Basic::get_switch_index(ISwitchVectorProperty *sp)
587 {
588  for (int i = 0; i < sp->nsp; i++)
589  if (sp->sp[i].s == ISS_ON)
590  return i;
591 
592  return -1;
593 }
594 
595 /**************************************************************************************
596 **
597 ***************************************************************************************/
598 void IEQ45Basic::connect_telescope()
599 {
600  switch (ConnectSP.sp[0].s)
601  {
602  case ISS_ON:
603 
604  if (simulation)
605  {
606  ConnectSP.s = IPS_OK;
607  IDSetSwitch(&ConnectSP, "Simulated telescope is online.");
608  return;
609  }
610 
611  if (tty_connect(PortT[0].text, 9600, 8, 0, 1, &fd) != TTY_OK)
612  {
613  ConnectS[0].s = ISS_OFF;
614  ConnectS[1].s = ISS_ON;
615  IDSetSwitch(
616  &ConnectSP,
617  "Error connecting to port %s. Make sure you have BOTH read and write permission to the port.",
618  PortT[0].text);
619  return;
620  }
621 
623  {
624  ConnectS[0].s = ISS_OFF;
625  ConnectS[1].s = ISS_ON;
626  IDSetSwitch(&ConnectSP, "Error connecting to Telescope. Telescope is offline.");
627  return;
628  }
629 
630  ConnectSP.s = IPS_OK;
631  IDSetSwitch(&ConnectSP, "Telescope is online. Retrieving basic data...");
632  get_initial_data();
633  break;
634 
635  case ISS_OFF:
636  ConnectS[0].s = ISS_OFF;
637  ConnectS[1].s = ISS_ON;
638  ConnectSP.s = IPS_IDLE;
639  if (simulation)
640  {
641  IDSetSwitch(&ConnectSP, "Simulated Telescope is offline.");
642  return;
643  }
644  IDSetSwitch(&ConnectSP, "Telescope is offline.");
645  IDLog("Telescope is offline.");
646 
648  break;
649  }
650 }
651 
652 /**************************************************************************************
653 **
654 ***************************************************************************************/
655 void IEQ45Basic::get_initial_data()
656 {
657  // Make sure short
659 
660  // Get current RA/DEC
663 
664  IDSetNumber(&EquatorialCoordsRNP, nullptr);
665 }
666 
667 /**************************************************************************************
668 **
669 ***************************************************************************************/
670 void IEQ45Basic::slew_error(int slewCode)
671 {
672  OnCoordSetSP.s = IPS_IDLE;
673  IDLog("Aborting Slew\n");
674  abortSlew(fd);
675  if (slewCode == 1)
676  IDSetSwitch(&OnCoordSetSP, "Object below horizon.");
677  else if (slewCode == 2)
678  IDSetSwitch(&OnCoordSetSP, "Object below the minimum elevation limit.");
679  else
680  IDSetSwitch(&OnCoordSetSP, "Slew failed.");
681 }
682 
683 /**************************************************************************************
684 **
685 ***************************************************************************************/
686 void IEQ45Basic::enable_simulation(bool enable)
687 {
688  simulation = enable;
689 
690  if (simulation)
691  IDLog("Warning: Simulation is activated.\n");
692  else
693  IDLog("Simulation is disabled.\n");
694 }
695 
696 /**************************************************************************************
697 **
698 ***************************************************************************************/
700 {
701  ConnectSP.s = IPS_IDLE;
702  IDSetSwitch(&ConnectSP, "The connection to the telescope is lost.");
703  return;
704 }
705 
706 /**************************************************************************************
707 **
708 ***************************************************************************************/
710 {
711  ConnectS[0].s = ISS_ON;
712  ConnectS[1].s = ISS_OFF;
713  ConnectSP.s = IPS_OK;
714 
715  IDSetSwitch(&ConnectSP, "The connection to the telescope has been resumed.");
716 }
bool fault
Definition: ieq45.h:106
int currentSet
Definition: ieq45.h:109
void ISPoll()
Definition: ieq45.cpp:442
IEQ45Basic()
Definition: ieq45.cpp:78
int lastSet
Definition: ieq45.h:110
double targetDEC
Definition: ieq45.h:111
void connection_lost()
Definition: ieq45.cpp:699
void ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
Definition: ieq45.cpp:164
double targetRA
Definition: ieq45.h:111
void ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Definition: ieq45.cpp:271
double lastDEC
Definition: ieq45.h:104
void ISGetProperties(const char *dev)
Definition: ieq45.cpp:147
int fd
Definition: ieq45.h:107
bool simulation
Definition: ieq45.h:105
double lastRA
Definition: ieq45.h:103
void ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
Definition: ieq45.cpp:194
void connection_resumed()
Definition: ieq45.cpp:709
~IEQ45Basic()
Definition: ieq45.cpp:98
int IEAddTimer(int millisecs, IE_TCF *fp, void *p)
Register a new single-shot timer function, fp, to be called with ud as argument after ms.
Definition: eventloop.c:582
void ISPoll(void *)
Definition: fli_wheel.c:393
const char * OPTIONS_GROUP
Definition: ieq45.cpp:44
#define currentDEC
Definition: ieq45.cpp:48
#define currentRA
Definition: ieq45.cpp:47
const char * mydev
Definition: ieq45.cpp:41
const char * BASIC_GROUP
Definition: ieq45.cpp:43
const int POLLMS_OVERRIDE
Definition: ieq45.cpp:40
#define getIEQ45DEC(fd, x)
Definition: ieq45driver.h:111
int check_IEQ45_connection(int fd)
#define getIEQ45RA(fd, x)
Definition: ieq45driver.h:110
int checkIEQ45Format(int fd)
ISState
Switch state.
Definition: indiapi.h:150
@ ISS_OFF
Definition: indiapi.h:151
@ ISS_ON
Definition: indiapi.h:152
#define NARRAY(a)
Handy macro to find the number of elements in array a[]. Must be used with actual array,...
Definition: indiapi.h:500
@ IP_RW
Definition: indiapi.h:186
@ 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
@ ISR_ATMOST1
Definition: indiapi.h:174
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.
Definition: indicom.c:946
int tty_disconnect(int fd)
Closes a tty connection and flushes the bus.
Definition: indicom.c:1148
void IDLog(const char *fmt,...)
Definition: indicom.c:316
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[].
Definition: indicom.c:141
Implementations for common driver routines.
@ TTY_OK
Definition: indicom.h:150
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
INumber * IUFindNumber(const INumberVectorProperty *nvp, const char *name)
Find an INumber member in a number text property.
Definition: indidevapi.c:66
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 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
#define INDI_UNUSED(x)
Definition: indidevapi.h:131
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 IUUpdateText(ITextVectorProperty *tvp, char *texts[], char *names[], int n)
Update all text members in a text vector property.
Definition: indidriver.c:1396
void IDMessage(const char *dev, const char *fmt,...)
Definition: indidriver.c:960
void IDDefNumber(const INumberVectorProperty *nvp, const char *fmt,...)
Definition: indidriver.c:1104
void IDDefText(const ITextVectorProperty *tvp, const char *fmt,...)
Definition: indidriver.c:1081
void IDSetText(const ITextVectorProperty *tvp, const char *fmt,...)
Definition: indidriver.c:1191
void IDDefSwitch(const ISwitchVectorProperty *svp, const char *fmt,...)
Definition: indidriver.c:1127
int fd
Definition: intelliscope.c:43
int selectTrackingMode(int fd, int trackMode)
int setObjectRA(int fd, double ra, bool addSpace)
int setObjectDEC(int fd, double dec, bool addSpace)
int abortSlew(int fd)
int Sync(int fd, char *matchedObject)
int Slew(int fd)
One number descriptor.
Number vector property descriptor.
Definition: indiapi.h:319
char name[MAXINDINAME]
Definition: indiapi.h:323
Switch vector property descriptor.
Definition: indiapi.h:367
char name[MAXINDINAME]
Definition: indiapi.h:371
char name[MAXINDINAME]
Definition: indiapi.h:250