Instrument Neutral Distributed Interface INDI 2.2.5
iafscaa.cpp
Go to the documentation of this file.
1/*
2 iOptron iAFS Focuser Rotator INDI driver
3
4 Copyright (C) 2024 Jasem Mutlaq
5 Copyright (C) 2025 Joe Zhou
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20*/
21
22#include "iafscaa.h"
23#include "indicom.h"
24
25#include <stdio.h>
26#include <termios.h>
27#include <string.h>
28#include <sys/time.h>
29#include <unistd.h>
30#include <math.h>
31#include <memory>
33
34#define iEAFFOCUS_TIMEOUT 10
35#define TEMPERATURE_THRESHOLD 0.1
36#define ROTATOR_TAB "Rotator"
37
38std::unique_ptr<iAFSRotator> iafsRotator(new iAFSRotator());
39
40/************************************************************************************
41*
42* ***********************************************************************************/
51
52/************************************************************************************
53*
54* ***********************************************************************************/
55
59
60/************************************************************************************
61*
62* ***********************************************************************************/
63
65{
67
70
71 TemperatureNP[0].fill("TEMPERATURE", "Celsius", "%2.2f", 0., 50., 0., 50.);
72 TemperatureNP.fill(getDeviceName(), "FOCUS_TEMPERATURE", "Temperature", MAIN_CONTROL_TAB, IP_RO, 0, IPS_IDLE);
73
74 SetZeroSP[0].fill("SETZERO", "Sync Focuser Position To 0", ISS_OFF);
75 SetZeroSP.fill(getDeviceName(), "Zero Position", "Zero Position", MAIN_CONTROL_TAB, IP_RW, ISR_ATMOST1, 0, IPS_IDLE);
76
77 /* Relative and absolute movement */
78 FocusRelPosNP[0].setMin(0.);
79 FocusRelPosNP[0].setMax(5000.);
80 FocusRelPosNP[0].setValue(0.);
81 FocusRelPosNP[0].setStep(10.);
82
83 FocusAbsPosNP[0].setMin(0.);
84 FocusAbsPosNP[0].setMax(99999.);
85 FocusAbsPosNP[0].setValue(0.);
86 FocusAbsPosNP[0].setStep(10.);
87
88 // Rotator Properties
90
91 // Firmware
92 FirmwareTP[0].fill("VERSION", "Version", "NA");
93 FirmwareTP.fill(getDeviceName(), "FIRMWARE_INFO", "Firmware", ROTATOR_TAB, IP_RO, 60,
94 IPS_IDLE);
95 StatusTP[0].fill("STATUS", "CAA Status", "NA");
96 StatusTP.fill(getDeviceName(), "Status_INFO", "Status", ROTATOR_TAB, IP_RO, 60,
97 IPS_IDLE);
98
99 // Rotator size
100 RotatorSize[0].fill("CAASIZE", "CAA Size (inch)", "%.1f", 2.0, 4.0, 1.0, 0);
101 RotatorSize.fill(getDeviceName(), "ROTATOR_SIZE", "CAA Size", ROTATOR_TAB, IP_RW,
102 60, IPS_IDLE);
105 return true;
106}
107
108/************************************************************************************
109*
110* ***********************************************************************************/
111
113{
115 if (isConnected())
116 {
117 defineProperty(TemperatureNP);
118 defineProperty(SetZeroSP);
119 // Rotator Properties
121 defineProperty(FirmwareTP);
122 defineProperty(RotatorSize);
123 defineProperty(StatusTP);
124 GetFocusParams();
125 }
126 else
127 {
128 deleteProperty(TemperatureNP);
129 deleteProperty(SetZeroSP);
130 // Rotator Properties
132 deleteProperty(FirmwareTP);
133 deleteProperty(RotatorSize);
134 deleteProperty(StatusTP);
135 }
136
137 return true;
138
139}
140
141/************************************************************************************
142*
143* ***********************************************************************************/
144
146{
147
148 if (Ack())
149 {
150 DEBUG(INDI::Logger::DBG_SESSION, "iAFSCAA Focuse Rotater is online. Getting parameters...");
151 getFirmware();
152 return true;
153 }
154 return false;
155}
156
157/************************************************************************************
158*
159* ***********************************************************************************/
160
162{
163 return "iAFSRotator";
164}
165
166/************************************************************************************
167*
168* ***********************************************************************************/
169
170bool iAFSRotator::Ack()
171{
172 int nbytes_written = 0, nbytes_read = 0, rc = -1;
173 char resp[16];
174 int ieafpos, ieafmodel, ieaflast;
175 sleep(2);
176 tcflush(PortFD, TCIOFLUSH);
177 if ( (rc = tty_write(PortFD, ":DeviceInfo#", 12, &nbytes_written)) != TTY_OK)
178 {
179 char errstr[MAXRBUF] = {0};
180 tty_error_msg(rc, errstr, MAXRBUF);
181 DEBUGF(INDI::Logger::DBG_ERROR, "Init send getdeviceinfo error: %s.", errstr);
182 return false;
183 }
184
185 if ( (rc = tty_read_section(PortFD, resp, '#', iEAFFOCUS_TIMEOUT * 2, &nbytes_read)) != TTY_OK)
186 {
187 char errstr[MAXRBUF] = {0};
188 tty_error_msg(rc, errstr, MAXRBUF);
189 DEBUGF(INDI::Logger::DBG_ERROR, "Init read deviceinfo error: %s.", errstr);
190 return false;
191 }
192 tcflush(PortFD, TCIOFLUSH);
193 resp[nbytes_read] = '\0';
194 sscanf(resp, "%6d%2d%4d", &ieafpos, &ieafmodel, &ieaflast);
195 // iAFSCAA Focuser Rotator 02=iEAF 03=iAFS 04=iAFS no CAA 05=iAFS+CAA
196 if (ieafmodel == 5)
197 {
198 return true;
199 }
200 else
201 {
202 DEBUGF(INDI::Logger::DBG_ERROR, "Ack Response: %s", resp);
203 return false;
204 }
205
206 return true;
207}
208
209/************************************************************************************
210*
211* ***********************************************************************************/
212bool iAFSRotator::getFirmware()
213{
214 int nbytes_written = 0, nbytes_read = 0, rc = -1;
215 char errstr[MAXRBUF];
216 char resp[16] = {0};
217 char joefirmwareinfo[16] = {0};
218 char iafsfirm[7] = {0};
219 char caafirm[7] = {0};
220 tcflush(PortFD, TCIOFLUSH);
221 if ( (rc = tty_write(PortFD, ":FW1#", 5, &nbytes_written)) != TTY_OK)
222 {
223 tty_error_msg(rc, errstr, MAXRBUF);
224 DEBUGF(INDI::Logger::DBG_ERROR, "get firmware error: %s.", errstr);
225 }
226 if ( (rc = tty_read_section(PortFD, resp, '#', iEAFFOCUS_TIMEOUT, &nbytes_read)) != TTY_OK)
227 {
228 tty_error_msg(rc, errstr, MAXRBUF);
229 DEBUGF(INDI::Logger::DBG_ERROR, "get firmware error: %s.", errstr);
230 return false;
231 }
232
233 tcflush(PortFD, TCIOFLUSH);
234 resp[nbytes_read] = '\0';
235 sscanf(resp, "%12s", joefirmwareinfo);
236 rc = sscanf(resp, "%6s%6s", iafsfirm, caafirm);
237 FirmwareTP[0].setText(caafirm);
238 FirmwareTP.apply();
239 return true;
240
241}
242/************************************************************************************
243*
244* ***********************************************************************************/
245
246bool iAFSRotator::updateInfo()
247{
248 int nbytes_written = 0, nbytes_read = 0, rc = -1;
249 char errstr[MAXRBUF];
250 char resp[16] = {0};
251 char joedeviceinfo[16] = {0};
252 int ieafpos, ieafmove, ieaftemp, ieafdir;
253
254 tcflush(PortFD, TCIOFLUSH);
255 if ( (rc = tty_write(PortFD, ":FI#", 4, &nbytes_written)) != TTY_OK)
256 {
257 tty_error_msg(rc, errstr, MAXRBUF);
258 DEBUGF(INDI::Logger::DBG_ERROR, "updateInfo error: %s.", errstr);
259 }
260 sleep(5);
261 if ( (rc = tty_read_section(PortFD, resp, '#', iEAFFOCUS_TIMEOUT, &nbytes_read)) != TTY_OK)
262 {
263 tty_error_msg(rc, errstr, MAXRBUF);
264 DEBUGF(INDI::Logger::DBG_ERROR, "updateInfo error: %s.", errstr);
265 return false;
266 }
267
268 tcflush(PortFD, TCIOFLUSH);
269
270 resp[nbytes_read] = '\0';
271
272 sscanf(resp, "%14s", joedeviceinfo);
273 rc = sscanf(resp, "%7d%1d%5d%1d", &ieafpos, &ieafmove, &ieaftemp, &ieafdir);
274// LOGF_INFO("******Focuser Response: %s", resp);
275
276 if (rc != 4)
277 {
278 LOGF_ERROR("Could not parse response %s", resp);
279 return false;
280 }
281
282 m_isMoving = ieafmove == 1;
283 auto temperature = ieaftemp / 100.0 - 273.15;
284 m_Reversed = (ieafdir == 0);
285 auto currentlyReversed = FocusReverseSP[INDI_ENABLED].getState() == ISS_ON;
286
287 // Only update if there is change
288 if (std::abs(temperature - TemperatureNP[0].getValue()) > TEMPERATURE_THRESHOLD)
289 {
290 TemperatureNP[0].setValue(temperature);
291 TemperatureNP.apply();
292 }
293
294 // Only update if there is change
295
296 if (m_Reversed != currentlyReversed)
297 {
302 }
303
304 // If absolute position is different, let's update
305 if (ieafpos != FocusAbsPosNP[0].getValue())
306 {
307 FocusAbsPosNP[0].setValue(ieafpos);
308 // Check if we are busy or not.
309 if ((m_isMoving == false && FocusAbsPosNP.getState() == IPS_BUSY) || (m_isMoving && FocusAbsPosNP.getState() != IPS_BUSY))
310 {
311 FocusAbsPosNP.setState(m_isMoving ? IPS_BUSY : IPS_OK);
312 FocusRelPosNP.setState(m_isMoving ? IPS_BUSY : IPS_OK);
314 }
316 }
317 // Update status if required
318 else if ((m_isMoving == false && FocusAbsPosNP.getState() == IPS_BUSY) || (m_isMoving
320 {
321 FocusAbsPosNP.setState(m_isMoving ? IPS_BUSY : IPS_OK);
322 FocusRelPosNP.setState(m_isMoving ? IPS_BUSY : IPS_OK);
325 }
326
327 return true;
328}
329
330/************************************************************************************
331*
332* ***********************************************************************************/
333bool iAFSRotator::updateInforotator()
334{
335 int nbytes_written = 0, nbytes_read = 0, rc = -1;
336 char errstr[MAXRBUF];
337 char resp[25] = {0};
338 char joedeviceinfo[25] = {0};
339 int ieafposdelta, ieafmove, ieafcurrpos, ieafdir,ieafsize;
340 double ieafcurrangle;
341 double fieafsize;
342 tcflush(PortFD, TCIOFLUSH);
343 if ( (rc = tty_write(PortFD, ":RI#", 4, &nbytes_written)) != TTY_OK)
344 {
345 tty_error_msg(rc, errstr, MAXRBUF);
346 DEBUGF(INDI::Logger::DBG_ERROR, "updateInfoRotator error: %s.", errstr);
347 }
348
349 if ( (rc = tty_read_section(PortFD, resp, '#', iEAFFOCUS_TIMEOUT, &nbytes_read)) != TTY_OK)
350 {
351 tty_error_msg(rc, errstr, MAXRBUF);
352 DEBUGF(INDI::Logger::DBG_ERROR, "updateInfoRotator error: %s.", errstr);
353 return false;
354 }
355
356 tcflush(PortFD, TCIOFLUSH);
357
358 resp[nbytes_read] = '\0';
359
360 sscanf(resp, "%23s", joedeviceinfo);
361 rc = sscanf(resp, "%10d%1d%9d%1d%2d", &ieafposdelta, &ieafmove, &ieafcurrpos, &ieafdir,&ieafsize);
362
363
364 if (rc != 5)
365 {
366 LOGF_ERROR("Could not parse response %s", resp);
367 return false;
368 }
369
370 mr_isMoving = ieafmove == 1;
371 StatusTP[0].setText(mr_isMoving ? "Move" : "Stop");
372 StatusTP.apply();
373 mr_Reversed = (ieafdir == 0);
374// ieafcaadelta = ieafposdelta;
375 fieafsize = ieafsize/10.0;
376 if (fieafsize != RotatorSize[0].getValue())
377 {
378 RotatorSize[0].setValue(fieafsize);
379 RotatorSize.setState(IPS_OK);
380 RotatorSize.apply();
381 }
382
383 auto currentlyReversed = ReverseRotatorSP[INDI_ENABLED].getState() == ISS_ON;
384
385 // Only update if there is change
386 if (mr_Reversed != currentlyReversed)
387 {
392 }
393
394 // If absolute position is different, let's update
395 ieafcurrangle=ieafcurrpos/360000.0;
396 if ( ieafcurrangle>=360.0)
397 {
398 ieafcurrangle= ieafcurrangle-360;
399 }
400 if ( ieafcurrangle<0.0)
401 {
402 ieafcurrangle= ieafcurrangle+360;
403 }
404
405// LOGF_INFO("*******Rotator curr angle : %f", ieafcurrangle);
406 if (ieafcurrangle != GotoRotatorNP[0].getValue())
407 {
408 GotoRotatorNP[0].setValue(ieafcurrangle);
410 // Check if we are busy or not.
411
412 if ((mr_isMoving == false && GotoRotatorNP.getState() == IPS_BUSY) || (mr_isMoving && GotoRotatorNP.getState() != IPS_BUSY))
413 {
414 GotoRotatorNP.setState(m_isMoving ? IPS_BUSY : IPS_OK);
416 }
417 }
418 // Update status if required
419 else if ((mr_isMoving == false && GotoRotatorNP.getState() == IPS_BUSY) || (mr_isMoving
421 {
422 GotoRotatorNP.setState(m_isMoving ? IPS_BUSY : IPS_OK);
424 }
425
426 return true;
427}
428
429/************************************************************************************
430*
431* ***********************************************************************************/
432
434{
435 INDI_UNUSED(ticks);
436 return false;
437}
438
439/************************************************************************************
440*
441* ***********************************************************************************/
442
443bool iAFSRotator::MoveMyFocuser(uint32_t position)
444{
445 int nbytes_written = 0, rc = -1;
446 char cmd[12] = {0};
447
448 snprintf(cmd, 12, ":FM%07u#", position);
449
450 tcflush(PortFD, TCIOFLUSH);
451 if ( (rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
452 {
453 char errstr[MAXRBUF];
454 tty_error_msg(rc, errstr, MAXRBUF);
455 LOGF_ERROR("setPosition error: %s.", errstr);
456 return false;
457 }
458 return true;
459}
460
461
462/************************************************************************************
463*
464* ***********************************************************************************/
465
467{
468 int nbytes_written = 0, rc = -1;
469
470 // If there is no change, return.
471 if (enabled == m_Reversed)
472 return true;
473
474 // Change Direction
475//DEBUG(INDI::Logger::DBG_SESSION, "iAFSCAA Focuse Reverse change dir FR command...");
476
477 tcflush(PortFD, TCIOFLUSH);
478 if ( (rc = tty_write(PortFD, ":FR#", 4, &nbytes_written)) != TTY_OK)
479 {
480 char errstr[MAXRBUF];
481 tty_error_msg(rc, errstr, MAXRBUF);
482 DEBUGF(INDI::Logger::DBG_ERROR, "change Direction error: %s.", errstr);
483 return false;
484 }
485
486 return true;
487}
488
489/************************************************************************************
490*
491* ***********************************************************************************/
492
493void iAFSRotator::setZero()
494{
495 int nbytes_written = 0, rc = -1;
496 // Set Zero
497 tcflush(PortFD, TCIOFLUSH);
498 if ( (rc = tty_write(PortFD, ":FZ#", 4, &nbytes_written)) != TTY_OK)
499 {
500 char errstr[MAXRBUF];
501 tty_error_msg(rc, errstr, MAXRBUF);
502 DEBUGF(INDI::Logger::DBG_ERROR, "set Zero error: %s.", errstr);
503 return;
504 }
505 return;
506}
507
508/************************************************************************************
509*
510* ***********************************************************************************/
511
512bool iAFSRotator::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
513{
514 if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
515 {
516 if (SetZeroSP.isNameMatch(name))
517 {
518 setZero();
519 SetZeroSP.setState(IPS_OK);
520 SetZeroSP.apply();
521 return true;
522 }
524 {
525 auto currentlyReversed = ReverseRotatorSP[INDI_ENABLED].getState() == ISS_OFF;
526 ReverseRotator(currentlyReversed);
529 return true;
530 }
531 if (AbortRotatorSP.isNameMatch(name))
532 {
533 AbortRotator();
538 return true;
539 }
540
541
542 }
543
544 return INDI::Focuser::ISNewSwitch(dev, name, states, names, n);
545}
546
547/************************************************************************************
548*
549* ***********************************************************************************/
550
551void iAFSRotator::GetFocusParams ()
552{
553 updateInfo();
554 updateInforotator();
555}
556
557/************************************************************************************
558*
559* ***********************************************************************************/
560
562{
563 uint32_t targetPos = targetTicks;
564
565 bool rc = false;
566
567 rc = MoveMyFocuser(targetPos);
568
569 if (rc == false)
570 return IPS_ALERT;
571
573
574 return IPS_BUSY;
575}
576
577/************************************************************************************
578*
579* ***********************************************************************************/
580
582{
583 int relativeTicks = ((dir == FOCUS_INWARD) ? -ticks : ticks) * (m_Reversed ? -1 : 1);
584 uint32_t newPosition = FocusAbsPosNP[0].getValue() + relativeTicks;
585 newPosition = std::max(0u, std::min(static_cast<uint32_t>(FocusAbsPosNP[0].getMax()), newPosition));
586
587 auto rc = MoveMyFocuser(newPosition);
588
589 if (rc == false)
590 return IPS_ALERT;
591
592 FocusRelPosNP[0].setValue(ticks);
594
595 return IPS_BUSY;
596}
597
598/************************************************************************************
599*
600* ***********************************************************************************/
601
603{
604 if (!isConnected())
605 return;
606
607 updateInfo();
608 updateInforotator();
610}
611
612/************************************************************************************
613*
614* ***********************************************************************************/
615
617{
618 int nbytes_written;
619 tcflush(PortFD, TCIOFLUSH);
620 if (tty_write(PortFD, ":FQ#", 4, &nbytes_written) == TTY_OK)
621 {
626 return true;
627 }
628 else
629 return false;
630}
631
632
633/************************************************************************************
634*
635* ***********************************************************************************/
636
638{
639 int nbytes_written;
640 tcflush(PortFD, TCIOFLUSH);
641 DEBUG(INDI::Logger::DBG_SESSION, "iAFSCAA Abort Moving...");
642 if (tty_write(PortFD, ":RQ#", 4, &nbytes_written) == TTY_OK)
643 {
646 return true;
647 }
648 else
649 return false;
650}
651
652/************************************************************************************
653*
654* ***********************************************************************************/
655
656bool iAFSRotator::SyncRotator(double angle)
657{
658 int nbytes_written = 0, rc = -1;
659 char cmd[14] = {0};
660 int position=round(angle*3600*100);
661 snprintf(cmd, 14, ":RY%09u#", position);
662 // Set Position
663 tcflush(PortFD, TCIOFLUSH);
664
665 if ( (rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
666 {
667 char errstr[MAXRBUF];
668 tty_error_msg(rc, errstr, MAXRBUF);
669 LOGF_ERROR("setPosition error: %s.", errstr);
670 return false;
671 }
672 GotoRotatorNP[0].setValue(angle);
675 return true;
676}
677
678/************************************************************************************
679*
680* ***********************************************************************************/
681
683{
684 int nbytes_written = 0, rc = -1;
685
686 // If there is no change, return.
687 if (enabled)
688 {
689 tcflush(PortFD, TCIOFLUSH);
690 if ( (rc = tty_write(PortFD, ":RR0#", 5, &nbytes_written)) != TTY_OK)
691 {
692 char errstr[MAXRBUF];
693 tty_error_msg(rc, errstr, MAXRBUF);
694 DEBUGF(INDI::Logger::DBG_ERROR, "change Rotator Direction error: %s.", errstr);
695 return false;
696 }
701 return true;
702 }
703 else {
704
705 tcflush(PortFD, TCIOFLUSH);
706 if ( (rc = tty_write(PortFD, ":RR1#", 5, &nbytes_written)) != TTY_OK)
707 {
708 char errstr[MAXRBUF];
709 tty_error_msg(rc, errstr, MAXRBUF);
710 DEBUGF(INDI::Logger::DBG_ERROR, "change Rotator Direction error: %s.", errstr);
711 return false;
712 }
717 return true;
718 }
719}
720/************************************************************************************
721*
722* ***********************************************************************************/
723
724bool iAFSRotator::MoveMyRotator(double angle)
725{
726 int nbytes_written = 0, rc = -1;
727 char cmd[14] = {0};
728 int position=(angle*3600*100);
729 snprintf(cmd, 14, ":RM%09u#", position);
730 tcflush(PortFD, TCIOFLUSH);
731
732 if ( (rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
733 {
734 char errstr[MAXRBUF];
735 tty_error_msg(rc, errstr, MAXRBUF);
736 LOGF_ERROR("setPosition error: %s.", errstr);
737 return false;
738 }
739
741
742 tcflush(PortFD, TCIFLUSH);
743
744 return true;
745}
746
747/************************************************************************************
748 *
749* ***********************************************************************************/
751{
752 IPState state = MoveAbsRotatorAngle(angle);
753 GotoRotatorNP.setState(state);
755
756 return state;
757
758}
759
760
761/************************************************************************************
762*
763* ***********************************************************************************/
764IPState iAFSRotator::MoveAbsRotatorAngle(double angle)
765{
766 int nbytes_written = 0, rc = -1;
767 char cmd[14] = {0};
768 int position=(angle*3600*100);
769 snprintf(cmd, 14, ":RM%09u#", position);
770 tcflush(PortFD, TCIOFLUSH);
771
772 if ( (rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
773 {
774 char errstr[MAXRBUF];
775 tty_error_msg(rc, errstr, MAXRBUF);
776 LOGF_ERROR("setPosition error: %s.", errstr);
777 return IPS_ALERT;
778 }
779
781
782 tcflush(PortFD, TCIFLUSH);
783
784 return IPS_BUSY;
785
786}
787
788/************************************************************************************
789*
790* ***********************************************************************************/
791bool iAFSRotator::setCaaSize(double caasize)
792{
793 int nbytes_written = 0, rc = -1;
794 char cmd[14] = {0};
795 int position=round(caasize*10);
796 snprintf(cmd, 14, ":RS%02u#", position);
797 tcflush(PortFD, TCIOFLUSH);
798 if ( (rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
799 {
800 char errstr[MAXRBUF];
801 tty_error_msg(rc, errstr, MAXRBUF);
802 LOGF_ERROR("set CAA Size error: %s.", errstr);
803 return false;
804 }
805
806 return true;
807}
808
809/************************************************************************************
810*
811* ***********************************************************************************/
812
813bool iAFSRotator::ISNewNumber (const char * dev, const char * name, double values[], char * names[], int n)
814{
815 if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
816 {
817 if (GotoRotatorNP.isNameMatch(name))
818 {
819
820 GotoRotatorNP.update(values, names, n);
821 MoveMyRotator(GotoRotatorNP[0].getValue());
824 return true;
825 }
826
827 if (SyncRotatorNP.isNameMatch(name))
828 {
829
830 SyncRotatorNP.update(values, names, n);
831 if (SyncRotator(SyncRotatorNP[0].getValue()))
833 else
836 return true;
837 }
838
839 if (RotatorSize.isNameMatch(name))
840 {
841
842 RotatorSize.update(values, names, n);
843 if (setCaaSize(RotatorSize[0].getValue()))
844 RotatorSize.setState(IPS_OK);
845 else
846 RotatorSize.setState(IPS_ALERT);
847 RotatorSize.apply();
848 return true;
849 }
850 }
851
852 return INDI::Focuser::ISNewNumber(dev, name, values, names, n);
853}
854
855
double temperature
void setDefaultBaudRate(BaudRate newRate)
setDefaultBaudRate Set default baud rate. The default baud rate is 9600 unless otherwise changed by t...
bool isConnected() const
void setDefaultPollingPeriod(uint32_t msec)
setDefaultPollingPeriod Change the default polling period to call TimerHit() function in the driver.
void setDriverInterface(uint32_t value)
setInterface Set driver interface. By default the driver interface is set to GENERAL_DEVICE....
void setVersion(uint16_t vMajor, uint16_t vMinor)
Set driver version information to be defined in DRIVER_INFO property as vMajor.vMinor.
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
uint32_t getPollingPeriod() const
getPollingPeriod Return the polling period.
void defineProperty(INumberVectorProperty *property)
void addAuxControls()
Add Debug, Simulation, and Configuration options to the driver.
uint32_t getDriverInterface() const
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
INDI::PropertyNumber FocusRelPosNP
INDI::PropertySwitch FocusReverseSP
void SetCapability(uint32_t cap)
FI::SetCapability sets the focuser capabilities. All capabilities must be initialized.
INDI::PropertyNumber FocusAbsPosNP
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Processes incoming new switch states from the client for this device. Handles updates to FocuserInter...
virtual bool updateProperties() override
Updates the state and definition of properties based on the current connection status....
virtual bool initProperties() override
Initializes the default properties for the focuser device. Sets up standard INDI properties,...
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Processes incoming new number values from the client for this device. Handles updates to FocuserInter...
Connection::Serial * serialConnection
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
bool isNameMatch(const char *otherName) const
bool update(const double values[], const char *const names[], int n)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, ISRule rule, double timeout, IPState state)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
INDI::PropertySwitch AbortRotatorSP
void initProperties(const char *groupName)
Initialize Rotator properties. It is recommended to call this function within initProperties() of you...
bool updateProperties()
updateProperties Define or Delete Rotator properties based on the connection status of the base devic...
void SetCapability(uint32_t cap)
SetRotatorCapability sets the Rotator capabilities. All capabilities must be initialized.
INDI::PropertyNumber SyncRotatorNP
INDI::PropertySwitch ReverseRotatorSP
INDI::PropertyNumber GotoRotatorNP
Provides interface to implement Rotator functionality.
virtual bool SyncRotator(double angle) override
SyncRotator Set current angle as the supplied angle without moving the rotator.
Definition iafscaa.cpp:656
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Processes incoming new number values from the client for this device. Handles updates to FocuserInter...
Definition iafscaa.cpp:813
virtual bool Handshake() override
Performs a device-specific handshake after a connection is established. This method should be overrid...
Definition iafscaa.cpp:145
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Processes incoming new switch states from the client for this device. Handles updates to FocuserInter...
Definition iafscaa.cpp:512
virtual IPState MoveAbsFocuser(uint32_t ticks) override
MoveFocuser the focuser to an absolute position.
Definition iafscaa.cpp:561
virtual IPState MoveRelFocuser(FocusDirection dir, uint32_t ticks) override
MoveFocuser the focuser to an relative position.
Definition iafscaa.cpp:581
virtual bool AbortRotator() override
AbortRotator Abort all motion.
Definition iafscaa.cpp:637
virtual bool AbortFocuser() override
AbortFocuser all focus motion.
Definition iafscaa.cpp:616
virtual bool ReverseFocuser(bool enabled) override
ReverseFocuser Reverse focuser motion direction.
Definition iafscaa.cpp:466
virtual void TimerHit() override
Callback function to be called once SetTimer duration elapses.
Definition iafscaa.cpp:602
virtual bool initProperties() override
Initializes the default properties for the focuser device. Sets up standard INDI properties,...
Definition iafscaa.cpp:64
const char * getDefaultName() override
Definition iafscaa.cpp:161
virtual bool ReverseRotator(bool enabled) override
ReverseRotator Reverse the direction of the rotator. CW is usually the normal direction,...
Definition iafscaa.cpp:682
virtual bool updateProperties() override
Updates the state and definition of properties based on the current connection status....
Definition iafscaa.cpp:112
virtual bool SetFocuserMaxPosition(uint32_t ticks) override
SetFocuserMaxPosition Update focuser maximum position. It only updates the PresetNP property limits.
Definition iafscaa.cpp:433
virtual IPState MoveRotator(double angle) override
MoveRotator Go to specific angle.
Definition iafscaa.cpp:750
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
#define TEMPERATURE_THRESHOLD
Definition dmfc.cpp:35
#define ROTATOR_TAB
Definition gemini.cpp:39
std::unique_ptr< iAFSRotator > iafsRotator(new iAFSRotator())
#define iEAFFOCUS_TIMEOUT
Definition ieaffocus.cpp:34
ISState
Switch state.
Definition indiapi.h:148
@ ISS_OFF
Definition indiapi.h:149
@ ISS_ON
Definition indiapi.h:150
@ IP_RW
Definition indiapi.h:184
@ IP_RO
Definition indiapi.h:182
IPState
Property state.
Definition indiapi.h:158
@ 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_ATMOST1
Definition indiapi.h:172
int tty_read_section(int fd, char *buf, char stop_char, int timeout, int *nbytes_read)
read buffer from terminal with a delimiter
Definition indicom.c:653
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
Definition indicom.c:418
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
Definition indicom.c:1243
Implementations for common driver routines.
@ TTY_OK
Definition indicom.h:54
#define INDI_UNUSED(x)
Definition indidevapi.h:132
#define MAXRBUF
Definition indidriver.c:52
#define DEBUG(priority, msg)
Macro to print log messages. Example of usage of the Logger: DEBUG(DBG_DEBUG, "hello " << "world");.
Definition indilogger.h:56
#define LOGF_ERROR(fmt,...)
Definition indilogger.h:80
#define DEBUGF(priority, msg,...)
Definition indilogger.h:57
#define getDeviceName
uint8_t cmd[4]
Definition pwc-ioctl.h:2
double round(double value, int decimal_places)