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
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
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
249
250 return 0;
251
252}
253
254int 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
269int 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
284std::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}
326pcf::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
351INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch0)(const pcf::IndiProperty &ipRecv)
352{
353 ip_ch0 = ipRecv;
354
355 return updateOutletState(0);
356}
357
358INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch1)(const pcf::IndiProperty &ipRecv)
359{
360 ip_ch1 = ipRecv;
361
362 return updateOutletState(1);
363}
364
365INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch2)(const pcf::IndiProperty &ipRecv)
366{
367 ip_ch2 = ipRecv;
368
369 return updateOutletState(2);
370}
371
372INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch3)(const pcf::IndiProperty &ipRecv)
373{
374 ip_ch3 = ipRecv;
375
376 return updateOutletState(3);
377}
378
379INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch4)(const pcf::IndiProperty &ipRecv)
380{
381 ip_ch4 = ipRecv;
382
383 return updateOutletState(4);
384}
385
386INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch5)(const pcf::IndiProperty &ipRecv)
387{
388 ip_ch5 = ipRecv;
389
390 return updateOutletState(5);
391}
392
393INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch6)(const pcf::IndiProperty &ipRecv)
394{
395 ip_ch6 = ipRecv;
396
397 return updateOutletState(6);
398}
399
400INDI_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.
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.
@ 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.
const pcf::IndiProperty & ipRecv
std::unique_lock< std::mutex > lock(m_indiMutex)
Definition dm.hpp:24
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.
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