summaryrefslogtreecommitdiffstats
path: root/kstars/kstars/indi/celestrongps.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kstars/kstars/indi/celestrongps.cpp')
-rw-r--r--kstars/kstars/indi/celestrongps.cpp778
1 files changed, 778 insertions, 0 deletions
diff --git a/kstars/kstars/indi/celestrongps.cpp b/kstars/kstars/indi/celestrongps.cpp
new file mode 100644
index 00000000..a187aaf8
--- /dev/null
+++ b/kstars/kstars/indi/celestrongps.cpp
@@ -0,0 +1,778 @@
+#if 0
+ Celestron GPS
+ Copyright (C) 2003 Jasem Mutlaq (mutlaqja@ikarustech.com)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <math.h>
+#include <unistd.h>
+#include <time.h>
+
+#include "celestronprotocol.h"
+#include "celestrongps.h"
+
+#define RA_THRESHOLD 0.01
+#define DEC_THRESHOLD 0.05
+#define mydev "Celestron GPS"
+
+CelestronGPS *telescope = NULL;
+
+
+/* There is _one_ binary for all LX200 drivers, but each binary is renamed
+** to its device name (i.e. lx200gps, lx200_16..etc). The main function will
+** fetch from std args the binary name and ISInit will create the apporpiate
+** device afterwards. If the binary name does not match any known devices,
+** we simply create a generic device
+*/
+extern char* me;
+
+#define COMM_GROUP "Communication"
+#define BASIC_GROUP "Main Control"
+#define MOVE_GROUP "Movement Control"
+
+static void ISPoll(void *);
+
+/*INDI controls */
+static ISwitch PowerS[] = {{"CONNECT" , "Connect" , ISS_OFF, 0, 0},{"DISCONNECT", "Disconnect", ISS_ON, 0, 0}};
+static ISwitch SlewModeS[] = {{"Slew", "", ISS_ON, 0, 0}, {"Find", "", ISS_OFF, 0, 0}, {"Centering", "", ISS_OFF, 0, 0}, {"Guide", "", ISS_OFF, 0, 0}};
+static ISwitch OnCoordSetS[] = {{"SLEW", "Slew", ISS_ON, 0 , 0}, {"TRACK", "Track", ISS_OFF, 0, 0}, {"SYNC", "Sync", ISS_OFF, 0, 0}};
+static ISwitch abortSlewS[] = {{"ABORT", "Abort", ISS_OFF, 0, 0}};
+
+static ISwitch MovementS[] = {{"N", "North", ISS_OFF, 0, 0}, {"W", "West", ISS_OFF, 0, 0}, {"E", "East", ISS_OFF, 0, 0}, {"S", "South", ISS_OFF, 0, 0}};
+
+/* equatorial position */
+static INumber eq[] = {
+ {"RA", "RA H:M:S", "%10.6m", 0., 24., 0., 0., 0, 0, 0},
+ {"DEC", "Dec D:M:S", "%10.6m", -90., 90., 0., 0., 0, 0, 0},
+};
+//TODO decide appropiate TIME_OUT
+static INumberVectorProperty eqNum = {
+ mydev, "EQUATORIAL_EOD_COORD", "Equatorial JNow", BASIC_GROUP, IP_RW, 0, IPS_IDLE,
+ eq, NARRAY(eq), "", 0};
+
+/* Fundamental group */
+static ISwitchVectorProperty PowerSw = { mydev, "CONNECTION" , "Connection", COMM_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, PowerS, NARRAY(PowerS), "", 0};
+static IText PortT[] = {{"PORT", "Port", 0, 0, 0, 0}};
+static ITextVectorProperty Port = { mydev, "DEVICE_PORT", "Ports", COMM_GROUP, IP_RW, 0, IPS_IDLE, PortT, NARRAY(PortT), "", 0};
+
+/* Movement group */
+static ISwitchVectorProperty OnCoordSetSw = { mydev, "ON_COORD_SET", "On Set", BASIC_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, OnCoordSetS, NARRAY(OnCoordSetS), "", 0};
+static ISwitchVectorProperty abortSlewSw = { mydev, "ABORT_MOTION", "Abort Slew/Track", BASIC_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, abortSlewS, NARRAY(abortSlewS), "", 0};
+static ISwitchVectorProperty SlewModeSw = { mydev, "Slew rate", "", MOVE_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, SlewModeS, NARRAY(SlewModeS), "", 0};
+
+static ISwitchVectorProperty MovementSw = { mydev, "MOVEMENT", "Move toward", MOVE_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, MovementS, NARRAY(MovementS), "", 0};
+
+
+/* send client definitions of all properties */
+void ISInit()
+{
+ static int isInit=0;
+
+ if (isInit)
+ return;
+
+ isInit = 1;
+
+ PortT[0].text = strcpy(new char[32], "/dev/ttyS0");
+
+ telescope = new CelestronGPS();
+
+ IEAddTimer (POLLMS, ISPoll, NULL);
+}
+
+void ISGetProperties (const char *dev)
+{ ISInit(); telescope->ISGetProperties(dev);}
+void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
+{ ISInit(); telescope->ISNewSwitch(dev, name, states, names, n);}
+void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
+{ ISInit(); telescope->ISNewText(dev, name, texts, names, n);}
+void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
+{ ISInit(); telescope->ISNewNumber(dev, name, values, names, n);}
+void ISPoll (void *p) { telescope->ISPoll(); IEAddTimer (POLLMS, ISPoll, NULL); p=p;}
+void ISNewBLOB (const char */*dev*/, const char */*name*/, int */*sizes[]*/, char **/*blobs[]*/, char **/*formats[]*/, char **/*names[]*/, int /*n*/)
+{}
+
+/**************************************************
+*** LX200 Generic Implementation
+***************************************************/
+
+CelestronGPS::CelestronGPS()
+{
+
+ targetRA = lastRA = 0;
+ targetDEC = lastDEC = 0;
+ currentSet = 0;
+ lastSet = -1;
+ lastMove[0] = lastMove[1] = lastMove[2] = lastMove[3] = 0;
+
+ JD = 0;
+
+ // Children call parent routines, this is the default
+ IDLog("initilizaing from Celeston GPS device...\n");
+
+}
+
+void CelestronGPS::ISGetProperties(const char *dev)
+{
+
+ if (dev && strcmp (mydev, dev))
+ return;
+
+ // COMM_GROUP
+ IDDefSwitch (&PowerSw, NULL);
+ IDDefText (&Port, NULL);
+
+ // BASIC_GROUP
+ IDDefNumber (&eqNum, NULL);
+ IDDefSwitch (&OnCoordSetSw, NULL);
+ IDDefSwitch (&abortSlewSw, NULL);
+ IDDefSwitch (&SlewModeSw, NULL);
+
+ // Movement group
+ IDDefSwitch (&MovementSw, NULL);
+
+ /* Send the basic data to the new client if the previous client(s) are already connected. */
+ if (PowerSw.s == IPS_OK)
+ getBasicData();
+
+}
+
+void CelestronGPS::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
+{
+ IText *tp;
+
+ // suppress warning
+ n=n;
+ // ignore if not ours //
+ if (strcmp (dev, mydev))
+ return;
+
+ if (!strcmp(name, Port.name) )
+ {
+ Port.s = IPS_OK;
+
+ tp = IUFindText( &Port, names[0] );
+ if (!tp)
+ return;
+
+ tp->text = new char[strlen(texts[0])+1];
+ strcpy(tp->text, texts[0]);
+ IDSetText (&Port, NULL);
+ return;
+ }
+}
+
+int CelestronGPS::handleCoordSet()
+{
+
+ int i=0;
+ char RAStr[32], DecStr[32];
+
+ switch (currentSet)
+ {
+
+ // Slew
+ case 0:
+ lastSet = 0;
+ if (eqNum.s == IPS_BUSY)
+ {
+ StopNSEW();
+ // sleep for 500 mseconds
+ usleep(500000);
+ }
+
+ if ((i = SlewToCoords(targetRA, targetDEC)))
+ {
+ slewError(i);
+ return (-1);
+ }
+
+ eqNum.s = IPS_BUSY;
+ fs_sexa(RAStr, targetRA, 2, 3600);
+ fs_sexa(DecStr, targetDEC, 2, 3600);
+ IDSetNumber(&eqNum, "Slewing to JNOW RA %s - DEC %s", RAStr, DecStr);
+ IDLog("Slewing to JNOW RA %s - DEC %s", RAStr, DecStr);
+ break;
+
+
+ // Track
+ case 1:
+ if (eqNum.s == IPS_BUSY)
+ {
+ StopNSEW();
+ // sleep for 500 mseconds
+ usleep(500000);
+ }
+
+ if ( (fabs ( targetRA - currentRA ) >= TRACKING_THRESHOLD) ||
+ (fabs (targetDEC - currentDEC) >= TRACKING_THRESHOLD))
+ {
+
+ IDLog("Exceeded Tracking threshold, will attempt to slew to the new target.\n");
+ IDLog("targetRA is %g, currentRA is %g\n", targetRA, currentRA);
+ IDLog("targetDEC is %g, currentDEC is %g\n*************************\n", targetDEC, currentDEC);
+
+ if (( i = SlewToCoords(targetRA, targetDEC)))
+ {
+ slewError(i);
+ return (-1);
+ }
+
+ fs_sexa(RAStr, targetRA, 2, 3600);
+ fs_sexa(DecStr, targetDEC, 2, 3600);
+ eqNum.s = IPS_BUSY;
+ IDSetNumber(&eqNum, "Slewing to JNow RA %s - DEC %s", RAStr, DecStr);
+ IDLog("Slewing to JNOW RA %s - DEC %s", RAStr, DecStr);
+ }
+ else
+ {
+ IDLog("Tracking called, but tracking threshold not reached yet.\n");
+ eqNum.s = IPS_OK;
+ eqNum.np[0].value = currentRA;
+ eqNum.np[1].value = currentDEC;
+ if (lastSet != 1)
+ IDSetNumber(&eqNum, "Tracking...");
+ else
+ IDSetNumber(&eqNum, NULL);
+ }
+ lastSet = 1;
+ break;
+
+ // Sync
+ case 2:
+ lastSet = 2;
+ OnCoordSetSw.s = IPS_OK;
+ SyncToCoords(targetRA, targetDEC);
+ eqNum.s = IPS_OK;
+ IDSetNumber(&eqNum, "Synchronization successful.");
+ break;
+ }
+
+ return (0);
+
+}
+
+void CelestronGPS::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
+{
+ double newRA=0, newDEC=0;
+
+ // ignore if not ours //
+ if (strcmp (dev, mydev))
+ return;
+
+ struct tm *tp;
+ time_t t;
+
+ time (&t);
+ tp = gmtime (&t);
+
+ if (!strcmp (name, eqNum.name))
+ {
+ int i=0, nset=0;
+
+ if (checkPower(&eqNum))
+ return;
+
+ for (nset = i = 0; i < n; i++)
+ {
+ INumber *eqp = IUFindNumber (&eqNum, names[i]);
+ if (eqp == &eq[0])
+ {
+ newRA = values[i];
+ nset += newRA >= 0 && newRA <= 24.0;
+ } else if (eqp == &eq[1])
+ {
+ newDEC = values[i];
+ nset += newDEC >= -90.0 && newDEC <= 90.0;
+ }
+ }
+
+ if (nset == 2)
+ {
+ //eqNum.s = IPS_BUSY;
+
+ tp->tm_mon += 1;
+ tp->tm_year += 1900;
+
+ // update JD
+ JD = UTtoJD(tp);
+
+ IDLog("We recevined JNOW RA %f - DEC %f\n", newRA, newDEC);;
+ /*apparentCoord( (double) J2000, JD, &newRA, &newDEC);
+ IDLog("Processed to RA %f - DEC %f\n", newRA, newDEC);*/
+
+ //eqNum.np[0].value = values[0];
+ //eqNum.np[1].value = values[1];
+ targetRA = newRA;
+ targetDEC = newDEC;
+
+ if (MovementSw.s == IPS_BUSY)
+ {
+ for (int i=0; i < 4; i++)
+ {
+ lastMove[i] = 0;
+ MovementS[i].s = ISS_OFF;
+ }
+
+ MovementSw.s = IPS_IDLE;
+ IDSetSwitch(&MovementSw, NULL);
+ }
+
+ if (handleCoordSet())
+ {
+ eqNum.s = IPS_IDLE;
+ IDSetNumber(&eqNum, NULL);
+ }
+ }
+ else
+ {
+ eqNum.s = IPS_IDLE;
+ IDSetNumber(&eqNum, "RA or Dec missing or invalid.");
+ }
+
+ return;
+ }
+}
+
+void CelestronGPS::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
+{
+
+ int index;
+ ISwitch *swp;
+
+ // Suppress warning
+ names = names;
+
+ //IDLog("in new Switch with Device= %s and Property= %s and #%d items\n", dev, name,n);
+ //IDLog("SolarSw name is %s\n", SolarSw.name);
+
+ // ignore if not ours //
+ if (strcmp (dev, mydev))
+ return;
+
+ // FIRST Switch ALWAYS for power
+ if (!strcmp (name, PowerSw.name))
+ {
+ IUResetSwitches(&PowerSw);
+ IUUpdateSwitches(&PowerSw, states, names, n);
+ powerTelescope();
+ return;
+ }
+
+ if (!strcmp(name, OnCoordSetSw.name))
+ {
+ if (checkPower(&OnCoordSetSw))
+ return;
+
+ IUResetSwitches(&OnCoordSetSw);
+ IUUpdateSwitches(&OnCoordSetSw, states, names, n);
+ currentSet = getOnSwitch(&OnCoordSetSw);
+ }
+
+ // Abort Slew
+ if (!strcmp (name, abortSlewSw.name))
+ {
+ if (checkPower(&abortSlewSw))
+ {
+ abortSlewSw.s = IPS_IDLE;
+ IDSetSwitch(&abortSlewSw, NULL);
+ return;
+ }
+
+ IUResetSwitches(&abortSlewSw);
+ StopNSEW();
+
+ if (eqNum.s == IPS_BUSY)
+ {
+ abortSlewSw.s = IPS_OK;
+ eqNum.s = IPS_IDLE;
+ IDSetSwitch(&abortSlewSw, "Slew aborted.");
+ IDSetNumber(&eqNum, NULL);
+ }
+ else if (MovementSw.s == IPS_BUSY)
+ {
+
+ for (int i=0; i < 4; i++)
+ lastMove[i] = 0;
+
+ MovementSw.s = IPS_IDLE;
+ abortSlewSw.s = IPS_OK;
+ eqNum.s = IPS_IDLE;
+ IUResetSwitches(&MovementSw);
+ IUResetSwitches(&abortSlewSw);
+ IDSetSwitch(&abortSlewSw, "Slew aborted.");
+ IDSetSwitch(&MovementSw, NULL);
+ IDSetNumber(&eqNum, NULL);
+ }
+ else
+ {
+ IUResetSwitches(&MovementSw);
+ abortSlewSw.s = IPS_IDLE;
+ IDSetSwitch(&abortSlewSw, NULL);
+ }
+
+ return;
+ }
+
+ // Slew mode
+ if (!strcmp (name, SlewModeSw.name))
+ {
+ if (checkPower(&SlewModeSw))
+ return;
+
+ IUResetSwitches(&SlewModeSw);
+ IUUpdateSwitches(&SlewModeSw, states, names, n);
+ index = getOnSwitch(&SlewModeSw);
+ SetRate(index);
+
+ SlewModeSw.s = IPS_OK;
+ IDSetSwitch(&SlewModeSw, NULL);
+ return;
+ }
+
+ // Movement
+ if (!strcmp (name, MovementSw.name))
+ {
+ if (checkPower(&MovementSw))
+ return;
+
+ index = -1;
+ IUUpdateSwitches(&MovementSw, states, names, n);
+ swp = IUFindSwitch(&MovementSw, names[0]);
+
+ if (!swp)
+ {
+ StopNSEW();
+ IUResetSwitches(&MovementSw);
+ MovementSw.s = IPS_IDLE;
+ IDSetSwitch(&MovementSw, NULL);
+ }
+
+ if (swp == &MovementS[0]) index = 0;
+ else if (swp == &MovementS[1]) index = 1;
+ else if (swp == &MovementS[2]) index = 2;
+ else index = 3;
+
+ lastMove[index] = lastMove[index] == 0 ? 1 : 0;
+ if (lastMove[index] == 0)
+ MovementS[index].s = ISS_OFF;
+
+ // North/South movement is illegal
+ if (lastMove[NORTH] && lastMove[SOUTH])
+ {
+ StopNSEW();
+ for (int i=0; i < 4; i++)
+ lastMove[i] = 0;
+
+ IUResetSwitches(&MovementSw);
+ MovementSw.s = IPS_IDLE;
+ IDSetSwitch(&MovementSw, "Slew aborted.");
+ return;
+ }
+
+ // East/West movement is illegal
+ if (lastMove[EAST] && lastMove[WEST])
+ {
+ StopNSEW();
+ for (int i=0; i < 4; i++)
+ lastMove[i] = 0;
+
+ IUResetSwitches(&MovementSw);
+ MovementSw.s = IPS_IDLE;
+ IDSetSwitch(&MovementSw, "Slew aborted.");
+ return;
+ }
+
+ //IDLog("We have switch %d \n ", index);
+ //IDLog("NORTH: %d -- WEST: %d -- EAST: %d -- SOUTH %d\n", lastMove[0], lastMove[1], lastMove[2], lastMove[3]);
+
+ if (lastMove[index] == 1)
+ StartSlew(index);
+ else
+ StopSlew(index);
+
+ if (!lastMove[0] && !lastMove[1] && !lastMove[2] && !lastMove[3])
+ MovementSw.s = IPS_IDLE;
+
+ if (lastMove[index] == 0)
+ IDSetSwitch(&MovementSw, "Moving toward %s aborted.", Direction[index]);
+ else
+ {
+ MovementSw.s = IPS_BUSY;
+ IDSetSwitch(&MovementSw, "Moving %s...", Direction[index]);
+ }
+ return;
+ }
+
+}
+
+
+int CelestronGPS::getOnSwitch(ISwitchVectorProperty *sp)
+{
+ for (int i=0; i < sp->nsp ; i++)
+ if (sp->sp[i].s == ISS_ON)
+ return i;
+
+ return -1;
+}
+
+
+int CelestronGPS::checkPower(ISwitchVectorProperty *sp)
+{
+ if (PowerSw.s != IPS_OK)
+ {
+ if (!strcmp(sp->label, ""))
+ IDMessage (mydev, "Cannot change property %s while the telescope is offline.", sp->name);
+ else
+ IDMessage (mydev, "Cannot change property %s while the telescope is offline.", sp->label);
+
+ sp->s = IPS_IDLE;
+ IDSetSwitch(sp, NULL);
+ return -1;
+ }
+
+ return 0;
+}
+
+int CelestronGPS::checkPower(INumberVectorProperty *np)
+{
+ if (PowerSw.s != IPS_OK)
+ {
+ if (!strcmp(np->label, ""))
+ IDMessage (mydev, "Cannot change property %s while the telescope is offline.", np->name);
+ else
+ IDMessage (mydev, "Cannot change property %s while the telescope is offline.", np->label);
+
+ np->s = IPS_IDLE;
+ IDSetNumber(np, NULL);
+ return -1;
+ }
+ return 0;
+}
+
+int CelestronGPS::checkPower(ITextVectorProperty *tp)
+{
+
+ if (PowerSw.s != IPS_OK)
+ {
+ if (!strcmp(tp->label, ""))
+ IDMessage (mydev, "Cannot change property %s while the telescope is offline.", tp->name);
+ else
+ IDMessage (mydev, "Cannot change property %s while the telescope is offline.", tp->label);
+
+ tp->s = IPS_IDLE;
+ IDSetText(tp, NULL);
+ return -1;
+ }
+
+ return 0;
+
+}
+
+void CelestronGPS::ISPoll()
+{
+ double dx, dy;
+ double currentRA, currentDEC;
+ int status;
+
+ switch (eqNum.s)
+ {
+ case IPS_IDLE:
+ if (PowerSw.s != IPS_OK)
+ break;
+ currentRA = GetRA();
+ currentDEC = GetDec();
+
+ if ( fabs (currentRA - lastRA) > 0.01 || fabs (currentDEC - lastDEC) > 0.01)
+ {
+ eqNum.np[0].value = currentRA;
+ eqNum.np[1].value = currentDEC;
+ lastRA = currentRA;
+ lastDEC = currentDEC;
+ IDSetNumber (&eqNum, NULL);
+
+ }
+ break;
+
+ case IPS_BUSY:
+ currentRA = GetRA();
+ currentDEC = GetDec();
+ dx = targetRA - currentRA;
+ dy = targetDEC - currentDEC;
+
+ IDLog("targetRA is %f, currentRA is %f\n", (float) targetRA, (float) currentRA);
+ IDLog("targetDEC is %f, currentDEC is %f\n****************************\n", (float) targetDEC, (float) currentDEC);
+
+ eqNum.np[0].value = currentRA;
+ eqNum.np[1].value = currentDEC;
+
+ status = CheckCoords(targetRA, targetDEC);
+
+ // Wait until acknowledged or within 3.6', change as desired.
+ switch (status)
+ {
+ case 0: /* goto in progress */
+ IDSetNumber (&eqNum, NULL);
+ break;
+ case 1: /* goto complete within tolerance */
+ case 2: /* goto complete but outside tolerance */
+ currentRA = targetRA;
+ currentDEC = targetDEC;
+
+ /*apparentCoord( JD, (double) J2000, &currentRA, &currentDEC);*/
+
+ eqNum.np[0].value = currentRA;
+ eqNum.np[1].value = currentDEC;
+
+ eqNum.s = IPS_OK;
+
+ if (currentSet == 0)
+ {
+ IUResetSwitches(&OnCoordSetSw);
+ OnCoordSetSw.sp[0].s = ISS_ON;
+ IDSetNumber (&eqNum, "Slew is complete");
+ }
+ else
+ {
+ IUResetSwitches(&OnCoordSetSw);
+ OnCoordSetSw.sp[1].s = ISS_ON;
+ IDSetNumber (&eqNum, "Slew is complete. Tracking...");
+ }
+
+ IDSetSwitch (&OnCoordSetSw, NULL);
+ break;
+ }
+ break;
+
+ case IPS_OK:
+ if (PowerSw.s != IPS_OK)
+ break;
+ currentRA = GetRA();
+ currentDEC = GetDec();
+
+ if ( fabs (currentRA - lastRA) > 0.01 || fabs (currentDEC - lastDEC) > 0.01)
+ {
+
+ eqNum.np[0].value = currentRA;
+ eqNum.np[1].value = currentDEC;
+ lastRA = currentRA;
+ lastDEC = currentDEC;
+ IDSetNumber (&eqNum, NULL);
+
+ }
+ break;
+
+
+ case IPS_ALERT:
+ break;
+ }
+
+ switch (MovementSw.s)
+ {
+ case IPS_IDLE:
+ break;
+ case IPS_BUSY:
+ currentRA = GetRA();
+ currentDEC = GetDec();
+
+ /*apparentCoord( JD, (double) J2000, &currentRA, &currentDEC);*/
+
+
+ eqNum.np[0].value = currentRA;
+ eqNum.np[1].value = currentDEC;
+
+ IDSetNumber (&eqNum, NULL);
+
+ break;
+ case IPS_OK:
+ break;
+ case IPS_ALERT:
+ break;
+ }
+
+}
+
+void CelestronGPS::getBasicData()
+{
+
+ targetRA = GetRA();
+ targetDEC = GetDec();
+
+ eqNum.np[0].value = targetRA;
+ eqNum.np[1].value = targetDEC;
+
+ IDSetNumber(&eqNum, NULL);
+
+}
+
+void CelestronGPS::powerTelescope()
+{
+
+ switch (PowerSw.sp[0].s)
+ {
+ case ISS_ON:
+
+ if (ConnectTel(Port.tp[0].text) < 0)
+ {
+ PowerS[0].s = ISS_OFF;
+ PowerS[1].s = ISS_ON;
+ IDSetSwitch (&PowerSw, "Error connecting to port %s", Port.tp[0].text);
+ return;
+ }
+
+ PowerSw.s = IPS_OK;
+ IDSetSwitch (&PowerSw, "Telescope is online. Retrieving basic data...");
+ getBasicData();
+ break;
+
+ case ISS_OFF:
+ IDSetSwitch (&PowerSw, "Telescope is offline.");
+ IDLog("Telescope is offline.");
+ DisconnectTel();
+ break;
+
+ }
+}
+
+void CelestronGPS::slewError(int slewCode)
+{
+ eqNum.s = IPS_IDLE;
+
+ switch (slewCode)
+ {
+ case 1:
+ IDSetNumber (&eqNum, "Invalid newDec in SlewToCoords");
+ break;
+ case 2:
+ IDSetNumber (&eqNum, "RA count overflow in SlewToCoords");
+ break;
+ case 3:
+ IDSetNumber (&eqNum, "Dec count overflow in SlewToCoords");
+ break;
+ case 4:
+ IDSetNumber (&eqNum, "No acknowledgement from telescope after SlewToCoords");
+ break;
+ default:
+ IDSetNumber (&eqNum, "Unknown error");
+ break;
+ }
+
+}