API
dssShutter.hpp
Go to the documentation of this file.
1 /** \file dssShutter.hpp
2  * \brief Uniblitz DSS shutter interface
3  *
4  * \author Jared R. Males (jaredmales@gmail.com)
5  *
6  * \ingroup app_files
7  */
8 
9 #ifndef dssShutter_hpp
10 #define dssShutter_hpp
11 
12 
13 namespace MagAOX
14 {
15 namespace app
16 {
17 namespace dev
18 {
19 
20 /// MagAO-X Uniblitz DSS Shutter interface
21 /** This is actually an interface to the digital I/O system, which controls the shutter.
22  *
23  * The derived class `derivedT` must be a MagAOXApp<true>, and should declare this class a friend like so:
24  \code
25  friend class dev::dssShutter<derivedT>;
26  \endcode
27  *
28  *
29  * Calls to this class's `setupConfig`, `loadConfig`, `appStartup`, `appLogic`, `appShutdown`
30  * `onPowerOff`, `whilePowerOff`, functions must be placed in the derived class's functions of the same name.
31  *
32  *
33  * \ingroup appdev
34  */
35 template<class derivedT>
37 {
38 protected:
39 
40  /** \name Configurable Parameters
41  * @{
42  */
43 
44  std::string m_powerDevice; ///< The device controlling this shutter's power
45  std::string m_powerChannel; ///< The channel controlling this shutter's power
46 
47  std::string m_dioDevice; ///< The device controlling this shutter's digital I/O.
48  std::string m_sensorChannel; ///< The channel reading this shutter's sensor
49  std::string m_triggerChannel; ///< The channel sending this shutter's trigger
50 
51  unsigned m_shutterWait {100}; ///< The time to pause between checks of the sensor state during open/shut [msec]. Default is 100.
52 
53  unsigned m_shutterTimeout {2000}; ///< Total time to wait for sensor to change state before timing out [msec]. Default is 2000.
54  ///@}
55 
56  int m_powerState {-1}; ///< The current power state, -1 is unknown, 0 is off, 1 is on.
57 
58  int m_sensorState {-1}; ///< The current sensor state, -1 is unknown, 0 is shut, 1 is open.
59 
60  int m_triggerState {-1}; ///< The current trigger state. -1 is unknown, 0 is low, 1 is high.
61 
62 public:
63 
64  /// Default c'tor
65  /**
66  * Sets derived().m_hasShutter to true.
67  */
69 
70  /// Setup the configuration system
71  /**
72  * This should be called in `derivedT::setupConfig` as
73  * \code
74  dssShutter<derivedT>::setupConfig(config);
75  \endcode
76  * with appropriate error checking.
77  */
78  void setupConfig(mx::app::appConfigurator & config /**< [out] the derived classes configurator*/);
79 
80  /// load the configuration system results
81  /**
82  * This should be called in `derivedT::loadConfig` as
83  * \code
84  dssShutter<derivedT>::loadConfig(config);
85  \endcode
86  * with appropriate error checking.
87  */
88  void loadConfig(mx::app::appConfigurator & config /**< [in] the derived classes configurator*/);
89 
90  /// Startup function
91  /**
92  * This should be called in `derivedT::appStartup` as
93  * \code
94  dssShutter<derivedT>::appStartup();
95  \endcode
96  * with appropriate error checking.
97  *
98  * \returns 0 on success
99  * \returns -1 on error, which is logged.
100  */
101  int appStartup();
102 
103  /// application logic
104  /** This should be called in `derivedT::appLogic` as
105  * \code
106  dssShutter<derivedT>::appLogic();
107  \endcode
108  * with appropriate error checking.
109  *
110  * \returns 0 on success
111  * \returns -1 on error, which is logged.
112  */
113  int appLogic();
114 
115  /// applogic shutdown
116  /** This should be called in `derivedT::appShutdown` as
117  * \code
118  dssShutter<derivedT>::appShutdown();
119  \endcode
120  * with appropriate error checking.
121  *
122  * \returns 0 on success
123  * \returns -1 on error, which is logged.
124  */
125  int appShutdown();
126 
127  /// Actions on power off
128  /** This should be called in `derivedT::appPowerOff` as
129  * \code
130  dssShutter<derivedT>::appPowerOff();
131  \endcode
132  * with appropriate error checking.
133  *
134  * \returns 0 on success
135  * \returns -1 on error, which is logged.
136  */
137  int onPowerOff();
138 
139  /// Actions while powered off
140  /** This should be called in `derivedT::whilePowerOff` as
141  * \code
142  dssShutter<derivedT>::whilePowerOff();
143  \endcode
144  * with appropriate error checking.
145  *
146  * \returns 0 on success
147  * \returns -1 on error, which is logged.
148  */
150 
151  /// Change shutter state
152  /** Sets m_doOpen or m_doShut and signals the appropriate thread.
153  * \returns 0 on success
154  * \returns -1 on error
155  */
156  int setShutterState( int sh /**< Desired shutter state. 0 for shut,1 for open*/);
157 
158  /// Open the shutter
159  /** Do not lock the mutex before calling this.
160  *
161  * \returns 0 on success
162  * \returns -1 on error
163  */
164  int open();
165 
166  /// Shut the shutter
167  /** Do not lock the mutex before calling this.
168  *
169  * \returns 0 on success
170  * \returns -1 on error
171  */
172  int shut();
173 
174 protected:
175 
176  /** \name Open/Shut Threads
177  *
178  * Separate threads are used since we need INDI updates while trying to open/shut.
179  * These threads sleep(1), unless interrupted by a signal. When signaled, they check
180  * for the m_doOpen or m_doShut flag, and if true the appropriate open() or shut()
181  * function is called. If not, they go back to sleep unless m_shutdown is true.
182  *
183  * @{
184  */
185 
186  bool m_doOpen {false}; ///< Flag telling the open thread that it should actually open the shutter, not just go back to sleep.
187 
188  bool m_openThreadInit {true}; ///< Initialization flag for the open thread.
189 
190  pid_t m_openThreadID {0}; ///< Open thread PID.
191 
192  pcf::IndiProperty m_openThreadProp; ///< The property to hold the open thread details.
193 
194  std::thread m_openThread; ///< The opening thread.
195 
196  /// Open thread starter function
197  static void openThreadStart( dssShutter * d /**< [in] pointer to this */);
198 
199  /// Open thread function
200  /** Runs until m_shutdown is true.
201  */
203 
204  bool m_doShut {false}; ///< Flag telling the shut thread that it should actually shut the shutter, not just go back to sleep.
205 
206  bool m_shutThreadInit {true}; ///< Initialization flag for the shut thread.
207 
208  pid_t m_shutThreadID {0}; ///< Shut thread PID.
209 
210  pcf::IndiProperty m_shutThreadProp; ///< The property to hold the shut thread details.
211 
212  std::thread m_shutThread; ///< The shutting thread
213 
214  /// Shut thread starter function.
215  static void shutThreadStart( dssShutter * d /**< [in] pointer to this */);
216 
217  /// Shut thread function
218  /** Runs until m_shutdown is true.
219  */
221 
222  ///@}
223 protected:
224  /** \name INDI
225  *
226  *@{
227  */
228 protected:
229  //declare our properties
230 
231  pcf::IndiProperty m_indiP_powerChannel; ///< Property used to monitor the shutter's power state
232  pcf::IndiProperty m_indiP_sensorChannel; ///< Property used to monitor the shutter's hall sensor
233  pcf::IndiProperty m_indiP_triggerChannel; ///< Property used to monitor and set the shutter's trigger
234 
235 public:
236 
237  /// The static callback function to be registered for shutter power channel changes
238  /**
239  * \returns 0 on success.
240  * \returns -1 on error.
241  */
242  static int st_setCallBack_powerChannel( void * app, ///< [in] a pointer to this, will be static_cast-ed to derivedT.
243  const pcf::IndiProperty &ipRecv ///< [in] the INDI property sent with the the new property request.
244  );
245 
246  /// The callback called by the static version, to actually process the new request.
247  /**
248  * \returns 0 on success.
249  * \returns -1 on error.
250  */
251  int setCallBack_powerChannel( const pcf::IndiProperty &ipRecv /**< [in] the INDI property sent with the the new property request.*/);
252 
253 
254  /// The static callback function to be registered for shutter sensor channel changes
255  /**
256  * \returns 0 on success.
257  * \returns -1 on error.
258  */
259  static int st_setCallBack_sensorChannel( void * app, ///< [in] a pointer to this, will be static_cast-ed to derivedT.
260  const pcf::IndiProperty &ipRecv ///< [in] the INDI property sent with the the new property request.
261  );
262 
263  /// The callback called by the static version, to actually process the new request.
264  /**
265  * \returns 0 on success.
266  * \returns -1 on error.
267  */
268  int setCallBack_sensorChannel( const pcf::IndiProperty &ipRecv /**< [in] the INDI property sent with the the new property request.*/);
269 
270  /// The static callback function to be registered for shutter trigger channel changes
271  /**
272  * \returns 0 on success.
273  * \returns -1 on error.
274  */
275  static int st_setCallBack_triggerChannel( void * app, ///< [in] a pointer to this, will be static_cast-ed to derivedT.
276  const pcf::IndiProperty &ipRecv ///< [in] the INDI property sent with the the new property request.
277  );
278 
279  /// The callback called by the static version, to actually process the new request.
280  /**
281  * \returns 0 on success.
282  * \returns -1 on error.
283  */
284  int setCallBack_triggerChannel( const pcf::IndiProperty &ipRecv /**< [in] the INDI property sent with the the new property request.*/);
285 
286 
287  ///@}
288 
289 private:
290 
291  /// Access the derived class.
292  derivedT & derived()
293  {
294  return *static_cast<derivedT *>(this);
295  }
296 };
297 
298 template<class derivedT>
300 {
301 }
302 
303 template<class derivedT>
304 void dssShutter<derivedT>::setupConfig(mx::app::appConfigurator & config)
305 {
306  config.add("shutter.powerDevice", "", "shutter.powerDevice", argType::Required, "shutter", "powerDevice", false, "string", "The device controlling this shutter's power");
307  config.add("shutter.powerChannel", "", "shutter.powerChannel", argType::Required, "shutter", "powerChannel", false, "string", "The channel controlling this shutter's power");
308 
309  config.add("shutter.dioDevice", "", "shutter.dioDevice", argType::Required, "shutter", "dioDevice", false, "string", "The device controlling this shutter's digital I/O.");
310 
311  config.add("shutter.sensorChannel", "", "shutter.sensorChannel", argType::Required, "shutter", "sensorChannel", false, "string", "The channel reading this shutter's sensor.");
312 
313  config.add("shutter.triggerChannel", "", "shutter.triggerChannel", argType::Required, "shutter", "triggerChannel", false, "string", "The channel sending this shutter's trigger.");
314 
315  config.add("shutter.wait", "", "shutter.wait", argType::Required, "shutter", "wait", false, "int", "The time to pause between checks of the sensor state during open/shut [msec]. Default is 100.");
316 
317  config.add("shutter.timeout", "", "shutter.timeout", argType::Required, "shutter", "timeout", false, "int", "Total time to wait for sensor to change state before timing out [msec]. Default is 2000.");
318 
319 }
320 
321 template<class derivedT>
322 void dssShutter<derivedT>::loadConfig(mx::app::appConfigurator & config)
323 {
324  config(m_powerDevice, "shutter.powerDevice");
325  config(m_powerChannel, "shutter.powerChannel");
326  config(m_dioDevice, "shutter.dioDevice");
327  config(m_sensorChannel, "shutter.sensorChannel");
328  config(m_triggerChannel, "shutter.triggerChannel");
329  config(m_shutterWait, "shutter.wait");
330  config(m_shutterTimeout, "shutter.timeout");
331 }
332 
333 
334 template<class derivedT>
336 {
337  //Register the powerChannel property for updates
338  if( derived().registerIndiPropertySet( m_indiP_powerChannel, m_powerDevice, m_powerChannel, st_setCallBack_powerChannel) < 0)
339  {
340  #ifndef DSSSHUTTER_TEST_NOLOG
341  derivedT::template log<software_error>({__FILE__,__LINE__});
342  #endif
343  return -1;
344  }
345 
346  //Register the sensorChannel property for updates
347  if( derived().registerIndiPropertySet( m_indiP_sensorChannel, m_dioDevice, m_sensorChannel, st_setCallBack_sensorChannel) < 0)
348  {
349  #ifndef DSSSHUTTER_TEST_NOLOG
350  derivedT::template log<software_error>({__FILE__,__LINE__});
351  #endif
352  return -1;
353  }
354 
355  //Register the triggerChannel property for updates
356  if( derived().registerIndiPropertySet( m_indiP_triggerChannel, m_dioDevice, m_triggerChannel, st_setCallBack_triggerChannel) < 0)
357  {
358  #ifndef DSSSHUTTER_TEST_NOLOG
359  derivedT::template log<software_error>({__FILE__,__LINE__});
360  #endif
361  return -1;
362  }
363 
364 
365 
366  if(derived().threadStart( m_openThread, m_openThreadInit, m_openThreadID, m_openThreadProp, 0, "", "open", this, openThreadStart) < 0)
367  {
368  derivedT::template log<software_error>({__FILE__, __LINE__});
369  return -1;
370  }
371 
372  if(derived().threadStart( m_shutThread, m_shutThreadInit, m_shutThreadID, m_shutThreadProp, 0, "", "shut", this, shutThreadStart) < 0)
373  {
374  derivedT::template log<software_error>({__FILE__, __LINE__});
375  return -1;
376  }
377 
378  //Install empty signal handler for USR1, which is used to interrupt sleeps in the open/shut threads.
379  struct sigaction act;
380  sigset_t set;
381 
382  act.sa_sigaction = &sigUsr1Handler;
383  act.sa_flags = SA_SIGINFO;
384  sigemptyset(&set);
385  act.sa_mask = set;
386 
387  errno = 0;
388  if( sigaction(SIGUSR1, &act, 0) < 0 )
389  {
390  std::string logss = "Setting handler for SIGUSR1 failed. Errno says: ";
391  logss += strerror(errno);
392 
393  derivedT::template log<software_error>({__FILE__, __LINE__, errno, 0, logss});
394 
395  return -1;
396  }
397 
398  return 0;
399 
400 }
401 
402 template<class derivedT>
404 {
405  if(m_powerState !=0 && m_powerState != 1)
406  {
407  derived().m_shutterStatus = "UNKNOWN";
408  derived().m_shutterState = -1;
409  return 0;
410  }
411 
412  if(m_powerState == 0)
413  {
414  derived().m_shutterStatus = "POWEROFF";
415  derived().m_shutterState = -1;
416  return 0;
417  }
418 
419  derived().m_shutterStatus = "READY";
420 
421  if(m_sensorState == 0)
422  {
423  derived().m_shutterState = 0;
424  return 0;
425  }
426 
427  if(m_sensorState == 1)
428  {
429  derived().m_shutterState = 1;
430  return 0;
431  }
432 
433  return 0;
434 }
435 
436 template<class derivedT>
438 {
439  if(m_openThread.joinable())
440  {
441  pthread_kill(m_openThread.native_handle(), SIGUSR1);
442  }
443 
444  if(m_shutThread.joinable())
445  {
446  pthread_kill(m_shutThread.native_handle(), SIGUSR1);
447  }
448 
449  if(m_openThread.joinable())
450  {
451  try
452  {
453  m_openThread.join(); //this will throw if it was already joined
454  }
455  catch(...)
456  {
457  }
458  }
459 
460  if(m_shutThread.joinable())
461  {
462  try
463  {
464  m_shutThread.join(); //this will throw if it was already joined
465  }
466  catch(...)
467  {
468  }
469  }
470  return 0;
471 }
472 
473 template<class derivedT>
475 {
476  return appLogic(); //Power state of derived() does not say anything about power state of the shutter
477 }
478 
479 template<class derivedT>
481 {
482  return appLogic(); //Power state of derived() does not say anything about power state of the shutter
483 }
484 
485 template<class derivedT>
487 {
488  if( sh == 1 )
489  {
490  m_doOpen = true;
491 
492  pthread_kill(m_openThread.native_handle(), SIGUSR1);
493 
494  return 0;
495  }
496  else if( sh == 0)
497  {
498  m_doShut = true;
499 
500  pthread_kill(m_shutThread.native_handle(), SIGUSR1);
501 
502  return 0;
503  }
504  else
505  {
506  derivedT::template log<software_error>({ __FILE__, __LINE__,"invalid shutter request"});
507 
508  return -1;
509  }
510 }
511 
512 template<class derivedT>
514 {
515  if(m_powerState != 1) return 0;
516 
517  int startss = m_sensorState;
518 
519  derived().recordCamera(true);
520  if(startss) return 0; //already open
521 
522  //First try:
523  int startts = m_triggerState;
524 
525  derived().sendNewProperty (m_indiP_triggerChannel, "target", (int) !m_triggerState);
526 
527  double t0 = mx::sys::get_curr_time();
528  while( m_sensorState != 1 )
529  {
530  mx::sys::milliSleep( m_shutterWait );
531  if( (mx::sys::get_curr_time() - t0)*1000 > m_shutterTimeout) break;
532  }
533 
534  if(m_sensorState == 1)
535  {
536  derived().recordCamera(true);
537  derivedT::template log<text_log>("shutter open");
538  return 0;
539  }
540 
541  if( m_triggerState == startts )
542  {
543  return derivedT::template log<software_error,-1>({__FILE__, __LINE__, "shutter trigger did not change state"});
544  }
545 
546  //If here, shutter is not open, and trigger did flip, so it's a starting state issue.
547  //So we try again.
548 
549  derived().sendNewProperty (m_indiP_triggerChannel, "target", (int) !m_triggerState);
550 
551  t0 = mx::sys::get_curr_time();
552  while( m_sensorState != 1 )
553  {
554  mx::sys::milliSleep( m_shutterWait );
555  if( (mx::sys::get_curr_time() - t0)*1000 > m_shutterTimeout) break;
556  }
557 
558  ///\todo need shutter log types
559  if(m_sensorState == 1)
560  {
561  derived().recordCamera(true);
562  derivedT::template log<text_log>("shutter open");
563  return 0;
564  }
565 
566  if( m_triggerState == !startts )
567  {
568  return derivedT::template log<software_error,-1>({__FILE__, __LINE__, "shutter trigger did not change state"});
569  }
570 
571  return derivedT::template log<software_error,-1>({__FILE__, __LINE__, "shutter failed to open"});
572 }
573 
574 template<class derivedT>
576 {
577  if(m_powerState != 1) return 0;
578 
579  int startss = m_sensorState;
580 
581  if(!startss) return 0; //already shut
582 
583  //First try:
584  int startts = m_triggerState;
585 
586  derived().sendNewProperty (m_indiP_triggerChannel, "target", (int) !m_triggerState);
587 
588  double t0 = mx::sys::get_curr_time();
589  while( m_sensorState != 0 )
590  {
591  mx::sys::milliSleep( m_shutterWait );
592  if( (mx::sys::get_curr_time() - t0)*1000 > m_shutterTimeout) break;
593  }
594 
595  ///\todo need shutter log types
596  if(m_sensorState == 0)
597  {
598  derived().recordCamera(true);
599  derivedT::template log<text_log>("shutter shut");
600  return 0;
601  }
602 
603  if( m_triggerState == startts )
604  {
605  return derivedT::template log<software_error,-1>({__FILE__, __LINE__, "shutter trigger did not change state"});
606  }
607 
608 
609  //If here, shutter is not open, and trigger did flip, so it's a starting state issue.
610  //So we try again.
611 
612  derived().sendNewProperty (m_indiP_triggerChannel, "target", (int) !m_triggerState);
613 
614  t0 = mx::sys::get_curr_time();
615  while( m_sensorState != 0 )
616  {
617  mx::sys::milliSleep( m_shutterWait );
618  if( (mx::sys::get_curr_time() - t0)*1000 > m_shutterTimeout) break;
619  }
620 
621  ///\todo need shutter log types
622  if(m_sensorState == 0)
623  {
624  derived().recordCamera(true);
625  derivedT::template log<text_log>("shutter shut");
626  return 0;
627  }
628 
629  if( m_triggerState == !startts )
630  {
631  return derivedT::template log<software_error,-1>({__FILE__, __LINE__, "shutter trigger did not change state"});
632  }
633 
634  return derivedT::template log<software_error,-1>({__FILE__, __LINE__, "shutter failed to shut"});
635 
636 
637 }
638 
639 template<class derivedT>
641 {
642  d->openThreadExec();
643 }
644 
645 template<class derivedT>
647 {
648  m_openThreadID = syscall(SYS_gettid);
649 
650  while( m_openThreadInit == true && derived().shutdown() == 0)
651  {
652  sleep(1);
653  }
654 
655  while(derived().shutdown() == 0)
656  {
657  if( m_doOpen )
658  {
659  if(open() < 0)
660  {
661  derivedT::template log<software_error>({__FILE__,__LINE__});
662  }
663  m_doOpen = false;
664  }
665 
666  sleep(1);
667 
668  }
669 
670  return;
671 }
672 
673 template<class derivedT>
675 {
676  d->shutThreadExec();
677 }
678 
679 template<class derivedT>
681 {
682  m_shutThreadID = syscall(SYS_gettid);
683 
684  while( m_shutThreadInit == true && derived().shutdown() == 0)
685  {
686  sleep(1);
687  }
688 
689  while(derived().shutdown() == 0)
690  {
691  if( m_doShut )
692  {
693  if(shut() < 0)
694  {
695  derivedT::template log<software_error>({__FILE__,__LINE__});
696  }
697  m_doShut = false;
698  }
699 
700  sleep(1);
701  }
702 
703  return;
704 }
705 
706 template<class derivedT>
708  const pcf::IndiProperty &ipRecv
709  )
710 {
711  return static_cast<derivedT *>(app)->setCallBack_powerChannel(ipRecv);
712 }
713 
714 template<class derivedT>
716 {
717  std::string ps;
718 
719  if(ipRecv.getName() != m_indiP_powerChannel.getName()) return 0;
720 
721  m_indiP_powerChannel = ipRecv;
722 
723  if(!ipRecv.find("state")) return 0;
724 
725  ps = ipRecv["state"].get<std::string>();
726 
727  if(ps == "On")
728  {
729  m_powerState = 1;
730  }
731  else if (ps == "Off")
732  {
733  m_powerState = 0;
734  }
735  else
736  {
737  m_powerState = -1;
738  }
739 
740  return 0;
741 }
742 
743 template<class derivedT>
745  const pcf::IndiProperty &ipRecv
746  )
747 {
748  return static_cast<derivedT *>(app)->setCallBack_sensorChannel(ipRecv);
749 }
750 
751 template<class derivedT>
753 {
754 
755  if(ipRecv.getName() != m_indiP_sensorChannel.getName()) return 0;
756 
757  m_indiP_sensorChannel = ipRecv;
758 
759  if(!ipRecv.find("current")) return 0;
760 
761  int ss = ipRecv["current"].get<int>();
762 
763  if(ss == 1)
764  {
765  m_sensorState = 1;
766  }
767  else if (ss == 0)
768  {
769  m_sensorState = 0;
770  }
771  else
772  {
773  m_sensorState = -1;
774  }
775 
776  return 0;
777 }
778 
779 
780 template<class derivedT>
782  const pcf::IndiProperty &ipRecv
783  )
784 {
785  return static_cast<derivedT *>(app)->setCallBack_triggerChannel(ipRecv);
786 }
787 
788 template<class derivedT>
790 {
791  if(ipRecv.getName() != m_indiP_triggerChannel.getName()) return 0;
792 
793  m_indiP_triggerChannel = ipRecv;
794 
795  if(!ipRecv.find("current")) return 0;
796 
797  int ts = ipRecv["current"].get<int>();
798 
799  if(ts == 1)
800  {
801  m_triggerState = 1;
802  }
803  else if (ts == 0)
804  {
805  m_triggerState = 0;
806  }
807  else
808  {
809  m_triggerState = -1;
810  }
811 
812  return 0;
813 }
814 
815 
816 
817 
818 
819 } //namespace dev
820 } //namespace app
821 } //namespace MagAOX
822 
823 #endif //dssShutter_hpp
MagAO-X Uniblitz DSS Shutter interface.
Definition: dssShutter.hpp:37
static int st_setCallBack_triggerChannel(void *app, const pcf::IndiProperty &ipRecv)
The static callback function to be registered for shutter trigger channel changes.
Definition: dssShutter.hpp:781
int m_sensorState
The current sensor state, -1 is unknown, 0 is shut, 1 is open.
Definition: dssShutter.hpp:58
int appStartup()
Startup function.
Definition: dssShutter.hpp:335
std::string m_triggerChannel
The channel sending this shutter's trigger.
Definition: dssShutter.hpp:49
bool m_openThreadInit
Initialization flag for the open thread.
Definition: dssShutter.hpp:188
pcf::IndiProperty m_indiP_powerChannel
Property used to monitor the shutter's power state.
Definition: dssShutter.hpp:231
int whilePowerOff()
Actions while powered off.
Definition: dssShutter.hpp:480
pcf::IndiProperty m_indiP_triggerChannel
Property used to monitor and set the shutter's trigger.
Definition: dssShutter.hpp:233
void loadConfig(mx::app::appConfigurator &config)
load the configuration system results
Definition: dssShutter.hpp:322
std::string m_powerChannel
The channel controlling this shutter's power.
Definition: dssShutter.hpp:45
std::thread m_shutThread
The shutting thread.
Definition: dssShutter.hpp:212
int setCallBack_sensorChannel(const pcf::IndiProperty &ipRecv)
The callback called by the static version, to actually process the new request.
Definition: dssShutter.hpp:752
int shut()
Shut the shutter.
Definition: dssShutter.hpp:575
int m_triggerState
The current trigger state. -1 is unknown, 0 is low, 1 is high.
Definition: dssShutter.hpp:60
int setCallBack_powerChannel(const pcf::IndiProperty &ipRecv)
The callback called by the static version, to actually process the new request.
Definition: dssShutter.hpp:715
std::string m_dioDevice
The device controlling this shutter's digital I/O.
Definition: dssShutter.hpp:47
derivedT & derived()
Access the derived class.
Definition: dssShutter.hpp:292
int onPowerOff()
Actions on power off.
Definition: dssShutter.hpp:474
pcf::IndiProperty m_indiP_sensorChannel
Property used to monitor the shutter's hall sensor.
Definition: dssShutter.hpp:232
pid_t m_openThreadID
Open thread PID.
Definition: dssShutter.hpp:190
int appLogic()
application logic
Definition: dssShutter.hpp:403
std::string m_sensorChannel
The channel reading this shutter's sensor.
Definition: dssShutter.hpp:48
static void shutThreadStart(dssShutter *d)
Shut thread starter function.
Definition: dssShutter.hpp:674
void openThreadExec()
Open thread function.
Definition: dssShutter.hpp:646
int setCallBack_triggerChannel(const pcf::IndiProperty &ipRecv)
The callback called by the static version, to actually process the new request.
Definition: dssShutter.hpp:789
int appShutdown()
applogic shutdown
Definition: dssShutter.hpp:437
bool m_doShut
Flag telling the shut thread that it should actually shut the shutter, not just go back to sleep.
Definition: dssShutter.hpp:204
static void openThreadStart(dssShutter *d)
Open thread starter function.
Definition: dssShutter.hpp:640
pcf::IndiProperty m_openThreadProp
The property to hold the open thread details.
Definition: dssShutter.hpp:192
unsigned m_shutterWait
The time to pause between checks of the sensor state during open/shut [msec]. Default is 100.
Definition: dssShutter.hpp:51
bool m_shutThreadInit
Initialization flag for the shut thread.
Definition: dssShutter.hpp:206
int m_powerState
The current power state, -1 is unknown, 0 is off, 1 is on.
Definition: dssShutter.hpp:56
bool m_doOpen
Flag telling the open thread that it should actually open the shutter, not just go back to sleep.
Definition: dssShutter.hpp:186
int open()
Open the shutter.
Definition: dssShutter.hpp:513
std::string m_powerDevice
The device controlling this shutter's power.
Definition: dssShutter.hpp:44
unsigned m_shutterTimeout
Total time to wait for sensor to change state before timing out [msec]. Default is 2000.
Definition: dssShutter.hpp:53
pcf::IndiProperty m_shutThreadProp
The property to hold the shut thread details.
Definition: dssShutter.hpp:210
void shutThreadExec()
Shut thread function.
Definition: dssShutter.hpp:680
static int st_setCallBack_sensorChannel(void *app, const pcf::IndiProperty &ipRecv)
The static callback function to be registered for shutter sensor channel changes.
Definition: dssShutter.hpp:744
void setupConfig(mx::app::appConfigurator &config)
Setup the configuration system.
Definition: dssShutter.hpp:304
pid_t m_shutThreadID
Shut thread PID.
Definition: dssShutter.hpp:208
std::thread m_openThread
The opening thread.
Definition: dssShutter.hpp:194
static int st_setCallBack_powerChannel(void *app, const pcf::IndiProperty &ipRecv)
The static callback function to be registered for shutter power channel changes.
Definition: dssShutter.hpp:707
int setShutterState(int sh)
Change shutter state.
Definition: dssShutter.hpp:486
const pcf::IndiProperty & ipRecv
void sigUsr1Handler(int signum, siginfo_t *siginf, void *ucont)
Empty signal handler. SIGUSR1 is used to interrupt sleep in various threads.
Definition: MagAOXApp.cpp:42
Definition: dm.hpp:24