LCOV - code coverage report
Current view: top level - apps/zaberLowLevel - zaberStage.hpp (source / functions) Coverage Total Hit
Test: MagAOX Lines: 42.8 % 498 213
Test Date: 2026-01-03 21:03:39 Functions: 49.0 % 49 24

            Line data    Source code
       1              : /** \file zaberStage.hpp
       2              :   * \brief A class with details of a single zaber stage
       3              :   *
       4              :   * \ingroup zaberLowLevel_files
       5              :   */
       6              : 
       7              : #ifndef zaberStage_hpp
       8              : #define zaberStage_hpp
       9              : 
      10              : #include <iostream>
      11              : 
      12              : 
      13              : #include "../../libMagAOX/libMagAOX.hpp" //Note this is included on command line to trigger pch
      14              : 
      15              : #include "za_serial.h"
      16              : 
      17              : 
      18              : namespace MagAOX
      19              : {
      20              : namespace app
      21              : {
      22              : 
      23              : /// A class to manage the details of one stage in a Zaber system.
      24              : /**
      25              :   * \ingroup zaberLowLevel
      26              :   */
      27              : template<class parentT>
      28              : class zaberStage
      29              : {
      30              : protected:
      31              :    parentT * m_parent {nullptr}; //The parent MagAOXApp
      32              : 
      33              :    std::string m_name; ///< The stage's name.
      34              : 
      35              :    std::string m_serial; ///< The stage's serial number.
      36              : 
      37              :    int m_deviceAddress {-1}; ///< The device's address, a.k.a. its order in the chain
      38              : 
      39              :    int m_axisNumber{0}; ///< The axis number at the address (normally 0 in MagAO-X)
      40              : 
      41              :    bool m_commandStatus {true}; ///< The status of the last command sent. true = OK, false = RJ (rejected)
      42              : 
      43              :    char m_deviceStatus {'U'}; ///< Current status.  Either 'I' for IDLE or 'B' for BUSY.  Intializes to 'U' for UNKOWN.
      44              : 
      45              :    bool m_homing {false};
      46              : 
      47              :    long m_rawPos; ///< The raw position reported by the device, in microsteps.
      48              : 
      49              :    long m_tgtPos {0}; ///< The tgt position last sent to the device, in microsteps.
      50              : 
      51              :    long m_maxPos; ///< The max position allowed for the device, set by config.  Will be set to no larger m_maxPosHW.
      52              : 
      53              :    float m_temp {-999}; ///< The driver temperature, in C.
      54              : 
      55              :    bool m_warn {false};
      56              : 
      57              :    bool m_warnFD {false};
      58              :    bool m_warnFDreported {false};
      59              :    bool m_warnFQ {false};
      60              :    bool m_warnFQreported {false};
      61              :    bool m_warnFS {false};
      62              :    bool m_warnFSreported {false};
      63              :    bool m_warnFT {false};
      64              :    bool m_warnFTreported {false};
      65              :    bool m_warnFB {false};
      66              :    bool m_warnFBreported {false};
      67              :    bool m_warnFP {false};
      68              :    bool m_warnFPreported {false};
      69              :    bool m_warnFE {false};
      70              :    bool m_warnFEreported {false};
      71              :    bool m_warnWH {false};
      72              :    bool m_warnWHreported {false};
      73              :    bool m_warnWL {false};
      74              :    bool m_warnWLreported {false};
      75              :    bool m_warnWP {false};
      76              :    bool m_warnWPreported {false};
      77              :    bool m_warnWV {false};
      78              :    bool m_warnWVreported {false};
      79              :    bool m_warnWT {false};
      80              :    bool m_warnWTreported {false};
      81              :    bool m_warnWM {false};
      82              :    bool m_warnWMreported {false};
      83              :    bool m_warnWR {false};
      84              :    bool m_warnWRreported {false};
      85              :    bool m_warnNC {false};
      86              :    bool m_warnNCreported {false};
      87              :    bool m_warnNI {false};
      88              :    bool m_warnNIreported {false};
      89              :    bool m_warnND {false};
      90              :    bool m_warnNDreported {false};
      91              :    bool m_warnNU {false};
      92              :    bool m_warnNUreported {false};
      93              :    bool m_warnNJ {false};
      94              :    bool m_warnNJreported {false};
      95              :    bool m_warnUNK {false};
      96              : 
      97              : public:
      98              : 
      99              :    zaberStage() = delete;
     100              : 
     101            6 :    zaberStage( parentT * parent)
     102            6 :    {
     103            6 :       m_parent = parent;
     104            6 :    }
     105              :    /// Get the device name
     106              :    /**
     107              :      * \returns the current value of m_name
     108              :      */
     109              :    std::string name();
     110              : 
     111              :    /// Set the device name
     112              :    /**
     113              :      * \returns 0 on success
     114              :      * \returns -1 on error
     115              :      */
     116              :    int name( const std::string & n /**< [in] the new device name*/);
     117              : 
     118              :    /// Get the device serial  number
     119              :    /**
     120              :      * \returns the current value of m_serial
     121              :      */
     122              :    std::string serial();
     123              : 
     124              :    /// Set the device serial
     125              :    /**
     126              :      * \returns 0 on success
     127              :      * \returns -1 on error
     128              :      */
     129              :    int serial( const std::string & s /**< [in] the new device serial*/);
     130              : 
     131              :    /// Get the device address
     132              :    /**
     133              :      * \returns the current value of m_deviceAddress
     134              :      */
     135              :    int deviceAddress();
     136              : 
     137              :    /// Set the device address
     138              :    /**
     139              :      * \returns 0 on success
     140              :      * \returns -1 on error
     141              :      */
     142              :    int deviceAddress( const int & da /**< [in] the new device address*/);
     143              : 
     144              :    /// Get the axis number
     145              :    /**
     146              :      * \returns the current value of m_axisNumber
     147              :      */
     148              :    int axisNumber();
     149              : 
     150              :    /// Set the axis number
     151              :    /**
     152              :      * \returns 0 on success
     153              :      * \returns -1 on error
     154              :      */
     155              :    int axisNumber( const int & an /**< [in] the new axis number */);
     156              : 
     157              :    /// Get the command status
     158              :    /**
     159              :      * \returns the current value of m_commandStatus
     160              :      */
     161              :    bool commandStatus();
     162              : 
     163              :    /// Get the device status
     164              :    /**
     165              :      * \returns the current value of m_deviceStatus
     166              :      */
     167              :    char deviceStatus();
     168              : 
     169              :    /// Get the homing status
     170              :    /**
     171              :      * \returns the current value of m_homing
     172              :      */
     173              :    bool homing();
     174              : 
     175              :    /// Get the current raw position, in counts
     176              :    /**
     177              :      * \returns the current value of m_rawPos
     178              :      */
     179              :    long rawPos();
     180              : 
     181              :    /// Get the current tgt position, in counts
     182              :    /**
     183              :      * \returns the current value of m_tgtPos
     184              :      */
     185              :    long tgtPos();
     186              : 
     187              :    /// Get the max position, in counts
     188              :    /**
     189              :      * \returns the current value of m_maxPos
     190              :      */
     191              :    long maxPos();
     192              : 
     193              :    /// Get the status of the warning flag
     194              :    /**
     195              :      * \returns the current value of m_warn
     196              :      */
     197              :    bool warn();
     198              : 
     199              :    /// Get the temperature, in C
     200              :    /**
     201              :      * \returns the current value of m_temp
     202              :      */
     203              :    float temp();
     204              : 
     205              :    /// Get the warning state
     206              :    /**
     207              :      * \returns the true if any warning flags are set.
     208              :      */
     209              :    bool warningState();
     210              : 
     211              :    bool warnFD();
     212              :    bool warnFQ();
     213              :    bool warnFS();
     214              :    bool warnFT();
     215              :    bool warnFB();
     216              :    bool warnFP();
     217              :    bool warnFE();
     218              :    bool warnWH();
     219              :    bool warnWL();
     220              :    bool warnWP();
     221              :    bool warnWV();
     222              :    bool warnWT();
     223              :    bool warnWM();
     224              :    bool warnWR();
     225              :    bool warnNC();
     226              :    bool warnNI();
     227              :    bool warnND();
     228              :    bool warnNU();
     229              :    bool warnNJ();
     230              :    bool warnUNK();
     231              : 
     232              :    /// Get a response from the device, after a command has been sent.
     233              :    /** Parses the standard parts of the response in this stage's fields,
     234              :      * and extracts the response string.
     235              :      *
     236              :      * \returns 0 on success.
     237              :      * \returns -1 on error.
     238              :      */
     239              :    int getResponse( std::string & response, ///< [out]  the text response
     240              :                     const std::string & repBuff ///< [in] the reply buffer, not decoded.
     241              :                   );
     242              : 
     243              :    /// Get a response from the device, after a command has been sent.
     244              :    /** Parses the standard parts of the response in this stages fields,
     245              :      * and extracts the response string.
     246              :      *
     247              :      * \overload
     248              :      *
     249              :      * \returns 0 on success.
     250              :      * \returns -1 on error.
     251              :      */
     252              :    int getResponse( std::string & response,  ///< [out] the text response component
     253              :                     const za_reply & rep     ///< [in] the decodedstage reply
     254              :                   );
     255              : 
     256              :    int sendCommand( std::string & response,  ///< [out] the response received from the stage
     257              :                     z_port port,   ///< [in]  the port with which to communicate
     258              :                     const std::string & command  ///< [in] the command to send
     259              :                    );
     260              : 
     261              :    int getMaxPos( z_port port /**< [in] the port with which to communicate */ );
     262              : 
     263              :    int updatePos( z_port port /**< [in] the port with which to communicate */ );
     264              : 
     265              :    int updateTemp( z_port port /**< [in] the port with which to communicate */ );
     266              : 
     267              :    int stop (z_port port );
     268              : 
     269              :    int estop (z_port port );
     270              : 
     271              :    int home( z_port port /**< [in] the port with which to communicate */ );
     272              : 
     273              :    int moveAbs( z_port port, ///< [in] the port with which to communicate
     274              :                 long rawPos ///< [in] the position to move to, in counts
     275              :               );
     276              : 
     277              :    /// Sets all warning flags to false
     278              :    /** This is not the same as clearing warnings on the device, this is just used for
     279              :      * bookkeeping.
     280              :      *
     281              :      * \returns 0 on success (always)
     282              :      */
     283              :    int unsetWarnings();
     284              : 
     285              :    /// Process a single warning from the device, setting the appropriate flag.
     286              :    /** Warnings are two ASCII characeters, e.g. "WR".
     287              :      *
     288              :      * \returns 0 if the warning is processed, including if it's not recognized.
     289              :      * \returns -1 on an error, currently not possible.
     290              :      */
     291              :    int processWarning( std::string & warn /**< [in] the two-character warning flag */);
     292              : 
     293              :    /// Parse the warning response from the device.
     294              :    /** Sends each warning flag to processWarning.
     295              :      *
     296              :      * \returns 0 on success
     297              :      * \returns -1 on error
     298              :      */
     299              :    int parseWarnings(std::string & response /**< [in] the response from the warnings query*/);
     300              : 
     301              :    /// Get warnings from the device
     302              :    /** Log entries will be made and flags will be set in this structure.
     303              :      *
     304              :      * \returns 0 on success
     305              :      * \returns -1 on error.
     306              :      */
     307              :    int getWarnings( z_port port /**< [in] the port with which to communicate */ );
     308              : 
     309              :    /// Clear all state so that when the system is powered back on we get the correct new state.
     310              :    int onPowerOff();
     311              : };
     312              : 
     313              : template<class parentT>
     314            0 : std::string zaberStage<parentT>::name()
     315              : {
     316            0 :    return m_name;
     317              : }
     318              : 
     319              : template<class parentT>
     320            0 : int zaberStage<parentT>::name( const std::string & n )
     321              : {
     322            0 :    m_name = n;
     323            0 :    return 0;
     324              : }
     325              : 
     326              : template<class parentT>
     327            0 : std::string zaberStage<parentT>::serial()
     328              : {
     329            0 :    return m_serial;
     330              : }
     331              : 
     332              : template<class parentT>
     333            0 : int zaberStage<parentT>::serial( const std::string & s )
     334              : {
     335            0 :    m_serial = s;
     336            0 :    return 0;
     337              : }
     338              : 
     339              : template<class parentT>
     340            0 : int zaberStage<parentT>::deviceAddress()
     341              : {
     342            0 :    return m_deviceAddress;
     343              : }
     344              : 
     345              : template<class parentT>
     346            0 : int zaberStage<parentT>::deviceAddress( const int & da )
     347              : {
     348            0 :    m_deviceAddress = da;
     349            0 :    return 0;
     350              : }
     351              : 
     352              : template<class parentT>
     353              : int zaberStage<parentT>::axisNumber()
     354              : {
     355              :    return m_axisNumber;
     356              : }
     357              : 
     358              : template<class parentT>
     359              : int zaberStage<parentT>::axisNumber( const int & an )
     360              : {
     361              :    m_axisNumber = an;
     362              :    return 0;
     363              : }
     364              : 
     365              : template<class parentT>
     366              : bool zaberStage<parentT>::commandStatus()
     367              : {
     368              :    return m_commandStatus;
     369              : }
     370              : 
     371              : template<class parentT>
     372            0 : char zaberStage<parentT>::deviceStatus()
     373              : {
     374            0 :    return m_deviceStatus;
     375              : }
     376              : 
     377              : template<class parentT>
     378            0 : bool zaberStage<parentT>::homing()
     379              : {
     380            0 :    return m_homing;
     381              : }
     382              : 
     383              : template<class parentT>
     384            0 : long zaberStage<parentT>::rawPos()
     385              : {
     386            0 :    return m_rawPos;
     387              : }
     388              : 
     389              : template<class parentT>
     390            0 : long zaberStage<parentT>::tgtPos()
     391              : {
     392            0 :    return m_tgtPos;
     393              : }
     394              : 
     395              : template<class parentT>
     396            0 : long zaberStage<parentT>::maxPos()
     397              : {
     398            0 :    return m_maxPos;
     399              : }
     400              : 
     401              : template<class parentT>
     402            0 : bool zaberStage<parentT>::warn()
     403              : {
     404            0 :    return m_warn;
     405              : }
     406              : 
     407              : template<class parentT>
     408            0 : float zaberStage<parentT>::temp()
     409              : {
     410            0 :    return m_temp;
     411              : }
     412              : 
     413              : template<class parentT>
     414            6 : bool zaberStage<parentT>::warningState()
     415              : {
     416            6 :    return m_warn;
     417              : }
     418              : 
     419              : template<class parentT>
     420            6 : bool zaberStage<parentT>::warnFD()
     421              : {
     422            6 :    return m_warnFD;
     423              : }
     424              : 
     425              : template<class parentT>
     426            6 : bool zaberStage<parentT>::warnFQ()
     427              : {
     428            6 :    return m_warnFQ;
     429              : }
     430              : 
     431              : template<class parentT>
     432            6 : bool zaberStage<parentT>::warnFS()
     433              : {
     434            6 :    return m_warnFS;
     435              : }
     436              : 
     437              : template<class parentT>
     438            6 : bool zaberStage<parentT>::warnFT()
     439              : {
     440            6 :    return m_warnFT;
     441              : }
     442              : 
     443              : template<class parentT>
     444            6 : bool zaberStage<parentT>::warnFB()
     445              : {
     446            6 :    return m_warnFB;
     447              : }
     448              : 
     449              : template<class parentT>
     450            6 : bool zaberStage<parentT>::warnFP()
     451              : {
     452            6 :    return m_warnFP;
     453              : }
     454              : 
     455              : template<class parentT>
     456            6 : bool zaberStage<parentT>::warnFE()
     457              : {
     458            6 :    return m_warnFE;
     459              : }
     460              : 
     461              : template<class parentT>
     462            6 : bool zaberStage<parentT>::warnWH()
     463              : {
     464            6 :    return m_warnWH;
     465              : }
     466              : 
     467              : template<class parentT>
     468            6 : bool zaberStage<parentT>::warnWL()
     469              : {
     470            6 :    return m_warnWL;
     471              : }
     472              : 
     473              : template<class parentT>
     474            6 : bool zaberStage<parentT>::warnWP()
     475              : {
     476            6 :    return m_warnWP;
     477              : }
     478              : 
     479              : template<class parentT>
     480            6 : bool zaberStage<parentT>::warnWV()
     481              : {
     482            6 :    return m_warnWV;
     483              : }
     484              : 
     485              : template<class parentT>
     486            6 : bool zaberStage<parentT>::warnWT()
     487              : {
     488            6 :    return m_warnWT;
     489              : }
     490              : 
     491              : template<class parentT>
     492            6 : bool zaberStage<parentT>::warnWM()
     493              : {
     494            6 :    return m_warnWM;
     495              : }
     496              : 
     497              : template<class parentT>
     498            7 : bool zaberStage<parentT>::warnWR()
     499              : {
     500            7 :    return m_warnWR;
     501              : }
     502              : 
     503              : template<class parentT>
     504            6 : bool zaberStage<parentT>::warnNC()
     505              : {
     506            6 :    return m_warnNC;
     507              : }
     508              : 
     509              : template<class parentT>
     510            6 : bool zaberStage<parentT>::warnNI()
     511              : {
     512            6 :    return m_warnNI;
     513              : }
     514              : 
     515              : template<class parentT>
     516            6 : bool zaberStage<parentT>::warnND()
     517              : {
     518            6 :    return m_warnND;
     519              : }
     520              : 
     521              : template<class parentT>
     522            6 : bool zaberStage<parentT>::warnNU()
     523              : {
     524            6 :    return m_warnNU;
     525              : }
     526              : 
     527              : template<class parentT>
     528            6 : bool zaberStage<parentT>::warnNJ()
     529              : {
     530            6 :    return m_warnNJ;
     531              : }
     532              : 
     533              : template<class parentT>
     534            6 : bool zaberStage<parentT>::warnUNK()
     535              : {
     536            6 :    return m_warnUNK;
     537              : }
     538              : 
     539              : template<class parentT>
     540              : int zaberStage<parentT>::getResponse( std::string & response,
     541              :                              const std::string & repBuff
     542              :                            )
     543              : {
     544              :    za_reply rep;
     545              :    int rv = za_decode(&rep, repBuff.c_str(), repBuff.size());
     546              :    if(rv != Z_SUCCESS)
     547              :    {
     548              :       if(m_parent)
     549              :       {
     550              :          if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1) return rv; //don't log, but propagate error
     551              :       }
     552              : 
     553              :       MagAOXAppT::log<software_error>({__FILE__, __LINE__, rv, "za_decode !=Z_SUCCESS"});
     554              :       return rv;
     555              :    }
     556              : 
     557              :    return getResponse(response, rep);
     558              : }
     559              : 
     560              : template<class parentT>
     561            0 : int zaberStage<parentT>::getResponse( std::string & response,
     562              :                                       const za_reply & rep
     563              :                                     )
     564              : {
     565            0 :    if(rep.device_address == m_deviceAddress)
     566              :    {
     567            0 :       if(rep.reply_flags[0] == 'O') m_commandStatus = true;
     568            0 :       else m_commandStatus = false;
     569              : 
     570              : 
     571            0 :       m_deviceStatus = rep.device_status[0];
     572              : 
     573            0 :       if(m_deviceStatus == 'I' && m_homing)
     574              :       {
     575            0 :          m_warnWR = false; //Clear preemptively
     576            0 :          m_homing = false;
     577              :       }
     578              : 
     579            0 :       if(rep.warning_flags[0] == '-') unsetWarnings();
     580            0 :       else m_warn = true;
     581              : 
     582            0 :       response = rep.response_data;
     583              : 
     584            0 :       return 0;
     585              :    }
     586              :    else
     587              :    {
     588            0 :       MagAOXAppT::log<software_error>({__FILE__, __LINE__, 0, "wrong device"});
     589            0 :       return -1;
     590              :    }
     591              : }
     592              : 
     593              : template<class parentT>
     594            0 : int zaberStage<parentT>::sendCommand( std::string & response,
     595              :                              z_port port,
     596              :                              const std::string & command
     597              :                            )
     598              : {
     599            0 :    MagAOXAppT::log<text_log>(std::string("Sending: ") + command, logPrio::LOG_DEBUG2);
     600              : 
     601            0 :    za_send(port, command.c_str(), command.size());
     602              : 
     603              :    char buff[256];
     604              : 
     605            0 :    while(1)
     606              :    {
     607            0 :       int rv = za_receive(port, buff, sizeof(buff));
     608            0 :       if(rv == Z_ERROR_TIMEOUT)
     609              :       {
     610            0 :          if(m_parent)
     611              :          {
     612            0 :             if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1) return rv; //don't log, but propagate error
     613              :          }
     614              : 
     615            0 :          MagAOXAppT::log<software_error>({__FILE__, __LINE__, 0, "Z_ERROR_TIMEOUT"});
     616            0 :          break; //assume error and just get out.
     617              :       }
     618            0 :       else if(rv < 0)
     619              :       {
     620            0 :          if(m_parent)
     621              :          {
     622            0 :             if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1) return rv; //don't log, but propagate error
     623              :          }
     624              : 
     625            0 :          MagAOXAppT::log<software_error>({__FILE__, __LINE__, 0, "za_receive !=Z_SUCCESS"});
     626            0 :          break;
     627              :       }
     628              :       za_reply rep;
     629              : 
     630              : 
     631            0 :       MagAOXAppT::log<text_log>(std::string("Received: ") + buff, logPrio::LOG_DEBUG2);
     632              : 
     633            0 :       rv = za_decode(&rep, buff, sizeof(buff));
     634            0 :       if(rv != Z_SUCCESS)
     635              :       {
     636            0 :          if(m_parent)
     637              :          {
     638            0 :             if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1) return rv; //don't log, but propagate error
     639              :          }
     640              : 
     641            0 :          MagAOXAppT::log<software_error>({__FILE__, __LINE__, 0, "za_decode !=Z_SUCCESS"});
     642            0 :          break;
     643              :       }
     644              : 
     645            0 :       if(rep.device_address == m_deviceAddress) return getResponse(response, rep);
     646              :    }
     647              : 
     648            0 :    response = "";
     649              : 
     650            0 :    return -1;
     651              : }
     652              : 
     653              : template<class parentT>
     654            0 : int zaberStage<parentT>::getMaxPos( z_port port )
     655              : {
     656            0 :    if(m_deviceAddress < 1)
     657              :    {
     658            0 :       return MagAOXAppT::log<software_error, -1>({__FILE__, __LINE__, "stage " + m_name + " with with s/n " + m_serial + " not found in system."});
     659              :    }
     660              : 
     661            0 :    std::string com = "/" + mx::ioutils::convertToString(m_deviceAddress) + " ";
     662            0 :    com += "get limit.max";
     663              : 
     664            0 :    std::string response;
     665              : 
     666            0 :    int rv = sendCommand(response, port, com);
     667              : 
     668            0 :    if(rv == 0)
     669              :    {
     670            0 :       if( m_commandStatus )
     671              :       {
     672            0 :          m_maxPos = mx::ioutils::convertFromString<long>(response);
     673            0 :          return 0;
     674              :       }
     675              :       else
     676              :       {
     677            0 :          if(m_parent)
     678              :          {
     679            0 :             if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1) return -1; //don't log, but propagate error
     680              :          }
     681              : 
     682            0 :          MagAOXAppT::log<software_error>({__FILE__, __LINE__, rv, "get limit.max Command Rejected"});
     683            0 :          return -1;
     684              :       }
     685              :    }
     686              :    else
     687              :    {
     688            0 :       MagAOXAppT::log<software_error>({__FILE__, __LINE__});
     689            0 :       if(m_parent)
     690              :       {
     691            0 :          if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1) return -1; //don't log, but propagate error
     692              :       }
     693              : 
     694            0 :       return -1;
     695              :    }
     696            0 : }
     697              : 
     698              : template<class parentT>
     699            0 : int zaberStage<parentT>::updatePos( z_port port )
     700              : {
     701            0 :    if(m_deviceAddress < 1)
     702              :    {
     703            0 :       return MagAOXAppT::log<software_error, -1>({__FILE__, __LINE__, "stage " + m_name + " with with s/n " + m_serial + " not found in system."});
     704              :    }
     705              : 
     706            0 :    std::string com = "/" + mx::ioutils::convertToString(m_deviceAddress) + " ";
     707            0 :    com += "get pos";
     708              : 
     709            0 :    std::string response;
     710              : 
     711            0 :    int rv = sendCommand(response, port, com);
     712              : 
     713            0 :    if(rv == 0)
     714              :    {
     715            0 :       if( m_commandStatus )
     716              :       {
     717            0 :          m_rawPos = mx::ioutils::convertFromString<long>(response);
     718            0 :          return 0;
     719              :       }
     720              :       else
     721              :       {
     722            0 :          if(m_parent)
     723              :          {
     724            0 :             if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1) return -1; //don't log, but propagate error
     725              :          }
     726              : 
     727            0 :          MagAOXAppT::log<software_error>({__FILE__, __LINE__, rv, "get pos Command Rejected"});
     728            0 :          return -1;
     729              :       }
     730              :    }
     731              :    else
     732              :    {
     733            0 :       if(m_parent)
     734              :       {
     735            0 :          if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1) return -1; //don't log, but propagate error
     736              :       }
     737              : 
     738            0 :       MagAOXAppT::log<software_error>({__FILE__, __LINE__});
     739            0 :       return -1;
     740              :    }
     741            0 : }
     742              : 
     743              : template<class parentT>
     744            0 : int zaberStage<parentT>::updateTemp( z_port port )
     745              : {
     746            0 :    if(m_deviceAddress < 1)
     747              :    {
     748            0 :       return MagAOXAppT::log<software_error, -1>({__FILE__, __LINE__, "stage " + m_name + " with with s/n " + m_serial + " not found in system."});
     749              :    }
     750              : 
     751            0 :    std::string com = "/" + mx::ioutils::convertToString(m_deviceAddress) + " ";
     752            0 :    com += "get driver.temperature";
     753              : 
     754            0 :    std::string response;
     755              : 
     756            0 :    int rv = sendCommand(response, port, com);
     757              : 
     758            0 :    if(rv == 0)
     759              :    {
     760            0 :       if( m_commandStatus )
     761              :       {
     762            0 :          m_temp = mx::ioutils::convertFromString<float>(response);
     763            0 :          return 0;
     764              :       }
     765              :       else
     766              :       {
     767            0 :          if(m_parent)
     768              :          {
     769            0 :             if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1) return -1; //don't log, but propagate error
     770              :          }
     771              : 
     772            0 :          MagAOXAppT::log<software_error>({__FILE__, __LINE__, rv, "get driver.temperature Command Rejected"});
     773            0 :          return -1;
     774              :       }
     775              :    }
     776              :    else
     777              :    {
     778            0 :       if(m_parent)
     779              :       {
     780            0 :          if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1) return -1; //don't log, but propagate error
     781              :       }
     782              : 
     783            0 :       MagAOXAppT::log<software_error>({__FILE__, __LINE__});
     784            0 :       return -1;
     785              :    }
     786            0 : }
     787              : 
     788              : template<class parentT>
     789            0 : int zaberStage<parentT>::stop( z_port port )
     790              : {
     791            0 :    if(m_deviceAddress < 1)
     792              :    {
     793            0 :       return MagAOXAppT::log<software_error, -1>({__FILE__, __LINE__, "stage " + m_name + " with with s/n " + m_serial + " not found in system."});
     794              :    }
     795              : 
     796            0 :    std::string com = "/" + mx::ioutils::convertToString(m_deviceAddress) + " ";
     797            0 :    com += "stop";
     798              : 
     799            0 :    std::string response;
     800              : 
     801            0 :    int rv = sendCommand(response, port, com);
     802              : 
     803            0 :    if(rv == 0)
     804              :    {
     805            0 :       if( m_commandStatus )
     806              :       {
     807            0 :          return 0;
     808              :       }
     809              :       else
     810              :       {
     811            0 :          if(m_parent)
     812              :          {
     813            0 :             if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1) return -1; //don't log, but propagate error
     814              :          }
     815              : 
     816            0 :          MagAOXAppT::log<software_error>({__FILE__, __LINE__, rv, m_name + " stop Command Rejected"});
     817            0 :          return -1;
     818              :       }
     819              :    }
     820              :    else
     821              :    {
     822            0 :       if(m_parent)
     823              :       {
     824            0 :          if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1) return -1; //don't log, but propagate error
     825              :       }
     826              : 
     827            0 :       MagAOXAppT::log<software_error>({__FILE__, __LINE__});
     828            0 :       return -1;
     829              :    }
     830            0 : }
     831              : 
     832              : template<class parentT>
     833            0 : int zaberStage<parentT>::estop( z_port port )
     834              : {
     835            0 :    if(m_deviceAddress < 1)
     836              :    {
     837            0 :       return MagAOXAppT::log<software_error, -1>({__FILE__, __LINE__, "stage " + m_name + " with with s/n " + m_serial + " not found in system."});
     838              :    }
     839              : 
     840            0 :    std::string com = "/" + mx::ioutils::convertToString(m_deviceAddress) + " ";
     841            0 :    com += "estop";
     842              : 
     843            0 :    std::string response;
     844              : 
     845            0 :    int rv = sendCommand(response, port, com);
     846              : 
     847            0 :    if(rv == 0)
     848              :    {
     849            0 :       if( m_commandStatus )
     850              :       {
     851            0 :          return 0;
     852              :       }
     853              :       else
     854              :       {
     855            0 :          if(m_parent)
     856              :          {
     857            0 :             if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1) return -1; //don't log, but propagate error
     858              :          }
     859              : 
     860            0 :          MagAOXAppT::log<software_error>({__FILE__, __LINE__, rv, m_name + " estop Command Rejected"});
     861            0 :          return -1;
     862              :       }
     863              :    }
     864              :    else
     865              :    {
     866            0 :       if(m_parent)
     867              :       {
     868            0 :          if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1) return -1; //don't log, but propagate error
     869              :       }
     870              : 
     871            0 :       MagAOXAppT::log<software_error>({__FILE__, __LINE__});
     872            0 :       return -1;
     873              :    }
     874            0 : }
     875              : 
     876              : template<class parentT>
     877            0 : int zaberStage<parentT>::home( z_port port )
     878              : {
     879            0 :    if(m_deviceAddress < 1)
     880              :    {
     881            0 :       return MagAOXAppT::log<software_error, -1>({__FILE__, __LINE__, "stage " + m_name + " with with s/n " + m_serial + " not found in system."});
     882              :    }
     883              : 
     884            0 :    std::string com = "/" + mx::ioutils::convertToString(m_deviceAddress) + " ";
     885            0 :    com += "home";
     886              : 
     887            0 :    std::string response;
     888              : 
     889            0 :    int rv = sendCommand(response, port, com);
     890              : 
     891            0 :    if(rv == 0)
     892              :    {
     893            0 :       if( m_commandStatus )
     894              :       {
     895            0 :          m_homing = true;
     896            0 :          return 0;
     897              :       }
     898              :       else
     899              :       {
     900            0 :          if(m_parent)
     901              :          {
     902            0 :             if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1) return -1; //don't log, but propagate error
     903              :          }
     904              : 
     905            0 :          MagAOXAppT::log<software_error>({__FILE__, __LINE__, rv, m_name + "Home Command Rejected"});
     906            0 :          return -1;
     907              :       }
     908              :    }
     909              :    else
     910              :    {
     911            0 :       if(m_parent)
     912              :       {
     913            0 :          if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1) return -1; //don't log, but propagate error
     914              :       }
     915              : 
     916            0 :       MagAOXAppT::log<software_error>({__FILE__, __LINE__});
     917            0 :       return -1;
     918              :    }
     919            0 : }
     920              : 
     921              : template<class parentT>
     922            0 : int zaberStage<parentT>::moveAbs( z_port port,
     923              :                          long rawPos
     924              :                        )
     925              : {
     926            0 :    if(m_deviceAddress < 1)
     927              :    {
     928            0 :       return MagAOXAppT::log<software_error, -1>({__FILE__, __LINE__, "stage " + m_name + " with with s/n " + m_serial + " not found in system."});
     929              :    }
     930              : 
     931            0 :    std::string com = "/" + mx::ioutils::convertToString(m_deviceAddress) + " ";
     932            0 :    com += "move abs " + std::to_string(rawPos);
     933              : 
     934            0 :    m_tgtPos = rawPos;
     935              : 
     936            0 :    std::string response;
     937              : 
     938            0 :    int rv = sendCommand(response, port, com);
     939              : 
     940            0 :    if(rv == 0)
     941              :    {
     942            0 :       if( m_commandStatus )
     943              :       {
     944            0 :          return 0;
     945              :       }
     946              :       else
     947              :       {
     948            0 :          if(m_parent)
     949              :          {
     950            0 :             if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1) return -1; //don't log, but propagate error
     951              :          }
     952              : 
     953            0 :          MagAOXAppT::log<software_error>({__FILE__, __LINE__, rv, m_name + "move abs Command Rejected"});
     954            0 :          return -1;
     955              :       }
     956              :    }
     957              :    else
     958              :    {
     959            0 :       if(m_parent)
     960              :       {
     961            0 :          if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1) return -1; //don't log, but propagate error
     962              :       }
     963              : 
     964            0 :       MagAOXAppT::log<software_error>({__FILE__, __LINE__});
     965            0 :       return -1;
     966              :    }
     967            0 : }
     968              : 
     969              : template<class parentT>
     970            0 : int zaberStage<parentT>::unsetWarnings()
     971              : {
     972            0 :    m_warn = false;
     973              : 
     974            0 :    m_warnFD = false;
     975            0 :    m_warnFQ = false;
     976            0 :    m_warnFS = false;
     977            0 :    m_warnFT = false;
     978            0 :    m_warnFB = false;
     979            0 :    m_warnFP = false;
     980            0 :    m_warnFE = false;
     981            0 :    m_warnWH = false;
     982            0 :    m_warnWL = false;
     983            0 :    m_warnWP = false;
     984            0 :    m_warnWV = false;
     985            0 :    m_warnWT = false;
     986            0 :    m_warnWM = false;
     987            0 :    m_warnWR = false;
     988            0 :    m_warnNC = false;
     989            0 :    m_warnNI = false;
     990            0 :    m_warnND = false;
     991            0 :    m_warnNU = false;
     992            0 :    m_warnNJ = false;
     993            0 :    m_warnUNK = false;
     994              : 
     995            0 :    return 0;
     996              : }
     997              : 
     998              : template<class parentT>
     999           21 : int zaberStage<parentT>::processWarning( std::string & warn )
    1000              : {
    1001           21 :    if(warn == "FD")
    1002              :    {
    1003            1 :       if(!m_warnFDreported)
    1004              :       {
    1005            1 :          MagAOXAppT::log<text_log>(m_name + " Driver Disabled (FD): The driver has disabled itself due to overheating." , logPrio::LOG_EMERGENCY);
    1006            1 :          m_warnFDreported = true;
    1007              :       }
    1008              : 
    1009            1 :       m_warnFD = true;
    1010            1 :       return 0;
    1011              :    }
    1012           20 :    else if(warn == "FQ")
    1013              :    {
    1014            1 :       if(!m_warnFQreported)
    1015              :       {
    1016            1 :          MagAOXAppT::log<text_log>(m_name + " warning FQ: you should probably check." , logPrio::LOG_EMERGENCY);
    1017            1 :          m_warnFQreported = true;
    1018              :       }
    1019              : 
    1020            1 :       m_warnFQ = true;
    1021            1 :       return 0;
    1022              :    }
    1023           19 :    else if(warn == "FS")
    1024              :    {
    1025            1 :       if(!m_warnFSreported)
    1026              :       {
    1027            1 :          MagAOXAppT::log<text_log>(m_name + " Stalled and Stopped (FS): Stalling was detected and the axis has stopped itself. " , logPrio::LOG_WARNING);
    1028            1 :          m_warnFSreported = true;
    1029              :       }
    1030            1 :       m_warnFS = true;
    1031            1 :       return 0;
    1032              :    }
    1033           18 :    else if(warn == "FT")
    1034              :    {
    1035            1 :       if(!m_warnFTreported)
    1036              :       {
    1037            1 :          MagAOXAppT::log<text_log>(m_name + " Excessive Twist (FT): The lockstep group has exceeded allowable twist and has stopped. " , logPrio::LOG_WARNING);
    1038            1 :          m_warnFTreported = true;
    1039              :       }
    1040              : 
    1041            1 :       m_warnFT = true;
    1042            1 :       return 0;
    1043              :    }
    1044           17 :    else if(warn == "FB")
    1045              :    {
    1046            1 :       if(!m_warnFBreported)
    1047              :       {
    1048            1 :          MagAOXAppT::log<text_log>(m_name + " Stream Bounds Error (FB): A previous streamed motion could not be executed because it failed a precondition" , logPrio::LOG_WARNING);
    1049            1 :          m_warnFBreported = true;
    1050              :       }
    1051              : 
    1052            1 :       m_warnFB = true;
    1053            1 :       return 0;
    1054              :    }
    1055           16 :    else if(warn == "FP")
    1056              :    {
    1057            1 :       if(!m_warnFPreported)
    1058              :       {
    1059            1 :          MagAOXAppT::log<text_log>(m_name + " Interpolated Path Deviation (FP): Streamed or sinusoidal motion was terminated because an axis slipped and thus the device deviated from the requested path. " , logPrio::LOG_WARNING);
    1060            1 :          m_warnFPreported = true;
    1061              :       }
    1062              : 
    1063            1 :       m_warnFP = true;
    1064            1 :       return 0;
    1065              :    }
    1066           15 :    else if(warn == "FE")
    1067              :    {
    1068            1 :       if(!m_warnFEreported)
    1069              :       {
    1070            1 :          MagAOXAppT::log<text_log>(m_name + " Limit Error (FE): The target limit sensor cannot be reached or is faulty. " , logPrio::LOG_WARNING);
    1071            1 :          m_warnFEreported = true;
    1072              :       }
    1073              : 
    1074            1 :       m_warnFE = true;
    1075            1 :       return 0;
    1076              :    }
    1077           14 :    else if(warn == "WH")
    1078              :    {
    1079            1 :       if(m_warnWHreported == false)
    1080              :       {
    1081            1 :          MagAOXAppT::log<text_log>(m_name + " Device not homed (WH): The device has a position reference, but has not been homed." , logPrio::LOG_WARNING);
    1082            1 :          m_warnWHreported = true;
    1083              :       }
    1084              : 
    1085            1 :       m_warnWH = true;
    1086            1 :       return 0;
    1087              :    }
    1088           13 :    else if(warn == "WL")
    1089              :    {
    1090            1 :       if(!m_warnWLreported)
    1091              :       {
    1092            1 :          MagAOXAppT::log<text_log>(m_name + " Unexpected Limit Trigger warning (WL): A movement operation did not complete due to a triggered limit sensor." , logPrio::LOG_WARNING);
    1093            1 :          m_warnWLreported = true;
    1094              :       }
    1095              : 
    1096            1 :       m_warnWL = true;
    1097            1 :       return 0;
    1098              :    }
    1099           12 :    else if(warn == "WP")
    1100              :    {
    1101            1 :       if(!m_warnWPreported)
    1102              :       {
    1103            1 :          MagAOXAppT::log<text_log>(m_name + " Invalid calibration type (WP): The saved calibration data type is unsupported" , logPrio::LOG_WARNING);
    1104            1 :          m_warnWPreported = true;
    1105              :       }
    1106              : 
    1107            1 :       m_warnWP = true;
    1108            1 :       return 0;
    1109              :    }
    1110           11 :    else if(warn == "WV")
    1111              :    {
    1112            1 :       if(!m_warnWVreported)
    1113              :       {
    1114            1 :          MagAOXAppT::log<text_log>(m_name + " Voltage Out of Range (WV): The supply voltage is outside the recommended operating range of the device" , logPrio::LOG_WARNING);
    1115            1 :          m_warnWVreported = true;
    1116              :       }
    1117              : 
    1118            1 :       m_warnWV = true;
    1119            1 :       return 0;
    1120              :    }
    1121           10 :    else if(warn == "WT")
    1122              :    {
    1123            1 :       if(!m_warnWTreported)
    1124              :       {
    1125            1 :          MagAOXAppT::log<text_log>(m_name + " Controller Temperature High (WT): The internal temperature of the controller has exceeded the recommended limit for the device." , logPrio::LOG_WARNING);
    1126            1 :          m_warnWTreported = true;
    1127              :       }
    1128              : 
    1129            1 :       m_warnWT = true;
    1130            1 :       return 0;
    1131              :    }
    1132            9 :    else if(warn == "WM")
    1133              :    {
    1134            1 :       if(m_warnWMreported == false)
    1135              :       {
    1136            1 :          MagAOXAppT::log<text_log>(m_name + " Displaced when Stationary (WM): While not in motion, the axis has been forced out of its position." , logPrio::LOG_WARNING);
    1137            1 :          m_warnWMreported = true;
    1138              :       }
    1139              : 
    1140            1 :       m_warnWM = true;
    1141            1 :       return 0;
    1142              :    }
    1143            8 :    else if(warn == "WR")
    1144              :    {
    1145            2 :       if(m_warnWRreported == false)
    1146              :       {
    1147            2 :          MagAOXAppT::log<text_log>(m_name + " No Reference Position (WR): Axis has not had a reference position established. [homing required]" , logPrio::LOG_WARNING);
    1148            2 :          m_warnWRreported = true;
    1149              :       }
    1150              : 
    1151            2 :       m_warnWR = true;
    1152            2 :       return 0;
    1153              :    }
    1154            6 :    else if(warn == "NC")
    1155              :    {
    1156            1 :       if(!m_warnNCreported)
    1157              :       {
    1158            1 :          MagAOXAppT::log<text_log>(m_name + " Manual Control (NC): Axis is busy due to manual control via the knob." , logPrio::LOG_WARNING);
    1159            1 :          m_warnNCreported = true;
    1160              :       }
    1161              : 
    1162            1 :       m_warnNC = true;
    1163            1 :       return 0;
    1164              :    }
    1165            5 :    else if(warn == "NI")
    1166              :    {
    1167            1 :       if(m_parent)
    1168              :       {
    1169            1 :          if(m_homing == true || warnWR()) return 0; //ignore this during homing
    1170              :       }
    1171              : 
    1172            1 :       if(!m_warnNIreported)
    1173              :       {
    1174            1 :          MagAOXAppT::log<text_log>(m_name + " Command Interrupted (NI): A movement operation (command or manual control) was requested while the axis was executing another movement command." , logPrio::LOG_WARNING);
    1175            1 :          m_warnNIreported = true;
    1176              :       }
    1177              : 
    1178            1 :       m_warnNI = true;
    1179            1 :       return 0;
    1180              :    }
    1181            4 :    else if(warn == "ND")
    1182              :    {
    1183            1 :       if(!m_warnNDreported)
    1184              :       {
    1185            1 :          MagAOXAppT::log<text_log>(m_name + " Stream Discontinuity (ND): The device has slowed down while following a streamed motion path because it has run out of queued motions." , logPrio::LOG_WARNING);
    1186            1 :          m_warnNDreported = true;
    1187              :       }
    1188              : 
    1189            1 :       m_warnND = true;
    1190            1 :       return 0;
    1191              :    }
    1192            3 :    else if(warn == "NU")
    1193              :    {
    1194            1 :       if(!m_warnNUreported)
    1195              :       {
    1196            1 :          MagAOXAppT::log<text_log>(m_name + " Setting Update Pending (NU): A setting is pending to be updated or a reset is pending." , logPrio::LOG_WARNING);
    1197            1 :          m_warnNUreported = true;
    1198              :       }
    1199              : 
    1200            1 :       m_warnNU = true;
    1201            1 :       return 0;
    1202              :    }
    1203            2 :    else if(warn == "NJ")
    1204              :    {
    1205            1 :       if(!m_warnNJreported)
    1206              :       {
    1207            1 :          MagAOXAppT::log<text_log>(m_name + " Joystick Calibrating (NJ): Joystick calibration is in progress." , logPrio::LOG_WARNING);
    1208            1 :          m_warnNJreported = true;
    1209              :       }
    1210              : 
    1211            1 :       m_warnNJ = true;
    1212            1 :       return 0;
    1213              :    }
    1214              :    else
    1215              :    {
    1216            1 :       MagAOXAppT::log<software_warning>({__FILE__, __LINE__, m_name + " unknown stage warning: " + warn});
    1217              : 
    1218            1 :       m_warnUNK = true;
    1219              : 
    1220            1 :       return 0;
    1221              :    }
    1222              : 
    1223              :    return -1;
    1224              : }
    1225              : 
    1226              : template<class parentT>
    1227            6 : int zaberStage<parentT>::parseWarnings( std::string & response )
    1228              : {
    1229            6 :    size_t nwarn = std::stoi( response.substr(0, 2));
    1230              : 
    1231            6 :    if(nwarn > 0) m_warn = true;
    1232              : 
    1233           48 :    for(size_t n =0; n< nwarn; ++n)
    1234              :    {
    1235           21 :       if(response.size() < 3 + n*3)
    1236              :       {
    1237            0 :          if(m_parent)
    1238              :          {
    1239            0 :             if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1) return -1; //don't log, but propagate error
    1240              :          }
    1241              : 
    1242            0 :          MagAOXAppT::log<software_error>({__FILE__, __LINE__, "parsing incomplete warning response"});
    1243            0 :          return -1;
    1244              :       }
    1245              : 
    1246           21 :       std::string warn = response.substr(3 + n*3, 2);
    1247              : 
    1248           21 :       int rv = processWarning(warn);
    1249           21 :       if(rv < 0)
    1250              :       {
    1251            0 :          if(m_parent)
    1252              :          {
    1253            0 :             if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1) return -1; //don't log, but propagate error
    1254              :          }
    1255              : 
    1256            0 :          MagAOXAppT::log<software_error>({__FILE__, __LINE__});
    1257            0 :          return -1;
    1258              :       }
    1259              :    }
    1260              : 
    1261            6 :    if(m_warnFDreported)
    1262              :    {
    1263            1 :       if(!m_warnFD)
    1264              :       {
    1265            0 :          m_warnFDreported = false;
    1266              :       }
    1267              :    }
    1268              : 
    1269            6 :    if(m_warnFQreported)
    1270              :    {
    1271            1 :       if(!m_warnFQ)
    1272              :       {
    1273            0 :          m_warnFQreported = false;
    1274              :       }
    1275              :    }
    1276              : 
    1277            6 :    if(m_warnFSreported)
    1278              :    {
    1279            1 :       if(!m_warnFS)
    1280              :       {
    1281            0 :          m_warnFSreported = false;
    1282              :       }
    1283              :    }
    1284              : 
    1285            6 :    if(m_warnFTreported)
    1286              :    {
    1287            1 :       if(!m_warnFT)
    1288              :       {
    1289            0 :          m_warnFTreported = false;
    1290              :       }
    1291              :    }
    1292              : 
    1293            6 :    if(m_warnFBreported)
    1294              :    {
    1295            1 :       if(!m_warnFB)
    1296              :       {
    1297            0 :          m_warnFBreported = false;
    1298              :       }
    1299              :    }
    1300              : 
    1301            6 :    if(m_warnFPreported)
    1302              :    {
    1303            1 :       if(!m_warnFP)
    1304              :       {
    1305            0 :          m_warnFPreported = false;
    1306              :       }
    1307              :    }
    1308              : 
    1309            6 :    if(m_warnFEreported)
    1310              :    {
    1311            1 :       if(!m_warnFE)
    1312              :       {
    1313            0 :          m_warnFEreported = false;
    1314              :       }
    1315              :    }
    1316              : 
    1317            6 :    if(m_warnWHreported)
    1318              :    {
    1319            1 :       if(!m_warnWH)
    1320              :       {
    1321            0 :          m_warnWHreported = false;
    1322              :       }
    1323              :    }
    1324              : 
    1325            6 :    if(m_warnWLreported)
    1326              :    {
    1327            1 :       if(!m_warnWL)
    1328              :       {
    1329            0 :          m_warnWLreported = false;
    1330              :       }
    1331              :    }
    1332              : 
    1333            6 :    if(m_warnWPreported)
    1334              :    {
    1335            1 :       if(!m_warnWP)
    1336              :       {
    1337            0 :          m_warnWPreported = false;
    1338              :       }
    1339              :    }
    1340              : 
    1341            6 :    if(m_warnWVreported)
    1342              :    {
    1343            1 :       if(!m_warnWV)
    1344              :       {
    1345            0 :          m_warnWVreported = false;
    1346              :       }
    1347              :    }
    1348              : 
    1349            6 :    if(m_warnWTreported)
    1350              :    {
    1351            1 :       if(!m_warnWT)
    1352              :       {
    1353            0 :          m_warnWTreported = false;
    1354              :       }
    1355              :    }
    1356              : 
    1357            6 :    if(m_warnWMreported)
    1358              :    {
    1359            1 :       if(!m_warnWM)
    1360              :       {
    1361            0 :          m_warnWMreported = false;
    1362              :       }
    1363              :    }
    1364              : 
    1365            6 :    if(m_warnWRreported)
    1366              :    {
    1367            2 :       if(!m_warnWR)
    1368              :       {
    1369            0 :          m_warnWRreported = false;
    1370              :       }
    1371              :    }
    1372              : 
    1373            6 :    if(m_warnNCreported)
    1374              :    {
    1375            1 :       if(!m_warnNC)
    1376              :       {
    1377            0 :          m_warnNCreported = false;
    1378              :       }
    1379              :    }
    1380              : 
    1381            6 :    if(m_warnNIreported)
    1382              :    {
    1383            1 :       if(!m_warnNI)
    1384              :       {
    1385            0 :          m_warnNIreported = false;
    1386              :       }
    1387              :    }
    1388              : 
    1389            6 :    if(m_warnNDreported)
    1390              :    {
    1391            1 :       if(!m_warnND)
    1392              :       {
    1393            0 :          m_warnNDreported = false;
    1394              :       }
    1395              :    }
    1396              : 
    1397            6 :    if(m_warnNUreported)
    1398              :    {
    1399            1 :       if(!m_warnNU)
    1400              :       {
    1401            0 :          m_warnNUreported = false;
    1402              :       }
    1403              :    }
    1404              : 
    1405            6 :    if(m_warnNJreported)
    1406              :    {
    1407            1 :       if(!m_warnNJ)
    1408              :       {
    1409            0 :          m_warnNJreported = false;
    1410              :       }
    1411              :    }
    1412              : 
    1413            6 :    return 0;
    1414              : 
    1415              : }
    1416              : 
    1417              : template<class parentT>
    1418            0 : int zaberStage<parentT>::getWarnings( z_port port )
    1419              : {
    1420            0 :    if(m_deviceAddress < 1)
    1421              :    {
    1422            0 :       return MagAOXAppT::log<software_error, -1>({__FILE__, __LINE__, "stage " + m_name + " with with s/n " + m_serial + " not found in system."});
    1423              :    }
    1424              : 
    1425            0 :    std::string com = "/" + mx::ioutils::convertToString(m_deviceAddress) + " ";
    1426            0 :    com += "warnings";
    1427              : 
    1428            0 :    std::string response;
    1429              : 
    1430            0 :    int rv = sendCommand(response, port, com);
    1431              : 
    1432            0 :    if(rv == 0)
    1433              :    {
    1434            0 :       if( m_commandStatus )
    1435              :       {
    1436            0 :          unsetWarnings(); //Clear all the flags before setting them to stay current.
    1437            0 :          return parseWarnings(response);
    1438              : 
    1439              :       }
    1440              :       else
    1441              :       {
    1442            0 :          if(m_parent)
    1443              :          {
    1444            0 :             if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1) return -1; //don't log, but propagate error
    1445              :          }
    1446              : 
    1447            0 :          MagAOXAppT::log<software_error>({__FILE__, __LINE__, rv, "warnings Command Rejected"});
    1448            0 :          return -1;
    1449              :       }
    1450              :    }
    1451              :    else
    1452              :    {
    1453            0 :       if(m_parent)
    1454              :       {
    1455            0 :          if(m_parent->powerState() != 1 || m_parent->powerStateTarget() != 1) return -1; //don't log, but propagate error
    1456              :       }
    1457              : 
    1458            0 :       MagAOXAppT::log<software_error>({__FILE__, __LINE__});
    1459            0 :       return -1;
    1460              :    }
    1461            0 : }
    1462              : 
    1463              : template<class parentT>
    1464            0 : int zaberStage<parentT>::onPowerOff( )
    1465              : {
    1466            0 :    m_commandStatus = true; ///< The status of the last command sent. true = OK, false = RJ (rejected)
    1467              : 
    1468            0 :    m_deviceStatus  = 'U'; ///< Current status.  Either 'I' for IDLE or 'B' for BUSY.  Intializes to 'U' for UNKOWN.
    1469              : 
    1470            0 :    m_homing = false;
    1471              : 
    1472              :    //We don't 0 rawPos so it is retained
    1473              : 
    1474            0 :    m_tgtPos = 0; ///< The tgt position last sent to the device, in microsteps.
    1475              : 
    1476            0 :    m_temp = -999; ///< The driver temperature, in C.
    1477              : 
    1478            0 :    unsetWarnings();
    1479            0 :    m_warnWRreported = false;
    1480              : 
    1481            0 :    return 0;
    1482              : }
    1483              : 
    1484              : } //namespace app
    1485              : } //namespace MagAOX
    1486              : 
    1487              : #endif //zaberStage_hpp
        

Generated by: LCOV version 2.0-1