ScyllaDB University Live | Free Virtual Training Event
Learn more
ScyllaDB Documentation Logo Documentation
  • Deployments
    • Cloud
    • Server
  • Tools
    • ScyllaDB Manager
    • ScyllaDB Monitoring Stack
    • ScyllaDB Operator
  • Drivers
    • CQL Drivers
    • DynamoDB Drivers
  • Resources
    • ScyllaDB University
    • Community Forum
    • Tutorials
Install
Ask AI
ScyllaDB Docs ScyllaDB IoT Example Documentation Build an IoT App with C++

Build an IoT App with C++¶

Architecture¶

In this section, we will walk you through the CarePet commands and explain the code behind them. The project is a single executable care-pet that can be run in three different modes:

  • migrate - Creates the carepet keyspace and tables.

  • sensor - Generates pet health data and pushes it into the storage.

  • server - REST API service for tracking pets’ health state.

The application logic is split into corresponding components: migrate, sensor, and server. There is also a common component that contains shared code, such as database connection logic and data models.

Building the project¶

The project uses CMake for building. To build the project, you need to have a C++ compiler (like GCC or Clang), CMake, and the Boost library installed.

From the cpp directory, run the following commands:

mkdir -p build
cd build
cmake ..
make

This will create the care-pet executable in the cpp/build directory.

Migrate¶

The ./build/care-pet migrate --scylla-host $NODE1 command executes the migration logic. The main function in src/main.cpp parses the command-line arguments and, for the migrate mode, calls the run_migrate function from src/migrate/migrate.cpp.

The run_migrate function connects to the ScyllaDB cluster and executes the CQL commands from the data/care-pet-ddl.cql file to create the necessary keyspace and tables.

// In src/migrate/migrate.cpp
void run_migrate(const po::variables_map& vm) {
    std::cout << "Running in migrate mode\n";
    Database db(vm["scylla-host"].as<std::string>());
    db.connect();

    auto ddl_files = vm["ddl-file"].as<std::vector<std::string>>();
    for (const auto& file_path : ddl_files) {
        std::ifstream file(file_path);
        if (!file.is_open()) {
            std::cerr << "Error: Could not open DDL file '" << file_path << "'\n";
            continue;
        }
        std::string ddl_query((std::istreambuf_iterator<char>(file)),
                              std::istreambuf_iterator<char>());
        db.execute_query(ddl_query);
        std::cout << "Executed DDL from " << file_path << "\n";
    }
}

The care-pet-ddl.cql file contains CREATE KEYSPACE and CREATE TABLE statements for owner, pet, sensor, measurement, and sensor_avg tables, similar to the Java example.

You can check the database structure with:

$ docker exec -it carepet-scylla1 cqlsh
cqlsh> USE carepet;
cqlsh:carepet> DESCRIBE TABLES
cqlsh:carepet> DESCRIBE TABLE pet

Sensor¶

The sensor service simulates the collar’s activity. You can use the following command to run the sensor service:

$ NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' care-pet-scylla1)
$ ./build/care-pet sensor --scylla-host $NODE1 --seconds 60

This command executes the run_sensor function from src/sensor/sensor.cpp. This function simulates a pet collar, generating random data for an owner, a pet, and its sensors. It then periodically sends measurement data to the database.

// In src/sensor/sensor.cpp
void run_sensor(const po::variables_map& vm) {
    std::cout << "Running in sensor mode\n";
    Database db(vm["scylla-host"].as<std::string>());
    db.connect("carepet");

    // ... create random owner, pet, and sensors ...
    // ... save them to the database ...

    int seconds = vm["seconds"].as<int>();
    auto start_time = std::chrono::steady_clock::now();

    while (std::chrono::steady_clock::now() - start_time < std::chrono::seconds(seconds)) {
        for (const auto& s : sensors) {
            Measurement m = read_sensor_data(s);
            // ... insert measurement into the database ...
        }
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}

The code uses prepared statements to insert data into the measurement table efficiently.

Server¶

The server service is a REST API for tracking the pets’ health state. The service allows you to query the database via HTTP.

Run the following commands to start the server:

$ NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' care-pet-scylla1)
$ ./build/care-pet server --scylla-host $NODE1 --host 0.0.0.0 --port 8080

This starts an HTTP server using Boost.Beast. The server exposes several endpoints to retrieve data from the database. The handlers for these endpoints are defined in src/server/handlers.cpp.

For example, to get an owner’s data, you can use:

$ curl http://127.0.0.1:8080/api/owner/{id}

The server also aggregates the data and saves it to the database in the sensor_avg table, similar to the Java implementation.

Resources¶

  • ScyllaDB C++ Driver on Github

Was this page helpful?

PREVIOUS
Build an IoT App with CSharp
  • Create an issue
  • Edit this page

On this page

  • Build an IoT App with C++
    • Architecture
    • Building the project
    • Migrate
    • Sensor
    • Server
    • Resources
ScyllaDB IoT Example Documentation
  • master
    • master
  • Getting Started with CarePet: A sample IoT App
  • Deploy in cloud
  • Design and Data Model
  • Build with Go
  • Build with JavaScript
  • Build with Java
  • Build with Python
  • Build with PHP
  • Build with Rust
  • Build with CSharp
  • Build with C++
  • Care-Pet GitHub Repository
  • Care-Pet Blog
Docs Tutorials University Contact Us About Us
© 2025, ScyllaDB. All rights reserved. | Terms of Service | Privacy Policy | ScyllaDB, and ScyllaDB Cloud, are registered trademarks of ScyllaDB, Inc.
Last updated on 09 October 2025.
Powered by Sphinx 7.4.7 & ScyllaDB Theme 1.8.8
Ask AI