本文提供了一个插座本地定时功能的开发示例,开发者可以参考本文,实现任意设备的本地定时功能。

背景信息

本地定时是相对云端定时而言,是指当设备离线时,也能自动执行定时任务。要实现本地定时的效果,设备端和APP端可以按照本文推荐的方式进行实现。

  • 设备端:按照平台标准数据格式,实现定时任务的增删改。
  • App端:可以直接使用平台提供的“设备界面”插件,或“本地定时”App插件,无需额外开发App页面。

定时

操作步骤

  1. 在控制台人机交互 > 自动化和定时处,勾选本地定时功能,并在功能参数中设置本地定时的最大条数(与设备端的存储、性能有关)。

    本地定时

    平台会在功能定义中自动插入一个本地定时的标准功能(LocalTimer),功能为JSON数组(JSON Array)格式,其中数组中的每个JSON都是一个定时任务,例如“每天6:00关闭空调”,并支持多个定时任务。

    功能的参数如下。

    • 必选参数1:定时时间-Timer-(cron类型)字符串
    • 必选参数2:启用-Enable-布尔
    • 必选参数3:可执行-IsValid-布尔
    • 可选参数4:定时动作-Targets-字符串
    • 可选参数5:时区-TimezoneOffset-整数(-43200到50400,步进1)
    参数类型 参数名称 标识符 数值类型 参数描述
    标准参数 定时时间 Timer 字符串 必选,不可删除,用于表示定时时间,使用corn格式
    标准参数 启用 Enable 布尔 必选,不可删除,表明是否启用
    标准参数 可执行 IsValid 布尔 必选,不可删除,表明这条定时任务是否需要展示给用户看(因为设备端会将所有定时的数据传给app端)
    自定义参数 定时动作 Targets 字符串 可选,用来表明当次设置的定时任务的具体动作。添加Targets属性可以设置任意数量的动作(最大值:2048,可以为空)
    自定义参数 时差 TimezoneOffset 整数 可选,用来表示本地事件与UTC时间的差值,单位秒,取值范围为(-43200到50400,步进1)
    自定义参数 如插孔开关1 SocketSwitch_1 布尔 定时的功能,必须和功能定义中的功能保持一致,如针对开关进行定时,此处设为 插孔开关1 - SocketSwitch_1 - 布尔型。
    自定义参数 如插孔开关2 SocketSwitch_2 布尔 每个定时任务中,支持多个功能
    说明 自定义参数的数量不限,可根据需要配置。
  2. 设备开发与调试。
    1. 在云端控制台上定义好了LocalTimer的属性。
      定义成功后,设备端可以接收从云端下来的property set消息,从而获取定时任务的具体信息。
    2. 获取aos1.3.4版本sdk,demo位于aos/example/linkkitapp/linkkit_example_solo.c
    3. 测试设备。
      设备收到定时任务的属性时,在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;
      }
      							
      说明 设备端接收到的一个本地定时的示例,采用数组格式描叙,数组中共5条定时记录,其中IsValid定义该条是否有效,每一条定时记录的处理,需要客户自己来实现。

      TSL示例如下。

      {
      "LocalTimer": [{
      "LightSwitch": 1,
      "ColorTemperature": 2000,
      "Timer": "5 4 1,2,3",
      "TimezoneOffset": 43200,
      "Brightness": 0,
      "Enable": 1,
      "Targets": "LightSwitch",
      "WorkMode": 0,
      "IsValid": 1
      }, {
      "LightSwitch": 0,
      "ColorTemperature": 2000,
      "Timer": "",
      "TimezoneOffset": 43200,
      "Brightness": 0,
      "Enable": 0,
      "Targets": "",
      "WorkMode": 0,
      "IsValid": 0
      }, {
      "LightSwitch": 0,
      "ColorTemperature": 2000,
      "Timer": "",
      "TimezoneOffset": 43200,
      "Brightness": 0,
      "Enable": 0,
      "Targets": "",
      "WorkMode": 0,
      "IsValid": 0
      }, {
      "LightSwitch": 0,
      "ColorTemperature": 2000,
      "Timer": "",
      "TimezoneOffset": 43200,
      "Brightness": 0,
      "Enable": 0,
      "Targets": "",
      "WorkMode": 0,
      "IsValid": 0
      }, {
      "LightSwitch": 0,
      "ColorTemperature": 2000,
      "Timer": "",
      "TimezoneOffset": 43200,
      "Brightness": 0,
      "Enable": 0,
      "Targets": "",
      "WorkMode": 0,
      "IsValid": 0
      }]
      }
  3. 集成App插件。
    本地定时插件的代码为: link://router/localTimer,可以将该代码复制到您的App代码中,调用该插件。

    详细操作参见配置App界面,在页面中可以看到目前所有的插件列表,单击每一个插件旁边的生成代码按钮,即可开通该插件在您的自有App中的调用权限。

  4. 配置兼容性。
    • 插件端

      当前本地定时插件中,如果在LocalTimer里添加了多个动作,则必须设置完所有动作,才能正常保存。该问题在新版本地定时插件通过添加了Targets已解决,可忽略。

    • 设备端

      设备端在收到LocalTimer后,会根据Targets属性来设定自己的定时任务。如果没有Targets或者Targets为空,则执行LocalTimer里添加的全部动作(指Timer,Enable,IsValid以外的属性动作)。