UniSet  1.7.0
MTR.h
00001 // --------------------------------------------------------------------------
00002 // --------------------------------------------------------------------------
00003 #ifndef _MTR_H_
00004 #define _MTR_H_
00005 // -----------------------------------------------------------------------------
00006 #include <string>
00007 #include <map>
00008 #include <list>
00009 #include <ostream>
00010 #include <cstring>
00011 #include <cmath>
00012 #include "modbus/ModbusTypes.h"
00013 #include "ComPort.h"
00014 // -----------------------------------------------------------------------------
00015 class ModbusRTUMaster;
00016 // -----------------------------------------------------------------------------
00017 namespace MTR
00018 {
00019     // реализованные в данном интерфейсе типы данных
00020     enum MTRType
00021     {
00022         mtUnknown,
00023         mtT1,
00024         mtT2,
00025         mtT3,
00026         mtT4,
00027         mtT5,
00028         mtT6,
00029         mtT7,
00030         mtT8,
00031         mtT9,
00032         mtT10,
00033         mtT16,
00034         mtT17,
00035         mtF1,
00036         mtT_Str16,
00037         mtT_Str8
00038     };
00039     // -------------------------------------------------------------------------
00040     std::string type2str( MTRType t );          
00041     MTRType str2type( const std::string& s );   
00042     int wsize( MTRType t );                     
00043     // -------------------------------------------------------------------------
00044     // Информация
00045     const ModbusRTU::ModbusData regModelNumber  = 0x01;
00046     const ModbusRTU::ModbusData regSerialNumber = 0x09;
00047     
00048     std::string getModelNumber( ModbusRTUMaster* mb, ModbusRTU::ModbusAddr addr );
00049     std::string getSerialNumber( ModbusRTUMaster* mb, ModbusRTU::ModbusAddr addr );
00050     // -------------------------------------------------------------------------
00051     // Настройки связи (чтение - read03, запись - write06)
00052     const ModbusRTU::ModbusData regUpdateConfiguration = 53;
00053     const ModbusRTU::ModbusData regAddress      = 55;
00054     const ModbusRTU::ModbusData regBaudRate     = 56;
00055     const ModbusRTU::ModbusData regStopBit      = 57; /* 0 - Stop bit, 1 - Stop bits */
00056     const ModbusRTU::ModbusData regParity       = 58;
00057     const ModbusRTU::ModbusData regDataBits     = 59;
00058 
00059     enum mtrBaudRate
00060     {
00061         br1200      = 0,
00062         br2400      = 1,
00063         br4800      = 2,
00064         br9600      = 3,
00065         br19200     = 4,
00066         br38400     = 5,
00067         br57600     = 6,
00068         br115200    = 7
00069     };
00070     
00071     enum mtrParity
00072     {
00073         mpNoParity      = 0,
00074         mpOddParity     = 1,
00075         mpEvenParity    = 2
00076     };
00077 
00078     enum mtrDataBits
00079     {
00080         db8Bits = 0,
00081         db7Bits = 1
00082     };
00083 
00084     bool setAddress( ModbusRTUMaster* mb, ModbusRTU::ModbusAddr addr, ModbusRTU::ModbusAddr newAddr );
00085     bool setBaudRate( ModbusRTUMaster* mb, ModbusRTU::ModbusAddr addr, mtrBaudRate br );
00086     bool setStopBit( ModbusRTUMaster* mb, ModbusRTU::ModbusAddr addr, bool state );
00087     bool setParity( ModbusRTUMaster* mb, ModbusRTU::ModbusAddr addr, mtrParity p );
00088     bool setDataBits( ModbusRTUMaster* mb, ModbusRTU::ModbusAddr addr, mtrDataBits d );
00089     ComPort::Parity get_parity( ModbusRTU::ModbusData data );
00090     ComPort::Speed get_speed( ModbusRTU::ModbusData data );
00091     // -------------------------------------------------------------------------
00092     enum MTRError
00093     {
00094         mtrNoError,
00095         mtrBadDeviceType,
00096         mtrDontReadConfile,
00097         mtrSendParamFailed,
00098         mtrUnknownError
00099     };
00100     std::ostream& operator<<(std::ostream& os, MTRError& e );
00101     // Настройка из конф. файла
00102     MTRError update_configuration( ModbusRTUMaster* mb, ModbusRTU::ModbusAddr addr, 
00103                     const std::string& mtrconfile, int verbose=0 );
00104     // ---------------------------
00105     // вспомогательные функции и типы данных
00106     typedef std::list<ModbusRTU::ModbusData> DataList;
00107     typedef std::map<ModbusRTU::ModbusData,DataList> DataMap;
00108     const int attempts = 3; //
00109     static const ModbusRTU::ModbusData skip[] = {48, 49, 59};  // registers which should not write
00110 
00111     bool send_param( ModbusRTUMaster* mb, DataMap& dmap, ModbusRTU::ModbusAddr addr, int verb );
00112     bool read_param( const std::string& str, std::string& str1, std::string& str2 );
00113     DataMap read_confile( const std::string& f );
00114     void update_communication_params( ModbusRTU::ModbusAddr reg, ModbusRTU::ModbusData data,
00115                   ModbusRTUMaster* mb, ModbusRTU::ModbusAddr& addr, int verb );
00116     // -------------------------------------------------------------------------
00117     static const int u2size = 2;
00118     // -------------------------------------------------------------------------
00119     class T1
00120     {
00121         public:
00122             T1():val(0){}
00123             T1( unsigned short v ):val(v){}
00124             T1( const ModbusRTU::ModbusData* data ):val(data[0]){}
00125             ~T1(){}
00126             // ------------------------------------------
00128             static int wsize(){ return 1; }
00130             static MTRType type(){ return mtT1; }
00131             // ------------------------------------------
00132             unsigned short val;
00133     };  
00134     std::ostream& operator<<(std::ostream& os, T1& t );
00135     // -------------------------------------------------------------------------
00136     class T2
00137     {
00138         public:
00139             T2():val(0){}
00140             T2( signed short v ):val(v){}
00141             T2( const ModbusRTU::ModbusData* data ):val(data[0]){}
00142             ~T2(){}
00143             // ------------------------------------------
00145             static int wsize(){ return 1; }
00147             static MTRType type(){ return mtT2; }
00148             // ------------------------------------------
00149             signed short val;
00150     };
00151     std::ostream& operator<<(std::ostream& os, T2& t );
00152     // -------------------------------------------------------------------------
00153     class T3
00154     {
00155         public:
00156             // ------------------------------------------
00158             typedef union
00159             {
00160                 unsigned short v[u2size];
00161                 signed int val; // :32
00162             } T3mem; 
00163             // ------------------------------------------
00164             // конструкторы на разные случаи...
00165             T3(){ memset(raw.v,0,sizeof(raw.v)); }
00166             
00167             T3( signed int i ){ raw.val = i; }
00168 
00169             T3( unsigned short v1, unsigned short v2 )
00170             {
00171                 raw.v[0] = v1;
00172                 raw.v[1] = v2;
00173             }
00174             
00175             T3( const ModbusRTU::ModbusData* data, int size )
00176             {
00177                 if( size >= u2size )
00178                 {
00179                     // У MTR обратный порядок слов в ответе
00180                     raw.v[0] = data[1];
00181                     raw.v[1] = data[0];
00182                 }
00183             }
00184 
00185             ~T3(){}
00186             // ------------------------------------------
00188             static int wsize(){ return u2size; }
00190             static MTRType type(){ return mtT3; }
00191             // ------------------------------------------
00192             // функции преобразования к разным типам
00193             operator long() { return raw.val; }
00194 
00195             T3mem raw;
00196     };
00197     std::ostream& operator<<(std::ostream& os, T3& t );
00198     // --------------------------------------------------------------------------
00199     class T4
00200     {
00201         public:
00202             // ------------------------------------------
00203             // конструкторы на разные случаи...
00204             T4():sval(""),raw(0){}
00205             T4( unsigned short v1 ):raw(v1)
00206             {
00207                 char c[3];
00208                 memcpy(c,&v1,sizeof(c));
00209                 sval = std::string(c);
00210             }
00211             
00212             T4( const ModbusRTU::ModbusData* data ):
00213                 raw(data[0])
00214             {
00215                 char c[3];
00216                 memcpy(c,&(data[0]),sizeof(c));
00217                 sval    = std::string(c);
00218             }
00219             
00220             ~T4(){}
00221             // ------------------------------------------
00223             static int wsize(){ return 1; }
00225             static MTRType type(){ return mtT4; }
00226             // ------------------------------------------
00227             std::string sval;
00228             unsigned short raw;
00229     };
00230     std::ostream& operator<<(std::ostream& os, T4& t );
00231     // --------------------------------------------------------------------------
00232     class T5
00233     {
00234         public:
00235             // ------------------------------------------
00237             typedef union
00238             {
00239                 unsigned short v[u2size];
00240                 struct u_T5
00241                 {
00242                     unsigned int val:24;
00243                     signed char exp; // :8
00244                 } __attribute__( ( packed ) ) u2;
00245                 long lval;
00246             } T5mem;
00247             // ------------------------------------------
00248             // конструкторы на разные случаи...
00249             T5():val(0){ memset(raw.v,0,sizeof(raw.v)); }
00250             T5( unsigned short v1, unsigned short v2 )
00251             {
00252                 raw.v[0] = v1;
00253                 raw.v[1] = v2;
00254                 val = raw.u2.val * pow( (long)10, (long)raw.u2.exp );
00255             }
00256             
00257             T5( long v )
00258             {
00259                 raw.lval = v;
00260             }
00261             
00262             T5( const ModbusRTU::ModbusData* data, int size )
00263             {
00264                 if( size >= u2size )
00265                 {
00266                     // При получении данных от MTR слова необходимо перевернуть
00267                     raw.v[0] = data[1];
00268                     raw.v[1] = data[0];
00269                     val = raw.u2.val * pow( (long)10, (long)raw.u2.exp );
00270                 }
00271             }
00272 
00273             ~T5(){}
00274             // ------------------------------------------
00276             static int wsize(){ return u2size; }
00278             static MTRType type(){ return mtT5; }
00279             // ------------------------------------------
00280             double val;
00281             T5mem raw;
00282     };
00283     std::ostream& operator<<(std::ostream& os, T5& t );
00284     // --------------------------------------------------------------------------
00285     class T6
00286     {
00287         public:
00288             // ------------------------------------------
00290             typedef union
00291             {
00292                 unsigned short v[u2size];
00293                 struct u_T6
00294                 {
00295                     signed int val:24;
00296                     signed char exp; // :8
00297                 } u2;
00298                 long lval;
00299             } T6mem;
00300             // ------------------------------------------
00301             // конструкторы на разные случаи...
00302             T6():val(0){ memset(raw.v,0,sizeof(raw.v)); }
00303             T6( unsigned short v1, unsigned short v2 )
00304             {
00305                 raw.v[0] = v1;
00306                 raw.v[1] = v2;
00307                 val = raw.u2.val * pow( (long)10, (long)raw.u2.exp );
00308             }
00309 
00310             T6( long v )
00311             {
00312                 raw.lval = v;
00313             }
00314             
00315             T6( const ModbusRTU::ModbusData* data, int size )
00316             {
00317                 if( size >= u2size )
00318                 {
00319                     // При получении данных от MTR слова необходимо перевернуть
00320                     raw.v[0] = data[1];
00321                     raw.v[1] = data[0];
00322                     val = raw.u2.val * pow( (long)10, (long)raw.u2.exp );
00323                 }
00324             }
00325 
00326             ~T6(){}
00327             // ------------------------------------------
00329             static int wsize(){ return u2size; }
00331             static MTRType type(){ return mtT6; }
00332             // ------------------------------------------
00333             double val;
00334             T6mem raw;
00335     };
00336     std::ostream& operator<<(std::ostream& os, T6& t );
00337     // --------------------------------------------------------------------------
00338     class T7
00339     {
00340         public:
00341             // ------------------------------------------
00343             typedef union
00344             {
00345                 unsigned short v[u2size];
00346                 struct u_T7
00347                 {
00348                     unsigned int val:16;
00349                     unsigned char ic; // :8 - Inductive/capacitive
00350                     unsigned char ie; // :8 - Import/export 
00351                 }__attribute__( ( packed ) ) u2;
00352                 long lval;
00353             } T7mem;
00354             // ------------------------------------------
00355             // конструкторы на разные случаи...
00356             T7():val(0){ memset(raw.v,0,sizeof(raw.v)); }
00357             T7( unsigned short v1, unsigned short v2 )
00358             {
00359                 raw.v[0] = v1;
00360                 raw.v[1] = v2;
00361                 val = raw.u2.val * pow( (long)10, (long)-4 );
00362             }
00363             T7( const long v )
00364             {
00365                 raw.lval = v;
00366             }
00367             
00368             T7( const ModbusRTU::ModbusData* data, int size )
00369             {
00370                 if( size >= u2size )
00371                 {
00372                     // При получении данных от MTR слова необходимо перевернуть
00373                     raw.v[0] = data[1];
00374                     raw.v[1] = data[0];
00375                     val = raw.u2.val * pow( (long)10, (long)-4 );
00376                 }
00377             }
00378 
00379             ~T7(){}
00380             // ------------------------------------------
00382             static int wsize(){ return u2size; }
00384             static MTRType type(){ return mtT7; }
00385             // ------------------------------------------
00386             double val;
00387             T7mem raw;
00388     };
00389     std::ostream& operator<<(std::ostream& os, T7& t );
00390     // --------------------------------------------------------------------------
00391     class T8
00392     {
00393         public:
00394             // ------------------------------------------
00396             typedef union
00397             {
00398                 unsigned short v[u2size];
00399                 struct u_T8
00400                 {
00401                     unsigned short mon:8;
00402                     unsigned short day:8;
00403                     unsigned short hour:8;
00404                     unsigned short min:8;
00405                 }__attribute__( ( packed ) ) u2;
00406             } T8mem;
00407             // ------------------------------------------
00408             // конструкторы на разные случаи...
00409             T8(){ memset(raw.v,0,sizeof(raw.v)); }
00410             T8( unsigned short v1, unsigned short v2 )
00411             {
00412                 raw.v[0] = v1;
00413                 raw.v[1] = v2;
00414             }
00415 
00416             T8( const ModbusRTU::ModbusData* data, int size )
00417             {
00418                 if( size >= u2size )
00419                 {
00420                     // При получении данных от MTR слова необходимо перевернуть
00421                     raw.v[1] = data[0];
00422                     raw.v[0] = data[1];
00423                 }
00424             }
00425             
00426             inline unsigned short day(){ return raw.u2.day; }
00427             inline unsigned short mon(){ return raw.u2.mon; }
00428             inline unsigned short hour(){ return raw.u2.hour; }
00429             inline unsigned short min(){ return raw.u2.min; }
00430 
00431             ~T8(){}
00432             // ------------------------------------------
00434             static int wsize(){ return u2size; }
00436             static MTRType type(){ return mtT8; }
00437             // ------------------------------------------
00438             T8mem raw;
00439     };
00440     std::ostream& operator<<(std::ostream& os, T8& t );
00441     // --------------------------------------------------------------------------
00442     class T9
00443     {
00444         public:
00445             // ------------------------------------------
00447             typedef union
00448             {
00449                 unsigned short v[u2size];
00450                 struct u_T9
00451                 {
00452                     unsigned short hour:8;
00453                     unsigned short min:8;
00454                     unsigned short sec:8;
00455                     unsigned short ssec:8;
00456                 }__attribute__( ( packed ) ) u2;
00457             } T9mem;
00458             // ------------------------------------------
00459             // конструкторы на разные случаи...
00460             T9(){ memset(raw.v,0,sizeof(raw.v)); }
00461             T9( unsigned short v1, unsigned short v2 )
00462             {
00463                 raw.v[0] = v1;
00464                 raw.v[1] = v2;
00465             }
00466 
00467             T9( const ModbusRTU::ModbusData* data, int size )
00468             {
00469                 if( size >= u2size )
00470                 {
00471                     // При получении данных от MTR слова необходимо перевернуть
00472                     raw.v[0] = data[1];
00473                     raw.v[1] = data[0];
00474                 }
00475             }
00476 
00477             inline unsigned short hour(){ return raw.u2.hour; }
00478             inline unsigned short min(){ return raw.u2.min; }
00479             inline unsigned short sec(){ return raw.u2.sec; }
00480             inline unsigned short ssec(){ return raw.u2.ssec; }
00481 
00482             ~T9(){}
00483             // ------------------------------------------
00485             static int wsize(){ return u2size; }
00487             static MTRType type(){ return mtT9; }
00488             // ------------------------------------------
00489             T9mem raw;
00490     };
00491     std::ostream& operator<<(std::ostream& os, T9& t );
00492     // -------------------------------------------------------------------------
00493     class T10
00494     {
00495         public:
00496             // ------------------------------------------
00498             typedef union
00499             {
00500                 unsigned short v[u2size];
00501                 struct u_T10
00502                 {
00503                     unsigned short year:16;
00504                     unsigned short mon:8;
00505                     unsigned short day:8;
00506                 }__attribute__( ( packed ) ) u2;
00507             } T10mem;
00508             // ------------------------------------------
00509             // конструкторы на разные случаи...
00510             T10(){ memset(raw.v,0,sizeof(raw.v)); }
00511             T10( unsigned short v1, unsigned short v2 )
00512             {
00513                 raw.v[0] = v1;
00514                 raw.v[1] = v2;
00515             }
00516 
00517             T10( const ModbusRTU::ModbusData* data, int size )
00518             {
00519                 if( size >= u2size )
00520                 {
00521                     // При получении данных от MTR слова необходимо перевернуть
00522                     raw.v[0] = data[1];
00523                     raw.v[1] = data[0];
00524                 }
00525             }
00526             
00527             inline unsigned short year(){ return raw.u2.year; }
00528             inline unsigned short mon(){ return raw.u2.mon; }
00529             inline unsigned short day(){ return raw.u2.day; }
00530 
00531             ~T10(){}
00532             // ------------------------------------------
00534             static int wsize(){ return u2size; }
00536             static MTRType type(){ return mtT10; }
00537             // ------------------------------------------
00538             T10mem raw;
00539     };
00540     std::ostream& operator<<(std::ostream& os, T10& t );
00541     // --------------------------------------------------------------------------
00542     
00543     class T16
00544     {
00545         public:
00546             T16():val(0){}
00547             T16( unsigned short v ):val(v)
00548             { 
00549                 fval = (float)(val)/100.0;
00550             }
00551             T16( const ModbusRTU::ModbusData* data ):val(data[0])
00552             {
00553                 fval = (float)(val)/100.0;
00554             }
00555             T16( float f ):fval(f)
00556             {
00557                 val = lroundf(fval*100);
00558             }
00559 
00560             ~T16(){}
00561             // ------------------------------------------
00563             static int wsize(){ return 1; }
00565             static MTRType type(){ return mtT16; }
00566             // ------------------------------------------
00567             operator float(){ return fval; }
00568             operator unsigned short(){ return val; }
00569 
00570             unsigned short val;
00571             float fval;
00572     };
00573     std::ostream& operator<<(std::ostream& os, T16& t );
00574     // --------------------------------------------------------------------------
00575     class T17
00576     {
00577         public:
00578             T17():val(0){}
00579             T17( signed short v ):val(v)
00580             { 
00581                 fval = (float)(v)/100.0;
00582             }
00583             T17( unsigned short v ):val(v)
00584             { 
00585                 fval = (float)( (signed short)(v) )/100.0;
00586             }
00587 
00588             T17( const ModbusRTU::ModbusData* data ):val(data[0])
00589             {
00590                 fval = (float)(val)/100.0;
00591             }
00592             T17( float f ):fval(f)
00593             {
00594                 val = lroundf(fval*100);
00595             }
00596             ~T17(){}
00597             // ------------------------------------------
00599             static int wsize(){ return 1; }
00601             static MTRType type(){ return mtT17; }
00602             // ------------------------------------------
00603             operator float(){ return fval; }
00604             operator signed short(){ return val; }
00605 
00606             signed short val;
00607             float fval;
00608     };
00609     std::ostream& operator<<(std::ostream& os, T17& t );
00610     // --------------------------------------------------------------------------
00611     class F1
00612     {
00613         public:
00614             // ------------------------------------------
00616             typedef union
00617             {
00618                 unsigned short v[2];
00619                 float val; // 
00620             } F1mem;
00621             // ------------------------------------------
00622             // конструкторы на разные случаи...
00623             F1(){ memset(raw.v,0,sizeof(raw.v)); }
00624             F1( unsigned short v1, unsigned short v2 )
00625             {
00626                 raw.v[0] = v1;
00627                 raw.v[1] = v2;
00628             }
00629 
00630             F1( float f )
00631             {
00632                 raw.val = f;
00633             }
00634 
00635             F1( const ModbusRTU::ModbusData* data, int size )
00636             {
00637                 if( size >= u2size )
00638                 {
00639                     // При получении данных от MTR слова необходимо перевернуть
00640                     raw.v[0] = data[1];
00641                     raw.v[1] = data[0];
00642                 }
00643             }
00644 
00645             ~F1(){}
00646             // ------------------------------------------
00648             static int wsize(){ return u2size; }
00650             static MTRType type(){ return mtF1; }
00651             // ------------------------------------------
00652             operator float(){ return raw.val; }
00653             operator long(){ return lroundf(raw.val); }
00654             
00655             F1mem raw;
00656     };
00657     std::ostream& operator<<(std::ostream& os, F1& t );
00658     // --------------------------------------------------------------------------
00659     class T_Str16
00660     {
00661         public:
00662             // ------------------------------------------
00663             // конструкторы на разные случаи...
00664             T_Str16():sval(""){}
00665             T_Str16( const ModbusRTU::ReadInputRetMessage& ret )
00666             {
00667                 char c[17];
00668                 ModbusRTU::ModbusData data[8];
00669                 for( int i=0; i<8; i++ )
00670                     data[i] = ModbusRTU::SWAPSHORT(ret.data[i]);
00671 
00672                 memcpy(c,&data,16);
00673                 c[16] = '\0';
00674                 sval = std::string(c);
00675             }
00676 
00677             ~T_Str16(){}
00678             // ------------------------------------------
00680             static int wsize(){ return 8; }
00682             static MTRType type(){ return mtT_Str16; }
00683             // ------------------------------------------
00684             std::string sval;
00685     };
00686     std::ostream& operator<<(std::ostream& os, T_Str16& t );
00687     // --------------------------------------------------------------------------
00688 
00689     class T_Str8
00690     {
00691         public:
00692             // ------------------------------------------
00693             // конструкторы на разные случаи...
00694             T_Str8():sval(""){}
00695             T_Str8( const ModbusRTU::ReadInputRetMessage& ret )
00696             {
00697                 char c[9];
00698                 ModbusRTU::ModbusData data[4];
00699                 for( int i=0; i<4; i++ )
00700                     data[i] = ModbusRTU::SWAPSHORT(ret.data[i]);
00701                 memcpy(c,&data,8);
00702                 c[8] = '\0';
00703                 sval = std::string(c);
00704             }
00705 
00706             ~T_Str8(){}
00707             // ------------------------------------------
00709             static int wsize(){ return 4; }
00711             static MTRType type(){ return mtT_Str8; }
00712             // ------------------------------------------
00713             std::string sval;
00714     };
00715     std::ostream& operator<<(std::ostream& os, T_Str8& t );
00716     // --------------------------------------------------------------------------
00717 } // end of namespace MTR
00718 // --------------------------------------------------------------------------
00719 #endif // _MTR_H_
00720 // -----------------------------------------------------------------------------