使用已适配IoT SDK的芯片开发智能灯
更新时间:2018-05-14 16:45:32
如您使用AliOS认证过的芯片(如已集成IoT SDK功能)模组或已经集成IoT SDK的芯片模组,您可以直接快速方便的开发您的产品。
您可以找您的芯片模组厂商拿到模组的固件代码后进入下一步开发。
1. 完成准备工作
按"设备端开发示例"-->"准备工作" 文档完成单个调试设备
ProductKey
、DeviceName
、DeviceSecret
、ProductSecret
的生成。按"添加产品"完成产品的定义。
2. 写入一机一密设备信息
按芯片厂商提供的烧录方式烧录,确认您芯片厂商实现的下列函数能正确读取到您的设备ProductKey
、DeviceName
、DeviceSecret
、ProductSecret
信息。
或者您仅仅为了验证开发流程,可以先将下列HAL函数默认读取您现在生成的设备信息。
- HAL_GetProductKey
- HAL_GetDeviceName
- HAL_GetDeviceSecret
HAL_GetProductSecret
3. TSL生成与下载
linkkit SDK支持两种获取TSL模型的途径
直接从云端拉取物的模型
应用程序调用linkkit_start()对SDK进行初始化时,需要将get_tsl_from_cloud入参设为1,设备端连云成功后会自动从云端拉取。从本地设置物的模型
应用程序调用linkkit_start()对SDK进行初始化时,需要将get_tsl_from_cloud入参设为0且需要调用linkit_set_tsl()设置物的模型- 进入控制台,选择"产品开发"->"产品名称",若此栏目无产品,请按照步骤一完成产品的创建及功能定义
- 点击产品右边的查看按钮,进入产品详情页面,点击查看JSON
int main()
{
get_tsl_from_cloud = 0;
linkkit_start(18, get_tsl_from_cloud, linkkit_loglevel_debug, &alinkops, linkkit_cloud_domain_sh, sample_ctx);
linkkit_set_tsl(TSL_STRING, strlen(TSL_STRING));
...
}
### <a name="v4mhok"></a>4. 编译SDK
对于已适配的硬件平台的情况下,可以直接编译出适配芯片的SDK lib,以`esp32` 日常环境为例。
* 在SDK根目录下执行`make reconfig`,选择`2`
```plain
SELECT A CONFIGURATION:
1) config.armcc.daily 9) config.h3c.rtk_online
2) config.esp32.daily 10) config.h3c.rtk_pre
3) config.esp32.online 11) config.openwrt.c1
4) config.esp32.pre 12) config.ubuntu.daily
5) config.esp8266.daily 13) config.ubuntu.online
6) config.esp8266.online 14) config.ubuntu.online.unittest
7) config.esp8266.pre 15) config.ubuntu.pre
8) config.h3c.rtk_daily
#? 2
SELECTED CONFIGURATION:
VENDOR : esp32
MODEL : daily
CONFIGURE .............................. [base/log]
CONFIGURE .............................. [base/tls]
CONFIGURE .............................. [base/utils]
CONFIGURE .............................. [connectivity/coap]
CONFIGURE .............................. [connectivity/examples]
CONFIGURE .............................. [connectivity/mqtt]
CONFIGURE .............................. [connectivity/ota]
CONFIGURE .............................. [connectivity/system]
CONFIGURE .............................. [external/cut]
CONFIGURE .............................. [hal-impl]
CONFIGURE .............................. [layers/cm]
CONFIGURE .............................. [layers/cm/examples]
CONFIGURE .............................. [layers/dm]
CONFIGURE .............................. [layers/linkkit]
CONFIGURE .............................. [layers/linkkit/samples]
CONFIGURE .............................. [modules/alcs]
CONFIGURE .............................. [modules/awss-ap]
CONFIGURE .............................. [sdk-tests]
CONFIGURE .............................. [service/fota]
BUILDING WITH EXISTING CONFIGURATION:
VENDOR : esp32
MODEL : daily
Components:
. external/cut
. connectivity/system
. connectivity/ota
. connectivity/mqtt
. connectivity/coap
. connectivity/examples
. layers/dm
. layers/linkkit
. layers/linkkit/samples
. layers/cm
. layers/cm/examples
. modules/alcs
. modules/awss-ap
. base/log
. base/utils
. base/tls
. hal-impl
. sdk-tests
. service/fota
执行
make
,生成libilop-esp32.a
make BUILDING WITH EXISTING CONFIGURATION: VENDOR : esp32 MODEL : daily [AR] libilop-hal.a <= [CC] mqtt-example.o <= mqtt-example.c makefile [CC] ut_json_parser.o <= ut_json_parser.c [CC] ut_mem_stats.o <= ut_mem_stats.c [CC] ut_json_token.o <= ut_json_token.c [CC] utils_base64.o <= utils_base64.c ... [AR] libilop-esp32.a <= base/log/lite-log.o base/utils/json_parser.o base/utils/json_token.o base/utils/linked_list.o base/utils/mem_stats.o base/utils/string_utils.o base/utils/utils_base64.o base/utils/utils_epoch_time.o base/utils/utils_hmac.o base/utils/utils_httpc.o base/utils/utils_list.o base/utils/utils_md5.o base/utils/utils_net.o base/utils/utils_sha1.o base/utils/utils_timer.o base/utils/work_queue.o connectivity/coap/alcs_api.o connectivity/coap/alcs_client.o connectivity/coap/alcs_coap.o connectivity/coap/alcs_server.o connectivity/coap/CoAPDeserialize.o connectivity/coap/CoAPExport.o connectivity/coap/CoAPMessage.o connectivity/coap/CoAPNetwork.o connectivity/coap/CoAPObserve.o connectivity/coap/CoAPPlatform.o connectivity/coap/CoAPResource.o connectivity/coap/CoAPSerialize.o connectivity/coap/CoAPServer.o connectivity/mqtt/mqtt_client.o connectivity/mqtt/MQTTConnectClient.o connectivity/mqtt/MQTTDeserializePublish.o connectivity/mqtt/mqtt_instance.o connectivity/mqtt/MQTTPacket.o connectivity/mqtt/MQTTSerializePublish.o connectivity/mqtt/MQTTSubscribeClient.o connectivity/mqtt/MQTTUnsubscribeClient.o connectivity/ota/ota.o connectivity/system/ca.o connectivity/system/class_interface.o connectivity/system/device.o connectivity/system/guider.o connectivity/system/id2_guider.o connectivity/system/report.o connectivity/system/sdk-impl.o layers/cm/iotx_cloud_conn_coap.o layers/cm/iotx_cloud_conn_http.o layers/cm/iotx_cloud_conn_mqtt.o layers/cm/iotx_cm_api.o layers/cm/iotx_cm_cloud_conn.o layers/cm/iotx_cm_common.o layers/cm/iotx_cm_local_conn.o layers/cm/iotx_cm_log.o layers/cm/iotx_cm_ota.o layers/cm/iotx_local_conn_alcs.o layers/dm/cJSON.o layers/dm/dm_cm_impl.o layers/dm/dm_cm_msg_info.o layers/dm/dm_impl.o layers/dm/dm_logger.o layers/dm/dm_slist.o layers/dm/dm_thing_manager.o layers/dm/dm_thing.o layers/linkkit/linkkit_export.o layers/linkkit/lite_queue.o modules/alcs/alcs_adapter.o modules/alcs/alcs_mqtt.o service/fota/service_ota.o
以上步骤已生成可以直接应用于esp32的二进制文件,将步骤1的
ProductKey
、DeviceName
、DeviceSecret
、ProductSecret
分别写入目标平台的HAL_GetProductKey
、HAL_GetDeviceName
、HAL_GetDeviceSecret
、HAL_GetProductSecret
函数linkkit SDK 提供的API位于layers/linkkit/include/linkkit_export.h,
完成设备功能的编写后,您可以链接libilop-目标平台.a
编译生成固件运行您的程序5. 示例代码
参考示例代码完成您设备相关操作代码的编写。
/** USER NOTIFICATION
* this sample code is only used for evaluation or test of the iLop project.
* Users should modify this sample code freely according to the product/device TSL, like
* property/event/service identifiers, and the item value type(type, length, etc...).
* Create user's own execution logic for specific products.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdarg.h>
#include <unistd.h>
#include "linkkit_export.h"
#include "iot_import.h"
/*
* example for product "灯-Demo"
*/
#define LINKKIT_PRINTF(...) \
do { \
printf("\e[0;32m%s@line%d\t:", __FUNCTION__, __LINE__); \
printf(__VA_ARGS__); \
printf("\e[0m"); \
} while (0)
/* identifier of property/service/event, users should modify this macros according to your own product TSL. */
#define EVENT_PROPERTY_POST_IDENTIFIER "post"
#define EVENT_ERROR_IDENTIFIER "Error"
#define EVENT_ERROR_OUTPUT_INFO_IDENTIFIER "ErrorCode"
#define EVENT_CUSTOM_IDENTIFIER "Custom"
/* specify ota buffer size for ota service, ota service will use this buffer for bin download. */
#define OTA_BUFFER_SIZE (512+1)
/* PLEASE set RIGHT tsl string according to your product. */
const char TSL_STRING[] = "{\"schema\":\"http://aliyun/iot/thing/desc/schema\",\"profile\":{\"productKey\":\"productKey123\",\"deviceName\":\"deviceName456\"},\"link\":\"/sys/a1AzoSi5TMc/olin_linkkit_test/thing/\",\"services\":[{\"outputData\":[],\"identifier\":\"set\",\"inputData\":[{\"identifier\":\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"主灯开关\"},{\"identifier\":\"RGBColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"红色\"},{\"identifier\":\"Green\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"绿色\"},{\"identifier\":\"Blue\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"蓝色\"}],\"type\":\"struct\"},\"name\":\"RGB调色\"},{\"identifier\":\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"夜灯开关\"},{\"identifier\":\"WorkMode\",\"dataType\":{\"specs\":{\"0\":\"手动\",\"1\":\"阅读\",\"2\":\"影院\",\"3\":\"夜灯\",\"4\":\"生活\",\"5\":\"柔和\"},\"type\":\"enum\"},\"name\":\"工作模式\"},{\"identifier\":\"ColorTemperature\",\"dataType\":{\"specs\":{\"unit\":\"K\",\"min\":\"2700\",\"unitName\":\"开尔文\",\"max\":\"6500\"},\"type\":\"int\"},\"name\":\"冷暖色温\"},{\"identifier\":\"Brightness\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"明暗度\"},{\"identifier\":\"HSLColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"°\",\"min\":\"0\",\"unitName\":\"度\",\"max\":\"360\"},\"type\":\"int\"},\"name\":\"色调\"},{\"identifier\":\"Saturation\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"饱和度\"},{\"identifier\":\"Lightness\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"亮度\"}],\"type\":\"struct\"},\"name\":\"HSL调色\"},{\"identifier\":\"HSVColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"色调\"},{\"identifier\":\"Saturation\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"饱和度\"},{\"identifier\":\"Value\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"明度\"}],\"type\":\"struct\"},\"name\":\"HSV调色\"},{\"identifier\":\"PropertyTime\",\"dataType\":{\"specs\":{},\"type\":\"date\"},\"name\":\"时间\"},{\"identifier\":\"Propertypoint\",\"dataType\":{\"specs\":{\"min\":\"-100\",\"max\":\"100\"},\"type\":\"double\"},\"name\":\"浮点型\"},{\"identifier\":\"PropertyCharacter\",\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":\"字符串\"}],\"method\":\"thing.service.property.set\",\"name\":\"set\",\"required\":true,\"callType\":\"sync\",\"desc\":\"属性设置\"},{\"outputData\":[{\"identifier\":\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"主灯开关\"},{\"identifier\":\"RGBColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"红色\"},{\"identifier\":\"Green\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"绿色\"},{\"identifier\":\"Blue\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"蓝色\"}],\"type\":\"struct\"},\"name\":\"RGB调色\"},{\"identifier\":\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"夜灯开关\"},{\"identifier\":\"WorkMode\",\"dataType\":{\"specs\":{\"0\":\"手动\",\"1\":\"阅读\",\"2\":\"影院\",\"3\":\"夜灯\",\"4\":\"生活\",\"5\":\"柔和\"},\"type\":\"enum\"},\"name\":\"工作模式\"},{\"identifier\":\"ColorTemperature\",\"dataType\":{\"specs\":{\"unit\":\"K\",\"min\":\"2700\",\"unitName\":\"开尔文\",\"max\":\"6500\"},\"type\":\"int\"},\"name\":\"冷暖色温\"},{\"identifier\":\"Brightness\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"明暗度\"},{\"identifier\":\"HSLColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"°\",\"min\":\"0\",\"unitName\":\"度\",\"max\":\"360\"},\"type\":\"int\"},\"name\":\"色调\"},{\"identifier\":\"Saturation\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"饱和度\"},{\"identifier\":\"Lightness\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"亮度\"}],\"type\":\"struct\"},\"name\":\"HSL调色\"},{\"identifier\":\"HSVColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"色调\"},{\"identifier\":\"Saturation\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"饱和度\"},{\"identifier\":\"Value\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"明度\"}],\"type\":\"struct\"},\"name\":\"HSV调色\"},{\"identifier\":\"PropertyTime\",\"dataType\":{\"specs\":{},\"type\":\"date\"},\"name\":\"时间\"},{\"identifier\":\"Propertypoint\",\"dataType\":{\"specs\":{\"min\":\"-100\",\"max\":\"100\"},\"type\":\"double\"},\"name\":\"浮点型\"},{\"identifier\":\"PropertyCharacter\",\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":\"字符串\"}],\"identifier\":\"get\",\"inputData\":[\"LightSwitch\",\"RGBColor\",\"NightLightSwitch\",\"WorkMode\",\"ColorTemperature\",\"Brightness\",\"HSLColor\",\"HSVColor\",\"PropertyTime\",\"Propertypoint\",\"PropertyCharacter\"],\"method\":\"thing.service.property.get\",\"name\":\"get\",\"required\":true,\"callType\":\"sync\",\"desc\":\"属性获取\"},{\"outputData\":[{\"identifier\":\"Contrastratio\",\"dataType\":{\"specs\":{\"min\":\"0\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"对比度\"}],\"identifier\":\"Custom\",\"inputData\":[{\"identifier\":\"transparency\",\"dataType\":{\"specs\":{\"min\":\"0\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"透明度\"}],\"method\":\"thing.service.Custom\",\"name\":\"自定义服务\",\"required\":false,\"callType\":\"async\"}],\"properties\":[{\"identifier\":\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"主灯开关\",\"accessMode\":\"rw\",\"required\":true},{\"identifier\":\"RGBColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"红色\"},{\"identifier\":\"Green\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"绿色\"},{\"identifier\":\"Blue\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"蓝色\"}],\"type\":\"struct\"},\"name\":\"RGB调色\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"夜灯开关\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"WorkMode\",\"dataType\":{\"specs\":{\"0\":\"手动\",\"1\":\"阅读\",\"2\":\"影院\",\"3\":\"夜灯\",\"4\":\"生活\",\"5\":\"柔和\"},\"type\":\"enum\"},\"name\":\"工作模式\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"ColorTemperature\",\"dataType\":{\"specs\":{\"unit\":\"K\",\"min\":\"2700\",\"unitName\":\"开尔文\",\"max\":\"6500\"},\"type\":\"int\"},\"name\":\"冷暖色温\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"Brightness\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"明暗度\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"HSLColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"°\",\"min\":\"0\",\"unitName\":\"度\",\"max\":\"360\"},\"type\":\"int\"},\"name\":\"色调\"},{\"identifier\":\"Saturation\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"饱和度\"},{\"identifier\":\"Lightness\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"亮度\"}],\"type\":\"struct\"},\"name\":\"HSL调色\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"HSVColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"色调\"},{\"identifier\":\"Saturation\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"饱和度\"},{\"identifier\":\"Value\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"明度\"}],\"type\":\"struct\"},\"name\":\"HSV调色\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"PropertyTime\",\"dataType\":{\"specs\":{},\"type\":\"date\"},\"name\":\"时间\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"Propertypoint\",\"dataType\":{\"specs\":{\"min\":\"-100\",\"max\":\"100\"},\"type\":\"double\"},\"name\":\"浮点型\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"PropertyCharacter\",\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":\"字符串\",\"accessMode\":\"rw\",\"required\":false}],\"events\":[{\"outputData\":[{\"identifier\":\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"主灯开关\"},{\"identifier\":\"RGBColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"红色\"},{\"identifier\":\"Green\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"绿色\"},{\"identifier\":\"Blue\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"蓝色\"}],\"type\":\"struct\"},\"name\":\"RGB调色\"},{\"identifier\":\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"夜灯开关\"},{\"identifier\":\"WorkMode\",\"dataType\":{\"specs\":{\"0\":\"手动\",\"1\":\"阅读\",\"2\":\"影院\",\"3\":\"夜灯\",\"4\":\"生活\",\"5\":\"柔和\"},\"type\":\"enum\"},\"name\":\"工作模式\"},{\"identifier\":\"ColorTemperature\",\"dataType\":{\"specs\":{\"unit\":\"K\",\"min\":\"2700\",\"unitName\":\"开尔文\",\"max\":\"6500\"},\"type\":\"int\"},\"name\":\"冷暖色温\"},{\"identifier\":\"Brightness\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"明暗度\"},{\"identifier\":\"HSLColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"°\",\"min\":\"0\",\"unitName\":\"度\",\"max\":\"360\"},\"type\":\"int\"},\"name\":\"色调\"},{\"identifier\":\"Saturation\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"饱和度\"},{\"identifier\":\"Lightness\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"亮度\"}],\"type\":\"struct\"},\"name\":\"HSL调色\"},{\"identifier\":\"HSVColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"色调\"},{\"identifier\":\"Saturation\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"饱和度\"},{\"identifier\":\"Value\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"明度\"}],\"type\":\"struct\"},\"name\":\"HSV调色\"},{\"identifier\":\"PropertyTime\",\"dataType\":{\"specs\":{},\"type\":\"date\"},\"name\":\"时间\"},{\"identifier\":\"Propertypoint\",\"dataType\":{\"specs\":{\"min\":\"-100\",\"max\":\"100\"},\"type\":\"double\"},\"name\":\"浮点型\"},{\"identifier\":\"PropertyCharacter\",\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":\"字符串\"}],\"identifier\":\"post\",\"method\":\"thing.event.property.post\",\"name\":\"post\",\"type\":\"info\",\"required\":true,\"desc\":\"属性上报\"},{\"outputData\":[{\"identifier\":\"ErrorCode\",\"dataType\":{\"specs\":{\"0\":\"恢复正常\"},\"type\":\"enum\"},\"name\":\"故障代码\"}],\"identifier\":\"Error\",\"method\":\"thing.event.Error.post\",\"name\":\"故障上报\",\"type\":\"info\",\"required\":true}]}";
/* user sample context struct. */
typedef struct _sample_context {
void* thing;
int cloud_connected;
int thing_enabled;
int service_custom_input_transparency;
int service_custom_output_contrastratio;
#ifdef SERVICE_OTA_ENABLED
char ota_buffer[OTA_BUFFER_SIZE];
#endif /* SERVICE_OTA_ENABLED */
} sample_context_t;
sample_context_t g_sample_context;
#ifdef SERVICE_OTA_ENABLED
/* callback function for fota service. */
static void fota_callback(service_fota_callback_type_t callback_type, const char* version)
{
sample_context_t* sample;
assert(callback_type < service_fota_callback_type_number);
sample = &g_sample_context;
/* temporarily disable thing when ota service invoked */
sample->thing_enabled = 0;
linkkit_invoke_ota_service(sample->ota_buffer, OTA_BUFFER_SIZE);
sample->thing_enabled = 1;
/* reboot the device... */
}
#endif /* SERVICE_OTA_ENABLED */
static int on_connect(void* ctx)
{
sample_context_t* sample = ctx;
sample->cloud_connected = 1;
LINKKIT_PRINTF("cloud is connected\n");
return 0;
}
static int on_disconnect(void* ctx)
{
sample_context_t* sample = ctx;
sample->cloud_connected = 0;
LINKKIT_PRINTF("cloud is disconnect\n");
return 0;
}
static int raw_data_arrived(void* thing_id, void* data, int len, void* ctx)
{
char raw_data[128] = {0};
LINKKIT_PRINTF("raw data arrived,len:%d\n", len);
/* do user's raw data process logical here. */
/* ............................... */
/* user's raw data process logical complete */
snprintf(raw_data, sizeof(raw_data), "test down raw reply data %lld", HAL_UptimeMs());
linkkit_invoke_raw_service(thing_id, 0, raw_data, strlen(raw_data));
return 0;
}
static int thing_create(void* thing_id, void* ctx)
{
sample_context_t* sample = ctx;
LINKKIT_PRINTF("new thing@%p created.\n", thing_id);
sample->thing = thing_id;
return 0;
}
static int thing_enable(void* thing_id, void* ctx)
{
sample_context_t* sample = ctx;
sample->thing_enabled = 1;
return 0;
}
static int thing_disable(void* thing, void* ctx)
{
sample_context_t* sample = ctx;
sample->thing_enabled = 0;
return 0;
}
#ifdef RRPC_ENABLED
static int handle_service_custom(sample_context_t* sample, void* thing, char* service_identifier, int request_id, int rrpc)
#else
static int handle_service_custom(sample_context_t* sample, void* thing, char* service_identifier, int request_id)
#endif /* RRPC_ENABLED */
{
char identifier[128] = {0};
/*
* get iutput value.
*/
snprintf(identifier, sizeof(identifier), "%s.%s", service_identifier, "transparency");
linkkit_get_value(linkkit_method_get_service_input_value, thing, identifier, &sample->service_custom_input_transparency, NULL);
/*
* set output value according to user's process result.
*/
snprintf(identifier, sizeof(identifier), "%s.%s", service_identifier, "Contrastratio");
sample->service_custom_output_contrastratio = sample->service_custom_input_transparency >= 0 ? sample->service_custom_input_transparency : sample->service_custom_input_transparency * -1;
linkkit_set_value(linkkit_method_set_service_output_value, thing, identifier, &sample->service_custom_output_contrastratio, NULL);
#ifdef RRPC_ENABLED
linkkit_answer_service(thing, service_identifier, request_id, 200, rrpc);
#else
linkkit_answer_service(thing, service_identifier, request_id, 200);
#endif /* RRPC_ENABLED */
return 0;
}
#ifdef RRPC_ENABLED
static int thing_call_service(void* thing_id, char* service, int request_id, int rrpc, void* ctx)
#else
static int thing_call_service(void* thing_id, char* service, int request_id, void* ctx)
#endif /* RRPC_ENABLED */
{
sample_context_t* sample = ctx;
LINKKIT_PRINTF("service(%s) requested, id: thing@%p, request id:%d\n",
service, thing_id, request_id);
if (strcmp(service, "Custom") == 0) {
#ifdef RRPC_ENABLED
handle_service_custom(sample, thing_id, service, request_id, rrpc);
#else
handle_service_custom(sample, thing_id, service, request_id);
#endif /* RRPC_ENABLED */
}
return 0;
}
static int thing_prop_changed(void* thing_id, char* property, void* ctx)
{
char* value_str = NULL;
char property_buf[64] = {0};
/* get new property value */
if (strstr(property, "HSVColor") != 0) {
int hue, saturation, value;
snprintf(property_buf, sizeof(property_buf), "%s.%s", property, "Hue");
linkkit_get_value(linkkit_method_get_property_value, thing_id, property_buf, &hue, &value_str);
snprintf(property_buf, sizeof(property_buf), "%s.%s", property, "Saturation");
linkkit_get_value(linkkit_method_get_property_value, thing_id, property_buf, &saturation, &value_str);
snprintf(property_buf, sizeof(property_buf), "%s.%s", property, "Value");
linkkit_get_value(linkkit_method_get_property_value, thing_id, property_buf, &value, &value_str);
LINKKIT_PRINTF("property(%s), Hue:%d, Saturation:%d, Value:%d\n", property, hue, saturation, value);
/* XXX: do user's process logical here. */
} else if (strstr(property, "HSLColor") != 0) {
int hue, saturation, lightness;
snprintf(property_buf, sizeof(property_buf), "%s.%s", property, "Hue");
linkkit_get_value(linkkit_method_get_property_value, thing_id, property_buf, &hue, &value_str);
snprintf(property_buf, sizeof(property_buf), "%s.%s", property, "Saturation");
linkkit_get_value(linkkit_method_get_property_value, thing_id, property_buf, &saturation, &value_str);
snprintf(property_buf, sizeof(property_buf), "%s.%s", property, "Lightness");
linkkit_get_value(linkkit_method_get_property_value, thing_id, property_buf, &lightness, &value_str);
LINKKIT_PRINTF("property(%s), Hue:%d, Saturation:%d, Lightness:%d\n", property, hue, saturation, lightness);
/* XXX: do user's process logical here. */
} else if (strstr(property, "RGBColor") != 0) {
int red, green, blue;
snprintf(property_buf, sizeof(property_buf), "%s.%s", property, "Red");
linkkit_get_value(linkkit_method_get_property_value, thing_id, property_buf, &red, &value_str);
snprintf(property_buf, sizeof(property_buf), "%s.%s", property, "Green");
linkkit_get_value(linkkit_method_get_property_value, thing_id, property_buf, &green, &value_str);
snprintf(property_buf, sizeof(property_buf), "%s.%s", property, "Blue");
linkkit_get_value(linkkit_method_get_property_value, thing_id, property_buf, &blue, &value_str);
LINKKIT_PRINTF("property(%s), Red:%d, Green:%d, Blue:%d\n", property, red, green, blue);
/* XXX: do user's process logical here. */
} else {
linkkit_get_value(linkkit_method_get_property_value, thing_id, property, NULL, &value_str);
LINKKIT_PRINTF("#### property(%s) new value set: %s ####\n", property, value_str);
}
/* do user's process logical here. */
linkkit_trigger_event(thing_id, EVENT_PROPERTY_POST_IDENTIFIER, property);
return 0;
}
static linkkit_ops_t alinkops = {
.on_connect = on_connect,
.on_disconnect = on_disconnect,
.raw_data_arrived = raw_data_arrived,
.thing_create = thing_create,
.thing_enable = thing_enable,
.thing_disable = thing_disable,
.thing_call_service = thing_call_service,
.thing_prop_changed = thing_prop_changed,
};
static unsigned long long uptime_sec(void)
{
static unsigned long long start_time = 0;
if (start_time == 0) {
start_time = HAL_UptimeMs();
}
return (HAL_UptimeMs() - start_time) / 1000;
}
#if 0
static int post_all_prop(sample_context_t* sample)
{
return linkkit_trigger_event(sample->thing, EVENT_PROPERTY_POST_IDENTIFIER, NULL);
}
#endif
static int post_event_error(sample_context_t* sample)
{
char event_output_identifier[64];
snprintf(event_output_identifier, sizeof(event_output_identifier), "%s.%s", EVENT_ERROR_IDENTIFIER, EVENT_ERROR_OUTPUT_INFO_IDENTIFIER);
int errorCode = 0;
linkkit_set_value(linkkit_method_set_event_output_value,
sample->thing,
event_output_identifier,
&errorCode, NULL);
return linkkit_trigger_event(sample->thing, EVENT_ERROR_IDENTIFIER, NULL);
}
#if 0
static int post_event_fault_alert(sample_context_t* sample)
{
char event_output_identifier[64];
snprintf(event_output_identifier, sizeof(event_output_identifier), "%s.%s", EVENT_ERROR_IDENTIFIER, EVENT_ERROR_OUTPUT_INFO_IDENTIFIER);
int errorCode = 0;
linkkit_set_value(linkkit_method_set_event_output_value,
sample->thing,
event_output_identifier,
&errorCode, NULL);
return linkkit_trigger_event(sample->thing, EVENT_ERROR_IDENTIFIER, NULL);
}
static int upload_raw_data(sample_context_t* sample)
{
char raw_data[128] = {0};
snprintf(raw_data, sizeof(raw_data), "test up raw data %lld", HAL_UptimeMs());
return linkkit_invoke_raw_service(sample->thing, 1, raw_data, strlen(raw_data));
}
#endif
static int is_active(sample_context_t* sample)
{
return sample->cloud_connected && sample->thing_enabled;
}
int main(int argc, char* argv[])
{
sample_context_t* sample_ctx = &g_sample_context;
int execution_time = 0;
int get_tsl_from_cloud = 0;
int exit = 0;
int ret;
unsigned long long now = 0;
unsigned long long prev_sec = 0;
int opt;
while ((opt = getopt(argc, argv, "t:g:h")) != -1) {
switch (opt) {
case 't':
execution_time = atoi(optarg);
break;
case 'g':
get_tsl_from_cloud = atoi(optarg);
break;
case 'h':
LINKKIT_PRINTF("-t to specify sample execution time period(minutes); -g to specify if get tsl from cloud(0: not, !0: yes).\n");
return 0;
break;
default:
break;
}
}
execution_time = execution_time < 1 ? 1 : execution_time;
LINKKIT_PRINTF("sample execution time: %d minutes\n", execution_time);
LINKKIT_PRINTF("%s tsl from cloud\n", get_tsl_from_cloud == 0 ? "Not get" : "get");
memset(sample_ctx, 0, sizeof(sample_context_t));
sample_ctx->thing_enabled = 1;
linkkit_start(18, get_tsl_from_cloud, linkkit_loglevel_debug, &alinkops, linkkit_cloud_domain_sh, sample_ctx);
if (!get_tsl_from_cloud) {
linkkit_set_tsl(TSL_STRING, strlen(TSL_STRING));
}
#ifdef SERVICE_OTA_ENABLED
linkkit_ota_init(fota_callback);
#endif /* SERVICE_OTA_ENABLED */
while (1) {
linkkit_dispatch();
now = uptime_sec();
if (prev_sec == now) {
#ifdef CMP_SUPPORT_MULTI_THREAD
HAL_SleepMs(100);
#else
linkkit_yield(100);
#endif
continue;
}
#if 0
/* about 30 seconds, assume trigger post property event about every 30s. */
if (now % 30 == 0 && is_active(sample_ctx)) {
post_all_prop(sample_ctx);
}
/* about 31 seconds, assume invoke raw up service about every 31s. */
if (now % 31 == 0 && is_active(sample_ctx)) {
upload_raw_data(sample_ctx);
}
/* about 60 seconds, assume trigger event about every 60s. */
if (now % 60 == 0 && is_active(sample_ctx)) {
post_event_fault_alert(sample_ctx);
}
#endif
/* about 60 seconds, assume trigger event about every 60s. */
if (now % 60 == 0 && is_active(sample_ctx)) {
post_event_error(sample_ctx);
}
if (now % 5 == 0 && is_active(sample_ctx)) {
ret = linkkit_trigger_deviceinfo_operate(sample_ctx->thing, "[{\"attrKey\":\"Temperature\",\"attrValue\":\"36.8\"}]", linkkit_deviceinfo_operate_update);
}
if (exit) break;
/* after all, this is an sample, give a chance to return... */
/* modify this value for this sample executaion time period */
if (now > 60 * execution_time) exit = 1;
prev_sec = now;
}
linkkit_end();
return 0;
}