C++ Tutorials¶
This directory contains C++ tutorial examples demonstrating how to use the Dracal device service API.
Prerequisites¶
- Dracal device service version 3.6.0 or higher installed and running
- CMake 3.15 or higher
- A C++ compiler with C++11 support
Getting Started¶
The tutorials are installed by default with the Dracal installer at:
- Windows:
C:\Program Files\Dracal\Tutorials\CPP - Ubuntu:
/usr/share/dracal-utilities/examples/CPP
⚠️ Important: You must copy the tutorial files to another directory. This avoids:
- Altering the original tutorial files
- Permission issues when building in system directories (which requires Administrator privileges)
Examples Overview¶
- example_1 (
1_check_running/main.cpp): Check if the Dracal Device Service is running - example_2 (
2_device_list/main.cpp): List all available devices - example_3 (
3_get_device/main.cpp): Retrieve information about a specific device - example_4 (
4_RTD300/main.cpp): Retrieve all channels information from the first RTD300 found
Pre-Built Executables¶
Pre-built executables are installed by default so you can test your installation before building. To help differentiate them from locally built executables, the pre-built executables are named:
-
Windows:
-
dracal-cpp-latest-example-1.exe dracal-cpp-latest-example-2.exedracal-cpp-latest-example-3.exe-
dracal-cpp-latest-example-4.exe -
Ubuntu:
-
dracal-cpp-latest-example-1 dracal-cpp-latest-example-2dracal-cpp-latest-example-3dracal-cpp-latest-example-4
The executables are located by default in
- Windows:
C:\Program Files\Dracal\Tutorials\CPP\Examples - Ubuntu: in the system path
Typical Output¶
dracal-cpp-latest-example-1
{
"service_name": "dracal-device-service",
"status": "ok",
"version": {
"major": 3,
"minor": 6,
"patch": 0,
"tag": "v3.6.0",
"tweak": 0
}
}
Dracal Device Service is running
Press enter to close this window...
dracal-cpp-latest-example-2
Dracal devices found:
VCP-BAR20 with serial E20298
VCP-RTD300-CAL with serial E22377
Press enter to close this window...
dracal-cpp-latest-example-3
First Dracal device found:
VCP-BAR20 with serial E20298
Channels
altitude : timestamp: 2025-12-10T19:40:49.194Z value: 186797.94 mm
atmospheric_pressure : timestamp: 2025-12-10T19:40:49.194Z value: 99.10 kPa
Press enter to close this window...
dracal-cpp-latest-example-4
First Dracal RTD300 device found:
Product: VCP-RTD300-CAL, Serial: E22377
Temperature:
timestamp: 2025-12-10T19:41:03.119Z
value : 123.36 °C
Press enter to close this window...
Building the Examples¶
Step 1: Configure the Build¶
From the tutorials directory root, run:
cmake -B build -S .
Step 2: Build the Project¶
cmake --build build --config Release
Step 3: Install the Executables¶
cmake --install build
Step 4: Run the Examples¶
Run the examples from the tutorials directory root:
Windows:
.\bin\dracal-cpp-3.6.0-example-1.exe
.\bin\dracal-cpp-3.6.0-example-2.exe
.\bin\dracal-cpp-3.6.0-example-3.exe
.\bin\dracal-cpp-3.6.0-example-4.exe
Ubuntu:
./bin/dracal-cpp-3.6.0-example-1
./bin/dracal-cpp-3.6.0-example-2
./bin/dracal-cpp-3.6.0-example-3
./bin/dracal-cpp-3.6.0-example-4
Troubleshooting¶
If you encounter build issues:
- Ensure the Dracal Device Service is installed and running
- Verify CMake version:
cmake --version - Check that you have write permissions in your build directory
Source¶
1_check_running/main.cpp¶
#include <hv/HttpClient.h>
#include <hv/hlog.h>
#include <hv/hv.h>
#include <iostream>
#include <string>
bool check_if_dracal_device_service_is_runnig(const std::string &url);
int main() {
const bool is_running = check_if_dracal_device_service_is_runnig("http://localhost:11395/dracal-service-info");
if (!is_running) {
std::cout << "The Dracal Device Serice is not running" << std::endl;
std::cout << std::endl << "\nPress enter to close this window..." << std::endl;
std::cin.get();
return -1;
}
std::cout << "Dracal Device Service is running" << std::endl;
std::cout << std::endl << "\nPress enter to close this window..." << std::endl;
std::cin.get();
return 0;
}
bool check_if_dracal_device_service_is_runnig(const std::string &url) {
hlog_disable();
hv::HttpClient client;
HttpRequest req;
HttpResponse resp;
req.method = HTTP_GET;
req.url = url;
req.timeout = 1;
int ret = client.send(&req, &resp);
if (ret != 0) {
return false;
}
if (resp.status_code != HTTP_STATUS_OK) {
return false;
}
std::cout << resp.body << std::endl;
return true;
}
2_device_list/main.cpp¶
#include <fmt/format.h>
#include <hv/HttpClient.h>
#include <hv/hlog.h>
#include <nlohmann/json.hpp>
#include <iostream>
using json = nlohmann::json;
using json_pointer = nlohmann::json::json_pointer;
json get_dracal_devices(const std::string &url);
int main() {
const json devices = get_dracal_devices("http://localhost:11395/3.6.0/devices/usb");
if (devices.empty()) {
std::cout << "No Dracal devices found." << std::endl;
std::cout << std::endl << "Press enter to close this window..." << std::endl;
std::cin.get();
return -1;
}
std::cout << "Dracal devices found:" << std::endl;
for (const auto &device : devices.items()) {
const std::string &serial = device.key();
const std::string &product = devices[json_pointer(fmt::format("/{}/info/product", serial))];
std::cout << fmt::format("\t{} with serial {}", product, serial) << std::endl;
}
std::cout << std::endl << "\nPress enter to close this window..." << std::endl;
std::cin.get();
return 0;
}
json get_dracal_devices(const std::string &url) {
hlog_disable();
hv::HttpClient client;
HttpRequest req;
HttpResponse resp;
req.method = HTTP_GET;
req.url = url;
req.timeout = 1;
int ret = client.send(&req, &resp);
if (ret != 0) {
return json::object();
}
if (resp.status_code != HTTP_STATUS_OK) {
return json::object();
}
const json js = json::parse(resp.body);
return js["devices"];
}
3_get_device/main.cpp¶
#include <fmt/format.h>
#include <hv/HttpClient.h>
#include <hv/hlog.h>
#include <nlohmann/json.hpp>
#include <iostream>
using json = nlohmann::json;
using json_pointer = nlohmann::json::json_pointer;
json get_dracal_devices(const std::string &url);
int main() {
const json devices = get_dracal_devices("http://localhost:11395/3.6.0/devices/usb");
if (devices.empty()) {
std::cout << "No Dracal devices found." << std::endl;
std::cout << std::endl << "\nPress enter to close this window..." << std::endl;
std::cin.get();
return -1;
}
std::cout << "First Dracal device found:" << std::endl;
const std::string &serial = devices.items().begin().key();
const json &device = devices[serial];
const std::string &product = device[json_pointer("/info/product")];
std::cout << fmt::format("{} with serial {}", product, serial) << std::endl;
std::cout << fmt::format("Channel{}", device["channels"].size() == 0 ? "" : "s") << std::endl;
for (const auto channel : device["channels"].items()) {
const std::string &name = channel.key();
const double value = device[json_pointer(fmt::format("/channels/{}/value/magnitude", name))];
const std::string &unit = device[json_pointer(fmt::format("/channels/{}/value/unit", name))];
const std::string &ts = device[json_pointer(fmt::format("/channels/{}/value/timestamp", name))];
std::cout << fmt::format("\t{:<25}: timestamp: {} value: {:.2f} {}", name, ts, value, unit) << std::endl;
}
std::cout << std::endl << "\nPress enter to close this window..." << std::endl;
std::cin.get();
return 0;
}
json get_dracal_devices(const std::string &url) {
hlog_disable();
hv::HttpClient client;
HttpRequest req;
HttpResponse resp;
req.method = HTTP_GET;
req.url = url;
req.timeout = 1;
int ret = client.send(&req, &resp);
if (ret != 0) {
return json::object();
}
if (resp.status_code != HTTP_STATUS_OK) {
return json::object();
}
const json js = json::parse(resp.body);
return js["devices"];
}
4_RTD300/main.cpp¶
#include <fmt/format.h>
#include <hv/HttpClient.h>
#include <hv/hlog.h>
#include <nlohmann/json.hpp>
#include <iostream>
using json = nlohmann::json;
using json_pointer = nlohmann::json::json_pointer;
json get_first_dracal_RTD_300_devices(const std::string &url);
int main() {
const json device = get_first_dracal_RTD_300_devices("http://localhost:11395/3.6.0/devices/usb");
if (device.empty()) {
std::cout << "No Dracal RTD300 devices found." << std::endl;
std::cout << std::endl << "Press enter to close this window..." << std::endl;
std::cin.get();
return -1;
}
std::cout << "First Dracal RTD300 device found:" << std::endl;
const std::string serial = device["devices"].items().begin().key();
const std::string product = device[json_pointer(fmt::format("/devices/{}/info/product", serial))];
const double value = device[json_pointer(fmt::format("/devices/{}/channels/temperature/value/magnitude", serial))];
const std::string &unit = device[json_pointer(fmt::format("/devices/{}/channels/temperature/value/unit", serial))];
const std::string &ts =
device[json_pointer(fmt::format("/devices/{}/channels/temperature/value/timestamp", serial))];
std::cout << fmt::format("\tProduct: {}, Serial: {}", product, serial) << std::endl;
std::cout << "\t\tTemperature:" << std::endl;
std::cout << fmt::format("\t\t\ttimestamp: {}", ts) << std::endl;
std::cout << fmt::format("\t\t\tvalue : {:.2f} {}", value, unit) << std::endl;
std::cout << std::endl << "\nPress enter to close this window..." << std::endl;
std::cin.get();
return 0;
}
json get_first_dracal_RTD_300_devices(const std::string &url) {
hlog_disable();
hv::HttpClient client;
HttpRequest req;
HttpResponse resp;
req.method = HTTP_GET;
req.url = url;
req.timeout = 1;
int ret = client.send(&req, &resp);
if (ret != 0) {
return json::object();
}
if (resp.status_code != HTTP_STATUS_OK) {
return json::object();
}
const json response = json::parse(resp.body);
for (const auto &device : response["devices"].items()) {
const std::string &serial = device.key();
const std::string &product = response[json_pointer(fmt::format("/devices/{}/info/product", serial))];
if (product == "USB-RTD300" || product == "VCP-RTD300" || product == "USB-RTD300-CAL" ||
product == "VCP-RTD300-CAL") {
json js = json::object();
js["devices"] = json::object();
js["devices"][serial] = device.value();
return js;
}
}
return json::object();
}