Line data Source code
1 : /** \file xt1121Ctrl.hpp
2 : * \brief The MagAO-X Acromag XT 1121digital I/O controller.
3 : *
4 : * \author Jared R. Males (jaredmales@gmail.com)
5 : *
6 : * \ingroup xt1121Ctrl_files
7 : */
8 :
9 : #ifndef xt1121Ctrl_hpp
10 : #define xt1121Ctrl_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 : #include "xtChannels.hpp"
17 :
18 : namespace MagAOX
19 : {
20 : namespace app
21 : {
22 :
23 :
24 : /** \defgroup xt1121Ctrl Acromag xt1121Controller
25 : * \brief Control of an Acromag xt1121digital I/O module
26 : *
27 : * <a href="../handbook/operating/software/apps/xt1121Ctrl.html">Application Documentation</a>
28 : *
29 : * \ingroup apps
30 : *
31 : */
32 :
33 : /** \defgroup xt1121Ctrl_files Acromag xt1121Controller Files
34 : * \ingroup xt1121Ctrl
35 : */
36 :
37 : /** MagAO-X application to control an Acromag xt1121digital i/o module
38 : *
39 : * \ingroup xt1121Ctrl
40 : *
41 : */
42 : class xt1121Ctrl : public MagAOXApp<>, public xt1121Channels
43 : {
44 :
45 : protected:
46 :
47 : /** \name configurable parameters
48 : *@{
49 : */
50 :
51 : std::string m_address; ///< The I.P. address of the device
52 :
53 : uint16_t m_port {502}; ///< The port to use. Default is 502 for modbus.
54 :
55 : ///@}
56 :
57 : modbus * m_mb {nullptr}; ///< The modbus protocol communication object
58 :
59 : public:
60 :
61 : ///Default c'tor
62 : xt1121Ctrl();
63 :
64 : ///Destructor
65 : ~xt1121Ctrl() noexcept;
66 :
67 : /// Setup the configuration system (called by MagAOXApp::setup())
68 : virtual void setupConfig();
69 :
70 : /// load the configuration system results (called by MagAOXApp::setup())
71 : virtual void loadConfig();
72 :
73 : /// Startup functions
74 : /** Sets up the INDI vars.
75 : *
76 : */
77 : virtual int appStartup();
78 :
79 : /// Implementation of the FSM for the Siglent SDG
80 : virtual int appLogic();
81 :
82 : /// Implementation of the on-power-off FSM logic
83 : virtual int onPowerOff();
84 :
85 : /// Implementation of the while-powered-off FSM
86 : virtual int whilePowerOff();
87 :
88 : /// Do any needed shutdown tasks. Currently nothing in this app.
89 : virtual int appShutdown();
90 :
91 : /// Get the current state of the outlets.
92 : /**
93 : * \returns 0 on success
94 : * \returns -1 on error
95 : */
96 : int getState();
97 :
98 : //INDI:
99 : protected:
100 : //declare our properties
101 : pcf::IndiProperty m_indiP_ch00;
102 : pcf::IndiProperty m_indiP_ch01;
103 : pcf::IndiProperty m_indiP_ch02;
104 : pcf::IndiProperty m_indiP_ch03;
105 : pcf::IndiProperty m_indiP_ch04;
106 : pcf::IndiProperty m_indiP_ch05;
107 : pcf::IndiProperty m_indiP_ch06;
108 : pcf::IndiProperty m_indiP_ch07;
109 : pcf::IndiProperty m_indiP_ch08;
110 : pcf::IndiProperty m_indiP_ch09;
111 : pcf::IndiProperty m_indiP_ch10;
112 : pcf::IndiProperty m_indiP_ch11;
113 : pcf::IndiProperty m_indiP_ch12;
114 : pcf::IndiProperty m_indiP_ch13;
115 : pcf::IndiProperty m_indiP_ch14;
116 : pcf::IndiProperty m_indiP_ch15;
117 :
118 : public:
119 :
120 : /// Callback worker to actually set or clear a channel and send it to the device
121 : /** Contains the target/current logic, and calls the xtChannels::setRegisters
122 : * function, and then the modbus write_registers.
123 : *
124 : * \returns 0 on success
125 : * \returns -1 on error
126 : */
127 : int channelSetCallback( size_t chNo, ///< [in] The channel number to set
128 : pcf::IndiProperty & ipToSet, ///< [in] The corresponding local INDI property
129 : const pcf::IndiProperty & ipRecv ///< [in] The received INDI property
130 : );
131 :
132 0 : INDI_NEWCALLBACK_DECL(xt1121Ctrl, m_indiP_ch00);
133 0 : INDI_NEWCALLBACK_DECL(xt1121Ctrl, m_indiP_ch01);
134 0 : INDI_NEWCALLBACK_DECL(xt1121Ctrl, m_indiP_ch02);
135 0 : INDI_NEWCALLBACK_DECL(xt1121Ctrl, m_indiP_ch03);
136 0 : INDI_NEWCALLBACK_DECL(xt1121Ctrl, m_indiP_ch04);
137 0 : INDI_NEWCALLBACK_DECL(xt1121Ctrl, m_indiP_ch05);
138 0 : INDI_NEWCALLBACK_DECL(xt1121Ctrl, m_indiP_ch06);
139 0 : INDI_NEWCALLBACK_DECL(xt1121Ctrl, m_indiP_ch07);
140 0 : INDI_NEWCALLBACK_DECL(xt1121Ctrl, m_indiP_ch08);
141 0 : INDI_NEWCALLBACK_DECL(xt1121Ctrl, m_indiP_ch09);
142 0 : INDI_NEWCALLBACK_DECL(xt1121Ctrl, m_indiP_ch10);
143 0 : INDI_NEWCALLBACK_DECL(xt1121Ctrl, m_indiP_ch11);
144 0 : INDI_NEWCALLBACK_DECL(xt1121Ctrl, m_indiP_ch12);
145 0 : INDI_NEWCALLBACK_DECL(xt1121Ctrl, m_indiP_ch13);
146 0 : INDI_NEWCALLBACK_DECL(xt1121Ctrl, m_indiP_ch14);
147 0 : INDI_NEWCALLBACK_DECL(xt1121Ctrl, m_indiP_ch15);
148 : };
149 :
150 : inline
151 : xt1121Ctrl::xt1121Ctrl() : MagAOXApp(MAGAOX_CURRENT_SHA1, MAGAOX_REPO_MODIFIED)
152 : {
153 : m_powerMgtEnabled = true;
154 : m_powerOnWait = 2; //set default.
155 : return;
156 : }
157 :
158 : inline
159 0 : xt1121Ctrl::~xt1121Ctrl() noexcept
160 : {
161 0 : if(m_mb)
162 : {
163 0 : delete m_mb;
164 : };
165 :
166 0 : return;
167 0 : }
168 :
169 : inline
170 0 : void xt1121Ctrl::setupConfig()
171 : {
172 0 : config.add("device.address", "", "device.address", argType::Required, "device", "address", true, "string", "The device I.P. address.");
173 0 : config.add("device.port", "", "device.port", argType::Required, "device", "port", true, "int", "The device port. Default is 502.");
174 : //config.add("device.powerOnWait", "", "device.powerOnWait", argType::Required, "device", "powerOnWait", false, "int", "Time after power-on to begin attempting connections [sec]. Default is 2 sec.");
175 0 : config.add("device.inputOnly", "", "device.inputOnly", argType::Required, "device", "inputOnly", false, "vector<int>", "List of channels which are input-only.");
176 :
177 0 : }
178 :
179 :
180 : ///\todo mxlib loadConfig needs to return int to propagate errors!
181 :
182 : inline
183 0 : void xt1121Ctrl::loadConfig()
184 : {
185 0 : config(m_address, "device.address");
186 0 : config(m_port, "device.port");
187 :
188 0 : std::vector<int> ino;
189 0 : config(ino, "device.inputOnly");
190 :
191 0 : for(size_t i=0; i< ino.size();++i)
192 : {
193 0 : if(setInputOnly(ino[i]) != 0)
194 : {
195 0 : log<text_log>("Error setting channel " + std::to_string(i) + " to input only.", logPrio::LOG_ERROR);
196 : }
197 : }
198 0 : }
199 :
200 :
201 :
202 : inline
203 0 : int xt1121Ctrl::appStartup()
204 : {
205 : // set up the INDI properties
206 0 : REG_INDI_NEWPROP(m_indiP_ch00, "ch00", pcf::IndiProperty::Number);
207 0 : m_indiP_ch00.add (pcf::IndiElement("current"));
208 0 : m_indiP_ch00["current"].set(-1);
209 0 : m_indiP_ch00.add (pcf::IndiElement("target"));
210 :
211 0 : REG_INDI_NEWPROP(m_indiP_ch01, "ch01", pcf::IndiProperty::Number);
212 0 : m_indiP_ch01.add (pcf::IndiElement("current"));
213 0 : m_indiP_ch01["current"].set(-1);
214 0 : m_indiP_ch01.add (pcf::IndiElement("target"));
215 :
216 0 : REG_INDI_NEWPROP(m_indiP_ch02, "ch02", pcf::IndiProperty::Number);
217 0 : m_indiP_ch02.add (pcf::IndiElement("current"));
218 0 : m_indiP_ch02["current"].set(-1);
219 0 : m_indiP_ch02.add (pcf::IndiElement("target"));
220 :
221 0 : REG_INDI_NEWPROP(m_indiP_ch03, "ch03", pcf::IndiProperty::Number);
222 0 : m_indiP_ch03.add (pcf::IndiElement("current"));
223 0 : m_indiP_ch03["current"].set(-1);
224 0 : m_indiP_ch03.add (pcf::IndiElement("target"));
225 :
226 0 : REG_INDI_NEWPROP(m_indiP_ch04, "ch04", pcf::IndiProperty::Number);
227 0 : m_indiP_ch04.add (pcf::IndiElement("current"));
228 0 : m_indiP_ch04["current"].set(-1);
229 0 : m_indiP_ch04.add (pcf::IndiElement("target"));
230 :
231 0 : REG_INDI_NEWPROP(m_indiP_ch05, "ch05", pcf::IndiProperty::Number);
232 0 : m_indiP_ch05.add (pcf::IndiElement("current"));
233 0 : m_indiP_ch05["current"].set(-1);
234 0 : m_indiP_ch05.add (pcf::IndiElement("target"));
235 :
236 0 : REG_INDI_NEWPROP(m_indiP_ch06, "ch06", pcf::IndiProperty::Number);
237 0 : m_indiP_ch06.add (pcf::IndiElement("current"));
238 0 : m_indiP_ch06["current"].set(-1);
239 0 : m_indiP_ch06.add (pcf::IndiElement("target"));
240 :
241 0 : REG_INDI_NEWPROP(m_indiP_ch07, "ch07", pcf::IndiProperty::Number);
242 0 : m_indiP_ch07.add (pcf::IndiElement("current"));
243 0 : m_indiP_ch07["current"].set(-1);
244 0 : m_indiP_ch07.add (pcf::IndiElement("target"));
245 :
246 0 : REG_INDI_NEWPROP(m_indiP_ch08, "ch08", pcf::IndiProperty::Number);
247 0 : m_indiP_ch08.add (pcf::IndiElement("current"));
248 0 : m_indiP_ch08["current"].set(-1);
249 0 : m_indiP_ch08.add (pcf::IndiElement("target"));
250 :
251 0 : REG_INDI_NEWPROP(m_indiP_ch09, "ch09", pcf::IndiProperty::Number);
252 0 : m_indiP_ch09.add (pcf::IndiElement("current"));
253 0 : m_indiP_ch09["current"].set(-1);
254 0 : m_indiP_ch09.add (pcf::IndiElement("target"));
255 :
256 0 : REG_INDI_NEWPROP(m_indiP_ch10, "ch10", pcf::IndiProperty::Number);
257 0 : m_indiP_ch10.add (pcf::IndiElement("current"));
258 0 : m_indiP_ch10["current"].set(-1);
259 0 : m_indiP_ch10.add (pcf::IndiElement("target"));
260 :
261 0 : REG_INDI_NEWPROP(m_indiP_ch11, "ch11", pcf::IndiProperty::Number);
262 0 : m_indiP_ch11.add (pcf::IndiElement("current"));
263 0 : m_indiP_ch11["current"].set(-1);
264 0 : m_indiP_ch11.add (pcf::IndiElement("target"));
265 :
266 0 : REG_INDI_NEWPROP(m_indiP_ch12, "ch12", pcf::IndiProperty::Number);
267 0 : m_indiP_ch12.add (pcf::IndiElement("current"));
268 0 : m_indiP_ch12["current"].set(-1);
269 0 : m_indiP_ch12.add (pcf::IndiElement("target"));
270 :
271 0 : REG_INDI_NEWPROP(m_indiP_ch13, "ch13", pcf::IndiProperty::Number);
272 0 : m_indiP_ch13.add (pcf::IndiElement("current"));
273 0 : m_indiP_ch13["current"].set(-1);
274 0 : m_indiP_ch13.add (pcf::IndiElement("target"));
275 :
276 0 : REG_INDI_NEWPROP(m_indiP_ch14, "ch14", pcf::IndiProperty::Number);
277 0 : m_indiP_ch14.add (pcf::IndiElement("current"));
278 0 : m_indiP_ch14["current"].set(-1);
279 0 : m_indiP_ch14.add (pcf::IndiElement("target"));
280 :
281 0 : REG_INDI_NEWPROP(m_indiP_ch15, "ch15", pcf::IndiProperty::Number);
282 0 : m_indiP_ch15.add (pcf::IndiElement("current"));
283 0 : m_indiP_ch15["current"].set(-1);
284 0 : m_indiP_ch15.add (pcf::IndiElement("target"));
285 :
286 :
287 0 : return 0;
288 :
289 : }
290 :
291 :
292 :
293 : inline
294 0 : int xt1121Ctrl::appLogic()
295 : {
296 0 : if( state() == stateCodes::POWERON )
297 : {
298 0 : if(!powerOnWaitElapsed())
299 : {
300 0 : return 0;
301 : }
302 :
303 0 : state(stateCodes::NOTCONNECTED);
304 : }
305 :
306 0 : if( state() == stateCodes::NOTCONNECTED || state() == stateCodes::ERROR)
307 : {
308 0 : std::string response;
309 :
310 : //Might have gotten here because of a power off.
311 0 : if(m_powerState == 0) return 0;
312 :
313 0 : m_mb = new(std::nothrow) modbus(m_address, m_port);
314 :
315 0 : if(m_mb == nullptr)
316 : {
317 0 : return log<software_critical, -1>({__FILE__, __LINE__, "allocation failure"});
318 : }
319 :
320 0 : m_mb->modbus_set_slave_id(1);
321 :
322 0 : if( m_mb->modbus_connect() == false)
323 : {
324 0 : if(!stateLogged())
325 : {
326 0 : log<text_log>("connect failed at " + m_address + ":" + std::to_string(m_port));
327 : }
328 0 : delete m_mb;
329 0 : m_mb = nullptr;
330 0 : return 0;
331 : }
332 :
333 0 : state(stateCodes::CONNECTED);
334 0 : log<text_log>("connected to " + m_address + ":" + std::to_string(m_port));
335 0 : }
336 :
337 0 : if( state() == stateCodes::CONNECTED )
338 : {
339 : //Get a lock
340 0 : std::unique_lock<std::mutex> lock(m_indiMutex);
341 :
342 0 : if( getState() == 0 )
343 : {
344 0 : state(stateCodes::READY);
345 0 : return 0;
346 : }
347 : else
348 : {
349 0 : state(stateCodes::ERROR);
350 0 : return log<software_error,0>({__FILE__,__LINE__});
351 : }
352 0 : }
353 :
354 0 : if( state() == stateCodes::READY || state() == stateCodes::OPERATING )
355 : {
356 : //Get a lock if we can
357 0 : std::unique_lock<std::mutex> lock(m_indiMutex, std::try_to_lock);
358 :
359 : //but don't wait for it, just go back around.
360 0 : if(!lock.owns_lock()) return 0;
361 :
362 0 : if(getState() < 0)
363 : {
364 0 : if(m_powerState == 0) return 0;
365 :
366 0 : state(stateCodes::ERROR);
367 0 : return 0;
368 : }
369 :
370 0 : return 0;
371 0 : }
372 :
373 : //Fall through check?
374 :
375 0 : return 0;
376 :
377 : }
378 :
379 : inline
380 0 : int xt1121Ctrl::onPowerOff()
381 : {
382 0 : std::lock_guard<std::mutex> lock(m_indiMutex);
383 :
384 0 : updateIfChanged(m_indiP_ch00, "current", -1);
385 0 : updateIfChanged(m_indiP_ch00, "target", -1);
386 :
387 0 : updateIfChanged(m_indiP_ch01, "current", -1);
388 0 : updateIfChanged(m_indiP_ch01, "target", -1);
389 :
390 0 : updateIfChanged(m_indiP_ch02, "current", -1);
391 0 : updateIfChanged(m_indiP_ch02, "target", -1);
392 :
393 0 : updateIfChanged(m_indiP_ch03, "current", -1);
394 0 : updateIfChanged(m_indiP_ch03, "target", -1);
395 :
396 0 : updateIfChanged(m_indiP_ch04, "current", -1);
397 0 : updateIfChanged(m_indiP_ch04, "target", -1);
398 :
399 0 : updateIfChanged(m_indiP_ch05, "current", -1);
400 0 : updateIfChanged(m_indiP_ch05, "target", -1);
401 :
402 0 : updateIfChanged(m_indiP_ch06, "current", -1);
403 0 : updateIfChanged(m_indiP_ch06, "target", -1);
404 :
405 0 : updateIfChanged(m_indiP_ch07, "current", -1);
406 0 : updateIfChanged(m_indiP_ch07, "target", -1);
407 :
408 0 : updateIfChanged(m_indiP_ch08, "current", -1);
409 0 : updateIfChanged(m_indiP_ch08, "target", -1);
410 :
411 0 : updateIfChanged(m_indiP_ch09, "current", -1);
412 0 : updateIfChanged(m_indiP_ch09, "target", -1);
413 :
414 0 : updateIfChanged(m_indiP_ch10, "current", -1);
415 0 : updateIfChanged(m_indiP_ch10, "target", -1);
416 :
417 0 : updateIfChanged(m_indiP_ch11, "current", -1);
418 0 : updateIfChanged(m_indiP_ch11, "target", -1);
419 :
420 0 : updateIfChanged(m_indiP_ch12, "current", -1);
421 0 : updateIfChanged(m_indiP_ch12, "target", -1);
422 :
423 0 : updateIfChanged(m_indiP_ch13, "current", -1);
424 0 : updateIfChanged(m_indiP_ch13, "target", -1);
425 :
426 0 : updateIfChanged(m_indiP_ch14, "current", -1);
427 0 : updateIfChanged(m_indiP_ch14, "target", -1);
428 :
429 0 : updateIfChanged(m_indiP_ch15, "current", -1);
430 0 : updateIfChanged(m_indiP_ch15, "target", -1);
431 :
432 :
433 0 : return 0;
434 0 : }
435 :
436 : inline
437 0 : int xt1121Ctrl::whilePowerOff()
438 : {
439 0 : return 0;
440 : }
441 :
442 : inline
443 0 : int xt1121Ctrl::appShutdown()
444 : {
445 0 : if(m_mb) m_mb->modbus_close();
446 0 : return 0;
447 : }
448 :
449 :
450 :
451 : inline
452 0 : int xt1121Ctrl::getState()
453 : {
454 : uint16_t input_regs[numRegisters];
455 :
456 : try
457 : {
458 : ///\todo this hangs if power goes off during call
459 0 : m_mb->modbus_read_input_registers(0,numRegisters,input_regs);
460 : }
461 0 : catch(std::exception & e)
462 : {
463 0 : if(m_powerState == 0) return 0; //due to power off
464 :
465 0 : return log<software_error,-1>({__FILE__, __LINE__, std::string("Exception caught: ") + e.what()});
466 0 : }
467 :
468 0 : if( readRegisters(input_regs) !=0 )
469 : {
470 0 : return log<software_error,-1>({__FILE__, __LINE__});
471 : }
472 :
473 0 : updateIfChanged(m_indiP_ch00, "current", channel(0));
474 0 : updateIfChanged(m_indiP_ch01, "current", channel(1));
475 0 : updateIfChanged(m_indiP_ch02, "current", channel(2));
476 0 : updateIfChanged(m_indiP_ch03, "current", channel(3));
477 0 : updateIfChanged(m_indiP_ch04, "current", channel(4));
478 0 : updateIfChanged(m_indiP_ch05, "current", channel(5));
479 0 : updateIfChanged(m_indiP_ch06, "current", channel(6));
480 0 : updateIfChanged(m_indiP_ch07, "current", channel(7));
481 0 : updateIfChanged(m_indiP_ch08, "current", channel(8));
482 0 : updateIfChanged(m_indiP_ch09, "current", channel(9));
483 0 : updateIfChanged(m_indiP_ch10, "current", channel(10));
484 0 : updateIfChanged(m_indiP_ch11, "current", channel(11));
485 0 : updateIfChanged(m_indiP_ch12, "current", channel(12));
486 0 : updateIfChanged(m_indiP_ch13, "current", channel(13));
487 0 : updateIfChanged(m_indiP_ch14, "current", channel(14));
488 0 : updateIfChanged(m_indiP_ch15, "current", channel(15));
489 :
490 0 : return 0;
491 :
492 :
493 : }
494 :
495 :
496 0 : int xt1121Ctrl::channelSetCallback( size_t chNo,
497 : pcf::IndiProperty & ipToSet,
498 : const pcf::IndiProperty & ipRecv
499 : )
500 : {
501 0 : int current = -1, target = -1;
502 :
503 0 : if(ipRecv.find("current"))
504 : {
505 0 : current = ipRecv["current"].get<unsigned>();
506 : }
507 :
508 0 : if(ipRecv.find("target"))
509 : {
510 0 : target = ipRecv["target"].get<unsigned>();
511 : }
512 :
513 0 : if(target == -1) target = current;
514 :
515 0 : if(target < 0) return 0;
516 :
517 : //Lock the mutex, waiting if necessary
518 0 : std::unique_lock<std::mutex> lock(m_indiMutex);
519 :
520 0 : if(target == 0) clearChannel(chNo);
521 0 : else setChannel(chNo);
522 :
523 0 : target = channel(chNo); //This checks for inputOnly
524 :
525 0 : updateIfChanged(ipToSet, "target", target);
526 :
527 : uint16_t input_regs[numRegisters];
528 :
529 0 : if( setRegisters(input_regs) !=0 )
530 : {
531 0 : return log<software_error,-1>({__FILE__, __LINE__});
532 : }
533 :
534 : try
535 : {
536 0 : m_mb->modbus_write_registers(0,numRegisters,input_regs);
537 : }
538 0 : catch(std::exception & e)
539 : {
540 0 : if(m_powerState == 0) return 0; //due to power off
541 :
542 0 : return log<software_error,-1>({__FILE__, __LINE__, std::string("Exception caught: ") + e.what()});
543 0 : }
544 :
545 :
546 0 : log<text_log>("Set channel " + std::to_string(chNo) + " to " + std::to_string(target));
547 :
548 0 : return 0;
549 :
550 0 : }
551 :
552 0 : INDI_NEWCALLBACK_DEFN(xt1121Ctrl, m_indiP_ch00)(const pcf::IndiProperty &ipRecv)
553 : {
554 0 : INDI_VALIDATE_CALLBACK_PROPS(m_indiP_ch00, ipRecv);
555 :
556 0 : return channelSetCallback(0, m_indiP_ch00, ipRecv);
557 :
558 : return -1;
559 : }
560 :
561 0 : INDI_NEWCALLBACK_DEFN(xt1121Ctrl, m_indiP_ch01)(const pcf::IndiProperty &ipRecv)
562 : {
563 0 : INDI_VALIDATE_CALLBACK_PROPS(m_indiP_ch01, ipRecv);
564 :
565 0 : return channelSetCallback(1, m_indiP_ch01, ipRecv);
566 :
567 : return -1;
568 : }
569 :
570 0 : INDI_NEWCALLBACK_DEFN(xt1121Ctrl, m_indiP_ch02)(const pcf::IndiProperty &ipRecv)
571 : {
572 0 : INDI_VALIDATE_CALLBACK_PROPS(m_indiP_ch02, ipRecv);
573 :
574 0 : return channelSetCallback(2, m_indiP_ch02, ipRecv);
575 :
576 : return -1;
577 : }
578 :
579 0 : INDI_NEWCALLBACK_DEFN(xt1121Ctrl, m_indiP_ch03)(const pcf::IndiProperty &ipRecv)
580 : {
581 0 : INDI_VALIDATE_CALLBACK_PROPS(m_indiP_ch03, ipRecv);
582 :
583 0 : return channelSetCallback(3, m_indiP_ch03, ipRecv);
584 :
585 : return -1;
586 : }
587 :
588 0 : INDI_NEWCALLBACK_DEFN(xt1121Ctrl, m_indiP_ch04)(const pcf::IndiProperty &ipRecv)
589 : {
590 0 : INDI_VALIDATE_CALLBACK_PROPS(m_indiP_ch04, ipRecv);
591 :
592 0 : return channelSetCallback(4, m_indiP_ch04, ipRecv);
593 :
594 : return -1;
595 : }
596 :
597 0 : INDI_NEWCALLBACK_DEFN(xt1121Ctrl, m_indiP_ch05)(const pcf::IndiProperty &ipRecv)
598 : {
599 0 : INDI_VALIDATE_CALLBACK_PROPS(m_indiP_ch05, ipRecv);
600 :
601 0 : return channelSetCallback(5, m_indiP_ch05, ipRecv);
602 :
603 : return -1;
604 : }
605 :
606 0 : INDI_NEWCALLBACK_DEFN(xt1121Ctrl, m_indiP_ch06)(const pcf::IndiProperty &ipRecv)
607 : {
608 0 : INDI_VALIDATE_CALLBACK_PROPS(m_indiP_ch06, ipRecv);
609 :
610 0 : return channelSetCallback(6, m_indiP_ch06, ipRecv);
611 :
612 : return -1;
613 : }
614 :
615 0 : INDI_NEWCALLBACK_DEFN(xt1121Ctrl, m_indiP_ch07)(const pcf::IndiProperty &ipRecv)
616 : {
617 0 : INDI_VALIDATE_CALLBACK_PROPS(m_indiP_ch07, ipRecv);
618 :
619 0 : return channelSetCallback(7, m_indiP_ch07, ipRecv);
620 :
621 : return -1;
622 : }
623 :
624 0 : INDI_NEWCALLBACK_DEFN(xt1121Ctrl, m_indiP_ch08)(const pcf::IndiProperty &ipRecv)
625 : {
626 0 : INDI_VALIDATE_CALLBACK_PROPS(m_indiP_ch08, ipRecv);
627 :
628 0 : return channelSetCallback(8, m_indiP_ch08, ipRecv);
629 :
630 : return -1;
631 : }
632 :
633 0 : INDI_NEWCALLBACK_DEFN(xt1121Ctrl, m_indiP_ch09)(const pcf::IndiProperty &ipRecv)
634 : {
635 0 : INDI_VALIDATE_CALLBACK_PROPS(m_indiP_ch09, ipRecv);
636 :
637 0 : return channelSetCallback(9, m_indiP_ch09, ipRecv);
638 :
639 : return -1;
640 : }
641 :
642 0 : INDI_NEWCALLBACK_DEFN(xt1121Ctrl, m_indiP_ch10)(const pcf::IndiProperty &ipRecv)
643 : {
644 0 : INDI_VALIDATE_CALLBACK_PROPS(m_indiP_ch10, ipRecv);
645 :
646 0 : return channelSetCallback(10, m_indiP_ch10, ipRecv);
647 :
648 : return -1;
649 : }
650 :
651 0 : INDI_NEWCALLBACK_DEFN(xt1121Ctrl, m_indiP_ch11)(const pcf::IndiProperty &ipRecv)
652 : {
653 0 : INDI_VALIDATE_CALLBACK_PROPS(m_indiP_ch11, ipRecv);
654 :
655 0 : return channelSetCallback(11, m_indiP_ch11, ipRecv);
656 :
657 : return -1;
658 : }
659 :
660 0 : INDI_NEWCALLBACK_DEFN(xt1121Ctrl, m_indiP_ch12)(const pcf::IndiProperty &ipRecv)
661 : {
662 0 : INDI_VALIDATE_CALLBACK_PROPS(m_indiP_ch12, ipRecv);
663 :
664 0 : return channelSetCallback(12, m_indiP_ch12, ipRecv);
665 :
666 : return -1;
667 : }
668 :
669 0 : INDI_NEWCALLBACK_DEFN(xt1121Ctrl, m_indiP_ch13)(const pcf::IndiProperty &ipRecv)
670 : {
671 0 : INDI_VALIDATE_CALLBACK_PROPS(m_indiP_ch13, ipRecv);
672 :
673 0 : return channelSetCallback(13, m_indiP_ch13, ipRecv);
674 :
675 : return -1;
676 : }
677 :
678 0 : INDI_NEWCALLBACK_DEFN(xt1121Ctrl, m_indiP_ch14)(const pcf::IndiProperty &ipRecv)
679 : {
680 0 : INDI_VALIDATE_CALLBACK_PROPS(m_indiP_ch14, ipRecv);
681 :
682 0 : return channelSetCallback(14, m_indiP_ch14, ipRecv);
683 :
684 : return -1;
685 : }
686 :
687 0 : INDI_NEWCALLBACK_DEFN(xt1121Ctrl, m_indiP_ch15)(const pcf::IndiProperty &ipRecv)
688 : {
689 0 : INDI_VALIDATE_CALLBACK_PROPS(m_indiP_ch15, ipRecv);
690 :
691 0 : return channelSetCallback(15, m_indiP_ch15, ipRecv);
692 :
693 : return -1;
694 : }
695 :
696 :
697 : }//namespace app
698 : } //namespace MagAOX
699 : #endif
|