How to Build Direct Connected Devices

How to build Direct Connected devices with the SmartThings Platform

Direct connected devices do not require a middle cloud or a hub. After flashing the firmware the device will use the SmartThings platform as its backend provider. Communication happens directly between the platform and the device over MQTT. The SDK enables rapid development of these devices on a variety of low cost SOCs.

Workstation Setup

Prerequisites:

Development of Direct Connected devices with the SDK is currently optimized for Ubuntu workstations. The tutorial will be using the latest 20.04 release of Ubuntu. The distro does not matter, but a Debian-based distro will yield the best results. The instructions will assume that you are using a current distribution that utilizes apt packages.

Video Tutorial Part 1

As a base we need to install the following packages.

sudo apt-get install gcc git cmake gperf ninja-build ccache wget make libncurses-dev flex bison gperf python3 python3-pip python3-setuptools python3-serial python3-cryptography python3-future python3-pyparsing python3-pyelftools libffi-dev libssl-dev

Make Python 3 the default

sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 10

Note:
This is system-wide change which may affect all of the applications.

We are going to be building our device on the ESP32 platform from Espressif. We need the Espressif IDF

cd ~
mkdir esp
cd ~/esp
git clone -b release/v3.3 --recursive https://github.com/espressif/esp-idf.git

Install the esp-idf

cd ~/esp/esp-idf
./install.sh

Copy the tool chain to your local directory as well. (ESP32)

cd ~/esp
wget https://dl.espressif.com/dl/xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz
tar -xvf xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz

Clone the SDK Reference
From the terminal, navigate to the directory you want the SmartThings Device SDK to locate and clone it using the following git command:

cd ~
git clone https://github.com/SmartThingsCommunity/st-device-sdk-c-ref.git

Automatically download the IoT Core Device Library and a chipset vendor’s SDK as follows:

cd ~/st-device-sdk-c-ref
python setup.py esp32

Register Project at the Developer Workspace

Now that the programming environment is set up, create a project and register the device information to the SmartThings Platform.

Sign in to the Developer Workspace with a Samsung Account.

2.1 Create a new project

Select select New Project → Device Integration → Direct-connected

2.2 Add a device profile

A Device Profile contains the Components, Capabilities, and metadata (ID, name, etc.). This information defines the actions and Attributes that an IoT device can perform.

Click the DEFINE DEVICE PROFILE → ADD A DEVICE PROFILE and fill out required information (e.g. Basic information, Component & Capability, UI display)

Note - The “Health Check” capability is automatically added for all direct connected devices. Leave it and add your Capabilities

2.3 Add Device Onboarding

The Device Onboarding is a set of instructions owners will see in the mobile app connecting their device to SmartThings. You can customize the screens presented by adding a device onboarding.

2.4 Add Product Info

The Product Info defines how this device is shown at SmartThings mobile app catalog. You can define the device’s category and regional availability.

2.5 Deploy Your Device to Test

You can start testing by deploying your device to test from Test → Test Devices or Overview page. Once completed, you will see your device in the SmartThings mobile app when in Developer Mode only after it has been deployed for testing.

1055×254 70.5 KB

2.6 Register Test Devices

Add the identity of the device for authentication with the SmartThings Cloud. This requires device information including the serial number and device public key (ED25519). Note - the maximum number of test devices is limited per user. At the time of this tutorial the limit is 100. Once you reach the maximum number of test devices, remove an existing one to proceed.

This example shows how to create an ED25519 key pair with the SDK keygen. You can get device_info.json file as a result from tools/keygen/linux/output_{ serialNumber}. The Linux version of key generator (keygen) utility is located at st-iot-device-sdk-c-reference/iot-core/tools/keygen/ or st-device-sdk-c/tools/keygen/

The serial number for testing devices will be randomly generated by this tool. The serial number is comprised of [STDK + 12-digit alphanumberic format].

cd ~/Workspace/st-device-sdk-c-ref/iot-core/tools/keygen/
python3 stdk-keygen.py –firmware switch_example_001

Use following serial number and public key for the identity of your device in Developer Workspace.

Serial Number: STDKE90W*uCX

Public Key: nFN5xuQusQZHoBSFaAoP9**kNdLnjDJRew=

Copy STDKE90WuCX from keygen output and paste it into “Device serial number” field of “Register A Test Device” page. Copy public key string from keygen output (nFN5xuQusQZHoBSFaAoP9*kNdLnjDJRew= in this example) and paste it into “Device Public Key” field.

889×1035 86.7 KB

2.7 Download onboarding_config.json

This information is required for an IoT device to connect to the SmartThings Platform.

If you use a sample device application from this git repository, download and overwrite the existing onboarding_config.json. The file is in the main directory of the sample device application with the new one you downloaded.

