00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <string.h>
00024 #include <unistd.h>
00025 #include <math.h>
00026
00027 #include "lx200_16.h"
00028 #include "lx200driver.h"
00029
00030 #define LX16GROUP "GPS/16 inch Features"
00031
00032 extern LX200Generic *telescope;
00033 extern ITextVectorProperty Time;
00034 extern int MaxReticleFlashRate;
00035
00036
00037
00038
00039
00040
00041
00042
00045
00046
00047
00050
00051
00054
00055
00056
00057 static ISwitch FanStatusS[] = { {"On", "", ISS_OFF, 0, 0}, {"Off", "", ISS_OFF, 0, 0}};
00058 static ISwitch HomeSearchS[] = { {"Save home", "", ISS_OFF, 0, 0} , {"Set home", "", ISS_OFF, 0, 0}};
00059 static ISwitch FieldDeRotatorS[] = { {"On", "", ISS_OFF, 0, 0}, {"Off", "", ISS_OFF,0 ,0}};
00060
00061
00062 #define MAXINDINAME 32
00063 #define MAXINDILABEL 32
00064 #define MAXINDIDEVICE 32
00065 #define MAXINDIGROUP 32
00066 #define MAXINDIFORMAT 32
00067
00068 static ISwitchVectorProperty FanStatusSw = { mydev, "Fan", "", LX16GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, FanStatusS, NARRAY(FanStatusS), "", 0};
00069
00070 static ISwitchVectorProperty HomeSearchSw = { mydev, "Park", "", LX16GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, HomeSearchS, NARRAY(HomeSearchS), "", 0};
00071
00072 static ISwitchVectorProperty FieldDeRotatorSw = { mydev, "Field De-rotator", "", LX16GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, FieldDeRotatorS, NARRAY(FieldDeRotatorS), "", 0};
00073
00074
00075
00076
00077 static INumber hor[] = {
00078 {"ALT", "Alt D:M:S", "%10.6m", -90., 90., 0., 0., 0, 0, 0},
00079 {"AZ", "Az D:M:S", "%10.6m", 0., 360., 0., 0., 0, 0, 0}};
00080
00081 static INumberVectorProperty horNum = {
00082 mydev, "HORIZONTAL_COORD", "Horizontal Coords", LX16GROUP, IP_RW, 0, IPS_IDLE,
00083 hor, NARRAY(hor), "", 0};
00084
00085 void changeLX200_16DeviceName(const char * newName)
00086 {
00087 strcpy(horNum.device, newName);
00088 strcpy(FanStatusSw.device, newName);
00089 strcpy(HomeSearchSw.device, newName);
00090 strcpy(FieldDeRotatorSw.device,newName);
00091 }
00092
00093 LX200_16::LX200_16() : LX200Autostar()
00094 {
00095
00096 }
00097
00098 void LX200_16::ISGetProperties (const char *dev)
00099 {
00100
00101 if (dev && strcmp (thisDevice, dev))
00102 return;
00103
00104
00105 LX200Autostar::ISGetProperties(dev);
00106
00107 IDDefNumber (&horNum, NULL);
00108
00109 IDDefSwitch (&FanStatusSw, NULL);
00110 IDDefSwitch (&HomeSearchSw, NULL);
00111 IDDefSwitch (&FieldDeRotatorSw, NULL);
00112
00113 }
00114
00115 void LX200_16::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
00116 {
00117
00118
00119 if (strcmp (dev, thisDevice))
00120 return;
00121
00122 LX200Autostar::ISNewText (dev, name, texts, names, n);
00123
00124 }
00125
00126 void LX200_16::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
00127 {
00128 double newAlt=0, newAz=0;
00129 char altStr[64], azStr[64];
00130 int err;
00131
00132
00133 if (strcmp (dev, thisDevice))
00134 return;
00135
00136 if ( !strcmp (name, horNum.name) )
00137 {
00138 int i=0, nset=0;
00139
00140 if (checkPower(&horNum))
00141 return;
00142
00143 for (nset = i = 0; i < n; i++)
00144 {
00145 INumber *horp = IUFindNumber (&horNum, names[i]);
00146 if (horp == &hor[0])
00147 {
00148 newAlt = values[i];
00149 nset += newAlt >= -90. && newAlt <= 90.0;
00150 } else if (horp == &hor[1])
00151 {
00152 newAz = values[i];
00153 nset += newAz >= 0. && newAz <= 360.0;
00154 }
00155 }
00156
00157 if (nset == 2)
00158 {
00159 if ( (err = setObjAz(newAz)) < 0 || (err = setObjAlt(newAlt)) < 0)
00160 {
00161 handleError(&horNum, err, "Setting Alt/Az");
00162 return;
00163 }
00164 horNum.s = IPS_OK;
00165
00166
00167 targetAz = newAz;
00168 targetAlt = newAlt;
00169
00170 fs_sexa(azStr, targetAz, 2, 3600);
00171 fs_sexa(altStr, targetAlt, 2, 3600);
00172
00173 IDSetNumber (&horNum, "Attempting to slew to Alt %s - Az %s", altStr, azStr);
00174 handleAltAzSlew();
00175 }
00176 else
00177 {
00178 horNum.s = IPS_IDLE;
00179 IDSetNumber(&horNum, "Altitude or Azimuth missing or invalid");
00180 }
00181
00182 return;
00183 }
00184
00185 LX200Autostar::ISNewNumber (dev, name, values, names, n);
00186 }
00187
00188
00189
00190
00191 void LX200_16::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
00192 {
00193 int index;
00194 int err;
00195
00196 if (strcmp (dev, thisDevice))
00197 return;
00198
00199 if (!strcmp(name, FanStatusSw.name))
00200 {
00201 if (checkPower(&FanStatusSw))
00202 return;
00203
00204 IUResetSwitches(&FanStatusSw);
00205 IUUpdateSwitches(&FanStatusSw, states, names, n);
00206 index = getOnSwitch(&FanStatusSw);
00207
00208 if (index == 0)
00209 {
00210 if ( (err = turnFanOn()) < 0)
00211 {
00212 handleError(&FanStatusSw, err, "Changing fan status");
00213 return;
00214 }
00215 }
00216 else
00217 {
00218 if ( (err = turnFanOff()) < 0)
00219 {
00220 handleError(&FanStatusSw, err, "Changing fan status");
00221 return;
00222 }
00223 }
00224
00225 FanStatusSw.s = IPS_OK;
00226 IDSetSwitch (&FanStatusSw, index == 0 ? "Fan is ON" : "Fan is OFF");
00227 return;
00228 }
00229
00230 if (!strcmp(name, HomeSearchSw.name))
00231 {
00232 if (checkPower(&HomeSearchSw))
00233 return;
00234
00235 IUResetSwitches(&HomeSearchSw);
00236 IUUpdateSwitches(&HomeSearchSw, states, names, n);
00237 index = getOnSwitch(&HomeSearchSw);
00238
00239 index == 0 ? seekHomeAndSave() : seekHomeAndSet();
00240 HomeSearchSw.s = IPS_BUSY;
00241 IDSetSwitch (&HomeSearchSw, index == 0 ? "Seek Home and Save" : "Seek Home and Set");
00242 return;
00243 }
00244
00245 if (!strcmp(name, FieldDeRotatorSw.name))
00246 {
00247 if (checkPower(&FieldDeRotatorSw))
00248 return;
00249
00250 IUResetSwitches(&FieldDeRotatorSw);
00251 IUUpdateSwitches(&FieldDeRotatorSw, states, names, n);
00252 index = getOnSwitch(&FieldDeRotatorSw);
00253
00254 index == 0 ? seekHomeAndSave() : seekHomeAndSet();
00255 FieldDeRotatorSw.s = IPS_OK;
00256 IDSetSwitch (&FieldDeRotatorSw, index == 0 ? "Field deRotator is ON" : "Field deRotator is OFF");
00257 return;
00258 }
00259
00260 LX200Autostar::ISNewSwitch (dev, name, states, names, n);
00261
00262 }
00263
00264 void LX200_16::handleAltAzSlew()
00265 {
00266 int i=0;
00267 char altStr[64], azStr[64];
00268
00269 if (horNum.s == IPS_BUSY)
00270 {
00271 abortSlew();
00272
00273
00274 usleep(100000);
00275 }
00276
00277 if ((i = slewToAltAz()))
00278 {
00279 horNum.s = IPS_IDLE;
00280 IDSetNumber(&horNum, "Slew not possible");
00281 return;
00282 }
00283
00284 horNum.s = IPS_BUSY;
00285 fs_sexa(azStr, targetAz, 2, 3600);
00286 fs_sexa(altStr, targetAlt, 2, 3600);
00287
00288 IDSetNumber(&horNum, "Slewing to Alt %s - Az %s", altStr, azStr);
00289 return;
00290 }
00291
00292 void LX200_16::ISPoll ()
00293 {
00294 int searchResult=0;
00295 double dx, dy;
00296 int err;
00297
00298 LX200Autostar::ISPoll();
00299
00300 switch (HomeSearchSw.s)
00301 {
00302 case IPS_IDLE:
00303 break;
00304
00305 case IPS_BUSY:
00306
00307 if ( (err = getHomeSearchStatus(&searchResult)) < 0)
00308 {
00309 handleError(&HomeSearchSw, err, "Home search");
00310 return;
00311 }
00312
00313 if (searchResult == 0)
00314 {
00315 HomeSearchSw.s = IPS_IDLE;
00316 IDSetSwitch(&HomeSearchSw, "Home search failed.");
00317 }
00318 else if (searchResult == 1)
00319 {
00320 HomeSearchSw.s = IPS_OK;
00321 IDSetSwitch(&HomeSearchSw, "Home search successful.");
00322 }
00323 else if (searchResult == 2)
00324 IDSetSwitch(&HomeSearchSw, "Home search in progress...");
00325 else
00326 {
00327 HomeSearchSw.s = IPS_IDLE;
00328 IDSetSwitch(&HomeSearchSw, "Home search error.");
00329 }
00330 break;
00331
00332 case IPS_OK:
00333 break;
00334 case IPS_ALERT:
00335 break;
00336 }
00337
00338 switch (horNum.s)
00339 {
00340 case IPS_IDLE:
00341 break;
00342
00343 case IPS_BUSY:
00344
00345 if ( (err = getLX200Az(¤tAz)) < 0 || (err = getLX200Alt(¤tAlt)) < 0)
00346 {
00347 IDSetNumber(&horNum, NULL);
00348 handleError(&horNum, err, "Get Alt/Az");
00349 return;
00350 }
00351
00352 dx = targetAz - currentAz;
00353 dy = targetAlt - currentAlt;
00354
00355 horNum.np[0].value = currentAlt;
00356 horNum.np[1].value = currentAz;
00357
00358 IDLog("targetAz is %g, currentAz is %g\n", targetAz, currentAz);
00359 IDLog("targetAlt is %g, currentAlt is %g\n**********************\n", targetAlt, currentAlt);
00360
00361
00362
00363 if ( fabs(dx) <= 0.05 && fabs(dy) <= 0.05)
00364 {
00365
00366 horNum.s = IPS_OK;
00367 currentAz = targetAz;
00368 currentAlt = targetAlt;
00369 IDSetNumber (&horNum, "Slew is complete");
00370 } else
00371 IDSetNumber (&horNum, NULL);
00372 break;
00373
00374 case IPS_OK:
00375 break;
00376
00377 case IPS_ALERT:
00378 break;
00379 }
00380
00381 }
00382
00383 void LX200_16::getBasicData()
00384 {
00385
00386 getLX200Az(&targetAz);
00387 getLX200Alt(&targetAlt);
00388
00389 horNum.np[0].value = targetAlt;
00390 horNum.np[1].value = targetAz;
00391
00392 IDSetNumber (&horNum, NULL);
00393
00394 LX200Autostar::getBasicData();
00395
00396 }