Instrument Neutral Distributed Interface INDI 2.2.5
magellan1.cpp
Go to the documentation of this file.
1#if 0
2MAGELLAN Generic
3Copyright (C) 2011 Onno Hommes ([email protected])
4
5This library is free software;
6you can redistribute it and / or
7modify it under the terms of the GNU Lesser General Public
8License as published by the Free Software Foundation;
9either
10version 2.1 of the License, or (at your option) any later version.
11
12This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY;
14without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16Lesser General Public License for more details.
17
18You should have received a copy of the GNU Lesser General Public
19License along with this library;
20if not, write to the Free Software
21Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110 - 1301 USA
22
23#endif
24
25#include "magellan1.h"
26
27#include "magellandriver.h"
28
29#include <memory>
30
31extern char *me;
32
33#define COMM_GROUP "Communication"
34#define BASIC_GROUP "Position"
35
36#define MAGELLAN_TRACK 0
37#define MAGELLAN_SYNC 1
38
39/* Handy Macros */
40#define currentRA EquatorialCoordsRN[0].value
41#define currentDEC EquatorialCoordsRN[1].value
42
43static void ISPoll(void *);
44static void retryConnection(void *);
45
46/*INDI Propertries */
47
48/**********************************************************************************************/
49/************************************ GROUP: Communication ************************************/
50/**********************************************************************************************/
51
52/********************************************
53 Property: Connection
54*********************************************/
55static ISwitch ConnectS[] = { { "CONNECT", "Connect", ISS_OFF, 0, 0 }, { "DISCONNECT", "Disconnect", ISS_ON, 0, 0 } };
57 0, IPS_IDLE, ConnectS, NARRAY(ConnectS), "", 0
58 };
59
60/********************************************
61 Property: Device Port
62*********************************************/
63/*wildi removed static */
64static IText PortT[] = { { "PORT", "Port", 0, 0, 0, 0 } };
65ITextVectorProperty PortTP = { mydev, "DEVICE_PORT", "Ports", COMM_GROUP, IP_RW, 0,
66 IPS_IDLE, PortT, NARRAY(PortT), "", 0
67 };
68
69/**********************************************************************************************/
70/************************************ GROUP: Position Display**********************************/
71/**********************************************************************************************/
72
73/********************************************
74 Property: Equatorial Coordinates JNow
75 Perm: RO
76*********************************************/
77INumber EquatorialCoordsRN[] = { { "RA", "RA H:M:S", "%10.6m", 0., 24., 0., 0., 0, 0, 0 },
78 { "DEC", "Dec D:M:S", "%10.6m", -90., 90., 0., 0., 0, 0, 0 }
79};
81{
82 mydev, "EQUATORIAL_EOD_COORD", "Equatorial JNow", BASIC_GROUP, IP_RO, 120,
84};
85
86/*****************************************************************************************************/
87/**************************************** END PROPERTIES *********************************************/
88/*****************************************************************************************************/
89
90static class Loader
91{
92 Magellan1 *telescope = nullptr;
93 std::unique_ptr<Magellan1> telescope;
94 public:
95 Loader()
96 {
97 IUSaveText(&PortT[0], "/dev/ttyS0");
98 telescope.reset(new Magellan1());
99 telescope->setCurrentDeviceName(mydev);
100 IEAddTimer(POLLMS, ISPoll, nullptr);
101 }
102} loader;
103
104/**************************************************
105*** MAGELLAN1 Implementation
106***************************************************/
107
109{
110 currentSiteNum = 1;
112 lastSet = -1;
113 fault = false;
114 simulation = false;
115 currentSet = 0;
116 fd = -1;
117
118 // Children call parent routines, this is the default
119 IDLog("Initializing from MAGELLAN device...\n");
120 IDLog("Driver Version: 2011-07-28\n");
121}
122
126
127void Magellan1::setCurrentDeviceName(const char *devName)
128{
129 strcpy(thisDevice, devName);
130}
131
132void Magellan1::ISGetProperties(const char *dev)
133{
134 if (dev != nullptr && strcmp(thisDevice, dev))
135 return;
136
137 // COMM_GROUP
138 IDDefSwitch(&ConnectSP, nullptr);
139 IDDefText(&PortTP, nullptr);
140
141 // POSITION_GROUP
143
144 /* Send the basic data to the new client if the previous client(s) are already connected. */
145 if (ConnectSP.s == IPS_OK)
146 getBasicData();
147}
148
150{
151 INDI_UNUSED(root);
152}
153
154void Magellan1::ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
155{
156 IText *tp;
157
158 /* Ignore other devices */
159 if (strcmp(dev, thisDevice))
160 return;
161
162 /* See if the port is updated */
163 if (!strcmp(name, PortTP.name))
164 {
165 PortTP.s = IPS_OK;
166 tp = IUFindText(&PortTP, names[0]);
167 if (!tp)
168 return;
169
170 IUSaveText(&PortTP.tp[0], texts[0]);
171 IDSetText(&PortTP, nullptr);
172 return;
173 }
174}
175
176void Magellan1::ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
177{
178 INDI_UNUSED(dev);
179 INDI_UNUSED(name);
180 INDI_UNUSED(values);
181 INDI_UNUSED(names);
182 INDI_UNUSED(n);
183}
184
185void Magellan1::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
186{
187 INDI_UNUSED(names);
188
189 /* Ignore other devices */
190 if (strcmp(thisDevice, dev))
191 return;
192
193 // FIRST Switch ALWAYS for Connection
194 if (!strcmp(name, ConnectSP.name))
195 {
196 bool connectionEstablished = (ConnectS[0].s == ISS_ON);
197 if (IUUpdateSwitch(&ConnectSP, states, names, n) < 0)
198 return;
199 if ((connectionEstablished && ConnectS[0].s == ISS_ON) || (!connectionEstablished && ConnectS[1].s == ISS_ON))
200 {
202 IDSetSwitch(&ConnectSP, nullptr);
203 return;
204 }
206 return;
207 }
208}
209
210void Magellan1::handleError(ISwitchVectorProperty *svp, int err, const char *msg)
211{
212 svp->s = IPS_ALERT;
213
214 /* First check to see if the telescope is connected */
216 {
217 /* The telescope is off locally */
218 ConnectS[0].s = ISS_OFF;
219 ConnectS[1].s = ISS_ON;
221 IDSetSwitch(&ConnectSP, "Telescope is not responding to commands, will retry in 10 seconds.");
222
223 IDSetSwitch(svp, nullptr);
224 IEAddTimer(10000, retryConnection, &fd);
225 return;
226 }
227
228 /* If the error is a time out, then the device doesn't support this property or busy*/
229 if (err == -2)
230 {
231 svp->s = IPS_ALERT;
232 IDSetSwitch(svp, "Device timed out. Current device may be busy or does not support %s. Will retry again.", msg);
233 }
234 else
235 /* Changing property failed, user should retry. */
236 IDSetSwitch(svp, "%s failed.", msg);
237
238 fault = true;
239}
240
241void Magellan1::handleError(INumberVectorProperty *nvp, int err, const char *msg)
242{
243 nvp->s = IPS_ALERT;
244
245 /* First check to see if the telescope is connected */
247 {
248 /* The telescope is off locally */
249 ConnectS[0].s = ISS_OFF;
250 ConnectS[1].s = ISS_ON;
252 IDSetSwitch(&ConnectSP, "Telescope is not responding to commands, will retry in 10 seconds.");
253
254 IDSetNumber(nvp, nullptr);
255 IEAddTimer(10000, retryConnection, &fd);
256 return;
257 }
258
259 /* If the error is a time out, then the device doesn't support this property */
260 if (err == -2)
261 {
262 nvp->s = IPS_ALERT;
263 IDSetNumber(nvp, "Device timed out. Current device may be busy or does not support %s. Will retry again.", msg);
264 }
265 else
266 /* Changing property failed, user should retry. */
267 IDSetNumber(nvp, "%s failed.", msg);
268
269 fault = true;
270}
271
272void Magellan1::handleError(ITextVectorProperty *tvp, int err, const char *msg)
273{
274 tvp->s = IPS_ALERT;
275
276 /* First check to see if the telescope is connected */
278 {
279 /* The telescope is off locally */
280 ConnectS[0].s = ISS_OFF;
281 ConnectS[1].s = ISS_ON;
283 IDSetSwitch(&ConnectSP, "Telescope is not responding to commands, will retry in 10 seconds.");
284
285 IDSetText(tvp, nullptr);
286 IEAddTimer(10000, retryConnection, &fd);
287 return;
288 }
289
290 /* If the error is a time out, then the device doesn't support this property */
291 if (err == -2)
292 {
293 tvp->s = IPS_ALERT;
294 IDSetText(tvp, "Device timed out. Current device may be busy or does not support %s. Will retry again.", msg);
295 }
296
297 else
298 {
299 /* Changing property failed, user should retry. */
300 IDSetText(tvp, "%s failed.", msg);
301 }
302
303 fault = true;
304}
305
307{
308 fault = false;
309 IDMessage(thisDevice, "Telescope is online.");
310}
311
313{
314 return (ConnectSP.sp[0].s == ISS_ON);
315}
316
317static void retryConnection(void *p)
318{
319 int fd = *((int *)p);
320
322 {
324 IDSetSwitch(&ConnectSP, "The connection to the telescope is lost.");
325 return;
326 }
327
328 ConnectS[0].s = ISS_ON;
329 ConnectS[1].s = ISS_OFF;
331
332 IDSetSwitch(&ConnectSP, "The connection to the telescope has been resumed.");
333}
334
336{
337 int err = 0;
338
339 if (!isTelescopeOn())
340 return;
341
342 if ((err = getMAGELLANRA(fd, &currentRA)) < 0 || (err = getMAGELLANDEC(fd, &currentDEC)) < 0)
343 {
346 handleError(&EquatorialCoordsRNP, err, "Getting RA/DEC");
347 return;
348 }
349
350 if (fault)
351 correctFault();
352
354
358}
359
361{
362 char calendarDate[32];
363 int err;
364
365 /* Magellan 1 Get Calendar Date As a Test (always 1/1/96) */
366 if ((err = getCalendarDate(fd, calendarDate)) < 0)
367 IDMessage(thisDevice, "Failed to retrieve calendar date from device.");
368 else
369 IDMessage(thisDevice, "Successfully retrieved calendar date from device.");
370
371 /* Only 24 Time format on Magellan and you cant get to the local time
372 which you can set in Magellan I */
374
375 if ((err = getMAGELLANRA(fd, &targetRA)) < 0 || (err = getMAGELLANDEC(fd, &targetDEC)) < 0)
376 {
379 handleError(&EquatorialCoordsRNP, err, "Getting RA/DEC");
380 return;
381 }
382
383 if (fault)
384 correctFault();
385
388
391}
392
394{
395 switch (ConnectSP.sp[0].s)
396 {
397 case ISS_ON:
398
399 /* Magellan I only has 1200 buad, 8 data bits, 0 parity and 1 stop bit */
400 if (tty_connect(PortTP.tp[0].text, 1200, 8, 0, 1, &fd) != TTY_OK)
401 {
402 ConnectS[0].s = ISS_OFF;
403 ConnectS[1].s = ISS_ON;
405 &ConnectSP,
406 "Error connecting to port %s. Make sure you have BOTH write and read permission to your port.\n",
407 PortTP.tp[0].text);
408 return;
409 }
411 {
412 ConnectS[0].s = ISS_OFF;
413 ConnectS[1].s = ISS_ON;
414 IDSetSwitch(&ConnectSP, "Error connecting to Telescope. Telescope is offline.");
415 return;
416 }
417
418#ifdef INDI_DEBUG
419 IDLog("Telescope test successful.\n");
420#endif
421
423 IDSetSwitch(&ConnectSP, "Telescope is online. Retrieving basic data...");
424 getBasicData();
425 break;
426
427 case ISS_OFF:
428 ConnectS[0].s = ISS_OFF;
429 ConnectS[1].s = ISS_ON;
431 IDSetSwitch(&ConnectSP, "Telescope is offline.");
432 IDLog("Telescope is offline.");
434 break;
435 }
436}
bool simulation
Definition magellan1.h:66
void connectTelescope()
int currentSiteNum
Definition magellan1.h:59
char thisDevice[64]
Definition magellan1.h:67
virtual ~Magellan1()
virtual void ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
virtual void ISGetProperties(const char *dev)
bool fault
Definition magellan1.h:65
double lastDEC
Definition magellan1.h:64
double targetDEC
Definition magellan1.h:70
int trackingMode
Definition magellan1.h:60
double lastRA
Definition magellan1.h:63
bool isTelescopeOn()
int currentSet
Definition magellan1.h:68
virtual void ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
virtual void ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
virtual void ISPoll()
virtual void getBasicData()
int timeFormat
Definition magellan1.h:58
void correctFault()
void handleError(ISwitchVectorProperty *svp, int err, const char *msg)
double targetRA
Definition magellan1.h:70
virtual void ISSnoopDevice(XMLEle *root)
int lastSet
Definition magellan1.h:69
void setCurrentDeviceName(const char *devName)
#define POLLMS
void ISPoll(void *p)
Definition fli_wheel.c:393
int IEAddTimer(int millisecs, IE_TCF *fp, void *p)
Register a new single-shot timer function, fp, to be called with ud as argument after ms.
Definition eventloop.c:586
#define currentDEC
Definition ieq45.cpp:48
#define currentRA
Definition ieq45.cpp:47
ISState
Switch state.
Definition indiapi.h:148
@ ISS_OFF
Definition indiapi.h:149
@ ISS_ON
Definition indiapi.h:150
#define NARRAY(a)
Handy macro to find the number of elements in array a[]. Must be used with actual array,...
Definition indiapi.h:498
@ IP_RW
Definition indiapi.h:184
@ IP_RO
Definition indiapi.h:182
@ IPS_BUSY
Definition indiapi.h:161
@ IPS_ALERT
Definition indiapi.h:162
@ IPS_IDLE
Definition indiapi.h:159
@ IPS_OK
Definition indiapi.h:160
@ ISR_1OFMANY
Definition indiapi.h:171
int tty_connect(const char *device, int bit_rate, int word_size, int parity, int stop_bits, int *fd)
Establishes a tty connection to a terminal device.
Definition indicom.c:1022
int tty_disconnect(int fd)
Closes a tty connection and flushes the bus.
Definition indicom.c:1224
void IDLog(const char *fmt,...)
Definition indicom.c:305
@ TTY_OK
Definition indicom.h:54
IText * IUFindText(const ITextVectorProperty *tvp, const char *name)
Find an IText member in a vector text property.
Definition indidevapi.c:265
void IUSaveText(IText *tp, const char *newtext)
Function to reliably save new text in a IText.
Definition indidevapi.c:44
#define INDI_UNUSED(x)
Definition indidevapi.h:132
int IUUpdateSwitch(ISwitchVectorProperty *svp, ISState *states, char *names[], int n)
Update all switches in a switch vector property.
void IDSetNumber(const INumberVectorProperty *nvp, const char *fmt,...)
void IDSetSwitch(const ISwitchVectorProperty *svp, const char *fmt,...)
void IDMessage(const char *dev, const char *fmt,...)
Definition indidriver.c:983
void IDDefNumber(const INumberVectorProperty *nvp, const char *fmt,...)
void IDDefText(const ITextVectorProperty *tvp, const char *fmt,...)
void IDSetText(const ITextVectorProperty *tvp, const char *fmt,...)
void IDDefSwitch(const ISwitchVectorProperty *svp, const char *fmt,...)
int fd
int getCalendarDate(int fd, char *date)
ISwitchVectorProperty ConnectSP
Definition magellan1.cpp:56
INumber EquatorialCoordsRN[]
Definition magellan1.cpp:77
#define BASIC_GROUP
Definition magellan1.cpp:34
INumberVectorProperty EquatorialCoordsRNP
Definition magellan1.cpp:80
ITextVectorProperty PortTP
Definition magellan1.cpp:65
#define COMM_GROUP
Definition magellan1.cpp:33
char * me
Definition indidriver.c:50
#define getMAGELLANRA(fd, x)
#define getMAGELLANDEC(fd, x)
int check_magellan_connection(int fd)
@ MAGELLAN_24
@ MAGELLAN_TRACK_DEFAULT
One number descriptor.
One switch descriptor.
One text descriptor.
Number vector property descriptor.
Definition indiapi.h:317
double value
Definition indiapi.h:288
Switch vector property descriptor.
Definition indiapi.h:365
char name[MAXINDINAME]
Definition indiapi.h:369
ISState s
Definition indiapi.h:353
Text vector property descriptor.
Definition indiapi.h:244
char name[MAXINDINAME]
Definition indiapi.h:248
char * text
Definition indiapi.h:230
#define mydev
Definition tcfs.cpp:32