Skip to content

Commit 1388fa1

Browse files
authored
Merge pull request Zuehlke#39 from StephanKa/feature/add-open62541-examples
added standard examples for open62541(pp)
2 parents 77349f9 + 0bf494f commit 1388fa1

File tree

10 files changed

+120
-2
lines changed

10 files changed

+120
-2
lines changed

CMakePresets.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
"cacheVariables": {
1919
"CPP_STARTER_USE_SML": "ON",
2020
"CPP_STARTER_USE_BOOST_BEAST": "ON",
21-
"CPP_STARTER_USE_CROW": "ON"
21+
"CPP_STARTER_USE_CROW": "ON",
22+
"CPP_STARTER_USE_OPEN62541PP": "ON",
23+
"CPP_STARTER_USE_OPEN62541": "ON"
2224
}
2325
},
2426
{

cmake/Options.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ OPTION(CPP_STARTER_USE_CROW "Enable compilation of crow sample" OFF)
3636
OPTION(CPP_STARTER_USE_CPPZMQ_PROTO "Enable compilation of protobuf and cppzmq sample" OFF)
3737
OPTION(CPP_STARTER_USE_EMBEDDED_TOOLCHAIN "Enable compilation of an example cortex m4 project" OFF)
3838
OPTION(CPP_STARTER_USE_QT "Enable compilation of an example QT project" OFF)
39+
OPTION(CPP_STARTER_USE_OPEN62541PP "Enable compilation of an example open62541pp wrapper project" OFF)
40+
OPTION(CPP_STARTER_USE_OPEN62541 "Enable compilation of an example open62541 project" OFF)
3941

4042
# test frameworks
4143
OPTION(CPP_STARTER_USE_CATCH2 "Enable compilation of an example test project using catch2" ON)

conanfile.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
class HelloConan(ConanFile):
88
settings = 'os', 'compiler', 'build_type', 'arch'
99
generators = 'CMakeDeps', 'CMakeToolchain'
10-
default_options = {'fmt/*:header_only': True, 'spdlog/*:header_only': True, 'qt/*:with_fontconfig': False}
10+
default_options = {'fmt/*:header_only': True, 'spdlog/*:header_only': True, 'qt/*:with_fontconfig': False, 'open62541/*:cpp_compatible': True}
1111

1212
def requirements(self):
1313
if self.settings.get_safe('arch') == 'armv7':
@@ -22,12 +22,14 @@ def requirements(self):
2222
if os.getenv("CONFIGURE_QT") == '1':
2323
self.requires('qt/6.7.3')
2424
else:
25+
2526
self.requires('sml/1.1.11')
2627
self.requires('nlohmann_json/3.11.3')
2728
self.requires('boost/1.87.0')
2829
self.requires('crowcpp-crow/1.2.0')
2930
self.requires('cppzmq/4.10.0')
3031
self.requires('protobuf/5.29.3')
32+
self.requires('open62541/1.4.6')
3133

3234
def configure(self):
3335
cmake = CMakeToolchain(self)

src/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,18 @@ IF(CPP_STARTER_USE_QT)
3636
ADD_SUBDIRECTORY(qt)
3737
ENDIF()
3838

39+
# open62541pp example
40+
IF(CPP_STARTER_USE_OPEN62541PP)
41+
MESSAGE("Using open62541pp")
42+
ADD_SUBDIRECTORY(open62541pp)
43+
ENDIF()
44+
45+
# open62541 example
46+
IF(CPP_STARTER_USE_OPEN62541)
47+
MESSAGE("Using open62541")
48+
ADD_SUBDIRECTORY(open62541)
49+
ENDIF()
50+
3951

4052
FIND_PACKAGE(docopt REQUIRED)
4153
FIND_PACKAGE(spdlog REQUIRED)

src/open62541/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
ADD_EXECUTABLE(open62541_client client.cpp)
2+
TARGET_LINK_LIBRARIES(open62541_client PRIVATE open62541::open62541)
3+
4+
ADD_EXECUTABLE(open62541_server server.cpp)
5+
TARGET_LINK_LIBRARIES(open62541_server PRIVATE open62541::open62541)

src/open62541/client.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#include <open62541/client.h>
2+
#include <open62541/client_highlevel.h>
3+
#include <open62541/client_config_default.h>
4+
5+
// This example is the original one from the open62541 examples
6+
7+
int main()
8+
{
9+
/* Create a client and connect */
10+
UA_Client *client = UA_Client_new();
11+
UA_ClientConfig_setDefault(UA_Client_getConfig(client));
12+
UA_StatusCode status = UA_Client_connect(client, "opc.tcp://localhost:4840");
13+
if (status != UA_STATUSCODE_GOOD) {
14+
UA_Client_delete(client);
15+
return status;
16+
}
17+
18+
/* Read the value attribute of the node. UA_Client_readValueAttribute is a
19+
* wrapper for the raw read service available as UA_Client_Service_read. */
20+
UA_Variant value;/* Variants can hold scalar values and arrays of any type */
21+
UA_Variant_init(&value);
22+
status = UA_Client_readValueAttribute(client, UA_NODEID_STRING(1, "the.answer"), &value);
23+
if (status == UA_STATUSCODE_GOOD && UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_INT32]))
24+
{
25+
printf("the value is: %i\n", *static_cast<UA_Int32 *>(value.data));
26+
}
27+
28+
/* Clean up */
29+
UA_Variant_clear(&value);
30+
UA_Client_delete(client);/* Disconnects the client internally */
31+
return status == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE;
32+
}

