source: BAORadio/libindi/v1/examples/tutorial_one.c@ 692

Last change on this file since 692 was 490, checked in by campagne, 15 years ago

import libindi (JEC)

File size: 7.4 KB
Line 
1/*
2 INDI Developers Manual
3 Tutorial #1
4
5 "Hello INDI"
6
7 We construct a most basic (and useless) device driver to illustate INDI.
8
9 Refer to README, which contains instruction on how to build this driver, and use it
10 with an INDI-compatible client.
11
12*/
13
14/** \file tutorial_one.c
15 \brief Construct a basic INDI driver with only one property.
16 \author Jasem Mutlaq
17*/
18
19/* Standard headers */
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23#include <math.h>
24#include <unistd.h>
25
26/* INDI Core headers */
27
28/* indidevapi.h contains API declerations */
29#include "indidevapi.h"
30
31/* INDI Eventloop mechanism */
32#include "eventloop.h"
33
34/* INDI Common Routines */
35#include "indicom.h"
36
37/* Definitions */
38
39#define mydev "Simple Device" /* Device name */
40#define MAIN_GROUP "Main Control" /* Group name */
41
42/* Function protptypes */
43void connectDevice(void);
44
45/*INDI controls */
46
47/* We will define only one vector switch property. The CONNECTION property is an INDI Standard Property and should be implemented in all INDI drivers.
48 * A vector property may have one or more members. */
49
50/* First, we define and initilize the members of the vector property */
51static ISwitch PowerS[] = {
52 {"CONNECT" /* 1st Swtich name */
53 , "Connect" /* Switch Label, i.e. what the GUI displays */
54 , ISS_OFF /* State of the switch, initially off */
55 , 0 /* auxiluary, set to 0 for now.*/
56 , 0} /* auxiluary, set to 0 for now */
57
58 ,{"DISCONNECT" /* 2nd Swtich name */
59 , "Disconnect" /* Switch Label, i.e. what the GUI displays */
60 , ISS_ON /* State of the switch, initially on */
61 , 0 /* auxiluary, set to 0 for now.*/
62 , 0} /* auxiluary, set to 0 for now */
63 };
64
65/* Next, we define and initlize the vector switch property that contains the two switches we defined above */
66static ISwitchVectorProperty PowerSP = {
67 mydev /* Device name */
68 , "CONNECTION" /* Property name */
69 , "Connection" /* Property label */
70 , MAIN_GROUP /* Property group */
71 , IP_RW /* Property premission, it's both read and write */
72 , ISR_1OFMANY /* Switch behavior. Only 1 of many switches are allowed to be on at the same time */
73 , 0 /* Timeout, 0 seconds */
74 , IPS_IDLE /* Initial state is idle */
75 , PowerS /* Switches comprimising this vector that we defined above */
76 , NARRAY(PowerS) /* Number of Switches. NARRAY is defined in indiapi.h */
77 , "" /* Timestamp, set to 0 */
78 , 0}; /* auxiluary, set to 0 for now */
79
80
81/* void ISGetProperties (const char *dev)
82* INDI will call this function when the client inquires about the device properties.
83* Here we will use IDxxx functions to define new properties to the client */
84void ISGetProperties (const char *dev)
85{
86 /* Tell the client to create a new Switch property PowerSP */
87 IDDefSwitch(&PowerSP, NULL);
88}
89
90/* void ISNewSwitch(...)
91 * INDI will call this function when the client wants to set a new state of existing switches
92 ** Parameters **
93
94 * dev: the device name
95 * name: the property name the client wants to update
96 * states: an array of states of members switches (ISS_ON and ISS_OFF)
97 * names: names of the switches. The names are parallel to the states. That is, member names[0] has a state states[0], and so on...
98 * n: number of switches to update, which is also the dimension of *states and names[]
99*/
100void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
101{
102 /* Let's check if the property the client wants to change is the PowerSP (name: CONNECTION) property*/
103 if (!strcmp (name, PowerSP.name))
104 {
105 /* If the clients wants to update this property, let's perform the following */
106
107 /* A. We update the switches by sending their names and updated states IUUpdateSwitches function. If there is an error, we return */
108 if (IUUpdateSwitch(&PowerSP, states, names, n) < 0) return;
109
110 /* B. We try to establish a connection to our device */
111 connectDevice();
112 return;
113 }
114}
115
116/* void ISNewText(...)
117 * INDI will call this function when the client wants to update an existing text.
118 ** Parameters **
119
120 * dev: the device name
121 * name: the property name the client wants to update
122 * texts: an array of texts.
123 * names: names of the members. The names are parallel to the texts.
124 * n: number of texts to update, which is also the dimension of *texts and names[]
125*/
126void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
127{
128 /* Even though we didn't define any text members, we need to define this function. Otherwise, the driver will not compile */
129 /* Since there is nothing to do, we simply return */
130 return;
131}
132
133/* void ISNewNumber(...)
134 * INDI will call this function when the client wants to update an existing number.
135 ** Parameters **
136
137 * dev: the device name
138 * name: the property name the client wants to update
139 * values: an array of values.
140 * names: names of the members. The names are parallel to the values.
141 * n: number of numbers to update, which is the dimension of *numbers and names[]
142*/
143void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
144{
145 /* Even though we didn't define any number members, we need to define this function. Otherwise, the driver will not compile */
146 /* Since there is nothing to do, we simply return */
147 return;
148}
149
150/* Note that we must define ISNewBLOB and ISSnoopDevice even if we don't use them, otherwise, the driver will NOT compile */
151void ISNewBLOB (const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n) {}
152void ISSnoopDevice (XMLEle *root) {}
153
154
155/* void connectDevice(void)
156 * This function is called when the state of PowerSP is changed in the ISNewSwitch() function.
157 * We check the state of CONNECT and DISCONNECT switches, and connect or disconnect our fake device accordingly */
158void connectDevice(void)
159{
160
161 /* Now we check the state of CONNECT, the 1st member of the PowerSP property we defined earliar */
162 switch (PowerS[0].s)
163 {
164 /* If CONNECT is on, then try to establish a connection to the device */
165 case ISS_ON:
166
167 /* The IDLog function is a very useful function that will log time-stamped messages to stderr. This function is invaluable to debug your drivers.
168 * It operates like printf */
169 IDLog ("Establishing a connection to %s...\n", mydev);
170
171 /* Change the state of the PowerSP (CONNECTION) property to OK */
172 PowerSP.s = IPS_OK;
173
174 /* Tell the client to update the states of the PowerSP property, and send a message to inform successful connection */
175 IDSetSwitch(&PowerSP, "Connection to %s is successful.", mydev);
176 break;
177
178 /* If CONNECT is off (which is the same thing as DISCONNECT being on), then try to disconnect the device */
179 case ISS_OFF:
180
181 IDLog ("Terminating connection to %s...\n", mydev);
182
183 /* The device is disconnected, change the state to IDLE */
184 PowerSP.s = IPS_IDLE;
185
186 /* Tell the client to update the states of the PowerSP property, and send a message to inform successful disconnection */
187 IDSetSwitch(&PowerSP, "%s has been disconneced.", mydev);
188
189 break;
190 }
191
192}
193
194/* That's it! check out tutorial_two where we simulate a simple telescope! */
Note: See TracBrowser for help on using the repository browser.