Alternatively, if the json information is guaranteed to be a parameter in the st_conn_init() function, you can refer to it differently according to your own development method.

890×450 92.8 KB

SmartThings Device SDK Reference repository.

2.8 Create a new device project

An easy way to get started is to branch out one of the example projects provided in the git repository. We will use the “switch_example” application from the SmartThings Device SDK Reference directory here.

Full path of the ESP32

~/st-device-sdk-c-ref/apps/ESP32/switch_example/

3. Update device information

Your IoT device requires two pieces of information when connecting to the SmartThings Platform :

  • Device Identity
  • Onboarding_config.json

3.1 Device Identity

Device identity provides data that need to be sent for authentication with the server. There are two different packets of information, one is ED25519 and the other is X.509.

ED25519

All of the device identity data is included in the device_info.json file in the main directory of the device application.

If you create a device identity with a command with an option like python3 stdk-keygen.py --firmware switch_example_001 like the first phase, you can get the ready to use device_info.json file directly. In this case, overwrite the existing device_info.json file with the new one you created.

Overwrite device_info.json with a new one

$ cp ./output_STDKE90W*uCX/device_info.json ~/st-device-sdk-c-ref/apps/ESP32/switch_example/main/

Flashed items Type Description Examples
PKType data PubKey Algorithm type ED25519
CACert file Server CA Certificate root.crt.pem
PublicKey file Client (= Device) Public key device.pubkey.b64
PrivateKey file Client (= Device) Private key device.seckey.b64
SerialNum data Device Serial Number SN12345678F
  1. Note :
    If you want to flash the device identity data in a specific partition, you should set the build configuration below to y. :
    CONFIG_STDK_IOT_CORE_SUPPORT_STNV_PARTITION=y
  2. X.509
    It will be supported later.

3.2 onboarding_config.json

Place the onboarding_config.json file created during the device registration phase in the main directory of the device application. Ensure you overwrite the existing onboarding_config.json file with the new one.

Example

Location for switch_example app of ESP32

~/st-device-sdk-c-ref/apps/ESP32/switch_example/main/onboarding_config.json

Example of onboarding_config.json

{

  "onboardingConfig": {

    "deviceOnboardingId": "OI_SWITCH_01",

    "mnId": "****",

    "setupId": "001",

    "vid": "VID_SWITCH_01",

    "deviceTypeId": "Switch",

    "ownershipValidationTypes": [
      "BUTTON"
    ],

    "identityType": "ED25519",

    "deviceIntegrationProfileKey": {

    "id": "123e4567-e89b-12d3-a456-426614174000",

    "majorVersion": 0,

    "minorVersion": 1

    }

  }

}
  • deviceOnboardingId : It is a prefix to be used for the SSID of Soft-AP during EasySetup process. This value comes from Device Onboarding ID when completing doing “Create a device information” in the Developer Workspace. By default, the last four digits(e.g. 7c16) of the example below represent the last four digits of the Serial Number of device.
    • Example of SSID : OI_SWITCH_01_E4mnId…7c16
  • mnId : Manufacturer ID. A unique four-letter ID assigned to SmartThings developers (individual MNID) or enrolled organizations (company MNID) that can be viewed at “My Page > MNID”.
  • setupId : a unique three-digit number. This value comes from Setup ID when completing “Create device onboarding information” in the Developer Workspace.
  • vid : An alphanumeric identifier for your device. This value comes from Vendor ID when completing “Create a device profile” in the Developer Workspace.
  • deviceTypeId : This determines the device’s icon and default UI layout in the SmartThings app. This is the value you selected from the list when completing “Create a device profile”.
  • ownershipValidationTypes : This is the type of ownership confirmation used during onboarding process. This value comes from the Confirm Method when completing “Create a device profile” in the Developer Workspace. Currently, there are four supported types.
    • JUSTWORKS
    • BUTTON
    • PIN
    • QR
  • identityType : A unique certificate or public key pair type used to authenticate a device on SmartThings Platform. You can choose between
    • ED25519
    • X.509 (coming soon)
  • deviceIntegrationProfileKey : information to indicate your device’s functionalities at SmartThings Platform.

3.3 Develop Device Application

A device application is developed using the APIs provided by the IoT Core Device Library. We recommend reusing the pre-supplied sample device applications, like switch_example. This allows for rapid development as you begin to build your new device. Please refer to the API references related to the IoT core device library as shown:

  • connection management
    • st_conn_init()
    • st_conn_set_noti_cb()
    • st_conn_start()
    • st_conn_cleanup()
    • st_conn_ownership_confirm()
  • capability management
    • st_cap_handle_init()
    • st_cap_cmd_set_cb()
    • st_cap_attr_create_int()
    • st_cap_attr_create_number()
    • st_cap_attr_create_string()
    • st_cap_attr_create_string_array()
    • st_cap_attr_free()
    • st_cap_attr_send()

