API
xt1121DCDU.hpp
Go to the documentation of this file.
1 /** \file xt1121DCDU.hpp
2  * \brief The MagAO-X xt1121-based D.C. Distribution Unit controller.
3  *
4  * \author Jared R. Males (jaredmales@gmail.com)
5  *
6  * \ingroup xt1121DCDU_files
7  */
8 
9 #ifndef xt1121DCDU_hpp
10 #define xt1121DCDU_hpp
11 
12 
13 #include "../../libMagAOX/libMagAOX.hpp" //Note this is included on command line to trigger pch
14 #include "../../magaox_git_version.h"
15 
16 /** \defgroup xt1121DCDU xt1121-based DC distribution unit
17  * \brief Control of MagAO-X D.C. power distrubition via the xt1121 DIO module.
18  *
19  * <a href="../handbook/operating/software/apps/xt1121DCDU.html">Application Documentation</a>
20  *
21  * \ingroup apps
22  *
23  */
24 
25 /** \defgroup xt1121DCDU_files xt1121 DCDU Files
26  * \ingroup xt1121DCDU
27  */
28 
29 namespace MagAOX
30 {
31 namespace app
32 {
33 
34 /// MagAO-X application to control D.C. distribution via an xt1121 DIO unit.
35 /** The device outlets are organized into channels. See \ref dev::outletController for details of configuring the channels.
36  *
37  *
38  * \ingroup xt1121DCDU
39  */
40 class xt1121DCDU : public MagAOXApp<>, public dev::outletController<xt1121DCDU>
41 {
42 
43 protected:
44 
45  std::string m_deviceName; ///< The device address
46 
47  std::vector<int> m_channelNumbers; ///< Vector of outlet numbers, used to construct the channel names to monitor as outlets 0-7.
48 
49  int m_outletStateDelay {5000}; ///< The maximum time to wait for an outlet to change state [msec].
50 
51 
52  pcf::IndiProperty ip_ch0;
53  pcf::IndiProperty ip_ch1;
54  pcf::IndiProperty ip_ch2;
55  pcf::IndiProperty ip_ch3;
56  pcf::IndiProperty ip_ch4;
57  pcf::IndiProperty ip_ch5;
58  pcf::IndiProperty ip_ch6;
59  pcf::IndiProperty ip_ch7;
60 
61 
62 
63 public:
64 
65  /// Default c'tor.
66  xt1121DCDU();
67 
68  /// D'tor, declared and defined for noexcept.
69  ~xt1121DCDU() noexcept
70  {}
71 
72  /// Setup the configuration system (called by MagAOXApp::setup())
73  virtual void setupConfig();
74 
75  /// load the configuration system results (called by MagAOXApp::setup())
76  virtual void loadConfig();
77 
78  /// Startup functions
79  /** Setsup the INDI vars.
80  * Checks if the device was found during loadConfig.
81  */
82  virtual int appStartup();
83 
84  /// Implementation of the FSM for the xt1121 DCDU.
85  virtual int appLogic();
86 
87  /// Do any needed shutdown tasks. Currently nothing in this app.
88  virtual int appShutdown();
89 
90  /// Update a single outlet state
91  /**
92  *
93  * \returns 0 on success
94  * \returns -1 on error
95  */
96  virtual int updateOutletState( int outletNum /**< [in] the outlet number to update */);
97 
98  /// Turn on an outlet.
99  /**
100  * \returns 0 on success
101  * \returns -1 on error
102  */
103  virtual int turnOutletOn( int outletNum /**< [in] the outlet number to turn on */);
104 
105  /// Turn off an outlet.
106  /**
107  * \returns 0 on success
108  * \returns -1 on error
109  */
110  virtual int turnOutletOff( int outletNum /**< [in] the outlet number to turn off */);
111 
112 protected:
113 
114  ///Helper function to get the xt1121Ctrl channel name for the given channel number.
115  /**
116  * \returns chXX where XX is 00 to 15, set by chno.
117  * \returns empty string if chno is not valid.
118  */
119  std::string xtChannelName( int chno);
120 
121  ///Helper function to get a pointer to the right INDI property for an outlet number.
122  /**
123  * \returns a pointer to one of the INDI properties if outletNum is valid
124  * \returns nullptr if outletNum is not valid.
125  */
126  pcf::IndiProperty * xtChannelProperty( int outletNum /**< [in] the outlet number */);
127 
136 };
137 
138 xt1121DCDU::xt1121DCDU() : MagAOXApp(MAGAOX_CURRENT_SHA1, MAGAOX_REPO_MODIFIED)
139 {
140  m_firstOne = true;
141  m_powerMgtEnabled = true;
142 
144 
145  return;
146 }
147 
149 {
150  config.add("device.name", "", "device.name", argType::Required, "device", "name", false, "string", "The device INDI name.");
151 
152  config.add("device.channelNumbers", "", "device.channelNumbers", argType::Required, "device", "channelNumbers", false, "vector<int>", "The channel numbers to use for the outlets, in order.");
153 
154 
156 
157 }
158 
159 
161 {
162  config(m_deviceName, "device.name");
163 
164  m_channelNumbers = {0,1,2,3,4,5,6,7};
165  config(m_channelNumbers, "device.channelNumbers");
166 
168 
169 }
170 
171 
172 
174 {
175  if(m_channelNumbers.size() != 8)
176  {
177  return log<text_log,-1>("Something other than 8 channel numbers specified.", logPrio::LOG_CRITICAL);
178  }
179 
188 
190  {
191  return log<text_log,-1>("Error setting up INDI for outlet control.", logPrio::LOG_CRITICAL);
192  }
193 
195 
196  return 0;
197 }
198 
200 {
201  if( state() == stateCodes::POWERON )
202  {
204  }
205 
206 
207  if(state() == stateCodes::READY)
208  {
209  std::unique_lock<std::mutex> lock(m_indiMutex, std::try_to_lock);
210 
211  int rv = updateOutletStates();
212 
213  if(rv < 0) return log<software_error,-1>({__FILE__, __LINE__});
214 
216 
217  return 0;
218  }
219 
221  log<text_log>("appLogic fell through", logPrio::LOG_CRITICAL);
222  return -1;
223 
224 }
225 
227 {
228  //don't bother
229  return 0;
230 }
231 
232 int xt1121DCDU::updateOutletState( int outletNum )
233 {
234  pcf::IndiProperty * ip = xtChannelProperty(outletNum);
235 
236  if(ip == nullptr)
237  {
238  return log<software_error, -1>({__FILE__, __LINE__, "bad outlet number"});
239  }
240 
241  int os = OUTLET_STATE_UNKNOWN;
242  if(ip->find("current"))
243  {
244  if((*ip)["current"].get<int>() == 0) os = OUTLET_STATE_OFF;
245  else if((*ip)["current"].get<int>() == 1) os = OUTLET_STATE_ON;
246  }
247 
248  m_outletStates[outletNum] = os;
249 
250  return 0;
251 
252 }
253 
254 int xt1121DCDU::turnOutletOn( int outletNum )
255 {
256  std::lock_guard<std::mutex> guard(m_indiMutex); //Lock the mutex before doing anything
257 
258  pcf::IndiProperty * ip = xtChannelProperty(outletNum);
259 
260  if(ip == nullptr)
261  {
262  return log<software_error, -1>({__FILE__, __LINE__, "bad outlet number"});
263  }
264 
265  return sendNewProperty(*ip, "target", 1);
266 
267 }
268 
269 int xt1121DCDU::turnOutletOff( int outletNum )
270 {
271  std::lock_guard<std::mutex> guard(m_indiMutex); //Lock the mutex before doing anything
272 
273  pcf::IndiProperty * ip = xtChannelProperty(outletNum);
274 
275  if(ip == nullptr)
276  {
277  return log<software_error, -1>({__FILE__, __LINE__, "bad outlet number"});
278  }
279 
280  return sendNewProperty(*ip, "target", 0);
281 
282 }
283 
284 std::string xt1121DCDU::xtChannelName( int chno)
285 {
286  switch(chno)
287  {
288  case 0:
289  return "ch00";
290  case 1:
291  return "ch01";
292  case 2:
293  return "ch02";
294  case 3:
295  return "ch03";
296  case 4:
297  return "ch04";
298  case 5:
299  return "ch05";
300  case 6:
301  return "ch06";
302  case 7:
303  return "ch07";
304  case 8:
305  return "ch08";
306  case 9:
307  return "ch09";
308  case 10:
309  return "ch10";
310  case 11:
311  return "ch11";
312  case 12:
313  return "ch12";
314  case 13:
315  return "ch13";
316  case 14:
317  return "ch14";
318  case 15:
319  return "ch15";
320  case 16:
321  return "ch16";
322  default:
323  return "";
324  }
325 }
326 pcf::IndiProperty * xt1121DCDU::xtChannelProperty( int outletNum )
327 {
328  switch(outletNum)
329  {
330  case 0:
331  return &ip_ch0;
332  case 1:
333  return &ip_ch1;
334  case 2:
335  return &ip_ch2;
336  case 3:
337  return &ip_ch3;
338  case 4:
339  return &ip_ch4;
340  case 5:
341  return &ip_ch5;
342  case 6:
343  return &ip_ch6;
344  case 7:
345  return &ip_ch7;
346  default:
347  return nullptr;
348  }
349 }
350 
351 INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch0)(const pcf::IndiProperty &ipRecv)
352 {
353  ip_ch0 = ipRecv;
354 
355  return updateOutletState(0);
356 }
357 
358 INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch1)(const pcf::IndiProperty &ipRecv)
359 {
360  ip_ch1 = ipRecv;
361 
362  return updateOutletState(1);
363 }
364 
365 INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch2)(const pcf::IndiProperty &ipRecv)
366 {
367  ip_ch2 = ipRecv;
368 
369  return updateOutletState(2);
370 }
371 
372 INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch3)(const pcf::IndiProperty &ipRecv)
373 {
374  ip_ch3 = ipRecv;
375 
376  return updateOutletState(3);
377 }
378 
379 INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch4)(const pcf::IndiProperty &ipRecv)
380 {
381  ip_ch4 = ipRecv;
382 
383  return updateOutletState(4);
384 }
385 
386 INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch5)(const pcf::IndiProperty &ipRecv)
387 {
388  ip_ch5 = ipRecv;
389 
390  return updateOutletState(5);
391 }
392 
393 INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch6)(const pcf::IndiProperty &ipRecv)
394 {
395  ip_ch6 = ipRecv;
396 
397  return updateOutletState(6);
398 }
399 
400 INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch7)(const pcf::IndiProperty &ipRecv)
401 {
402  ip_ch7 = ipRecv;
403 
404  return updateOutletState(7);
405 }
406 
407 } //namespace app
408 } //namespace MagAOX
409 
410 #endif //xt1121DCDU_hpp
The base-class for MagAO-X applications.
Definition: MagAOXApp.hpp:73
stateCodes::stateCodeT state()
Get the current state code.
Definition: MagAOXApp.hpp:2297
static int log(const typename logT::messageT &msg, logPrioT level=logPrio::LOG_DEFAULT)
Make a log entry.
Definition: MagAOXApp.hpp:1804
std::mutex m_indiMutex
Mutex for locking INDI communications.
Definition: MagAOXApp.hpp:545
int sendNewProperty(const pcf::IndiProperty &ipSend, const std::string &el, const T &newVal)
Send a newProperty command to another device (using the INDI Client interface)
Definition: MagAOXApp.hpp:3268
MagAO-X application to control D.C. distribution via an xt1121 DIO unit.
Definition: xt1121DCDU.hpp:41
virtual int turnOutletOff(int outletNum)
Turn off an outlet.
Definition: xt1121DCDU.hpp:269
virtual int updateOutletState(int outletNum)
Update a single outlet state.
Definition: xt1121DCDU.hpp:232
pcf::IndiProperty * xtChannelProperty(int outletNum)
Helper function to get a pointer to the right INDI property for an outlet number.
Definition: xt1121DCDU.hpp:326
virtual int appStartup()
Startup functions.
Definition: xt1121DCDU.hpp:173
INDI_SETCALLBACK_DECL(xt1121DCDU, ip_ch5)
pcf::IndiProperty ip_ch2
Definition: xt1121DCDU.hpp:54
INDI_SETCALLBACK_DECL(xt1121DCDU, ip_ch1)
virtual void loadConfig()
load the configuration system results (called by MagAOXApp::setup())
Definition: xt1121DCDU.hpp:160
virtual void setupConfig()
Setup the configuration system (called by MagAOXApp::setup())
Definition: xt1121DCDU.hpp:148
INDI_SETCALLBACK_DECL(xt1121DCDU, ip_ch3)
pcf::IndiProperty ip_ch6
Definition: xt1121DCDU.hpp:58
pcf::IndiProperty ip_ch3
Definition: xt1121DCDU.hpp:55
virtual int appShutdown()
Do any needed shutdown tasks. Currently nothing in this app.
Definition: xt1121DCDU.hpp:226
virtual int appLogic()
Implementation of the FSM for the xt1121 DCDU.
Definition: xt1121DCDU.hpp:199
std::string xtChannelName(int chno)
Helper function to get the xt1121Ctrl channel name for the given channel number.
Definition: xt1121DCDU.hpp:284
std::vector< int > m_channelNumbers
Vector of outlet numbers, used to construct the channel names to monitor as outlets 0-7.
Definition: xt1121DCDU.hpp:47
int m_outletStateDelay
The maximum time to wait for an outlet to change state [msec].
Definition: xt1121DCDU.hpp:49
INDI_SETCALLBACK_DECL(xt1121DCDU, ip_ch2)
~xt1121DCDU() noexcept
D'tor, declared and defined for noexcept.
Definition: xt1121DCDU.hpp:69
INDI_SETCALLBACK_DECL(xt1121DCDU, ip_ch0)
pcf::IndiProperty ip_ch4
Definition: xt1121DCDU.hpp:56
INDI_SETCALLBACK_DECL(xt1121DCDU, ip_ch6)
pcf::IndiProperty ip_ch1
Definition: xt1121DCDU.hpp:53
pcf::IndiProperty ip_ch5
Definition: xt1121DCDU.hpp:57
std::string m_deviceName
The device address.
Definition: xt1121DCDU.hpp:45
xt1121DCDU()
Default c'tor.
Definition: xt1121DCDU.hpp:138
virtual int turnOutletOn(int outletNum)
Turn on an outlet.
Definition: xt1121DCDU.hpp:254
INDI_SETCALLBACK_DECL(xt1121DCDU, ip_ch7)
pcf::IndiProperty ip_ch7
Definition: xt1121DCDU.hpp:59
INDI_SETCALLBACK_DECL(xt1121DCDU, ip_ch4)
pcf::IndiProperty ip_ch0
Definition: xt1121DCDU.hpp:52
#define REG_INDI_SETPROP(prop, devName, propName)
Register a SET INDI property with the class, using the standard callback name.
Definition: indiMacros.hpp:282
@ FAILURE
The application has failed, should be used when m_shutdown is set for an error.
Definition: stateCodes.hpp:42
@ READY
The device is ready for operation, but is not operating.
Definition: stateCodes.hpp:56
@ NOTCONNECTED
The application is not connected to the device or service.
Definition: stateCodes.hpp:49
@ POWERON
The device power is on.
Definition: stateCodes.hpp:48
const pcf::IndiProperty & ipRecv
Definition: MagAOXApp.hpp:3434
INDI_SETCALLBACK_DEFN(adcTracker, m_indiP_teldata)(const pcf
Definition: adcTracker.hpp:461
std::unique_lock< std::mutex > lock(m_indiMutex)
Definition: dm.hpp:24
constexpr static logPrioT LOG_CRITICAL
The process can not continue and will shut down (fatal)
Definition: logPriority.hpp:37
#define OUTLET_STATE_OFF
#define OUTLET_STATE_UNKNOWN
#define OUTLET_STATE_ON
A generic outlet controller.
int updateINDI()
Update the INDI properties for this device controller.
bool m_firstOne
Flag is true if the first outlet is numbered 1, otherwise assumes starting at 0.
int loadConfig(mx::app::appConfigurator &config)
Load the [channel] sections from an application configurator.
int setupConfig(mx::app::appConfigurator &config)
Setup an application configurator for an outletController.
virtual int updateOutletStates()
Get the states of all outlets from the device.
int setNumberOfOutlets(int numOuts)
Sets the number of outlets. This should be called by the derived class constructor.
std::vector< int > m_outletStates
The current states of each outlet. These MUST be updated by derived classes in the overridden updated...
Software ERR log entry.
A simple text log, a string-type log.
Definition: text_log.hpp:24