Instrument Neutral Distributed Interface INDI  1.9.2
indigps.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2  Copyright(c) 2015 Jasem Mutlaq. All rights reserved.
3 
4  INDI GPS Device Class
5 
6  This program is free software; you can redistribute it and/or modify it
7  under the terms of the GNU General Public License as published by the Free
8  Software Foundation; either version 2 of the License, or (at your option)
9  any later version.
10 
11  This program is distributed in the hope that it will be useful, but WITHOUT
12  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14  more details.
15 
16  You should have received a copy of the GNU Library General Public License
17  along with this library; see the file COPYING.LIB. If not, write to
18  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  Boston, MA 02110-1301, USA.
20 
21  The full GNU General Public License is included in this distribution in the
22  file called LICENSE.
23 *******************************************************************************/
24 
25 #include "indigps.h"
26 
27 #include <cstring>
28 
29 namespace INDI
30 {
31 
33 {
35 
36  IUFillNumber(&PeriodN[0], "PERIOD", "Period (s)", "%.f", 0, 3600, 60.0, 0);
37  IUFillNumberVector(&PeriodNP, PeriodN, 1, getDeviceName(), "GPS_REFRESH_PERIOD", "Refresh", MAIN_CONTROL_TAB, IP_RW, 0, IPS_IDLE);
38 
39  IUFillSwitch(&RefreshS[0], "REFRESH", "GPS", ISS_OFF);
40  IUFillSwitchVector(&RefreshSP, RefreshS, 1, getDeviceName(), "GPS_REFRESH", "Refresh", MAIN_CONTROL_TAB, IP_RW,
41  ISR_ATMOST1, 0, IPS_IDLE);
42 
43  IUFillNumber(&LocationN[LOCATION_LATITUDE], "LAT", "Lat (dd:mm:ss)", "%010.6m", -90, 90, 0, 0.0);
44  IUFillNumber(&LocationN[LOCATION_LONGITUDE], "LONG", "Lon (dd:mm:ss)", "%010.6m", 0, 360, 0, 0.0);
45  IUFillNumber(&LocationN[LOCATION_ELEVATION], "ELEV", "Elevation (m)", "%g", -200, 10000, 0, 0);
46  IUFillNumberVector(&LocationNP, LocationN, 3, getDeviceName(), "GEOGRAPHIC_COORD", "Location", MAIN_CONTROL_TAB,
47  IP_RO, 60, IPS_IDLE);
48 
49  IUFillText(&TimeT[0], "UTC", "UTC Time", nullptr);
50  IUFillText(&TimeT[1], "OFFSET", "UTC Offset", nullptr);
51  IUFillTextVector(&TimeTP, TimeT, 2, getDeviceName(), "TIME_UTC", "UTC", MAIN_CONTROL_TAB, IP_RO, 60, IPS_IDLE);
52 
54 
55  // Default interface, can be overridden by child
57 
58  return true;
59 }
60 
62 {
64 
65  if (isConnected())
66  {
67  // Update GPS and send values to client
68  IPState state = updateGPS();
69 
70  LocationNP.s = state;
72  TimeTP.s = state;
74  RefreshSP.s = state;
77 
78  if (state != IPS_OK)
79  {
80  if (state == IPS_BUSY)
81  DEBUG(Logger::DBG_SESSION, "GPS fix is in progress...");
82 
84  }
85  else if (PeriodN[0].value > 0)
86  timerID = SetTimer(PeriodN[0].value);
87  }
88  else
89  {
94 
95  if (timerID > 0)
96  {
98  timerID = -1;
99  }
100  }
101 
102  return true;
103 }
104 
105 void GPS::TimerHit()
106 {
107  if (!isConnected())
108  {
110  return;
111  }
112 
113  IPState state = updateGPS();
114 
115  LocationNP.s = state;
116  TimeTP.s = state;
117  RefreshSP.s = state;
118 
119  switch (state)
120  {
121  // Ok
122  case IPS_OK:
123  IDSetNumber(&LocationNP, nullptr);
124  IDSetText(&TimeTP, nullptr);
125  // We got data OK, but if we are required to update once in a while, we'll call it.
126  if (PeriodN[0].value > 0)
127  timerID = SetTimer(PeriodN[0].value*1000);
128  return;
129  break;
130 
131  // GPS fix is in progress or alert
132  case IPS_ALERT:
133  IDSetNumber(&LocationNP, nullptr);
134  IDSetText(&TimeTP, nullptr);
135  break;
136 
137  default:
138  break;
139  }
140 
142 }
143 
145 {
146  DEBUG(Logger::DBG_ERROR, "updateGPS() must be implemented in GPS device child class to update TIME_UTC and "
147  "GEOGRAPHIC_COORD properties.");
148  return IPS_ALERT;
149 }
150 
151 bool GPS::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
152 {
153  if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
154  {
155  if (!strcmp(name, RefreshSP.name))
156  {
157  RefreshS[0].s = ISS_OFF;
158  RefreshSP.s = IPS_OK;
159  IDSetSwitch(&RefreshSP, nullptr);
160 
161  // Manual trigger
162  TimerHit();
163  }
164  }
165 
166  return DefaultDevice::ISNewSwitch(dev, name, states, names, n);
167 }
168 
169 bool GPS::ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
170 {
171  if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
172  {
173  if (strcmp(name, PeriodNP.name) == 0)
174  {
175  double prevPeriod = PeriodN[0].value;
176  IUUpdateNumber(&PeriodNP, values, names, n);
177  // Do not remove timer if GPS update is still in progress
178  if (timerID > 0 && RefreshSP.s != IPS_BUSY)
179  {
181  timerID = -1;
182  }
183 
184  if (PeriodN[0].value == 0)
185  {
186  DEBUG(Logger::DBG_SESSION, "GPS Update Timer disabled.");
187  }
188  else
189  {
190  timerID = SetTimer(PeriodN[0].value*1000);
191  if (prevPeriod == 0)
192  DEBUG(Logger::DBG_SESSION, "GPS Update Timer enabled.");
193  }
194 
195  PeriodNP.s = IPS_OK;
196  IDSetNumber(&PeriodNP, nullptr);
197 
198  return true;
199  }
200  }
201 
202  return DefaultDevice::ISNewNumber(dev, name, values, names, n);
203 }
204 
205 bool GPS::saveConfigItems(FILE *fp)
206 {
208 
210  return true;
211 }
212 }
IP_RO
@ IP_RO
Definition: indiapi.h:183
INDI::GPS::LocationN
INumber LocationN[3]
Definition: indigps.h:86
IPState
IPState
Property state.
Definition: indiapi.h:158
IPS_OK
@ IPS_OK
Definition: indiapi.h:161
_INumberVectorProperty::s
IPState s
Definition: indiapi.h:332
ISS_OFF
@ ISS_OFF
Definition: indiapi.h:150
IDSetText
void IDSetText(const ITextVectorProperty *t, const char *msg,...) ATTRIBUTE_FORMAT_PRINTF(2
Tell client to update an existing text vector property.
INDI::GPS::updateProperties
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
Definition: indigps.cpp:83
IPS_ALERT
@ IPS_ALERT
Definition: indiapi.h:163
IUFillNumber
void IUFillNumber(INumber *np, const char *name, const char *label, const char *format, double min, double max, double step, double value)
Assign attributes for a number property. The number's auxiliary elements will be set to NULL.
Definition: indidriver.c:348
INDI::DefaultDevice::defineProperty
void defineProperty(INumberVectorProperty *property)
Definition: defaultdevice.cpp:997
MAIN_CONTROL_TAB
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
Definition: defaultdevice.cpp:34
INDI::Logger::DBG_ERROR
@ DBG_ERROR
Definition: indilogger.h:192
IUFillTextVector
void IUFillTextVector(ITextVectorProperty *tvp, IText *tp, int ntp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a text vector property. The vector's auxiliary elements will be set to NULL.
Definition: indidriver.c:477
INDI::DefaultDevice::setDefaultPollingPeriod
void setDefaultPollingPeriod(uint32_t msec)
setDefaultPollingPeriod Change the default polling period to call TimerHit() function in the driver.
Definition: defaultdevice.cpp:1157
INDI::GPS::timerID
int timerID
Definition: indigps.h:100
INDI::BaseDevice::getDeviceName
const char * getDeviceName() const
Definition: basedevice.cpp:799
INDI::Logger::DBG_SESSION
@ DBG_SESSION
Definition: indilogger.h:194
INDI::GPS::PeriodN
INumber PeriodN[1]
Definition: indigps.h:97
INDI::GPS::RefreshS
ISwitch RefreshS[1]
Definition: indigps.h:93
IUSaveConfigNumber
void IUSaveConfigNumber(FILE *fp, const INumberVectorProperty *nvp)
Add a number vector property value to the configuration file.
Definition: indicom.c:1434
IUFillText
void IUFillText(IText *tp, const char *name, const char *label, const char *initialText)
Assign attributes for a text property. The text's auxiliary elements will be set to NULL.
Definition: indidriver.c:369
DEBUG
#define DEBUG(priority, msg)
Macro to print log messages. Example of usage of the Logger: DEBUG(DBG_DEBUG, "hello " << "world");.
Definition: indilogger.h:56
INDI::DefaultDevice::initProperties
virtual bool initProperties()
Initilize properties initial state and value. The child class must implement this function.
Definition: defaultdevice.cpp:917
INDI::GPS::saveConfigItems
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save refresh period
Definition: indigps.cpp:227
INDI::DefaultDevice::getCurrentPollingPeriod
uint32_t getCurrentPollingPeriod() const
getCurrentPollingPeriod Return the current polling period.
Definition: defaultdevice.cpp:1139
INDI::GPS::LOCATION_ELEVATION
@ LOCATION_ELEVATION
Definition: indigps.h:54
INDI::DefaultDevice::SetTimer
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
Definition: defaultdevice.cpp:865
INDI::GPS::LOCATION_LATITUDE
@ LOCATION_LATITUDE
Definition: indigps.h:52
INDI::GPS::TimeTP
ITextVectorProperty TimeTP
Definition: indigps.h:90
INDI::GPS::LOCATION_LONGITUDE
@ LOCATION_LONGITUDE
Definition: indigps.h:53
INDI::DefaultDevice::ISNewNumber
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process the client newNumber command.
Definition: defaultdevice.cpp:593
IUFillSwitchVector
void IUFillSwitchVector(ISwitchVectorProperty *svp, ISwitch *sp, int nsp, const char *dev, const char *name, const char *label, const char *group, IPerm p, ISRule r, double timeout, IPState s)
Assign attributes for a switch vector property. The vector's auxiliary elements will be set to NULL.
Definition: indidriver.c:412
IUFillNumberVector
void IUFillNumberVector(INumberVectorProperty *nvp, INumber *np, int nnp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a number vector property. The vector's auxiliary elements will be set to NULL.
Definition: indidriver.c:455
IPS_BUSY
@ IPS_BUSY
Definition: indiapi.h:162
INDI::BaseDevice::GPS_INTERFACE
@ GPS_INTERFACE
Definition: basedevice.h:78
IPS_IDLE
@ IPS_IDLE
Definition: indiapi.h:160
INDI::GPS::TimerHit
virtual void TimerHit() override
TimerHit Keep calling updateGPS() until it is successfull, if it fails upon first connection.
Definition: indigps.cpp:127
INDI::GPS::initProperties
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
Definition: indigps.cpp:54
INDI::GPS::LocationNP
INumberVectorProperty LocationNP
Definition: indigps.h:85
ISR_ATMOST1
@ ISR_ATMOST1
Definition: indiapi.h:173
_INumberVectorProperty::name
char name[MAXINDINAME]
Definition: indiapi.h:322
INDI::GPS::ISNewSwitch
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
Definition: indigps.cpp:173
_ITextVectorProperty::name
char name[MAXINDINAME]
Definition: indiapi.h:249
INDI::BaseDevice::isConnected
bool isConnected() const
Definition: basedevice.cpp:518
INDI::GPS::ISNewNumber
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
Definition: indigps.cpp:191
INDI::GPS::TimeT
IText TimeT[2]
Definition: indigps.h:89
INDI::GPS::RefreshSP
ISwitchVectorProperty RefreshSP
Definition: indigps.h:94
_ISwitchVectorProperty::s
IPState s
Definition: indiapi.h:382
_ITextVectorProperty::s
IPState s
Definition: indiapi.h:259
INDI
Namespace to encapsulate INDI client, drivers, and mediator classes.
Definition: AlignmentSubsystemForClients.cpp:11
IUUpdateNumber
int IUUpdateNumber(INumberVectorProperty *nvp, double values[], char *names[], int n)
Update all numbers in a number vector property.
Definition: indidriver.c:225
indigps.h
INDI::DefaultDevice::saveConfigItems
virtual bool saveConfigItems(FILE *fp)
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
Definition: defaultdevice.cpp:175
IP_RW
@ IP_RW
Definition: indiapi.h:185
INDI::DefaultDevice::RemoveTimer
void RemoveTimer(int id)
Remove timer added with SetTimer.
Definition: defaultdevice.cpp:874
ISState
ISState
Switch state.
Definition: indiapi.h:148
INDI::DefaultDevice::ISNewSwitch
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process the client newSwitch command.
Definition: defaultdevice.cpp:409
INDI::GPS::PeriodNP
INumberVectorProperty PeriodNP
Definition: indigps.h:98
INDI::DefaultDevice::deleteProperty
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
Definition: defaultdevice.cpp:965
IDSetNumber
void void void IDSetNumber(const INumberVectorProperty *n, const char *msg,...) ATTRIBUTE_FORMAT_PRINTF(2
Tell client to update an existing number vector property.
IDSetSwitch
void void void void void IDSetSwitch(const ISwitchVectorProperty *s, const char *msg,...) ATTRIBUTE_FORMAT_PRINTF(2
Tell client to update an existing switch vector property.
INDI::DefaultDevice::setDriverInterface
void setDriverInterface(uint16_t value)
setInterface Set driver interface. By default the driver interface is set to GENERAL_DEVICE....
Definition: defaultdevice.cpp:902
IUFillSwitch
void IUFillSwitch(ISwitch *sp, const char *name, const char *label, ISState s)
Assign attributes for a switch property. The switch's auxiliary elements will be set to NULL.
Definition: indidriver.c:320
INDI::DefaultDevice::updateProperties
virtual bool updateProperties()
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
Definition: defaultdevice.cpp:890
INDI::GPS::updateGPS
virtual IPState updateGPS()
updateGPS Retrieve Location & Time from GPS. Update LocationNP & TimeTP properties (value and state) ...
Definition: indigps.cpp:166
_ISwitchVectorProperty::name
char name[MAXINDINAME]
Definition: indiapi.h:370