Instrument Neutral Distributed Interface INDI  2.0.2
fli_wheel.c
Go to the documentation of this file.
1 #if 0
2  FLI WHEEL
3  INDI Interface for Finger Lakes Instruments Filter Wheels
4  Copyright (C) 2005 Gaetano Vocca (yagvoc-web AT yahoo DOT it)
5  Based on fli_ccd by Jasem Mutlaq (mutlaqja AT ikarustech DOT com)
6 
7  This library is free software; 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; either
10  version 2.1 of the License, or (at your option) any later version.
11 
12  This library is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  Lesser General Public License for more details.
16 
17  You should have received a copy of the GNU Lesser General Public
18  License along with this library; if not, write to the Free Software
19  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 
21 #endif
22 
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <cstring>
26 #include <stdarg.h>
27 #include <cmath>
28 #include <unistd.h>
29 #include <ctime>
30 #include <fcntl.h>
31 #include <cerrno>
32 #include <sys/stat.h>
33 #include <sys/time.h>
34 #include <sys/types.h>
35 #include <sys/socket.h>
36 #include <netinet/in.h>
37 #include <netdb.h>
38 
39 #include "libfli.h"
40 #include "indidevapi.h"
41 #include "eventloop.h"
42 #include "indicom.h"
43 
44 void ISInit(void);
45 void getBasicData(void);
46 void ISPoll(void *);
47 void handleExposure(void *);
48 void connectFilter(void);
49 int findwheel(flidomain_t domain);
50 int manageDefaults(char errmsg[]);
55 int isFilterConnected(void);
56 
57 double min(void);
58 double max(void);
59 
60 extern char *me;
61 extern int errno;
62 
63 #define mydev "FLI Wheel"
64 
65 #define MAIN_GROUP "Main Control"
66 
67 #define LAST_FILTER 14 /* Max slot index */
68 #define FIRST_FILTER 0 /* Min slot index */
69 
70 #define currentFilter FilterN[0].value
71 
72 #define POLLMS_OVERRIDE 1000
73 #define LIBVERSIZ 1024
74 #define PREFIXSIZ 64
75 #define PIPEBUFSIZ 8192
76 #define FRAME_ILEN 64
77 
78 typedef struct
79 {
80  flidomain_t domain;
81  char *dname;
82  char *name;
83  char *model;
84  long HWRevision;
85  long FWRevision;
88  long home;
89 } cam_t;
90 
91 static flidev_t fli_dev;
92 static cam_t *FLIWheel;
93 static int portSwitchIndex;
94 static int simulation;
95 static int targetFilter;
96 
97 long int Domains[] = { FLIDOMAIN_USB, FLIDOMAIN_SERIAL, FLIDOMAIN_PARALLEL_PORT, FLIDOMAIN_INET };
98 
99 /*INDI controls */
100 
101 /* Connect/Disconnect */
102 static ISwitch PowerS[] = { { "CONNECT", "Connect", ISS_OFF, 0, 0 }, { "DISCONNECT", "Disconnect", ISS_ON, 0, 0 } };
103 static ISwitchVectorProperty PowerSP = { mydev, "CONNECTION", "Connection", MAIN_GROUP, IP_RW, ISR_1OFMANY,
104  60, IPS_IDLE, PowerS, NARRAY(PowerS), "", 0 };
105 
106 /* Types of Ports */
107 static ISwitch PortS[] = { { "USB", "", ISS_ON, 0, 0 },
108  { "Serial", "", ISS_OFF, 0, 0 },
109  { "Parallel", "", ISS_OFF, 0, 0 },
110  { "INet", "", ISS_OFF, 0, 0 } };
111 static ISwitchVectorProperty PortSP = { mydev, "Port Type", "", MAIN_GROUP, IP_RW, ISR_1OFMANY,
112  0, IPS_IDLE, PortS, NARRAY(PortS), "", 0 };
113 
114 /* Filter control */
115 static INumber FilterN[] = { { "FILTER_SLOT_VALUE", "Active Filter", "%2.0f", FIRST_FILTER, LAST_FILTER, 1, 0, 0, 0,
116  0 } };
117 static INumberVectorProperty FilterNP = { mydev, "FILTER_SLOT", "Filter", MAIN_GROUP, IP_RW, 0,
118  IPS_IDLE, FilterN, NARRAY(FilterN), "", 0 };
119 
120 /* send client definitions of all properties */
121 void ISInit()
122 {
123  static int isInit = 0;
124 
125  if (isInit)
126  return;
127 
128  /* USB by default {USB, SERIAL, PARALLEL, INET} */
129  portSwitchIndex = 0;
130 
131  targetFilter = 0;
132 
133  /* No Simulation by default */
134  simulation = 0;
135 
136  /* Enable the following for simulation mode */
137  /*simulation = 1;
138  IDLog("WARNING: Simulation is on\n");*/
139 
141 
142  isInit = 1;
143 }
144 
145 void ISGetProperties(const char *dev)
146 {
147  ISInit();
148 
149  if (dev != nullptr && strcmp(mydev, dev))
150  return;
151 
152  /* Main Control */
153  IDDefSwitch(&PowerSP, NULL);
154  IDDefSwitch(&PortSP, NULL);
155  IDDefNumber(&FilterNP, NULL);
156 }
157 
158 void ISNewBLOB(const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[],
159  char *names[], int n)
160 {
161  INDI_UNUSED(dev);
162  INDI_UNUSED(name);
163  INDI_UNUSED(sizes);
164  INDI_UNUSED(blobsizes);
165  INDI_UNUSED(blobs);
166  INDI_UNUSED(formats);
167  INDI_UNUSED(names);
168  INDI_UNUSED(n);
169 }
171 {
172  INDI_UNUSED(root);
173 }
174 
175 void ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
176 {
177  /* ignore if not ours */
178  if (dev != nullptr && strcmp(dev, mydev))
179  return;
180 
181  ISInit();
182 
183  /* Port type */
184  if (!strcmp(name, PortSP.name))
185  {
186  PortSP.s = IPS_IDLE;
187  IUResetSwitch(&PortSP);
188  IUUpdateSwitch(&PortSP, states, names, n);
189  portSwitchIndex = getOnSwitch(&PortSP);
190 
191  PortSP.s = IPS_OK;
192  IDSetSwitch(&PortSP, NULL);
193  return;
194  }
195 
196  /* Connection */
197  if (!strcmp(name, PowerSP.name))
198  {
199  IUResetSwitch(&PowerSP);
200  IUUpdateSwitch(&PowerSP, states, names, n);
201  connectFilter();
202  return;
203  }
204 }
205 
206 void ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
207 {
208  ISInit();
209 
210  /* ignore if not ours */
211  if (dev != nullptr && strcmp(mydev, dev))
212  return;
213 
214  /* suppress warning */
215  n = n;
216  dev = dev;
217  name = name;
218  names = names;
219  texts = texts;
220 }
221 
222 void ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
223 {
224  long err;
225  INumber *np;
226  long newFilter;
227 
228  n = n;
229 
230  /* ignore if not ours */
231  if (dev != nullptr && strcmp(dev, mydev))
232  return;
233 
234  ISInit();
235 
236  if (!strcmp(FilterNP.name, name))
237  {
238  if (simulation)
239  {
240  targetFilter = values[0];
241  FilterNP.s = IPS_BUSY;
242  IDSetNumber(&FilterNP, "Setting current filter to slot %d", targetFilter);
243  IDLog("Setting current filter to slot %d\n", targetFilter);
244  return;
245  }
246 
247  if (!isFilterConnected())
248  {
249  IDMessage(mydev, "Device not connected.");
250  FilterNP.s = IPS_IDLE;
251  IDSetNumber(&FilterNP, NULL);
252  return;
253  }
254 
255  targetFilter = values[0];
256 
257  np = IUFindNumber(&FilterNP, names[0]);
258 
259  if (!np)
260  {
261  FilterNP.s = IPS_ALERT;
262  IDSetNumber(&FilterNP, "Unknown error. %s is not a member of %s property.", names[0], name);
263  return;
264  }
265 
266  if (targetFilter < FIRST_FILTER || targetFilter > FLIWheel->filter_count - 1)
267  {
268  FilterNP.s = IPS_ALERT;
269  IDSetNumber(&FilterNP, "Error: valid range of filter is from %d to %d", FIRST_FILTER, LAST_FILTER);
270  return;
271  }
272 
273  FilterNP.s = IPS_BUSY;
274  IDSetNumber(&FilterNP, "Setting current filter to slot %d", targetFilter);
275  IDLog("Setting current filter to slot %d\n", targetFilter);
276 
277  if ((err = FLISetFilterPos(fli_dev, targetFilter)))
278  {
279  FilterNP.s = IPS_ALERT;
280  IDSetNumber(&FilterNP, "FLISetFilterPos() failed. %s.", strerror((int)-err));
281  IDLog("FLISetFilterPos() failed. %s.", strerror((int)-err));
282  return;
283  }
284 
285  /* Check current filter position */
286  if ((err = FLIGetFilterPos(fli_dev, &newFilter)))
287  {
288  FilterNP.s = IPS_ALERT;
289  IDSetNumber(&FilterNP, "FLIGetFilterPos() failed. %s.", strerror((int)-err));
290  IDLog("FLIGetFilterPos() failed. %s.\n", strerror((int)-err));
291  return;
292  }
293 
294  if (newFilter == targetFilter)
295  {
296  FLIWheel->current_filter = targetFilter;
297  FilterN[0].value = FLIWheel->current_filter;
298  FilterNP.s = IPS_OK;
299  IDSetNumber(&FilterNP, "Filter set to slot #%d", targetFilter);
300  return;
301  }
302 
303  return;
304  }
305 }
306 
307 /* Retrieves basic data from the Wheel upon connection like temperature, array size, firmware..etc */
309 {
310  char buff[2048];
311  long err;
312 
313  if ((err = FLIGetModel(fli_dev, buff, 2048)))
314  {
315  IDMessage(mydev, "FLIGetModel() failed. %s.", strerror((int)-err));
316  IDLog("FLIGetModel() failed. %s.\n", strerror((int)-err));
317  return;
318  }
319  else
320  {
321  if ((FLIWheel->model = malloc(sizeof(char) * 2048)) == NULL)
322  {
323  IDMessage(mydev, "malloc() failed.");
324  IDLog("malloc() failed.");
325  return;
326  }
327 
328  strcpy(FLIWheel->model, buff);
329  }
330 
331  if ((err = FLIGetHWRevision(fli_dev, &FLIWheel->HWRevision)))
332  {
333  IDMessage(mydev, "FLIGetHWRevision() failed. %s.", strerror((int)-err));
334  IDLog("FLIGetHWRevision() failed. %s.\n", strerror((int)-err));
335 
336  return;
337  }
338 
339  if ((err = FLIGetFWRevision(fli_dev, &FLIWheel->FWRevision)))
340  {
341  IDMessage(mydev, "FLIGetFWRevision() failed. %s.", strerror((int)-err));
342  IDLog("FLIGetFWRevision() failed. %s.\n", strerror((int)-err));
343  return;
344  }
345 
346  if ((err = FLIGetFilterCount(fli_dev, &FLIWheel->filter_count)))
347  {
348  IDMessage(mydev, "FLIGetFilterCount() failed. %s.", strerror((int)-err));
349  IDLog("FLIGetFilterCount() failed. %s.\n", strerror((int)-err));
350  return;
351  }
352 
353  IDLog("The filter count is %ld\n", FLIWheel->filter_count);
354 
355  FilterN[0].max = FLIWheel->filter_count - 1;
356  FilterNP.s = IPS_OK;
357 
358  IUUpdateMinMax(&FilterNP);
359  IDSetNumber(&FilterNP, "Setting basic data");
360 
361  IDLog("Exiting getBasicData()\n");
362 }
363 
364 int manageDefaults(char errmsg[])
365 {
366  long err;
367 
368  /*IDLog("Resetting filter wheel to slot %d\n", 0);
369  FLIWheel->home = 0;
370  if (( err = FLISetFilterPos(fli_dev, 0)))
371  {
372  IDMessage(mydev, "FLISetFilterPos() failed. %s.", strerror((int)-err));
373  IDLog("FLISetFilterPos() failed. %s.\n", strerror((int)-err));
374  return (int)-err;
375  }*/
376 
377  if ((err = FLIGetFilterPos(fli_dev, &FLIWheel->current_filter)))
378  {
379  IDMessage(mydev, "FLIGetFilterPos() failed. %s.", strerror((int)-err));
380  IDLog("FLIGetFilterPos() failed. %s.\n", strerror((int)-err));
381  return (int)-err;
382  }
383 
384  IDLog("The current filter is %ld\n", FLIWheel->current_filter);
385 
386  FilterN[0].value = FLIWheel->current_filter;
387  IDSetNumber(&FilterNP, "Storing defaults");
388 
389  /* Success */
390  return 0;
391 }
392 
393 void ISPoll(void *p)
394 {
395  static int simMTC = 5;
396 
397  if (!isFilterConnected())
398  {
400  return;
401  }
402 
403  switch (FilterNP.s)
404  {
405  case IPS_IDLE:
406  case IPS_OK:
407  break;
408 
409  case IPS_BUSY:
410  /* Simulate that it takes 5 seconds to change slot */
411  if (simulation)
412  {
413  simMTC--;
414  if (simMTC == 0)
415  {
416  simMTC = 5;
417  currentFilter = targetFilter;
418  FilterNP.s = IPS_OK;
419  IDSetNumber(&FilterNP, "Filter set to slot #%2.0f", currentFilter);
420  break;
421  }
422  IDSetNumber(&FilterNP, NULL);
423  break;
424  }
425 
426  /*if (( err = FLIGetFilterPos(fli_dev, &currentFilter)))
427  {
428  FilterNP.s = IPS_ALERT;
429  IDSetNumber(&FilterNP, "FLIGetFilterPos() failed. %s.", strerror((int)-err));
430  IDLog("FLIGetFilterPos() failed. %s.\n", strerror((int)-err));
431  return;
432  }
433 
434  if (targetFilter == currentFilter)
435  {
436  FLIWheel->current_filter = currentFilter;
437  FilterNP.s = IPS_OK;
438  IDSetNumber(&FilterNP, "Filter set to slot #%2.0f", currentFilter);
439  return;
440  }
441 
442  IDSetNumber(&FilterNP, NULL);*/
443  break;
444 
445  case IPS_ALERT:
446  break;
447  }
448 
450 }
451 
453 {
454  int i = 0;
455  for (i = 0; i < sp->nsp; i++)
456  {
457  /*IDLog("Switch %s is %s\n", sp->sp[i].name, sp->sp[i].s == ISS_ON ? "On" : "Off");*/
458  if (sp->sp[i].s == ISS_ON)
459  return i;
460  }
461 
462  return -1;
463 }
464 
466 {
467  if (simulation)
468  return 0;
469 
470  if (PowerSP.s != IPS_OK)
471  {
472  if (!strcmp(sp->label, ""))
473  IDMessage(mydev, "Cannot change property %s while the wheel is offline.", sp->name);
474  else
475  IDMessage(mydev, "Cannot change property %s while the wheel is offline.", sp->label);
476 
477  sp->s = IPS_IDLE;
478  IDSetSwitch(sp, NULL);
479  return -1;
480  }
481 
482  return 0;
483 }
484 
486 {
487  if (simulation)
488  return 0;
489 
490  if (PowerSP.s != IPS_OK)
491  {
492  if (!strcmp(np->label, ""))
493  IDMessage(mydev, "Cannot change property %s while the wheel is offline.", np->name);
494  else
495  IDMessage(mydev, "Cannot change property %s while the wheel is offline.", np->label);
496 
497  np->s = IPS_IDLE;
498  IDSetNumber(np, NULL);
499  return -1;
500  }
501 
502  return 0;
503 }
504 
506 {
507  if (simulation)
508  return 0;
509 
510  if (PowerSP.s != IPS_OK)
511  {
512  if (!strcmp(tp->label, ""))
513  IDMessage(mydev, "Cannot change property %s while the wheel is offline.", tp->name);
514  else
515  IDMessage(mydev, "Cannot change property %s while the wheel is offline.", tp->label);
516 
517  tp->s = IPS_IDLE;
518  IDSetText(tp, NULL);
519  return -1;
520  }
521 
522  return 0;
523 }
524 
526 {
527  long err;
528  char errmsg[ERRMSG_SIZE];
529 
530  /* USB by default {USB, SERIAL, PARALLEL, INET} */
531  switch (PowerS[0].s)
532  {
533  case ISS_ON:
534 
535  if (simulation)
536  {
537  /* Success! */
538  PowerS[0].s = ISS_ON;
539  PowerS[1].s = ISS_OFF;
540  PowerSP.s = IPS_OK;
541  IDSetSwitch(&PowerSP, "Simulation Wheel is online.");
542  IDLog("Simulation Wheel is online.\n");
543  return;
544  }
545 
546  IDLog("Current portSwitch is %d\n", portSwitchIndex);
547  IDLog("Attempting to find the device in domain %ld\n", Domains[portSwitchIndex]);
548 
549  if (findwheel(Domains[portSwitchIndex]))
550  {
551  PowerSP.s = IPS_IDLE;
552  PowerS[0].s = ISS_OFF;
553  PowerS[1].s = ISS_ON;
554  IDSetSwitch(&PowerSP, "Error: no wheels were detected.");
555  IDLog("Error: no wheels were detected.\n");
556  return;
557  }
558 
559  if ((err = FLIOpen(&fli_dev, FLIWheel->name, FLIWheel->domain | FLIDEVICE_FILTERWHEEL)))
560  {
561  PowerSP.s = IPS_IDLE;
562  PowerS[0].s = ISS_OFF;
563  PowerS[1].s = ISS_ON;
564  IDSetSwitch(&PowerSP, "Error: FLIOpen() failed. %s.", strerror((int)-err));
565  IDLog("Error: FLIOpen() failed. %s.\n", strerror((int)-err));
566  return;
567  }
568 
569  /* Success! */
570  PowerS[0].s = ISS_ON;
571  PowerS[1].s = ISS_OFF;
572  PowerSP.s = IPS_OK;
573  IDSetSwitch(&PowerSP, "Wheel is online. Retrieving basic data.");
574  IDLog("Wheel is online. Retrieving basic data.\n");
575  getBasicData();
576 
577  if (manageDefaults(errmsg))
578  {
579  IDMessage(mydev, errmsg, NULL);
580  IDLog("%s", errmsg);
581  return;
582  }
583 
584  break;
585 
586  case ISS_OFF:
587 
588  if (simulation)
589  {
590  PowerS[0].s = ISS_OFF;
591  PowerS[1].s = ISS_ON;
592  PowerSP.s = IPS_IDLE;
593  IDSetSwitch(&PowerSP, "Wheel is offline.");
594  return;
595  }
596 
597  PowerS[0].s = ISS_OFF;
598  PowerS[1].s = ISS_ON;
599  PowerSP.s = IPS_IDLE;
600  if ((err = FLIClose(fli_dev)))
601  {
602  PowerSP.s = IPS_ALERT;
603  IDSetSwitch(&PowerSP, "Error: FLIClose() failed. %s.", strerror((int)-err));
604  IDLog("Error: FLIClose() failed. %s.\n", strerror((int)-err));
605  return;
606  }
607  IDSetSwitch(&PowerSP, "Wheel is offline.");
608  break;
609  }
610 }
611 
612 /* isFilterConnected: return 1 if we have a connection, 0 otherwise */
614 {
615  if (simulation)
616  return 1;
617 
618  return ((PowerS[0].s == ISS_ON) ? 1 : 0);
619 }
620 
621 int findwheel(flidomain_t domain)
622 {
623  char **devlist;
624  long err;
625 
626  IDLog("In find Camera, the domain is %ld\n", domain);
627 
628  if ((err = FLIList(domain | FLIDEVICE_FILTERWHEEL, &devlist)))
629  {
630  IDLog("FLIList() failed. %s\n", strerror((int)-err));
631  return -1;
632  }
633 
634  if (devlist != NULL && devlist[0] != NULL)
635  {
636  int i;
637 
638  IDLog("Trying to allocate memory to FLIWheel\n");
639  if ((FLIWheel = malloc(sizeof(cam_t))) == NULL)
640  {
641  IDLog("malloc() failed.\n");
642  return -1;
643  }
644 
645  for (i = 0; devlist[i] != NULL; i++)
646  {
647  int j;
648 
649  for (j = 0; devlist[i][j] != '\0'; j++)
650  if (devlist[i][j] == ';')
651  {
652  devlist[i][j] = '\0';
653  break;
654  }
655  }
656 
657  FLIWheel->domain = domain;
658 
659  /* Each driver handles _only_ one camera for now */
660  switch (domain)
661  {
662  case FLIDOMAIN_PARALLEL_PORT:
663  FLIWheel->dname = strdup("parallel port");
664  break;
665 
666  case FLIDOMAIN_USB:
667  FLIWheel->dname = strdup("USB");
668  break;
669 
670  case FLIDOMAIN_SERIAL:
671  FLIWheel->dname = strdup("serial");
672  break;
673 
674  case FLIDOMAIN_INET:
675  FLIWheel->dname = strdup("inet");
676  break;
677 
678  default:
679  FLIWheel->dname = strdup("Unknown domain");
680  }
681 
682  IDLog("Domain set OK\n");
683 
684  FLIWheel->name = strdup(devlist[0]);
685 
686  if ((err = FLIFreeList(devlist)))
687  {
688  IDLog("FLIFreeList() failed. %s.\n", strerror((int)-err));
689  return -1;
690  }
691 
692  } /* end if */
693  else
694  {
695  if ((err = FLIFreeList(devlist)))
696  {
697  IDLog("FLIFreeList() failed. %s.\n", strerror((int)-err));
698  return -1;
699  }
700 
701  return -1;
702  }
703 
704  IDLog("Findcam() finished successfully.\n");
705  return 0;
706 }
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
Public interface to INDI's eventloop mechanism.
int findwheel(flidomain_t domain)
Definition: fli_wheel.c:621
#define FIRST_FILTER
Definition: fli_wheel.c:68
int manageDefaults(char errmsg[])
Definition: fli_wheel.c:364
void ISNewBLOB(const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
Update data of an existing blob vector property.
Definition: fli_wheel.c:158
void connectFilter(void)
Definition: fli_wheel.c:525
void ISInit(void)
Definition: fli_wheel.c:121
void handleExposure(void *)
void ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Update the value of an existing switch vector property.
Definition: fli_wheel.c:175
void ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
Update the value of an existing text vector property.
Definition: fli_wheel.c:206
int checkPowerS(ISwitchVectorProperty *sp)
Definition: fli_wheel.c:465
#define POLLMS_OVERRIDE
Definition: fli_wheel.c:72
void ISGetProperties(const char *dev)
Get Device Properties.
Definition: fli_wheel.c:145
double max(void)
long int Domains[]
Definition: fli_wheel.c:97
#define currentFilter
Definition: fli_wheel.c:70
int checkPowerN(INumberVectorProperty *np)
Definition: fli_wheel.c:485
#define mydev
Definition: fli_wheel.c:63
int getOnSwitch(ISwitchVectorProperty *sp)
Definition: fli_wheel.c:452
void ISPoll(void *)
Definition: fli_wheel.c:393
#define MAIN_GROUP
Definition: fli_wheel.c:65
void getBasicData(void)
Definition: fli_wheel.c:308
void ISSnoopDevice(XMLEle *root)
Function defined by Drivers that is called when another Driver it is snooping (by having previously c...
Definition: fli_wheel.c:170
void ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
Definition: fli_wheel.c:222
int errno
int isFilterConnected(void)
Definition: fli_wheel.c:613
int checkPowerT(ITextVectorProperty *tp)
Definition: fli_wheel.c:505
#define LAST_FILTER
Definition: fli_wheel.c:67
double min(void)
char * me
Definition: indidriver.c:50
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
void IDLog(const char *fmt,...)
Definition: indicom.c:316
Implementations for common driver routines.
#define ERRMSG_SIZE
Definition: indicom.h:49
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
Interface to the reference INDI C API device implementation on the Device Driver side.
#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
void IDMessage(const char *dev, const char *fmt,...)
Definition: indidriver.c:960
void IUUpdateMinMax(const INumberVectorProperty *nvp)
Function to update the min and max elements of a number in the client.
Definition: indidriver.c:1296
void IDDefNumber(const INumberVectorProperty *nvp, const char *fmt,...)
Definition: indidriver.c:1104
void IDSetText(const ITextVectorProperty *tvp, const char *fmt,...)
Definition: indidriver.c:1191
void IDDefSwitch(const ISwitchVectorProperty *svp, const char *fmt,...)
Definition: indidriver.c:1127
Namespace to encapsulate INDI client, drivers, and mediator classes.
One number descriptor.
One switch descriptor.
Number vector property descriptor.
Definition: indiapi.h:319
char name[MAXINDINAME]
Definition: indiapi.h:323
char label[MAXINDILABEL]
Definition: indiapi.h:325
Switch vector property descriptor.
Definition: indiapi.h:367
char name[MAXINDINAME]
Definition: indiapi.h:371
char label[MAXINDILABEL]
Definition: indiapi.h:373
Text vector property descriptor.
Definition: indiapi.h:246
char label[MAXINDILABEL]
Definition: indiapi.h:252
char name[MAXINDINAME]
Definition: indiapi.h:250
long HWRevision
Definition: fli_wheel.c:84
long FWRevision
Definition: fli_wheel.c:85
long home
Definition: fli_wheel.c:88
long current_filter
Definition: fli_wheel.c:86
long filter_count
Definition: fli_wheel.c:87
flidomain_t domain
Definition: fli_wheel.c:80
char * model
Definition: fli_wheel.c:83
char * dname
Definition: fli_wheel.c:81
char * name
Definition: fli_wheel.c:82