Instrument Neutral Distributed Interface INDI  0.9.6
tutorial_dome.c
1 #if 0
2  Inter-driver communications tutorial - Dome Driver
3  Copyright (C) 2007 Jasem Mutlaq (mutlaqja@ikarustech.com)
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License as published by the Free Software Foundation; either
8  version 2.1 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 
19 #endif
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <stdarg.h>
25 #include <math.h>
26 #include <unistd.h>
27 #include <time.h>
28 #include <fcntl.h>
29 #include <errno.h>
30 #include <sys/stat.h>
31 #include <sys/time.h>
32 #include <sys/types.h>
33 #include <sys/socket.h>
34 #include <netinet/in.h>
35 #include <netdb.h>
36 #include <zlib.h>
37 
38 #include "indidevapi.h"
39 #include "eventloop.h"
40 #include "indicom.h"
41 
42 #define mydev "Dome"
43 
44 #define MAIN_GROUP "Main"
45 #define SNOOP_GROUP "Snooped"
46 
47 void closeDome();
48 
49 /* Connect/Disconnect */
50 static ISwitch PowerS[] = {{"CONNECT" , "Connect" , ISS_OFF, 0, 0},{"DISCONNECT", "Disconnect", ISS_ON, 0, 0}};
51 static ISwitchVectorProperty PowerSP = { mydev, "CONNECTION" , "Connection", MAIN_GROUP, IP_RW, ISR_1OFMANY, 60, IPS_IDLE, PowerS, NARRAY(PowerS), "", 0};
52 
53 /* Dome Open/Close */
54 static ISwitch DomeS[] = {{"Open", "", ISS_ON, 0, 0}, {"Close", "", ISS_OFF, 0, 0}};
55 static ISwitchVectorProperty DomeSP = { mydev, "Dome Status", "", MAIN_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, DomeS , NARRAY(DomeS), "", 0};
56 
57 /* The property we're trying to fetch from the rain driver. It's a carbon copy of the property define in rain.c, we initilize its structure here like any
58  other local property, but we don't define it to client, it's only used internally within the driver.
59 
60  MAKE SURE to set the property's device name to the device we're snooping on! If you copy/paste the property definition from the snooped driver
61  don't forget to remove "mydev" and replace it with the driver name.
62 */
63 static ILight RainL[] = {{"Status", "", IPS_IDLE, 0, 0}};
64 static ILightVectorProperty RainLP = { "Rain", "Rain Alert", "", SNOOP_GROUP, IPS_IDLE, RainL , NARRAY(RainL), "", 0};
65 
66 void ISGetProperties (const char *dev)
67 {
68  /* MAIN_GROUP */
69  IDDefSwitch(&PowerSP, NULL);
70  IDDefSwitch(&DomeSP, NULL);
71 
72  /* Let's listen for Rain Alert property in the device Rain */
73  IDSnoopDevice("Rain", "Rain Alert");
74 }
75 
76 void ISNewBLOB (const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n) {}
77 
78 void ISSnoopDevice (XMLEle *root)
79 {
80 
81  IPState old_state = RainL[0].s;
82 
83  /* If the "Rain Alert" property gets updated in the Rain device, we will receive a notification. We need to process the new values of Rain Alert and update the local version
84  of the property.*/
85  if (IUSnoopLight(root, &RainLP) == 0)
86  {
87 
88  // If the dome is connected and rain is Alert */
89  if (PowerSP.s == IPS_OK && RainL[0].s == IPS_ALERT)
90  {
91  // If dome is open, then close it */
92  if (DomeS[0].s == ISS_ON)
93  closeDome();
94  else
95  IDMessage(mydev, "Rain Alert Detected! Dome is already closed.");
96  }
97  else if (old_state == IPS_ALERT && RainL[0].s != IPS_ALERT)
98  IDMessage(mydev, "Rain threat passed. Opening the dome is now safe.");
99 
100  }
101 
102 }
103 
104 void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
105 {
106  /* ignore if not ours */
107  if (dev && strcmp (dev, mydev))
108  return;
109 
110  /* Connection */
111  if (!strcmp (name, PowerSP.name))
112  {
113  if (IUUpdateSwitch(&PowerSP, states, names, n) < 0)
114  return;
115 
116  PowerSP.s = IPS_OK;
117 
118  if (PowerS[0].s == ISS_ON)
119  IDSetSwitch(&PowerSP, "Dome is online.");
120  else
121  {
122  PowerSP.s = IPS_IDLE;
123  IDSetSwitch(&PowerSP, "Dome is offline.");
124  }
125 
126  return;
127  }
128 
129  /* Dome */
130  if (!strcmp (name, DomeSP.name))
131  {
132 
133  if (PowerSP.s != IPS_OK)
134  {
135  IDMessage(mydev, "Dome is offline!");
136  return;
137  }
138 
139  if (IUUpdateSwitch(&DomeSP, states, names, n) < 0)
140  return;
141 
142  DomeSP.s = IPS_BUSY;
143 
144  if (DomeS[0].s == ISS_ON)
145  {
146  if (RainL[0].s == IPS_ALERT)
147  {
148  DomeSP.s = IPS_ALERT;
149  DomeS[0].s = ISS_OFF;
150  DomeS[1].s = ISS_ON;
151  IDSetSwitch(&DomeSP, "It is raining, cannot open dome.");
152  return;
153  }
154 
155  IDSetSwitch(&DomeSP, "Dome is opening.");
156  }
157  else
158  IDSetSwitch(&DomeSP, "Dome is closing.");
159 
160  sleep(5);
161 
162  DomeSP.s = IPS_OK;
163 
164  if (DomeS[0].s == ISS_ON)
165  IDSetSwitch(&DomeSP, "Dome is open.");
166  else
167  IDSetSwitch(&DomeSP, "Dome is closed.");
168 
169  return;
170  }
171 
172 }
173 
174 void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
175 {
176  /* ignore if not ours */
177  if (dev && strcmp (mydev, dev))
178  return;
179 
180  /* suppress warning */
181  n=n; dev=dev; name=name; names=names; texts=texts;
182 }
183 
184 
185 void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) {}
186 
187 void closeDome()
188 {
189  DomeSP.s = IPS_BUSY;
190 
191  IDSetSwitch(&DomeSP, "Rain Alert! Dome is closing...");
192 
193  sleep(5);
194 
195  DomeS[0].s = ISS_OFF;
196  DomeS[1].s = ISS_ON;
197 
198  DomeSP.s = IPS_OK;
199 
200  IDSetSwitch(&DomeSP, "Dome is closed.");
201 
202 
203 }
204