Compare commits
6 Commits
fa04055e57
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 4756f19073 | |||
| d3b6425a66 | |||
| b615bfa9e2 | |||
| 6498395ed8 | |||
| f78d95d98d | |||
| e66d62ed6a |
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
"$id": "https://example.com/wh-telemetry.schema.json",
|
"$id": "https://git.weihua-iot.cn/crosstyan/whtp/raw/branch/main/schema.json",
|
||||||
"title": "WH Telemetry Protocol v1 Message",
|
"title": "WH Telemetry Protocol v1 Message",
|
||||||
"description": "JSON Schema definition for a WH Telemetry Protocol (WHTP) telemetry message.",
|
"description": "JSON Schema definition for a WH Telemetry Protocol (WHTP) telemetry message.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
|||||||
66
schema.md
66
schema.md
@ -1,8 +1,10 @@
|
|||||||
# WH Telemetry Protocol Specification
|
# WH Telemetry Protocol Specification
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
WH Telemetry Protocol(WHTP)是一套专为物联网场景设计的轻量级、强自描述性遥测数据上行协议,采用 JSON 作为数据承载格式。WHTP 面向传感器数据、遥测采集、边缘网关等设备与云端的数据交互,兼顾数据结构规范、易于解析与灵活拓展,适用于农业、环境监测、工业自动化等多种场景。
|
WH Telemetry Protocol(WHTP)是一套专为物联网场景设计的轻量级、强自描述性遥测数据上行协议,采用 JSON 作为数据承载格式。WHTP 面向传感器数据、遥测采集、边缘网关等设备与云端的数据交互,兼顾数据结构规范、易于解析与灵活拓展,适用于农业、环境监测、工业自动化等多种场景。
|
||||||
|
|
||||||
协议设计核心特点:
|
### 核心特点
|
||||||
|
|
||||||
- 自描述:字段类型、单位、置信度、枚举、错误信息等全部可内嵌于消息,无需依赖外部 schema 即可独立解析
|
- 自描述:字段类型、单位、置信度、枚举、错误信息等全部可内嵌于消息,无需依赖外部 schema 即可独立解析
|
||||||
- 结构统一:所有遥测消息采用统一的数据结构,便于前端/平台/存储适配与二次开发
|
- 结构统一:所有遥测消息采用统一的数据结构,便于前端/平台/存储适配与二次开发
|
||||||
@ -11,13 +13,20 @@ WH Telemetry Protocol(WHTP)是一套专为物联网场景设计的轻量级
|
|||||||
- 可扩展性:预留元数据(metadata)与用户自定义信息(user),支持平台与业务个性化扩展
|
- 可扩展性:预留元数据(metadata)与用户自定义信息(user),支持平台与业务个性化扩展
|
||||||
- 错误与置信机制:内建错误码、错误信息与置信度表达,方便数据质量管理与自动化校验
|
- 错误与置信机制:内建错误码、错误信息与置信度表达,方便数据质量管理与自动化校验
|
||||||
|
|
||||||
消息结构总览:
|
### 消息结构总览
|
||||||
|
|
||||||
- 根级字段:描述消息身份、设备、时间、环境等全局信息
|
- 根级字段:描述消息身份、设备、时间、环境等全局信息
|
||||||
- 字段组(fields):每个测量项(field)携带唯一 ID、测量值(value)、类型元信息(metadata)
|
- 字段组(fields):每个测量项(field)携带唯一 ID、测量值(value)、类型元信息(metadata)
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> 本文档假设读者熟悉 [Typescript](https://www.typescriptlang.org/) 类型系统, 以及 [JSON](https://www.json.org/json-en.html) 格式, 并使用 [Typescript](https://www.typescriptlang.org/) 作为伪代码/类型定义语言
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> 请配合 [JSON Schema](https://json-schema.org/) 使用 (见 [schema.json](./schema.json)), 以获得更好的类型推导与校验体验
|
||||||
|
|
||||||
## 根级字段
|
## 根级字段
|
||||||
|
|
||||||
|
|
||||||
| 字段 | 必选 | 类型 | 说明 |
|
| 字段 | 必选 | 类型 | 说明 |
|
||||||
| --------- | ---- | --------------- | ---------------------------------------------- |
|
| --------- | ---- | --------------- | ---------------------------------------------- |
|
||||||
| version | 是 | number | 协议主版本号 |
|
| version | 是 | number | 协议主版本号 |
|
||||||
@ -97,9 +106,9 @@ type Timestamp =
|
|||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> 根级 (root-level) 时间戳表示消息生成或入队时刻, 字段级 (field-level) 时间戳表示实际数据采样时刻, 应使用字段级时间戳进行所有时间序列分析
|
> 根级 (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` 对象的定义详见后文 [字段描述项](#%E5%AD%97%E6%AE%B5%E6%8F%8F%E8%BF%B0%E9%A1%B9) 章节
|
||||||
|
|
||||||
### 根级元数据
|
### 根级元数据
|
||||||
|
|
||||||
@ -116,7 +125,7 @@ interface MessageMetadata {
|
|||||||
```
|
```
|
||||||
|
|
||||||
> [!NOTE]
|
> [!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)
|
> `user` 字段之外的 `metadata` 字段为已定义 (well-defined) 字段; 用户应优先使用已定义字段, 若不能满足需求才可使用 [用户自定义字段](#%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)
|
||||||
|
|
||||||
#### 全局枚举
|
#### 全局枚举
|
||||||
|
|
||||||
@ -148,6 +157,8 @@ enum AirQuality {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
详见 [枚举类型](#%E6%9E%9A%E4%B8%BE%E7%B1%BB%E5%9E%8B)
|
||||||
|
|
||||||
#### 位置信息
|
#### 位置信息
|
||||||
|
|
||||||
`metadata.location` 字段类型为 `Location`, 表示消息采集时的设备地理位置, 如
|
`metadata.location` 字段类型为 `Location`, 表示消息采集时的设备地理位置, 如
|
||||||
@ -188,7 +199,9 @@ type Location = {
|
|||||||
type UserData = Record<string, any>
|
type UserData = Record<string, any>
|
||||||
```
|
```
|
||||||
|
|
||||||
## 消息描述字段
|
## 字段描述项
|
||||||
|
|
||||||
|
每个字段 (field) 描述一个测量项, 其类型为 `Field`
|
||||||
|
|
||||||
### 字段标识符
|
### 字段标识符
|
||||||
|
|
||||||
@ -198,7 +211,7 @@ type UserData = Record<string, any>
|
|||||||
|
|
||||||
`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)
|
#### 标量 (scalar)
|
||||||
|
|
||||||
`string | number | boolean | enum<id>`, 如
|
`string | number | boolean | enum<id>`, 如
|
||||||
|
|
||||||
@ -222,14 +235,15 @@ type UserData = Record<string, any>
|
|||||||
{
|
{
|
||||||
"id": "example_enum",
|
"id": "example_enum",
|
||||||
"value": 1, // interpreted as "good"
|
"value": 1, // interpreted as "good"
|
||||||
"metadata": { "data_type": "enum:this", "enum": { "1": "good", "2": "moderate", "3": "bad" } }
|
"metadata": { "data_type": "enum:this", "enum": { "good": 1, "moderate": 2, "bad": 3 } }
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> 枚举类型 `enum:this` 表示该字段使用内联枚举, 其定义见下文 ["枚举类型"](#%E6%9E%9A%E4%B8%BE%E7%B1%BB%E5%9E%8B) 章节
|
> 枚举类型 `enum:this` 表示该字段使用内联枚举, 其定义见下文 ["枚举类型"](#%E6%9E%9A%E4%B8%BE%E7%B1%BB%E5%9E%8B) 章节
|
||||||
|
|
||||||
2. **等间隔数组 (array)**
|
#### 等间隔数组 (array)
|
||||||
|
|
||||||
`T[]`,通过 `sample_interval` 指定采样间隔, T 为标量类型, 如
|
`T[]`,通过 `sample_interval` 指定采样间隔, T 为标量类型, 如
|
||||||
|
|
||||||
```jsonc
|
```jsonc
|
||||||
@ -243,7 +257,7 @@ type UserData = Record<string, any>
|
|||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> 强烈建议所有等间隔数组都显式填写 `sample_interval` 字段, 若不填写则默认采样间隔为 1s
|
> 强烈建议所有等间隔数组都显式填写 `sample_interval` 字段, 若不填写则默认采样间隔为 1s
|
||||||
|
|
||||||
3. **非等间隔(irregular)**
|
#### 非等间隔(irregular)
|
||||||
|
|
||||||
`{ v: T[], t: Timestamp[] }`, T 为标量类型, 如
|
`{ v: T[], t: Timestamp[] }`, T 为标量类型, 如
|
||||||
|
|
||||||
@ -258,8 +272,8 @@ type UserData = Record<string, any>
|
|||||||
|
|
||||||
> [!IMPORTANT]
|
> [!IMPORTANT]
|
||||||
>
|
>
|
||||||
> - `null` 与 `undefined` 不被支持
|
> - `null` 与 `undefined` 为非法值
|
||||||
> - 嵌套数组(如 `array<array<number>>`)亦为非法类型
|
> - 嵌套数组(如 `array<array<number>>`)为非法类型
|
||||||
|
|
||||||
### 字段级元数据
|
### 字段级元数据
|
||||||
|
|
||||||
@ -269,17 +283,17 @@ field 级字段元数据, 用于描述 `value` 的类型, 采样间隔, 单位,
|
|||||||
|
|
||||||
`data_type` 用于描述 `value` 的类型, 其类型为 `DataType`
|
`data_type` 用于描述 `value` 的类型, 其类型为 `DataType`
|
||||||
|
|
||||||
```typescript
|
```haskell
|
||||||
type DataType =
|
type DataType =
|
||||||
| ScalarType
|
| ScalarType
|
||||||
| ArrayType ScalarType
|
| ArrayType ScalarType
|
||||||
| IrregularType ScalarType
|
| IrregularType ScalarType
|
||||||
```
|
```
|
||||||
|
|
||||||
所有合法的 `data_type` 如下:
|
所有合法的 `data_type` 的值如下:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
type DataType =
|
type DataTypeLiteral =
|
||||||
| "string"
|
| "string"
|
||||||
| "number"
|
| "number"
|
||||||
| "boolean"
|
| "boolean"
|
||||||
@ -297,8 +311,10 @@ type DataType =
|
|||||||
| `irregular<enum:this>`
|
| `irregular<enum:this>`
|
||||||
```
|
```
|
||||||
|
|
||||||
- `null` 和 `undefined` 是非法的
|
> [!IMPORTANT]
|
||||||
- 嵌套是非法的
|
>
|
||||||
|
> - `null` 与 `undefined` 为非法值
|
||||||
|
> - 嵌套数组(如 `array<array<number>>`)为非法类型
|
||||||
|
|
||||||
下面分别介绍各个类型
|
下面分别介绍各个类型
|
||||||
|
|
||||||
@ -333,7 +349,7 @@ newtype Enum = number
|
|||||||
|
|
||||||
标量类型 (scalar) 为 `string | number | boolean | Enum` 的统称, 其定义见上文
|
标量类型 (scalar) 为 `string | number | boolean | Enum` 的统称, 其定义见上文
|
||||||
|
|
||||||
```haskell
|
```typescript
|
||||||
type ScalarType = PrimitiveType | Enum
|
type ScalarType = PrimitiveType | Enum
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -341,24 +357,24 @@ type ScalarType = PrimitiveType | Enum
|
|||||||
|
|
||||||
本协议中的数组类型在 `field` 中的含义为 **等采样率** 的数组 (array), 其定义为:
|
本协议中的数组类型在 `field` 中的含义为 **等采样率** 的数组 (array), 其定义为:
|
||||||
|
|
||||||
```haskell
|
```typescript
|
||||||
type ArrayType T = T[] -- array<T>
|
type ArrayType<T> = T[] // array<T>
|
||||||
```
|
```
|
||||||
|
|
||||||
##### 非等间隔数组类型
|
##### 非等间隔数组类型
|
||||||
|
|
||||||
本协议中的非等间隔数组类型在 `field` 中的含义为 **非等采样率** 或 **采样率未知** 的数组, 其定义为:
|
本协议中的非等间隔数组类型在 `field` 中的含义为 **非等采样率** 或 **采样率未知** 的数组, 其定义为:
|
||||||
|
|
||||||
```haskell
|
```typescript
|
||||||
type IrregularType T = { v: T[], t: Timestamp[] } -- irregular<T>
|
type IrregularType<T> = { v: T[], t: Timestamp[] } // irregular<T>
|
||||||
```
|
```
|
||||||
|
|
||||||
`t` 数组必须与 `v` 数组长度相同, 且 `t` 数组中的时间戳必须严格递增, 否则会被视为非法数据
|
`t` 数组必须与 `v` 数组长度相同, 且 `t` 数组中的时间戳必须严格递增, 否则会被视为非法数据
|
||||||
|
|
||||||
等间隔数组与非等间隔数组统称为批量 (batch) 数据
|
等间隔数组与非等间隔数组统称为批量 (batch) 数据
|
||||||
|
|
||||||
```haskell
|
```typescript
|
||||||
type BatchType T = ArrayType T | IrregularType T
|
type BatchType<T> = ArrayType<T> | IrregularType<T>
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 字段时间戳
|
#### 字段时间戳
|
||||||
@ -452,7 +468,7 @@ type SampleInterval =
|
|||||||
|
|
||||||
#### 内联枚举
|
#### 内联枚举
|
||||||
|
|
||||||
`enum` 描述内联枚举, 可选, 其类型为 `InlineEnum`, 当 `data_type` 为 `enum:this` 及其衍生类型时, 用于定义内联枚举值
|
`enum` 描述内联枚举, 可选, 其类型为 `InlineEnum`, 当 `data_type` 为 `enum:this` 及其衍生类型时, 用于定义内联枚举值, 详见 [枚举类型](#%E6%9E%9A%E4%B8%BE%E7%B1%BB%E5%9E%8B)
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
type InlineEnum = Record<string, number>
|
type InlineEnum = Record<string, number>
|
||||||
|
|||||||
Reference in New Issue
Block a user