LCOV - code coverage report
Current view: top level - apps/xt1121DCDU - xt1121DCDU.hpp (source / functions) Coverage Total Hit
Test: MagAOX Lines: 0.0 % 163 0
Test Date: 2026-01-03 21:03:39 Functions: 0.0 % 28 0

            Line data    Source code
       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            0 :    ~xt1121DCDU() noexcept
      70            0 :    {}
      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              : 
     128            0 :    INDI_SETCALLBACK_DECL(xt1121DCDU, ip_ch0);
     129            0 :    INDI_SETCALLBACK_DECL(xt1121DCDU, ip_ch1);
     130            0 :    INDI_SETCALLBACK_DECL(xt1121DCDU, ip_ch2);
     131            0 :    INDI_SETCALLBACK_DECL(xt1121DCDU, ip_ch3);
     132            0 :    INDI_SETCALLBACK_DECL(xt1121DCDU, ip_ch4);
     133            0 :    INDI_SETCALLBACK_DECL(xt1121DCDU, ip_ch5);
     134            0 :    INDI_SETCALLBACK_DECL(xt1121DCDU, ip_ch6);
     135            0 :    INDI_SETCALLBACK_DECL(xt1121DCDU, ip_ch7);
     136              : };
     137              : 
     138            0 : xt1121DCDU::xt1121DCDU() : MagAOXApp(MAGAOX_CURRENT_SHA1, MAGAOX_REPO_MODIFIED)
     139              : {
     140            0 :    m_firstOne = true;
     141            0 :    m_powerMgtEnabled = true;
     142              : 
     143            0 :    setNumberOfOutlets(8);
     144              : 
     145            0 :    return;
     146            0 : }
     147              : 
     148            0 : void xt1121DCDU::setupConfig()
     149              : {
     150            0 :    config.add("device.name", "", "device.name", argType::Required, "device", "name", false, "string", "The device INDI name.");
     151              : 
     152            0 :    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              : 
     155            0 :    dev::outletController<xt1121DCDU>::setupConfig(config);
     156              : 
     157            0 : }
     158              : 
     159              : 
     160            0 : void xt1121DCDU::loadConfig()
     161              : {
     162            0 :    config(m_deviceName, "device.name");
     163              : 
     164            0 :    m_channelNumbers = {0,1,2,3,4,5,6,7};
     165            0 :    config(m_channelNumbers, "device.channelNumbers");
     166              : 
     167            0 :    dev::outletController<xt1121DCDU>::loadConfig(config);
     168              : 
     169            0 : }
     170              : 
     171              : 
     172              : 
     173            0 : int xt1121DCDU::appStartup()
     174              : {
     175            0 :    if(m_channelNumbers.size() != 8)
     176              :    {
     177            0 :       return log<text_log,-1>("Something other than 8 channel numbers specified.", logPrio::LOG_CRITICAL);
     178              :    }
     179              : 
     180            0 :    REG_INDI_SETPROP(ip_ch0, m_deviceName, xtChannelName(m_channelNumbers[0]));
     181            0 :    REG_INDI_SETPROP(ip_ch1, m_deviceName, xtChannelName(m_channelNumbers[1]));
     182            0 :    REG_INDI_SETPROP(ip_ch2, m_deviceName, xtChannelName(m_channelNumbers[2]));
     183            0 :    REG_INDI_SETPROP(ip_ch3, m_deviceName, xtChannelName(m_channelNumbers[3]));
     184            0 :    REG_INDI_SETPROP(ip_ch4, m_deviceName, xtChannelName(m_channelNumbers[4]));
     185            0 :    REG_INDI_SETPROP(ip_ch5, m_deviceName, xtChannelName(m_channelNumbers[5]));
     186            0 :    REG_INDI_SETPROP(ip_ch6, m_deviceName, xtChannelName(m_channelNumbers[6]));
     187            0 :    REG_INDI_SETPROP(ip_ch7, m_deviceName, xtChannelName(m_channelNumbers[7]));
     188              : 
     189            0 :    if(dev::outletController<xt1121DCDU>::setupINDI() < 0)
     190              :    {
     191            0 :       return log<text_log,-1>("Error setting up INDI for outlet control.", logPrio::LOG_CRITICAL);
     192              :    }
     193              : 
     194            0 :    state(stateCodes::NOTCONNECTED);
     195              : 
     196            0 :    return 0;
     197              : }
     198              : 
     199            0 : int xt1121DCDU::appLogic()
     200              : {
     201            0 :    if( state() == stateCodes::POWERON )
     202              :    {
     203            0 :       state(stateCodes::READY);
     204              :    }
     205              : 
     206              : 
     207            0 :    if(state() == stateCodes::READY)
     208              :    {
     209            0 :       std::unique_lock<std::mutex> lock(m_indiMutex, std::try_to_lock);
     210              : 
     211            0 :       int rv = updateOutletStates();
     212              : 
     213            0 :       if(rv < 0) return log<software_error,-1>({__FILE__, __LINE__});
     214              : 
     215            0 :       dev::outletController<xt1121DCDU>::updateINDI();
     216              : 
     217            0 :       return 0;
     218            0 :    }
     219              : 
     220            0 :    state(stateCodes::FAILURE);
     221            0 :    log<text_log>("appLogic fell through", logPrio::LOG_CRITICAL);
     222            0 :    return -1;
     223              : 
     224              : }
     225              : 
     226            0 : int xt1121DCDU::appShutdown()
     227              : {
     228              :    //don't bother
     229            0 :    return 0;
     230              : }
     231              : 
     232            0 : int xt1121DCDU::updateOutletState( int outletNum )
     233              : {
     234            0 :    pcf::IndiProperty * ip = xtChannelProperty(outletNum);
     235              : 
     236            0 :    if(ip == nullptr)
     237              :    {
     238            0 :       return log<software_error, -1>({__FILE__, __LINE__, "bad outlet number"});
     239              :    }
     240              : 
     241            0 :    int os = OUTLET_STATE_UNKNOWN;
     242            0 :    if(ip->find("current"))
     243              :    {
     244            0 :       if((*ip)["current"].get<int>() == 0) os = OUTLET_STATE_OFF;
     245            0 :       else if((*ip)["current"].get<int>() == 1) os = OUTLET_STATE_ON;
     246              :    }
     247              : 
     248            0 :    m_outletStates[outletNum] = os;
     249              : 
     250            0 :    return 0;
     251              : 
     252              : }
     253              : 
     254            0 : int xt1121DCDU::turnOutletOn( int outletNum )
     255              : {
     256            0 :    std::lock_guard<std::mutex> guard(m_indiMutex);  //Lock the mutex before doing anything
     257              : 
     258            0 :    pcf::IndiProperty * ip = xtChannelProperty(outletNum);
     259              : 
     260            0 :    if(ip == nullptr)
     261              :    {
     262            0 :       return log<software_error, -1>({__FILE__, __LINE__, "bad outlet number"});
     263              :    }
     264              : 
     265            0 :    return sendNewProperty(*ip, "target", 1);
     266              : 
     267            0 : }
     268              : 
     269            0 : int xt1121DCDU::turnOutletOff( int outletNum )
     270              : {
     271            0 :    std::lock_guard<std::mutex> guard(m_indiMutex);  //Lock the mutex before doing anything
     272              : 
     273            0 :    pcf::IndiProperty * ip = xtChannelProperty(outletNum);
     274              : 
     275            0 :    if(ip == nullptr)
     276              :    {
     277            0 :       return log<software_error, -1>({__FILE__, __LINE__, "bad outlet number"});
     278              :    }
     279              : 
     280            0 :    return sendNewProperty(*ip, "target", 0);
     281              : 
     282            0 : }
     283              : 
     284            0 : std::string xt1121DCDU::xtChannelName( int chno)
     285              : {
     286            0 :    switch(chno)
     287              :    {
     288            0 :       case 0:
     289            0 :          return "ch00";
     290            0 :       case 1:
     291            0 :          return "ch01";
     292            0 :       case 2:
     293            0 :          return "ch02";
     294            0 :       case 3:
     295            0 :          return "ch03";
     296            0 :       case 4:
     297            0 :          return "ch04";
     298            0 :       case 5:
     299            0 :          return "ch05";
     300            0 :       case 6:
     301            0 :          return "ch06";
     302            0 :       case 7:
     303            0 :          return "ch07";
     304            0 :       case 8:
     305            0 :          return "ch08";
     306            0 :       case 9:
     307            0 :          return "ch09";
     308            0 :       case 10:
     309            0 :          return "ch10";
     310            0 :       case 11:
     311            0 :          return "ch11";
     312            0 :       case 12:
     313            0 :          return "ch12";
     314            0 :       case 13:
     315            0 :          return "ch13";
     316            0 :       case 14:
     317            0 :          return "ch14";
     318            0 :       case 15:
     319            0 :          return "ch15";
     320            0 :       case 16:
     321            0 :          return "ch16";
     322            0 :       default:
     323            0 :          return "";
     324              :    }
     325              : }
     326            0 : pcf::IndiProperty * xt1121DCDU::xtChannelProperty( int outletNum )
     327              : {
     328            0 :    switch(outletNum)
     329              :    {
     330            0 :       case 0:
     331            0 :          return &ip_ch0;
     332            0 :       case 1:
     333            0 :          return &ip_ch1;
     334            0 :       case 2:
     335            0 :          return &ip_ch2;
     336            0 :       case 3:
     337            0 :          return &ip_ch3;
     338            0 :       case 4:
     339            0 :          return &ip_ch4;
     340            0 :       case 5:
     341            0 :          return &ip_ch5;
     342            0 :       case 6:
     343            0 :          return &ip_ch6;
     344            0 :       case 7:
     345            0 :          return &ip_ch7;
     346            0 :       default:
     347            0 :          return nullptr;
     348              :    }
     349              : }
     350              : 
     351            0 : INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch0)(const pcf::IndiProperty &ipRecv)
     352              : {
     353            0 :    ip_ch0 = ipRecv;
     354              : 
     355            0 :    return updateOutletState(0);
     356              : }
     357              : 
     358            0 : INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch1)(const pcf::IndiProperty &ipRecv)
     359              : {
     360            0 :    ip_ch1 = ipRecv;
     361              : 
     362            0 :    return updateOutletState(1);
     363              : }
     364              : 
     365            0 : INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch2)(const pcf::IndiProperty &ipRecv)
     366              : {
     367            0 :    ip_ch2 = ipRecv;
     368              : 
     369            0 :    return updateOutletState(2);
     370              : }
     371              : 
     372            0 : INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch3)(const pcf::IndiProperty &ipRecv)
     373              : {
     374            0 :    ip_ch3 = ipRecv;
     375              : 
     376            0 :    return updateOutletState(3);
     377              : }
     378              : 
     379            0 : INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch4)(const pcf::IndiProperty &ipRecv)
     380              : {
     381            0 :    ip_ch4 = ipRecv;
     382              : 
     383            0 :    return updateOutletState(4);
     384              : }
     385              : 
     386            0 : INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch5)(const pcf::IndiProperty &ipRecv)
     387              : {
     388            0 :    ip_ch5 = ipRecv;
     389              : 
     390            0 :    return updateOutletState(5);
     391              : }
     392              : 
     393            0 : INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch6)(const pcf::IndiProperty &ipRecv)
     394              : {
     395            0 :    ip_ch6 = ipRecv;
     396              : 
     397            0 :    return updateOutletState(6);
     398              : }
     399              : 
     400            0 : INDI_SETCALLBACK_DEFN(xt1121DCDU, ip_ch7)(const pcf::IndiProperty &ipRecv)
     401              : {
     402            0 :    ip_ch7 = ipRecv;
     403              : 
     404            0 :    return updateOutletState(7);
     405              : }
     406              : 
     407              : } //namespace app
     408              : } //namespace MagAOX
     409              : 
     410              : #endif //xt1121DCDU_hpp
        

Generated by: LCOV version 2.0-1