Skip to content

C++ Tutorials

This directory contains C++ tutorial examples demonstrating how to use the Dracal device service API.

Prerequisites

  • Dracal device service version 3.8.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.exe
  • dracal-cpp-latest-example-3.exe
  • dracal-cpp-latest-example-4.exe

  • Ubuntu:

  • dracal-cpp-latest-example-1

  • dracal-cpp-latest-example-2
  • dracal-cpp-latest-example-3
  • dracal-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": 8,
        "patch": 0,
        "tag": "v3.8.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.8.0-example-1.exe
.\bin\dracal-cpp-3.8.0-example-2.exe
.\bin\dracal-cpp-3.8.0-example-3.exe
.\bin\dracal-cpp-3.8.0-example-4.exe

Ubuntu:

./bin/dracal-cpp-3.8.0-example-1
./bin/dracal-cpp-3.8.0-example-2
./bin/dracal-cpp-3.8.0-example-3
./bin/dracal-cpp-3.8.0-example-4

Troubleshooting

If you encounter build issues:

  1. Ensure the Dracal Device Service is installed and running
  2. Verify CMake version: cmake --version
  3. 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?pretty=true");

    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.8.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.8.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.8.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();
}