x
This commit is contained in:
@ -15,7 +15,7 @@ WH Telemetry Protocol(简称 **WHTP**)是一套面向物联网场景的 **JS
|
|||||||
1. 阅读主规范 [schema.md](schema.md),了解字段定义与类型系统。
|
1. 阅读主规范 [schema.md](schema.md),了解字段定义与类型系统。
|
||||||
2. 查看 [example.jsonc](example.jsonc) 获取完整示例。
|
2. 查看 [example.jsonc](example.jsonc) 获取完整示例。
|
||||||
3. 若采用 MQTT 作为载体,参考 [mqtt.md](mqtt.md) 的主题、QoS、Retain 与连接安全实践。
|
3. 若采用 MQTT 作为载体,参考 [mqtt.md](mqtt.md) 的主题、QoS、Retain 与连接安全实践。
|
||||||
4. 参见 [schema.json](schema.json) 获取 [JSON Schema](https://json-schema.org/) 定义。使用 [ATLASSIAN JSON Schema Viewer](https://json-schema.app/view/%23?url=https%3A%2F%2Fweihua-iot.cn%2Fschema.json) 在线可视化/校验。
|
4. 参见 [schema.json](schema.json) 获取 [JSON Schema](https://json-schema.org/) 定义。使用 [ATLASSIAN JSON Schema Viewer](https://json-schema.app/view/%23?url=https%3A%2F%2Fgit.weihua-iot.cn%2Fcrosstyan%2Fwhtp%2Fraw%2Fbranch%2Fmain%2Fschema.json) 在线可视化/校验。
|
||||||
|
|
||||||
## 仓库结构
|
## 仓库结构
|
||||||
|
|
||||||
|
|||||||
91
schema.json
91
schema.json
@ -39,41 +39,7 @@
|
|||||||
"pattern": "^[A-Za-z0-9_-]{21}$"
|
"pattern": "^[A-Za-z0-9_-]{21}$"
|
||||||
},
|
},
|
||||||
"dev_type": {
|
"dev_type": {
|
||||||
"description": "Device model identifier.",
|
"$ref": "#/definitions/DeviceType"
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"required": [
|
|
||||||
"type_id"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"type_id": {
|
|
||||||
"type": "string",
|
|
||||||
"format": "nanoid",
|
|
||||||
"pattern": "^[A-Za-z0-9_-]{21}$"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"required": [
|
|
||||||
"type_name"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"type_name": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"timestamp": {
|
"timestamp": {
|
||||||
"$ref": "#/definitions/Timestamp"
|
"$ref": "#/definitions/Timestamp"
|
||||||
@ -220,6 +186,43 @@
|
|||||||
},
|
},
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
},
|
},
|
||||||
|
"DeviceType": {
|
||||||
|
"description": "Device model identifier.",
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"required": [
|
||||||
|
"type_id"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type_id": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "nanoid",
|
||||||
|
"pattern": "^[A-Za-z0-9_-]{21}$"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"required": [
|
||||||
|
"type_name"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type_name": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"FieldMetadata": {
|
"FieldMetadata": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"description": "Metadata describing a field value.",
|
"description": "Metadata describing a field value.",
|
||||||
@ -322,11 +325,21 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"coordinates": {
|
"coordinates": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
"minItems": 2,
|
"minItems": 2,
|
||||||
"maxItems": 2
|
"maxItems": 2,
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "number",
|
||||||
|
"minimum": -180,
|
||||||
|
"maximum": 180
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "number",
|
||||||
|
"minimum": -90,
|
||||||
|
"maximum": 90
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"additionalItems": false
|
||||||
},
|
},
|
||||||
"coordinate_system": {
|
"coordinate_system": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
|||||||
73
schema.md
73
schema.md
@ -194,33 +194,78 @@ type UserData = Record<string, any>
|
|||||||
|
|
||||||
### 值 (`value`)
|
### 值 (`value`)
|
||||||
|
|
||||||
字段实际测量值,其类型必须与 `metadata.data_type` 完全对应,形态分三类:
|
字段实际测量值,其类型必须与 `metadata.data_type` 完全对应, 详见 ["数据类型"](#%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B) 章节
|
||||||
|
|
||||||
|
1. **标量** (scalar)
|
||||||
|
|
||||||
|
`string | number | boolean | enum<id>`, 如
|
||||||
|
|
||||||
1. **标量** — `string | number | boolean | enum`
|
|
||||||
```jsonc
|
```jsonc
|
||||||
"value": 42
|
{
|
||||||
|
"id": "example_number",
|
||||||
|
"value": 42,
|
||||||
|
"metadata": { "data_type": "number" }
|
||||||
|
}
|
||||||
```
|
```
|
||||||
2. **等间隔数组 (array)** — `T[]`,通过 `sample_interval` 指定采样间隔
|
|
||||||
```jsonc
|
```jsonc
|
||||||
|
{
|
||||||
|
"id": "example_string",
|
||||||
|
"value": "hello",
|
||||||
|
"metadata": { "data_type": "string" }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```jsonc
|
||||||
|
{
|
||||||
|
"id": "example_enum",
|
||||||
|
"value": 1, // interpreted as "good"
|
||||||
|
"metadata": { "data_type": "enum:this", "enum": { "1": "good", "2": "moderate", "3": "bad" } }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> 枚举类型 `enum:this` 表示该字段使用内联枚举, 其定义见下文 ["枚举类型"](#%E6%9E%9A%E4%B8%BE%E7%B1%BB%E5%9E%8B) 章节
|
||||||
|
|
||||||
|
2. **等间隔数组 (array)**
|
||||||
|
`T[]`,通过 `sample_interval` 指定采样间隔, T 为标量类型, 如
|
||||||
|
|
||||||
|
```jsonc
|
||||||
|
{
|
||||||
|
"id": "example_array",
|
||||||
"value": [1, 2, 3],
|
"value": [1, 2, 3],
|
||||||
"metadata": { "data_type": "array<number>", "sample_interval": 0.5 }
|
"metadata": { "data_type": "array<number>", "sample_interval": 0.5 }
|
||||||
|
}
|
||||||
```
|
```
|
||||||
3. **非等间隔(irregular)** — `{ v: T[], t: Timestamp[] }`
|
|
||||||
|
> [!NOTE]
|
||||||
|
> 强烈建议所有等间隔数组都显式填写 `sample_interval` 字段, 若不填写则默认采样间隔为 1s
|
||||||
|
|
||||||
|
3. **非等间隔(irregular)**
|
||||||
|
|
||||||
|
`{ v: T[], t: Timestamp[] }`, T 为标量类型, 如
|
||||||
|
|
||||||
```jsonc
|
```jsonc
|
||||||
|
{
|
||||||
|
"id": "example_irregular",
|
||||||
"value": { "v": [1,2,3], "t": [1715145600,1715145601,1715145603] },
|
"value": { "v": [1,2,3], "t": [1715145600,1715145601,1715145603] },
|
||||||
"metadata": { "data_type": "irregular<number>" }
|
"metadata": { "data_type": "irregular<number>" }
|
||||||
|
}
|
||||||
```
|
```
|
||||||
`t` 数组必须与 `v` 数组长度相同, 且 `t` 数组中的时间戳必须严格递增, 否则会被视为非法数据
|
`t` 数组必须与 `v` 数组长度相同, 且 `t` 数组中的时间戳必须严格递增, 否则会被视为非法数据
|
||||||
|
|
||||||
`null` 与 `undefined` 不被支持,嵌套数组(如 `array<array<number>>`)亦为非法。
|
> [!IMPORTANT]
|
||||||
|
>
|
||||||
|
> - `null` 与 `undefined` 不被支持
|
||||||
|
> - 嵌套数组(如 `array<array<number>>`)亦为非法类型
|
||||||
|
|
||||||
### 元数据 (`metadata`)
|
### 字段级元数据
|
||||||
|
|
||||||
field 级字段元数据, 用于描述 `value` 的类型, 采样间隔, 单位, 标签, 置信度, 错误码, 错误信息, 内联枚举, 用户自定义信息等
|
field 级字段元数据, 用于描述 `value` 的类型, 采样间隔, 单位, 标签, 置信度, 错误码, 错误信息, 内联枚举, 用户自定义信息等, 其类型为 `FieldMetadata`
|
||||||
|
|
||||||
#### 数据类型 (`data_type`)
|
#### 数据类型
|
||||||
|
|
||||||
必填。字符串。用于描述 `value` 的类型。
|
`data_type` 用于描述 `value` 的类型, 其类型为 `DataType`
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
type DataType =
|
type DataType =
|
||||||
@ -255,7 +300,7 @@ type DataType =
|
|||||||
|
|
||||||
下面分别介绍各个类型
|
下面分别介绍各个类型
|
||||||
|
|
||||||
##### 原始型別 (`primitive`)
|
##### 原始型別
|
||||||
|
|
||||||
协议中的 **原始型别(primitive)** 直接对应于 JSON 支持的基本数据类型。所有字段的最基本取值都必须属于原始型别。
|
协议中的 **原始型别(primitive)** 直接对应于 JSON 支持的基本数据类型。所有字段的最基本取值都必须属于原始型别。
|
||||||
|
|
||||||
@ -269,14 +314,14 @@ type PrimitiveType = string | number | boolean
|
|||||||
- `number`:IEEE-754 双精度浮点数
|
- `number`:IEEE-754 双精度浮点数
|
||||||
- `boolean`:布尔值,仅允许 true 或 false(不支持 0/1 或字符串)
|
- `boolean`:布尔值,仅允许 true 或 false(不支持 0/1 或字符串)
|
||||||
|
|
||||||
##### 枚举类型 (`enums`)
|
##### 枚举类型
|
||||||
|
|
||||||
在本协议中,枚举类型本质上是一种特殊的 number 类型。其取值必须限定在一组预先定义的枚举值中。枚举的具体定义可以来源于:
|
在本协议中,枚举类型 (`enum`, [Enumeration](https://en.wikipedia.org/wiki/Enumeration)) 本质上是一种特殊的 number 类型。其取值必须限定在一组预先定义的枚举值中。枚举的具体定义可以来源于:
|
||||||
|
|
||||||
- 全局定义:`metadata.enums`(适用于多个字段复用的场景)
|
- 全局定义:`metadata.enums`(适用于多个字段复用的场景)
|
||||||
- 字段内联定义:`fields[*].metadata.enum`(只对当前字段有效)
|
- 字段内联定义:`fields[*].metadata.enum`(只对当前字段有效)
|
||||||
|
|
||||||
每个枚举值都必须对应唯一的数值(number)。在类型系统中,枚举类型可以视为带有标签约束的 number:
|
每个枚举值都必须对应唯一的数值(number)。在类型系统中,枚举类型可以视为带有标签约束的 number:
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
newtype Enum = number
|
newtype Enum = number
|
||||||
|
|||||||
Reference in New Issue
Block a user