Rust SDK for connecting ESP32 boards to Bytebeam 🦀

Rust SDK for connecting ESP32 boards to Bytebeam 🦀

You built a really cool project in Rust for an ESP32 board, but does it have remote monitoring? Can you perform hassle free OTA updates? Worry not! Bytebeam has you covered <3

But the question is "How can I connect my esp-rs project to bytebeam cloud?" Well, the answer is simple; all you need is an internet connection and the Bytebeam ESP-RS SDK!

Let me walk you through how you can set up the board and use our SDK.

This post assumes that you are familiar with building and flashing Rust applications on ESP board, if not, The Rust on ESP book will be a good start, come back to this post later.
This post also assumes you are familiar with Bytebeam, if not it might be a good idea to start with the docs

Let's get started

It's really simple to get started; just add bytebeam-esp-rs as a dependency in your Cargo.toml, and TA-DA! You are almost all set to use it....almost!? Before you can connect, Bytebeam cloud needs to verify that the device actually belongs to you, for that you will need the certificates and keys. You can get your config file by following provisioning a device guide.

Provisioning

bytebeam-esp-rs requires a file named device_config.json to be present in SPIFFS partition of your board. To make it easier, we provide a provision application. All you need to do is put your device_config.json inside the provision project (right where device_config.json.example is) and flash it!

$ git clone https://github.com/bytebeamio/bytebeam-esp-rs-sdk.git
$ cd bytebeam-esp-rs-sdk/tools/provision

# put device_config.json here!!

$ cargo espflash --release --monitor --partition-table partitions.csv
NOTE: partitions.csv file is already present. If you want to use your custom partition table, replace the partitions.csv file before flashing.

You can terminate the program after seeing the "Provisioning Done" message. Now you are all set you to use the SDK.

Add bytebeam-esp-rs to your project

Add bytebeam-esp-rs in your Cargo.toml

cargo add bytebeam-esp-rs

This will add entry in your Cargo.toml like:

[dependency]
bytebeam-esp-rs = "0.1.0"

Now, in your main.rs, initialise ByteBeamClient

/* other imports */
use bytebeam_esp_rs::ByteBeamClient;

fn main() -> anyhow::Result<()> {
    /*...
    Setup esp for Rust 
    Connect to internet and initialize SNTP/NTP to sync time
    ...*/

    let bytebeam_client = ByteBeamClient::init()?;

    // use bytebeam_client here!
}

Voila! The client is now ready to do all sorts of wonders!

Examples

Let me show you some examples of how you can use SDK. For more details, check out our docs. You can also see full-fledged examples in our GitHub repository.

Streams are used for pushing data to Bytebeam Cloud. In order to publish to a stream, you can use the publish_to_stream method:

#[derive(Serialize)]
struct LedStream {
    // your custom fields!
    status: String,
}

fn main() {
    // ....
    let bytebeam_client = ByteBeamClient::init()?;

    let sequence = 1;
    let message = LedStream {
        status: "ON".into(),
    };

    // You can remove .expect and handle the error
    bytebeam_client
        .publish_to_stream("led_status", sequence, message)
        .expect("published successfully");
    //...
}
The data we want to publish must be something that can be serialized. The easiest way is to define a struct with the fields that are in the stream ( except id and timestamp, we add them internally ), and add serde::Serialize derive attribute.

For sending commands to your ESP using actions, you can register an action handler using the register_action_handle method:

let bytebeam_client = ByteBeamClient::init()?;

// You can pass a closure
bytebeam_client.register_action_handle(
    "example_action".into(),
    &|action: Action, bytebeam_client: &ByteBeamClient| {
        // handler body
    },
);

// or you can also pass down a function
bytebeam_client.register_action_handle("toggle".into(), &toggle);

// Function signature
fn toggle(action: Action, bytebeam_client: &ByteBeamClient) {
    // function body
}
An action handler function must take Action and &ByteBeamClient as arguments.

Enabling Over-The-Air updates is simple:

bytebeam_client.enable_ota();

To learn more about firmware updates on Bytebeam, see the docs.

Conclusion

We saw how easy it is to add the Byteam ESP-RS SDK to your existing project. I hope you will create amazing projects with the SDK. Don't forget to give us feedback. If you face any issues, or want to contribute, feel free to open issues and PRs on our GitHub repository.

You can explore more about esp and Bytebeam with this blog series.

CHALLENGE: Try to port the example in those blog posts from C to Rust and add them to /examples. ( please open a PR as well! )