Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added standard examples for open62541(pp) #39

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
"cacheVariables": {
"CPP_STARTER_USE_SML": "ON",
"CPP_STARTER_USE_BOOST_BEAST": "ON",
"CPP_STARTER_USE_CROW": "ON"
"CPP_STARTER_USE_CROW": "ON",
"CPP_STARTER_USE_OPEN62541PP": "ON",
"CPP_STARTER_USE_OPEN62541": "ON"
}
},
{
Expand Down
2 changes: 2 additions & 0 deletions cmake/Options.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,5 @@ OPTION(CPP_STARTER_USE_CROW "Enable compilation of crow sample" OFF)
OPTION(CPP_STARTER_USE_CPPZMQ_PROTO "Enable compilation of protobuf and cppzmq sample" OFF)
OPTION(CPP_STARTER_USE_EMBEDDED_TOOLCHAIN "Enable compilation of an example cortex m4 project" OFF)
OPTION(CPP_STARTER_USE_QT "Enable compilation of an example QT project" OFF)
OPTION(CPP_STARTER_USE_OPEN62541PP "Enable compilation of an example open62541pp wrapper project" OFF)
OPTION(CPP_STARTER_USE_OPEN62541 "Enable compilation of an example open62541 project" OFF)
4 changes: 2 additions & 2 deletions conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
class HelloConan(ConanFile):
settings = 'os', 'compiler', 'build_type', 'arch'
generators = 'CMakeDeps', 'CMakeToolchain'
default_options = {'fmt/*:header_only': True, 'spdlog/*:header_only': True, 'qt/*:with_fontconfig': False}
default_options = {'fmt/*:header_only': True, 'spdlog/*:header_only': True, 'qt/*:with_fontconfig': False, 'open62541/*:cpp_compatible': True}

def configure(self):
cmake = CMakeToolchain(self)
Expand All @@ -24,7 +24,7 @@ def configure(self):
requirement = ['catch2/3.7.0', 'gtest/1.15.0', 'docopt.cpp/0.6.3',
'spdlog/1.14.1', 'sml/1.1.11', 'nlohmann_json/3.11.3',
'boost/1.83.0', 'crowcpp-crow/1.2.0', 'cppzmq/4.10.0',
'protobuf/5.27.0']
'protobuf/5.27.0', 'open62541/1.3.9']
self.requires = conans.model.requires.Requirements(requirement)

def build(self):
Expand Down
12 changes: 12 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,18 @@ IF(CPP_STARTER_USE_QT)
ADD_SUBDIRECTORY(qt)
ENDIF()

# open62541pp example
IF(CPP_STARTER_USE_OPEN62541PP)
MESSAGE("Using open62541pp")
ADD_SUBDIRECTORY(open62541pp)
ENDIF()

# open62541 example
IF(CPP_STARTER_USE_OPEN62541)
MESSAGE("Using open62541")
ADD_SUBDIRECTORY(open62541)
ENDIF()


FIND_PACKAGE(docopt REQUIRED)
FIND_PACKAGE(spdlog REQUIRED)
Expand Down
5 changes: 5 additions & 0 deletions src/open62541/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ADD_EXECUTABLE(open62541_client client.cpp)
TARGET_LINK_LIBRARIES(open62541_client PRIVATE open62541::open62541)

ADD_EXECUTABLE(open62541_server server.cpp)
TARGET_LINK_LIBRARIES(open62541_server PRIVATE open62541::open62541)
28 changes: 28 additions & 0 deletions src/open62541/client.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include <open62541/client.h>
#include <open62541/client_highlevel.h>
#include <open62541/client_config_default.h>

int main()
{
/* Create a client and connect */
UA_Client *client = UA_Client_new();
UA_ClientConfig_setDefault(UA_Client_getConfig(client));
UA_StatusCode status = UA_Client_connect(client, "opc.tcp://localhost:4840");
if (status != UA_STATUSCODE_GOOD) {
UA_Client_delete(client);
return status;
}

/* Read the value attribute of the node. UA_Client_readValueAttribute is a
* wrapper for the raw read service available as UA_Client_Service_read. */
UA_Variant value;/* Variants can hold scalar values and arrays of any type */
UA_Variant_init(&value);
status = UA_Client_readValueAttribute(client, UA_NODEID_STRING(1, "the.answer"), &value);
if (status == UA_STATUSCODE_GOOD &&
UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_INT32])) { printf("the value is: %i\n", *static_cast<UA_Int32 *>(value.data)); }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

formatting?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we really want to show the C API with C printf in the C++ example project?

at least add a comment with explanation that this is the official C example and we might want to use (or write!) a C++ wrapper if possible.


/* Clean up */
UA_Variant_clear(&value);
UA_Client_delete(client);/* Disconnects the client internally */
return status == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE;
}
17 changes: 17 additions & 0 deletions src/open62541/server.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include <open62541/server.h>
#include <open62541/server_config_default.h>

int main()
{
UA_Server *server = UA_Server_new();
UA_Server_run_startup(server);

/* Should the server networklayer block (with a timeout) until a message
arrives or should it return immediately? */
const UA_Boolean waitInternal = true;
while (true) { UA_Server_run_iterate(server, waitInternal); }

UA_Server_run_shutdown(server);
UA_Server_delete(server);
return 0;
}
16 changes: 16 additions & 0 deletions src/open62541pp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
INCLUDE(FetchContent)

FETCHCONTENT_DECLARE(
open62541pp
GIT_REPOSITORY https://github.com/open62541pp/open62541pp.git
GIT_TAG v0.15.0
)
FETCHCONTENT_MAKEAVAILABLE(open62541pp)

INCLUDE_DIRECTORIES(${open62541pp_SOURCE_DIR})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use target_include_directories instead


ADD_EXECUTABLE(open62541pp_client client.cpp)
TARGET_LINK_LIBRARIES(open62541pp_client PRIVATE open62541pp::open62541pp)

ADD_EXECUTABLE(open62541pp_server server.cpp)
TARGET_LINK_LIBRARIES(open62541pp_server PRIVATE open62541pp::open62541pp)
13 changes: 13 additions & 0 deletions src/open62541pp/client.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include <iostream>

#include <open62541pp/open62541pp.h>

int main() {
opcua::Client client;
client.connect("opc.tcp://localhost:4840");

opcua::Node node = client.getNode(opcua::VariableId::Server_ServerStatus_CurrentTime);
const auto dt = node.readValueScalar<opcua::DateTime>();

std::cout << "Server date (UTC): " << dt.format("%Y-%m-%d %H:%M:%S") << "\n";
}
15 changes: 15 additions & 0 deletions src/open62541pp/server.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include <open62541pp/open62541pp.h>

int main() {
opcua::Server server;

// Add a variable node to the Objects node
opcua::Node parentNode = server.getObjectsNode();
opcua::Node myIntegerNode = parentNode.addVariable({1, 1000}, "TheAnswer");
// Write some node attributes
myIntegerNode.writeDisplayName({"en-US", "The Answer"})
.writeDataType(opcua::DataTypeId::Int32)
.writeValueScalar(42);

server.run();
}