UniSet @VERSION@
OPCUAClient.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 OPCUAClient_H_
18#define OPCUAClient_H_
19// -----------------------------------------------------------------------------
20#include <string>
21#include <vector>
22#include <unordered_map>
23#include <map>
24#include <variant>
25
26#include "open62541pp/open62541pp.hpp"
27#include "open62541pp/detail/exceptioncatcher.hpp"
28#include "open62541pp/detail/client_utils.hpp"
29
30#include "Exceptions.h"
31#include "DebugStream.h"
32//--------------------------------------------------------------------------
33namespace uniset
34{
35 // -----------------------------------------------------------------------------
38 {
39 public:
41 virtual ~OPCUAClient();
42
43 bool connect( const std::string& addr );
44 bool connect( const std::string& addr, const std::string& user, const std::string& pass );
45 void disconnect() noexcept;
46
47 // supported types (other types are converted to these if possible)
48 enum class VarType : int
49 {
50 Int32 = 0,
51 Float = 1
52 };
53 static VarType str2vtype( std::string_view s );
54
55 struct ResultVar
56 {
57 ResultVar() {}
58 std::variant<int32_t, float> value = { 0 };
59 opcua::StatusCode status;
60 VarType type = { VarType::Int32 }; // by default
61
62 // get as int32_t (cast to int32_t if possible)
63 int32_t get();
64
65 template<class VType>
66 VType as()
67 {
68 try
69 {
70 return std::get<VType>(value);
71 }
72 catch(const std::bad_variant_access&) {}
73
74 return {};
75 }
76 };
77
78 opcua::StatusCode read(const std::vector<opcua::ua::ReadValueId>& attrs, std::vector<ResultVar>& results);
79 opcua::StatusCode write32( std::vector<opcua::ua::WriteValue>& values );
80 opcua::StatusCode write32( const std::string& attr, int32_t value );
81 opcua::StatusCode set( const std::string& attr, bool set );
82 opcua::StatusCode write( const opcua::ua::WriteValue& writeValue );
83
84 static opcua::ua::WriteValue makeWriteValue32( const std::string& name, int32_t val );
85 static opcua::ua::ReadValueId makeReadValue32( const std::string& name );
86
87 void onSessionActivated(opcua::StateCallback callback)
88 {
89 client.onSessionActivated(std::move(callback));
90 }
91
92 void onConnected(opcua::StateCallback callback)
93 {
94 client.onConnected(std::move(callback));
95 }
96
97 void onSessionClosed(opcua::StateCallback callback)
98 {
99 client.onSessionClosed(std::move(callback));
100 }
101
102 void onDisconnected(opcua::StateCallback callback)
103 {
104 client.onDisconnected(std::move(callback));
105 }
106
107 void runIterate(uint16_t timeoutMilliseconds)
108 {
109 client.runIterate(timeoutMilliseconds);
110 }
111
112 void onInactive(opcua::InactivityCallback callback)
113 {
114 client.onInactive(std::move(callback));
115 }
116
117 void onSubscriptionInactive(opcua::SubscriptionInactivityCallback callback)
118 {
119 client.onSubscriptionInactive(std::move(callback));
120 }
121
122 opcua::ua::IntegerId createSubscription(const opcua::SubscriptionParameters& parameters)
123 {
124 auto subscription = opcua::Subscription<opcua::Client>{client, parameters};
125 subscription.setPublishingMode(true);
126 return subscription.subscriptionId();
127 }
128
129 void rethrowException()
130 {
131 auto& exceptionCatcher = opcua::detail::getExceptionCatcher(client);
132 exceptionCatcher.rethrow(); // Работает только один раз, после повторной отправки удаляется!
133 }
134
135 opcua::StatusCode subscribeDataChanges(std::vector<opcua::ua::ReadValueId>& ids,
136 std::vector<OPCUAClient::ResultVar>& results,
137 float samplingInterval,
138 float publishingInterval);
139
140 size_t getSubscriptionSize()
141 {
142 size_t count = 0;
143 auto subscriptions = client.subscriptions();
144 for (auto& sub : subscriptions) {
145 count += sub.monitoredItems().size();
146 }
147 return count;
148 }
149
150 opcua::StatusCode deleteSubscription(opcua::ua::IntegerId subId)
151 {
152 return opcua::services::deleteSubscription(client, subId);
153 }
154
155 inline opcua::Node<opcua::Client> createNode(opcua::ua::VariableId nodeName)
156 {
157 return opcua::Node{client, nodeName};
158 }
159
160 std::shared_ptr<DebugStream> log();
161 void setLog( const std::shared_ptr<DebugStream>& dlog );
162
163 protected:
164
165 opcua::Client client;
166 std::shared_ptr<DebugStream> dlog;
167
168 private:
169 void processResult(const opcua::String& node_name, const opcua::DataValue& in, ResultVar& out);
170 };
171 // --------------------------------------------------------------------------
172} // end of namespace uniset
173// -----------------------------------------------------------------------------
174#endif // OPCUAClient_H_
175// -----------------------------------------------------------------------------
Definition OPCUAClient.h:38
Definition AccessConfig.h:30
Definition OPCUAClient.h:56