UniSet @VERSION@
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// -------------------------------------------------------------------------
37namespace uniset
38{
39 // -----------------------------------------------------------------------------
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
59 friend std::ostream& operator<<( std::ostream& os, const ExchangeMode& em );
60 friend std::string to_string( const ExchangeMode& m );
61 static ExchangeMode from_string( const std::string& s );
62 static std::vector<std::string> supported_modes();
63
71
72
73 friend std::string to_string( const SafeMode& m );
74 friend std::ostream& operator<<( std::ostream& os, const SafeMode& m );
75
83
84 static DeviceType getDeviceType( const std::string& dtype ) noexcept;
85 friend std::ostream& operator<<( std::ostream& os, const DeviceType& dt );
86
87 struct RTUDevice;
88 struct RegInfo;
89
90 struct RSProperty:
91 public IOBase
92 {
93 int8_t nbit = { -1 };
94 VTypes::VType vType = { VTypes::vtUnknown };
95 uint16_t rnum = { 1 };
96 uint8_t nbyte = { 0 };
97 uint16_t mask = { 0 };
98 uint8_t offset = { 0 };
100 RSProperty() {}
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
116 typedef std::map<ModbusRTU::RegID, std::shared_ptr<RegInfo>> RegMap;
117 struct RegInfo
118 {
119 // т.к. RSProperty содержит rwmutex с запрещённым конструктором копирования
120 // приходится здесь тоже объявлять разрешенными только операции "перемещения"
121 RegInfo( const RegInfo& r ) = delete;
122 RegInfo& operator=(const RegInfo& r) = delete;
123 RegInfo( RegInfo&& r ) = default;
124 RegInfo& operator=(RegInfo&& r) = default;
125 RegInfo() = default;
126
127 ModbusRTU::ModbusData mbval = { 0 };
128 inline bool setMBVal(ModbusRTU::ModbusData nv)
129 {
130 if( mbval != nv )
131 mbval_changed = true;
132
133 mbval = nv;
134 return mbval_changed;
135 }
136 ModbusRTU::ModbusData mbreg = { 0 };
137 ModbusRTU::SlaveFunctionCode mbfunc = { ModbusRTU::fnUnknown };
138 PList slst;
139 ModbusRTU::RegID regID = { 0 };
140
141 std::shared_ptr<RTUDevice> dev;
142
143 // only for RTU188
144 RTUStorage::RTUJack rtuJack = { RTUStorage::nUnknown };
145 int rtuChan = { 0 };
146
147 // only for MTR
148 MTR::MTRType mtrType = { MTR::mtUnknown };
150 // optimization
151 size_t q_num = { 0 };
152 size_t q_count = { 1 };
154 RegMap::iterator rit;
155
156 // начальная инициализация для "записываемых" регистров
157 // Механизм:
158 // Если tcp_preinit="1", то сперва будет сделано чтение значения из устройства.
159 // при этом флаг mb_init=false пока не пройдёт успешной инициализации
160 // Если tcp_preinit="0", то флаг mb_init сразу выставляется в true.
161 bool mb_initOK = { false };
163 // Флаг sm_init означает, что писать в устройство нельзя, т.к. значение в "карте регистров"
164 // ещё не инициализировано из SM
165 bool sm_initOK = { false };
167 // Флаг mbval_changed == true означает, что значение датчика для регистра на запись изменилось и нужно
168 // записать его в устройство.
169 // При старте по-умолчанию первый запрос отправляется, если для конкретного датчика не выставлен
170 // тег "init_mbval_changed=0".
171 // Также можно указать "init_mbval_changed=0" в глобальной секции для процесса обмена или параметром
172 // "--prefix-init-mbval-changed 0" командной строки. Тогда все регистры будут инициализировать mbval_changed
173 // этим значением, если не указать тег для датчика.
174 bool mbval_changed = { true };
175 };
176
177 friend std::ostream& operator<<( std::ostream& os, const RegInfo& r );
178 friend std::ostream& operator<<( std::ostream& os, const RegInfo* r );
179
181 {
182 ModbusRTU::ModbusAddr mbaddr = { 0 };
183 std::unordered_map<size_t, std::shared_ptr<RegMap>> pollmap;
184
187 // resp - respond..(контроль наличия связи)
189 IOController::IOStateList::iterator resp_it;
190 DelayTimer resp_Delay; // таймер для формирования задержки на отпускание (пропадание связи)
191 PassiveTimer resp_ptInit; // таймер для формирования задержки на инициализацию связи (задержка на выставление датчика связи после запуска)
192 bool resp_state = { false };
193 bool resp_invert = { false };
194 bool resp_force = { false };
195 Trigger trInitOK; // триггер для "инициализации"
196 std::atomic<size_t> numreply = { 0 }; // количество успешных запросов..
197 std::atomic<size_t> prev_numreply = { 0 };
198
199 //
200 bool ask_every_reg = { false };
202 // режим работы
204 IOController::IOStateList::iterator mode_it;
205 long mode = { emNone }; // режим работы с устройством (см. ExchangeMode)
206
207 // safe mode
208 long safeMode = { safeNone };
210 IOController::IOStateList::iterator safemode_it;
211 long safemode_value = { 1 };
212
213 // return TRUE if state changed
214 bool checkRespond( std::shared_ptr<DebugStream>& log );
215
216 // специфические поля для RS
217 ComPort::Speed speed = { ComPort::ComSpeed38400 };
218 std::shared_ptr<RTUStorage> rtu188;
219 ComPort::Parity parity = { ComPort::NoParity };
220 ComPort::CharacterSize csize = { ComPort::CSize8 };
221 ComPort::StopBits stopBits = { ComPort::OneBit };
222
223 std::string getShortInfo() const;
224 };
225
226 friend std::ostream& operator<<( std::ostream& os, RTUDevice& d );
227
228 typedef std::unordered_map<ModbusRTU::ModbusAddr, std::shared_ptr<RTUDevice>> RTUDeviceMap;
229
230 friend std::ostream& operator<<( std::ostream& os, RTUDeviceMap& d );
231 static void printMap(RTUDeviceMap& d);
232
233 typedef std::list<IOBase> ThresholdList;
234
236 {
237 InitRegInfo():
238 dev(0), mbreg(0),
239 mbfunc(ModbusRTU::fnUnknown),
240 initOK(false)
241 {}
242 RSProperty p;
243 std::shared_ptr<RTUDevice> dev;
244 ModbusRTU::ModbusData mbreg;
245 ModbusRTU::SlaveFunctionCode mbfunc;
246 bool initOK;
247 std::shared_ptr<RegInfo> ri;
248 };
249 typedef std::list<InitRegInfo> InitList;
250
251 static void rtuQueryOptimization( RTUDeviceMap& m, size_t maxQueryCount );
252 static void rtuQueryOptimizationForDevice( const std::shared_ptr<RTUDevice>& d, size_t maxQueryCount );
253 static void rtuQueryOptimizationForRegMap( const std::shared_ptr<RegMap>& regmap, size_t maxQueryCount );
254
255 // т.к. пороговые датчики не связаны напрямую с обменом, создаём для них отдельный список
256 // и отдельно его проверяем потом
257 ThresholdList thrlist;
258 RTUDeviceMap devices;
259 InitList initRegList;
261 void loadConfig( const std::shared_ptr<uniset::UniXML>& xml, UniXML::iterator sensorsSection );
262 void initDeviceList( const std::shared_ptr<UniXML>& xml );
263 bool initItem( UniXML::iterator& it );
264
265 std::string s_field;
266 std::string s_fvalue;
267
268 // определение timeout для соединения
269 timeout_t recv_timeout = { 500 }; // msec
270 timeout_t default_timeout = { 5000 }; // msec
271 timeout_t aftersend_pause = { 0 };
272 timeout_t polltime = { 100 };
273 timeout_t sleepPause_msec = { 10 };
274
275 size_t maxQueryCount = { ModbusRTU::MAXDATALEN };
276 xmlNode* cnode = { 0 };
277 std::shared_ptr<DebugStream> mblog;
278 std::string myname;
279 std::string prefix;
280 std::string prop_prefix;
281 std::string defaultMBtype;
282 std::string defaultMBaddr;
283 bool mbregFromID = { false };
284 bool defaultMBinitOK = { false }; // флаг определяющий нужно ли ждать "первого обмена" или при запуске сохранять в SM значение default.
285 bool noQueryOptimization = { false };
286 std::shared_ptr<uniset::Configuration> conf;
287 std::shared_ptr<SMInterface> shm;
288
289 void cloneParams( const std::shared_ptr<MBConfig>& conf );
290 std::string getShortInfo() const;
291
292 static const size_t changeOnlyWrite = { 65535 };
293 bool init_mbval_changed = { true };
295 bool checkDuplicationRegID( const ModbusRTU::RegID id, const std::shared_ptr<RTUDevice>& dev, const std::shared_ptr<RegMap>& rmap ) const;
297 protected:
298
299 bool initSMValue( ModbusRTU::ModbusData* data, int count, RSProperty* p );
300
301 void readConfiguration(const std::shared_ptr<uniset::UniXML>& xml, UniXML::iterator sensorsSection );
302 void initOffsetList();
303
304 std::shared_ptr<RTUDevice> addDev( RTUDeviceMap& dmap, ModbusRTU::ModbusAddr a, UniXML::iterator& it );
305 std::shared_ptr<RegInfo> addReg(std::shared_ptr<RegMap>& devices, ModbusRTU::RegID id, ModbusRTU::ModbusData r, UniXML::iterator& it, std::shared_ptr<RTUDevice> dev );
306 RSProperty* addProp( PList& plist, RSProperty&& p );
307
308 bool initMTRitem(UniXML::iterator& it, std::shared_ptr<RegInfo>& p );
309 bool initRTU188item(UniXML::iterator& it, std::shared_ptr<RegInfo>& p );
310 bool initRSProperty( RSProperty& p, UniXML::iterator& it );
311 bool initRegInfo(std::shared_ptr<RegInfo>& r, UniXML::iterator& it, std::shared_ptr<RTUDevice>& dev );
312 bool initRTUDevice( std::shared_ptr<RTUDevice>& d, UniXML::iterator& it );
313 bool initDeviceInfo( RTUDeviceMap& m, ModbusRTU::ModbusAddr a, UniXML::iterator& it );
314 };
315 // --------------------------------------------------------------------------
316} // end of namespace uniset
317// -----------------------------------------------------------------------------
318namespace std
319{
320 std::string to_string( const uniset::MBConfig::PList& p );
321}
322#endif // _MBConfig_H_
323// -----------------------------------------------------------------------------
Definition DelayTimer.h:30
Definition MBConfig.h:42
bool initItem(UniXML::iterator &it)
Definition MBConfig.cc:603
std::string prop_prefix
Definition MBConfig.h:280
bool checkDuplicationRegID(const ModbusRTU::RegID id, const std::shared_ptr< RTUDevice > &dev, const std::shared_ptr< RegMap > &rmap) const
Definition MBConfig.cc:1237
SafeMode
Definition MBConfig.h:66
@ safeResetIfNotRespond
Definition MBConfig.h:68
@ safeExternalControl
Definition MBConfig.h:69
@ safeNone
Definition MBConfig.h:67
static const size_t changeOnlyWrite
Definition MBConfig.h:292
DeviceType
Definition MBConfig.h:77
@ dtRTU188
Definition MBConfig.h:81
@ dtUnknown
Definition MBConfig.h:78
@ dtRTU
Definition MBConfig.h:79
@ dtMTR
Definition MBConfig.h:80
size_t maxQueryCount
Definition MBConfig.h:275
bool init_mbval_changed
Definition MBConfig.h:293
timeout_t polltime
Definition MBConfig.h:272
InitList initRegList
Definition MBConfig.h:259
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
STL namespace.
Definition AccessConfig.h:30
const ObjectId DefaultObjectId
Definition UniSetTypes.h:71
long ObjectId
Definition UniSetTypes_i.idl:30
Definition IOBase.h:35
Definition MBConfig.h:236
Definition MBConfig.h:92
VTypes::VType vType
Definition MBConfig.h:94
uint8_t offset
Definition MBConfig.h:98
int8_t nbit
Definition MBConfig.h:93
uint8_t nbyte
Definition MBConfig.h:96
uint16_t mask
Definition MBConfig.h:97
uint16_t rnum
Definition MBConfig.h:95
Definition MBConfig.h:181
uniset::ObjectId safemode_id
Definition MBConfig.h:209
long safeMode
Definition MBConfig.h:208
DeviceType dtype
Definition MBConfig.h:185
ModbusRTU::ModbusAddr mbaddr
Definition MBConfig.h:182
bool ask_every_reg
Definition MBConfig.h:200
Definition MBConfig.h:118
size_t q_count
Definition MBConfig.h:152
ModbusRTU::ModbusData mbreg
Definition MBConfig.h:136
ModbusRTU::SlaveFunctionCode mbfunc
Definition MBConfig.h:137
MTR::MTRType mtrType
Definition MBConfig.h:148
bool mb_initOK
Definition MBConfig.h:161
size_t q_num
Definition MBConfig.h:151
bool mbval_changed
Definition MBConfig.h:174
bool sm_initOK
Definition MBConfig.h:165