diff --git a/schema.md b/schema.md index 45b4635..12dd1e7 100644 --- a/schema.md +++ b/schema.md @@ -29,32 +29,32 @@ WH Telemetry Protocol(WHTP)是一套专为物联网场景设计的轻量级 | fields | 是 | `Field[]` | 采集字段数组 | | metadata | 否 | object | 消息级元数据 | -### Version (`version`) +### 版本 -必填。正整数,仅表示协议主版本号。当前版本为 **1**。 +`version` 描述协议主版本号, 必填, 其类型为 `number`, 仅表示协议主版本号。当前版本为 **1**。 -### 消息类型 (`msg_type`) +### 消息类型 -必填。字符串。目前仅允许 `"telemetry"`,用于上传遥测数据。 +`msg_type` 描述消息类型, 必填, 其类型为 `string`, 目前仅允许 `"telemetry"`,用于上传遥测数据。 -### 消息模式 (`mode`) +### 消息模式 -可选,字符串,默认 `"descriptive"`。 +`mode` 描述消息模式, 可选, 其类型为 `string`, 默认 `"descriptive"`。 * `descriptive` —— 自描述模式,允许在字段 `metadata` 中携带全部上下文信息,消息本身即可被独立解析。 * `strict` (RFU, reserved for future use) —— 严格模式,不允许出现字段级 `metadata`,字段定义需通过外部文档约定,适用于带宽受限或固定 Schema 场景。(目前无实际意义, 需要与二进制协议配合) -### 设备 ID (`dev_id`) +### 设备ID -必填。设备唯一标识,采用 [NanoID](https://github.com/ai/nanoid) 格式(如 `2B1oj2S5k7kS8mL_QaCs`),在设备生命周期内保持不变。 +`dev_id` 描述设备唯一标识, 必填, 其类型为 `string`, 采用 [NanoID](https://github.com/ai/nanoid) 格式(如 `2B1oj2S5k7kS8mL_QaCs`),在设备生命周期内保持不变。 -### 设备类型 (`dev_type`) +### 设备类型 ```typescript type DeviceType = string | { type_id: string } | { type_name: string } ``` -必选。用于标识设备类别或型号。支持三种写法: +`dev_type` 描述设备型号, 必填, 其类型为 `DeviceType`, 用于标识设备类别或型号。支持三种写法: 1. **字符串**:例如 `"device_type_name"`;与 `{ "type_name": string }` 等价 2. **对象** `{ "type_id": NanoID }`;NanoID 为设备型号的唯一标识, 由平台分配 @@ -67,7 +67,9 @@ type DeviceType = string | { type_id: string } | { type_name: string } > - 对于长期稳定的系统, 推荐使用 `{ "type_id": NanoID }` 格式, 作为稳定的唯一标识符 > - 对于临时场景, 可以使用 `string` 或 `{ "type_name": string }` 格式 -### 根级时间戳 (`timestamp`) +### 根级时间戳 + +`timestamp` 描述消息生成时刻, 其类型为 `Timestamp` ```typescript type Timestamp = @@ -95,14 +97,13 @@ type Timestamp = > [!NOTE] > 根级 (root-level) 时间戳表示消息生成或入队时刻, 字段级 (field-level) 时间戳表示实际数据采样时刻, 应使用字段级时间戳进行所有时间序列分析 -### 消息描述字段组 (`fields`) +### 消息描述字段组 -必填。`Field` 对象数组,数组中每个元素代表一个测量项,其 `id` 在同一条消息内必须唯一。 -关于 `Field` 对象的定义详见后文 ["消息描述字段"](#%E6%B6%88%E6%81%AF%E6%8F%8F%E8%BF%B0%E5%AD%97%E6%AE%B5) 章节。 +`fields` 描述消息中包含的测量项, 其类型为 `Field[]`, 数组中每个元素代表一个测量项, 其 `id` 在同一条消息内必须唯一, 关于 `Field` 对象的定义详见后文 [消息描述字段](#%E6%B6%88%E6%81%AF%E6%8F%8F%E8%BF%B0%E5%AD%97%E6%AE%B5) 章节 -### 消息元数据 (`metadata`) +### 根级元数据 -`user` 字段之外的 `metadata` 字段为已定义 (well-defined) 字段, 其定义见下文 +`metadata` 描述根级 (消息级) 元数据, 其类型为 `MessageMetadata` ```typescript interface MessageMetadata { @@ -114,16 +115,17 @@ interface MessageMetadata { } ``` -#### 全局枚举 (`enums`) +> [!NOTE] +> `user` 字段之外的 `metadata` 字段为已定义 (well-defined) 字段; 用户应优先使用已定义字段, 若不能满足需求才可使用[用户自定义字段](#%E7%94%A8%E6%88%B7%E8%87%AA%E5%AE%9A%E4%B9%89%E5%AD%97%E6%AE%B5) -可选。全局枚举定义表,用于在字段 `fields[*].metadata.data_type` 中以 `enum:` 形式引用。 +#### 全局枚举 ```typescript type InlineEnum = Record type EnumDefinition = { id: string; value: InlineEnum }; ``` -示例 +`metadata.enums` 字段类型为 `EnumDefinition[]`, 用于在字段 `fields[*].metadata.data_type` 中以 `enum:` 形式引用, 如 ```jsonc "metadata": { @@ -138,17 +140,17 @@ type EnumDefinition = { id: string; value: InlineEnum }; 等价于 -```cpp -enum class AirQuality { +```typescript +enum AirQuality { GOOD = 1, MODERATE = 2, BAD = 3, -}; +} ``` -#### 位置信息 (`location`) +#### 位置信息 -可选。表示消息采集时的设备地理位置 +`metadata.location` 字段类型为 `Location`, 表示消息采集时的设备地理位置, 如 ```typescript type Location = { @@ -170,17 +172,17 @@ type Location = { } ``` -#### 电量 (`battery`) +#### 电量 -可选。数字,范围 0–100,对应设备剩余电量百分比。 +`metadata.battery` 字段类型为数字, 表示设备剩余电量百分比, 其范围为 0–100 -#### 序列号 (`seq`) +#### 序列号 -可选。无符号整数。每上传一条消息递增 1,用于检测丢包或乱序。达到上限后循环计数(默认为 32 位无符号整数回绕)。 +`metadata.seq` 字段类型为无符号整数, 每上传一条消息递增 1, 用于检测丢包或乱序, 达到上限后循环计数(默认为 32 位无符号整数回绕) -#### 用户自定义信息 (`user`) +#### 根级用户自定义字段 -可选。任意键值对,为数据生产方保留的自定义信息区 +`metadata.user` 字段为任意键值对, 为数据生产方保留的自定义信息区, 其类型为 `UserData` ```typescript type UserData = Record @@ -188,13 +190,13 @@ type UserData = Record ## 消息描述字段 -### 标识符 (`id`) +### 字段标识符 -必填。ASCII 字符串,仅允许字母、数字与下划线,且不得以数字开头。长度建议 1–64 字符。例如 `temperature_sensor`。 +`id` 描述字段标识符, 必填, 其类型为 `string`, ASCII 字符串,仅允许字母、数字与下划线,且不得以数字开头。长度建议 1–64 字符。例如 `temperature_sensor`。 -### 值 (`value`) +### 字段值 -字段实际测量值,其类型必须与 `metadata.data_type` 完全对应, 详见 ["数据类型"](#%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B) 章节 +`value` 描述字段值, 其类型必须与 `metadata.data_type` 完全对应, 详见 ["数据类型"](#%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B) 章节 1. **标量** (scalar) @@ -327,23 +329,23 @@ type PrimitiveType = string | number | boolean newtype Enum = number ``` -##### 标量类型 (`scalar`) +##### 标量类型 -标量类型为 `string | number | boolean | Enum` 的统称, 其定义见上文 +标量类型 (scalar) 为 `string | number | boolean | Enum` 的统称, 其定义见上文 ```haskell type ScalarType = PrimitiveType | Enum ``` -##### 等间隔数组类型 (`array`) +##### 等间隔数组类型 -本协议中的数组类型在 `field` 中的含义为 **等采样率** 的数组, 其定义为: +本协议中的数组类型在 `field` 中的含义为 **等采样率** 的数组 (array), 其定义为: ```haskell type ArrayType T = T[] -- array ``` -##### 非等间隔数组类型 (`irregular`) +##### 非等间隔数组类型 本协议中的非等间隔数组类型在 `field` 中的含义为 **非等采样率** 或 **采样率未知** 的数组, 其定义为: @@ -359,19 +361,19 @@ type IrregularType T = { v: T[], t: Timestamp[] } -- irregular type BatchType T = ArrayType T | IrregularType T ``` -#### field 时间戳 (`timestamp`) +#### 字段时间戳 -可选。若不存在则取 `root.timestamp` 的值; 表示该字段 **采样时刻** 的时间戳, 其类型为 `Timestamp` +`timestamp` 描述字段时间戳, 可选, 其类型为 `Timestamp`, 若不存在则取 `root.timestamp` 的值; 表示该字段 **采样时刻** 的时间戳 -#### 标签 (`label`) +#### 标签 -可选。字段展示名,UTF-8 字符串,便于人机界面直观呈现。实际是否使用/如何使用由数据消费方决定。 +`label` 描述字段展示名, 可选, 其类型为 `string`, 便于人机界面直观呈现。实际是否使用/如何使用由数据消费方决定。 示例:`"label": "温度"` -#### 错误码 (`error_code`) +#### 错误码 -可选。非零整数。0 表示无错误;其他值与以下错误码表对应,用于描述测量异常。 +`error_code` 描述错误码, 可选, 其类型为 `number`, 非零整数。0 表示无错误;其他值与以下错误码表对应,用于描述测量异常。 | 代码 | 分类 | 名称 | 描述 | | ---------- | ---------- | --------------------- | ------------------------------------------ | @@ -394,17 +396,17 @@ type BatchType T = ArrayType T | IrregularType T | 512–1023 | 应用 | — | 留给具体应用 / 产品线自定义 | | 1024–65535 | 厂商自定义 | — | 厂商或项目私有错误码区间 | -#### 错误信息 (`error_msg`) +#### 错误信息 -可选。UTF-8 字符串,对 `error_code` 进行人类可读的补充说明。 +`error_msg` 描述错误信息, 可选, 其类型为 `string`, 对 `error_code` 进行人类可读的补充说明。 -#### 置信度 (`confidence`) +#### 置信度 ```typescript type Confidence = number | number[] ``` -置信度用于表征 value 数据的可靠性,其取值类型可为单个数值(`number`)或数值数组(`number[]`),具体规则如下: +`confidence` 描述置信度, 可选, 其类型为 `Confidence`, 用于表征 value 数据的可靠性,其取值类型可为单个数值(`number`)或数值数组(`number[]`),具体规则如下: - 当 confidence 为单个数值时,表示该字段所有采样点共用相同的置信度。此形式适用于任意类型的 value(包括单点和批量数据)。 - 当 confidence 为数值数组时,表示每个采样点各自的置信度。此形式仅适用于批量数据(即 value 为数组或不等间隔序列);此时 confidence 数组长度必须与采样点数量严格一致。 @@ -420,9 +422,9 @@ type Confidence = number | number[] > - 如未指定 confidence 字段,则默认所有采样点的置信度为 1 -#### 采样间隔 (`sample_interval`) +#### 采样间隔 -可选。采样间隔, 用于描述 `value` 为等间隔数组时, 数组中每个元素的时间间隔 (建议所有等间隔数组都显式填写该字段) +`sample_interval` 描述采样间隔, 可选, 其类型为 `SampleInterval`, 用于描述 `value` 为等间隔数组时, 数组中每个元素的时间间隔 ```typescript type TimeDelta = { ms?: number, s?: number, m?: number, h?: number, d?: number, w?: number } @@ -439,27 +441,26 @@ type SampleInterval = 示例:`"sample_interval": 0.5`(两次采样间隔 0.5 秒) -#### 单位 (`unit`) +> [!IMPORTANT] +> 强烈建议所有等间隔数组都显式填写 `sample_interval` 字段 -可选。测量值单位。推荐使用 [UCUM](https://ucum.org/ucum) 码(如 `"Cel"` 代表摄氏度),也支持自由字符串。 +#### 单位 + +`unit` 描述单位, 可选, 其类型为 `string`, 推荐使用 [UCUM](https://ucum.org/ucum) 码(如 `"Cel"` 代表摄氏度),也支持自由字符串。 示例:`"unit": "Cel"` -#### 内联枚举 (`enum`) +#### 内联枚举 -可选。当 `data_type` 为 `enum:this` 及其衍生类型时, 用于定义内联枚举值 +`enum` 描述内联枚举, 可选, 其类型为 `InlineEnum`, 当 `data_type` 为 `enum:this` 及其衍生类型时, 用于定义内联枚举值 ```typescript type InlineEnum = Record ``` -#### 用户自定义信息 (`user`) +#### 字段级用户自定义字段 -可选。任意键值对,为数据生产方保留的自定义信息区: - -```typescript -type UserData = Record -``` +`user` 描述字段级用户自定义字段, 可选, 类型定义同 [根级用户自定义字段](#%E6%A0%B9%E7%BA%A7%E7%94%A8%E6%88%B7%E8%87%AA%E5%AE%9A%E4%B9%89%E5%AD%97%E6%AE%B5) ## 伪代码类型定义