//OpenSCADA file: tarchives.h /*************************************************************************** * Copyright (C) 2003-2023 by Roman Savochenko, * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; version 2 of the License. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef TARCHIVES_H #define TARCHIVES_H #define SARH_VER 20 //ArchiveS type modules version #define SARH_ID "Archive" #include #include #include "tbds.h" #include "tarchval.h" using std::string; using std::vector; namespace OSCADA { //************************************************ //* Message archiver * //************************************************ //************************************************ //* TMArchivator * //************************************************ class TTypeArchivator; class TMArchivator : public TCntrNode, public TConfig { friend class TArchiveS; public: //Public methods TMArchivator( const string &id, const string &db, TElem *cf_el ); TCntrNode &operator=( const TCntrNode &node ); string id( ) { return mId; } string workId( ); string name( ); string dscr( ) { return cfg("DESCR").getS(); } bool toStart( ) { return mStart; } bool startStat( ) const { return runSt; } string addr( ) const { return cfg("ADDR").getS(); } int level( ) { return mLevel; } void categ( vector &list ); string DB( bool qTop = false ) const { return storage(mDB, qTop); } string tbl( ); string fullDB( bool qTop = false ) { return DB(qTop)+'.'+tbl(); } void setName( const string &vl ) { cfg("NAME").setS(vl); } void setDscr( const string &vl ) { cfg("DESCR").setS(vl); } void setToStart( bool vl ) { mStart = vl; modif(); } void setAddr( const string &vl ) { cfg("ADDR").setS(vl); } void setLevel( int lev ) { mLevel = lev; } void setDB( const string &vl, bool qTop = false ) { setStorage(mDB, vl, qTop); if(!qTop) modifG(); } // Redundancy time_t redntTm( ) { return lstRdMess.time; } //Time of the last redundancy operation // In redundancy now bool redntUse( ) { return mRdUse; } void setRedntUse( bool vl ) { mRdUse = vl; } // Enabled the archiver's redundancy bool redntMode( ) { return cfg("REDNT").getB(); } void setRedntMode( bool vl ) { cfg("REDNT").setB(vl); } // Redundancy condition: , , , {ForceStation} string redntRun( ) { return cfg("REDNT_RUN").getS(); } void setRedntRun( const string &vl ) { cfg("REDNT_RUN").setS(vl); } virtual void redntDataUpdate( ); virtual void start( ); virtual void stop( ); virtual time_t begin( ) { return 0; } virtual time_t end( ) { return 0; } virtual bool put( vector &mess, bool force = false ); // mostly used by redundancy to prevent cycling virtual time_t get( time_t bTm, time_t eTm, vector &mess, const string &category = "", char level = 0, time_t upTo = 0 ) { return 0; }; TTypeArchivator &owner( ) const; protected: //Protected methods void cntrCmdProc( XMLNode *opt ); //Control interface command process void postEnable( int flag ); void preDisable( int flag ); void postDisable( int flag ); //Delete all DB if flag 1 bool cfgChange( TCfg &co, const TVariant &pc ) { modif(); return true; } void load_( TConfig *cfg ); void save_( ); TVariant objFuncCall( const string &id, vector &prms, const string &user_lang ); // Check messages criteries bool chkMessOK( const string &icateg, int8_t ilvl ); //Protected atributes bool runSt; int messHead; //Last read and archived head of messages buffer private: //Private methods const char *nodeName( ) const { return mId.getSd(); } //Private attributes TCfg &mId, //Mess arch id &mLevel; //Mess arch level char &mStart; //Mess arch starting flag string mDB; unsigned mRdUse : 1; unsigned mRdFirst: 1; TMess::SRec lstRdMess; }; //************************************************ //* Archive subsystem * //************************************************ //************************************************ //* TTypeArchivator * //************************************************ class TArchiveS; class TVArchivator; class TTypeArchivator: public TModule { public: //Public methods TTypeArchivator( const string &id ); virtual ~TTypeArchivator( ); // Messages void messList( vector &list ) const { chldList(mMess, list); } bool messPresent( const string &id ) const { return chldPresent(mMess, id); } string messAdd( const string &id, const string &idb = DB_GEN ); void messDel( const string &id, bool full = false ) { chldDel(mMess, id, -1, full?NodeRemove:NodeNoFlg); } AutoHD messAt( const string &id ) const { return chldAt(mMess, id); } // Values void valList( vector &list ) const { chldList(mVal, list); } bool valPresent( const string &id ) const { return chldPresent(mVal, id); } string valAdd( const string &id, const string &idb = DB_GEN ); void valDel( const string &id, bool full = false ) { chldDel(mVal, id, -1, full?NodeRemove:NodeNoFlg); } AutoHD valAt( const string &id ) const { return chldAt(mVal, id); } TArchiveS &owner( ) const; protected: //Protected methods void cntrCmdProc( XMLNode *opt ); //Control interface command process virtual TMArchivator *AMess( const string &id, const string &stor ) { throw TError(nodePath().c_str(),_("Message archiver is not supported!")); } virtual TVArchivator *AVal( const string &id, const string &stor ) { throw TError(nodePath().c_str(),_("Value archiver is not supported!")); } private: //Private attributes int mMess, mVal; }; //************************************************ //* TArchiveS * //************************************************ class TVArchive; class TArchiveS : public TSubSYS { friend class TMArchivator; public: //Public data enum AutoIdMode { BothPrmAttrId = 0, OnlyPrmId, OnlyAttrId, AllCntrPrmAttrId }; //Public methods TArchiveS( ); ~TArchiveS( ); string subName( ) const { return _("Archives-History"); } int subVer( ) const { return SARH_VER; } int messPeriod( ) { return mMessPer; } int alarmsClrDays( ) { return mAlarmsClrDays; } int valPeriod( ) { return vmax(1, mValPer); } int valPrior( ) { return mValPrior; } bool valForceCurTm( ) { return mValForceCurTm; } AutoIdMode autoIdMode( ){ return (AutoIdMode)mAutoIdMode; } void setMessPeriod( int ivl ) { mMessPer = ivl; modif(); } void setAlarmsClrDays( int ivl ){ mAlarmsClrDays = vmax(0, vmin(1000,ivl)); modif(); } void setValPeriod( int ivl ) { mValPer = ivl; modif(); } void setValPrior( int ivl ) { mValPrior = vmax(-1, vmin(199,ivl)); modif(); } void setValForceCurTm( bool vl ){ mValForceCurTm = vl; modif(); } void setAutoIdMode( AutoIdMode vl ) { mAutoIdMode = vl; modif(); } void setToUpdate( ) { toUpdate = true; } void unload( ); void subStart( ); void subStop( ); void perSYSCall( unsigned int cnt ); // Value archives functions void valList( vector &list ) const { chldList(mAval, list); } bool valPresent( const string &id ) const { return chldPresent(mAval, id); } string valAdd( const string &id, const string &idb = DB_GEN ); void valDel( const string &id, bool db = false ); AutoHD valAt( const string &id ) const { return chldAt(mAval, id); } void setActMess( TMArchivator *a, bool val ); void setActVal( TVArchive *a, bool val ); // Archivers AutoHD at( const string &name ) const { return modAt(name); } // Message archive function void messPut( time_t tm, int utm, const string &categ, int8_t level, const string &mess, const string &arch = "" ); void messPut( const TMess::SRec &rec, const string &arch = "" ); void messPut( const vector &recs, const string &arch = "" ); time_t messGet( time_t bTm, time_t eTm, vector &recs, const string &category = "", int8_t level = TMess::Debug, const string &arch = "", time_t upTo = 0 ); time_t messBeg( const string &arch = "" ); time_t messEnd( const string &arch = "" ); // Redundancy time_t rdTm( ); //Time of the last redundancy operation bool rdProcess( XMLNode *reqSt = NULL ); double rdRestDtOverTm( ) { return mRdRestDtOverTm; } //In days void setRdRestDtOverTm( double vl ) { mRdRestDtOverTm = vmin(356, vmax(0,vl)); modif(); } void rdActArchMList( vector &ls, bool isRun = false ); string rdStRequest( const string &arch, XMLNode &req, const string &prevSt = "", bool toRun = true ); TElem &messE( ) { return elMess; } TElem &valE( ) { return elVal; } TElem &aValE( ) { return elAval; } //Public attributes bool subStarting; protected: //Protected methods void load_( ); void save_( ); private: //Private methods string optDescr( ); static void *ArhMessTask( void *param ); static void *ArhValTask( void *param ); void cntrCmdProc( XMLNode *opt ); //Control interface command process TVariant objFuncCall( const string &id, vector &prms, const string &user_lang ); unsigned messBufLen( ) { return mBuf.size(); } void setMessBufLen( unsigned len ); //Private attributes TElem elMess, //Message archiver's DB elements elVal, //Value archivator's DB elements elAval; //Value archives DB elements // Messages archiving int mMessPer; //Message archiving period bool prcStMess; //Process messages flag // Messages buffer ResMtx mRes; //Mess access resource unsigned headBuf; //Head of messages buffer vector mBuf; //Messages buffer map mAlarms;//Alarms buffer int mAlarmsClrDays; //Days of the alarms automatic clearing // Value archiving ResMtx vRes; //Value access resource int mValPer, //Value archiving period mValPrior, //Value archive task priority mAval, mAutoIdMode; bool mValForceCurTm, //Time of taken values force to current and overide it's source from prcStVal, //Process value flag endrunReqVal, //Endrun value request toUpdate; vector > actMess; vector > actVal; // Redundancy ResRW mRdRes; double mRdRestDtOverTm; //Overtime of the redundant history reload at start in hours map > mRdArchM; time_t mRdAlarms; }; } #endif // TARCHIVES_H