Instrument Neutral Distributed Interface INDI 2.2.5
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
44void ISInit(void);
45void getBasicData(void);
46void ISPoll(void *);
47void handleExposure(void *);
48void connectFilter(void);
49int findwheel(flidomain_t domain);
50int manageDefaults(char errmsg[]);
55int isFilterConnected(void);
56
57double min(void);
58double max(void);
59
60extern char *me;
61extern 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
78typedef struct
79{
80 flidomain_t domain;
81 char *dname;
82 char *name;
83 char *model;
88 long home;
89} cam_t;
90
91static flidev_t fli_dev;
92static cam_t *FLIWheel;
93static int portSwitchIndex;
94static int simulation;
95static int targetFilter;
96
97long int Domains[] = { FLIDOMAIN_USB, FLIDOMAIN_SERIAL, FLIDOMAIN_PARALLEL_PORT, FLIDOMAIN_INET };
98
99/*INDI controls */
100
101/* Connect/Disconnect */
102static ISwitch PowerS[] = { { "CONNECT", "Connect", ISS_OFF, 0, 0 }, { "DISCONNECT", "Disconnect", ISS_ON, 0, 0 } };
103static ISwitchVectorProperty PowerSP = { mydev, "CONNECTION", "Connection", MAIN_GROUP, IP_RW, ISR_1OFMANY,
104 60, IPS_IDLE, PowerS, NARRAY(PowerS), "", 0 };
105
106/* Types of Ports */
107static 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 } };
111static ISwitchVectorProperty PortSP = { mydev, "Port Type", "", MAIN_GROUP, IP_RW, ISR_1OFMANY,
112 0, IPS_IDLE, PortS, NARRAY(PortS), "", 0 };
113
114/* Filter control */
115static INumber FilterN[] = { { "FILTER_SLOT_VALUE", "Active Filter", "%2.0f", FIRST_FILTER, LAST_FILTER, 1, 0, 0, 0,
116 0 } };
117static 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 */
121void 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
145void 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
158void 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
175void 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);
202 return;
203 }
204}
205
206void 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
222void 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
364int 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
393void 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
621int 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:586
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:148
@ ISS_OFF
Definition indiapi.h:149
@ ISS_ON
Definition indiapi.h:150
#define NARRAY(a)
Handy macro to find the number of elements in array a[]. Must be used with actual array,...
Definition indiapi.h:498
@ IP_RW
Definition indiapi.h:184
@ IPS_BUSY
Definition indiapi.h:161
@ IPS_ALERT
Definition indiapi.h:162
@ IPS_IDLE
Definition indiapi.h:159
@ IPS_OK
Definition indiapi.h:160
@ ISR_1OFMANY
Definition indiapi.h:171
void IDLog(const char *fmt,...)
Definition indicom.c:305
Implementations for common driver routines.
void IUResetSwitch(ISwitchVectorProperty *svp)
Reset all switches in a switch vector property to OFF.
Definition indidevapi.c:366
INumber * IUFindNumber(const INumberVectorProperty *nvp, const char *name)
Find an INumber member in a number text property.
Definition indidevapi.c:275
Interface to the reference INDI C API device implementation on the Device Driver side.
#define INDI_UNUSED(x)
Definition indidevapi.h:132
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,...)
void IDMessage(const char *dev, const char *fmt,...)
Definition indidriver.c:983
void IUUpdateMinMax(const INumberVectorProperty *nvp)
Function to update the min and max elements of a number in the client.
void IDDefNumber(const INumberVectorProperty *nvp, const char *fmt,...)
void IDSetText(const ITextVectorProperty *tvp, const char *fmt,...)
void IDDefSwitch(const ISwitchVectorProperty *svp, const char *fmt,...)
#define ERRMSG_SIZE
Definition indimacros.h:33
Namespace to encapsulate INDI client, drivers, and mediator classes.
One number descriptor.
One switch descriptor.
Number vector property descriptor.
Definition indiapi.h:317
char name[MAXINDINAME]
Definition indiapi.h:321
char label[MAXINDILABEL]
Definition indiapi.h:323
Switch vector property descriptor.
Definition indiapi.h:365
char name[MAXINDINAME]
Definition indiapi.h:369
char label[MAXINDILABEL]
Definition indiapi.h:371
ISState s
Definition indiapi.h:353
Text vector property descriptor.
Definition indiapi.h:244
char label[MAXINDILABEL]
Definition indiapi.h:250
char name[MAXINDINAME]
Definition indiapi.h:248
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