本地定时功能开发实践

更新时间:2019-01-16 14:20:56

1. 概述

本文提供了一个插座本地定时功能的开发案例,开发者可以参考本文,实现任意设备的本地定时功能。
“本地定时”是相对”云端定时”而言的,是指当设备离线时,也能自动执行定时任务。要实现本地定时的效果,设备端和APP端可以按照本文推荐的方式进行实现。
设备端:按照平台标准数据格式,实现定时任务的增删改。
APP端:可以直接使用平台提供的“设备界面”插件,或“本地定时”APP插件,无需额外开发APP页面。

定时.png | left | 827x218

2. 准备工作

控制台中注册您的产品,详细参考 产品注册,本文以插座为例。在 功能定义 中,需要选择标准功能“本地定时”(LocalTimer),为JSON数组(JSON Array)格式,其中数组中的每个JSON都是一个定时任务,比如“每天6:00关闭空调”,并支持多个定时任务。
参数如下:
必选参数1:定时时间-Timer-(cron类型)字符串
必选参数2:启用-Enable-布尔
必选参数3:可执行-IsValid-布尔
可选参数4:定时动作-Targets-字符串

参数名称 标识符 参数类型 参数描述
标准参数 定时时间 Timer 字符串 必选,不可删除,用于表示定时时间,使用corn格式
标准参数 启用 Enable 布尔 必选,不可删除,表明是否启用
标准参数 可执行 IsValid 布尔 必选,不可删除,表明这条定时任务是否需要展示给用户看(因为设备端会将所有定时的数据传给app端)
自定义参数 定时动作 Targets 字符串 可选,用来表明当次设置的定时任务的具体动作有哪些。如果没有添加Targets属性,那么用户在设置定时的时候必须把全部动作设置才能保存,添加Targets属性才可以设置任意数量的动作(最大值:2048,可以为空)
自定义参数 如插孔开关1 SocketSwitch_1 布尔 定时的功能,必须和功能定义中的功能保持一致,如针对开关进行定时,此处设为 插孔开关1 - SocketSwitch_1 - 布尔型。
自定义参数 如插孔开关2 SocketSwitch_2 布尔 每个定时任务中,支持多个功能
自定义参数 不限数量

image.png | left | 537x540

3. 设备开发和调试

  • 在云端控制台上定义好了LocalTimer的属性之后,设备端可以接收从云端下来的property set消息,从而获取定时任务的具体信息。

  • 获取aos1.3.4版本sdk,demo位于aos/example/linkkitapp/linkkit_example_solo.c

  • 设备收到定时任务的属性时,会进到user_property_set_event_handler中,如下图所示:

      /*
       * the handler of property changed
       * alink method: thing.service.property.set
       */
      static int user_property_set_event_handler(const int devid, const char *request, const int request_len)
      {
          int res = 0;
          user_example_ctx_t *user_example_ctx = user_example_get_ctx();
    
          EXAMPLE_TRACE("Property Set Received, Devid: %d, Request: %s", devid, request);
    
          cJSON * data_JSON = cJSON_Parse(request);
          if(cJSON_GetObjectItem(data_JSON,"LocalTimer") != NULL)
          {
              cJSON *localtime_arr = cJSON_GetObjectItem(data_JSON,"LocalTimer");
              uint32_t arrysize = cJSON_GetArraySize(localtime_arr);
              cJSON *arr_item = localtime_arr->child;
              for(int i = 0;i < arrysize; i++)
                  handle_localtime(arr_item, i);
          }
    
          res = IOT_Linkkit_Report(user_example_ctx->master_devid, ITM_MSG_POST_PROPERTY,(unsigned char *)request, request_len);
          EXAMPLE_TRACE("Post Property Message ID: %d", res);
          cJSON_Delete(data_JSON);
    
          return 0;
      }
    
  • TSL示例
    {
    "LocalTimer": [{

      "LightSwitch": 1,
      "ColorTemperature": 2000,
      "Timer": "5 4 \* \*1,2,3",
      "Brightness": 0,
      "Enable": 1,
      "Targets": "LightSwitch",
      "WorkMode": 0,
      "IsValid": 1
    

    }, {

      "LightSwitch": 0,
      "ColorTemperature": 2000,
      "Timer": "",
      "Brightness": 0,
      "Enable": 0,
      "Targets": "",
      "WorkMode": 0,
      "IsValid": 0
    

    }, {

      "LightSwitch": 0,
      "ColorTemperature": 2000,
      "Timer": "",
      "Brightness": 0,
      "Enable": 0,
      "Targets": "",
      "WorkMode": 0,
      "IsValid": 0
    

    }, {

      "LightSwitch": 0,
      "ColorTemperature": 2000,
      "Timer": "",
      "Brightness": 0,
      "Enable": 0,
      "Targets": "",
      "WorkMode": 0,
      "IsValid": 0
    

    }, {

      "LightSwitch": 0,
      "ColorTemperature": 2000,
      "Timer": "",
      "Brightness": 0,
      "Enable": 0,
      "Targets": "",
      "WorkMode": 0,
      "IsValid": 0
    

    }]
    }

  • 如上是设备端接收到的一个本地定时的示例,采用数组格式描叙,数组中共5条定时记录,其中"IsValid"定义该条是否有效,定时的逻辑处理可以参考如上实现,每一条详细处理,需要客户自己来实现。

4. 集成APP插件

本地定时插件的代码为:link://router/localTimer,可以将该代码复制到您的App代码中,调用该插件。
如何开通:
在living.aliyun.com网站里您的项目中,找到自有品牌APP模块,进入后,将会看到App界面这个导航。点进去后,在页面中可以看到目前所有的插件列表,点击每一个插件旁边的“生成代码”按钮,即可开通该插件在您的自有App中的调用权限。

新版本地定时兼容问题

插件端

1.当前本地定时LocalTimer里如果添加了多个动作,那必须设置完所有动作,才能正常保存。
2.新版本地定时插件解决了该问题,当检测出功能定义里添加了Targets,设置任意(大于零)个动作就能正常保存,如果没有Targets则走以前的旧逻辑。(如 1 所述)

2.设备端

设备端在收到LocalTimer后,看Targets属性里的动作有哪些,根据这些动作来设定自己的定时任务。没有Targets或者Targets为空字符串,就执行LocalTimer里添加的全部动作(这些动作不是指Timer,Enable,IsValid这几个属性)。

results matching ""

    No results matching ""