Skip to content

How to write code for sending device event

Kwang-Hui edited this page Sep 17, 2021 · 4 revisions

There are two ways for sending device event to SmartThings Platform.

  • Using API or Macro
  • Using Capability Sample source code

Using API or Macro

There exist APIs and Macros for sending device event.

Developer can decide whether to use APIs or Macros. But as you can see from below ST_CAP_SEND_ATTR_STRING's implementation, Macros are using APIs internally.

#define ST_CAP_SEND_ATTR_STRING(cap_handle, attribute, value_string, unit, data, output_seq_num)\
{\
	IOT_EVENT *attr = NULL;\
	iot_cap_val_t value;\
\
	value.type = IOT_CAP_VAL_TYPE_STRING;\
	value.string = value_string;\
	attr = st_cap_create_attr(cap_handle, attribute, &value, unit, data);\
	if (attr != NULL){\
		output_seq_num = st_cap_send_attr(&attr, 1);\
		st_cap_free_attr(attr);\
	}\
}

There are another useful files in iot-core > src > include > caps for sending events.

Let's think about sending dustLevel event of Dust Sensor capability for example. The first thing you need to do is finding the definition of Dust Sensor capability from API-ref document

{
    "id": "dustSensor",
    "version": 1,
    "name": "Dust Sensor",
    "status": "live",
    "attributes": {
        "fineDustLevel": {
            "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                    "value": {
                        "title": "PositiveInteger",
                        "type": "integer",
                        "minimum": 0
                    },
                    "unit": {
                        "type": "string",
                        "enum": [
                            "\u03bcg/m^3"
                        ],
                        "default": "\u03bcg/m^3"
                    }
                },
                "required": [
                    "value"
                ]
            }
        },
        "dustLevel": {
            "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                    "value": {
                        "title": "PositiveInteger",
                        "type": "integer",
                        "minimum": 0
                    },
                    "unit": {
                        "type": "string",
                        "enum": [
                            "\u03bcg/m^3"
                        ],
                        "default": "\u03bcg/m^3"
                    }
                },
                "required": [
                    "value"
                ]
            }
        }
    },
    "commands": {

    }
}

After then you can pick the attribute name, value and unit string from definition and put them as API parameters.

static void send_dust_level(int value_number)
{
    IOT_CAP_HANDLE *handle;
    int seq;

    handle = st_cap_handle_init(ctx, "main", "dustSensor", NULL, NULL);
    ST_CAP_SEND_ATTR_NUMBER(handle, "dustLevel", value_number, 
                            "\u03bcg/m^3", NULL, seq);
}

This can be changed like below by including caps/iot_caps_helper_dustSensor.h header file. You don't need to analysis capability definition. Just include caps/iot_caps_helper_dustSensor.h which converts capability definition into C-style structure.
This would be helpful especially when you're using modern code editors.

caps_helper_example

#include <caps/iot_caps_helper_dustSensor.h>
static void send_dust_level(int value_number)
{
    IOT_CAP_HANDLE *handle;
    int seq;

    handle = st_cap_handle_init(ctx, "main", caps_helper_dustSensor.id, NULL, NULL);
    ST_CAP_SEND_ATTR_NUMBER(handle, caps_helper_dustSensor.attr_dustLevel.name, value_number, 
                            caps_helper_dustSensor.attr_dustLevel.unit_ug_per_m3, NULL, seq);
}

Using Capability Sample source code

There is another way for sending device event. This might be more simpler than using API or Macro.
Let's think about the same scenario - sending dustLevel event of Dust Sensor capability - for example.

Step 1: Copy sample files

You can just copy corresponding sample source (.c) and header (.h) files from apps > capability_sample directory to your device application's source directory. (e.g. caps_dustSensor.c, caps_dustSensor.h)

$ cp apps/capability_sample/caps_dustSensor.* apps/{YOUR_APP_PATH}/main/

Step 2: Include header file

#include "caps_dustSensor.h"

Step 3: Use capability sample functions

caps_dustSensor.c provides several functions to abstract capability. You can just call that functions like below example.

#include "caps_dustSensor.h"
static void send_dust_level(int value_number)
{
    caps_dustSensor_data_t *cap_dustSensor_data;

    cap_dustSensor_data = caps_dustSensor_initialize(ctx, "main", NULL, NULL);
    if (cap_dustSensor_data) {
        cap_dustSensor_data->set_dustLevel_value(cap_dustSensor_data, value_number);
        cap_dustSensor_data->set_dustLevel_unit(cap_dustSensor_data, caps_helper_dustSensor.attr_dustLevel.unit_ug_per_m3);
        cap_dustSensor_data->attr_dustLevel_send(cap_dustSensor_data);
    }
}

Step 4: Update build configuration to include added capability sample source code

The added source code should be part of your application by updating build configuration.

e.g. Adding caps_dustSensor.c to apps/esp32/switch_example/main/CMakeLists.txt in case of esp32 switch_example application.

idf_component_register(SRCS "main.c"
                            "device_control.c"
                            "iot_cli_cmd.c"
                            "iot_uart_cli.c"
                            "caps_switch.c"
+                           "caps_dustSensor.c"
                        EMBED_FILES "device_info.json"
                                    "onboarding_config.json"
                    )
Clone this wiki locally