UniSet  2.24.2
MBConfig.h
1 /*
2  * Copyright (c) 2020 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 _MBConfig_H_
18 #define _MBConfig_H_
19 // -----------------------------------------------------------------------------
20 #include <ostream>
21 #include <string>
22 #include <map>
23 #include <unordered_map>
24 #include <memory>
25 #include "IONotifyController.h"
26 #include "Calibration.h"
27 #include "DelayTimer.h"
28 #include "SMInterface.h"
29 #include "SharedMemory.h"
30 #include "IOBase.h"
31 #include "VTypes.h"
32 #include "MTR.h"
33 #include "RTUStorage.h"
34 #include "modbus/ModbusClient.h"
35 #include "Configuration.h"
36 // -------------------------------------------------------------------------
37 namespace uniset
38 {
39  // -----------------------------------------------------------------------------
41  class MBConfig
42  {
43  public:
44  MBConfig(const std::shared_ptr<uniset::Configuration>& conf
45  , xmlNode* cnode
46  , std::shared_ptr<SMInterface> _shm );
47 
48  ~MBConfig();
49 
52  {
53  emNone = 0,
55  emReadOnly = 2,
57  emSkipExchange = 4
58  };
59  friend std::ostream& operator<<( std::ostream& os, const ExchangeMode& em );
60 
62  enum SafeMode
63  {
64  safeNone = 0,
67  };
68 
69 
70  friend std::string to_string( const SafeMode& m );
71  friend std::ostream& operator<<( std::ostream& os, const SafeMode& m );
72 
74  {
78  dtRTU188
79  };
80 
81  static DeviceType getDeviceType( const std::string& dtype ) noexcept;
82  friend std::ostream& operator<<( std::ostream& os, const DeviceType& dt );
83 
84  struct RTUDevice;
85  struct RegInfo;
86 
87  struct RSProperty:
88  public IOBase
89  {
90  // only for RTU
91  int8_t nbit;
92  VTypes::VType vType;
93  uint16_t rnum;
94  uint8_t nbyte;
96  RSProperty():
97  nbit(-1), vType(VTypes::vtUnknown),
98  rnum(VTypes::wsize(VTypes::vtUnknown)),
99  nbyte(0)
100  {}
101 
102  // т.к. IOBase содержит rwmutex с запрещённым конструктором копирования
103  // приходится здесь тоже объявлять разрешенными только операции "перемещения"
104  RSProperty( const RSProperty& r ) = delete;
105  RSProperty& operator=(const RSProperty& r) = delete;
106  RSProperty( RSProperty&& r ) = default;
107  RSProperty& operator=(RSProperty&& r) = default;
108 
109  std::shared_ptr<RegInfo> reg;
110  };
111 
112  friend std::ostream& operator<<( std::ostream& os, const RSProperty& p );
113 
114  typedef std::list<RSProperty> PList;
115  std::ostream& print_plist( std::ostream& os, const PList& p );
116 
117  typedef std::map<ModbusRTU::RegID, std::shared_ptr<RegInfo>> RegMap;
118  struct RegInfo
119  {
120  // т.к. RSProperty содержит rwmutex с запрещённым конструктором копирования
121  // приходится здесь тоже объявлять разрешенными только операции "перемещения"
122  RegInfo( const RegInfo& r ) = default;
123  RegInfo& operator=(const RegInfo& r) = delete;
124  RegInfo( RegInfo&& r ) = delete;
125  RegInfo& operator=(RegInfo&& r) = default;
126  RegInfo() = default;
127 
128  ModbusRTU::ModbusData mbval = { 0 };
129  ModbusRTU::ModbusData mbreg = { 0 };
130  ModbusRTU::SlaveFunctionCode mbfunc = { ModbusRTU::fnUnknown };
131  PList slst;
132  ModbusRTU::RegID regID = { 0 };
133 
134  std::shared_ptr<RTUDevice> dev;
135 
136  // only for RTU188
137  RTUStorage::RTUJack rtuJack = { RTUStorage::nUnknown };
138  int rtuChan = { 0 };
139 
140  // only for MTR
141  MTR::MTRType mtrType = { MTR::mtUnknown };
143  // optimization
144  size_t q_num = { 0 };
145  size_t q_count = { 1 };
147  RegMap::iterator rit;
148 
149  // начальная инициализация для "записываемых" регистров
150  // Механизм:
151  // Если tcp_preinit="1", то сперва будет сделано чтение значения из устройства.
152  // при этом флаг mb_init=false пока не пройдёт успешной инициализации
153  // Если tcp_preinit="0", то флаг mb_init сразу выставляется в true.
154  bool mb_initOK = { false };
156  // Флаг sm_init означает, что писать в устройство нельзя, т.к. значение в "карте регистров"
157  // ещё не инициализировано из SM
158  bool sm_initOK = { false };
159  };
160 
161  friend std::ostream& operator<<( std::ostream& os, const RegInfo& r );
162  friend std::ostream& operator<<( std::ostream& os, const RegInfo* r );
163 
164  struct RTUDevice
165  {
166  ModbusRTU::ModbusAddr mbaddr = { 0 };
167  std::unordered_map<size_t, std::shared_ptr<RegMap>> pollmap;
168 
171  // resp - respond..(контроль наличия связи)
173  IOController::IOStateList::iterator resp_it;
174  DelayTimer resp_Delay; // таймер для формирования задержки на отпускание (пропадание связи)
175  PassiveTimer resp_ptInit; // таймер для формирования задержки на инициализацию связи (задержка на выставление датчика связи после запуска)
176  bool resp_state = { false };
177  bool resp_invert = { false };
178  bool resp_force = { false };
179  Trigger trInitOK; // триггер для "инициализации"
180  std::atomic<size_t> numreply = { 0 }; // количество успешных запросов..
181  std::atomic<size_t> prev_numreply = { 0 };
182 
183  //
184  bool ask_every_reg = { false };
186  // режим работы
188  IOController::IOStateList::iterator mode_it;
189  long mode = { emNone }; // режим работы с устройством (см. ExchangeMode)
190 
191  // safe mode
192  long safeMode = { safeNone };
194  IOController::IOStateList::iterator safemode_it;
195  long safemode_value = { 1 };
196 
197  // return TRUE if state changed
198  bool checkRespond( std::shared_ptr<DebugStream>& log );
199 
200  // специфические поля для RS
201  ComPort::Speed speed = { ComPort::ComSpeed38400 };
202  std::shared_ptr<RTUStorage> rtu188;
203  ComPort::Parity parity = { ComPort::NoParity };
204  ComPort::CharacterSize csize = { ComPort::CSize8 };
205  ComPort::StopBits stopBits = { ComPort::OneBit };
206 
207  std::string getShortInfo() const;
208  };
209 
210  friend std::ostream& operator<<( std::ostream& os, RTUDevice& d );
211 
212  typedef std::unordered_map<ModbusRTU::ModbusAddr, std::shared_ptr<RTUDevice>> RTUDeviceMap;
213 
214  friend std::ostream& operator<<( std::ostream& os, RTUDeviceMap& d );
215  static void printMap(RTUDeviceMap& d);
216 
217  typedef std::list<IOBase> ThresholdList;
218 
219  struct InitRegInfo
220  {
221  InitRegInfo():
222  dev(0), mbreg(0),
223  mbfunc(ModbusRTU::fnUnknown),
224  initOK(false)
225  {}
226  RSProperty p;
227  std::shared_ptr<RTUDevice> dev;
228  ModbusRTU::ModbusData mbreg;
229  ModbusRTU::SlaveFunctionCode mbfunc;
230  bool initOK;
231  std::shared_ptr<RegInfo> ri;
232  };
233  typedef std::list<InitRegInfo> InitList;
234 
235  static void rtuQueryOptimization( RTUDeviceMap& m, size_t maxQueryCount );
236  static void rtuQueryOptimizationForDevice( const std::shared_ptr<RTUDevice>& d, size_t maxQueryCount );
237  static void rtuQueryOptimizationForRegMap( const std::shared_ptr<RegMap>& regmap, size_t maxQueryCount );
238 
239  // т.к. пороговые датчики не связаны напрямую с обменом, создаём для них отдельный список
240  // и отдельно его проверяем потом
241  ThresholdList thrlist;
242  RTUDeviceMap devices;
243  InitList initRegList;
245  void loadConfig( const std::shared_ptr<uniset::UniXML>& xml, UniXML::iterator sensorsSection );
246  void initDeviceList( const std::shared_ptr<UniXML>& xml );
247  bool initItem( UniXML::iterator& it );
248 
249  std::string s_field;
250  std::string s_fvalue;
251 
252  // определение timeout для соединения
253  timeout_t recv_timeout = { 500 }; // msec
254  timeout_t default_timeout = { 5000 }; // msec
255  timeout_t aftersend_pause = { 0 };
256  timeout_t polltime = { 100 };
257  timeout_t sleepPause_msec = { 10 };
258 
259  size_t maxQueryCount = { ModbusRTU::MAXDATALEN };
260  xmlNode* cnode = { 0 };
261  std::shared_ptr<DebugStream> mblog;
262  std::string myname;
263  std::string prefix;
264  std::string prop_prefix;
265  std::string defaultMBtype;
266  std::string defaultMBaddr;
267  bool mbregFromID = { false };
268  bool defaultMBinitOK = { false }; // флаг определяющий нужно ли ждать "первого обмена" или при запуске сохранять в SM значение default.
269  bool noQueryOptimization = { false };
270  std::shared_ptr<uniset::Configuration> conf;
271  std::shared_ptr<SMInterface> shm;
272 
273  void cloneParams( const std::shared_ptr<MBConfig>& conf );
274  std::string getShortInfo() const;
275 
276  protected:
277 
278  bool initSMValue( ModbusRTU::ModbusData* data, int count, RSProperty* p );
279 
280  void readConfiguration(const std::shared_ptr<uniset::UniXML>& xml, UniXML::iterator sensorsSection );
281  void initOffsetList();
282 
283  std::shared_ptr<RTUDevice> addDev( RTUDeviceMap& dmap, ModbusRTU::ModbusAddr a, UniXML::iterator& it );
284  std::shared_ptr<RegInfo> addReg(std::shared_ptr<RegMap>& devices, ModbusRTU::RegID id, ModbusRTU::ModbusData r, UniXML::iterator& it, std::shared_ptr<RTUDevice> dev );
285  RSProperty* addProp( PList& plist, RSProperty&& p );
286 
287  bool initMTRitem(UniXML::iterator& it, std::shared_ptr<RegInfo>& p );
288  bool initRTU188item(UniXML::iterator& it, std::shared_ptr<RegInfo>& p );
289  bool initRSProperty( RSProperty& p, UniXML::iterator& it );
290  bool initRegInfo(std::shared_ptr<RegInfo>& r, UniXML::iterator& it, std::shared_ptr<RTUDevice>& dev );
291  bool initRTUDevice( std::shared_ptr<RTUDevice>& d, UniXML::iterator& it );
292  bool initDeviceInfo( RTUDeviceMap& m, ModbusRTU::ModbusAddr a, UniXML::iterator& it );
293  };
294  // --------------------------------------------------------------------------
295 } // end of namespace uniset
296 // -----------------------------------------------------------------------------
297 #endif // _MBConfig_H_
298 // -----------------------------------------------------------------------------
Definition: DelayTimer.h:30
Definition: MBConfig.h:42
bool initItem(UniXML::iterator &it)
Definition: MBConfig.cc:575
std::string prop_prefix
Definition: MBConfig.h:264
SafeMode
Definition: MBConfig.h:63
@ safeResetIfNotRespond
Definition: MBConfig.h:65
@ safeExternalControl
Definition: MBConfig.h:66
@ safeNone
Definition: MBConfig.h:64
DeviceType
Definition: MBConfig.h:74
@ dtRTU188
Definition: MBConfig.h:78
@ dtUnknown
Definition: MBConfig.h:75
@ dtRTU
Definition: MBConfig.h:76
@ dtMTR
Definition: MBConfig.h:77
size_t maxQueryCount
Definition: MBConfig.h:259
timeout_t polltime
Definition: MBConfig.h:256
InitList initRegList
Definition: MBConfig.h:243
ExchangeMode
Definition: MBConfig.h:52
@ emNone
Definition: MBConfig.h:53
@ emSkipExchange
Definition: MBConfig.h:57
@ emReadOnly
Definition: MBConfig.h:55
@ emSkipSaveToSM
Definition: MBConfig.h:56
@ emWriteOnly
Definition: MBConfig.h:54
Пассивный таймер
Definition: PassiveTimer.h:94
Definition: UniXML.h:44
Definition: CommonEventLoop.h:15
const ObjectId DefaultObjectId
Definition: UniSetTypes.h:70
long ObjectId
Definition: UniSetTypes_i.idl:30
Definition: IOBase.h:35
Definition: MBConfig.h:220
Definition: MBConfig.h:89
VTypes::VType vType
Definition: MBConfig.h:92
int8_t nbit
Definition: MBConfig.h:91
uint8_t nbyte
Definition: MBConfig.h:94
uint16_t rnum
Definition: MBConfig.h:93
Definition: MBConfig.h:165
uniset::ObjectId safemode_id
Definition: MBConfig.h:193
long safeMode
Definition: MBConfig.h:192
DeviceType dtype
Definition: MBConfig.h:169
ModbusRTU::ModbusAddr mbaddr
Definition: MBConfig.h:166
bool ask_every_reg
Definition: MBConfig.h:184
Definition: MBConfig.h:119
size_t q_count
Definition: MBConfig.h:145
ModbusRTU::ModbusData mbreg
Definition: MBConfig.h:129
ModbusRTU::SlaveFunctionCode mbfunc
Definition: MBConfig.h:130
MTR::MTRType mtrType
Definition: MBConfig.h:141
bool mb_initOK
Definition: MBConfig.h:154
size_t q_num
Definition: MBConfig.h:144
bool sm_initOK
Definition: MBConfig.h:158