Main function example for ESP32 :

void app_main(void)

{



 /**
    SmartThings Device SDK(STDK) aims to make it easier to develop IoT devices by providing
    additional st_iot_core layer to the existing chip vendor SW Architecture.
    That is, you can simply develop a basic application
    by just calling the APIs provided by st_iot_core layer like below.
   
  // create a iot context
    1. st_conn_init();
  
  // create a handle to process capability
    2. st_cap_handle_init(); (called in function 'capability_init')
  
 // register a callback function to process capability command when it comes from the SmartThings Server.
    3. st_cap_cmd_set_cb(); (called in function 'capability_init')
  
// process on-boarding procedure. There is nothing more to do on the app side than call the API.
    4. st_conn_start(); (called in function 'connection_start')
*/

unsigned char *onboarding_config = (unsigned char *) onboarding_config_start;
unsigned int onboarding_config_len = onboarding_config_end - onboarding_config_start;
unsigned char *device_info = (unsigned char *) device_info_start;
unsigned int device_info_len = device_info_end - device_info_start;

int iot_err;

// create a iot context
ctx = st_conn_init(onboarding_config, onboarding_config_len, device_info, device_info_len);

if (ctx != NULL) {
  iot_err = st_conn_set_noti_cb(ctx, iot_noti_cb, NULL);
  if (iot_err)
    printf(“fail to set notification callback function\n”);
  } else {
     printf(“fail to create the iot_context\n”);
}

// create a handle to process capability and initialize capability info

capability_init();
gpio_init();
register_iot_cli_cmd();
uart_cli_main();
xTaskCreate(app_main_task, “app_main_task”, 4096, NULL, 10, NULL);

// connect to server
connection_start();

}

3.4 Build & Flash the App

Go to the root directory of the SmartThings Device SDK Reference git repo and execute the build script(build.sh) with the below parameter.

Example for ESP32

./build.sh {app_directory} {option}

cd ~/st-device-sdk-c-ref/
python build.py apps/esp32/switch_example flash

After compiling the result will be output. View the result with the following commands.

cd ~/st-device-sdk-c-ref/
tree output/ -L 3

output/

