diff --git a/README.md b/README.md index b570f1a..cd712a9 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ WH Telemetry Protocol(简称 **WHTP**)是一套面向物联网场景的 **JS 1. 阅读主规范 [schema.md](schema.md),了解字段定义与类型系统。 2. 查看 [example.jsonc](example.jsonc) 获取完整示例。 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) 在线可视化/校验。 ## 仓库结构 diff --git a/schema.json b/schema.json index 069f0d4..35f0f7c 100644 --- a/schema.json +++ b/schema.json @@ -39,41 +39,7 @@ "pattern": "^[A-Za-z0-9_-]{21}$" }, "dev_type": { - "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 - } - ] - } - ] + "$ref": "#/definitions/DeviceType" }, "timestamp": { "$ref": "#/definitions/Timestamp" @@ -220,6 +186,43 @@ }, "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": { "type": "object", "description": "Metadata describing a field value.", @@ -322,11 +325,21 @@ "properties": { "coordinates": { "type": "array", - "items": { - "type": "number" - }, "minItems": 2, - "maxItems": 2 + "maxItems": 2, + "items": [ + { + "type": "number", + "minimum": -180, + "maximum": 180 + }, + { + "type": "number", + "minimum": -90, + "maximum": 90 + } + ], + "additionalItems": false }, "coordinate_system": { "type": "string", diff --git a/schema.md b/schema.md index 7927916..45b4635 100644 --- a/schema.md +++ b/schema.md @@ -194,33 +194,78 @@ type UserData = Record ### 值 (`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`, 如 + + ```jsonc + { + "id": "example_number", + "value": 42, + "metadata": { "data_type": "number" } + } + ``` + + ```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 为标量类型, 如 -1. **标量** — `string | number | boolean | enum` ```jsonc - "value": 42 + { + "id": "example_array", + "value": [1, 2, 3], + "metadata": { "data_type": "array", "sample_interval": 0.5 } + } ``` -2. **等间隔数组 (array)** — `T[]`,通过 `sample_interval` 指定采样间隔 + + > [!NOTE] + > 强烈建议所有等间隔数组都显式填写 `sample_interval` 字段, 若不填写则默认采样间隔为 1s + +3. **非等间隔(irregular)** + + `{ v: T[], t: Timestamp[] }`, T 为标量类型, 如 + ```jsonc - "value": [1, 2, 3], - "metadata": { "data_type": "array", "sample_interval": 0.5 } - ``` -3. **非等间隔(irregular)** — `{ v: T[], t: Timestamp[] }` - ```jsonc - "value": { "v": [1,2,3], "t": [1715145600,1715145601,1715145603] }, - "metadata": { "data_type": "irregular" } + { + "id": "example_irregular", + "value": { "v": [1,2,3], "t": [1715145600,1715145601,1715145603] }, + "metadata": { "data_type": "irregular" } + } ``` `t` 数组必须与 `v` 数组长度相同, 且 `t` 数组中的时间戳必须严格递增, 否则会被视为非法数据 -`null` 与 `undefined` 不被支持,嵌套数组(如 `array>`)亦为非法。 +> [!IMPORTANT] +> +> - `null` 与 `undefined` 不被支持 +> - 嵌套数组(如 `array>`)亦为非法类型 -### 元数据 (`metadata`) +### 字段级元数据 -field 级字段元数据, 用于描述 `value` 的类型, 采样间隔, 单位, 标签, 置信度, 错误码, 错误信息, 内联枚举, 用户自定义信息等 +field 级字段元数据, 用于描述 `value` 的类型, 采样间隔, 单位, 标签, 置信度, 错误码, 错误信息, 内联枚举, 用户自定义信息等, 其类型为 `FieldMetadata` -#### 数据类型 (`data_type`) +#### 数据类型 -必填。字符串。用于描述 `value` 的类型。 +`data_type` 用于描述 `value` 的类型, 其类型为 `DataType` ```typescript type DataType = @@ -255,7 +300,7 @@ type DataType = 下面分别介绍各个类型 -##### 原始型別 (`primitive`) +##### 原始型別 协议中的 **原始型别(primitive)** 直接对应于 JSON 支持的基本数据类型。所有字段的最基本取值都必须属于原始型别。 @@ -269,14 +314,14 @@ type PrimitiveType = string | number | boolean - `number`:IEEE-754 双精度浮点数 - `boolean`:布尔值,仅允许 true 或 false(不支持 0/1 或字符串) -##### 枚举类型 (`enums`) +##### 枚举类型 -在本协议中,枚举类型本质上是一种特殊的 number 类型。其取值必须限定在一组预先定义的枚举值中。枚举的具体定义可以来源于: +在本协议中,枚举类型 (`enum`, [Enumeration](https://en.wikipedia.org/wiki/Enumeration)) 本质上是一种特殊的 number 类型。其取值必须限定在一组预先定义的枚举值中。枚举的具体定义可以来源于: - 全局定义:`metadata.enums`(适用于多个字段复用的场景) - 字段内联定义:`fields[*].metadata.enum`(只对当前字段有效) -每个枚举值都必须对应唯一的数值(number)。在类型系统中,枚举类型可以视为带有标签约束的 number: +每个枚举值都必须对应唯一的数值(number)。在类型系统中,枚举类型可以视为带有标签约束的 number: ```haskell newtype Enum = number