时间服务

更新时间:2024-04-17 06:15:10下载pdf

本文介绍蓝牙设备支持的时间服务。

概述

概念介绍

蓝牙设备支持本地时间服务,设备上电后时间从 0 开始,时间精度为 1s,误差取决于不同芯片内部低频晶振的精度或者外部低频晶振的精度。

当设备和涂鸦智能 App 配网成功后,设备会向 App 请求时间同步。根据设备请求时间类型的不同,App 支持返回云端实时时间,也支持返回 App 本地时间,之后设备会按照获取到的时间标准执行本地时间服务。

功能描述

如下图所示,时间服务主要包含 RTC 计时、UTC 时间转换和时间同步三个模块。

其中,RTC 计时主要由 tal_rtc.c 实现,包含芯片平台相关的 RTC 计时服务。UTC 时间转换模块由 tal_utc 组件实现,包含时间戳和通用时间格式转换等内容。时间同步模块的主要功能是从云端/App 同步实时时间。

时间服务

数据结构

tuya_ble_timestamp_data_t

typedef struct {
    UINT8_T timestamp_string[14];
    INT16_T time_zone;   // Multiply actual time zone by 100.
} tuya_ble_timestamp_data_t;
  • timestamp_string:13 字节字符串,Unix ms 级时间。

  • time_zone:有符号型,实际时区的 100 倍,例如北京东八区为 8 × 100 = 800,西 7.5 区为 -750。

tuya_ble_time_noraml_data_t

typedef struct {
    UINT16_T nYear;
    UINT8_T nMonth;
    UINT8_T nDay;
    UINT8_T nHour;
    UINT8_T nMin;
    UINT8_T nSec;
    UINT8_T DayIndex; /* 0 = Sunday */
    INT16_T time_zone;   // Multiply actual time zone by 100.
} tuya_ble_time_noraml_data_t;
  • nYear:年。
  • nMonth:月。
  • nDay:日。
  • nHour:时。
  • nMin:分。
  • nSec:秒。
  • DayIndex:星期。
  • time_zone:有符号型,实际时区的 100 倍,例如北京东八区为 8 × 100 = 800,西 7.5 区为 -750。

tuya_ble_timestamp_with_dst_data_t

typedef struct {
    UINT32_T timestamp;
    INT16_T time_zone;   /**< Multiply actual time zone by 100. */
    UINT8_T n_years_dst; /**< how many years of daylight saving time. */
    UINT8_T *p_data;      /**< the point of dst data. */
    UINT16_T data_len;      /**< dst data length. */
} tuya_ble_timestamp_with_dst_data_t;
  • timestamp:Unix 时间戳。
  • time_zone:有符号型,实际时区的 100 倍,例如北京东八区为 8 × 100 = 800,西 7.5 区为 -750。
  • n_years_dst:表示后面有几年的夏令时数据,0 表示没有夏令时数据,1 表示后面只有 1 年的夏令时数据。
  • p_data:夏令时数据。
  • data_len:夏令时数据长度。
序号 长度 字段 说明
1~10 10 start_1 第 1 年的夏令时起始时间,10 字节 Unix 时间戳字符串。
11~20 10 end_1 第 1 年的夏令时结束时间,10 字节 Unix 时间戳字符串(必须大于当前时间 timestamp)。
…… …… …… ……
~ 10 start_n 第 n 年的夏令时起始时间,10 字节 Unix 时间戳字符串。
~ 10 end_n 第 n 年的夏令时结束时间,10 字节 Unix 时间戳字符串。

说明

  • 如果 app 从云端获取不到时间,app 需要回复全 0 数据(二进制 0)。
  • 响应包中的第一组夏令时数据(start_1 : end_1)有可能是当年的,也有可能是下一年的,app 判断条件是如果当前时间点 timestamp 还没进入当年的夏令时时间段或者已经处于当年夏令时时间段内,第一组的夏令时数据应该是当年的,否则第一组的夏令时数据是 timestamp 当前时间点下一年的。

tal_utc_date_t

typedef struct {
    UINT16_T year;
    UINT8_T month;
    UINT8_T day;
    UINT8_T hour;
    UINT8_T min;
    UINT8_T sec;
    UINT8_T dayIndex; /* 0 = Sunday */
} tal_utc_date_t;
  • year:年。
  • month:月。
  • day:日。
  • hour:时。
  • min:分。
  • sec:秒。
  • dayIndex:星期。

接口说明

RTC 初始化

RTC 上电后从 0 开始计时,RTC 的精度根据不同的芯片或者时钟源的选取会有不同。

接口说明

OPERATE_RET tal_rtc_init(VOID_T);

设置 RTC

接口说明

OPERATE_RET tal_rtc_time_set(TIME_T time_sec);

参数说明

参数 说明
time_sec 4 字节 Unix 时间戳

获取 RTC

接口说明

OPERATE_RET tal_rtc_time_get(TIME_T *time_sec);

参数说明

参数 说明
time_sec 4 字节 Unix 时间戳的指针

设置时区

接口说明

OPERATE_RET tal_utc_set_time_zone(INT16_T time_zone);

参数说明

参数 说明
time_zone 有符号型,实际时区的 100 倍,例如北京东八区为 8 × 100 = 800,西 7.5 区为 -750。

获取时区

接口说明

INT16_T tal_utc_get_time_zone(VOID_T);

参数说明