`-- esp32

├── iotcore_switch_example_20200729_65a1678_0a8cbe1

│ ├── address_info.txt

│ ├── bootloader.bin

│ ├── debug

│ ├── ota_data_initial.bin

│ ├── partitions.2MB.bin

│ └── switch_example.bin

You are using the ESP32 Chipset so you can now run the following command to flash the entire binaries(e.g. app, bootloader, and init data bin) to the chipset.

The serial port must be matched to the computer environment. For example, the settings for serial port flashing can be configured with the menuconfig option in Espressif. If the serial port setting does not match your environment, execute the following:

Note : The menuconfig option is only supported on the Espressif chipset. If you use a different chipset, please set it according to the selected original chipset guide.

Example for ESP32

./build.sh {app_directory} {option}

cd ~/st-device-sdk-c-ref
python build.py apps/ESP32/switch_example menuconfig

Note - You don’t need to run ./build.sh apps/ESP32/switch_example before running ./build.sh appes/ESP32/switch_example flash, this will automatically rebuild everything that must included before flashing.

For more details about flashing and monitoring, refer to the README file.

Testing

If you haven’t already, visit the Google Play or the iOS App Store and download the SmartThings app on your phone.

From the SmartThings App:

4.1 Enable developer mode

You must enable the Developer Mode in the SmartThings app before testing. For more details, please refer to the link below.

smartthings.developer.samsung.com

288×601 89.5 KB

4.2 Reset the device

Push the reset button of device.

If you use an Espressif chipset, you can also run the monitor command to reset the device from the console window like below.

$ cd ~/st-device-sdk-c-ref
python build.py apps/esp32/switch_example monitor
This is only for Espressif chipset.

4.3 Add device(Onboarding Process)

There are two ways to add a device in the SmartThings application. You can proceed in one of the two ways below.

  • Select the Device Onboarding Name via “My Testing Devices” menu.

1600×826 465 KB

  • Use the automatic Detection pop-up window. By default, the last four digits(e.g. 7c16) of the example detection pop-up below represent the last four digits of the Serial Number of device.

1600×399 214 KB

5. Success!

Now that your device is on the SmartThings App. If there is no problem during the onboarding process, it means your device is registered to the SmartThings Platform.

Now you can control and automate monitor your device with the SmartThings App. Ensure you adequately test your device performance before submitting for Works with SmartThings Certification.

368×600 166 KB

15 Likes

Quick question:

On the new platform, I know what a “connected device” is (endpoint, usually but not always cloud to cloud). No hub required.

And what a “hub-connected device” is (Zigbee or zwave). Hub obviously required.

What’s a “direct connected device”? And is a hub required? :thinking:

No hub and no middle cloud needed. I give a good explainer in the video but I will also update the description. Good question.

1 Like

CHEESE-N-RICE! this is an unusually excellent triptych. They should pay you. I suspect you will be punished.

A cryptic triptych comment. Cannot tell if sarcasm or not so…

1 Like

Any details on how to store device info in NV using CONFIG_STDK_IOT_CORE_SUPPORT_STNV_PARTITION

I see in the code how it is configured and reads the data but its not clear how to Initialize it from the factory.

https://github.com/SmartThingsCommunity/st-device-sdk-c/blob/master/doc/STDK_APIs.pdf

API Reference can be found here (An updated reference will be published soon)

Looks like no iot_* function exists to write to the ‘stnv’ partition.
The only function iot_bsp_fs_open_from_stnv opens R/O. I wonder why that is?

I was able to write it directly.
err = nvs_open_from_partition(“stnv”, “stdk”, NVS_READWRITE, &my_handle);
err = nvs_set_str(my_handle, “SerialNum”, “serialnumhash”);
err = nvs_set_str(my_handle, “PrivateKey”, “privatekeyhash”);
err = nvs_set_str(my_handle, “PublicKey”, “pubkeyhash”);

As you can see from API, those information need to be securely cared.
We are providing tools to build it as separated flash image in case of ESP chipset as reference.
Please refer https://github.com/SmartThingsCommunity/st-device-sdk-c/tree/master/tools/keygen#commercial

1 Like

THANKS!!
I am very new to IoT development and your tuitorial has helped me a lot to get started with smarttgings platform.

I would really appreciate if you can create another video going over coding of various functions like integrating touch input control etc.for the ESP32 and how it works.

2 Likes

@jody.albritton
Hey, I am looking to find some resources specifically for the coding part of ESP32 using STDK.

I am relatively new and was still able to follow all the instructions in this guide successfully. Thanks for making it simple :blush:

It covers how to flash device using the switch-example from GitHub however, I have no clue on how to change the code to work for my needs. Basically looking for some tutorial or documentation that can help me learn that.

I am willing to pay for someone to teach me.

As an example, I would like to be able to control 4 switches using a single ESP32 and have 4 cards for their respective control on SmartThings app. Maybe also a fan control to understand how to implement other capabilities.

Anything is welcome. Code suggestions, videos, docs or tutoring etc.

Thanks,
Shivam

1 Like

hi how are you I am currently having an issue with the

python3 stdk-keygen.py --firmware switch_example_001

on windows 10 I am trying to get the public and private key so I can authenticate the device

Hi Jody @jody.albritton , awesome tutorial - thank you. I was watching Part 1 of your YouTube example , in there you mention Part II and Part III but I cant find the links as they are unlisted. Where can I find them please?

Thanks Nige.

Is it possible to use this SDK with a Raspberry PI as the device instead of an MCU? Could an “RPI” type BSP be created to enable this?

In one of the SDK readme files it talks about an option to test in a POSIX environment, but it includes this statement which I don’t understand, and makes it sound like it wouldn’t be fully functional:

But, unlike the resource limited MCU devices, you can NOT check the onboarding process in the POSIX environment because it does not support a SoftAP function by default.

Can anyone clarify?

@jody.albritton this is probably your wheelhouse?

This is the error I’m getting when I try to run it on a RPI; is this the issue alluded to in my prior posted question or is this something else? Looks like wifi provisioning is failing:

E [IoT]: _iot_security_be_bsp_fs_load_from_nv(121) > iot_bsp_fs_open(./WifiProvStatus) = -16

E [IoT]: _iot_nv_io_storage(126) > iot_security_storage_read = -1200

Also a point of improvement in the documentation: You need to add the pre-req of pynacl and qrcode libraries to your instructions for the keygen tool. The keygen readme file lists pynacl but qrcode needs to be added there as well.

1 Like

I want to hire someone to modify project code do you know someone?

i need to add more buttons to this device code

@jody.albritton

on the switch example, it all connects to “main”

what do I do to add another button how do I add more components and link it in the code

Hi, @Edward_shamosh,
Please try below steps.

  1. Add additional capabilities as you want at your project by editing Device Profile - Component & Capabilities tab.
  2. Write corresponding capability handler code - please refer here

Hi @TAustin,
As you can see, currently SDK doesn’t support RPi (linux) for full functionality.
Current posix port is for API level unit test.