Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

monitor_point.cc

00001 /**********************************************************************/
00002 /*  Class MonitorPoint:- access a monitor point via an AT Dataset.    */
00003 /*                                           */
00004 /*                                                                    */
00005 /*                                          Simon Hoyle               */
00006 /*                      -2002                 */
00007 /**********************************************************************/
00008 
00009 
00010 #include <iostream>
00011 #ifdef SOLARIS
00012 #include <stdio.h>
00013 #endif
00014 #include <cstring>
00015 #include <ctype.h>
00016 #include <assert.h>
00017 
00018 #include "monitor_point.h"
00019 #include "dataset.h"
00020 
00021 using namespace std;
00022 
00023 bool MonitorPoint::debugAll = false;
00024 
00025 
00026 MonitorPoint::MonitorPoint(CommsDevice* cd) : commsDev(cd)
00027 { 
00028     memset(valStr, 0, 30);
00029     memset(timestamp, 0, 15);
00030     memset(response, 0, 120);
00031     dbp.offset = 0.0;
00032     dbp.scale = 1.0;
00033     mask = 0xFFFF;
00034     lineariser = NULL;
00035     upperLimitReached = lowerLimitReached = false;
00036     maxVal = minVal = 0.0;
00037     memset(maxTime, 0, 15);
00038     memset(minTime, 0, 15);
00039 }
00040 
00041 MonitorPoint::MonitorPoint(const char* name, CommsDevice* cd) : commsDev(cd)
00042 {
00043     strncpy(dbp.name, name, 39);
00044     memset(valStr, 0, 30);
00045     memset(timestamp, 0, 15);
00046     memset(response, 0, 120);
00047     dbp.offset = 0.0;
00048     dbp.scale = 1.0;
00049     mask = 0xFFFF;
00050     lineariser = NULL;
00051     upperLimitReached = lowerLimitReached = false;
00052     maxVal = minVal = 0.0;
00053     memset(maxTime, 0, 15);
00054     memset(minTime, 0, 15);
00055 }
00056 
00057 MonitorPoint::~MonitorPoint() { }
00058 
00059 int MonitorPoint::init(const char* dbLine)
00060 {
00061     int status = parseDbLine(dbLine);
00062     commDevType = DATASET;
00063     primaryAddr = Dataset::MONITOR | (dbp.ds_addr << 25) | ((dbp.dsOp + dbp.pt_addr) << 16);
00064     if (debugAll || debug)
00065     {
00066         cout << "MonitorPoint:" << dbp.name
00067         << ":init: " << "dbParams=" << endl;
00068         printDbParams();
00069         cout << endl;
00070     }
00071     switch (dbp.dsCat) {
00072         case Dataset::BIT1 : mask = 0x0001; break;
00073         case Dataset::REG8 : mask = 0x00FF; break;
00074         case Dataset::REG16: mask = 0xFFFF; break;
00075         default: break;
00076     }
00077     minVal = dbp.lower; maxVal = dbp.upper;
00078     return status;
00079 }
00080 
00081 void MonitorPoint::init(Dataset::Op_t dsOp, Dataset::Cat_t dsCat, int dsAddr, int ptAddr, 
00082                         char* format, int interval, bool enabled, char* desc)
00083 {
00084     dbp.dsOp = dsOp;
00085     strcpy(dbp.op, "-\0");
00086     dbp.dsCat = dsCat;
00087     dbp.ds_addr = dsAddr;
00088     dbp.pt_addr = ptAddr;
00089     dbp.scale = 1.0;
00090     dbp.offset = 0.0;
00091     strncpy(dbp.format, format, 7);
00092     dbp.interval = interval;
00093     dbp.enabled = enabled;
00094     strncpy(dbp.desc, desc, 59);
00095     commDevType = DATASET;
00096     primaryAddr = Dataset::MONITOR | (dbp.ds_addr << 25) | ((dbp.dsOp + dbp.pt_addr) << 16);
00097     switch (dbp.dsCat) {
00098         case Dataset::BIT1 : mask = 0x0001; break;
00099         case Dataset::REG8 : mask = 0x00FF; break;
00100         case Dataset::REG16: mask = 0xFFFF; break;
00101         default: break;
00102     }
00103     if (debugAll || debug)
00104     {
00105         cout << "MonitorPoint:" << dbp.name
00106         << ":init: " << "dbParams=" << endl;
00107         printDbParams();
00108         cout << endl;
00109     }
00110 }
00111 
00112 int MonitorPoint::initComms()
00113 {
00114     return commsDev->init(primaryAddr);
00115 }
00116 
00117 bool MonitorPoint::hasID(const char* id)
00118 {
00119     if (strncmp(id, dbp.name, strlen(dbp.name)) == 0) 
00120         return true;
00121     return false;
00122 }
00123 
00124 const char* MonitorPoint::read()
00125 {
00126     readTime = time(NULL);
00127     strftime(timestamp, 14, "%H:%M:%S", gmtime(&readTime));
00128   
00129     if (dbp.dsCat == Dataset::ANALOG)
00130     {
00131         status = commsDev->mon(primaryAddr, &fval);
00132         if (status == 0)
00133         {
00134             fval *= dbp.scale; fval += dbp.offset;
00135             if (lineariser != NULL)    
00136                 fval = (*lineariser)(fval);
00137             sprintf(valStr, dbp.format, fval);
00138             checkLimits(fval);
00139         }
00140         else
00141         {
00142             sprintf(valStr, "%s", commsDev->getErrMsg(status));
00143             if (debug || debugAll)
00144                 cerr << "MonitorPoint:" << dbp.name 
00145                 << ":read: " << commsDev->getErrMsg(status) << endl;
00146         }
00147     }
00148     else
00149     {
00150        status = commsDev->mon(primaryAddr, &ival);
00151         if (status == 0)
00152             sprintf(valStr, dbp.format, ival & mask);
00153         else
00154         {
00155             sprintf(valStr, "%s", commsDev->getErrMsg(status));
00156             if (debug || debugAll)
00157                 cerr << "MonitorPoint:" << dbp.name 
00158                 << ":read: " << commsDev->getErrMsg(status) << endl;
00159         }
00160     }
00161     sprintf(response, "%s\t%s\t%s", dbp.name, valStr, timestamp);
00162     return response;
00163 }
00164 
00165 const char* MonitorPoint::read(const char* id)
00166 {
00167     if (!hasID(id)) 
00168     {
00169         sprintf(response, "<ERR>\t%s is not %s", dbp.name, id);
00170         return response;
00171     }
00172 
00173     readTime = time(NULL);
00174     strftime(timestamp, 14, "%H:%M:%S", gmtime(&readTime));
00175   
00176     if (dbp.dsCat == Dataset::ANALOG)
00177     {
00178         status = commsDev->mon(primaryAddr, &fval);
00179         if (status == 0)
00180         {
00181             fval *= dbp.scale; fval += dbp.offset;
00182             if (lineariser != NULL)    
00183                 fval = (*lineariser)(fval);
00184             sprintf(valStr, dbp.format, fval);
00185             checkLimits(fval);
00186         }
00187         else
00188         {
00189             sprintf(valStr, "%s", commsDev->getErrMsg(status));
00190             if (debug || debugAll)
00191                 cerr << "MonitorPoint:" << dbp.name 
00192                 << ":read: " << commsDev->getErrMsg(status) << endl;
00193         }
00194     }
00195     else
00196     {
00197         status = commsDev->mon(primaryAddr, &ival, Dataset::LONG_TIMEOUT);
00198         if (status == 0)
00199         {
00200             ival &= mask;
00201             sprintf(valStr, dbp.format, ival);
00202         }
00203         else
00204         {
00205             sprintf(valStr, "%s", commsDev->getErrMsg(status));
00206             if (debug || debugAll)
00207                 cerr << "MonitorPoint:" << dbp.name 
00208                 << ":read: " << commsDev->getErrMsg(status) << endl;
00209         }
00210     }
00211 
00212     if (status == 0)
00213         sprintf(response, "<OK>\t%s\t%s\t%s", dbp.name, valStr, timestamp);
00214     else
00215         sprintf(response, "<ERR>\t%s\t%s\t%s", dbp.name, valStr, timestamp);
00216 
00217     return response;   
00218 }
00219 
00220 int MonitorPoint::read(int* val)
00221 {
00222     assert(dbp.dsCat != Dataset::ANALOG);
00223     readTime = time(NULL);
00224     strftime(timestamp, 14, "%H:%M:%S", gmtime(&readTime));
00225     status = commsDev->mon(primaryAddr, &ival);
00226     if (status == 0) 
00227     {
00228         ival &= mask;
00229         *val = ival;
00230     }
00231     return status;       
00232 }
00233 
00234 int MonitorPoint::read(float* val)
00235 {
00236     assert(dbp.dsCat == Dataset::ANALOG);
00237     readTime = time(NULL);
00238     strftime(timestamp, 14, "%H:%M:%S", gmtime(&readTime));
00239     status = commsDev->mon(primaryAddr, &fval);;
00240     if (status == 0)
00241     {
00242         fval *= dbp.scale; fval += dbp.offset;
00243         if (lineariser != NULL)    
00244             fval = (*lineariser)(fval);
00245         *val = fval;
00246         checkLimits(fval);
00247     }
00248     return status;
00249 }
00250 
00251 void MonitorPoint::add(MonitorPoint::LinearFunc l)
00252 {
00253     lineariser = l;
00254 }
00255 
00256 const char* MonitorPoint::getID()
00257 {
00258     return dbp.name;
00259 }
00260 
00261 int MonitorPoint::getStatus()
00262 {
00263     return status;
00264 }
00265 
00266 float MonitorPoint::getFval()
00267 {
00268     return fval;
00269 }
00270 
00271 int MonitorPoint::getIval()
00272 {
00273     return ival;
00274 }
00275 
00276 const char* MonitorPoint::getFormattedVal()
00277 {
00278     static char val[15] = { 0 };
00279 
00280     if (dbp.dsCat == Dataset::ANALOG)
00281         sprintf(val, dbp.format, fval);
00282     else
00283         sprintf(val, dbp.format, ival);
00284     return val;
00285 }
00286 
00287 int MonitorPoint::getInterval()
00288 {
00289     return dbp.interval;
00290 }
00291 
00292 int MonitorPoint::getRefNum()
00293 {
00294     return dbp.refNum;
00295 }
00296 
00297 int MonitorPoint::getPrimaryAddress()
00298 {
00299     return primaryAddr;
00300 }
00301 
00302 CommsDevice* MonitorPoint::getCommsDev()
00303 {
00304     return commsDev;
00305 }
00306 
00307 CommsDevice::State MonitorPoint::getState()
00308 {
00309     return commsDev->getState();
00310 }
00311 
00312 const char* MonitorPoint::getTimestamp()
00313 {
00314     return timestamp;
00315 }
00316 
00317 const char* MonitorPoint::getFormat()
00318 {
00319     return dbp.format;
00320 }
00321 
00322 float MonitorPoint::getMaxVal() 
00323 { 
00324     float max = maxVal;
00325     maxVal = dbp.upper;
00326     return max; 
00327 }
00328 
00329 float MonitorPoint::getMinVal() 
00330 { 
00331     float min = minVal;
00332     minVal = dbp.lower;
00333     return min; 
00334 }
00335 
00336 bool MonitorPoint::hasExceededUpperLimit()
00337 {
00338     if (upperLimitReached)
00339     {
00340         upperLimitReached = false;
00341         return true;
00342     }
00343     return false;
00344 }
00345 
00346 bool MonitorPoint::hasExceededLowerLimit()
00347 {
00348     if (lowerLimitReached)
00349     {
00350         lowerLimitReached = false;
00351         return true;
00352     }
00353     return false;
00354 }
00355 
00356 void MonitorPoint::prependID(const char* str)
00357 {
00358     static char tmp[40] = { 0 };
00359 
00360     strncpy(tmp, str, 10);
00361     strncat(tmp, dbp.name, 29);
00362     strcpy(dbp.name, tmp);
00363 }
00364 
00365 bool MonitorPoint::isEnabled()
00366 {
00367     return dbp.enabled;
00368 }
00369 
00370 void MonitorPoint::setEnabled(bool onOff)
00371 {
00372     dbp.enabled = onOff;
00373 }
00374 
00375 void MonitorPoint::setLimits(float lower, float upper)
00376 {
00377     assert(lower < upper);
00378     dbp.lower = lower;
00379     minVal = lower;
00380     dbp.upper = upper;
00381     maxVal = upper;
00382 }
00383 
00384 void MonitorPoint::checkLimits(float fval)
00385 {
00386     if (fval > dbp.upper)
00387     {
00388         upperLimitReached = true;
00389         if (fval > maxVal)
00390         {
00391             maxVal = fval;
00392             strftime(maxTime, 14, "%H:%M:%S", localtime(&readTime));
00393         }
00394     }
00395     else if (fval < dbp.lower)
00396     {
00397         lowerLimitReached = true;
00398         if (fval < minVal)
00399         {
00400             minVal = fval;
00401             //cout << "MonitorPoint:" << dbp.name << ": minVal = " << minVal << endl;
00402             strftime(minTime, 14, "%H:%M:%S", localtime(&readTime));
00403         }
00404     }
00405 }
00406 
00407 void MonitorPoint::printDbParams()
00408 {
00409     cout << dbp.refNum << ' ' << dbp.name << endl;
00410     cout << '\t' << "op: " << dbp.op << ' ';
00411     cout << "dsOp: " << dbp.dsOp << ' ';
00412     cout << "dsCat: " << dbp.dsCat << ' ';
00413     cout << "ds_addr: " << dbp.ds_addr << ' ';
00414     cout << "pt_addr: " << dbp.pt_addr << ' ';
00415     cout << "scale: " << dbp.scale << ' ';
00416     cout << "offset: " << dbp.offset << endl;
00417     cout << '\t' << "format: " << dbp.format << ' ';
00418     cout << "interval: " << dbp.interval << ' ';
00419     cout << "enabled: " << dbp.enabled << ' ';
00420     cout << "lower: " << dbp.lower << ' ';
00421     cout << "upper: " << dbp.upper << ' ';
00422     cout << "units: " << dbp.units << endl;
00423     cout << " desc: " << dbp.desc << endl;
00424 }
00425 
00426 int MonitorPoint::parseDbLine(const char* dbLine)
00427 {
00428     char enabled[2];
00429     char* start;
00430     char* end;
00431 
00432     if (debug || debugAll)
00433     {
00434         cout << "MonitorPoint:" << dbp.name
00435         << ":parseDbLine: dbLine=" << endl << dbLine << endl;
00436     }
00437     int n = sscanf(dbLine, "%u%s%s%d%d%f%f%s%d%s%f%f%s", &dbp.refNum, dbp.name,
00438                    dbp.op, &dbp.ds_addr, &dbp.pt_addr, &dbp.scale, 
00439                    &dbp.offset, dbp.format, &dbp.interval,
00440                enabled, &dbp.lower, &dbp.upper, dbp.units);
00441     if (n < 13)
00442     {
00443         if (debug || debugAll)
00444         {
00445             cerr << "MonitorPoint:" << dbp.name
00446             << ":parseDbLine: Failed to scan all fields (scanned " 
00447             << n << " of 13):" << endl << dbLine << endl;
00448             printDbParams();
00449         }
00450         return -1;
00451     }   
00452     dbp.dsOp = Dataset::strToOp(dbp.op);
00453     dbp.dsCat = Dataset::strToCat(dbp.op); 
00454     start = strchr(dbLine, '\"');  
00455     if (start != NULL)
00456     {
00457         end = strrchr(dbLine, '\"');
00458     if (end != NULL)
00459         {
00460         int n = end - start - 1;
00461         if (n > 0) memcpy(dbp.desc, start + 1, n);
00462         }
00463     }       
00464     dbp.enabled = (enabled[0] == 'Y'); 
00465     return 0;
00466 }
00467 
00468 

Generated on Mon Apr 30 13:32:36 2007 for Parkes M & C - PKMC C++ library API by  doxygen 1.4.4