UniSet  2.6.0
MTR.h
1 /*
2  * Copyright (c) 2015 Pavel Vainerman.
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as
6  * published by the Free Software Foundation, version 2.1.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  * Lesser General Lesser Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  */
16 // --------------------------------------------------------------------------
17 #ifndef _MTR_H_
18 #define _MTR_H_
19 // -----------------------------------------------------------------------------
20 #include <string>
21 #include <map>
22 #include <unordered_map>
23 #include <list>
24 #include <ostream>
25 #include <cstring>
26 #include <cmath>
27 #include "modbus/ModbusTypes.h"
28 #include "ComPort.h"
29 // -------------------------------------------------------------------------
30 namespace uniset
31 {
32  // -----------------------------------------------------------------------------
33  class ModbusRTUMaster;
34  // -----------------------------------------------------------------------------
35  namespace MTR
36  {
37  // реализованные в данном интерфейсе типы данных
38  enum MTRType
39  {
40  mtUnknown,
41  mtT1,
42  mtT2,
43  mtT3,
44  mtT4,
45  mtT5,
46  mtT6,
47  mtT7,
48  mtT8,
49  mtT9,
50  mtT10,
51  mtT16,
52  mtT17,
53  mtF1,
54  mtT_Str16,
55  mtT_Str8
56  };
57  // -------------------------------------------------------------------------
58  std::string type2str( MTRType t );
59  MTRType str2type( const std::string& s );
60  size_t wsize( MTRType t );
61  // -------------------------------------------------------------------------
62  // Информация
63  const ModbusRTU::ModbusData regModelNumber = 0x01;
64  const ModbusRTU::ModbusData regSerialNumber = 0x09;
65 
66  std::string getModelNumber( ModbusRTUMaster* mb, ModbusRTU::ModbusAddr addr );
67  std::string getSerialNumber( ModbusRTUMaster* mb, ModbusRTU::ModbusAddr addr );
68  // -------------------------------------------------------------------------
69  // Настройки связи (чтение - read03, запись - write06)
70  const ModbusRTU::ModbusData regUpdateConfiguration = 53;
71  const ModbusRTU::ModbusData regAddress = 55;
72  const ModbusRTU::ModbusData regBaudRate = 56;
73  const ModbusRTU::ModbusData regStopBit = 57; /* 0 - Stop bit, 1 - Stop bits */
74  const ModbusRTU::ModbusData regParity = 58;
75  const ModbusRTU::ModbusData regDataBits = 59;
76 
77  enum mtrBaudRate
78  {
79  br1200 = 0,
80  br2400 = 1,
81  br4800 = 2,
82  br9600 = 3,
83  br19200 = 4,
84  br38400 = 5,
85  br57600 = 6,
86  br115200 = 7
87  };
88 
89  enum mtrParity
90  {
91  mpNoParity = 0,
92  mpOddParity = 1,
93  mpEvenParity = 2
94  };
95 
96  enum mtrDataBits
97  {
98  db8Bits = 0,
99  db7Bits = 1
100  };
101 
102  bool setAddress( ModbusRTUMaster* mb, ModbusRTU::ModbusAddr addr, ModbusRTU::ModbusAddr newAddr );
103  bool setBaudRate( ModbusRTUMaster* mb, ModbusRTU::ModbusAddr addr, mtrBaudRate br );
104  bool setStopBit( ModbusRTUMaster* mb, ModbusRTU::ModbusAddr addr, bool state );
105  bool setParity( ModbusRTUMaster* mb, ModbusRTU::ModbusAddr addr, mtrParity p );
106  bool setDataBits( ModbusRTUMaster* mb, ModbusRTU::ModbusAddr addr, mtrDataBits d );
107  ComPort::Parity get_parity( ModbusRTU::ModbusData data );
108  ComPort::Speed get_speed( ModbusRTU::ModbusData data );
109  // -------------------------------------------------------------------------
110  enum MTRError
111  {
112  mtrNoError,
113  mtrBadDeviceType,
114  mtrDontReadConfile,
115  mtrSendParamFailed,
116  mtrUnknownError
117  };
118  std::ostream& operator<<(std::ostream& os, MTRError& e );
119  // Настройка из конф. файла
120  MTRError update_configuration( ModbusRTUMaster* mb, ModbusRTU::ModbusAddr addr,
121  const std::string& mtrconfile, int verbose = 0 );
122  // ---------------------------
123  // вспомогательные функции и типы данных
124  typedef std::list<ModbusRTU::ModbusData> DataList;
125  typedef std::unordered_map<ModbusRTU::ModbusData, DataList> DataMap;
126  const int attempts = 3; //
127  static const ModbusRTU::ModbusData skip[] = {48, 49, 59}; // registers which should not write
128 
129  bool send_param( ModbusRTUMaster* mb, DataMap& dmap, ModbusRTU::ModbusAddr addr, int verb );
130  bool read_param( const std::string& str, std::string& str1, std::string& str2 );
131  DataMap read_confile( const std::string& f );
132  void update_communication_params( ModbusRTU::ModbusAddr reg, ModbusRTU::ModbusData data,
133  ModbusRTUMaster* mb, ModbusRTU::ModbusAddr& addr, int verb );
134  // -------------------------------------------------------------------------
135  static const size_t u2size = 2;
136  // -------------------------------------------------------------------------
137  class T1
138  {
139  public:
140  T1(): val(0) {}
141  T1( unsigned short v ): val(v) {}
142  T1( const ModbusRTU::ModbusData* data ): val(data[0]) {}
143  ~T1() {}
144  // ------------------------------------------
146  static size_t wsize()
147  {
148  return 1;
149  }
151  static MTRType type()
152  {
153  return mtT1;
154  }
155  // ------------------------------------------
156  unsigned short val;
157  };
158  std::ostream& operator<<(std::ostream& os, T1& t );
159  // -------------------------------------------------------------------------
160  class T2
161  {
162  public:
163  T2(): val(0) {}
164  T2( signed short v ): val(v) {}
165  T2( const ModbusRTU::ModbusData* data ): val(data[0]) {}
166  ~T2() {}
167  // ------------------------------------------
169  static size_t wsize()
170  {
171  return 1;
172  }
174  static MTRType type()
175  {
176  return mtT2;
177  }
178  // ------------------------------------------
179  signed short val;
180  };
181  std::ostream& operator<<(std::ostream& os, T2& t );
182  // -------------------------------------------------------------------------
183  class T3
184  {
185  public:
186  // ------------------------------------------
188  typedef union
189  {
190  unsigned short v[u2size];
191  signed int val; // :32
192  } T3mem;
193  // ------------------------------------------
194  // конструкторы на разные случаи...
195  T3()
196  {
197  memset(raw.v, 0, sizeof(raw.v));
198  }
199 
200  T3( signed int i )
201  {
202  raw.val = i;
203  }
204 
205  T3( unsigned short v1, unsigned short v2 )
206  {
207  raw.v[0] = v1;
208  raw.v[1] = v2;
209  }
210 
211  T3( const ModbusRTU::ModbusData* data, size_t size )
212  {
213  if( size >= u2size )
214  {
215  // У MTR обратный порядок слов в ответе
216  raw.v[0] = data[1];
217  raw.v[1] = data[0];
218  }
219  }
220 
221  ~T3() {}
222  // ------------------------------------------
224  static size_t wsize()
225  {
226  return u2size;
227  }
229  static MTRType type()
230  {
231  return mtT3;
232  }
233  // ------------------------------------------
234  // функции преобразования к разным типам
235  operator long()
236  {
237  return raw.val;
238  }
239 
240  T3mem raw;
241  };
242  std::ostream& operator<<(std::ostream& os, T3& t );
243  // --------------------------------------------------------------------------
244  class T4
245  {
246  public:
247  // ------------------------------------------
248  // конструкторы на разные случаи...
249  T4(): sval(""), raw(0) {}
250  T4( uint16_t v1 ): raw(v1)
251  {
252  char c[3];
253  memcpy(c, &v1, 2);
254  c[2] = '\0';
255  sval = std::string(c);
256  }
257 
258  T4( const ModbusRTU::ModbusData* data ):
259  raw(data[0])
260  {
261  char c[3];
262  memcpy(c, &(data[0]), 2);
263  c[2] = '\0';
264  sval = std::string(c);
265  }
266 
267  ~T4() {}
268  // ------------------------------------------
270  static size_t wsize()
271  {
272  return 1;
273  }
275  static MTRType type()
276  {
277  return mtT4;
278  }
279  // ------------------------------------------
280  std::string sval;
281  unsigned short raw;
282  };
283  std::ostream& operator<<(std::ostream& os, T4& t );
284  // --------------------------------------------------------------------------
285  class T5
286  {
287  public:
288  // ------------------------------------------
290  typedef union
291  {
292  unsigned short v[u2size];
293  struct u_T5
294  {
295  unsigned int val: 24;
296  signed char exp; // :8
297  } __attribute__( ( packed ) ) u2;
298  long lval;
299  } T5mem;
300  // ------------------------------------------
301  // конструкторы на разные случаи...
302  T5(): val(0)
303  {
304  memset(raw.v, 0, sizeof(raw.v));
305  }
306  T5( unsigned short v1, unsigned short v2 )
307  {
308  raw.v[0] = v1;
309  raw.v[1] = v2;
310  val = raw.u2.val * pow( (long)10, (long)raw.u2.exp );
311  }
312 
313  T5( long v )
314  {
315  raw.lval = v;
316  val = raw.u2.val * pow( (long)10, (long)raw.u2.exp );
317  }
318 
319  T5( const ModbusRTU::ModbusData* data, size_t size ): val(0)
320  {
321  if( size >= u2size )
322  {
323  // При получении данных от MTR слова необходимо перевернуть
324  raw.v[0] = data[1];
325  raw.v[1] = data[0];
326  val = raw.u2.val * pow( (long)10, (long)raw.u2.exp );
327  }
328  }
329 
330  ~T5() {}
331  // ------------------------------------------
333  static size_t wsize()
334  {
335  return u2size;
336  }
338  static MTRType type()
339  {
340  return mtT5;
341  }
342  // ------------------------------------------
343  double val;
344  T5mem raw;
345  };
346  std::ostream& operator<<(std::ostream& os, T5& t );
347  // --------------------------------------------------------------------------
348  class T6
349  {
350  public:
351  // ------------------------------------------
353  typedef union
354  {
355  unsigned short v[u2size];
356  struct u_T6
357  {
358  signed int val: 24;
359  signed char exp; // :8
360  } u2;
361  long lval;
362  } T6mem;
363  // ------------------------------------------
364  // конструкторы на разные случаи...
365  T6(): val(0)
366  {
367  memset(raw.v, 0, sizeof(raw.v));
368  }
369  T6( unsigned short v1, unsigned short v2 )
370  {
371  raw.v[0] = v1;
372  raw.v[1] = v2;
373  val = raw.u2.val * pow( (long)10, (long)raw.u2.exp );
374  }
375 
376  T6( long v )
377  {
378  raw.lval = v;
379  val = raw.u2.val * pow( (long)10, (long)raw.u2.exp );
380  }
381 
382  T6( const ModbusRTU::ModbusData* data, size_t size )
383  {
384  if( size >= u2size )
385  {
386  // При получении данных от MTR слова необходимо перевернуть
387  raw.v[0] = data[1];
388  raw.v[1] = data[0];
389  val = raw.u2.val * pow( (long)10, (long)raw.u2.exp );
390  }
391  }
392 
393  ~T6() {}
394  // ------------------------------------------
396  static size_t wsize()
397  {
398  return u2size;
399  }
401  static MTRType type()
402  {
403  return mtT6;
404  }
405  // ------------------------------------------
406  double val = { 0.0 };
407  T6mem raw;
408  };
409  std::ostream& operator<<(std::ostream& os, T6& t );
410  // --------------------------------------------------------------------------
411  class T7
412  {
413  public:
414  // ------------------------------------------
416  typedef union
417  {
418  unsigned short v[u2size];
419  struct u_T7
420  {
421  unsigned int val: 16;
422  unsigned char ic; // :8 - Inductive/capacitive
423  unsigned char ie; // :8 - Import/export
424  } __attribute__( ( packed ) ) u2;
425  long lval;
426  } T7mem;
427  // ------------------------------------------
428  // конструкторы на разные случаи...
429  T7(): val(0)
430  {
431  memset(raw.v, 0, sizeof(raw.v));
432  }
433  T7( unsigned short v1, unsigned short v2 )
434  {
435  raw.v[0] = v1;
436  raw.v[1] = v2;
437  val = raw.u2.val * pow( (long)10, (long) - 4 );
438  }
439  T7( const long v )
440  {
441  raw.lval = v;
442  val = raw.u2.val * pow( (long)10, (long) - 4 );
443  }
444 
445  T7( const ModbusRTU::ModbusData* data, size_t size )
446  {
447  if( size >= u2size )
448  {
449  // При получении данных от MTR слова необходимо перевернуть
450  raw.v[0] = data[1];
451  raw.v[1] = data[0];
452  val = raw.u2.val * pow( (long)10, (long) - 4 );
453  }
454  }
455 
456  ~T7() {}
457  // ------------------------------------------
459  static size_t wsize()
460  {
461  return u2size;
462  }
464  static MTRType type()
465  {
466  return mtT7;
467  }
468  // ------------------------------------------
469  double val = { 0.0 };
470  T7mem raw;
471  };
472  std::ostream& operator<<(std::ostream& os, T7& t );
473  // --------------------------------------------------------------------------
474  class T8
475  {
476  public:
477  // ------------------------------------------
479  typedef union
480  {
481  unsigned short v[u2size];
482  struct u_T8
483  {
484  unsigned short mon: 8;
485  unsigned short day: 8;
486  unsigned short hour: 8;
487  unsigned short min: 8;
488  } __attribute__( ( packed ) ) u2;
489  } T8mem;
490  // ------------------------------------------
491  // конструкторы на разные случаи...
492  T8()
493  {
494  memset(raw.v, 0, sizeof(raw.v));
495  }
496  T8( unsigned short v1, unsigned short v2 )
497  {
498  raw.v[0] = v1;
499  raw.v[1] = v2;
500  }
501 
502  T8( const ModbusRTU::ModbusData* data, size_t size )
503  {
504  if( size >= u2size )
505  {
506  // При получении данных от MTR слова необходимо перевернуть
507  raw.v[1] = data[0];
508  raw.v[0] = data[1];
509  }
510  }
511 
512  inline unsigned short day()
513  {
514  return raw.u2.day;
515  }
516  inline unsigned short mon()
517  {
518  return raw.u2.mon;
519  }
520  inline unsigned short hour()
521  {
522  return raw.u2.hour;
523  }
524  inline unsigned short min()
525  {
526  return raw.u2.min;
527  }
528 
529  ~T8() {}
530  // ------------------------------------------
532  static size_t wsize()
533  {
534  return u2size;
535  }
537  static MTRType type()
538  {
539  return mtT8;
540  }
541  // ------------------------------------------
542  T8mem raw;
543  };
544  std::ostream& operator<<(std::ostream& os, T8& t );
545  // --------------------------------------------------------------------------
546  class T9
547  {
548  public:
549  // ------------------------------------------
551  typedef union
552  {
553  unsigned short v[u2size];
554  struct u_T9
555  {
556  unsigned short hour: 8;
557  unsigned short min: 8;
558  unsigned short sec: 8;
559  unsigned short ssec: 8;
560  } __attribute__( ( packed ) ) u2;
561  } T9mem;
562  // ------------------------------------------
563  // конструкторы на разные случаи...
564  T9()
565  {
566  memset(raw.v, 0, sizeof(raw.v));
567  }
568  T9( unsigned short v1, unsigned short v2 )
569  {
570  raw.v[0] = v1;
571  raw.v[1] = v2;
572  }
573 
574  T9( const ModbusRTU::ModbusData* data, size_t size )
575  {
576  if( size >= u2size )
577  {
578  // При получении данных от MTR слова необходимо перевернуть
579  raw.v[0] = data[1];
580  raw.v[1] = data[0];
581  }
582  }
583 
584  inline unsigned short hour()
585  {
586  return raw.u2.hour;
587  }
588  inline unsigned short min()
589  {
590  return raw.u2.min;
591  }
592  inline unsigned short sec()
593  {
594  return raw.u2.sec;
595  }
596  inline unsigned short ssec()
597  {
598  return raw.u2.ssec;
599  }
600 
601  ~T9() {}
602  // ------------------------------------------
604  static size_t wsize()
605  {
606  return u2size;
607  }
609  static MTRType type()
610  {
611  return mtT9;
612  }
613  // ------------------------------------------
614  T9mem raw;
615  };
616  std::ostream& operator<<(std::ostream& os, T9& t );
617  // -------------------------------------------------------------------------
618  class T10
619  {
620  public:
621  // ------------------------------------------
623  typedef union
624  {
625  unsigned short v[u2size];
626  struct u_T10
627  {
628  unsigned short year: 16;
629  unsigned short mon: 8;
630  unsigned short day: 8;
631  } __attribute__( ( packed ) ) u2;
632  } T10mem;
633  // ------------------------------------------
634  // конструкторы на разные случаи...
635  T10()
636  {
637  memset(raw.v, 0, sizeof(raw.v));
638  }
639  T10( unsigned short v1, unsigned short v2 )
640  {
641  raw.v[0] = v1;
642  raw.v[1] = v2;
643  }
644 
645  T10( const ModbusRTU::ModbusData* data, size_t size )
646  {
647  if( size >= u2size )
648  {
649  // При получении данных от MTR слова необходимо перевернуть
650  raw.v[0] = data[1];
651  raw.v[1] = data[0];
652  }
653  }
654 
655  inline unsigned short year()
656  {
657  return raw.u2.year;
658  }
659  inline unsigned short mon()
660  {
661  return raw.u2.mon;
662  }
663  inline unsigned short day()
664  {
665  return raw.u2.day;
666  }
667 
668  ~T10() {}
669  // ------------------------------------------
671  static size_t wsize()
672  {
673  return u2size;
674  }
676  static MTRType type()
677  {
678  return mtT10;
679  }
680  // ------------------------------------------
681  T10mem raw;
682  };
683  std::ostream& operator<<(std::ostream& os, T10& t );
684  // --------------------------------------------------------------------------
685 
686  class T16
687  {
688  public:
689  T16(): val(0) {}
690  T16( unsigned short v ): val(v)
691  {
692  fval = (float)(val) / 100.0;
693  }
694  T16( const ModbusRTU::ModbusData* data ): val(data[0])
695  {
696  fval = (float)(val) / 100.0;
697  }
698  T16( float f ): fval(f)
699  {
700  val = lroundf(fval * 100);
701  }
702 
703  ~T16() {}
704  // ------------------------------------------
706  static size_t wsize()
707  {
708  return 1;
709  }
711  static MTRType type()
712  {
713  return mtT16;
714  }
715  // ------------------------------------------
716  operator float()
717  {
718  return fval;
719  }
720  operator unsigned short()
721  {
722  return val;
723  }
724 
725  unsigned short val = { 0 };
726  float fval = { 0.0 };
727  };
728  std::ostream& operator<<(std::ostream& os, T16& t );
729  // --------------------------------------------------------------------------
730  class T17
731  {
732  public:
733  T17(): val(0) {}
734  T17( signed short v ): val(v)
735  {
736  fval = (float)(v) / 100.0;
737  }
738  T17( unsigned short v ): val(v)
739  {
740  fval = (float)( (signed short)(v) ) / 100.0;
741  }
742 
743  T17( const ModbusRTU::ModbusData* data ): val(data[0])
744  {
745  fval = (float)(val) / 100.0;
746  }
747  T17( float f ): fval(f)
748  {
749  val = lroundf(fval * 100);
750  }
751  ~T17() {}
752  // ------------------------------------------
754  static size_t wsize()
755  {
756  return 1;
757  }
759  static MTRType type()
760  {
761  return mtT17;
762  }
763  // ------------------------------------------
764  operator float()
765  {
766  return fval;
767  }
768  operator signed short()
769  {
770  return val;
771  }
772 
773  signed short val = { 0 };
774  float fval = { 0 };
775  };
776  std::ostream& operator<<(std::ostream& os, T17& t );
777  // --------------------------------------------------------------------------
778  class F1
779  {
780  public:
781  // ------------------------------------------
783  typedef union
784  {
785  unsigned short v[2];
786  float val; //
787  } F1mem;
788  // ------------------------------------------
789  // конструкторы на разные случаи...
790  F1()
791  {
792  memset(raw.v, 0, sizeof(raw.v));
793  }
794  F1( unsigned short v1, unsigned short v2 )
795  {
796  raw.v[0] = v1;
797  raw.v[1] = v2;
798  }
799 
800  F1( float f )
801  {
802  raw.val = f;
803  }
804 
805  F1( const ModbusRTU::ModbusData* data, size_t size )
806  {
807  if( size >= u2size )
808  {
809  // При получении данных от MTR слова необходимо перевернуть
810  raw.v[0] = data[1];
811  raw.v[1] = data[0];
812  }
813  }
814 
815  ~F1() {}
816  // ------------------------------------------
818  static size_t wsize()
819  {
820  return u2size;
821  }
823  static MTRType type()
824  {
825  return mtF1;
826  }
827  // ------------------------------------------
828  operator float()
829  {
830  return raw.val;
831  }
832  operator long()
833  {
834  return lroundf(raw.val);
835  }
836 
837  F1mem raw;
838  };
839  std::ostream& operator<<(std::ostream& os, F1& t );
840  // --------------------------------------------------------------------------
841  class T_Str16
842  {
843  public:
844  // ------------------------------------------
845  // конструкторы на разные случаи...
846  T_Str16(): sval("") {}
848  {
849  char c[17];
850  ModbusRTU::ModbusData data[8];
851 
852  for( int i = 0; i < 8; i++ )
853  data[i] = ModbusRTU::SWAPSHORT(ret.data[i]);
854 
855  memcpy(c, &data, 16);
856  c[16] = '\0';
857  sval = std::string(c);
858  }
859 
860  ~T_Str16() {}
861  // ------------------------------------------
863  static size_t wsize()
864  {
865  return 8;
866  }
868  static MTRType type()
869  {
870  return mtT_Str16;
871  }
872  // ------------------------------------------
873  std::string sval;
874  };
875  std::ostream& operator<<(std::ostream& os, T_Str16& t );
876  // --------------------------------------------------------------------------
877 
878  class T_Str8
879  {
880  public:
881  // ------------------------------------------
882  // конструкторы на разные случаи...
883  T_Str8(): sval("") {}
885  {
886  char c[9];
887  ModbusRTU::ModbusData data[4];
888 
889  for( int i = 0; i < 4; i++ )
890  data[i] = ModbusRTU::SWAPSHORT(ret.data[i]);
891 
892  memcpy(c, &data, 8);
893  c[8] = '\0';
894  sval = std::string(c);
895  }
896 
897  ~T_Str8() {}
898  // ------------------------------------------
900  static size_t wsize()
901  {
902  return 4;
903  }
905  static MTRType type()
906  {
907  return mtT_Str8;
908  }
909  // ------------------------------------------
910  std::string sval;
911  };
912  std::ostream& operator<<(std::ostream& os, T_Str8& t );
913  // --------------------------------------------------------------------------
914  } // end of namespace MTR
915  // --------------------------------------------------------------------------
916 } // end of namespace uniset
917 // --------------------------------------------------------------------------
918 #endif // _MTR_H_
919 // -----------------------------------------------------------------------------