API
 
Loading...
Searching...
No Matches
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
29namespace MagAOX
30{
31namespace 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 */
40class xt1121DCDU : public MagAOXApp<>, public dev::outletController<xt1121DCDU>
41{
42
43protected:
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
63public:
64
65 /// Default c'tor.
66 xt1121DCDU();
67
68 /// D'tor, declared and defined for noexcept.
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
112protected:
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
138xt1121DCDU::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
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 if( !lock.owns_lock() )
211 {
212 return 0;
213 }
214
215 int rv = updateOutletStates();
216
217 if(rv < 0) return log<software_error,-1>({__FILE__, __LINE__});
218
220
221 return 0;
222 }
223
225 log<text_log>("appLogic fell through", logPrio::LOG_CRITICAL);
226 return -1;
227
228}
229
231{
232 //don't bother
233 return 0;
234}
235
237{
238 pcf::IndiProperty * ip = xtChannelProperty(outletNum);
239
240 if(ip == nullptr)
241 {
242 return log<software_error, -1>({__FILE__, __LINE__, "bad outlet number"});
243 }
244
245 int os = OUTLET_STATE_UNKNOWN;
246 if(ip->find("current"))
247 {
248 if((*ip)["current"].get<int>() == 0) os = OUTLET_STATE_OFF;
249 else if((*ip)["current"].get<int>() == 1) os = OUTLET_STATE_ON;
250 }
251
253
254 return 0;
255
256}
257
258int xt1121DCDU::turnOutletOn( int outletNum )
259{
260 std::lock_guard<std::mutex> guard(m_indiMutex); //Lock the mutex before doing anything
261
262 pcf::IndiProperty * ip = xtChannelProperty(outletNum);
263
264 if(ip == nullptr)
265 {
266 return log<software_error, -1>({__FILE__, __LINE__, "bad outlet number"});
267 }
268
269 return sendNewProperty(*ip, "target", 1);
270
271}
272
273int xt1121DCDU::turnOutletOff( int outletNum )
274{
275 std::lock_guard<std::mutex> guard(m_indiMutex); //Lock the mutex before doing anything
276
277 pcf::IndiProperty * ip = xtChannelProperty(outletNum);
278
279 if(ip == nullptr)
280 {
281 return log<software_error, -1>({__FILE__, __LINE__, "bad outlet number"});
282 }
283
284 return sendNewProperty(*ip, "target", 0);
285
286}
287
288std::string xt1121DCDU::xtChannelName( int chno)
289{
290 switch(chno)
291 {
292 case 0:
293 return "ch00";
294 case 1:
295 return "ch01";
296 case 2:
297 return "ch02";
298 case 3:
299 return "ch03";
300 case 4:
301 return "ch04";
302 case 5:
303 return "ch05";
304 case 6:
305 return "ch06";
306 case 7:
307 return "ch07";
308 case 8:
309 return "ch08";
310 case 9:
311 return "ch09";
312 case 10:
313 return "ch10";
314 case 11:
315 return "ch11";
316 case 12:
317 return "ch12";
318 case 13:
319 return "ch13";
320 case 14:
321 return "ch14";
322 case 15:
323 return "ch15";
324 case 16:
325 return "ch16";
326 default:
327 return "";
328 }
329}
330pcf::IndiProperty * xt1121DCDU::xtChannelProperty( int outletNum )
331{
332 switch(outletNum)
333 {
334 case 0:
335 return &ip_ch0;
336 case 1:
337 return &ip_ch1;
338 case 2:
339 return &ip_ch2;
340 case 3:
341 return &ip_ch3;
342 case 4:
343 return &ip_ch4;
344 case 5:
345 return &ip_ch5;
346 case 6:
347 return &ip_ch6;
348 case 7:
349 return &ip_ch7;
350 default:
351 return nullptr;
352 }
353}
354
355INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch0)(const pcf::IndiProperty &ipRecv)
356{
357 std::lock_guard<std::mutex> guard(m_indiMutex);
358 ip_ch0 = ipRecv;
359
360 return updateOutletState(0);
361}
362
363INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch1)(const pcf::IndiProperty &ipRecv)
364{
365 std::lock_guard<std::mutex> guard(m_indiMutex);
366 ip_ch1 = ipRecv;
367
368 return updateOutletState(1);
369}
370
371INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch2)(const pcf::IndiProperty &ipRecv)
372{
373 std::lock_guard<std::mutex> guard(m_indiMutex);
374 ip_ch2 = ipRecv;
375
376 return updateOutletState(2);
377}
378
379INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch3)(const pcf::IndiProperty &ipRecv)
380{
381 std::lock_guard<std::mutex> guard(m_indiMutex);
382 ip_ch3 = ipRecv;
383
384 return updateOutletState(3);
385}
386
387INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch4)(const pcf::IndiProperty &ipRecv)
388{
389 std::lock_guard<std::mutex> guard(m_indiMutex);
390 ip_ch4 = ipRecv;
391
392 return updateOutletState(4);
393}
394
395INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch5)(const pcf::IndiProperty &ipRecv)
396{
397 std::lock_guard<std::mutex> guard(m_indiMutex);
398 ip_ch5 = ipRecv;
399
400 return updateOutletState(5);
401}
402
403INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch6)(const pcf::IndiProperty &ipRecv)
404{
405 std::lock_guard<std::mutex> guard(m_indiMutex);
406 ip_ch6 = ipRecv;
407
408 return updateOutletState(6);
409}
410
411INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch7)(const pcf::IndiProperty &ipRecv)
412{
413 std::lock_guard<std::mutex> guard(m_indiMutex);
414 ip_ch7 = ipRecv;
415
416 return updateOutletState(7);
417}
418
419} //namespace app
420} //namespace MagAOX
421
422#endif //xt1121DCDU_hpp
The base-class for XWCTk applications.
stateCodes::stateCodeT state()
Get the current state code.
static int log(const typename logT::messageT &msg, logPrioT level=logPrio::LOG_DEFAULT)
Make a log entry.
std::mutex m_indiMutex
Mutex for locking INDI communications.
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)
MagAO-X application to control D.C. distribution via an xt1121 DIO unit.
virtual int turnOutletOff(int outletNum)
Turn off an outlet.
virtual int updateOutletState(int outletNum)
Update a single outlet state.
pcf::IndiProperty * xtChannelProperty(int outletNum)
Helper function to get a pointer to the right INDI property for an outlet number.
virtual int appStartup()
Startup functions.
INDI_SETCALLBACK_DECL(xt1121DCDU, ip_ch5)
pcf::IndiProperty ip_ch2
INDI_SETCALLBACK_DECL(xt1121DCDU, ip_ch1)
virtual void loadConfig()
load the configuration system results (called by MagAOXApp::setup())
virtual void setupConfig()
Setup the configuration system (called by MagAOXApp::setup())
INDI_SETCALLBACK_DECL(xt1121DCDU, ip_ch3)
pcf::IndiProperty ip_ch6
pcf::IndiProperty ip_ch3
virtual int appShutdown()
Do any needed shutdown tasks. Currently nothing in this app.
virtual int appLogic()
Implementation of the FSM for the xt1121 DCDU.
std::string xtChannelName(int chno)
Helper function to get the xt1121Ctrl channel name for the given channel number.
std::vector< int > m_channelNumbers
Vector of outlet numbers, used to construct the channel names to monitor as outlets 0-7.
int m_outletStateDelay
The maximum time to wait for an outlet to change state [msec].
INDI_SETCALLBACK_DECL(xt1121DCDU, ip_ch2)
~xt1121DCDU() noexcept
D'tor, declared and defined for noexcept.
INDI_SETCALLBACK_DECL(xt1121DCDU, ip_ch0)
pcf::IndiProperty ip_ch4
INDI_SETCALLBACK_DECL(xt1121DCDU, ip_ch6)
pcf::IndiProperty ip_ch1
pcf::IndiProperty ip_ch5
std::string m_deviceName
The device address.
xt1121DCDU()
Default c'tor.
virtual int turnOutletOn(int outletNum)
Turn on an outlet.
INDI_SETCALLBACK_DECL(xt1121DCDU, ip_ch7)
pcf::IndiProperty ip_ch7
INDI_SETCALLBACK_DECL(xt1121DCDU, ip_ch4)
pcf::IndiProperty ip_ch0
#define INDI_SETCALLBACK_DEFN(class, prop)
Define the callback for a set property request.
#define REG_INDI_SETPROP(prop, devName, propName)
Register a SET INDI property with the class, using the standard callback name.
const pcf::IndiProperty & ipRecv
std::unique_lock< std::mutex > lock(m_indiMutex)
Definition dm.hpp:19
static constexpr logPrioT LOG_CRITICAL
The process can not continue and will shut down (fatal)
#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.
@ FAILURE
The application has failed, should be used when m_shutdown is set for an error.
@ READY
The device is ready for operation, but is not operating.
@ NOTCONNECTED
The application is not connected to the device or service.
@ POWERON
The device power is on.
Software ERR log entry.
A simple text log, a string-type log.
Definition text_log.hpp:24