SmartThings Direct-connected devices are Wi-Fi enabled devices that use the SmartThings Platform as their primary cloud infrastructure. And these devices will use the MQTT protocol for communication.
This article demonstrates how to integrate a direct-connected device with SmartThings.
When developing a new direct-connected device application with SmartThings SDK, you will progress through the following steps. You can also refer to the Samsung Developer - Code Lab. It will be more practical for you to understand the SmartThings SDK for Direct Connected Devices.
The first thing you need to do is set up your programming environment.
There are two git repositories for working with the SmartThings SDK for Direct Connected Devices. The first git repository is for the Internet of Things (IoT) core device library itself, while the second git repository is for sample device applications that use this IoT core device library on the chipset vendor's own SDK.
You can just choose to download the Reference repository from GitHub, if you use a chipset that has already been ported. In this case, the IoT Core Device Library
and a chipset SDK
can be easily downloaded as submodules in this Reference repository through the predefined setup.py
script. If you are new for using the SmartThings SDK for Direct Connected Devices, we recommend you to use the Reference repository for easier understanding.
From the terminal, navigate to the directory you want the SmartThings SDK for Direct Connected Devices to locate (e.g. ~/
) and clone it using the following git command:
$ cd ~
$ git clone https://github.com/SmartThingsCommunity/st-device-sdk-c-ref.git
Note :
For the rest of this document, we will assume the above path (
~/st-device-sdk-c-ref
) is the default reference source code.
You can use a script to automatically download the IoT Core Device Library
and a chipset vendor's SDK
(e.g. esp32
) as follows:
$ cd ~/st-device-sdk-c-ref
$ python setup.py
Usage: python setup.py [BSP_NAME]
--------------------------------------------------
ex) python setup.py esp32
$ python setup.py esp32
In order for your device to connect to the SmartThings cloud, authentication data files are required.
Run the following stdk-keygen.py
script in a terminal on your local machine to create a Device Identity.
$ cd ~/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:
STDK**E90W***uCX
Public Key:
nFN5x***uQusQ****ZHoBSFaAoP9***kNdLnjDJRew=
$ tree
.
├── output_STDK**E90W***uCX
│ ├── device_info.json
│ ├── device.pubkey.b64
│ └── device.seckey.b64
├── README.md
└── stdk-keygen.py
1 directory, 5 files
$ cat output_STDK**E90W***uCX/device_info.json
{
"deviceInfo": {
"firmwareVersion": "switch_example_001",
"privateKey": "dH**JKMRD5X****BaV+fGoXa3qZfNW3V****jHXOmd0=",
"publicKey": "nFN5x***uQusQ****ZHoBSFaAoP9***kNdLnjDJRew=",
"serialNumber": "STDK**E90W***uCX"
}
}
Copy the Serial Number and Public Key after running the command. You will need to upload these values to the SmartThings Platform via Developer Workspace - Projects during the next phase.
If you create a device identity with a command with an option like above, You can get the ready-to-use device_info.json
file directly.
You must setup a toolchain according to each chipset you selected.
Example for ESP32 :
-
Setup ESP32 environment for the SmartThings SDK for Direct Connected Devices by running
setup.py
$ cd ~/st-device-sdk-c-ref $ python setup.py esp32
Now that the programming environment is setup, you need to create project and register device information to the SmartThings Platform.
First, please sign in to the Developer Workspace with a Samsung Account.
If you have a plan to commercialize a product, I recommend creating an organizational workspace instead of a private workspace. You cannot request the certification in private workspace.
If you find the person mark at the top-right in Developer Workspace, you can get the link of the request form for an organization workspace.
- If you need new organization, selcet Create New Organization in Type of Organization Change
- If you want to join or remove an existing organization, select Add User to Existing Organization or Remove User from Existing Organization
MNid can be found next to the organization name at the top right of the developer workspace page that is a member of the organization.
Once the application is completed, the progress status will be sent to the email address you applied for.
To create project for direct connected device. Please select select New Project → Device Integration → Direct-connected
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 → CREATE DEVICE PROFILE or ADD A DEVICE PROFILE and then fill out required information (e.g. Basic infor, Component & Capability, UI display)
The "Health Check" capability is automatically added for all direct connected devices. Please leave it and add your capabilities
The device onboarding guides device owners when their device is first registering and connecting to SmartThings. You can customize the screens presented by adding a device onboarding. The ownership validation type is also defined at this stage.
The product info defines how this device is shown at SmartThings mobile app catalog. You can define device’s category and its regional availability.
You can start testing by deploying your device to test from Test → Test Devices or Overview page. You will be able to see your device in the SmartThings mobile app when in Developer Mode only when after it has been deployed for testing.
You can add identity of device for authenticating your device to SmartThings cloud. This requires device information like serial number and device public key (ED25519). Because maximum number of test device is limited per user, Once you reaches maximum number of test device, you should remove one of existing one.
This example shows how to create ED25519 key pair with SDK tools. You can get device_info.json file as a result from tools/keygen/linux/output_{ serialNumber}
Key generator utility (keygen.py) is located at st-iot-device-sdk-c-reference/iot-core/tools/keygen/
or st-device-sdk-c/tools/keygen/
Serial number for testing device would be randomly generated by this tool which has STDK + 12-digit alphanumberic format.
$ cd ~/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:
STDK**E90W***uCX
Public Key:
nFN5x***uQusQ****ZHoBSFaAoP9***kNdLnjDJRew=
Copy STDK**E90W***uCX
from keygen output and paste it into “Device serial number” field of “Register A Test Device” page.
Copy public key string from keygen output (nFN5x***uQusQ****ZHoBSFaAoP9***kNdLnjDJRew=
in this example) and paste it into “Device Public Key” field.
Using device QR code could be helpful while device onboarding. QR code should have format like below. (Please refer here for more details)
This link is [QR code design template] (https://developer.smartthings.com/docs/devices/direct-connected/publish#qr-code-design-template).
{Your mnId}: 4-digit alphanumeric mnId of your account
{Device onboardingId}: 3-digit number Onboarding ID, you can find it from your developer workspace project “Device Onboarding” > “Other Info” page
{Device serialNumber}: device serial number which is registered at your developer workspace project
https://qr.samsungiots.com/?m={Your mnId}&s={Device onboardingId}&r={Device serialNumber}
You can simply generate QR code with using below python3 script
import qrcode
mnid = 'FFFF' # "FFFF" is an example. you should replace it with yours
onboardingId = '111' # "111" is an example. you should replace it with yours
serialNumber = 'STDKtest0001' # "STDKtest0001" is an example. you should replace it with yours
qrUrl = 'https://qr.samsungiots.com/?m=' + mnid + '&s=' + onboardingId + '&r=' + serialNumber
qrcode.QRCode(box_size=10, border=4)
img = qrcode.make(qrUrl)
img.save(serialNumber + '.png')
This is the information that the IoT device must have in order to connect to the SmartThings Platform.
If you use a sample device application from this git repository, please download it and then, just overwrite the existing onboarding_config.json
file is in the main
directory of sample device application with the new one you downloaded. In fact, overwriting is just one of several possible ways to inject it to the device. 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 way.
You have set up the environment and registered a device, so now it is time to develop a new device application in the SmartThings Device SDK Reference repository.
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/
Your IoT device needs two pieces of information when connecting to the SmartThings Platform. These json formatted information should be passed to SmartThings Device SDK as a parameter of st_conn_init()
api.
- device_info.json
- onboarding_config.json
-
device_info.json
device_info.json
file could contain per device specific information including firmware version, device private key, device public key and device serial number.We have two type of the format of
device_info.json
.-
All inclusive
device_info.json
file could include all the information as json format. Our SmartThings Device SDK sample application (e.g.light_example
,switch_example
) uses this method.
This is the easiest and simplest way to contain security information for devices. But having per device specific information as json format may not be suitable for manufacturing. So this is recommended for the test devices for individual developer.{ "deviceInfo": { "firmwareVersion": "firmwareVersion_here", "privateKey": "privateKey_here", "publicKey": "publicKey_here", "serialNumber": "serialNumber_here" } }
This file can be generated by stdk-keygen.py like below example.
python3 stdk-keygen.py --firmware switch_example_ver001 --mnid fJXX
-
Firmware version only
We can leave only the firmware version at
device_info.json
like below.{ "deviceInfo": { "firmwareVersion": "firmwareVersion_here" } }
In this case other sercurity information like device private key, device public key and device serial number should be moved to dedicated secure partition - called as SmartThings Non-Volatile (STNV) Partition - with
CONFIG_STDK_IOT_CORE_SUPPORT_STNV_PARTITION
option enabled.
This is subitable for manufacturing because it could have dedicated secure partition for immutable information. SmartThings Device SDK expect security information from STNV parition with below path name. The mapping betweeniot_nvd_t
and real storage path name can be found atiot_bsp_nv_data_XXX.c
for each bsp's porting layer.
stdk-keygen.py also supports batch creation by reading csv formatted series of device serial number.Data Path Description Detail Examples PublicKey Client (= Device) Public key base64 encoded ED25519 Public Key device.pubkey.b64 PrivateKey Client (= Device) Private key base64 encoded ED25519 Privated Key device.seckey.b64 SerialNum Device Serial Number alphanumberic string (8~30) SN12345678F Note :
If
CONFIG_STDK_IOT_CORE_SUPPORT_STNV_PARTITION
option has enabled, SmartThings Device SDK ignoresprivateKey
,publicKey
andserialNumber
field fromdevice_info.json
file
-
-
onboarding_config.json
The
onboarding_config.json
contains project common information. this can be downloaded from Developer Workspace project page as a file. Our sample appliation (e.g.light_example
,switch_example
) embedding it as an object blob. But developer could decide how to embed it as a part of device firmware.{ "onboardingConfig": { "deviceOnboardingId": "NAME", "mnId": "MNID", "setupId": "999", "vid": "VID", "deviceTypeId": "TYPE", "ownershipValidationTypes": [ "JUSTWORKS", "BUTTON", "PIN", "QR" ], "identityType": "ED25519", "deviceIntegrationProfileKey": { "id": "DIP_UUID", "majorVersion": 0, "minorVersion": 1 }, "productId": "PRODUCT_ID_UUID" } }
A device application is developed using the APIs provided by the IoT Core Device Library. We recommend reuse of the example device applications, like switch_example
, light_example
. This allows for rapid development as you begin to develop your new device.
Major APIs are like below:
-
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_create_attr()
- ST_CAP_CREATE_ATTR_NUMBER
- ST_CAP_SEND_ATTR_NUMBER
- ST_CAP_CREATE_ATTR_STRING
- ST_CAP_SEND_ATTR_STRING
- ST_CAP_CREATE_ATTR_STRINGS_ARRAY
- ST_CAP_SEND_ATTR_STRINGS_ARRAY
- st_cap_free_attr()
- st_cap_send_attr()
Main function example for ESP32 :
void app_main(void)
{
/**
SmartThings Device SDK 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();
iot_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();
}
Go to the root directory of the SmartThings Device SDK Reference git repo. and execute the build script(build.py) with the below parameter.
# Example for ESP32
$ cd ~/st-device-sdk-c-ref/
$ python build.py apps/esp32/switch_example # python build.py {app_directory}
After compiling, following results can be seen. In fact, as you know, we have to flash these results according to the binary download method that exists per chipset.
# Example for ESP32
$ cd ~/st-device-sdk-c-ref/
$ tree output/ -L 3
output/
`-- esp32
├── iotcore_switch_example_20211223_e242418_20aab5c
│ ├── bootloader.bin
│ ├── debug
│ ├── ota_data_initial.bin
│ ├── partition-table.bin
│ └── switch_example.bin
In case of Espressif chipset (e.g. ESP32), you can now run the following command to flash the entire binaries (e.g. app, bootloader, and init data bin) to the chipset.
# Example for ESP32
# python build.py {app_directory} {option}
$ cd ~/st-device-sdk-c-ref/
$ python build.py apps/esp32/switch_example flash
The serial port needs to be matched to the computer environment for serial port flashing. For example, the settings for serial port flashing can be configured with menuconfig
option in Espressif. If the serial port setting does not match your environment, please 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
# python build.py {app_directory} {option}
$ cd ~/st-device-sdk-c-ref
$ python build.py apps/esp32/switch_example menuconfig
Plus, You don't need to run python build.py appes/esp32/switch_example
before running python build.py appes/esp32/switch_example flash
, this will automatically rebuild everything that needs to be built before flashing.
For more details about flashing and monitoring, please refer to the README file.
The SmartThings App should be used to control an IoT device that is running with the SmartThings Platform. Go to application market place (e.g. Play Store, App Store, Galaxy Store) and download the SmartThings app on your mobile device.
-
Enable developer mode
You need to enable the Developer Mode in the SmartThings app before start testing.
Please refer here for more details.
-
Add device
Go to Add device and click My Testing Devices or Scan QR code. You can now see and add your self-published devices.
-
Control device
You can control test device from dash board action and device plug user interface