参数 说明
返回值 有符号型,实际时区的 100 倍,例如北京东八区为 8 × 100 = 800,西 7.5 区为 -750。

默认请求实时时间

设备配网成功后,会默认请求一次时间同步,可通过 TUYA_BLE_AUTO_REQUEST_TIME_CONFIGURE 配置请求的时间类型,默认值为 1

#define TUYA_BLE_AUTO_REQUEST_TIME_CONFIGURE 1 // 请求云端实时时间,结果通过 TUYA_BLE_CB_EVT_TIME_STAMP 上报到应用层,格式详见对 tuya_ble_timestamp_data_t 的说明
#define TUYA_BLE_AUTO_REQUEST_TIME_CONFIGURE 2 // 请求 App 本地实时时间,结果通过 TUYA_BLE_CB_EVT_APP_LOCAL_TIME_NORMAL 上报到应用层,格式详见对 tuya_ble_time_noraml_data_t 的说明
#define TUYA_BLE_AUTO_REQUEST_TIME_CONFIGURE 3 // 请求云端实时时间(带夏令时),结果通过 TUYA_BLE_CB_EVT_TIME_STAMP_WITH_DST 上报到应用层,格式详见对 tuya_ble_timestamp_with_dst_data_t 的说明

请求实时时间

当设备配网成功后,就可以调用该接口请求 App 端/云端的时间。如果需要定时获取实时时间,可以在定时器中调用该函数。注意只有在连接的状态下才能成功获取实时时间,否则会报状态错误。

接口说明

tuya_ble_status_t tuya_ble_time_req(UINT8_T time_type);

参数说明

参数 说明
time_type 0x00:请求云端实时时间,结果通过 TUYA_BLE_CB_EVT_TIME_STAMP 上报到应用层,格式详见对 tuya_ble_timestamp_data_t 的说明。
0x01:请求云端实时时间,结果通过 TUYA_BLE_CB_EVT_TIME_NORMAL 上报到应用层,格式详见对 tuya_ble_time_noraml_data_t 的说明。
0x02:请求 App 本地实时时间,结果通过 TUYA_BLE_CB_EVT_APP_LOCAL_TIME_NORMAL 上报到应用层,格式详见对 tuya_ble_time_noraml_data_t 的说明。

时间戳转日期

Unix 时间戳转换成通用日期类型。

接口说明

OPERATE_RET tal_utc_timestamp2date(UINT32_T timestamp, tal_utc_date_t* date, BOOL_T daylightSaving)

参数说明

参数 说明
timestamp 4 字节 Unix 时间戳
date 详见上文中对 tal_utc_date_t 的解析。
daylightSaving 夏令时,0x00:非夏令时,0x01:夏令时

日期转时间戳

通用日期类型转换成 Unix 时间戳。

接口说明

UINT32_T tal_utc_date2timestamp(tal_utc_date_t *date, BOOL_T daylightSaving);

参数说明

参数 说明
date 详见上文中对 tal_utc_date_t 的解析。
daylightSaving 夏令时,0x00:非夏令时,0x01:夏令时
返回值 4 字节 Unix 时间戳

使用方法

设备每次上电后,tal_rtc_init 接口会初始化设备本地时间,从 0 开始计时。此时设备时间和网络时间不同步,使用 tal_rtc_time_gettal_utc_get_time_zone 查询到的时间为从上电开始的秒数。

当设备完成配网/重连过程后,设备会默认请求一次时间同步,可通过 TUYA_BLE_AUTO_REQUEST_TIME_CONFIGURE 配置请求的时间类型。不同类型时间的说明请参考上文中对该宏的介绍。

此后还可以通过调用接口 tuya_ble_time_req 请求时间同步。如果需要定时获取实时时间,可以在定时器中调用该函数。注意只有在连接的状态下才能成功获取实时时间,否则会报状态错误。

当同步的时间下发给设备后,设备会依次调用 tal_rtc_time_settal_utc_set_time_zone 更新本地的时间戳和时区。此时设备时间和网络时间同步,使用 tal_rtc_time_gettal_utc_get_time_zone 查询到的时间为实际的网络时间。

时间服务

功能测试

测试 Case

TEST_CID_GET_TIME
TEST_CID_REQ_TIME
TEST_CID_SET_RTC_TIME
TEST_CID_GET_RTC_TIME

前置条件

  • 您已经下载了涂鸦智能 App。
  • 请确认您的设备处于配网状态。

操作步骤

通过上位机(模拟实际产品)和手机 App 进行数据交互。

  1. 查询设备本地时间。调用 tal_rtc_time_gettal_utc_get_time_zone 获取设备本地时间戳和时区,上电后从 0 开始。

    时间服务
  2. 配网成功后,默认请求实时时间。通过宏 TUYA_BLE_AUTO_REQUEST_TIME_CONFIGURE 控制请求的时间类型。

    时间服务
  3. 手动请求实时时间。实际是调用接口 tuya_ble_time_req 请求时间同步。

    时间服务
  4. 查询设备本地时间。调用 tal_rtc_time_gettal_utc_get_time_zone 获取设备本地时间戳和时区,配网成功后同步网络时间。

    时间服务

    上位机使用的相关问题,请访问 Logic 上位机使用指南

支持与帮助

在开发过程遇到问题,您可以登录 TuyaOS 开发者论坛 TuyaOS-蓝牙设备开发 版块进行沟通咨询。

咨询前建议首先查阅 官方资料 或参考已有帖子,并认真阅读 发帖规范