LCOV - code coverage report
Current view: top level - drivers/mdev - mdev_mscb.cxx (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 134 0
Test Date: 2025-11-11 10:26:08 Functions: 0.0 % 6 0

            Line data    Source code
       1              : /********************************************************************\
       2              : 
       3              :   Name:         mdev_mscb.cxx
       4              :   Created by:   Stefan Ritt
       5              : 
       6              :   Contents:     MIDAS device drivers class for MSCB devices
       7              : 
       8              : \********************************************************************/
       9              : 
      10              : #include <iostream>
      11              : 
      12              : #include "midas.h"
      13              : #include "odbxx.h"
      14              : 
      15              : #include "mdev_mscb.h"
      16              : 
      17            0 : void mdev_mscb::odb_setup(void) {
      18              :    // MPDC settings in ODB
      19              :    midas::odb settings = {
      20              :            { "Grid display",  false },
      21            0 :            { "Names MSCB",    std::string(31, '\0')},
      22            0 :            { "Unit MSCB",     std::string(31, '\0')},
      23              :            { "Editable",      false },
      24              :            { "Group",         false },
      25            0 :            { "MSCB",          {} },
      26            0 :    };
      27              : 
      28            0 :    settings.connect("/Equipment/" + m_equipment_name + "/Settings");
      29            0 :    m_settings.connect("/Equipment/" + m_equipment_name + "/Settings");
      30              : 
      31              :    // loop over all nodes
      32            0 :    m_n_variables = 0;
      33              : 
      34            0 :    for (auto & node : m_node) {
      35            0 :       if (!midas::odb::exists("/Equipment/" + m_equipment_name + "/Settings/MSCB/" +
      36            0 :                               node.m_device + "/Enabled"))
      37            0 :          m_settings["MSCB"][node.m_device]["Enabled"] = true;
      38              : 
      39            0 :       node.m_enabled = m_settings["MSCB"][node.m_device]["Enabled"];
      40            0 :       m_settings["MSCB"][node.m_device]["Device"]  = node.m_device;
      41            0 :       m_settings["MSCB"][node.m_device]["Pwd"]     = node.m_pwd;
      42            0 :       m_settings["MSCB"][node.m_device]["Address"] = node.m_address;
      43              : 
      44              :       // loop over all variables
      45            0 :       for (int i=0 ; i<(int)node.m_mscb_var.size() ; i++) {
      46              : 
      47              :          // check for double names
      48            0 :          for (int j=0 ; j<m_n_variables ; j++)
      49            0 :             if (m_settings["Names MSCB"][j].s() == node.m_mscb_var[i].name)
      50            0 :                mthrow("Variable name \"" + node.m_mscb_var[i].name + "\" defined twice.");
      51              : 
      52              :          // set into in ODB
      53            0 :          m_settings["Names MSCB"][m_n_variables].set_string_size(node.m_mscb_var[i].name, 32);
      54            0 :          m_settings["Editable"][m_n_variables] = node.m_mscb_var[i].output;
      55            0 :          m_settings["MSCB"][node.m_device]["Variables"][i] = node.m_mscb_var[i].var;
      56            0 :          m_n_variables++;
      57              :       }
      58              : 
      59            0 :       m_settings["MSCB"][node.m_device]["Variables"].resize(node.m_mscb_var.size());
      60              :    }
      61              : 
      62            0 :    if (m_n_variables > 0) {
      63            0 :       m_settings["Names MSCB"].resize(m_n_variables);
      64            0 :       m_settings["Editable"].resize(m_n_variables);
      65            0 :       m_settings["Group"] = m_group;
      66              :    }
      67              : 
      68              :    // MSCB variables in ODB
      69            0 :    m_variables.connect("/Equipment/" + m_equipment_name + "/Variables");
      70            0 :    for (int i=0 ; i<m_n_variables ; i++)
      71            0 :       m_variables["MSCB"][i] = (float) ss_nan();
      72              : 
      73              :    // MSCB common tree
      74            0 :    m_common.connect("/Equipment/" + m_equipment_name + "/Common");
      75            0 : }
      76              : 
      77            0 : void mdev_mscb::init(void) {
      78              : 
      79            0 :    if (!m_common["Enabled"]) {
      80            0 :       std::cout << "Equipment \"" << m_equipment_name << "\" disabled" << std::endl;
      81            0 :       return;
      82              :    }
      83              : 
      84              :    // loop over all MSCB nodes
      85            0 :    int n_variables = 0;
      86            0 :    for (mscb_node &node : m_node) {
      87              : 
      88            0 :       if (!node.m_enabled)
      89            0 :          continue;
      90              : 
      91              :       try {
      92              : 
      93            0 :          node.m_mscb = new midas::mscb(node.m_device, node.m_address, node.m_pwd, node.m_enabled);
      94              : 
      95            0 :       } catch (mexception &e) {
      96            0 :          std::string s = "Cannot connect to MSCB device \"" + node.m_device + ":" +
      97            0 :                          std::to_string(node.m_address) + "\"";
      98            0 :          mthrow1(s);
      99            0 :       }
     100              : 
     101              :       // loop over all variables for that node
     102            0 :       for (size_t i=0 ; i<node.m_mscb_var.size() ; i++) {
     103              : 
     104              :          // retrieve index for variable "var"
     105            0 :          if (node.m_mscb_var[i].var != "") {
     106            0 :             node.m_mscb_var[i].index = node.m_mscb->idx(node.m_mscb_var[i].var);
     107            0 :             if (node.m_mscb_var[i].index == -1) {
     108            0 :                std::string s = "Invalid MSCB variable name \"" + node.m_device + ":" +
     109            0 :                    std::to_string(node.m_address) + ":" + node.m_mscb_var[i].var + "\"";
     110            0 :                mthrow1(s);
     111            0 :             }
     112              :          }
     113              : 
     114              :          try {
     115              : 
     116              :             // retrieve value for mirror
     117            0 :             m_mirror.push_back((float)(*node.m_mscb)[node.m_mscb_var[i].index]);
     118              : 
     119            0 :          } catch (mexception &e) {
     120            0 :             std::string s;
     121            0 :             if (node.m_mscb_var[i].var == "")
     122            0 :                s = "Cannot retrieve MSCB variable \"" + node.m_device + ":" +
     123            0 :                                std::to_string(node.m_address) + ":" + std::to_string(node.m_mscb_var[i].index) + "\"";
     124              :             else
     125            0 :                s = "Cannot retrieve MSCB variable \"" + node.m_device + ":" +
     126            0 :                             std::to_string(node.m_address) + ":" + node.m_mscb_var[i].var + "\"";
     127            0 :             mthrow1(s);
     128            0 :          }
     129              : 
     130              :          // retrieve unit from MSCB node
     131            0 :          std::string unit = node.m_mscb->get_unit_short(node.m_mscb_var[i].index);
     132              : 
     133              :          // overwrite if unit has been passed to constructor
     134            0 :          if (!node.m_mscb_var[i].unit.empty())
     135            0 :             unit = node.m_mscb_var[i].unit;
     136              : 
     137              :          // write unit to ODB
     138            0 :          m_settings["Unit MSCB"][n_variables].set_string_size(unit, 32);
     139              : 
     140              :          // write format to ODB
     141            0 :          if (node.m_mscb_var[i].format.empty())
     142            0 :             m_settings["Format MSCB"][n_variables].set_string_size("f2", 32);
     143              :          else
     144            0 :             m_settings["Format MSCB"][n_variables].set_string_size(node.m_mscb_var[i].format, 32);
     145              : 
     146            0 :          n_variables++;
     147            0 :       }
     148              : 
     149              :    }
     150              : 
     151              :    // install callback
     152            0 :    if (n_variables > 0)
     153            0 :       m_variables["MSCB"].watch([this](midas::odb &o) {
     154              : 
     155            0 :          int n_var = 0;
     156              : 
     157              :          // loop over all MSCB nodes
     158            0 :          for (mscb_node &node : m_node) {
     159              :             // loop over all variables for that node
     160            0 :             for (size_t i = 0; i < node.m_mscb_var.size(); i++, n_var++) {
     161              : 
     162            0 :                if (node.m_mscb_var[i].output) {
     163            0 :                   float f = o[n_var];
     164              : 
     165              :                   // check if data differs from mirror
     166            0 :                   if (f != m_mirror[n_var] && !ss_isnan(f)) {
     167              : 
     168              :                      // call confirm function if present
     169            0 :                      if (node.m_mscb_var[i].confirm != nullptr) {
     170            0 :                         bool confirm = node.m_mscb_var[i].confirm(node.m_mscb_var[i], f);
     171            0 :                         if (!confirm)
     172            0 :                            continue;
     173              :                      }
     174              : 
     175              :                      // store data in mirror
     176            0 :                      m_mirror[n_var] = f;
     177              : 
     178              :                      // write data to MSCB node
     179            0 :                      int index = node.m_mscb_var[i].index;
     180            0 :                      std::cout << "Write \"" << f << "\" to " << node.m_device << ":" << node.m_address << ":" << index << std::endl;
     181              : 
     182            0 :                      (*node.m_mscb)[index] = f;
     183              :                   }
     184              :                }
     185              :             }
     186              :          }
     187            0 :       });
     188              : }
     189              : 
     190            0 : void mdev_mscb::exit(void) {
     191            0 : }
     192              : 
     193            0 : void mdev_mscb::loop(void) {
     194              : 
     195              :    // read input values once per second
     196            0 :    if (ss_millitime() - m_readout_last  > m_readout_period) {
     197              : 
     198            0 :       if (!m_common["Enabled"])
     199            0 :          return;
     200              : 
     201              :       // read all nodes
     202            0 :       int n_var = 0;
     203            0 :       std::string error_message = "";
     204            0 :       for (auto node : m_node) {
     205              : 
     206              :          // skip disabled nodes
     207            0 :          if (!node.m_enabled) {
     208            0 :             n_var += node.m_mscb_var.size();
     209            0 :             continue;
     210              :          }
     211              : 
     212              :          // read all node variables
     213            0 :          auto status = node.m_mscb->read_range();
     214            0 :          if (status != MSCB_SUCCESS) {
     215            0 :             for (size_t i = 0; i < node.m_mscb_var.size(); i++) {
     216            0 :                m_mirror[n_var] = (float) ss_nan();
     217            0 :                m_variables["MSCB"][n_var] = (float) ss_nan();
     218            0 :                n_var++;
     219              :             }
     220              : 
     221            0 :             error_message = "Communication error with \"" +
     222            0 :                             node.m_mscb->get_submaster() + ":" +
     223            0 :                             std::to_string(node.m_mscb->get_node_address()) + "\"";
     224              : 
     225              :          } else { // status == MSCB_SUCCESS
     226              : 
     227              :             // read all variables from MSCB
     228            0 :             for (size_t i = 0; i < node.m_mscb_var.size(); i++) {
     229            0 :                float f = (*node.m_mscb)[node.m_mscb_var[i].index];
     230            0 :                if (node.m_mscb_var[i].convert != nullptr) {
     231            0 :                   f = node.m_mscb_var[i].convert(f);
     232              :                }
     233              : 
     234            0 :                m_mirror[n_var] = f;
     235            0 :                m_variables["MSCB"][n_var] = f;
     236            0 :                n_var++;
     237              :             }
     238              :          }
     239            0 :       }
     240              : 
     241            0 :       if (!error_message.empty())
     242            0 :          mthrow1(error_message);
     243              : 
     244            0 :       m_readout_last = ss_millitime();
     245            0 :    }
     246              : 
     247              : }
     248              : 
     249            0 : int mdev_mscb::read_event(char *pevent, int off) {
     250              : 
     251            0 :    if (!m_common["Enabled"])
     252            0 :       return 0;
     253              : 
     254              :    float *pdata;
     255              : 
     256              :    // init bank structure
     257            0 :    bk_init32a(pevent);
     258              : 
     259              :    // create a bank with values
     260            0 :    bk_create(pevent, "SMSC", TID_FLOAT, (void **)&pdata);
     261            0 :    for (int i = 0; i < m_n_variables; i++)
     262            0 :       *pdata++ = m_variables["MSCB"][i];
     263            0 :    bk_close(pevent, pdata);
     264              : 
     265            0 :    return bk_size(pevent);
     266              : }
     267              : 
        

Generated by: LCOV version 2.0-1