src/open62541/server.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#include <open62541/server.h>
2+
#include <open62541/server_config_default.h>
3+
4+
// This example is the original one from the open62541 examples
5+
6+
int main()
7+
{
8+
UA_Server *server = UA_Server_new();
9+
UA_Server_run_startup(server);
10+
11+
/* Should the server networklayer block (with a timeout) until a message
12+
arrives or should it return immediately? */
13+
const UA_Boolean waitInternal = true;
14+
while (true) { UA_Server_run_iterate(server, waitInternal); }
15+
16+
UA_Server_run_shutdown(server);
17+
UA_Server_delete(server);
18+
return 0;
19+
}

src/open62541pp/CMakeLists.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
INCLUDE(FetchContent)
2+
3+
FETCHCONTENT_DECLARE(
4+
open62541pp
5+
GIT_REPOSITORY https://github.com/open62541pp/open62541pp.git
6+
GIT_TAG v0.15.0
7+
)
8+
FETCHCONTENT_MAKEAVAILABLE(open62541pp)
9+
10+
ADD_EXECUTABLE(open62541pp_client client.cpp)
11+
TARGET_LINK_LIBRARIES(open62541pp_client PRIVATE open62541pp::open62541pp)
12+
TARGET_INCLUDE_DIRECTORIES(open62541pp_client PUBLIC ${open62541pp_SOURCE_DIR})
13+
14+
ADD_EXECUTABLE(open62541pp_server server.cpp)
15+
TARGET_LINK_LIBRARIES(open62541pp_server PRIVATE open62541pp::open62541pp)
16+
TARGET_INCLUDE_DIRECTORIES(open62541pp_server PUBLIC ${open62541pp_SOURCE_DIR})

src/open62541pp/client.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include <iostream>
2+
3+
#include <open62541pp/open62541pp.h>
4+
5+
int main() {
6+
opcua::Client client;
7+
client.connect("opc.tcp://localhost:4840");
8+
9+
opcua::Node node = client.getNode(opcua::VariableId::Server_ServerStatus_CurrentTime);
10+
const auto dt = node.readValueScalar<opcua::DateTime>();
11+
12+
std::cout << "Server date (UTC): " << dt.format("%Y-%m-%d %H:%M:%S") << "\n";
13+
}

src/open62541pp/server.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#include <open62541pp/open62541pp.h>
2+
3+
int main() {
4+
opcua::Server server;
5+
6+
// Add a variable node to the Objects node
7+
opcua::Node parentNode = server.getObjectsNode();
8+
opcua::Node myIntegerNode = parentNode.addVariable({1, 1000}, "TheAnswer");
9+
// Write some node attributes
10+
myIntegerNode.writeDisplayName({"en-US", "The Answer"})
11+
.writeDataType(opcua::DataTypeId::Int32)
12+
.writeValueScalar(42);
13+
14+
server.run();
15+
}

0 commit comments

Comments
 (0)