LCOV - code coverage report
Current view: top level - drivers/device - mdevice.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 87 0
Test Date: 2025-11-11 10:26:08 Functions: 0.0 % 3 0

            Line data    Source code
       1              : /*
       2              :    mdevice.h
       3              : 
       4              :    Base class mdevice to create proper ODB settings under
       5              :    /Equipment/<name>/Settings
       6              : 
       7              :    Derived class mdevice_mscb for MSCB devices
       8              : 
       9              :    Created S. Ritt 11.04.2022
      10              : */
      11              : 
      12              : #include <cmath>
      13              : #include <history.h>
      14              : #include "mstrlcpy.h"
      15              : 
      16              : #define FORMULA_SIZE 64
      17              : 
      18              : //---- generic class ------------------------------------------------
      19              : 
      20              : class mdevice {
      21              : 
      22              : public:
      23              : 
      24              :    EQUIPMENT *mEq;
      25              :    std::string mDevName;
      26              :    std::vector<std::string> mName;
      27              :    midas::odb mOdbDev;
      28              :    midas::odb mOdbSettings;
      29              :    midas::odb mOdbVars;
      30              :    int mDevIndex;
      31              :    int mNchannels;
      32              :    int mNblocks;
      33              :    double mThreshold;
      34              :    double mFactor;
      35              :    double mOffset;
      36              : 
      37              : public:
      38            0 :    mdevice(std::string eq_name, std::string dev_name,
      39              :           DWORD flags,
      40            0 :           INT(*dd) (INT cmd, ...)) {
      41              : 
      42              :       // search equipment in equipment table
      43              :       int idx;
      44            0 :       for (idx = 0; equipment[idx].name[0]; idx++)
      45            0 :          if (equipment[idx].name == eq_name)
      46            0 :             break;
      47            0 :       if (equipment[idx].name[0] == 0) {
      48              :          char str[256];
      49            0 :          snprintf(str, sizeof(str), "Equipment \"%s\" not found in equipment table", eq_name.c_str());
      50            0 :          cm_msg(MERROR, "device::device", "%s", str);
      51            0 :          mthrow(str);
      52              :          return;
      53              :       }
      54            0 :       mEq = &equipment[idx];
      55              : 
      56            0 :       if (mEq->driver == nullptr) { // create new device driver list
      57            0 :          mEq->driver = (DEVICE_DRIVER *) calloc(2, sizeof(DEVICE_DRIVER));
      58            0 :          mDevIndex = 0;
      59              : 
      60              :       } else { // extend existing device driver list
      61              : 
      62              :          // check for double name
      63              :          int n;
      64            0 :          for (n = 0; mEq->driver[n].name[0]; n++) {
      65            0 :             if (mEq->driver[n].name == dev_name) {
      66              :                char str[256];
      67            0 :                snprintf(str, sizeof(str), "Device \"%s\" defined twice for equipment \"%s\"", dev_name.c_str(),
      68              :                        eq_name.c_str());
      69            0 :                cm_msg(MERROR, "device::device", "%s", str);
      70            0 :                mthrow(str);
      71              :                return;
      72              :             }
      73              :          }
      74            0 :          int size = (n + 2) * sizeof(DEVICE_DRIVER);
      75            0 :          mEq->driver = (DEVICE_DRIVER *) realloc(mEq->driver, size);
      76            0 :          memset((void *) &mEq->driver[n + 1], 0, sizeof(DEVICE_DRIVER));
      77            0 :          mDevIndex = n;
      78              :       }
      79              : 
      80            0 :       mstrlcpy(mEq->driver[mDevIndex].name, dev_name.c_str(), sizeof(mEq->driver[mDevIndex].name));
      81            0 :       mDevName = dev_name;
      82            0 :       mEq->driver[mDevIndex].pequipment_name = new std::string(eq_name);
      83            0 :       mEq->driver[mDevIndex].flags = flags;
      84            0 :       mEq->driver[mDevIndex].dd = dd;
      85            0 :       mEq->driver[mDevIndex].channels = 0;
      86            0 :       mNchannels = 0;
      87            0 :       mNblocks = 0;
      88            0 :       mThreshold = 0;
      89            0 :       mFactor = 1;
      90            0 :       mOffset = 0;
      91              : 
      92            0 :       mOdbDev.connect("/Equipment/" + eq_name + "/Settings/Devices/" + dev_name);
      93            0 :       mOdbSettings.connect("/Equipment/" + eq_name + "/Settings");
      94            0 :       mOdbVars.connect("/Equipment/" + eq_name + "/Variables");
      95            0 :    }
      96              : 
      97            0 :    void define_var(std::string name = "", double threshold = std::nan(""),
      98              :                    double factor = std::nan(""), double offset = std::nan(""))
      99              :    {
     100            0 :       int chn_index = 0;
     101              : 
     102              :       // individual variable can overwrite standard value
     103            0 :       if (std::isnan(threshold))
     104            0 :          threshold = mThreshold;
     105            0 :       if (std::isnan(factor))
     106            0 :          factor = mFactor;
     107            0 :       if (std::isnan(offset))
     108            0 :          offset = mOffset;
     109              : 
     110              :       // put info into settings subtree
     111            0 :       if (mEq->driver[mDevIndex].flags & DF_INPUT) {
     112              :          // count total number of input channels
     113            0 :          for (int i=0 ; i <= mDevIndex ; i++)
     114            0 :             if (mEq->driver[i].flags & DF_INPUT)
     115            0 :                chn_index += mEq->driver[i].channels;
     116              : 
     117            0 :          mOdbSettings["Update Threshold"][chn_index] = (float) threshold;
     118            0 :          mOdbSettings["Input Factor"][chn_index] = (float) factor;
     119            0 :          mOdbSettings["Input Offset"][chn_index] = (float) offset;
     120            0 :          mOdbSettings["Names Input"][chn_index].set_string_size(name, 32);
     121            0 :          mName.push_back(name);
     122              : 
     123            0 :          std::vector<float> inp = mOdbVars["Input"];
     124            0 :          if ((int)inp.size() < chn_index+1) {
     125            0 :             inp.resize(chn_index+1);
     126            0 :             mOdbVars["Input"] = inp;
     127              :          }
     128            0 :       }
     129              : 
     130            0 :       else if (mEq->driver[mDevIndex].flags & DF_OUTPUT) {
     131              :          // count total number of output channels
     132            0 :          for (int i=0 ; i <= mDevIndex ; i++)
     133            0 :             if (mEq->driver[i].flags & DF_OUTPUT)
     134            0 :                chn_index += mEq->driver[i].channels;
     135              : 
     136            0 :          mOdbSettings["Output Factor"][chn_index] = (float) factor;
     137            0 :          mOdbSettings["Output Offset"][chn_index] = (float) offset;
     138            0 :          mOdbSettings["Names Output"][chn_index].set_string_size(name, 32);
     139            0 :          mName.push_back(name);
     140              : 
     141            0 :          std::vector<float> outp = mOdbVars["Output"];
     142            0 :          if ((int)outp.size() < chn_index+1) {
     143            0 :             outp.resize(chn_index+1);
     144            0 :             mOdbVars["Output"] = outp;
     145              :          }
     146            0 :       }
     147              : 
     148              :       else {
     149              :          // count total number of channels
     150            0 :          for (int i=0 ; i <= mDevIndex ; i++)
     151            0 :             chn_index += mEq->driver[i].channels;
     152              : 
     153            0 :          mOdbSettings["Names"][chn_index].set_string_size(name, 32);
     154            0 :          mName.push_back(name);
     155              :       }
     156              : 
     157            0 :       mEq->driver[mDevIndex].channels++;
     158            0 :       mNchannels++;
     159            0 :    }
     160              : 
     161              :    void define_varf(std::string name = "", double threshold = std::nan(""),
     162              :                    std::string formula = "", std::string unit = "")
     163              :    {
     164              :       int chn_index = 0;
     165              : 
     166              :       // individual variable can overwrite standard value
     167              :       if (std::isnan(threshold))
     168              :          threshold = mThreshold;
     169              : 
     170              :       // put info into settings subtree
     171              :       if (mEq->driver[mDevIndex].flags & DF_INPUT) {
     172              :          // count total number of input channels
     173              :          for (int i=0 ; i <= mDevIndex ; i++)
     174              :             if (mEq->driver[i].flags & DF_INPUT)
     175              :                chn_index += mEq->driver[i].channels;
     176              : 
     177              :          mOdbSettings["Update Threshold"][chn_index] = (float) threshold;
     178              :          mOdbSettings["Input Formula"][chn_index].set_string_size(formula, FORMULA_SIZE);
     179              :          mOdbSettings["Input Unit"][chn_index].set_string_size(unit, 32);
     180              :          mOdbSettings["Names Input"][chn_index].set_string_size(name, 32);
     181              :          mName.push_back(name);
     182              : 
     183              :          std::vector<float> inp = mOdbVars["Input"];
     184              :          if ((int)inp.size() < chn_index+1) {
     185              :             inp.resize(chn_index+1);
     186              :             mOdbVars["Input"] = inp;
     187              :          }
     188              :       }
     189              : 
     190              :       else if (mEq->driver[mDevIndex].flags & DF_OUTPUT) {
     191              :          // count total number of output channels
     192              :          for (int i=0 ; i <= mDevIndex ; i++)
     193              :             if (mEq->driver[i].flags & DF_OUTPUT)
     194              :                chn_index += mEq->driver[i].channels;
     195              : 
     196              :          mOdbSettings["Output Formula"][chn_index] = formula;
     197              :          mOdbSettings["Input Unit"][chn_index].set_string_size(unit, 32);
     198              :          mOdbSettings["Names Output"][chn_index].set_string_size(name, 32);
     199              :          mName.push_back(name);
     200              : 
     201              :          std::vector<float> outp = mOdbVars["Output"];
     202              :          if ((int)outp.size() < chn_index+1) {
     203              :             outp.resize(chn_index+1);
     204              :             mOdbVars["Output"] = outp;
     205              :          }
     206              :       }
     207              : 
     208              :       else {
     209              :          // count total number of channels
     210              :          for (int i=0 ; i <= mDevIndex ; i++)
     211              :             chn_index += mEq->driver[i].channels;
     212              : 
     213              :          mOdbSettings["Names"][chn_index].set_string_size(name, 32);
     214              :          mName.push_back(name);
     215              :       }
     216              : 
     217              :       mEq->driver[mDevIndex].channels++;
     218              :       mNchannels++;
     219              :    }
     220              : 
     221              :    void add_func(void func(midas::odb &)) {
     222              :       mOdbVars["Input"].watch(func);
     223              :    }
     224              : 
     225              :    midas::odb *odbDevice()
     226              :    {
     227              :       return &mOdbDev;
     228              :    }
     229              : 
     230              :    void define_param(int i, std::string name, std::string str)
     231              :    {
     232              :       mOdbDev[name][i].set_string_size(str, 32);
     233              :    }
     234              : 
     235              :    void define_param(int i, std::string name, int p)
     236              :    {
     237              :       mOdbDev[name][i] = p;
     238              :    }
     239              : 
     240            0 :    void define_history_panel(std::string panelName, int i1, int i2 = -1)
     241              :    {
     242            0 :       std::vector<std::string> vars;
     243              : 
     244            0 :       if (i2 == -1)
     245            0 :          vars.push_back(mEq->name + std::string(":") + mName[i1]);
     246              :       else
     247            0 :          for (int i=i1 ; i<=i2 ; i++)
     248            0 :             vars.push_back(mEq->name + std::string(":") + mName[i]);
     249              : 
     250            0 :       hs_define_panel(mEq->name, panelName.c_str(), vars);
     251            0 :    }
     252              : 
     253              :    void define_history_panel(std::string panelName, std::vector<std::string> vars)
     254              :    {
     255              :       for (std::size_t i=0 ; i<vars.size() ; i++)
     256              :          if (vars[i].find(":") == std::string::npos)
     257              :             vars[i] = std::string(mEq->name) + ":" + vars[i];
     258              :       hs_define_panel(mEq->name, panelName.c_str(), vars);
     259              :    }
     260              : 
     261              :    void set_threshold(double threshold)
     262              :    {
     263              :       mThreshold = threshold;
     264              :    }
     265              : 
     266              :    void set_factor_offset(double factor, double offset)
     267              :    {
     268              :       mFactor = factor;
     269              :       mOffset = offset;
     270              :    }
     271              : 
     272              : };
        

Generated by: LCOV version 2.0-1