UniSet 2.32.1
OPCUAExchange.h
1/*
2 * Copyright (c) 2023 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 OPCUAExchange_H_
18#define OPCUAExchange_H_
19// -----------------------------------------------------------------------------
20#include <vector>
21#include <memory>
22#include <deque>
23#include <string>
24#include <regex>
25#include <optional>
26#include "UniXML.h"
27#include "ThreadCreator.h"
28#include "PassiveTimer.h"
29#include "Trigger.h"
30#include "IONotifyController.h"
31#include "UniSetObject.h"
32#include "Mutex.h"
33#include "MessageType.h"
34#include "SMInterface.h"
35#include "IOBase.h"
36#include "SharedMemory.h"
37#include "LogServer.h"
38#include "DebugStream.h"
39#include "LogAgregator.h"
40#include "OPCUAClient.h"
41// -------------------------------------------------------------------------
42#ifndef vmonit
43#define vmonit( var ) vmon.add( #var, var )
44#endif
45// -------------------------------------------------------------------------
46namespace uniset
47{
48 // ---------------------------------------------------------------------
145 // ---------------------------------------------------------------------
148 public UniSetObject
149 {
150 public:
151 OPCUAExchange( uniset::ObjectId id, uniset::ObjectId icID, const std::shared_ptr<SharedMemory>& shm = nullptr, const std::string& prefix = "opcua" );
152 virtual ~OPCUAExchange();
153
154 static std::shared_ptr<OPCUAExchange> init_opcuaexchange(int argc, const char* const* argv,
155 uniset::ObjectId icID, const std::shared_ptr<SharedMemory>& ic = nullptr,
156 const std::string& prefix = "opcua");
157
158 static void help_print( int argc, const char* const* argv );
159
160 virtual uniset::SimpleInfo* getInfo( const char* userparam = 0 ) override;
161
162 static uint8_t firstBit( uint32_t mask );
163
164 // offset = firstBit(mask)
165 static uint32_t getBits( uint32_t value, uint32_t mask, uint8_t offset );
166 // if mask = 0 return value
167 static uint32_t setBits( uint32_t value, uint32_t set, uint32_t mask, uint8_t offset );
168 // if mask=0 return set
169 static uint32_t forceSetBits( uint32_t value, uint32_t set, uint32_t mask, uint8_t offset );
170
171 using Tick = uint8_t;
172
173 static const size_t numChannels = 2;
175 {
176 std::vector<OPCUAClient::ResultVar> results;
177 std::vector<UA_ReadValueId> ids;
178 };
180 {
181 std::vector<UA_WriteValue> ids;
182 };
185 public IOBase
186 {
187 // т.к. IOBase содержит rwmutex с запрещённым конструктором копирования
188 // приходится здесь тоже объявлять разрешенными только операции "перемещения"
189 OPCAttribute(const OPCAttribute& r ) = delete;
190 OPCAttribute& operator=(const OPCAttribute& r) = delete;
191 OPCAttribute(OPCAttribute&& r ) = default;
192 OPCAttribute& operator=(OPCAttribute&& r) = default;
193 OPCAttribute() = default;
194
196 int32_t val { 0 };
197 Tick tick = { 0 }; // на каждом ли тике работать с этим аттрибутом
198 uint32_t mask = { 0 };
199 uint8_t offset = { 0 };
200 OPCUAClient::VarType vtype = { OPCUAClient::VarType::Int32 };
201
202 // with precision
203 float as_float();
204
205 // with precision/noprecision
206 int32_t set( float val );
207
208 std::string attrName = {""};
209 struct RdValue
210 {
211 std::shared_ptr<ReadGroup> gr;
212 size_t grIndex = {0};
213 int32_t get();
214 float getF();
215 bool statusOk();
216 UA_StatusCode status();
217 };
218 RdValue rval[numChannels];
219
220 struct WrValue
221 {
222 std::shared_ptr<WriteGroup> gr;
223 size_t grIndex = {0};
224 bool set( int32_t val );
225 bool setF( float val );
226 bool statusOk();
227 UA_StatusCode status();
228 const UA_WriteValue& ref();
229 static void init( UA_WriteValue* wval, const std::string& nodeId, const std::string& type, int32_t defvalue );
230 };
231 WrValue wval[numChannels];
232
233 friend std::ostream& operator<<(std::ostream& os, const OPCAttribute& inf );
234 friend std::ostream& operator<<(std::ostream& os, const std::shared_ptr<OPCAttribute>& inf );
235 };
236
239 {
240 emNone = 0,
245 emLastNumber
246 };
247
248 protected:
249
250 enum Timers
251 {
252 tmUpdates
253 };
254
255 struct Channel;
256 void channel1Thread();
257 void channel2Thread();
258 void channelThread( Channel* ch );
259 bool prepare();
260 void channelExchange( Tick tick, Channel* ch, bool writeOn );
261 void updateFromChannel( Channel* ch );
262 void updateToChannel( Channel* ch );
263 void updateFromSM();
264 void writeToSM();
265 bool isUpdateSM( bool wrFunc ) const noexcept;
266
267 virtual void sysCommand( const uniset::SystemMessage* sm ) override;
268 virtual void askSensors( UniversalIO::UIOCommand cmd );
269 virtual void sensorInfo( const uniset::SensorMessage* sm ) override;
270 virtual void timerInfo( const uniset::TimerMessage* sm ) override;
271 virtual bool activateObject() override;
272 virtual bool deactivateObject() override;
273
274 // чтение файла конфигурации
275 void readConfiguration();
276 bool initIOItem( UniXML::iterator& it );
277 bool readItem( const std::shared_ptr<UniXML>& xml, UniXML::iterator& it, xmlNode* sec );
278 bool waitSM();
279 bool tryConnect(Channel* ch);
280 void initOutputs();
281
282 xmlNode* confnode = { 0 };
283 timeout_t polltime = { 100 };
284 timeout_t updatetime = { 100 };
286 typedef std::vector< std::shared_ptr<OPCAttribute> > IOList;
287 IOList iolist;
288 size_t maxItem = { 0 };
289
290 struct Channel
291 {
292 size_t num;
293 size_t idx;
294 std::shared_ptr<OPCUAClient> client;
295 uniset::Trigger trStatus;
296 uniset::PassiveTimer ptTimeout;
297 std::atomic_bool status = { false };
298 std::string addr;
299 std::string user;
300 std::string pass;
301 std::unordered_map<Tick, std::shared_ptr<ReadGroup>> readValues;
302 std::unordered_map<Tick, std::shared_ptr<WriteGroup>> writeValues;
304 IOController::IOStateList::iterator respond_it;
305 };
306 Channel channels[numChannels];
307 uniset::Trigger noConnections;
308 std::atomic_uint32_t currentChannel = { 0 };
309
310 uniset::timeout_t reconnectPause = { 10000 };
311 int filtersize = { 0 };
312 float filterT = { 0.0 };
313
314 std::string s_field;
315 std::string s_fvalue;
316 std::optional<std::regex> s_fvalue_re;
317
318 std::shared_ptr<SMInterface> shm;
319 std::string prefix;
320 std::string prop_prefix;
321
322 PassiveTimer ptHeartBeat;
323 uniset::ObjectId sidHeartBeat;
324 int maxHeartBeat = { 10 };
325 IOController::IOStateList::iterator itHeartBeat;
326
327 bool force = { false };
328 bool force_out = { false };
329 bool writeToAllChannels = { false };
330 timeout_t smReadyTimeout = { 15000 };
332 std::atomic_bool activated = { false };
333 std::atomic_bool cancelled = { false };
334 std::atomic_bool readconf_ok = { false };
335 int activateTimeout;
336 uniset::ObjectId sidTestSMReady = { uniset::DefaultObjectId };
338 IOController::IOStateList::iterator itRespond;
339
340 std::shared_ptr<LogAgregator> loga;
341 std::shared_ptr<DebugStream> opclog;
342 std::shared_ptr<LogServer> logserv;
343 std::string logserv_host = {""};
344 int logserv_port = {0};
345
346 std::shared_ptr< ThreadCreator<OPCUAExchange> > thrChannel[numChannels];
347
349 IOController::IOStateList::iterator itExchangeMode;
350 long exchangeMode = { emNone };
352 VMonitor vmon;
353
354 private:
355 };
356 // --------------------------------------------------------------------------
357} // end of namespace uniset
358// -----------------------------------------------------------------------------
359#endif // OPCUAExchange_H_
360// -----------------------------------------------------------------------------
Definition OPCUAExchange.h:149
timeout_t smReadyTimeout
Definition OPCUAExchange.h:330
bool writeToAllChannels
Definition OPCUAExchange.h:329
uniset::ObjectId sidExchangeMode
Definition OPCUAExchange.h:348
bool force
Definition OPCUAExchange.h:327
timeout_t updatetime
Definition OPCUAExchange.h:284
virtual bool activateObject() override
Активизация объекта (переопределяется для необходимых действий после активизации)
Definition OPCUAExchange.cc:1219
bool force_out
Definition OPCUAExchange.h:328
xmlNode * confnode
Definition OPCUAExchange.h:282
virtual bool deactivateObject() override
Деактивация объекта (переопределяется для необходимых действий при завершении работы)
Definition OPCUAExchange.cc:1233
IOList iolist
Definition OPCUAExchange.h:287
timeout_t polltime
Definition OPCUAExchange.h:283
ExchangeMode
Definition OPCUAExchange.h:239
@ emSkipExchange
Definition OPCUAExchange.h:244
@ emNone
Definition OPCUAExchange.h:240
@ emWriteOnly
Definition OPCUAExchange.h:241
@ emSkipSaveToSM
Definition OPCUAExchange.h:243
@ emReadOnly
Definition OPCUAExchange.h:242
long exchangeMode
Definition OPCUAExchange.h:350
Пассивный таймер
Definition PassiveTimer.h:94
Definition MessageType.h:127
Definition MessageType.h:171
Definition MessageType.h:214
Definition Trigger.h:31
Definition UniSetObject.h:80
Definition VMonitor.h:117
Definition Mutex.h:32
Definition Calibration.h:27
const ObjectId DefaultObjectId
Definition UniSetTypes.h:71
long ObjectId
Definition UniSetTypes_i.idl:30
Definition IOBase.h:35
Definition OPCUAExchange.h:291
Definition OPCUAExchange.h:210
Definition OPCUAExchange.h:221
Definition OPCUAExchange.h:186
Definition OPCUAExchange.h:175
Definition OPCUAExchange.h:180
Definition UniSetTypes_i.idl:65