Instrument Neutral Distributed Interface INDI  2.0.2
baader_dome.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2  Baader Planetarium Dome INDI Driver
3 
4  Copyright(c) 2014 Jasem Mutlaq. All rights reserved.
5 
6  Baader Dome INDI Driver
7 
8  This library is free software; you can redistribute it and/or
9  modify it under the terms of the GNU Library General Public
10  License version 2 as published by the Free Software Foundation.
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  Library General Public License for more details.
16  .
17  You should have received a copy of the GNU Library General Public License
18  along with this library; see the file COPYING.LIB. If not, write to
19  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  Boston, MA 02110-1301, USA.
21 *******************************************************************************/
22 
23 #include "baader_dome.h"
24 
25 #include "indicom.h"
26 
27 #include <cmath>
28 #include <cstring>
29 #include <memory>
30 #include <termios.h>
31 
32 // We declare an auto pointer to BaaderDome.
33 std::unique_ptr<BaaderDome> baaderDome(new BaaderDome());
34 
35 #define DOME_CMD 9 /* Dome command in bytes */
36 #define DOME_BUF 16 /* Dome command buffer */
37 #define DOME_TIMEOUT 3 /* 3 seconds comm timeout */
38 
39 #define SIM_SHUTTER_TIMER 5.0 /* Simulated Shutter closes/open in 5 seconds */
40 #define SIM_FLAP_TIMER 5.0 /* Simulated Flap closes/open in 3 seconds */
41 #define SIM_DOME_HI_SPEED 5.0 /* Simulated dome speed 5.0 degrees per second, constant */
42 #define SIM_DOME_LO_SPEED 0.5 /* Simulated dome speed 0.5 degrees per second, constant */
43 
45 {
46  targetAz = 0;
51 
56 
59 }
60 
62 {
64 
65  IUFillSwitch(&CalibrateS[0], "Start", "", ISS_OFF);
67  ISR_ATMOST1, 0, IPS_IDLE);
68 
69  IUFillSwitch(&DomeFlapS[0], "FLAP_OPEN", "Open", ISS_OFF);
70  IUFillSwitch(&DomeFlapS[1], "FLAP_CLOSE", "Close", ISS_ON);
72  ISR_1OFMANY, 60, IPS_OK);
73 
75 
77 
78  return true;
79 }
80 
81 /************************************************************************************
82  *
83 * ***********************************************************************************/
85 {
86  targetAz = 0;
87 
88  if (UpdatePosition())
89  IDSetNumber(&DomeAbsPosNP, nullptr);
90 
91  if (UpdateShutterStatus())
92  IDSetSwitch(&DomeShutterSP, nullptr);
93 
94  if (UpdateFlapStatus())
95  IDSetSwitch(&DomeFlapSP, nullptr);
96 
97  if (InitPark())
98  {
99  // If loading parking data is successful, we just set the default parking values.
101  }
102  else
103  {
104  // Otherwise, we set all parking data to default in case no parking data is found.
105  SetAxis1Park(0);
107  }
108 
109  return true;
110 }
111 
112 /************************************************************************************
113  *
114 * ***********************************************************************************/
116 {
117  return Ack();
118 }
119 
120 /************************************************************************************
121  *
122 * ***********************************************************************************/
124 {
125  return (const char *)"Baader Dome";
126 }
127 
128 /************************************************************************************
129  *
130 * ***********************************************************************************/
132 {
134 
135  if (isConnected())
136  {
139 
140  SetupParms();
141  }
142  else
143  {
146  }
147 
148  return true;
149 }
150 
151 /************************************************************************************
152  *
153 * ***********************************************************************************/
154 bool BaaderDome::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
155 {
156  if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
157  {
158  if (strcmp(name, CalibrateSP.name) == 0)
159  {
161 
162  if (status == DOME_READY)
163  {
164  CalibrateSP.s = IPS_OK;
165  LOG_INFO("Dome is already calibrated.");
166  IDSetSwitch(&CalibrateSP, nullptr);
167  return true;
168  }
169 
170  if (CalibrateSP.s == IPS_BUSY)
171  {
172  Abort();
173  LOG_INFO("Calibration aborted.");
176  IDSetSwitch(&CalibrateSP, nullptr);
177  return true;
178  }
179 
181 
182  LOG_INFO("Starting calibration procedure...");
183 
185 
186  calibrationStart = DomeAbsPosN[0].value;
187 
188  // Goal of procedure is to reach south point to hit sensor
190  if (calibrationTarget1 > 360)
191  calibrationTarget1 -= 360;
192 
194  {
196  LOG_ERROR("Calibration failure due to dome motion failure.");
198  IDSetSwitch(&CalibrateSP, nullptr);
199  return false;
200  }
201 
204  LOGF_INFO("Calibration is in progress. Moving to position %g.", calibrationTarget1);
205  IDSetSwitch(&CalibrateSP, nullptr);
206  return true;
207  }
208 
209  if (strcmp(name, DomeFlapSP.name) == 0)
210  {
211  int ret = 0;
212  int prevStatus = IUFindOnSwitchIndex(&DomeFlapSP);
213  IUUpdateSwitch(&DomeFlapSP, states, names, n);
214  int FlapDome = IUFindOnSwitchIndex(&DomeFlapSP);
215 
216  // No change of status, let's return
217  if (prevStatus == FlapDome)
218  {
219  DomeFlapSP.s = IPS_OK;
220  IDSetSwitch(&DomeFlapSP, nullptr);
221  }
222 
223  // go back to prev status in case of failure
225  DomeFlapS[prevStatus].s = ISS_ON;
226 
227  if (FlapDome == 0)
228  ret = ControlDomeFlap(FLAP_OPEN);
229  else
231 
232  if (ret == 0)
233  {
234  DomeFlapSP.s = IPS_OK;
236  DomeFlapS[FlapDome].s = ISS_ON;
237  IDSetSwitch(&DomeFlapSP, "Flap is %s.", (FlapDome == 0 ? "open" : "closed"));
238  return true;
239  }
240  else if (ret == 1)
241  {
244  DomeFlapS[FlapDome].s = ISS_ON;
245  IDSetSwitch(&DomeFlapSP, "Flap is %s...", (FlapDome == 0 ? "opening" : "closing"));
246  return true;
247  }
248 
250  IDSetSwitch(&DomeFlapSP, "Flap failed to %s.", (FlapDome == 0 ? "open" : "close"));
251  return false;
252  }
253  }
254 
255  return INDI::Dome::ISNewSwitch(dev, name, states, names, n);
256 }
257 
258 /************************************************************************************
259  *
260 * ***********************************************************************************/
262 {
263  int nbytes_written = 0, nbytes_read = 0, rc = -1;
264  char errstr[MAXRBUF];
265  char resp[DOME_BUF];
266  char status[DOME_BUF];
267 
268  sim = isSimulation();
269 
270  tcflush(PortFD, TCIOFLUSH);
271 
272  if (!sim && (rc = tty_write(PortFD, "d#getflap", DOME_CMD, &nbytes_written)) != TTY_OK)
273  {
274  tty_error_msg(rc, errstr, MAXRBUF);
275  LOGF_ERROR("d#getflap Ack error: %s.", errstr);
276  return false;
277  }
278 
279  LOG_DEBUG("CMD (d#getflap)");
280 
281  if (sim)
282  {
283  strncpy(resp, "d#flapclo", DOME_BUF);
284  nbytes_read = DOME_CMD;
285  }
286  else if ((rc = tty_read(PortFD, resp, DOME_CMD, DOME_TIMEOUT, &nbytes_read)) != TTY_OK)
287  {
288  tty_error_msg(rc, errstr, MAXRBUF);
289  LOGF_ERROR("Ack error: %s.", errstr);
290  return false;
291  }
292 
293  resp[nbytes_read] = '\0';
294 
295  LOGF_DEBUG("RES (%s)", resp);
296 
297  rc = sscanf(resp, "d#%s", status);
298 
299  if (rc > 0)
300  return true;
301 
302  return false;
303 }
304 
305 /************************************************************************************
306  *
307 * ***********************************************************************************/
309 {
310  int nbytes_written = 0, nbytes_read = 0, rc = -1;
311  char errstr[MAXRBUF];
312  char resp[DOME_BUF];
313  char status[DOME_BUF];
314 
315  tcflush(PortFD, TCIOFLUSH);
316 
317  if (!sim && (rc = tty_write(PortFD, "d#getshut", DOME_CMD, &nbytes_written)) != TTY_OK)
318  {
319  tty_error_msg(rc, errstr, MAXRBUF);
320  LOGF_ERROR("d#getshut UpdateShutterStatus error: %s.", errstr);
321  return false;
322  }
323 
324  LOG_DEBUG("CMD (d#getshut)");
325 
326  if (sim)
327  {
329  strncpy(resp, "d#shutclo", DOME_CMD + 1);
330  else if (simShutterStatus == SHUTTER_OPENED)
331  strncpy(resp, "d#shutope", DOME_CMD + 1);
332  else if (simShutterStatus == SHUTTER_MOVING)
333  strncpy(resp, "d#shutrun", DOME_CMD + 1);
334  nbytes_read = DOME_CMD;
335  }
336  else if ((rc = tty_read(PortFD, resp, DOME_CMD, DOME_TIMEOUT, &nbytes_read)) != TTY_OK)
337  {
338  tty_error_msg(rc, errstr, MAXRBUF);
339  LOGF_ERROR("UpdateShutterStatus error: %s.", errstr);
340  return false;
341  }
342 
343  resp[nbytes_read] = '\0';
344 
345  LOGF_DEBUG("RES (%s)", resp);
346 
347  rc = sscanf(resp, "d#shut%s", status);
348 
349  if (rc > 0)
350  {
353 
354  if (strcmp(status, "ope") == 0)
355  {
358 
361  }
362  else if (strcmp(status, "clo") == 0)
363  {
366 
369  }
370  else if (strcmp(status, "run") == 0)
371  {
374  }
375  else
376  {
379  LOGF_ERROR("Unknown Shutter status: %s.", resp);
380  }
381  return true;
382  }
383  return false;
384 }
385 
386 /************************************************************************************
387  *
388 * ***********************************************************************************/
390 {
391  int nbytes_written = 0, nbytes_read = 0, rc = -1;
392  char errstr[MAXRBUF];
393  char resp[DOME_BUF];
394  unsigned short domeAz = 0;
395 
396  tcflush(PortFD, TCIOFLUSH);
397 
398  if (!sim && (rc = tty_write(PortFD, "d#getazim", DOME_CMD, &nbytes_written)) != TTY_OK)
399  {
400  tty_error_msg(rc, errstr, MAXRBUF);
401  LOGF_ERROR("d#getazim UpdatePosition error: %s.", errstr);
402  return false;
403  }
404 
405  LOG_DEBUG("CMD (d#getazim)");
406 
407  if (sim)
408  {
410  snprintf(resp, DOME_BUF, "d#azr%04d", MountAzToDomeAz(DomeAbsPosN[0].value));
411  else
412  snprintf(resp, DOME_BUF, "d#azi%04d", MountAzToDomeAz(DomeAbsPosN[0].value));
413  nbytes_read = DOME_CMD;
414  }
415  else if ((rc = tty_read(PortFD, resp, DOME_CMD, DOME_TIMEOUT, &nbytes_read)) != TTY_OK)
416  {
417  tty_error_msg(rc, errstr, MAXRBUF);
418  LOGF_ERROR("UpdatePosition error: %s.", errstr);
419  return false;
420  }
421 
422  resp[nbytes_read] = '\0';
423 
424  LOGF_DEBUG("RES (%s)", resp);
425 
426  rc = sscanf(resp, "d#azr%hu", &domeAz);
427 
428  if (rc > 0)
429  {
431  {
432  status = DOME_READY;
434  LOG_INFO("Dome is calibrated.");
435  CalibrateSP.s = IPS_OK;
436  IDSetSwitch(&CalibrateSP, nullptr);
437  }
438  else if (status == DOME_CALIBRATING)
439  {
440  status = DOME_READY;
442  LOG_INFO("Calibration complete.");
443  CalibrateSP.s = IPS_OK;
444  IDSetSwitch(&CalibrateSP, nullptr);
445  }
446 
447  DomeAbsPosN[0].value = DomeAzToMountAz(domeAz);
448  return true;
449  }
450  else
451  {
452  rc = sscanf(resp, "d#azi%hu", &domeAz);
453  if (rc > 0)
454  {
455  DomeAbsPosN[0].value = DomeAzToMountAz(domeAz);
456  return true;
457  }
458  }
459  return false;
460 }
461 
462 /************************************************************************************
463  *
464 * ***********************************************************************************/
465 unsigned short BaaderDome::MountAzToDomeAz(double mountAz)
466 {
467  int domeAz = 0;
468 
469  domeAz = (mountAz) * 10.0 - 1800;
470 
471  if (mountAz >= 0 && mountAz <= 179.9)
472  domeAz += 3600;
473 
474  if (domeAz > 3599)
475  domeAz = 3599;
476  else if (domeAz < 0)
477  domeAz = 0;
478 
479  return ((unsigned short)(domeAz));
480 }
481 
482 /************************************************************************************
483  *
484 * ***********************************************************************************/
485 double BaaderDome::DomeAzToMountAz(unsigned short domeAz)
486 {
487  double mountAz = 0;
488 
489  mountAz = ((double)(domeAz + 1800)) / 10.0;
490 
491  if (domeAz >= 1800)
492  mountAz -= 360;
493 
494  if (mountAz > 360)
495  mountAz -= 360;
496  else if (mountAz < 0)
497  mountAz += 360;
498 
499  return mountAz;
500 }
501 
502 /************************************************************************************
503  *
504 * ***********************************************************************************/
506 {
507  if (!isConnected())
508  return; // No need to reset timer if we are not connected anymore
509 
510  UpdatePosition();
511 
512  if (DomeAbsPosNP.s == IPS_BUSY)
513  {
514  if (sim)
515  {
516  double speed = 0;
517  if (fabs(targetAz - DomeAbsPosN[0].value) > SIM_DOME_HI_SPEED)
518  speed = SIM_DOME_HI_SPEED;
519  else
520  speed = SIM_DOME_LO_SPEED;
521 
522  if (DomeRelPosNP.s == IPS_BUSY)
523  {
524  // CW
525  if (DomeMotionS[0].s == ISS_ON)
526  DomeAbsPosN[0].value += speed;
527  // CCW
528  else
529  DomeAbsPosN[0].value -= speed;
530  }
531  else
532  {
533  if (targetAz > DomeAbsPosN[0].value)
534  {
535  DomeAbsPosN[0].value += speed;
536  }
537  else if (targetAz < DomeAbsPosN[0].value)
538  {
539  DomeAbsPosN[0].value -= speed;
540  }
541  }
542 
543  if (DomeAbsPosN[0].value < DomeAbsPosN[0].min)
544  DomeAbsPosN[0].value += DomeAbsPosN[0].max;
545  if (DomeAbsPosN[0].value > DomeAbsPosN[0].max)
546  DomeAbsPosN[0].value -= DomeAbsPosN[0].max;
547  }
548 
549  if (fabs(targetAz - DomeAbsPosN[0].value) < DomeParamN[0].value)
550  {
551  DomeAbsPosN[0].value = targetAz;
552  LOG_INFO("Dome reached requested azimuth angle.");
553 
554  if (status != DOME_CALIBRATING)
555  {
556  if (getDomeState() == DOME_PARKING)
557  SetParked(true);
558  else if (getDomeState() == DOME_UNPARKING)
559  SetParked(false);
560  else
562  }
563 
564  if (status == DOME_CALIBRATING)
565  {
567  {
568  LOG_INFO("Calibration stage 1 complete. Starting stage 2...");
569  calibrationTarget2 = DomeAbsPosN[0].value + 2;
573  }
575  {
577  "Calibration stage 2 complete. Returning to initial position %g...", calibrationStart);
581  }
583  {
585  LOG_INFO("Dome reached initial position.");
586  }
587  }
588  }
589 
590  IDSetNumber(&DomeAbsPosNP, nullptr);
591  }
592  else
593  IDSetNumber(&DomeAbsPosNP, nullptr);
594 
596 
597  if (sim && DomeShutterSP.s == IPS_BUSY)
598  {
599  if (simShutterTimer-- <= 0)
600  {
601  simShutterTimer = 0;
603  }
604  }
605  else
606  IDSetSwitch(&DomeShutterSP, nullptr);
607 
609 
610  if (sim && DomeFlapSP.s == IPS_BUSY)
611  {
612  if (simFlapTimer-- <= 0)
613  {
614  simFlapTimer = 0;
616  }
617  }
618  else
619  IDSetSwitch(&DomeFlapSP, nullptr);
620 
622 }
623 
624 /************************************************************************************
625  *
626 * ***********************************************************************************/
628 {
629  int nbytes_written = 0, nbytes_read = 0, rc = -1;
630  char errstr[MAXRBUF];
631  char cmd[DOME_BUF];
632  char resp[DOME_BUF];
633 
634  if (status == DOME_UNKNOWN)
635  {
636  LOG_WARN("Dome is not calibrated. Please calibrate dome before issuing any commands.");
637  return IPS_ALERT;
638  }
639 
640  targetAz = az;
641 
642  snprintf(cmd, DOME_BUF, "d#azi%04d", MountAzToDomeAz(targetAz));
643 
644  tcflush(PortFD, TCIOFLUSH);
645 
646  if (!sim && (rc = tty_write(PortFD, cmd, DOME_CMD, &nbytes_written)) != TTY_OK)
647  {
648  tty_error_msg(rc, errstr, MAXRBUF);
649  LOGF_ERROR("%s MoveAbsDome error: %s.", cmd, errstr);
650  return IPS_ALERT;
651  }
652 
653  LOGF_DEBUG("CMD (%s)", cmd);
654 
655  if (sim)
656  {
657  strncpy(resp, "d#gotmess", DOME_CMD + 1);
658  nbytes_read = DOME_CMD;
659  }
660  else if ((rc = tty_read(PortFD, resp, DOME_CMD, DOME_TIMEOUT, &nbytes_read)) != TTY_OK)
661  {
662  tty_error_msg(rc, errstr, MAXRBUF);
663  LOGF_ERROR("MoveAbsDome error: %s.", errstr);
664  return IPS_ALERT;
665  }
666 
667  resp[nbytes_read] = '\0';
668 
669  LOGF_DEBUG("RES (%s)", resp);
670 
671  if (strcmp(resp, "d#gotmess") == 0)
672  return IPS_BUSY;
673 
674  return IPS_ALERT;
675 }
676 
677 /************************************************************************************
678  *
679 * ***********************************************************************************/
681 {
682  targetAz = DomeAbsPosN[0].value + azDiff;
683 
684  if (targetAz < DomeAbsPosN[0].min)
685  targetAz += DomeAbsPosN[0].max;
686  if (targetAz > DomeAbsPosN[0].max)
687  targetAz -= DomeAbsPosN[0].max;
688 
689  // It will take a few cycles to reach final position
690  return MoveAbs(targetAz);
691 }
692 
693 /************************************************************************************
694  *
695 * ***********************************************************************************/
697 {
699 
700  return MoveAbs(targetAz);
701 }
702 
703 /************************************************************************************
704  *
705 * ***********************************************************************************/
707 {
708  return IPS_OK;
709 }
710 
711 /************************************************************************************
712  *
713 * ***********************************************************************************/
715 {
716  int nbytes_written = 0, nbytes_read = 0, rc = -1;
717  char errstr[MAXRBUF];
718  char cmd[DOME_BUF];
719  char resp[DOME_BUF];
720 
721  memset(cmd, 0, sizeof(cmd));
722 
723  if (operation == SHUTTER_OPEN)
724  {
725  targetShutter = operation;
726  strncpy(cmd, "d#opeshut", DOME_CMD + 1);
727  }
728  else
729  {
730  targetShutter = operation;
731  strncpy(cmd, "d#closhut", DOME_CMD + 1);
732  }
733 
734  tcflush(PortFD, TCIOFLUSH);
735 
736  if (!sim && (rc = tty_write(PortFD, cmd, DOME_CMD, &nbytes_written)) != TTY_OK)
737  {
738  tty_error_msg(rc, errstr, MAXRBUF);
739  LOGF_ERROR("%s ControlDomeShutter error: %s.", cmd, errstr);
740  return IPS_ALERT;
741  }
742 
743  LOGF_DEBUG("CMD (%s)", cmd);
744 
745  if (sim)
746  {
748  strncpy(resp, "d#gotmess", DOME_CMD + 1);
749  nbytes_read = DOME_CMD;
750  }
751  else if ((rc = tty_read(PortFD, resp, DOME_CMD, DOME_TIMEOUT, &nbytes_read)) != TTY_OK)
752  {
753  tty_error_msg(rc, errstr, MAXRBUF);
754  LOGF_ERROR("ControlDomeShutter error: %s.", errstr);
755  return IPS_ALERT;
756  }
757 
758  resp[nbytes_read] = '\0';
759 
760  LOGF_DEBUG("RES (%s)", resp);
761 
762  if (strcmp(resp, "d#gotmess") == 0)
763  {
765  return IPS_BUSY;
766  }
767  return IPS_ALERT;
768 }
769 
770 /************************************************************************************
771  *
772 * ***********************************************************************************/
774 {
775  LOGF_INFO("Attempting to abort dome motion by stopping at %g", DomeAbsPosN[0].value);
776  MoveAbs(DomeAbsPosN[0].value);
777  return true;
778 }
779 
780 /************************************************************************************
781  *
782 * ***********************************************************************************/
784 {
785  switch (status)
786  {
787  case FLAP_OPENED:
788  return "Flap is open.";
789  break;
790  case FLAP_CLOSED:
791  return "Flap is closed.";
792  break;
793  case FLAP_MOVING:
794  return "Flap is in motion.";
795  break;
796  case FLAP_UNKNOWN:
797  default:
798  return "Flap status is unknown.";
799  break;
800  }
801 }
802 
803 /************************************************************************************
804  *
805 * ***********************************************************************************/
807 {
808  int nbytes_written = 0, nbytes_read = 0, rc = -1;
809  char errstr[MAXRBUF];
810  char cmd[DOME_BUF];
811  char resp[DOME_BUF];
812 
813  memset(cmd, 0, sizeof(cmd));
814 
815  if (operation == FLAP_OPEN)
816  {
817  targetFlap = operation;
818  strncpy(cmd, "d#opeflap", DOME_CMD + 1);
819  }
820  else
821  {
822  targetFlap = operation;
823  strncpy(cmd, "d#cloflap", DOME_CMD + 1);
824  }
825 
826  tcflush(PortFD, TCIOFLUSH);
827 
828  if (!sim && (rc = tty_write(PortFD, cmd, DOME_CMD, &nbytes_written)) != TTY_OK)
829  {
830  tty_error_msg(rc, errstr, MAXRBUF);
831  LOGF_ERROR("%s ControlDomeFlap error: %s.", cmd, errstr);
832  return -1;
833  }
834 
835  LOGF_DEBUG("CMD (%s)", cmd);
836 
837  if (sim)
838  {
840  strncpy(resp, "d#gotmess", DOME_CMD + 1);
841  nbytes_read = DOME_CMD;
842  }
843  else if ((rc = tty_read(PortFD, resp, DOME_CMD, DOME_TIMEOUT, &nbytes_read)) != TTY_OK)
844  {
845  tty_error_msg(rc, errstr, MAXRBUF);
846  LOGF_ERROR("ControlDomeFlap error: %s.", errstr);
847  return -1;
848  }
849 
850  resp[nbytes_read] = '\0';
851 
852  LOGF_DEBUG("RES (%s)", resp);
853 
854  if (strcmp(resp, "d#gotmess") == 0)
855  {
857  return 1;
858  }
859  return -1;
860 }
861 
862 /************************************************************************************
863  *
864 * ***********************************************************************************/
866 {
867  int nbytes_written = 0, nbytes_read = 0, rc = -1;
868  char errstr[MAXRBUF];
869  char resp[DOME_BUF];
870  char status[DOME_BUF];
871 
872  tcflush(PortFD, TCIOFLUSH);
873 
874  if (!sim && (rc = tty_write(PortFD, "d#getflap", DOME_CMD, &nbytes_written)) != TTY_OK)
875  {
876  tty_error_msg(rc, errstr, MAXRBUF);
877  LOGF_ERROR("d#getflap UpdateflapStatus error: %s.", errstr);
878  return false;
879  }
880 
881  LOG_DEBUG("CMD (d#getflap)");
882 
883  if (sim)
884  {
885  if (simFlapStatus == FLAP_CLOSED)
886  strncpy(resp, "d#flapclo", DOME_CMD + 1);
887  else if (simFlapStatus == FLAP_OPENED)
888  strncpy(resp, "d#flapope", DOME_CMD + 1);
889  else if (simFlapStatus == FLAP_MOVING)
890  strncpy(resp, "d#flaprun", DOME_CMD + 1);
891  nbytes_read = DOME_CMD;
892  }
893  else if ((rc = tty_read(PortFD, resp, DOME_CMD, DOME_TIMEOUT, &nbytes_read)) != TTY_OK)
894  {
895  tty_error_msg(rc, errstr, MAXRBUF);
896  LOGF_ERROR("UpdateflapStatus error: %s.", errstr);
897  return false;
898  }
899 
900  resp[nbytes_read] = '\0';
901 
902  LOGF_DEBUG("RES (%s)", resp);
903 
904  rc = sscanf(resp, "d#flap%s", status);
905 
906  if (rc > 0)
907  {
908  DomeFlapSP.s = IPS_OK;
910 
911  if (strcmp(status, "ope") == 0)
912  {
915 
918  }
919  else if (strcmp(status, "clo") == 0)
920  {
923 
926  }
927  else if (strcmp(status, "run") == 0)
928  {
931  }
932  else
933  {
936  LOGF_ERROR("Unknown flap status: %s.", resp);
937  }
938  return true;
939  }
940  return false;
941 }
942 
943 /************************************************************************************
944  *
945 * ***********************************************************************************/
947 {
948  int nbytes_written = 0, nbytes_read = 0, rc = -1;
949  char errstr[MAXRBUF];
950  char cmd[DOME_BUF];
951  char resp[DOME_BUF];
952 
953  strncpy(cmd, "d#encsave", DOME_CMD + 1);
954 
955  tcflush(PortFD, TCIOFLUSH);
956 
957  if (!sim && (rc = tty_write(PortFD, cmd, DOME_CMD, &nbytes_written)) != TTY_OK)
958  {
959  tty_error_msg(rc, errstr, MAXRBUF);
960  LOGF_ERROR("%s SaveEncoderPosition error: %s.", cmd, errstr);
961  return false;
962  }
963 
964  LOGF_DEBUG("CMD (%s)", cmd);
965 
966  if (sim)
967  {
968  strncpy(resp, "d#gotmess", DOME_CMD + 1);
969  nbytes_read = DOME_CMD;
970  }
971  else if ((rc = tty_read(PortFD, resp, DOME_CMD, DOME_TIMEOUT, &nbytes_read)) != TTY_OK)
972  {
973  tty_error_msg(rc, errstr, MAXRBUF);
974  LOGF_ERROR("SaveEncoderPosition error: %s.", errstr);
975  return false;
976  }
977 
978  resp[nbytes_read] = '\0';
979 
980  LOGF_DEBUG("RES (%s)", resp);
981 
982  return strcmp(resp, "d#gotmess") == 0;
983 }
984 
985 /************************************************************************************
986  *
987 * ***********************************************************************************/
989 {
990  // Only save if calibration is complete
993 
994  return INDI::Dome::saveConfigItems(fp);
995 }
996 
997 /************************************************************************************
998  *
999 * ***********************************************************************************/
1001 {
1002  SetAxis1Park(DomeAbsPosN[0].value);
1003  return true;
1004 }
1005 /************************************************************************************
1006  *
1007 * ***********************************************************************************/
1008 
1010 {
1011  // By default set position to 90
1012  SetAxis1Park(90);
1013  return true;
1014 }
#define DOME_TIMEOUT
Definition: baader_dome.cpp:37
#define SIM_SHUTTER_TIMER
Definition: baader_dome.cpp:39
#define SIM_DOME_HI_SPEED
Definition: baader_dome.cpp:41
#define DOME_CMD
Definition: baader_dome.cpp:35
#define SIM_DOME_LO_SPEED
Definition: baader_dome.cpp:42
#define SIM_FLAP_TIMER
Definition: baader_dome.cpp:40
#define DOME_BUF
Definition: baader_dome.cpp:36
std::unique_ptr< BaaderDome > baaderDome(new BaaderDome())
FlapStatus simFlapStatus
Definition: baader_dome.h:99
int ControlDomeFlap(FlapOperation operation)
virtual IPState MoveAbs(double az) override
Move the Dome to an absolute azimuth.
bool UpdateShutterStatus()
bool SaveEncoderPosition()
CalibrationStage calibrationStage
Definition: baader_dome.h:88
FlapOperation targetFlap
Definition: baader_dome.h:94
unsigned short MountAzToDomeAz(double mountAz)
ISwitch CalibrateS[1]
Definition: baader_dome.h:80
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Saves the Device Port and Dome Presets in the configuration file
const char * GetFlapStatusString(FlapStatus status)
double simFlapTimer
Definition: baader_dome.h:97
double calibrationTarget1
Definition: baader_dome.h:91
ISwitchVectorProperty DomeFlapSP
Definition: baader_dome.h:84
double calibrationTarget2
Definition: baader_dome.h:92
virtual const char * getDefaultName() override
virtual bool Handshake() override
perform handshake with device to check communication
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual IPState ControlShutter(ShutterOperation operation) override
Open or Close shutter.
FlapStatus flapStatus
Definition: baader_dome.h:87
ShutterState simShutterStatus
Definition: baader_dome.h:98
double simShutterTimer
Definition: baader_dome.h:96
bool UpdateFlapStatus()
bool UpdatePosition()
virtual bool SetDefaultPark() override
SetDefaultPark Set default coordinates/encoders value as the desired parking position.
bool SetupParms()
Definition: baader_dome.cpp:84
@ CALIBRATION_UNKNOWN
Definition: baader_dome.h:31
@ CALIBRATION_STAGE1
Definition: baader_dome.h:32
@ CALIBRATION_STAGE3
Definition: baader_dome.h:34
@ CALIBRATION_COMPLETE
Definition: baader_dome.h:35
@ CALIBRATION_STAGE2
Definition: baader_dome.h:33
virtual bool SetCurrentPark() override
SetCurrentPark Set current coordinates/encoders value as the desired parking position.
virtual bool Abort() override
Abort all dome motion.
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
Definition: baader_dome.cpp:61
virtual IPState UnPark() override
UnPark dome. The action of the Unpark command is dome specific, but it may include opening the shutte...
ShutterOperation targetShutter
Definition: baader_dome.h:93
@ DOME_CALIBRATING
Definition: baader_dome.h:28
double calibrationStart
Definition: baader_dome.h:90
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual IPState Park() override
Goto Park Position. The park position is an absolute azimuth value.
double targetAz
Definition: baader_dome.h:89
ISwitchVectorProperty CalibrateSP
Definition: baader_dome.h:81
virtual IPState MoveRel(double azDiff) override
Move the Dome to an relative position.
virtual void TimerHit() override
Callback function to be called once SetTimer duration elapses.
ISwitch DomeFlapS[2]
Definition: baader_dome.h:83
double DomeAzToMountAz(unsigned short domeAz)
DomeStatus status
Definition: baader_dome.h:86
bool isConnected() const
Definition: basedevice.cpp:520
const char * getDeviceName() const
Definition: basedevice.cpp:821
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
void defineProperty(INumberVectorProperty *property)
uint32_t getCurrentPollingPeriod() const
getCurrentPollingPeriod Return the current polling period.
bool isSimulation() const
void addAuxControls()
Add Debug, Simulation, and Configuration options to the driver.
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
ISwitch DomeShutterS[2]
Definition: indidome.h:549
@ DOME_CAN_PARK
Definition: indidome.h:159
@ DOME_CAN_ABS_MOVE
Definition: indidome.h:157
@ DOME_HAS_SHUTTER
Definition: indidome.h:161
@ DOME_CAN_REL_MOVE
Definition: indidome.h:158
@ DOME_CAN_ABORT
Definition: indidome.h:156
@ DOME_HAS_VARIABLE_SPEED
Definition: indidome.h:162
ISwitch DomeMotionS[2]
Definition: indidome.h:531
void SetParked(bool isparked)
SetParked Change the mount parking status. The data park file (stored in ~/.indi/ParkData....
Definition: indidome.cpp:1633
void SetDomeCapability(uint32_t cap)
SetDomeCapability set the dome capabilities. All capabilities must be initialized.
Definition: indidome.cpp:1561
const char * GetShutterStatusString(ShutterState status)
getShutterStatusString
Definition: indidome.cpp:1569
@ DOME_UNPARKING
Definition: indidome.h:135
@ DOME_PARKING
Definition: indidome.h:134
@ DOME_SYNCED
Definition: indidome.h:133
ShutterState m_ShutterState
Definition: indidome.h:624
void SetAxis1Park(double value)
SetRAPark Set current AZ parking position. The data park file (stored in ~/.indi/ParkData....
Definition: indidome.cpp:1861
INumber DomeAbsPosN[1]
Definition: indidome.h:534
void SetAxis1ParkDefault(double steps)
SetAxis1Park Set default AZ parking position.
Definition: indidome.cpp:1868
ShutterOperation
Shutter operation command.
Definition: indidome.h:114
@ SHUTTER_CLOSE
Definition: indidome.h:116
@ SHUTTER_OPEN
Definition: indidome.h:115
int PortFD
Definition: indidome.h:617
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
Definition: indidome.cpp:93
INumberVectorProperty DomeAbsPosNP
Definition: indidome.h:533
double GetAxis1Park()
Definition: indidome.cpp:1851
ISwitchVectorProperty DomeShutterSP
Definition: indidome.h:548
@ SHUTTER_MOVING
Definition: indidome.h:149
@ SHUTTER_UNKNOWN
Definition: indidome.h:150
@ SHUTTER_OPENED
Definition: indidome.h:147
@ SHUTTER_CLOSED
Definition: indidome.h:148
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
Definition: indidome.cpp:279
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
Definition: indidome.cpp:492
INumberVectorProperty DomeRelPosNP
Definition: indidome.h:536
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Saves the Device Port and Dome Presets in the configuration file
Definition: indidome.cpp:1043
INumber DomeParamN[1]
Definition: indidome.h:543
void setDomeState(const DomeState &value)
Definition: indidome.cpp:1156
bool InitPark()
InitPark Loads parking data (stored in ~/.indi/ParkData.xml) that contains parking status and parking...
Definition: indidome.cpp:1644
void SetParkDataType(DomeParkData type)
setParkDataType Sets the type of parking data stored in the park data file and presented to the user.
Definition: indidome.cpp:1587
DomeState getDomeState() const
Definition: indidome.h:285
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
double max(void)
double min(void)
ISState
Switch state.
Definition: indiapi.h:150
@ ISS_OFF
Definition: indiapi.h:151
@ ISS_ON
Definition: indiapi.h:152
@ IP_RW
Definition: indiapi.h:186
IPState
Property state.
Definition: indiapi.h:160
@ IPS_BUSY
Definition: indiapi.h:163
@ IPS_ALERT
Definition: indiapi.h:164
@ IPS_IDLE
Definition: indiapi.h:161
@ IPS_OK
Definition: indiapi.h:162
@ ISR_1OFMANY
Definition: indiapi.h:173
@ ISR_ATMOST1
Definition: indiapi.h:174
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
Definition: indicom.c:424
int tty_read(int fd, char *buf, int nbytes, int timeout, int *nbytes_read)
read buffer from terminal
Definition: indicom.c:482
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
Definition: indicom.c:1167
Implementations for common driver routines.
@ TTY_OK
Definition: indicom.h:150
int IUFindOnSwitchIndex(const ISwitchVectorProperty *svp)
Returns the index of first ON switch it finds in the vector switch property.
Definition: indidevapi.c:128
void IUResetSwitch(ISwitchVectorProperty *svp)
Reset all switches in a switch vector property to OFF.
Definition: indidevapi.c:148
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: indidevapi.c:158
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: indidevapi.c:235
int IUUpdateSwitch(ISwitchVectorProperty *svp, ISState *states, char *names[], int n)
Update all switches in a switch vector property.
Definition: indidriver.c:1308
void IDSetNumber(const INumberVectorProperty *nvp, const char *fmt,...)
Definition: indidriver.c:1211
void IDSetSwitch(const ISwitchVectorProperty *svp, const char *fmt,...)
Definition: indidriver.c:1231
#define LOGF_INFO(fmt,...)
Definition: indilogger.h:82
#define LOG_DEBUG(txt)
Definition: indilogger.h:75
#define LOG_WARN(txt)
Definition: indilogger.h:73
#define LOGF_DEBUG(fmt,...)
Definition: indilogger.h:83
#define LOG_ERROR(txt)
Shorter logging macros. In order to use these macros, the function (or method) "getDeviceName()" must...
Definition: indilogger.h:72
#define LOGF_ERROR(fmt,...)
Definition: indilogger.h:80
#define LOG_INFO(txt)
Definition: indilogger.h:74
#define DEBUGF(priority, msg,...)
Definition: indilogger.h:57
#define MAXRBUF
Definition: indiserver.cpp:102
__u8 cmd[4]
Definition: pwc-ioctl.h:2
char name[MAXINDINAME]
Definition: indiapi.h:371